From 64b1ee298667d74720bef06f978e94e0b1e9883c Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 3 Jan 2018 18:02:05 -0500 Subject: [PATCH 0001/1048] started implementation of eosio.system contract as wasm contract --- CMakeLists.txt | 3 ++ README.md | 84 ++++++++++++++++++++++++++++++++++ eosio.system.abi | 37 +++++++++++++++ eosio.system.cpp | 52 +++++++++++++++++++++ eosio.system.hpp | 116 +++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 292 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 README.md create mode 100644 eosio.system.abi create mode 100644 eosio.system.cpp create mode 100644 eosio.system.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..22ecb154 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,3 @@ +file(GLOB ABI_FILES "*.abi") +configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) +add_wast_target(eosio.system "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/README.md b/README.md new file mode 100644 index 00000000..a954337f --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +eosio.system +---------- + +This contract enables users to stake tokens, and then configure and vote on producers and worker proposals. + +Users can also proxy their voting influence to other users. + +The state of this contract is read to determine the 21 active block producers. + +Actions: +The naming convention is codeaccount::actionname followed by a list of paramters. + +Indicates that a particular account wishes to become a producer +## eosio.system::cfgproducer account config + - **account** the producer account to update + - updates the configuration settings for a particular producer, these + + Storage changes are billed to 'account' + +## eosio.system::okproducer account producer vote + - **account** the account which is doing the voting + - **producer** the producer which is being voted for (or unvoted for) + - **vote** true if the producer should be voted for, false if not + + Each account has a maximum number of votes it can maintain. Storage changes will be billed to 'account' + +## eosio.system::setproxy account proxy + - **account** the account which is updating it's proxy + - **proxy** the account which will have the power to vote account's stake + + All current votes are removed and a new proxy link is created. The votes for every producer the proxy + has voted for are updated immediately. + + Storage changes will be billed to 'account' + +## eosio.system::unstake account quantity + - **account** - the account which is requsting their balance be unstaked + - **quantity** - the quantity which will be unstaked, unstaked tokens lose voting influence immediately + + - in order to unstake tokens, an account must request them. The user will receive them over + time via weekly withdraws. The length of time will be configured by the median time as set by + the active producers. + + - If this is called while in the process of unstaking, the currently pending unstake is canceled as if + quantity were 0, then it is applied as if a new unstake request was made. + + - all producers this 'from' has voted for will have their votes updated immediately. + + - bandwidth and storage for the deferred transaction will be billed to 'from' + +## eosio.system::withdraw account + - this action can only be triggered by eosio.system via a deferred transaction generated by unstake + - this will generate an inline eosio.token::transfer call from=eosio.system to=account and amount equal to the next withdraw increment + - this will generate another deferred withdraw to continue the process if there are still withdraws to be made + + +## eosio.system::transfer from to amount memo + - decrements balance of from if amount <= balance + - increments balance of to by amount + - memo is ignored + +## eosio.system::stakevote account amount + - the primary currency of eosio is controlled by the token contract which enables users to transfer + balances from one user to another. The receiver is notified on incoming balances and the vote contract + will stake the tokens on receipt. + + - all producers this 'from' has voted for will have their votes updated immediately. + + +## eosio.system::onblock account blocktime blocknum + - this special action is triggered when a block is applied by the given producer and cannot be generated from + any other source. It is used to pay producers and calculate missed blocks of other producers. + + - producer pay is deposited into the prodcer's stake balance and can be withdrawn over time. + + - if blocknum is the start of a new round this may update the active producer config from the producer votes. + +## eosio.system::freeze producer accounts true|false + - requires permission of the @producers account + - if an account is frozen, all authorizations of that account are rejected and the code for that account will not be run + +## eosio.system::paystandby producer + - every block some amount of tokens is paid + - at most once per day a producer may claim a percentage of the standby pay equal to their totalvotes / allvotes diff --git a/eosio.system.abi b/eosio.system.abi new file mode 100644 index 00000000..c8d8e4b1 --- /dev/null +++ b/eosio.system.abi @@ -0,0 +1,37 @@ +{ + "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/eosio.system.cpp b/eosio.system.cpp new file mode 100644 index 00000000..55849533 --- /dev/null +++ b/eosio.system.cpp @@ -0,0 +1,52 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ + +#include + +namespace eosiosystem { + using namespace eosio; + + /// When storing accounts, check for empty balance and remove account + void store_account( account_name account_to_store, const account& a ) { + /// value, scope + accounts::store( a, account_to_store ); + } + + void on( const eosiosystem::transfer& transfer_msg ) { + require_recipient( transfer_msg.to, transfer_msg.from ); + require_auth( transfer_msg.from ); + + auto from = get_account( transfer_msg.from ); + auto to = get_account( transfer_msg.to ); + + from.balance -= transfer_msg.quantity; /// token subtraction has underflow assertion + to.balance += transfer_msg.quantity; /// token addition has overflow assertion + + store_account( transfer_msg.from, from ); + store_account( transfer_msg.to, to ); + } + + void init() { + // TODO verify that + //store_account( system_name, account( native_tokens(1000ll*1000ll*1000ll) ) ); + } + +} // namespace eosiosystem + +using namespace eosiosystem; + +extern "C" { + + /// The apply method implements the dispatch of events to this contract + void apply( uint64_t code, uint64_t action ) { + if( code == system_code ) { + if( action == N(init) ) { + init(); + } else if( action == N(transfer) ) { + on( current_action< eosiosystem::transfer >() ); + } + } + } +} diff --git a/eosio.system.hpp b/eosio.system.hpp new file mode 100644 index 00000000..baf16533 --- /dev/null +++ b/eosio.system.hpp @@ -0,0 +1,116 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ + +#include +#include +#include + +namespace eosiosystem { + + /** + * @defgroup eosio.system EOSIO System Contract + * @brief Defines the wasm components of the system contract + * + * @{ + */ + + /** + * We create the native EOSIO token type + */ + typedef eosio::token native_tokens; + const account_name system_code = N(eosio.system); + const table_name account_table = N(account); + + /** + * transfer requires that the sender and receiver be the first two + * accounts notified and that the sender has provided authorization. + * @abi action + */ + struct transfer { + /** + * account to transfer from + */ + account_name from; + /** + * account to transfer to + */ + account_name to; + /** + * quantity to transfer + */ + native_tokens quantity; + }; + + + + /** + * @brief row in account table stored within each scope + * @abi table + */ + struct account { + /** + Constructor with default zero quantity (balance). + */ + account( native_tokens b = native_tokens() ):balance(b){} + + /** + * The key is constant because there is only one record per scope/currency/accounts + */ + const uint64_t key = N(account); + + /** + * Balance number of tokens in account + **/ + native_tokens balance; + native_tokens vote_stake; + native_tokens proxied_vote_stake; + uint64_t last_vote_weight = 0; + //time_point last_stake_withdraw; + account_name proxy; + + + /** + Method to check if accoutn is empty. + @return true if account balance is zero. + **/ + bool is_empty()const { return balance.quantity == 0; } + }; + + struct producer { + account_name key; /// producer name + uint64_t votes; /// total votes received by producer + /// producer config... + }; + + struct producer_vote { + account_name voter; + account_name producer; + uint64_t voteweight = 0; + }; + + /** + Defines the database table for account information + **/ + using accounts = eosio::table; + + /** + * accounts information for owner is stored: + * + * owner/TOKEN_NAME/account/account -> account + * + * This API is made available for 3rd parties wanting read access to + * the users balance. If the account doesn't exist a default constructed + * account will be returned. + * @param owner The account owner + * @return account instance + */ + inline account get_account( account_name owner ) { + account owned_account; + /// scope, record + accounts::get( owned_account, owner ); + return owned_account; + } + +} /// @} /// currencyapi From 7822198a77f2aac8e248d4bb637e3c091182c0b6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 5 Jan 2018 18:23:03 -0500 Subject: [PATCH 0002/1048] updates to eoslib to support reflection and seralization --- eosio.system.cpp | 56 ++++++++++++++++++++++++++++++++++-------------- eosio.system.hpp | 33 ++++++++++++++++++++++++---- 2 files changed, 69 insertions(+), 20 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 55849533..17f234d9 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -4,33 +4,57 @@ */ #include +#include namespace eosiosystem { using namespace eosio; - /// When storing accounts, check for empty balance and remove account - void store_account( account_name account_to_store, const account& a ) { - /// value, scope - accounts::store( a, account_to_store ); + typedef eosio::singleton account_single; + + void on( const eosiosystem::transfer& act ) { + require_recipient( act.to, act.from ); + require_auth( act.from ); + + auto from = account_single::get_or_create( act.from ); + auto to = account_single::get_or_create( act.to ); + + from.balance -= act.quantity; /// token subtraction has underflow assertion + to.balance += act.quantity; /// token addition has overflow assertion + + account_single::set( act.from, from ); + account_single::set( act.to, to ); } - void on( const eosiosystem::transfer& transfer_msg ) { - require_recipient( transfer_msg.to, transfer_msg.from ); - require_auth( transfer_msg.from ); + void on( const eosiosystem::stakevote& act ) { + require_recipient( act.to, act.from ); + require_auth( act.from ); + + auto from = account_single::get_or_create( act.from ); + from.balance -= act.quantity; /// token subtraction has underflow assertion + account_single::set( act.from, from ); - auto from = get_account( transfer_msg.from ); - auto to = get_account( transfer_msg.to ); + auto to = account_single::get_or_create( act.to ); + to.vote_stake += act.quantity; /// token addition has overflow assertion + account_single::set( act.to, to ); - from.balance -= transfer_msg.quantity; /// token subtraction has underflow assertion - to.balance += transfer_msg.quantity; /// token addition has overflow assertion + /// TODO: iterate over all producer votes on act.to + /* + producer_vote current; + if( producer_votes::by_voter::front( current ) ) { + do { - store_account( transfer_msg.from, from ); - store_account( transfer_msg.to, to ); + } while ( producer_votes::by_voter::next( current ) ); + } + */ + } void init() { - // TODO verify that - //store_account( system_name, account( native_tokens(1000ll*1000ll*1000ll) ) ); + assert( !account_single::exists( system_code ), "contract already initialized" ) ; + + account system; + system.balance = native_tokens( 1000ll*1000ll*1000ll ); + account_single::set( system_code, system ); } } // namespace eosiosystem @@ -45,7 +69,7 @@ extern "C" { if( action == N(init) ) { init(); } else if( action == N(transfer) ) { - on( current_action< eosiosystem::transfer >() ); + on( unpack_action() ); } } } diff --git a/eosio.system.hpp b/eosio.system.hpp index baf16533..6fa30e5b 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -6,6 +6,7 @@ #include #include #include +#include namespace eosiosystem { @@ -13,7 +14,6 @@ namespace eosiosystem { * @defgroup eosio.system EOSIO System Contract * @brief Defines the wasm components of the system contract * - * @{ */ /** @@ -44,10 +44,29 @@ namespace eosiosystem { }; + /** + * This will transfer tokens from from.balance to to.vote_stake + */ + struct stakevote { + account_name from; + account_name to; + native_tokens quantity; + }; + + /** - * @brief row in account table stored within each scope - * @abi table + * This table is used to track an individual user's token balance and vote stake. + * + * + * Location: + * + * { + * code: system_code + * scope: ${owner_account_name} + * table: N(singlton) + * key: N(account) + * } */ struct account { /** @@ -78,6 +97,8 @@ namespace eosiosystem { bool is_empty()const { return balance.quantity == 0; } }; + + struct producer { account_name key; /// producer name uint64_t votes; /// total votes received by producer @@ -113,4 +134,8 @@ namespace eosiosystem { return owned_account; } -} /// @} /// currencyapi +} /// eosiosystem + +EOSLIB_REFLECT( eosiosystem::account, (balance)(vote_stake)(proxied_vote_stake)(last_vote_weight)(proxy) ) +EOSLIB_REFLECT( eosiosystem::transfer, (from)(to)(quantity) ) +EOSLIB_REFLECT( eosiosystem::stakevote, (from)(to)(quantity) ) From ecc1906e6f620cd2e650145e41ec9311bed4bec6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 9 Jan 2018 17:32:42 -0500 Subject: [PATCH 0003/1048] progress on bancor --- eosio.system.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index 6fa30e5b..af2dac9b 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -43,6 +43,10 @@ namespace eosiosystem { native_tokens quantity; }; + struct transfer_memo : public transfer { + string memo; + }; + /** * This will transfer tokens from from.balance to to.vote_stake From 1c8564966de55bbe2d0931057493203e85b61447 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 23 Jan 2018 09:21:05 -0500 Subject: [PATCH 0004/1048] add_wast_executable and add_wast_library macros in CMake, paramters for llvm, stltest that works --- CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 22ecb154..350b21f0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,3 +1,8 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) -add_wast_target(eosio.system "${CMAKE_SOURCE_DIR}/contracts" ${CMAKE_CURRENT_BINARY_DIR}) + +add_wast_executable(TARGET eosio.system + INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" + LIBRARIES eoslib + DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} +) From 4c940999cf27836e20658c89d2d097707fda95e7 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 26 Jan 2018 11:55:18 -0500 Subject: [PATCH 0005/1048] Defining helper macros to simplify code. --- eosio.system.hpp | 130 ----------------------------------------------- 1 file changed, 130 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index af2dac9b..b2cafe14 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -10,136 +10,6 @@ namespace eosiosystem { - /** - * @defgroup eosio.system EOSIO System Contract - * @brief Defines the wasm components of the system contract - * - */ - - /** - * We create the native EOSIO token type - */ - typedef eosio::token native_tokens; - const account_name system_code = N(eosio.system); - const table_name account_table = N(account); - - /** - * transfer requires that the sender and receiver be the first two - * accounts notified and that the sender has provided authorization. - * @abi action - */ - struct transfer { - /** - * account to transfer from - */ - account_name from; - /** - * account to transfer to - */ - account_name to; - /** - * quantity to transfer - */ - native_tokens quantity; - }; - - struct transfer_memo : public transfer { - string memo; - }; - - - /** - * This will transfer tokens from from.balance to to.vote_stake - */ - struct stakevote { - account_name from; - account_name to; - native_tokens quantity; - }; - - - - /** - * This table is used to track an individual user's token balance and vote stake. - * - * - * Location: - * - * { - * code: system_code - * scope: ${owner_account_name} - * table: N(singlton) - * key: N(account) - * } - */ - struct account { - /** - Constructor with default zero quantity (balance). - */ - account( native_tokens b = native_tokens() ):balance(b){} - - /** - * The key is constant because there is only one record per scope/currency/accounts - */ - const uint64_t key = N(account); - - /** - * Balance number of tokens in account - **/ - native_tokens balance; - native_tokens vote_stake; - native_tokens proxied_vote_stake; - uint64_t last_vote_weight = 0; - //time_point last_stake_withdraw; - account_name proxy; - - - /** - Method to check if accoutn is empty. - @return true if account balance is zero. - **/ - bool is_empty()const { return balance.quantity == 0; } - }; - - - - struct producer { - account_name key; /// producer name - uint64_t votes; /// total votes received by producer - /// producer config... - }; - - struct producer_vote { - account_name voter; - account_name producer; - uint64_t voteweight = 0; - }; - - /** - Defines the database table for account information - **/ - using accounts = eosio::table; - - /** - * accounts information for owner is stored: - * - * owner/TOKEN_NAME/account/account -> account - * - * This API is made available for 3rd parties wanting read access to - * the users balance. If the account doesn't exist a default constructed - * account will be returned. - * @param owner The account owner - * @return account instance - */ - inline account get_account( account_name owner ) { - account owned_account; - /// scope, record - accounts::get( owned_account, owner ); - return owned_account; - } } /// eosiosystem -EOSLIB_REFLECT( eosiosystem::account, (balance)(vote_stake)(proxied_vote_stake)(last_vote_weight)(proxy) ) -EOSLIB_REFLECT( eosiosystem::transfer, (from)(to)(quantity) ) -EOSLIB_REFLECT( eosiosystem::stakevote, (from)(to)(quantity) ) From 4a8a2b3ba9e5e6e14f976967d6924e49e6bc7573 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 26 Jan 2018 14:43:13 -0500 Subject: [PATCH 0006/1048] remove raw pack/unpack and switch to operators --- eosio.system.cpp | 64 ++---------------------------------------------- eosio.system.hpp | 44 ++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 63 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 17f234d9..d228a833 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -4,73 +4,13 @@ */ #include -#include - -namespace eosiosystem { - using namespace eosio; - - typedef eosio::singleton account_single; - - void on( const eosiosystem::transfer& act ) { - require_recipient( act.to, act.from ); - require_auth( act.from ); - - auto from = account_single::get_or_create( act.from ); - auto to = account_single::get_or_create( act.to ); - - from.balance -= act.quantity; /// token subtraction has underflow assertion - to.balance += act.quantity; /// token addition has overflow assertion - - account_single::set( act.from, from ); - account_single::set( act.to, to ); - } - - void on( const eosiosystem::stakevote& act ) { - require_recipient( act.to, act.from ); - require_auth( act.from ); - - auto from = account_single::get_or_create( act.from ); - from.balance -= act.quantity; /// token subtraction has underflow assertion - account_single::set( act.from, from ); - - auto to = account_single::get_or_create( act.to ); - to.vote_stake += act.quantity; /// token addition has overflow assertion - account_single::set( act.to, to ); - - /// TODO: iterate over all producer votes on act.to - /* - producer_vote current; - if( producer_votes::by_voter::front( current ) ) { - do { - - } while ( producer_votes::by_voter::next( current ) ); - } - */ - - } - - void init() { - assert( !account_single::exists( system_code ), "contract already initialized" ) ; - - account system; - system.balance = native_tokens( 1000ll*1000ll*1000ll ); - account_single::set( system_code, system ); - } - -} // namespace eosiosystem using namespace eosiosystem; extern "C" { /// The apply method implements the dispatch of events to this contract - void apply( uint64_t code, uint64_t action ) { - if( code == system_code ) { - if( action == N(init) ) { - init(); - } else if( action == N(transfer) ) { - on( unpack_action() ); - } - } + void apply( uint64_t code, uint64_t act ) { + eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index b2cafe14..2f28a8bc 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -2,14 +2,56 @@ * @file * @copyright defined in eos/LICENSE.txt */ - #include #include #include #include +#include +#include +#include + namespace eosiosystem { + template + class contract { + public: + static const account_name system_account = N(eosio.system); + typedef eosio::generic_currency< eosio::token > currency; + + ACTION( SystemAccount, regproducer ) { + account_name producer_to_register; + + EOSLIB_SERIALIZE( regproducer, (producer_to_register) ); + }; + + ACTION( SystemAccount, regproxy ) { + account_name proxy_to_register; + + EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ); + }; + + static void on( const regproducer& reg ) { + require_auth( reg.producer_to_register ); + } + + static void on( const regproxy& reg ) { + require_auth( reg.proxy_to_register ); + } + + + static void apply( account_name code, action_name act ) { + if( !eosio::dispatch( code, act) ) + { + assert( false, "received unexpected action" ); + } + } /// apply + }; } /// eosiosystem From b39b1caff62d711ed0f0b1ebd5378b057054a9e4 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Fri, 26 Jan 2018 17:29:40 -0600 Subject: [PATCH 0007/1048] Rename all remaining eos strings eosio. --- eosio.system.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2f28a8bc..5b3ec1fc 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -2,14 +2,14 @@ * @file * @copyright defined in eos/LICENSE.txt */ -#include -#include -#include -#include - -#include -#include -#include +#include +#include +#include +#include + +#include +#include +#include namespace eosiosystem { From 279b073b7d1904bc4126af592d0cc480feb01461 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Fri, 26 Jan 2018 17:29:40 -0600 Subject: [PATCH 0008/1048] Rename all remaining eos strings eosio. --- eosio.system.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2f28a8bc..5b3ec1fc 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -2,14 +2,14 @@ * @file * @copyright defined in eos/LICENSE.txt */ -#include -#include -#include -#include - -#include -#include -#include +#include +#include +#include +#include + +#include +#include +#include namespace eosiosystem { From 4d171c31194606d3d450f6b2b5919cddcd0584a8 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 30 Jan 2018 14:13:08 -0600 Subject: [PATCH 0009/1048] Moving to non-native transfer --- eosio.system.abi | 13 ++++++++++++- eosio.system.hpp | 12 ++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index c8d8e4b1..66592b7d 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -10,8 +10,16 @@ "fields": [ {"name":"from", "type":"account_name"}, {"name":"to", "type":"account_name"}, - {"name":"quantity", "type":"uint64"} + {"name":"quantity", "type":"asset"}, + {"name":"memo", "type":"string"} ] + },{ + "name": "issue", + "base": "", + "fields": [ + {"name":"to", "type":"account_name"}, + {"name":"quantity", "type":"asset"} + ] },{ "name": "account", "base": "", @@ -24,6 +32,9 @@ "actions": [{ "name": "transfer", "type": "transfer" + },{ + "name": "issue", + "type": "issue" } ], "tables": [{ diff --git a/eosio.system.hpp b/eosio.system.hpp index 2f28a8bc..3ee7b71f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -41,14 +41,10 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { - if( !eosio::dispatch( code, act) ) - { - assert( false, "received unexpected action" ); + if( !eosio::dispatch( code, act) ) { + if ( !eosio::dispatch( code, act ) ) { + assert( false, "received unexpected action" ); + } } } /// apply }; From d230b7c0181acaa050754bb4c1db4f8530783ac1 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Wed, 31 Jan 2018 09:19:30 -0600 Subject: [PATCH 0010/1048] Rename contracts/eosiolib/eos.hpp to eosio.hpp --- eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 5b3ec1fc..e87b4db2 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -2,7 +2,7 @@ * @file * @copyright defined in eos/LICENSE.txt */ -#include +#include #include #include #include From cb38c382c673f0178b24c132d550d6b9eb0e1e3d Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 31 Jan 2018 18:25:02 -0500 Subject: [PATCH 0011/1048] start of updates to system contract --- eosio.system.hpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index 3ee7b71f..5d0ee243 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -19,6 +19,34 @@ namespace eosiosystem { static const account_name system_account = N(eosio.system); typedef eosio::generic_currency< eosio::token > currency; + struct total_bandwidth { + account_name owner; + typename currency::token_type total_net_weight; + typename currency::token_type total_cpu_weight; + }; + + typedef eosio::table64 total_bandwidth; + + struct delegated_bandwidth { + account_name from; + account_name to; + typename currency::token_type net_weight; + typename currency::token_type cpu_weight; + + uint32_t start_pending_net_withdraw = 0; + typename currency::token_type pending_net_withdraw; + uint64_t deferred_net_withdraw_handler = 0; + + uint32_t start_pending_cpu_withdraw = 0; + typename currency::token_type pending_cpu_withdraw; + uint64_t deferred_cpu_withdraw_handler = 0; + }; + + ACTION( SystemAccount, finshundel ) { + account_name from; + account_name to; + }; + ACTION( SystemAccount, regproducer ) { account_name producer_to_register; @@ -31,6 +59,29 @@ namespace eosiosystem { EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ); }; + ACTION( SystemAccount, delnetbw ) { + account_name from; + account_name receiver; + typename currency::token_type stake_quantity; + + EOSLIB_SERIALIZE( delnetbw, (delegator)(receiver)(stake_quantity) ) + }; + + ACTION( SystemAccount, undelnetbw ) { + account_name from; + account_name receiver; + typename currency::token_type stake_quantity; + + EOSLIB_SERIALIZE( delnetbw, (delegator)(receiver)(stake_quantity) ) + }; + + static void on( const delnetbw& del ) { + require_auth( del.from ); + // require_account( receiver ); + + currency::inline_transfer( del.from, SystemAccount, del.stake_quantity, "stake bandwidth" ); + } + static void on( const regproducer& reg ) { require_auth( reg.producer_to_register ); } From 269b95c77b60f6fb51409a209fbac425c602bc11 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 3 Feb 2018 21:41:42 -0600 Subject: [PATCH 0012/1048] Add nonce to eosio.system contract --- eosio.system.abi | 9 +++++++++ eosio.system.hpp | 16 +++++++++++++--- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 66592b7d..b67e3c8c 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -27,6 +27,12 @@ {"name":"key", "type":"name"}, {"name":"balance", "type":"uint64"} ] + },{ + "name": "nonce", + "base": "", + "fields": [ + {"name":"value", "type":"string"} + ] } ], "actions": [{ @@ -35,6 +41,9 @@ },{ "name": "issue", "type": "issue" + },{ + "name": "nonce", + "type": "nonce" } ], "tables": [{ diff --git a/eosio.system.hpp b/eosio.system.hpp index 916ebd70..da5abf39 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -75,7 +76,13 @@ namespace eosiosystem { EOSLIB_SERIALIZE( delnetbw, (delegator)(receiver)(stake_quantity) ) }; - static void on( const delnetbw& del ) { + ACTION( SystemAccount, nonce ) { + eosio::string value; + + EOSLIB_SERIALIZE( nonce, (value) ); + }; + + static void on( const delnetbw& del ) { require_auth( del.from ); // require_account( receiver ); @@ -90,11 +97,14 @@ namespace eosiosystem { require_auth( reg.proxy_to_register ); } + static void on( const nonce& ) { + } static void apply( account_name code, action_name act ) { - if( !eosio::dispatch( code, act) ) { + if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { - assert( false, "received unexpected action" ); + eosio::print("Unexpected action: ", act, "\n"); + assert( false, "received unexpected action"); } } } /// apply From 53f2e6acdb5e3556abe6b3f19176615c67e08197 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 5 Feb 2018 11:34:33 -0600 Subject: [PATCH 0013/1048] Fix proxy contract for new eosio.system account --- eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index da5abf39..8b2ba378 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -102,7 +102,7 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { if( !eosio::dispatch( code, act) ) { - if ( !eosio::dispatch( code, act ) ) { + if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", act, "\n"); assert( false, "received unexpected action"); } From 2c67899c231a7c3cf39f1cd1f9a90c9bdc793944 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 5 Feb 2018 15:26:10 -0500 Subject: [PATCH 0014/1048] Added bta to FC_REFLECT. Fixed after merge build issues --- eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index da5abf39..e884e840 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -26,7 +26,7 @@ namespace eosiosystem { typename currency::token_type total_cpu_weight; }; - typedef eosio::table64 total_bandwidth; + typedef eosio::table64 total_bandwidth; struct delegated_bandwidth { account_name from; From 458f80a2e8d9b27b8d2589678b96c4d5718d3de9 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Thu, 8 Feb 2018 16:27:30 -0600 Subject: [PATCH 0015/1048] Add eos contract abi to eosio account abi --- eosio.system.abi | 6 +----- eosio.system.cpp | 2 +- eosio.system.hpp | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index b67e3c8c..8ae70972 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -1,9 +1,5 @@ { - "types": [{ - "new_type_name": "account_name", - "type": "name" - } - ], + "types": [], "structs": [{ "name": "transfer", "base": "", diff --git a/eosio.system.cpp b/eosio.system.cpp index d228a833..c2c3f2c7 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -11,6 +11,6 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t code, uint64_t act ) { - eosiosystem::contract::apply( code, act ); + eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index a5df9e05..606b8a51 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -17,7 +17,7 @@ namespace eosiosystem { template class contract { public: - static const account_name system_account = N(eosio.system); + static const account_name system_account = N(eosio); typedef eosio::generic_currency< eosio::token > currency; struct total_bandwidth { From fa0995d458f2f00b8b214764057e822c35ab975a Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 9 Feb 2018 08:55:33 -0600 Subject: [PATCH 0016/1048] Fix eosio.system name and nonce struct --- eosio.system.abi | 1 + eosio.system.cpp | 2 +- eosio.system.hpp | 7 ++++--- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 8ae70972..6dc3bc3e 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -27,6 +27,7 @@ "name": "nonce", "base": "", "fields": [ + {"name":"from", "type":"account_name"}, {"name":"value", "type":"string"} ] } diff --git a/eosio.system.cpp b/eosio.system.cpp index c2c3f2c7..ee50cc7e 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -11,6 +11,6 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t code, uint64_t act ) { - eosiosystem::contract::apply( code, act ); + eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index 606b8a51..1eccdafc 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -17,7 +17,7 @@ namespace eosiosystem { template class contract { public: - static const account_name system_account = N(eosio); + static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; struct total_bandwidth { @@ -77,9 +77,10 @@ namespace eosiosystem { }; ACTION( SystemAccount, nonce ) { + account_name from; eosio::string value; - EOSLIB_SERIALIZE( nonce, (value) ); + EOSLIB_SERIALIZE( nonce, (from)(value) ); }; static void on( const delnetbw& del ) { @@ -103,7 +104,7 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { - eosio::print("Unexpected action: ", act, "\n"); + eosio::print("Unexpected action: ", eosio::name(act), "\n"); eos_assert( false, "received unexpected action"); } } From 2f6757c242e8a0b98533037209548f1341115459 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 9 Feb 2018 09:43:09 -0600 Subject: [PATCH 0017/1048] Remove from attribute from nonce --- eosio.system.abi | 1 - eosio.system.hpp | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 6dc3bc3e..8ae70972 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -27,7 +27,6 @@ "name": "nonce", "base": "", "fields": [ - {"name":"from", "type":"account_name"}, {"name":"value", "type":"string"} ] } diff --git a/eosio.system.hpp b/eosio.system.hpp index 1eccdafc..8bcb2a62 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -77,10 +77,9 @@ namespace eosiosystem { }; ACTION( SystemAccount, nonce ) { - account_name from; eosio::string value; - EOSLIB_SERIALIZE( nonce, (from)(value) ); + EOSLIB_SERIALIZE( nonce, (value) ); }; static void on( const delnetbw& del ) { From 4ea5fe10f473ae267e6c414ce75d7b2a7c3a7eb3 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 9 Feb 2018 16:16:31 -0500 Subject: [PATCH 0018/1048] merge master, fix tests --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1bfb4683..a5484c10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,6 @@ configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" - LIBRARIES eosiolib + LIBRARIES libc++ libc eosiolib DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} ) From 9320f2cab54e70134700408a160b4bae6cf782c2 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 11 Feb 2018 15:58:43 -0500 Subject: [PATCH 0019/1048] migrate eosio.system to use multi_index --- CMakeLists.txt | 2 +- eosio.system.cpp | 2 +- eosio.system.hpp | 51 ++++++++++++++++++++++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a5484c10..d982b293 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system - INCLUDE_FOLDERS "${STANDARD_INCLUDE_FOLDERS}" + INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} /usr/local/include LIBRARIES libc++ libc eosiolib DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/eosio.system.cpp b/eosio.system.cpp index ee50cc7e..7095c039 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -11,6 +11,6 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t code, uint64_t act ) { - eosiosystem::contract::apply( code, act ); +// eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index 8bcb2a62..a9b57e38 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -11,6 +11,7 @@ #include #include #include +#include namespace eosiosystem { @@ -20,15 +21,20 @@ namespace eosiosystem { static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; + /* struct total_bandwidth { account_name owner; typename currency::token_type total_net_weight; typename currency::token_type total_cpu_weight; }; + */ - typedef eosio::table64 total_bandwidth; +// typedef eosio::table64 total_bandwidth; + + //eosio::multi_index< N(totalband), total_bandwidth > bandwidth_index; struct delegated_bandwidth { + uint64_t primary; account_name from; account_name to; typename currency::token_type net_weight; @@ -41,8 +47,19 @@ namespace eosiosystem { uint32_t start_pending_cpu_withdraw = 0; typename currency::token_type pending_cpu_withdraw; uint64_t deferred_cpu_withdraw_handler = 0; + + + uint64_t primary_key()const { return primary; } + uint128_t by_from_to()const { return (uint128_t(from)<<64) | to; } }; + + static eosio::multi_index< N(delband), delegated_bandwidth, + eosio::index_by<0, N(byfromto), delegated_bandwidth, + eosio::const_mem_fun > + > del_bandwidth_index; + + ACTION( SystemAccount, finshundel ) { account_name from; account_name to; @@ -65,6 +82,7 @@ namespace eosiosystem { account_name receiver; typename currency::token_type stake_quantity; + EOSLIB_SERIALIZE( delnetbw, (delegator)(receiver)(stake_quantity) ) }; @@ -82,31 +100,52 @@ namespace eosiosystem { EOSLIB_SERIALIZE( nonce, (value) ); }; - static void on( const delnetbw& del ) { + /// new id options: + // 1. hash + collision + // 2. incrementing count (key=> tablename + + void on( const delnetbw& del ) { require_auth( del.from ); // require_account( receiver ); + auto idx = del_bandwidth_index.template get_index(); + auto itr = idx.find( (uint128_t(del.from) << 64) | del.to ); + if( itr == idx.end() ) { + del_bandwidth_index.emplace( del.from, [&]( auto& dbo ){ + dbo.id = del_bandwidth_index.new_id( del.from ); + dbo.from = del.from; + dbo.to = del.to; + dbo.net_weight = del.stake_quantity; + }); + } + else { + del_bandwidth_index.update( *itr, del.from, [&]( auto& dbo ){ + dbo.net_weight = del.stake_quantity; + }); + } currency::inline_transfer( del.from, SystemAccount, del.stake_quantity, "stake bandwidth" ); } - static void on( const regproducer& reg ) { + void on( const regproducer& reg ) { require_auth( reg.producer_to_register ); } - static void on( const regproxy& reg ) { + void on( const regproxy& reg ) { require_auth( reg.proxy_to_register ); } - static void on( const nonce& ) { + void on( const nonce& ) { } - static void apply( account_name code, action_name act ) { + void apply( account_name code, action_name act ) { + /* if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eos_assert( false, "received unexpected action"); } } + */ } /// apply }; From f44d67ef3e7b950cf385dfd9ff0278b70e5c4fa8 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 12 Feb 2018 15:25:36 -0500 Subject: [PATCH 0020/1048] progress on eosio.system --- eosio.system.hpp | 47 +++++++++++++++++++++++++++++------------------ 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index a9b57e38..75ba11e8 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -21,20 +21,20 @@ namespace eosiosystem { static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; - /* struct total_bandwidth { account_name owner; typename currency::token_type total_net_weight; typename currency::token_type total_cpu_weight; + + uint64_t primary_key()const { return owner; } }; - */ -// typedef eosio::table64 total_bandwidth; - //eosio::multi_index< N(totalband), total_bandwidth > bandwidth_index; + /** + * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. + */ struct delegated_bandwidth { - uint64_t primary; account_name from; account_name to; typename currency::token_type net_weight; @@ -49,15 +49,12 @@ namespace eosiosystem { uint64_t deferred_cpu_withdraw_handler = 0; - uint64_t primary_key()const { return primary; } - uint128_t by_from_to()const { return (uint128_t(from)<<64) | to; } + uint64_t primary_key()const { return to; } }; - static eosio::multi_index< N(delband), delegated_bandwidth, - eosio::index_by<0, N(byfromto), delegated_bandwidth, - eosio::const_mem_fun > - > del_bandwidth_index; + typedef eosio::multi_index< N(totalband), total_bandwidth > total_bandwidth_index_type; + typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; ACTION( SystemAccount, finshundel ) { @@ -106,25 +103,39 @@ namespace eosiosystem { void on( const delnetbw& del ) { require_auth( del.from ); + + del_bandwidth_index_type del_index( SystemAccount, del.from ); + total_bandwidth_index_type total_index( SystemAccount, del.to ); // require_account( receiver ); - auto idx = del_bandwidth_index.template get_index(); - auto itr = idx.find( (uint128_t(del.from) << 64) | del.to ); - if( itr == idx.end() ) { - del_bandwidth_index.emplace( del.from, [&]( auto& dbo ){ - dbo.id = del_bandwidth_index.new_id( del.from ); + auto itr = del_index.find( del.to ); + if( itr == del_index.end() ) { + del_index.emplace( del.from, [&]( auto& dbo ){ dbo.from = del.from; dbo.to = del.to; dbo.net_weight = del.stake_quantity; }); } else { - del_bandwidth_index.update( *itr, del.from, [&]( auto& dbo ){ + del_index.update( *itr, del.from, [&]( auto& dbo ){ dbo.net_weight = del.stake_quantity; }); } + + auto tot_itr = total_index.find( del.to ); + if( tot_itr == total_index.end() ) { + total_index.emplace( del.from, [&]( auto& tot ) { + tot.owner = del.to; + tot.total_net_weight += del.stake_quantity; + }); + } else { + total_index.update( *tot_itr, 0, [&]( auto& tot ) { + tot.total_net_weight += del.stake_quantity; + }); + } + currency::inline_transfer( del.from, SystemAccount, del.stake_quantity, "stake bandwidth" ); - } + } // delnetbw void on( const regproducer& reg ) { require_auth( reg.producer_to_register ); From 43fc194ba1edc46ee80fc3b6a4e22d9f47d775b0 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 12 Feb 2018 16:39:06 -0500 Subject: [PATCH 0021/1048] rename eos_assert to eosio_assert, implement is_account() api, and move implementation from apply_context.hpp to .cpp --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d982b293..c8863aeb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system - INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} /usr/local/include + INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} ${Boost_INCLUDE_DIR} LIBRARIES libc++ libc eosiolib DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} ) From 442357e617f81128c8838f1300938356541e819c Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 12 Feb 2018 16:47:44 -0500 Subject: [PATCH 0022/1048] eosiolib/preprocessor removed, use one from system-wide boost instead --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d982b293..0f75591e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system - INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} /usr/local/include + INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} LIBRARIES libc++ libc eosiolib DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} ) From 956211710c01b82dc93b3636fdb63d37bf181e68 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 12 Feb 2018 18:16:38 -0500 Subject: [PATCH 0023/1048] fix errors migrating eos_assert to eosio_assert --- eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 75ba11e8..e307b270 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -153,7 +153,7 @@ namespace eosiosystem { if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); - eos_assert( false, "received unexpected action"); + eosio_assert( false, "received unexpected action"); } } */ From 2d20cd7fa3940e2511238c6baeb6c7137ec5b490 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Mon, 12 Feb 2018 19:13:39 -0500 Subject: [PATCH 0024/1048] fixes for eosiod_run_tests.py, maybe --- eosio.system.cpp | 2 +- eosio.system.hpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 7095c039..ee50cc7e 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -11,6 +11,6 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t code, uint64_t act ) { -// eosiosystem::contract::apply( code, act ); + eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index e307b270..42022efd 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -101,7 +101,7 @@ namespace eosiosystem { // 1. hash + collision // 2. incrementing count (key=> tablename - void on( const delnetbw& del ) { + static void on( const delnetbw& del ) { require_auth( del.from ); del_bandwidth_index_type del_index( SystemAccount, del.from ); @@ -137,26 +137,26 @@ namespace eosiosystem { currency::inline_transfer( del.from, SystemAccount, del.stake_quantity, "stake bandwidth" ); } // delnetbw - void on( const regproducer& reg ) { + static void on( const regproducer& reg ) { require_auth( reg.producer_to_register ); } - void on( const regproxy& reg ) { + static void on( const regproxy& reg ) { require_auth( reg.proxy_to_register ); } - void on( const nonce& ) { + static void on( const nonce& ) { } - void apply( account_name code, action_name act ) { - /* + static void apply( account_name code, action_name act ) { + if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); } } - */ + } /// apply }; From 4570a559f1048d5667077a300276d4c8d9ebe659 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 13 Feb 2018 10:42:33 -0500 Subject: [PATCH 0025/1048] eosio.system del net bandwidth impl - fix bug with eosiolib/multi_index update --- eosio.system.hpp | 38 +++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 42022efd..655a4c7f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -12,6 +12,7 @@ #include #include #include +#include namespace eosiosystem { @@ -21,12 +22,15 @@ namespace eosiosystem { static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; - struct total_bandwidth { + struct total_resources { account_name owner; typename currency::token_type total_net_weight; typename currency::token_type total_cpu_weight; + uint32_t total_ram = 0; uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ); }; @@ -50,10 +54,15 @@ namespace eosiosystem { uint64_t primary_key()const { return to; } + + EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) + (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) + (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) ); + }; - typedef eosio::multi_index< N(totalband), total_bandwidth > total_bandwidth_index_type; + typedef eosio::multi_index< N(totalband), total_resources> total_resources_index_type; typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; @@ -80,7 +89,7 @@ namespace eosiosystem { typename currency::token_type stake_quantity; - EOSLIB_SERIALIZE( delnetbw, (delegator)(receiver)(stake_quantity) ) + EOSLIB_SERIALIZE( delnetbw, (from)(receiver)(stake_quantity) ) }; ACTION( SystemAccount, undelnetbw ) { @@ -105,14 +114,15 @@ namespace eosiosystem { require_auth( del.from ); del_bandwidth_index_type del_index( SystemAccount, del.from ); - total_bandwidth_index_type total_index( SystemAccount, del.to ); - // require_account( receiver ); + total_resources_index_type total_index( SystemAccount, del.receiver ); + + //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - auto itr = del_index.find( del.to ); - if( itr == del_index.end() ) { + auto itr = del_index.find( del.receiver); + if( itr != nullptr ) { del_index.emplace( del.from, [&]( auto& dbo ){ dbo.from = del.from; - dbo.to = del.to; + dbo.to = del.receiver; dbo.net_weight = del.stake_quantity; }); } @@ -122,10 +132,10 @@ namespace eosiosystem { }); } - auto tot_itr = total_index.find( del.to ); - if( tot_itr == total_index.end() ) { - total_index.emplace( del.from, [&]( auto& tot ) { - tot.owner = del.to; + auto tot_itr = total_index.find( del.receiver ); + if( tot_itr == nullptr ) { + tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { + tot.owner = del.receiver; tot.total_net_weight += del.stake_quantity; }); } else { @@ -134,6 +144,8 @@ namespace eosiosystem { }); } + set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); + currency::inline_transfer( del.from, SystemAccount, del.stake_quantity, "stake bandwidth" ); } // delnetbw @@ -150,7 +162,7 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { - if( !eosio::dispatch( code, act) ) { + if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); From ef1ce2075eec28243f09b0e9e870728716cdcf03 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 13 Feb 2018 11:58:18 -0500 Subject: [PATCH 0026/1048] add get() helper to multiindex, implement unstake bandwidth --- eosio.system.hpp | 83 ++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 69 insertions(+), 14 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 655a4c7f..f1b07ced 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -83,21 +83,23 @@ namespace eosiosystem { EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ); }; - ACTION( SystemAccount, delnetbw ) { + ACTION( SystemAccount, delegatebw ) { account_name from; account_name receiver; - typename currency::token_type stake_quantity; + typename currency::token_type stake_net_quantity; + typename currency::token_type stake_cpu_quantity; - EOSLIB_SERIALIZE( delnetbw, (from)(receiver)(stake_quantity) ) + EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity) ) }; - ACTION( SystemAccount, undelnetbw ) { + ACTION( SystemAccount, undelegatebw ) { account_name from; account_name receiver; - typename currency::token_type stake_quantity; + typename currency::token_type unstake_net_quantity; + typename currency::token_type unstake_cpu_quantity; - EOSLIB_SERIALIZE( delnetbw, (delegator)(receiver)(stake_quantity) ) + EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) ) }; ACTION( SystemAccount, nonce ) { @@ -110,7 +112,14 @@ namespace eosiosystem { // 1. hash + collision // 2. incrementing count (key=> tablename - static void on( const delnetbw& del ) { + static void on( const delegatebw& del ) { + eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); + eosio_assert( del.stake_net_quantity.quantity >= 0, "must stake a positive amount" ); + + auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity; + eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); + + require_auth( del.from ); del_bandwidth_index_type del_index( SystemAccount, del.from ); @@ -123,12 +132,14 @@ namespace eosiosystem { del_index.emplace( del.from, [&]( auto& dbo ){ dbo.from = del.from; dbo.to = del.receiver; - dbo.net_weight = del.stake_quantity; + dbo.net_weight = del.stake_net_quantity; + dbo.cpu_weight = del.stake_cpu_quantity; }); } else { del_index.update( *itr, del.from, [&]( auto& dbo ){ - dbo.net_weight = del.stake_quantity; + dbo.net_weight = del.stake_net_quantity; + dbo.cpu_weight = del.stake_cpu_quantity; }); } @@ -136,18 +147,62 @@ namespace eosiosystem { if( tot_itr == nullptr ) { tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { tot.owner = del.receiver; - tot.total_net_weight += del.stake_quantity; + tot.total_net_weight += del.stake_net_quantity; + tot.total_cpu_weight += del.stake_cpu_quantity; }); } else { total_index.update( *tot_itr, 0, [&]( auto& tot ) { - tot.total_net_weight += del.stake_quantity; + tot.total_net_weight += del.stake_net_quantity; + tot.total_cpu_weight += del.stake_cpu_quantity; }); } set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); - currency::inline_transfer( del.from, SystemAccount, del.stake_quantity, "stake bandwidth" ); - } // delnetbw + currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); + } // delegatebw + + + + static void on( const undelegatebw& del ) { + eosio_assert( del.unstake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); + eosio_assert( del.unstake_net_quantity.quantity >= 0, "must stake a positive amount" ); + + auto total_stake = del.unstake_cpu_quantity + del.unstake_net_quantity; + eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); + + require_auth( del.from ); + + del_bandwidth_index_type del_index( SystemAccount, del.from ); + total_resources_index_type total_index( SystemAccount, del.receiver ); + + //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); + + const auto& dbw = del_index.get(del.receiver); + eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); + eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); + + del_index.update( dbw, del.from, [&]( auto& dbo ){ + dbo.net_weight -= del.unstake_net_quantity; + dbo.cpu_weight -= del.unstake_cpu_quantity; + + }); + + const auto& totals = total_index.get( del.receiver ); + total_index.update( totals, 0, [&]( auto& tot ) { + tot.total_net_weight -= del.unstake_net_quantity; + tot.total_cpu_weight -= del.unstake_cpu_quantity; + }); + + set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 ); + + /// TODO: implement / enforce time delays on withdrawing + currency::inline_transfer( SystemAccount, del.from, total_stake, "unstake bandwidth" ); + } // undelegatebw + + + + static void on( const regproducer& reg ) { require_auth( reg.producer_to_register ); @@ -162,7 +217,7 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { - if( !eosio::dispatch( code, act) ) { + if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); From e1446d5bc640b77929cded1b98e60b6dd3f37ace Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 13 Feb 2018 15:26:43 -0500 Subject: [PATCH 0027/1048] progress on system contract producer voting --- eosio.system.hpp | 177 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 173 insertions(+), 4 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index f1b07ced..e4419c96 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -14,13 +14,58 @@ #include #include +#include +#include + namespace eosiosystem { + using eosio::index_by; + using eosio::const_mem_fun; + using eosio::bytes; + using std::map; + using std::pair; template class contract { public: static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; + typedef typename currency::token_type system_token_type; + + struct producer_votes { + account_name owner; + uint128_t total_votes; + + uint64_t primary_key()const { return owner; } + uint128_t by_votes()const { return total_votes; } + + EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ); + }; + typedef eosio::multi_index< N(producervote), producer_votes, + index_by<0, N(prototalvote), producer_votes, const_mem_fun > + > producer_votes_index_type; + + struct account_votes { + account_name owner; + account_name proxy; + uint32_t last_update; + system_token_type staked; + std::vector producers; + + uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ); + }; + typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; + + + struct producer_config { + account_name owner; + eosio::bytes packed_key; /// a packed public key object + + uint64_t primary_key()const { return owner; } + EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ); + }; + typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; struct total_resources { account_name owner; @@ -34,7 +79,6 @@ namespace eosiosystem { }; - /** * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. */ @@ -73,8 +117,9 @@ namespace eosiosystem { ACTION( SystemAccount, regproducer ) { account_name producer_to_register; + bytes producer_key; - EOSLIB_SERIALIZE( regproducer, (producer_to_register) ); + EOSLIB_SERIALIZE( regproducer, (producer_to_register)(producer_key) ); }; ACTION( SystemAccount, regproxy ) { @@ -204,12 +249,132 @@ namespace eosiosystem { + /** + * This method will create a producr_config and producer_votes object for 'producer_to_register' + * + * @pre producer is not already registered + * @pre producer to register is an account + * @pre authority of producer to register + * + */ static void on( const regproducer& reg ) { - require_auth( reg.producer_to_register ); + auto producer = reg.producer_to_register; + require_auth( producer ); + + producer_votes_index_type votes( SystemAccount, SystemAccount ); + const auto* existing = votes.find( producer ); + eosio_assert( !existing, "producer already registered" ); + + votes.emplace( producer, [&]( auto& pv ){ + pv.owner = producer; + pv.total_votes = 0; + }); + + producer_config_index_type proconfig( SystemAccount, SystemAccount ); + proconfig.emplace( producer, [&]( auto& pc ) { + pc.owner = producer; + pc.packed_key = reg.producer_key; + }); + } + + ACTION( SystemAccount, stakevote ) { + account_name voter; + system_token_type amount_to_stake; + + EOSLIB_SERIALIZE( stakevote, (voter)(amount_to_stake) ) + }; + + static void on( const stakevote& sv ) { + eosio_assert( sv.amount_to_stake.quantity > 0, "must stake some tokens" ); + require_auth( sv.voter ); + + account_votes_index_type avotes( SystemAccount, SystemAccount ); + + const auto* acv = avotes.find( sv.voter ); + if( !acv ) { + acv = &avotes.emplace( sv.voter, [&]( auto& av ) { + av.owner = sv.voter; + av.last_update = now(); + av.proxy = 0; + }); + } + + uint128_t old_weight = acv->staked.quantity; + uint128_t new_weight = old_weight + sv.amount_to_stake.quantity; + + producer_votes_index_type votes( SystemAccount, SystemAccount ); + + for( auto p : acv->producers ) { + votes.update( votes.get( p ), 0, [&]( auto& v ) { + v.total_votes -= old_weight; + v.total_votes += new_weight; + }); + } + + avotes.update( *acv, 0, [&]( auto av ) { + av.last_update = now(); + av.staked += sv.amount_to_stake; + }); + + currency::inline_transfer( sv.voter, SystemAccount, sv.amount_to_stake, "stake for voting" ); + }; + + ACTION( SystemAccount, voteproducer ) { + account_name voter; + account_name proxy; + std::vector producers; + + EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) + }; + + /** + * @pre vp.producers must be sorted from lowest to highest + * @pre if proxy is set then no producers can be voted for + * @pre every listed producer or proxy must have been previously registered + * @pre vp.voter must authorize this action + * @pre voter must have previously staked some EOS for voting + */ + static void on( const voteproducer& vp ) { + eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); + eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); + if( vp.proxy != 0 ) eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); + + require_auth( vp.voter ); + + account_votes_index_type avotes( SystemAccount, SystemAccount ); + const auto& existing = avotes.get( vp.voter ); + + std::map > producer_vote_changes; + + uint128_t old_weight = existing.staked.quantity; /// old time + uint128_t new_weight = old_weight; /// TODO: update for current weight + + for( const auto& p : existing.producers ) + producer_vote_changes[p].first = old_weight; + for( const auto& p : vp.producers ) + producer_vote_changes[p].second = new_weight; + + producer_votes_index_type votes( SystemAccount, SystemAccount ); + for( const auto& delta : producer_vote_changes ) { + if( delta.second.first != delta.second.second ) { + const auto& provote = votes.get( delta.first ); + votes.update( provote, 0, [&]( auto& pv ){ + pv.total_votes -= delta.second.first; + pv.total_votes += delta.second.second; + }); + } + } + + avotes.update( existing, 0, [&]( auto& av ) { + av.proxy = vp.proxy; + av.last_update = now(); + av.producers = vp.producers; + }); } static void on( const regproxy& reg ) { require_auth( reg.proxy_to_register ); + } static void on( const nonce& ) { @@ -217,7 +382,11 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { - if( !eosio::dispatch( code, act) ) { + if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); From ea954138fc767b947abffd85d4df47824f09a9bb Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 13 Feb 2018 18:21:26 -0500 Subject: [PATCH 0028/1048] progress testing system --- eosio.system.abi | 23 ++++++++++++++++++++++- eosio.system.cpp | 1 + eosio.system.hpp | 23 +++++++++++++---------- 3 files changed, 36 insertions(+), 11 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 8ae70972..41278cf6 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -29,7 +29,22 @@ "fields": [ {"name":"value", "type":"string"} ] + },{ + "name": "regproducer", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"} + {"name":"producer_key", "type":"bytes"} + ] + },{ + "name": "stakevote", + "base": "", + "fields": [ + {"name":"voter", "type":"account_name"} + {"name":"amount", "type":"asset"} + ] } + ], "actions": [{ "name": "transfer", @@ -40,6 +55,12 @@ },{ "name": "nonce", "type": "nonce" + },{ + "name": "regproducer", + "type": "regproducer" + },{ + "name": "stakevote", + "type": "stakevote" } ], "tables": [{ @@ -50,4 +71,4 @@ "key_types" : ["name"] } ] -} \ No newline at end of file +} diff --git a/eosio.system.cpp b/eosio.system.cpp index ee50cc7e..de631628 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -11,6 +11,7 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t code, uint64_t act ) { + print( name(code), "::", name(act) ); eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index e4419c96..834d37a3 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -23,6 +23,7 @@ namespace eosiosystem { using eosio::bytes; using std::map; using std::pair; + using eosio::print; template class contract { @@ -116,10 +117,10 @@ namespace eosiosystem { }; ACTION( SystemAccount, regproducer ) { - account_name producer_to_register; + account_name producer; bytes producer_key; - EOSLIB_SERIALIZE( regproducer, (producer_to_register)(producer_key) ); + EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) ); }; ACTION( SystemAccount, regproxy ) { @@ -250,7 +251,7 @@ namespace eosiosystem { /** - * This method will create a producr_config and producer_votes object for 'producer_to_register' + * This method will create a producr_config and producer_votes object for 'producer' * * @pre producer is not already registered * @pre producer to register is an account @@ -258,7 +259,7 @@ namespace eosiosystem { * */ static void on( const regproducer& reg ) { - auto producer = reg.producer_to_register; + auto producer = reg.producer; require_auth( producer ); producer_votes_index_type votes( SystemAccount, SystemAccount ); @@ -279,14 +280,16 @@ namespace eosiosystem { ACTION( SystemAccount, stakevote ) { account_name voter; - system_token_type amount_to_stake; + system_token_type amount; - EOSLIB_SERIALIZE( stakevote, (voter)(amount_to_stake) ) + EOSLIB_SERIALIZE( stakevote, (voter)(amount) ) }; static void on( const stakevote& sv ) { - eosio_assert( sv.amount_to_stake.quantity > 0, "must stake some tokens" ); + print( "on stake vote\n" ); + eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); require_auth( sv.voter ); + return; account_votes_index_type avotes( SystemAccount, SystemAccount ); @@ -300,7 +303,7 @@ namespace eosiosystem { } uint128_t old_weight = acv->staked.quantity; - uint128_t new_weight = old_weight + sv.amount_to_stake.quantity; + uint128_t new_weight = old_weight + sv.amount.quantity; producer_votes_index_type votes( SystemAccount, SystemAccount ); @@ -313,10 +316,10 @@ namespace eosiosystem { avotes.update( *acv, 0, [&]( auto av ) { av.last_update = now(); - av.staked += sv.amount_to_stake; + av.staked += sv.amount; }); - currency::inline_transfer( sv.voter, SystemAccount, sv.amount_to_stake, "stake for voting" ); + // currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); }; ACTION( SystemAccount, voteproducer ) { From 9e65efb86f27c8c75aabad88df79c29883f2ade2 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 13 Feb 2018 20:31:15 -0500 Subject: [PATCH 0029/1048] fix currency permission for inline transfer --- eosio.system.cpp | 2 +- eosio.system.hpp | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index de631628..7d905ff0 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -11,7 +11,7 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t code, uint64_t act ) { - print( name(code), "::", name(act) ); + print( eosio::name(code), "::", eosio::name(act) ); eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index 834d37a3..2745e32f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -289,7 +289,6 @@ namespace eosiosystem { print( "on stake vote\n" ); eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); require_auth( sv.voter ); - return; account_votes_index_type avotes( SystemAccount, SystemAccount ); @@ -319,7 +318,7 @@ namespace eosiosystem { av.staked += sv.amount; }); - // currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); + currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); }; ACTION( SystemAccount, voteproducer ) { From 440fa28f6f964dab6e293d4b990b0367c45f1679 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 18 Feb 2018 17:00:29 -0500 Subject: [PATCH 0030/1048] Cleanup API for EOSIO MultiIndex 1. no longer need to specify index number 2. no longer need to specify type multiple times 3. clean up unnecessary references 4. remove member variables that are not needed 5. implement store for index 6. implement find iterator for secondary given primary key --- eosio.system.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2745e32f..0fbe8c52 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -18,7 +18,7 @@ #include namespace eosiosystem { - using eosio::index_by; + using eosio::indexed_by; using eosio::const_mem_fun; using eosio::bytes; using std::map; @@ -42,7 +42,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ); }; typedef eosio::multi_index< N(producervote), producer_votes, - index_by<0, N(prototalvote), producer_votes, const_mem_fun > + indexed_by > > producer_votes_index_type; struct account_votes { From 3d4edab14db6bc97cb3d4a6632b2f6dbdcd85041 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 19 Feb 2018 16:41:32 -0500 Subject: [PATCH 0031/1048] fix warnings in many contracts --- eosio.system.hpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 0fbe8c52..9080da09 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -34,12 +34,13 @@ namespace eosiosystem { struct producer_votes { account_name owner; + uint64_t padding = 0; uint128_t total_votes; uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } - EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ); + EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ) }; typedef eosio::multi_index< N(producervote), producer_votes, indexed_by > @@ -54,7 +55,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ); + EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ) }; typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; @@ -64,7 +65,7 @@ namespace eosiosystem { eosio::bytes packed_key; /// a packed public key object uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ); + EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) }; typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; @@ -76,7 +77,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ); + EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ) }; @@ -102,7 +103,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) - (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) ); + (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) ) }; @@ -120,13 +121,13 @@ namespace eosiosystem { account_name producer; bytes producer_key; - EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) ); + EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) ) }; ACTION( SystemAccount, regproxy ) { account_name proxy_to_register; - EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ); + EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ) }; ACTION( SystemAccount, delegatebw ) { @@ -151,7 +152,7 @@ namespace eosiosystem { ACTION( SystemAccount, nonce ) { eosio::string value; - EOSLIB_SERIALIZE( nonce, (value) ); + EOSLIB_SERIALIZE( nonce, (value) ) }; /// new id options: @@ -319,7 +320,7 @@ namespace eosiosystem { }); currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); - }; + } ACTION( SystemAccount, voteproducer ) { account_name voter; From 385cf93304a630921bcbb2417fb48a98b9d7fd88 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 21 Feb 2018 15:56:31 -0500 Subject: [PATCH 0032/1048] system contract split into 2 parts #1455 --- delegate_bandwith.hpp | 189 ++++++++++++++++++++ eosio.system.hpp | 383 ++--------------------------------------- producers_election.hpp | 212 +++++++++++++++++++++++ 3 files changed, 417 insertions(+), 367 deletions(-) create mode 100644 delegate_bandwith.hpp create mode 100644 producers_election.hpp diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp new file mode 100644 index 00000000..29922f96 --- /dev/null +++ b/delegate_bandwith.hpp @@ -0,0 +1,189 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + +namespace eosiosystem { + using eosio::indexed_by; + using eosio::const_mem_fun; + using eosio::bytes; + using eosio::print; + using std::map; + using std::pair; + + template + class delegate_bandwith { + public: + static const account_name system_account = SystemAccount; + typedef eosio::generic_currency< eosio::token > currency; + typedef typename currency::token_type system_token_type; + + struct total_resources { + account_name owner; + typename currency::token_type total_net_weight; + typename currency::token_type total_cpu_weight; + uint32_t total_ram = 0; + + uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ) + }; + + + /** + * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. + */ + struct delegated_bandwidth { + account_name from; + account_name to; + typename currency::token_type net_weight; + typename currency::token_type cpu_weight; + + uint32_t start_pending_net_withdraw = 0; + typename currency::token_type pending_net_withdraw; + uint64_t deferred_net_withdraw_handler = 0; + + uint32_t start_pending_cpu_withdraw = 0; + typename currency::token_type pending_cpu_withdraw; + uint64_t deferred_cpu_withdraw_handler = 0; + + + uint64_t primary_key()const { return to; } + + EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) + (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) + (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) ) + + }; + + typedef eosio::multi_index< N(totalband), total_resources> total_resources_index_type; + typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; + + ACTION( SystemAccount, finshundel ) { + account_name from; + account_name to; + }; + + ACTION( SystemAccount, delegatebw ) { + account_name from; + account_name receiver; + typename currency::token_type stake_net_quantity; + typename currency::token_type stake_cpu_quantity; + + + EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity) ) + }; + + ACTION( SystemAccount, undelegatebw ) { + account_name from; + account_name receiver; + typename currency::token_type unstake_net_quantity; + typename currency::token_type unstake_cpu_quantity; + + EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) ) + }; + + /// new id options: + // 1. hash + collision + // 2. incrementing count (key=> tablename + + static void on( const delegatebw& del ) { + eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); + eosio_assert( del.stake_net_quantity.quantity >= 0, "must stake a positive amount" ); + + auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity; + eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); + + + require_auth( del.from ); + + del_bandwidth_index_type del_index( SystemAccount, del.from ); + total_resources_index_type total_index( SystemAccount, del.receiver ); + + //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); + + auto itr = del_index.find( del.receiver); + if( itr != nullptr ) { + del_index.emplace( del.from, [&]( auto& dbo ){ + dbo.from = del.from; + dbo.to = del.receiver; + dbo.net_weight = del.stake_net_quantity; + dbo.cpu_weight = del.stake_cpu_quantity; + }); + } + else { + del_index.update( *itr, del.from, [&]( auto& dbo ){ + dbo.net_weight = del.stake_net_quantity; + dbo.cpu_weight = del.stake_cpu_quantity; + }); + } + + auto tot_itr = total_index.find( del.receiver ); + if( tot_itr == nullptr ) { + tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { + tot.owner = del.receiver; + tot.total_net_weight += del.stake_net_quantity; + tot.total_cpu_weight += del.stake_cpu_quantity; + }); + } else { + total_index.update( *tot_itr, 0, [&]( auto& tot ) { + tot.total_net_weight += del.stake_net_quantity; + tot.total_cpu_weight += del.stake_cpu_quantity; + }); + } + + set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); + + currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); + } // delegatebw + + static void on( const undelegatebw& del ) { + eosio_assert( del.unstake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); + eosio_assert( del.unstake_net_quantity.quantity >= 0, "must stake a positive amount" ); + + auto total_stake = del.unstake_cpu_quantity + del.unstake_net_quantity; + eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); + + require_auth( del.from ); + + del_bandwidth_index_type del_index( SystemAccount, del.from ); + total_resources_index_type total_index( SystemAccount, del.receiver ); + + //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); + + const auto& dbw = del_index.get(del.receiver); + eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); + eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); + + del_index.update( dbw, del.from, [&]( auto& dbo ){ + dbo.net_weight -= del.unstake_net_quantity; + dbo.cpu_weight -= del.unstake_cpu_quantity; + + }); + + const auto& totals = total_index.get( del.receiver ); + total_index.update( totals, 0, [&]( auto& tot ) { + tot.total_net_weight -= del.unstake_net_quantity; + tot.total_cpu_weight -= del.unstake_cpu_quantity; + }); + + set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 ); + + /// TODO: implement / enforce time delays on withdrawing + currency::inline_transfer( SystemAccount, del.from, total_stake, "unstake bandwidth" ); + } // undelegatebw + }; +} diff --git a/eosio.system.hpp b/eosio.system.hpp index 9080da09..1a7a85a1 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -2,152 +2,25 @@ * @file * @copyright defined in eos/LICENSE.txt */ -#include -#include -#include -#include -#include +#pragma once -#include -#include -#include -#include -#include +#include "producers_election.hpp" +#include "delegate_bandwith.hpp" -#include -#include +#include namespace eosiosystem { - using eosio::indexed_by; - using eosio::const_mem_fun; - using eosio::bytes; - using std::map; - using std::pair; - using eosio::print; template - class contract { + class contract : public producers_election, public delegate_bandwith { public: + using producers_election::on; + using delegate_bandwith::on; + using pe = producers_election; + using db = delegate_bandwith; + static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; - typedef typename currency::token_type system_token_type; - - struct producer_votes { - account_name owner; - uint64_t padding = 0; - uint128_t total_votes; - - uint64_t primary_key()const { return owner; } - uint128_t by_votes()const { return total_votes; } - - EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ) - }; - typedef eosio::multi_index< N(producervote), producer_votes, - indexed_by > - > producer_votes_index_type; - - struct account_votes { - account_name owner; - account_name proxy; - uint32_t last_update; - system_token_type staked; - std::vector producers; - - uint64_t primary_key()const { return owner; } - - EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ) - }; - typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; - - - struct producer_config { - account_name owner; - eosio::bytes packed_key; /// a packed public key object - - uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) - }; - typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; - - struct total_resources { - account_name owner; - typename currency::token_type total_net_weight; - typename currency::token_type total_cpu_weight; - uint32_t total_ram = 0; - - uint64_t primary_key()const { return owner; } - - EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ) - }; - - - /** - * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. - */ - struct delegated_bandwidth { - account_name from; - account_name to; - typename currency::token_type net_weight; - typename currency::token_type cpu_weight; - - uint32_t start_pending_net_withdraw = 0; - typename currency::token_type pending_net_withdraw; - uint64_t deferred_net_withdraw_handler = 0; - - uint32_t start_pending_cpu_withdraw = 0; - typename currency::token_type pending_cpu_withdraw; - uint64_t deferred_cpu_withdraw_handler = 0; - - - uint64_t primary_key()const { return to; } - - EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) - (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) - (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) ) - - }; - - - typedef eosio::multi_index< N(totalband), total_resources> total_resources_index_type; - typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; - - - ACTION( SystemAccount, finshundel ) { - account_name from; - account_name to; - }; - - ACTION( SystemAccount, regproducer ) { - account_name producer; - bytes producer_key; - - EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) ) - }; - - ACTION( SystemAccount, regproxy ) { - account_name proxy_to_register; - - EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ) - }; - - ACTION( SystemAccount, delegatebw ) { - account_name from; - account_name receiver; - typename currency::token_type stake_net_quantity; - typename currency::token_type stake_cpu_quantity; - - - EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity) ) - }; - - ACTION( SystemAccount, undelegatebw ) { - account_name from; - account_name receiver; - typename currency::token_type unstake_net_quantity; - typename currency::token_type unstake_cpu_quantity; - - EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) ) - }; ACTION( SystemAccount, nonce ) { eosio::string value; @@ -155,240 +28,16 @@ namespace eosiosystem { EOSLIB_SERIALIZE( nonce, (value) ) }; - /// new id options: - // 1. hash + collision - // 2. incrementing count (key=> tablename - - static void on( const delegatebw& del ) { - eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); - eosio_assert( del.stake_net_quantity.quantity >= 0, "must stake a positive amount" ); - - auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity; - eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); - - - require_auth( del.from ); - - del_bandwidth_index_type del_index( SystemAccount, del.from ); - total_resources_index_type total_index( SystemAccount, del.receiver ); - - //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - - auto itr = del_index.find( del.receiver); - if( itr != nullptr ) { - del_index.emplace( del.from, [&]( auto& dbo ){ - dbo.from = del.from; - dbo.to = del.receiver; - dbo.net_weight = del.stake_net_quantity; - dbo.cpu_weight = del.stake_cpu_quantity; - }); - } - else { - del_index.update( *itr, del.from, [&]( auto& dbo ){ - dbo.net_weight = del.stake_net_quantity; - dbo.cpu_weight = del.stake_cpu_quantity; - }); - } - - auto tot_itr = total_index.find( del.receiver ); - if( tot_itr == nullptr ) { - tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { - tot.owner = del.receiver; - tot.total_net_weight += del.stake_net_quantity; - tot.total_cpu_weight += del.stake_cpu_quantity; - }); - } else { - total_index.update( *tot_itr, 0, [&]( auto& tot ) { - tot.total_net_weight += del.stake_net_quantity; - tot.total_cpu_weight += del.stake_cpu_quantity; - }); - } - - set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); - - currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); - } // delegatebw - - - - static void on( const undelegatebw& del ) { - eosio_assert( del.unstake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); - eosio_assert( del.unstake_net_quantity.quantity >= 0, "must stake a positive amount" ); - - auto total_stake = del.unstake_cpu_quantity + del.unstake_net_quantity; - eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); - - require_auth( del.from ); - - del_bandwidth_index_type del_index( SystemAccount, del.from ); - total_resources_index_type total_index( SystemAccount, del.receiver ); - - //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - - const auto& dbw = del_index.get(del.receiver); - eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); - eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); - - del_index.update( dbw, del.from, [&]( auto& dbo ){ - dbo.net_weight -= del.unstake_net_quantity; - dbo.cpu_weight -= del.unstake_cpu_quantity; - - }); - - const auto& totals = total_index.get( del.receiver ); - total_index.update( totals, 0, [&]( auto& tot ) { - tot.total_net_weight -= del.unstake_net_quantity; - tot.total_cpu_weight -= del.unstake_cpu_quantity; - }); - - set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 ); - - /// TODO: implement / enforce time delays on withdrawing - currency::inline_transfer( SystemAccount, del.from, total_stake, "unstake bandwidth" ); - } // undelegatebw - - - - - - /** - * This method will create a producr_config and producer_votes object for 'producer' - * - * @pre producer is not already registered - * @pre producer to register is an account - * @pre authority of producer to register - * - */ - static void on( const regproducer& reg ) { - auto producer = reg.producer; - require_auth( producer ); - - producer_votes_index_type votes( SystemAccount, SystemAccount ); - const auto* existing = votes.find( producer ); - eosio_assert( !existing, "producer already registered" ); - - votes.emplace( producer, [&]( auto& pv ){ - pv.owner = producer; - pv.total_votes = 0; - }); - - producer_config_index_type proconfig( SystemAccount, SystemAccount ); - proconfig.emplace( producer, [&]( auto& pc ) { - pc.owner = producer; - pc.packed_key = reg.producer_key; - }); - } - - ACTION( SystemAccount, stakevote ) { - account_name voter; - system_token_type amount; - - EOSLIB_SERIALIZE( stakevote, (voter)(amount) ) - }; - - static void on( const stakevote& sv ) { - print( "on stake vote\n" ); - eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); - require_auth( sv.voter ); - - account_votes_index_type avotes( SystemAccount, SystemAccount ); - - const auto* acv = avotes.find( sv.voter ); - if( !acv ) { - acv = &avotes.emplace( sv.voter, [&]( auto& av ) { - av.owner = sv.voter; - av.last_update = now(); - av.proxy = 0; - }); - } - - uint128_t old_weight = acv->staked.quantity; - uint128_t new_weight = old_weight + sv.amount.quantity; - - producer_votes_index_type votes( SystemAccount, SystemAccount ); - - for( auto p : acv->producers ) { - votes.update( votes.get( p ), 0, [&]( auto& v ) { - v.total_votes -= old_weight; - v.total_votes += new_weight; - }); - } - - avotes.update( *acv, 0, [&]( auto av ) { - av.last_update = now(); - av.staked += sv.amount; - }); - - currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); - } - - ACTION( SystemAccount, voteproducer ) { - account_name voter; - account_name proxy; - std::vector producers; - - EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) - }; - - /** - * @pre vp.producers must be sorted from lowest to highest - * @pre if proxy is set then no producers can be voted for - * @pre every listed producer or proxy must have been previously registered - * @pre vp.voter must authorize this action - * @pre voter must have previously staked some EOS for voting - */ - static void on( const voteproducer& vp ) { - eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); - eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); - if( vp.proxy != 0 ) eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); - - require_auth( vp.voter ); - - account_votes_index_type avotes( SystemAccount, SystemAccount ); - const auto& existing = avotes.get( vp.voter ); - - std::map > producer_vote_changes; - - uint128_t old_weight = existing.staked.quantity; /// old time - uint128_t new_weight = old_weight; /// TODO: update for current weight - - for( const auto& p : existing.producers ) - producer_vote_changes[p].first = old_weight; - for( const auto& p : vp.producers ) - producer_vote_changes[p].second = new_weight; - - producer_votes_index_type votes( SystemAccount, SystemAccount ); - for( const auto& delta : producer_vote_changes ) { - if( delta.second.first != delta.second.second ) { - const auto& provote = votes.get( delta.first ); - votes.update( provote, 0, [&]( auto& pv ){ - pv.total_votes -= delta.second.first; - pv.total_votes += delta.second.second; - }); - } - } - - avotes.update( existing, 0, [&]( auto& av ) { - av.proxy = vp.proxy; - av.last_update = now(); - av.producers = vp.producers; - }); - } - - static void on( const regproxy& reg ) { - require_auth( reg.proxy_to_register ); - - } - static void on( const nonce& ) { } static void apply( account_name code, action_name act ) { - - if( !eosio::dispatch::delegatebw, + typename delegate_bandwith::undelegatebw, + typename producers_election::regproxy, + typename producers_election::regproducer, + typename producers_election::voteproducer, + typename producers_election::stakevote, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); diff --git a/producers_election.hpp b/producers_election.hpp new file mode 100644 index 00000000..7ce61706 --- /dev/null +++ b/producers_election.hpp @@ -0,0 +1,212 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once +#include +#include +#include + +#include +#include +#include +#include + +#include + +namespace eosiosystem { + using eosio::indexed_by; + using eosio::const_mem_fun; + using eosio::bytes; + using eosio::print; + using std::map; + using std::pair; + + template + class producers_election { + public: + static const account_name system_account = SystemAccount; + typedef eosio::generic_currency< eosio::token > currency; + typedef typename currency::token_type system_token_type; + + struct producer_votes { + account_name owner; + uint64_t padding = 0; + uint128_t total_votes; + + uint64_t primary_key()const { return owner; } + uint128_t by_votes()const { return total_votes; } + + EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ) + }; + + typedef eosio::multi_index< N(producervote), producer_votes, + indexed_by > + > producer_votes_index_type; + + struct account_votes { + account_name owner; + account_name proxy; + uint32_t last_update; + system_token_type staked; + std::vector producers; + + uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ) + }; + typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; + + + struct producer_config { + account_name owner; + eosio::bytes packed_key; /// a packed public key object + + uint64_t primary_key()const { return owner; } + EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) + }; + typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; + + ACTION( SystemAccount, regproducer ) { + account_name producer; + bytes producer_key; + + EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) ) + }; + + /** + * This method will create a producer_config and producer_votes object for 'producer' + * + * @pre producer is not already registered + * @pre producer to register is an account + * @pre authority of producer to register + * + */ + static void on( const regproducer& reg ) { + auto producer = reg.producer; + require_auth( producer ); + + producer_votes_index_type votes( SystemAccount, SystemAccount ); + const auto* existing = votes.find( producer ); + eosio_assert( !existing, "producer already registered" ); + + votes.emplace( producer, [&]( auto& pv ){ + pv.owner = producer; + pv.total_votes = 0; + }); + + producer_config_index_type proconfig( SystemAccount, SystemAccount ); + proconfig.emplace( producer, [&]( auto& pc ) { + pc.owner = producer; + pc.packed_key = reg.producer_key; + }); + } + + ACTION( SystemAccount, stakevote ) { + account_name voter; + system_token_type amount; + + EOSLIB_SERIALIZE( stakevote, (voter)(amount) ) + }; + + static void on( const stakevote& sv ) { + print( "on stake vote\n" ); + eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); + require_auth( sv.voter ); + + account_votes_index_type avotes( SystemAccount, SystemAccount ); + + const auto* acv = avotes.find( sv.voter ); + if( !acv ) { + acv = &avotes.emplace( sv.voter, [&]( auto& av ) { + av.owner = sv.voter; + av.last_update = now(); + av.proxy = 0; + }); + } + + uint128_t old_weight = acv->staked.quantity; + uint128_t new_weight = old_weight + sv.amount.quantity; + + producer_votes_index_type votes( SystemAccount, SystemAccount ); + + for( auto p : acv->producers ) { + votes.update( votes.get( p ), 0, [&]( auto& v ) { + v.total_votes -= old_weight; + v.total_votes += new_weight; + }); + } + + avotes.update( *acv, 0, [&]( auto av ) { + av.last_update = now(); + av.staked += sv.amount; + }); + + currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); + } + + ACTION( SystemAccount, voteproducer ) { + account_name voter; + account_name proxy; + std::vector producers; + + EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) + }; + + /** + * @pre vp.producers must be sorted from lowest to highest + * @pre if proxy is set then no producers can be voted for + * @pre every listed producer or proxy must have been previously registered + * @pre vp.voter must authorize this action + * @pre voter must have previously staked some EOS for voting + */ + static void on( const voteproducer& vp ) { + eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); + eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); + if( vp.proxy != 0 ) eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); + + require_auth( vp.voter ); + + account_votes_index_type avotes( SystemAccount, SystemAccount ); + const auto& existing = avotes.get( vp.voter ); + + std::map > producer_vote_changes; + + uint128_t old_weight = existing.staked.quantity; /// old time + uint128_t new_weight = old_weight; /// TODO: update for current weight + + for( const auto& p : existing.producers ) + producer_vote_changes[p].first = old_weight; + for( const auto& p : vp.producers ) + producer_vote_changes[p].second = new_weight; + + producer_votes_index_type votes( SystemAccount, SystemAccount ); + for( const auto& delta : producer_vote_changes ) { + if( delta.second.first != delta.second.second ) { + const auto& provote = votes.get( delta.first ); + votes.update( provote, 0, [&]( auto& pv ){ + pv.total_votes -= delta.second.first; + pv.total_votes += delta.second.second; + }); + } + } + + avotes.update( existing, 0, [&]( auto& av ) { + av.proxy = vp.proxy; + av.last_update = now(); + av.producers = vp.producers; + }); + } + + ACTION( SystemAccount, regproxy ) { + account_name proxy_to_register; + + EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ) + }; + + static void on( const regproxy& reg ) { + require_auth( reg.proxy_to_register ); + + } + }; +} From c8788ed9aa22e02b7b371b0681ac5c361bea8070 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 22 Feb 2018 16:45:10 -0500 Subject: [PATCH 0033/1048] producers register desired system parameters, unstaking requests, proxy voting #1455 --- eosio.system.hpp | 4 +- producers_election.hpp | 334 +++++++++++++++++++++++++++++++---------- 2 files changed, 256 insertions(+), 82 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 1a7a85a1..150a8e02 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -34,8 +34,8 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, - typename producers_election::regproxy, - typename producers_election::regproducer, + typename producers_election::register_proxy, + typename producers_election::register_producer, typename producers_election::voteproducer, typename producers_election::stakevote, nonce>( code, act) ) { diff --git a/producers_election.hpp b/producers_election.hpp index 7ce61706..67ab8bb2 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -11,14 +11,17 @@ #include #include #include +#include #include namespace eosiosystem { using eosio::indexed_by; using eosio::const_mem_fun; + using eosio::member; using eosio::bytes; using eosio::print; + using eosio::transaction; using std::map; using std::pair; @@ -29,79 +32,151 @@ namespace eosiosystem { typedef eosio::generic_currency< eosio::token > currency; typedef typename currency::token_type system_token_type; - struct producer_votes { - account_name owner; - uint64_t padding = 0; - uint128_t total_votes; + static constexpr uint32_t max_unstake_requests = 10; + static constexpr uint32_t voting_stake_freez_time = 180*24*3600; - uint64_t primary_key()const { return owner; } - uint128_t by_votes()const { return total_votes; } + struct producer_preferences { + uint32_t max_blk_size; + uint32_t target_blk_size; - EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ) + uint64_t max_storage_size; + uint64_t rescource_window_size; + + uint32_t max_blk_cpu; + uint32_t target_blk_cpu; + + uint16_t inflation_rate; // inflation in percents * 10000; + + uint32_t max_trx_lifetime; + uint16_t max_transaction_recursion; + + producer_preferences() { bzero(this, sizeof(*this)); } + + EOSLIB_SERIALIZE( producer_preferences, (max_blk_size)(target_blk_size)(max_storage_size)(rescource_window_size) + (max_blk_cpu)(target_blk_cpu)(inflation_rate)(max_trx_lifetime)(max_transaction_recursion) ) }; - typedef eosio::multi_index< N(producervote), producer_votes, - indexed_by > - > producer_votes_index_type; + struct producer_info { + account_name owner; + uint64_t padding = 0; + uint128_t total_votes; + producer_preferences prefs; + + uint64_t primary_key()const { return owner; } + uint128_t by_votes()const { return total_votes; } + + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs) ) + }; + + typedef eosio::multi_index< N(producervote), producer_info, + indexed_by > + > producer_info_index_type; struct account_votes { - account_name owner; - account_name proxy; - uint32_t last_update; - system_token_type staked; - std::vector producers; + account_name owner; + account_name proxy; + uint32_t last_update; + uint32_t i_am_proxy; + uint128_t proxied_votes; + system_token_type staked; + std::vector producers; - uint64_t primary_key()const { return owner; } + uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ) + EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(i_am_proxy)(staked)(producers) ) }; typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; struct producer_config { - account_name owner; - eosio::bytes packed_key; /// a packed public key object + account_name owner; + eosio::bytes packed_key; /// a packed public key object - uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) + uint64_t primary_key()const { return owner; } + EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) }; typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; - ACTION( SystemAccount, regproducer ) { + struct unstake_request { + uint64_t id; + account_name account; + system_token_type amount; + time refund_time; + + uint64_t primary_key() const { return id; } + EOSLIB_SERIALIZE( unstake_request, (id)(account)(amount)(refund_time) ) + }; + + typedef eosio::multi_index< N(unstakerequests), unstake_request, + indexed_by >, + indexed_by > + > unstake_requests_table; + + struct unstake_requests_count { + account_name account; + uint16_t count; + uint64_t primary_key() const { return account; } + EOSLIB_SERIALIZE( unstake_requests_count, (account)(count) ) + }; + + typedef eosio::multi_index< N(unstakecount), unstake_requests_count> unstake_requests_counts_table; + + ACTION( SystemAccount, register_producer ) { account_name producer; bytes producer_key; + producer_preferences prefs; - EOSLIB_SERIALIZE( regproducer, (producer)(producer_key) ) + EOSLIB_SERIALIZE( register_producer, (producer)(producer_key)(prefs) ) }; /** - * This method will create a producer_config and producer_votes object for 'producer' + * This method will create a producer_config and producer_info object for 'producer' * * @pre producer is not already registered * @pre producer to register is an account * @pre authority of producer to register * */ - static void on( const regproducer& reg ) { - auto producer = reg.producer; - require_auth( producer ); + static void on( const register_producer& reg ) { + require_auth( reg.producer ); - producer_votes_index_type votes( SystemAccount, SystemAccount ); - const auto* existing = votes.find( producer ); + producer_info_index_type producers( SystemAccount, SystemAccount ); + const auto* existing = producers.find( reg.producer ); eosio_assert( !existing, "producer already registered" ); - votes.emplace( producer, [&]( auto& pv ){ - pv.owner = producer; - pv.total_votes = 0; + producers.emplace( reg.producer, [&]( producer_info& info ){ + info.owner = reg.producer; + info.total_votes = 0; + info.prefs = reg.prefs; }); producer_config_index_type proconfig( SystemAccount, SystemAccount ); - proconfig.emplace( producer, [&]( auto& pc ) { - pc.owner = producer; + proconfig.emplace( reg.producer, [&]( auto& pc ) { + pc.owner = reg.producer; pc.packed_key = reg.producer_key; }); } + ACTION( SystemAccount, change_producer_preferences ) { + account_name producer; + bytes producer_key; + producer_preferences prefs; + + EOSLIB_SERIALIZE( register_producer, (producer)(producer_key)(prefs) ) + }; + + static void on( const change_producer_preferences& change) { + require_auth( change.producer ); + + producer_info_index_type producers( SystemAccount, SystemAccount ); + const auto* ptr = producers.find( change.producer ); + eosio_assert( bool(ptr), "producer is not registered" ); + + producers.update( *ptr, change.producer, [&]( producer_info& info ){ + info.prefs = change.prefs; + }); + } + ACTION( SystemAccount, stakevote ) { account_name voter; system_token_type amount; @@ -110,7 +185,6 @@ namespace eosiosystem { }; static void on( const stakevote& sv ) { - print( "on stake vote\n" ); eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); require_auth( sv.voter ); @@ -118,40 +192,94 @@ namespace eosiosystem { const auto* acv = avotes.find( sv.voter ); if( !acv ) { - acv = &avotes.emplace( sv.voter, [&]( auto& av ) { - av.owner = sv.voter; - av.last_update = now(); - av.proxy = 0; + acv = &avotes.emplace( sv.voter, [&]( account_votes& a ) { + a.owner = sv.voter; + a.last_update = now(); + a.proxy = 0; + a.i_am_proxy = 0; + a.proxied_votes = 0; + a.staked.quantity = 0; }); } - uint128_t old_weight = acv->staked.quantity; - uint128_t new_weight = old_weight + sv.amount.quantity; - - producer_votes_index_type votes( SystemAccount, SystemAccount ); + producer_info_index_type producers( SystemAccount, SystemAccount ); for( auto p : acv->producers ) { - votes.update( votes.get( p ), 0, [&]( auto& v ) { - v.total_votes -= old_weight; - v.total_votes += new_weight; + producers.update( producers.get( p ), 0, [&]( auto& v ) { + v.total_votes += sv.amount.quantity; }); } - avotes.update( *acv, 0, [&]( auto av ) { + avotes.update( *acv, 0, [&]( auto& av ) { av.last_update = now(); av.staked += sv.amount; }); - + currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); } + ACTION( SystemAccount, unstakevote ) { + account_name voter; + system_token_type amount; + + EOSLIB_SERIALIZE( unstakevote, (voter)(amount) ) + }; + + static void on( const unstakevote& usv ) { + eosio_assert( usv.amount.quantity > 0, "unstake amount should be > 0" ); + require_auth( usv.voter ); + + unstake_requests_counts_table counts( SystemAccount, SystemAccount ); + auto ptr = counts.find( usv.voter ); + eosio_assert( !ptr || ptr->count < max_unstake_requests, "unstake requests limit exceeded"); + + if ( ptr ) { + counts.update(*ptr, usv.voter, [&](auto& r) { ++r.count; }); + } else { + counts.emplace(usv.voter, [&](auto& r) { r.count = 1; }); + } + + unstake_requests_table requests( SystemAccount, SystemAccount ); + auto pk = requests.available_primary_key(); + requests.emplace( usv.voter, [&](unstake_request& r) { + r.id = pk; + r.account = usv.voter; + r.transfer_time = now() + voting_stake_freez_time; + }); + + account_votes_index_type avotes( SystemAccount, SystemAccount ); + + const auto* acv = avotes.find( usv.voter ); + eosio_assert( bool(acv), "stake not found" ); + + eosio_assert( acv->staked.quantity < usv.amount.quantity, "attempt to unstake more than total stake amount" ); + + producer_info_index_type producers( SystemAccount, SystemAccount ); + + for( auto p : acv->producers ) { + producers.update( producers.get( p ), 0, [&]( auto& v ) { + v.total_votes -= usv.amount.quantity; + }); + } + + if ( usv.amount.quantity < acv->staked ) { + avotes.update( *acv, 0, [&]( auto& av ) { + av.last_update = now(); + av.staked -= usv.amount.quantity; + }); + } else { + eos_assert( usv.amount.quantity == acv->staked, "unstaking more than is at staked" ); + avotes.remove( *acv ); + } + } + ACTION( SystemAccount, voteproducer ) { account_name voter; account_name proxy; std::vector producers; EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) - }; + }; /** * @pre vp.producers must be sorted from lowest to highest @@ -161,52 +289,98 @@ namespace eosiosystem { * @pre voter must have previously staked some EOS for voting */ static void on( const voteproducer& vp ) { - eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); - eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); - if( vp.proxy != 0 ) eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); - require_auth( vp.voter ); + //validate input + if ( vp.proxy ) { + eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); + } else { + eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); + eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); + } + account_votes_index_type avotes( SystemAccount, SystemAccount ); - const auto& existing = avotes.get( vp.voter ); - - std::map > producer_vote_changes; - - uint128_t old_weight = existing.staked.quantity; /// old time - uint128_t new_weight = old_weight; /// TODO: update for current weight - - for( const auto& p : existing.producers ) - producer_vote_changes[p].first = old_weight; - for( const auto& p : vp.producers ) - producer_vote_changes[p].second = new_weight; - - producer_votes_index_type votes( SystemAccount, SystemAccount ); - for( const auto& delta : producer_vote_changes ) { - if( delta.second.first != delta.second.second ) { - const auto& provote = votes.get( delta.first ); - votes.update( provote, 0, [&]( auto& pv ){ - pv.total_votes -= delta.second.first; - pv.total_votes += delta.second.second; - }); + auto ptr = avotes.find( vp.voter ); + + eosio_assert( bool(ptr), "no stake to vote" ); + if ( ptr->i_am_proxy ) { + eosio_assert( vp.proxy == 0 , "accounts elected to be proxy are not allowed to use another proxy" ); + } + + //find old producers, update old proxy if needed + const std::vector* old_producers = nullptr; + if( ptr->proxy ) { + if ( ptr->proxy == vp.proxy ) { + return; // nothing changed } + auto old_proxy = avotes.find( ptr->proxy ); + avotes.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= ptr->staked.quantity; } ); + old_producers = &old_proxy->producers; + } else { + old_producers = &ptr->producers; } - avotes.update( existing, 0, [&]( auto& av ) { - av.proxy = vp.proxy; - av.last_update = now(); - av.producers = vp.producers; + //find new producers, update new proxy if needed + const std::vector* new_producers = nullptr; + if ( vp.proxy ) { + auto new_proxy = avotes.find( ptr->proxy ); + avotes.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += ptr->staked.quantity; } ); + new_producers = &new_proxy->producers; + } else { + new_producers = &vp.producers; + } + + producer_info_index_type producers( SystemAccount, SystemAccount ); + + //revoke prower only from no longer elected + std::vector revoked( old_producers->size() ); + auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); + for ( auto it = revoked.begin(); it != end_it; ++it ) { + producers.update( producers.get( *it ), 0, [&]( auto& pi ) { pi.total_votes -= ptr->staked.quantity; }); + } + + //update newly elected + std::vector elected( new_producers->size() ); + end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); + for ( auto it = elected.begin(); it != end_it; ++it ) { + producers.update( producers.get( *it ), 0, [&]( auto& pi ) { pi.total_votes += ptr->staked.quantity; }); + } + + // save new values to the account itself + avotes.update( *ptr, 0, [&](account_votes& a) { + a.proxy = vp.proxy; + a.last_update = now(); + a.producers = vp.producers; }); } - ACTION( SystemAccount, regproxy ) { + ACTION( SystemAccount, register_proxy ) { account_name proxy_to_register; - EOSLIB_SERIALIZE( regproxy, (proxy_to_register) ) + EOSLIB_SERIALIZE( register_proxy, (proxy_to_register) ) }; - static void on( const regproxy& reg ) { + static void on( const register_proxy& reg ) { require_auth( reg.proxy_to_register ); + account_votes_index_type avotes( SystemAccount, SystemAccount ); + auto ptr = avotes.find( reg.proxy_to_register ); + if ( ptr ) { + eosio_assert( ptr->i_am_proxy == 0, "account is already a proxy" ); + eosio_assert( ptr->proxy == 0, "account that uses another proxy is not allowed to become a proxy" ); + avotes.update( *ptr, 0, [&](account_votes& a) { + a.i_am_proxy = 1; + }); + } else { + avotes.emplace( reg.proxy_to_register, [&]( account_votes& a ) { + a.owner = reg.proxy_to_register; + a.last_update = now(); + a.proxy = 0; + a.i_am_proxy = 1; + a.proxied_votes = 0; + a.staked.quantity = 0; + }); + } } }; } From 4a0202b1e1a6b05713524077b8103bdd262c888a Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 22 Feb 2018 18:05:54 -0500 Subject: [PATCH 0034/1048] improvements #1455 --- eosio.system.hpp | 5 +++-- producers_election.hpp | 37 +++++++++++++++++++++---------------- 2 files changed, 24 insertions(+), 18 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 150a8e02..7ffbc81f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -36,8 +36,9 @@ namespace eosiosystem { typename delegate_bandwith::undelegatebw, typename producers_election::register_proxy, typename producers_election::register_producer, - typename producers_election::voteproducer, - typename producers_election::stakevote, + typename producers_election::vote_producer, + typename producers_election::stake_vote, + typename producers_election::unstake_vote, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); diff --git a/producers_election.hpp b/producers_election.hpp index 67ab8bb2..3a44ea99 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -108,7 +108,6 @@ namespace eosiosystem { }; typedef eosio::multi_index< N(unstakerequests), unstake_request, - indexed_by >, indexed_by > > unstake_requests_table; @@ -177,14 +176,14 @@ namespace eosiosystem { }); } - ACTION( SystemAccount, stakevote ) { + ACTION( SystemAccount, stake_vote ) { account_name voter; system_token_type amount; - EOSLIB_SERIALIZE( stakevote, (voter)(amount) ) + EOSLIB_SERIALIZE( stake_vote, (voter)(amount) ) }; - static void on( const stakevote& sv ) { + static void on( const stake_vote& sv ) { eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); require_auth( sv.voter ); @@ -218,14 +217,14 @@ namespace eosiosystem { currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); } - ACTION( SystemAccount, unstakevote ) { + ACTION( SystemAccount, unstake_vote ) { account_name voter; system_token_type amount; - EOSLIB_SERIALIZE( unstakevote, (voter)(amount) ) + EOSLIB_SERIALIZE( unstake_vote, (voter)(amount) ) }; - static void on( const unstakevote& usv ) { + static void on( const unstake_vote& usv ) { eosio_assert( usv.amount.quantity > 0, "unstake amount should be > 0" ); require_auth( usv.voter ); @@ -244,7 +243,7 @@ namespace eosiosystem { requests.emplace( usv.voter, [&](unstake_request& r) { r.id = pk; r.account = usv.voter; - r.transfer_time = now() + voting_stake_freez_time; + r.refund_time = now() + voting_stake_freez_time; }); account_votes_index_type avotes( SystemAccount, SystemAccount ); @@ -262,23 +261,23 @@ namespace eosiosystem { }); } - if ( usv.amount.quantity < acv->staked ) { + if ( usv.amount < acv->staked ) { avotes.update( *acv, 0, [&]( auto& av ) { av.last_update = now(); - av.staked -= usv.amount.quantity; + av.staked -= usv.amount; }); } else { - eos_assert( usv.amount.quantity == acv->staked, "unstaking more than is at staked" ); + eosio_assert( usv.amount == acv->staked, "unstaking more than is at staked" ); avotes.remove( *acv ); } } - ACTION( SystemAccount, voteproducer ) { + ACTION( SystemAccount, vote_producer ) { account_name voter; account_name proxy; std::vector producers; - EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) + EOSLIB_SERIALIZE( vote_producer, (voter)(proxy)(producers) ) }; /** @@ -288,7 +287,7 @@ namespace eosiosystem { * @pre vp.voter must authorize this action * @pre voter must have previously staked some EOS for voting */ - static void on( const voteproducer& vp ) { + static void on( const vote_producer& vp ) { require_auth( vp.voter ); //validate input @@ -332,7 +331,7 @@ namespace eosiosystem { producer_info_index_type producers( SystemAccount, SystemAccount ); - //revoke prower only from no longer elected + //revoke votes only from no longer elected std::vector revoked( old_producers->size() ); auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); for ( auto it = revoked.begin(); it != end_it; ++it ) { @@ -367,9 +366,10 @@ namespace eosiosystem { auto ptr = avotes.find( reg.proxy_to_register ); if ( ptr ) { eosio_assert( ptr->i_am_proxy == 0, "account is already a proxy" ); - eosio_assert( ptr->proxy == 0, "account that uses another proxy is not allowed to become a proxy" ); + eosio_assert( ptr->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); avotes.update( *ptr, 0, [&](account_votes& a) { a.i_am_proxy = 1; + a.last_update = now(); }); } else { avotes.emplace( reg.proxy_to_register, [&]( account_votes& a ) { @@ -382,5 +382,10 @@ namespace eosiosystem { }); } } + + struct block {}; + + static void on( const block& ) { + } }; } From e84d492bf671bea6ddad7c5e79335939c3b502f8 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 22 Feb 2018 18:47:37 -0500 Subject: [PATCH 0035/1048] compilation fix #1455 --- producers_election.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/producers_election.hpp b/producers_election.hpp index 3a44ea99..0707e799 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -104,11 +104,12 @@ namespace eosiosystem { time refund_time; uint64_t primary_key() const { return id; } + uint64_t rt() const { return refund_time; } EOSLIB_SERIALIZE( unstake_request, (id)(account)(amount)(refund_time) ) }; typedef eosio::multi_index< N(unstakerequests), unstake_request, - indexed_by > + indexed_by > > unstake_requests_table; struct unstake_requests_count { From 17ed82e86642e5c362c87d5d193a66a4f2e35909 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 22 Feb 2018 18:51:16 -0500 Subject: [PATCH 0036/1048] table name fix #1455 --- producers_election.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/producers_election.hpp b/producers_election.hpp index 0707e799..20167a3c 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -108,7 +108,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( unstake_request, (id)(account)(amount)(refund_time) ) }; - typedef eosio::multi_index< N(unstakerequests), unstake_request, + typedef eosio::multi_index< N(unstakereqs), unstake_request, indexed_by > > unstake_requests_table; From 1db07603e73d58972b29542ff88884afb88ba592 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 23 Feb 2018 11:25:02 -0500 Subject: [PATCH 0037/1048] proxy voting fixes, unregister proxy, decrease/cancel unstake request --- eosio.system.hpp | 2 + producers_election.hpp | 163 +++++++++++++++++++++++++++++++---------- 2 files changed, 125 insertions(+), 40 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 7ffbc81f..1bc492ae 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -35,10 +35,12 @@ namespace eosiosystem { if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, typename producers_election::register_proxy, + typename producers_election::unregister_proxy, typename producers_election::register_producer, typename producers_election::vote_producer, typename producers_election::stake_vote, typename producers_election::unstake_vote, + typename producers_election::decrease_unstake_vote_request, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); diff --git a/producers_election.hpp b/producers_election.hpp index 20167a3c..b8127770 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -76,14 +76,14 @@ namespace eosiosystem { account_name owner; account_name proxy; uint32_t last_update; - uint32_t i_am_proxy; + uint32_t is_proxy; uint128_t proxied_votes; system_token_type staked; std::vector producers; uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(i_am_proxy)(staked)(producers) ) + EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(is_proxy)(staked)(producers) ) }; typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; @@ -184,36 +184,53 @@ namespace eosiosystem { EOSLIB_SERIALIZE( stake_vote, (voter)(amount) ) }; - static void on( const stake_vote& sv ) { - eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); - require_auth( sv.voter ); - + static void increase_voting_power( account_name voter, system_token_type amount ) { account_votes_index_type avotes( SystemAccount, SystemAccount ); + const auto* acv = avotes.find( voter ); - const auto* acv = avotes.find( sv.voter ); if( !acv ) { - acv = &avotes.emplace( sv.voter, [&]( account_votes& a ) { - a.owner = sv.voter; + acv = &avotes.emplace( voter, [&]( account_votes& a ) { + a.owner = voter; a.last_update = now(); a.proxy = 0; - a.i_am_proxy = 0; + a.is_proxy = 0; a.proxied_votes = 0; - a.staked.quantity = 0; + a.staked = amount; }); + } else { + avotes.update( *acv, 0, [&]( auto& av ) { + av.last_update = now(); + av.staked += amount; + }); + } - producer_info_index_type producers( SystemAccount, SystemAccount ); + const std::vector* producers = nullptr; + if ( acv->proxy ) { + auto proxy = avotes.find( acv->proxy ); + avotes.update( *proxy, 0, [&](account_votes& a) { a.proxied_votes += amount.quantity; } ); + if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers + producers = &proxy->producers; + } + } else { + producers = &acv->producers; + } - for( auto p : acv->producers ) { - producers.update( producers.get( p ), 0, [&]( auto& v ) { - v.total_votes += sv.amount.quantity; - }); + if ( producers ) { + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + for( auto p : *producers ) { + producers_tbl.update( producers_tbl.get( p ), 0, [&]( auto& v ) { + v.total_votes += amount.quantity; + }); + } } + } - avotes.update( *acv, 0, [&]( auto& av ) { - av.last_update = now(); - av.staked += sv.amount; - }); + static void on( const stake_vote& sv ) { + eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); + require_auth( sv.voter ); + + increase_voting_power( sv.voter, sv.amount ); currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); } @@ -244,6 +261,7 @@ namespace eosiosystem { requests.emplace( usv.voter, [&](unstake_request& r) { r.id = pk; r.account = usv.voter; + r.amount = usv.amount; r.refund_time = now() + voting_stake_freez_time; }); @@ -254,22 +272,54 @@ namespace eosiosystem { eosio_assert( acv->staked.quantity < usv.amount.quantity, "attempt to unstake more than total stake amount" ); - producer_info_index_type producers( SystemAccount, SystemAccount ); + const std::vector* producers = nullptr; + if ( acv->proxy ) { + auto proxy = avotes.find( acv->proxy ); + avotes.update( *proxy, 0, [&](account_votes& a) { a.proxied_votes -= usv.amount.quantity; } ); + if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers + producers = &proxy->producers; + } + } else { + producers = &acv->producers; + } - for( auto p : acv->producers ) { - producers.update( producers.get( p ), 0, [&]( auto& v ) { - v.total_votes -= usv.amount.quantity; - }); + if ( producers ) { + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + for( auto p : *producers ) { + producers_tbl.update( producers_tbl.get( p ), 0, [&]( auto& v ) { + v.total_votes -= usv.amount.quantity; + }); + } } - if ( usv.amount < acv->staked ) { + if ( usv.amount <= acv->staked ) { + //only update, never delete, because we need to keep is_proxy flag and proxied_amount avotes.update( *acv, 0, [&]( auto& av ) { av.last_update = now(); av.staked -= usv.amount; }); + } + } + + ACTION( SystemAccount, decrease_unstake_vote_request ) { + uint64_t request_id; + system_token_type amount; + + EOSLIB_SERIALIZE( decrease_unstake_vote_request, (request_id) ) + }; + + static void on( const decrease_unstake_vote_request& decrease_req ) { + unstake_requests_table requests( SystemAccount, SystemAccount ); + auto ptr = requests.find( decrease_req.request_id ); + eosio_assert( bool(ptr), "unstake vote request not found" ); + + require_auth( ptr->account ); + eosio_assert( ptr->amount <= decrease_req.amount, "unstake request amount is less than amount of requested decrease" ); + increase_voting_power( ptr->account, ptr->amount ); + if ( ptr->amount == decrease_req.amount ) { + requests.remove( *ptr ); } else { - eosio_assert( usv.amount == acv->staked, "unstaking more than is at staked" ); - avotes.remove( *acv ); + requests.update( *ptr, 0, [&](auto& r) { r.amount -= decrease_req.amount; } ); } } @@ -294,6 +344,7 @@ namespace eosiosystem { //validate input if ( vp.proxy ) { eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); + require_recipient( vp.proxy ); } else { eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); @@ -303,7 +354,7 @@ namespace eosiosystem { auto ptr = avotes.find( vp.voter ); eosio_assert( bool(ptr), "no stake to vote" ); - if ( ptr->i_am_proxy ) { + if ( ptr->is_proxy ) { eosio_assert( vp.proxy == 0 , "accounts elected to be proxy are not allowed to use another proxy" ); } @@ -315,7 +366,9 @@ namespace eosiosystem { } auto old_proxy = avotes.find( ptr->proxy ); avotes.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= ptr->staked.quantity; } ); - old_producers = &old_proxy->producers; + if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) + old_producers = &old_proxy->producers; + } } else { old_producers = &ptr->producers; } @@ -323,7 +376,8 @@ namespace eosiosystem { //find new producers, update new proxy if needed const std::vector* new_producers = nullptr; if ( vp.proxy ) { - auto new_proxy = avotes.find( ptr->proxy ); + auto new_proxy = avotes.find( vp.proxy ); + eosio_assert( new_proxy->is_proxy, "selected proxy has not elected to be a proxy" ); avotes.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += ptr->staked.quantity; } ); new_producers = &new_proxy->producers; } else { @@ -332,16 +386,18 @@ namespace eosiosystem { producer_info_index_type producers( SystemAccount, SystemAccount ); - //revoke votes only from no longer elected - std::vector revoked( old_producers->size() ); - auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); - for ( auto it = revoked.begin(); it != end_it; ++it ) { - producers.update( producers.get( *it ), 0, [&]( auto& pi ) { pi.total_votes -= ptr->staked.quantity; }); + if ( old_producers ) { //old_producers == 0 if proxy has stoped being a proxy and votes were taken back from producers at that moment + //revoke votes only from no longer elected + std::vector revoked( old_producers->size() ); + auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); + for ( auto it = revoked.begin(); it != end_it; ++it ) { + producers.update( producers.get( *it ), 0, [&]( auto& pi ) { pi.total_votes -= ptr->staked.quantity; }); + } } //update newly elected std::vector elected( new_producers->size() ); - end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); + auto end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); for ( auto it = elected.begin(); it != end_it; ++it ) { producers.update( producers.get( *it ), 0, [&]( auto& pi ) { pi.total_votes += ptr->staked.quantity; }); } @@ -366,24 +422,51 @@ namespace eosiosystem { account_votes_index_type avotes( SystemAccount, SystemAccount ); auto ptr = avotes.find( reg.proxy_to_register ); if ( ptr ) { - eosio_assert( ptr->i_am_proxy == 0, "account is already a proxy" ); + eosio_assert( ptr->is_proxy == 0, "account is already a proxy" ); eosio_assert( ptr->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); avotes.update( *ptr, 0, [&](account_votes& a) { - a.i_am_proxy = 1; + a.is_proxy = 1; a.last_update = now(); + //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value }); } else { avotes.emplace( reg.proxy_to_register, [&]( account_votes& a ) { a.owner = reg.proxy_to_register; a.last_update = now(); a.proxy = 0; - a.i_am_proxy = 1; + a.is_proxy = 1; a.proxied_votes = 0; a.staked.quantity = 0; }); } } + ACTION( SystemAccount, unregister_proxy ) { + account_name proxy_to_unregister; + + EOSLIB_SERIALIZE( unregister_proxy, (proxy_to_unregister) ) + }; + + static void on( const unregister_proxy& reg ) { + require_auth( reg.proxy_to_unregister ); + + account_votes_index_type avotes( SystemAccount, SystemAccount ); + auto ptr = avotes.find( reg.proxy_to_unregister ); + eosio_assert( bool(ptr), "proxy not found" ); + eosio_assert( ptr->is_proxy == 1, "account is already a proxy" ); + + producer_info_index_type producers( SystemAccount, SystemAccount ); + for ( auto pr : ptr->producers ) { + producers.update( producers.get( pr ), 0, [&]( auto& pi ) { pi.total_votes -= ptr->proxied_votes; }); + } + + avotes.update( *ptr, 0, [&](account_votes& a) { + a.is_proxy = 0; + a.last_update = now(); + //a.proxied_votes should be kept in order to be able to reenable this proxy in the future + }); + } + struct block {}; static void on( const block& ) { From 8b4cb1ac0afa8a1cb5c22cd93035d132fd72f4c0 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 23 Feb 2018 14:31:28 -0500 Subject: [PATCH 0038/1048] push elected producers to active producers, calculate parameters elected by producers, back to canceling unstake requests instead of decreasing --- eosio.system.hpp | 2 +- producers_election.hpp | 96 ++++++++++++++++++++++++++++++------------ 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 1bc492ae..42a826cf 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -40,7 +40,7 @@ namespace eosiosystem { typename producers_election::vote_producer, typename producers_election::stake_vote, typename producers_election::unstake_vote, - typename producers_election::decrease_unstake_vote_request, + typename producers_election::cancel_unstake_vote_request, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); diff --git a/producers_election.hpp b/producers_election.hpp index b8127770..ccff77e8 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -33,7 +34,8 @@ namespace eosiosystem { typedef typename currency::token_type system_token_type; static constexpr uint32_t max_unstake_requests = 10; - static constexpr uint32_t voting_stake_freez_time = 180*24*3600; + static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week + static constexpr uint32_t unstake_payments = 26; // during 26 weeks struct producer_preferences { uint32_t max_blk_size; @@ -100,12 +102,13 @@ namespace eosiosystem { struct unstake_request { uint64_t id; account_name account; - system_token_type amount; - time refund_time; + system_token_type current_amount; + system_token_type weekly_refund_amount; + time next_refund_time; uint64_t primary_key() const { return id; } - uint64_t rt() const { return refund_time; } - EOSLIB_SERIALIZE( unstake_request, (id)(account)(amount)(refund_time) ) + uint64_t rt() const { return next_refund_time; } + EOSLIB_SERIALIZE( unstake_request, (id)(account)(current_amount)(weekly_refund_amount)(next_refund_time) ) }; typedef eosio::multi_index< N(unstakereqs), unstake_request, @@ -226,7 +229,50 @@ namespace eosiosystem { } } - static void on( const stake_vote& sv ) { + static void update_elected_producers() { + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + auto& idx = producers_tbl.template get<>( N(prototalvote) ); + + //use twice bigger integer types for aggregates + uint64_t max_blk_size =0; + uint64_t target_blk_size = 0; + uint128_t max_storage_size = 0; + uint128_t rescource_window_size= 0; + uint64_t max_blk_cpu = 0; + uint64_t target_blk_cpu = 0; + uint32_t inflation_rate = 0; + uint64_t max_trx_lifetime = 0; + uint32_t max_transaction_recursion = 0; + + std::vector elected(21); + auto it = std::prev( idx.end() ); + for (auto out = elected.begin(); out != elected.end(); ++out) { + *out = it->owner; + + max_blk_size += it->prefs.max_blk_size; + target_blk_size += it->prefs.target_blk_size; + max_storage_size += it->prefs.max_storage_size; + rescource_window_size += it->prefs.rescource_window_size; + max_blk_cpu += it->prefs.max_blk_cpu; + target_blk_cpu += it->prefs.target_blk_cpu; + inflation_rate += it->prefs.inflation_rate; + max_trx_lifetime += it->prefs.max_trx_lifetime; + max_transaction_recursion += it->prefs.max_transaction_recursion; + + if (it == idx.begin()) { + break; + } + --it; + } + set_active_producers( elected.data(), elected.size() ); + //set_max_blk_size(max_blk_size); + } + + static void process_unstake_requests() { + + } + + static void on( const stake_vote& sv ) { eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); require_auth( sv.voter ); @@ -261,8 +307,10 @@ namespace eosiosystem { requests.emplace( usv.voter, [&](unstake_request& r) { r.id = pk; r.account = usv.voter; - r.amount = usv.amount; - r.refund_time = now() + voting_stake_freez_time; + r.current_amount = usv.amount; + //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments + r.weekly_refund_amount = system_token_type( usv.amount.quantity/unstake_payments + usv.amount.quantity%unstake_payments ); + r.next_refund_time = now() + unstake_pay_period; }); account_votes_index_type avotes( SystemAccount, SystemAccount ); @@ -292,35 +340,27 @@ namespace eosiosystem { } } - if ( usv.amount <= acv->staked ) { - //only update, never delete, because we need to keep is_proxy flag and proxied_amount - avotes.update( *acv, 0, [&]( auto& av ) { - av.last_update = now(); - av.staked -= usv.amount; - }); - } + //only update, never delete, because we need to keep is_proxy flag and proxied_amount + avotes.update( *acv, 0, [&]( auto& av ) { + av.last_update = now(); + av.staked -= usv.amount; + }); } - ACTION( SystemAccount, decrease_unstake_vote_request ) { + ACTION( SystemAccount, cancel_unstake_vote_request ) { uint64_t request_id; - system_token_type amount; - EOSLIB_SERIALIZE( decrease_unstake_vote_request, (request_id) ) + EOSLIB_SERIALIZE( cancel_unstake_vote_request, (request_id) ) }; - static void on( const decrease_unstake_vote_request& decrease_req ) { + static void on( const cancel_unstake_vote_request& cancel_req ) { unstake_requests_table requests( SystemAccount, SystemAccount ); - auto ptr = requests.find( decrease_req.request_id ); + auto ptr = requests.find( cancel_req.request_id ); eosio_assert( bool(ptr), "unstake vote request not found" ); require_auth( ptr->account ); - eosio_assert( ptr->amount <= decrease_req.amount, "unstake request amount is less than amount of requested decrease" ); - increase_voting_power( ptr->account, ptr->amount ); - if ( ptr->amount == decrease_req.amount ) { - requests.remove( *ptr ); - } else { - requests.update( *ptr, 0, [&](auto& r) { r.amount -= decrease_req.amount; } ); - } + increase_voting_power( ptr->account, ptr->current_amount ); + requests.remove( *ptr ); } ACTION( SystemAccount, vote_producer ) { @@ -470,6 +510,8 @@ namespace eosiosystem { struct block {}; static void on( const block& ) { + update_elected_producers(); + process_unstake_requests(); } }; } From 92ef0996abc096897399df5e78258f68b826c67e Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 23 Feb 2018 18:57:03 -0500 Subject: [PATCH 0039/1048] median voting, check for producers existence --- producers_election.hpp | 119 +++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 51 deletions(-) diff --git a/producers_election.hpp b/producers_election.hpp index ccff77e8..710fcb43 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -14,7 +14,7 @@ #include #include -#include +#include namespace eosiosystem { using eosio::indexed_by; @@ -23,8 +23,6 @@ namespace eosiosystem { using eosio::bytes; using eosio::print; using eosio::transaction; - using std::map; - using std::pair; template class producers_election { @@ -61,11 +59,13 @@ namespace eosiosystem { struct producer_info { account_name owner; uint64_t padding = 0; - uint128_t total_votes; + uint128_t total_votes = 0; producer_preferences prefs; + eosio::bytes packed_key; /// a packed public key object uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } + bool active() const { return !packed_key.empty(); } EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs) ) }; @@ -143,11 +143,11 @@ namespace eosiosystem { static void on( const register_producer& reg ) { require_auth( reg.producer ); - producer_info_index_type producers( SystemAccount, SystemAccount ); - const auto* existing = producers.find( reg.producer ); + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + const auto* existing = producers_tbl.find( reg.producer ); eosio_assert( !existing, "producer already registered" ); - producers.emplace( reg.producer, [&]( producer_info& info ){ + producers_tbl.emplace( reg.producer, [&]( producer_info& info ){ info.owner = reg.producer; info.total_votes = 0; info.prefs = reg.prefs; @@ -171,11 +171,11 @@ namespace eosiosystem { static void on( const change_producer_preferences& change) { require_auth( change.producer ); - producer_info_index_type producers( SystemAccount, SystemAccount ); - const auto* ptr = producers.find( change.producer ); + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + const auto* ptr = producers_tbl.find( change.producer ); eosio_assert( bool(ptr), "producer is not registered" ); - producers.update( *ptr, change.producer, [&]( producer_info& info ){ + producers_tbl.update( *ptr, change.producer, [&]( producer_info& info ){ info.prefs = change.prefs; }); } @@ -222,7 +222,9 @@ namespace eosiosystem { if ( producers ) { producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); for( auto p : *producers ) { - producers_tbl.update( producers_tbl.get( p ), 0, [&]( auto& v ) { + auto ptr = producers_tbl.find( p ); + eosio_assert( bool(ptr), "never existed producer" ); //data corruption + producers_tbl.update( *ptr, 0, [&]( auto& v ) { v.total_votes += amount.quantity; }); } @@ -234,38 +236,43 @@ namespace eosiosystem { auto& idx = producers_tbl.template get<>( N(prototalvote) ); //use twice bigger integer types for aggregates - uint64_t max_blk_size =0; - uint64_t target_blk_size = 0; - uint128_t max_storage_size = 0; - uint128_t rescource_window_size= 0; - uint64_t max_blk_cpu = 0; - uint64_t target_blk_cpu = 0; - uint32_t inflation_rate = 0; - uint64_t max_trx_lifetime = 0; - uint32_t max_transaction_recursion = 0; - - std::vector elected(21); + std::array max_blk_size; + std::array target_blk_size; + std::array max_storage_size; + std::array rescource_window_size; + std::array max_blk_cpu; + std::array target_blk_cpu; + std::array inflation_rate; // inflation in percents * 10000; + std::array max_trx_lifetime; + std::array max_transaction_recursion; + + std::array elected; auto it = std::prev( idx.end() ); - for (auto out = elected.begin(); out != elected.end(); ++out) { - *out = it->owner; - - max_blk_size += it->prefs.max_blk_size; - target_blk_size += it->prefs.target_blk_size; - max_storage_size += it->prefs.max_storage_size; - rescource_window_size += it->prefs.rescource_window_size; - max_blk_cpu += it->prefs.max_blk_cpu; - target_blk_cpu += it->prefs.target_blk_cpu; - inflation_rate += it->prefs.inflation_rate; - max_trx_lifetime += it->prefs.max_trx_lifetime; - max_transaction_recursion += it->prefs.max_transaction_recursion; + size_t n = 0; + while ( n < 21 ) { + if ( it->active() ) { + elected[n] = it->owner; + + max_blk_size[n] = it->prefs.max_blk_size; + target_blk_size[n] = it->prefs.target_blk_size; + max_storage_size[n] = it->prefs.max_storage_size; + rescource_window_size[n] = it->prefs.rescource_window_size; + max_blk_cpu[n] = it->prefs.max_blk_cpu; + target_blk_cpu[n] = it->prefs.target_blk_cpu; + inflation_rate[n] = it->prefs.inflation_rate; + max_trx_lifetime[n] = it->prefs.max_trx_lifetime; + max_transaction_recursion[n] = it->prefs.max_transaction_recursion; + ++n; + } if (it == idx.begin()) { break; } --it; } - set_active_producers( elected.data(), elected.size() ); - //set_max_blk_size(max_blk_size); + set_active_producers( elected.data(), n ); + size_t median = n/2; + //set_max_blk_size(max_blk_size[median]); } static void process_unstake_requests() { @@ -277,7 +284,6 @@ namespace eosiosystem { require_auth( sv.voter ); increase_voting_power( sv.voter, sv.amount ); - currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); } @@ -297,9 +303,9 @@ namespace eosiosystem { eosio_assert( !ptr || ptr->count < max_unstake_requests, "unstake requests limit exceeded"); if ( ptr ) { - counts.update(*ptr, usv.voter, [&](auto& r) { ++r.count; }); + counts.update( *ptr, usv.voter, [&](auto& r) { ++r.count; } ); } else { - counts.emplace(usv.voter, [&](auto& r) { r.count = 1; }); + counts.emplace( usv.voter, [&](auto& r) { r.count = 1; } ); } unstake_requests_table requests( SystemAccount, SystemAccount ); @@ -334,10 +340,12 @@ namespace eosiosystem { if ( producers ) { producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); for( auto p : *producers ) { - producers_tbl.update( producers_tbl.get( p ), 0, [&]( auto& v ) { + auto prod = producers_tbl.find( p ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& v ) { v.total_votes -= usv.amount.quantity; }); - } + } } //only update, never delete, because we need to keep is_proxy flag and proxied_amount @@ -424,14 +432,16 @@ namespace eosiosystem { new_producers = &vp.producers; } - producer_info_index_type producers( SystemAccount, SystemAccount ); + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); if ( old_producers ) { //old_producers == 0 if proxy has stoped being a proxy and votes were taken back from producers at that moment //revoke votes only from no longer elected std::vector revoked( old_producers->size() ); auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); for ( auto it = revoked.begin(); it != end_it; ++it ) { - producers.update( producers.get( *it ), 0, [&]( auto& pi ) { pi.total_votes -= ptr->staked.quantity; }); + auto prod = producers_tbl.find( *it ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= ptr->staked.quantity; }); } } @@ -439,7 +449,12 @@ namespace eosiosystem { std::vector elected( new_producers->size() ); auto end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); for ( auto it = elected.begin(); it != end_it; ++it ) { - producers.update( producers.get( *it ), 0, [&]( auto& pi ) { pi.total_votes += ptr->staked.quantity; }); + auto prod = producers_tbl.find( *it ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers + eosio_assert( prod->active(), "can vote only for active producers" ); + } + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += ptr->staked.quantity; }); } // save new values to the account itself @@ -491,16 +506,18 @@ namespace eosiosystem { require_auth( reg.proxy_to_unregister ); account_votes_index_type avotes( SystemAccount, SystemAccount ); - auto ptr = avotes.find( reg.proxy_to_unregister ); - eosio_assert( bool(ptr), "proxy not found" ); - eosio_assert( ptr->is_proxy == 1, "account is already a proxy" ); + auto proxy = avotes.find( reg.proxy_to_unregister ); + eosio_assert( bool(proxy), "proxy not found" ); + eosio_assert( proxy->is_proxy == 1, "account is already a proxy" ); - producer_info_index_type producers( SystemAccount, SystemAccount ); - for ( auto pr : ptr->producers ) { - producers.update( producers.get( pr ), 0, [&]( auto& pi ) { pi.total_votes -= ptr->proxied_votes; }); + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + for ( auto p : proxy->producers ) { + auto ptr = producers_tbl.find( p ); + eosio_assert( bool(ptr), "never existed producer" ); //data corruption + producers_tbl.update( *ptr, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); } - avotes.update( *ptr, 0, [&](account_votes& a) { + avotes.update( *proxy, 0, [&](account_votes& a) { a.is_proxy = 0; a.last_update = now(); //a.proxied_votes should be kept in order to be able to reenable this proxy in the future From b81c269ab6d7de783f8f6c45254afcc17a0e34e9 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 27 Feb 2018 11:48:37 -0500 Subject: [PATCH 0040/1048] draft of new vote unstaking code, set_blockchain_parameters, chain_config::real_threads removed --- eosio.system.hpp | 2 +- producers_election.hpp | 259 +++++++++++++++++++++-------------------- 2 files changed, 132 insertions(+), 129 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 42a826cf..7198d5db 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -40,7 +40,7 @@ namespace eosiosystem { typename producers_election::vote_producer, typename producers_election::stake_vote, typename producers_election::unstake_vote, - typename producers_election::cancel_unstake_vote_request, + typename producers_election::unstake_vote_deferred, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); diff --git a/producers_election.hpp b/producers_election.hpp index 710fcb43..963d89e8 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -11,7 +11,7 @@ #include #include #include -#include +#include #include #include @@ -35,25 +35,12 @@ namespace eosiosystem { static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week static constexpr uint32_t unstake_payments = 26; // during 26 weeks - struct producer_preferences { - uint32_t max_blk_size; - uint32_t target_blk_size; - - uint64_t max_storage_size; - uint64_t rescource_window_size; - - uint32_t max_blk_cpu; - uint32_t target_blk_cpu; - - uint16_t inflation_rate; // inflation in percents * 10000; - - uint32_t max_trx_lifetime; - uint16_t max_transaction_recursion; + struct producer_preferences : eosio::blockchain_parameters { + uint32_t inflation_rate; // inflation coefficient * 10000 (i.e. inflation in percent * 1000) producer_preferences() { bzero(this, sizeof(*this)); } - EOSLIB_SERIALIZE( producer_preferences, (max_blk_size)(target_blk_size)(max_storage_size)(rescource_window_size) - (max_blk_cpu)(target_blk_cpu)(inflation_rate)(max_trx_lifetime)(max_transaction_recursion) ) + EOSLIB_SERIALIZE_DERIVED( producer_preferences, eosio::blockchain_parameters, (inflation_rate) ) }; struct producer_info { @@ -75,18 +62,23 @@ namespace eosiosystem { > producer_info_index_type; struct account_votes { - account_name owner; - account_name proxy; - uint32_t last_update; - uint32_t is_proxy; - uint128_t proxied_votes; + account_name owner = 0; + account_name proxy = 0; + uint32_t last_update = 0; + uint32_t is_proxy = 0; system_token_type staked; + system_token_type unstaking; + system_token_type unstake_per_week; + uint128_t proxied_votes = 0; std::vector producers; + uint32_t deferred_trx_id = 0; + time last_unstake_time = 0; //uint32 uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(is_proxy)(staked)(producers) ) + EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) }; + typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; @@ -97,32 +89,8 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) }; - typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; - struct unstake_request { - uint64_t id; - account_name account; - system_token_type current_amount; - system_token_type weekly_refund_amount; - time next_refund_time; - - uint64_t primary_key() const { return id; } - uint64_t rt() const { return next_refund_time; } - EOSLIB_SERIALIZE( unstake_request, (id)(account)(current_amount)(weekly_refund_amount)(next_refund_time) ) - }; - - typedef eosio::multi_index< N(unstakereqs), unstake_request, - indexed_by > - > unstake_requests_table; - - struct unstake_requests_count { - account_name account; - uint16_t count; - uint64_t primary_key() const { return account; } - EOSLIB_SERIALIZE( unstake_requests_count, (account)(count) ) - }; - - typedef eosio::multi_index< N(unstakecount), unstake_requests_count> unstake_requests_counts_table; + typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; ACTION( SystemAccount, register_producer ) { account_name producer; @@ -235,33 +203,47 @@ namespace eosiosystem { producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); auto& idx = producers_tbl.template get<>( N(prototalvote) ); - //use twice bigger integer types for aggregates - std::array max_blk_size; - std::array target_blk_size; + std::array target_block_size; + std::array max_block_size; + std::array target_block_acts_per_scope; + std::array max_block_acts_per_scope; + std::array target_block_acts; + std::array max_block_acts; std::array max_storage_size; - std::array rescource_window_size; - std::array max_blk_cpu; - std::array target_blk_cpu; - std::array inflation_rate; // inflation in percents * 10000; - std::array max_trx_lifetime; - std::array max_transaction_recursion; + std::array max_transaction_lifetime; + std::array max_authority_depth; + std::array max_transaction_exec_time; + std::array max_inline_depth; + std::array max_inline_action_size; + std::array max_generated_transaction_size; + std::array inflation_rate; std::array elected; + auto it = std::prev( idx.end() ); size_t n = 0; while ( n < 21 ) { if ( it->active() ) { elected[n] = it->owner; - max_blk_size[n] = it->prefs.max_blk_size; - target_blk_size[n] = it->prefs.target_blk_size; + target_block_size[n] = it->prefs.target_block_size; + max_block_size[n] = it->prefs.max_block_size; + + target_block_acts_per_scope[n] = it->prefs.target_block_acts_per_scope; + max_block_acts_per_scope[n] = it->prefs.max_block_acts_per_scope; + + target_block_acts[n] = it->prefs.target_block_acts; + max_block_acts[n] = it->prefs.max_block_acts; + max_storage_size[n] = it->prefs.max_storage_size; - rescource_window_size[n] = it->prefs.rescource_window_size; - max_blk_cpu[n] = it->prefs.max_blk_cpu; - target_blk_cpu[n] = it->prefs.target_blk_cpu; + max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; + max_authority_depth[n] = it->prefs.max_authority_depth; + max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; + max_inline_depth[n] = it->prefs.max_inline_depth; + max_inline_action_size[n] = it->prefs.max_inline_action_size; + max_generated_transaction_size[n] = it->prefs.max_generated_transaction_size; + inflation_rate[n] = it->prefs.inflation_rate; - max_trx_lifetime[n] = it->prefs.max_trx_lifetime; - max_transaction_recursion[n] = it->prefs.max_transaction_recursion; ++n; } @@ -272,14 +254,27 @@ namespace eosiosystem { } set_active_producers( elected.data(), n ); size_t median = n/2; - //set_max_blk_size(max_blk_size[median]); - } - static void process_unstake_requests() { - + ::blockchain_parameters concensus = { + target_block_size[median], + max_block_size[median], + target_block_acts_per_scope[median], + max_block_acts_per_scope[median], + target_block_acts[median], + max_block_acts[median], + max_storage_size[median], + max_transaction_lifetime[median], + max_transaction_exec_time[median], + max_authority_depth[median], + max_inline_depth[median], + max_inline_action_size[median], + max_generated_transaction_size[median] + }; + + set_blockchain_parameters(&concensus); } - static void on( const stake_vote& sv ) { + static void on( const stake_vote& sv ) { eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); require_auth( sv.voter ); @@ -295,80 +290,89 @@ namespace eosiosystem { }; static void on( const unstake_vote& usv ) { - eosio_assert( usv.amount.quantity > 0, "unstake amount should be > 0" ); require_auth( usv.voter ); - - unstake_requests_counts_table counts( SystemAccount, SystemAccount ); - auto ptr = counts.find( usv.voter ); - eosio_assert( !ptr || ptr->count < max_unstake_requests, "unstake requests limit exceeded"); - - if ( ptr ) { - counts.update( *ptr, usv.voter, [&](auto& r) { ++r.count; } ); - } else { - counts.emplace( usv.voter, [&](auto& r) { r.count = 1; } ); - } - - unstake_requests_table requests( SystemAccount, SystemAccount ); - auto pk = requests.available_primary_key(); - requests.emplace( usv.voter, [&](unstake_request& r) { - r.id = pk; - r.account = usv.voter; - r.current_amount = usv.amount; - //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments - r.weekly_refund_amount = system_token_type( usv.amount.quantity/unstake_payments + usv.amount.quantity%unstake_payments ); - r.next_refund_time = now() + unstake_pay_period; - }); - account_votes_index_type avotes( SystemAccount, SystemAccount ); - const auto* acv = avotes.find( usv.voter ); eosio_assert( bool(acv), "stake not found" ); - eosio_assert( acv->staked.quantity < usv.amount.quantity, "attempt to unstake more than total stake amount" ); + if ( 0 < usv.amount.quantity ) { + eosio_assert( acv->staked < usv.amount, "cannot unstake more than total stake amount" ); - const std::vector* producers = nullptr; - if ( acv->proxy ) { - auto proxy = avotes.find( acv->proxy ); - avotes.update( *proxy, 0, [&](account_votes& a) { a.proxied_votes -= usv.amount.quantity; } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; + if (acv->deferred_trx_id) { + //XXX cancel_deferred_transaction(acv->deferred_trx_id); } - } else { - producers = &acv->producers; - } - if ( producers ) { - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& v ) { - v.total_votes -= usv.amount.quantity; - }); + uint32_t new_trx_id = 0;//XXX send_deferred(); + + avotes.update( *acv, 0, [&](account_votes& a) { + a.staked -= usv.amount; + a.unstaking += a.unstaking + usv.amount; + //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments + a.unstake_per_week = system_token_type( a.unstaking.quantity /unstake_payments + a.unstaking.quantity % unstake_payments ); + a.deferred_trx_id = new_trx_id; + a.last_update = now(); + }); + + const std::vector* producers = nullptr; + if ( acv->proxy ) { + auto proxy = avotes.find( acv->proxy ); + avotes.update( *proxy, 0, [&](account_votes& a) { a.proxied_votes -= usv.amount.quantity; } ); + if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers + producers = &proxy->producers; } - } + } else { + producers = &acv->producers; + } - //only update, never delete, because we need to keep is_proxy flag and proxied_amount - avotes.update( *acv, 0, [&]( auto& av ) { - av.last_update = now(); - av.staked -= usv.amount; - }); + if ( producers ) { + producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + for( auto p : *producers ) { + auto prod = producers_tbl.find( p ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& v ) { + v.total_votes -= usv.amount.quantity; + }); + } + } + } else { + if (acv->deferred_trx_id) { + //XXX cancel_deferred_transaction(acv->deferred_trx_id); + } + avotes.update( *acv, 0, [&](account_votes& a) { + a.staked += a.unstaking; + a.unstaking.quantity = 0; + a.unstake_per_week.quantity = 0; + a.deferred_trx_id = 0; + a.last_update = now(); + }); + } } - ACTION( SystemAccount, cancel_unstake_vote_request ) { - uint64_t request_id; + ACTION( SystemAccount, unstake_vote_deferred ) { + account_name voter; - EOSLIB_SERIALIZE( cancel_unstake_vote_request, (request_id) ) + EOSLIB_SERIALIZE( unstake_vote_deferred, (voter) ) }; - static void on( const cancel_unstake_vote_request& cancel_req ) { - unstake_requests_table requests( SystemAccount, SystemAccount ); - auto ptr = requests.find( cancel_req.request_id ); - eosio_assert( bool(ptr), "unstake vote request not found" ); + static void on( const unstake_vote_deferred& usv) { + require_auth( usv.voter ); + account_votes_index_type avotes( SystemAccount, SystemAccount ); + const auto* acv = avotes.find( usv.voter ); + eosio_assert( bool(acv), "stake not found" ); - require_auth( ptr->account ); - increase_voting_power( ptr->account, ptr->current_amount ); - requests.remove( *ptr ); + auto weeks = (now() - acv->last_unstake_time) / unstake_pay_period; + eosio_assert( 0 == weeks, "less than one week since last unstaking balance transfer" ); + + auto unstake_amount = std::min(weeks * acv->unstake_per_week, acv->unstaking); + uint32_t new_trx_id = unstake_amount < acv->unstaking ? /* XXX send_deferred() */ 0 : 0; + + currency::inline_transfer( usv.voter, SystemAccount, unstake_amount, "unstake voting" ); + + avotes.update( *acv, 0, [&](account_votes& a) { + a.unstaking -= unstake_amount; + a.deferred_trx_id = new_trx_id; + a.last_unstake_time = a.last_unstake_time + weeks * unstake_pay_period; + }); } ACTION( SystemAccount, vote_producer ) { @@ -528,7 +532,6 @@ namespace eosiosystem { static void on( const block& ) { update_elected_producers(); - process_unstake_requests(); } }; } From a3d294fe3c541ae50d30f67ffc1bbedaa3fd3458 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 27 Feb 2018 13:19:38 -0500 Subject: [PATCH 0041/1048] singleton for inflation voting outcome --- producers_election.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/producers_election.hpp b/producers_election.hpp index 963d89e8..972da18a 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,7 @@ namespace eosiosystem { using eosio::member; using eosio::bytes; using eosio::print; + using eosio::singleton; using eosio::transaction; template @@ -61,6 +63,8 @@ namespace eosiosystem { indexed_by > > producer_info_index_type; + typedef singleton inflation_singleton; + struct account_votes { account_name owner = 0; account_name proxy = 0; @@ -163,9 +167,6 @@ namespace eosiosystem { acv = &avotes.emplace( voter, [&]( account_votes& a ) { a.owner = voter; a.last_update = now(); - a.proxy = 0; - a.is_proxy = 0; - a.proxied_votes = 0; a.staked = amount; }); } else { @@ -272,6 +273,8 @@ namespace eosiosystem { }; set_blockchain_parameters(&concensus); + + inflation_singleton::set( inflation_rate[median] ); } static void on( const stake_vote& sv ) { From 4567d7f696eb08e98458187a887493ea6b2a8738 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 27 Feb 2018 13:46:17 -0500 Subject: [PATCH 0042/1048] some types/variables name changed to more meaningfull ones --- producers_election.hpp | 82 +++++++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 41 deletions(-) diff --git a/producers_election.hpp b/producers_election.hpp index 972da18a..c4de2360 100644 --- a/producers_election.hpp +++ b/producers_election.hpp @@ -61,7 +61,7 @@ namespace eosiosystem { typedef eosio::multi_index< N(producervote), producer_info, indexed_by > - > producer_info_index_type; + > producers_table; typedef singleton inflation_singleton; @@ -83,7 +83,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) }; - typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; + typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_table; struct producer_config { @@ -115,7 +115,7 @@ namespace eosiosystem { static void on( const register_producer& reg ) { require_auth( reg.producer ); - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + producers_table producers_tbl( SystemAccount, SystemAccount ); const auto* existing = producers_tbl.find( reg.producer ); eosio_assert( !existing, "producer already registered" ); @@ -143,11 +143,11 @@ namespace eosiosystem { static void on( const change_producer_preferences& change) { require_auth( change.producer ); - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); - const auto* ptr = producers_tbl.find( change.producer ); - eosio_assert( bool(ptr), "producer is not registered" ); + producers_table producers_tbl( SystemAccount, SystemAccount ); + const auto* prod = producers_tbl.find( change.producer ); + eosio_assert( bool(prod), "producer is not registered" ); - producers_tbl.update( *ptr, change.producer, [&]( producer_info& info ){ + producers_tbl.update( *prod, change.producer, [&]( producer_info& info ){ info.prefs = change.prefs; }); } @@ -160,7 +160,7 @@ namespace eosiosystem { }; static void increase_voting_power( account_name voter, system_token_type amount ) { - account_votes_index_type avotes( SystemAccount, SystemAccount ); + account_votes_table avotes( SystemAccount, SystemAccount ); const auto* acv = avotes.find( voter ); if( !acv ) { @@ -189,11 +189,11 @@ namespace eosiosystem { } if ( producers ) { - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + producers_table producers_tbl( SystemAccount, SystemAccount ); for( auto p : *producers ) { - auto ptr = producers_tbl.find( p ); - eosio_assert( bool(ptr), "never existed producer" ); //data corruption - producers_tbl.update( *ptr, 0, [&]( auto& v ) { + auto prod = producers_tbl.find( p ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& v ) { v.total_votes += amount.quantity; }); } @@ -201,7 +201,7 @@ namespace eosiosystem { } static void update_elected_producers() { - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + producers_table producers_tbl( SystemAccount, SystemAccount ); auto& idx = producers_tbl.template get<>( N(prototalvote) ); std::array target_block_size; @@ -294,7 +294,7 @@ namespace eosiosystem { static void on( const unstake_vote& usv ) { require_auth( usv.voter ); - account_votes_index_type avotes( SystemAccount, SystemAccount ); + account_votes_table avotes( SystemAccount, SystemAccount ); const auto* acv = avotes.find( usv.voter ); eosio_assert( bool(acv), "stake not found" ); @@ -328,7 +328,7 @@ namespace eosiosystem { } if ( producers ) { - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + producers_table producers_tbl( SystemAccount, SystemAccount ); for( auto p : *producers ) { auto prod = producers_tbl.find( p ); eosio_assert( bool(prod), "never existed producer" ); //data corruption @@ -359,7 +359,7 @@ namespace eosiosystem { static void on( const unstake_vote_deferred& usv) { require_auth( usv.voter ); - account_votes_index_type avotes( SystemAccount, SystemAccount ); + account_votes_table avotes( SystemAccount, SystemAccount ); const auto* acv = avotes.find( usv.voter ); eosio_assert( bool(acv), "stake not found" ); @@ -405,27 +405,27 @@ namespace eosiosystem { eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); } - account_votes_index_type avotes( SystemAccount, SystemAccount ); - auto ptr = avotes.find( vp.voter ); + account_votes_table avotes( SystemAccount, SystemAccount ); + auto voter = avotes.find( vp.voter ); - eosio_assert( bool(ptr), "no stake to vote" ); - if ( ptr->is_proxy ) { + eosio_assert( bool(voter), "no stake to vote" ); + if ( voter->is_proxy ) { eosio_assert( vp.proxy == 0 , "accounts elected to be proxy are not allowed to use another proxy" ); } //find old producers, update old proxy if needed const std::vector* old_producers = nullptr; - if( ptr->proxy ) { - if ( ptr->proxy == vp.proxy ) { + if( voter->proxy ) { + if ( voter->proxy == vp.proxy ) { return; // nothing changed } - auto old_proxy = avotes.find( ptr->proxy ); - avotes.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= ptr->staked.quantity; } ); + auto old_proxy = avotes.find( voter->proxy ); + avotes.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) old_producers = &old_proxy->producers; } } else { - old_producers = &ptr->producers; + old_producers = &voter->producers; } //find new producers, update new proxy if needed @@ -433,13 +433,13 @@ namespace eosiosystem { if ( vp.proxy ) { auto new_proxy = avotes.find( vp.proxy ); eosio_assert( new_proxy->is_proxy, "selected proxy has not elected to be a proxy" ); - avotes.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += ptr->staked.quantity; } ); + avotes.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); new_producers = &new_proxy->producers; } else { new_producers = &vp.producers; } - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + producers_table producers_tbl( SystemAccount, SystemAccount ); if ( old_producers ) { //old_producers == 0 if proxy has stoped being a proxy and votes were taken back from producers at that moment //revoke votes only from no longer elected @@ -448,7 +448,7 @@ namespace eosiosystem { for ( auto it = revoked.begin(); it != end_it; ++it ) { auto prod = producers_tbl.find( *it ); eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= ptr->staked.quantity; }); + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= voter->staked.quantity; }); } } @@ -461,11 +461,11 @@ namespace eosiosystem { if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers eosio_assert( prod->active(), "can vote only for active producers" ); } - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += ptr->staked.quantity; }); + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += voter->staked.quantity; }); } // save new values to the account itself - avotes.update( *ptr, 0, [&](account_votes& a) { + avotes.update( *voter, 0, [&](account_votes& a) { a.proxy = vp.proxy; a.last_update = now(); a.producers = vp.producers; @@ -481,12 +481,12 @@ namespace eosiosystem { static void on( const register_proxy& reg ) { require_auth( reg.proxy_to_register ); - account_votes_index_type avotes( SystemAccount, SystemAccount ); - auto ptr = avotes.find( reg.proxy_to_register ); - if ( ptr ) { - eosio_assert( ptr->is_proxy == 0, "account is already a proxy" ); - eosio_assert( ptr->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - avotes.update( *ptr, 0, [&](account_votes& a) { + account_votes_table avotes( SystemAccount, SystemAccount ); + auto voter = avotes.find( reg.proxy_to_register ); + if ( voter ) { + eosio_assert( voter->is_proxy == 0, "account is already a proxy" ); + eosio_assert( voter->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); + avotes.update( *voter, 0, [&](account_votes& a) { a.is_proxy = 1; a.last_update = now(); //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value @@ -512,16 +512,16 @@ namespace eosiosystem { static void on( const unregister_proxy& reg ) { require_auth( reg.proxy_to_unregister ); - account_votes_index_type avotes( SystemAccount, SystemAccount ); + account_votes_table avotes( SystemAccount, SystemAccount ); auto proxy = avotes.find( reg.proxy_to_unregister ); eosio_assert( bool(proxy), "proxy not found" ); eosio_assert( proxy->is_proxy == 1, "account is already a proxy" ); - producer_info_index_type producers_tbl( SystemAccount, SystemAccount ); + producers_table producers_tbl( SystemAccount, SystemAccount ); for ( auto p : proxy->producers ) { - auto ptr = producers_tbl.find( p ); - eosio_assert( bool(ptr), "never existed producer" ); //data corruption - producers_tbl.update( *ptr, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); + auto prod = producers_tbl.find( p ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); } avotes.update( *proxy, 0, [&](account_votes& a) { From e234a1666611676c95cc3b2a38923d0bffadb5cc Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 27 Feb 2018 14:30:23 -0500 Subject: [PATCH 0043/1048] producers_election.hpp renamed to voting.hpp --- producers_election.hpp => voting.hpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename producers_election.hpp => voting.hpp (100%) diff --git a/producers_election.hpp b/voting.hpp similarity index 100% rename from producers_election.hpp rename to voting.hpp From d6f8244a7fb0aa4b3beb19eacb4b8285701fc6c7 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 27 Feb 2018 14:31:05 -0500 Subject: [PATCH 0044/1048] producers_election.hpp renamed to voting.hpp fixes --- eosio.system.hpp | 22 +++++++++++----------- voting.hpp | 5 +++-- 2 files changed, 14 insertions(+), 13 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 7198d5db..99e87a79 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,7 +4,7 @@ */ #pragma once -#include "producers_election.hpp" +#include "voting.hpp" #include "delegate_bandwith.hpp" #include @@ -12,11 +12,11 @@ namespace eosiosystem { template - class contract : public producers_election, public delegate_bandwith { + class contract : public voting, public delegate_bandwith { public: - using producers_election::on; + using voting::on; using delegate_bandwith::on; - using pe = producers_election; + using pe = voting; using db = delegate_bandwith; static const account_name system_account = SystemAccount; @@ -34,13 +34,13 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, - typename producers_election::register_proxy, - typename producers_election::unregister_proxy, - typename producers_election::register_producer, - typename producers_election::vote_producer, - typename producers_election::stake_vote, - typename producers_election::unstake_vote, - typename producers_election::unstake_vote_deferred, + typename voting::register_proxy, + typename voting::unregister_proxy, + typename voting::register_producer, + typename voting::vote_producer, + typename voting::stake_vote, + typename voting::unstake_vote, + typename voting::unstake_vote_deferred, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); diff --git a/voting.hpp b/voting.hpp index c4de2360..74d0e852 100644 --- a/voting.hpp +++ b/voting.hpp @@ -27,7 +27,7 @@ namespace eosiosystem { using eosio::transaction; template - class producers_election { + class voting { public: static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; @@ -364,7 +364,8 @@ namespace eosiosystem { eosio_assert( bool(acv), "stake not found" ); auto weeks = (now() - acv->last_unstake_time) / unstake_pay_period; - eosio_assert( 0 == weeks, "less than one week since last unstaking balance transfer" ); + eosio_assert( 0 == weeks, "less than one week passed since last transfer or unstake request" ); + eosio_assert( 0 < acv->unstaking.quantity, "no unstaking money to transfer" ); auto unstake_amount = std::min(weeks * acv->unstake_per_week, acv->unstaking); uint32_t new_trx_id = unstake_amount < acv->unstaking ? /* XXX send_deferred() */ 0 : 0; From 51c25074098f0bf9c26d2462ef24a54013a9b366 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 28 Feb 2018 19:27:55 -0500 Subject: [PATCH 0045/1048] stake/unstake storage, producers vote for storage_reserve_ratio --- common.hpp | 31 +++++++++++++ delegate_bandwith.hpp | 101 ++++++++++++++++++++++++++++++------------ voting.hpp | 76 ++++++++++++++++--------------- 3 files changed, 144 insertions(+), 64 deletions(-) create mode 100644 common.hpp diff --git a/common.hpp b/common.hpp new file mode 100644 index 00000000..a0d25cdb --- /dev/null +++ b/common.hpp @@ -0,0 +1,31 @@ +#pragma once +#include + +#include +#include +#include +#include + +namespace eosiosystem { + + template + class common { + public: + static constexpr account_name system_account = SystemAccount; + typedef eosio::generic_currency< eosio::token > currency; + typedef typename currency::token_type system_token_type; + + struct eosio_parameters : eosio::blockchain_parameters { + uint32_t inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) + uint32_t storage_reserve_ratio = 1; // ratio * 1000 + uint64_t total_storage_bytes_reserved = 0; + system_token_type total_storage_stake; + eosio_parameters() { bzero(this, sizeof(*this)); } + + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) + (storage_reserve_ratio)(total_storage_bytes_reserved)(total_storage_stake) ) + }; + + typedef eosio::singleton eosio_parameters_singleton; + }; +} diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 29922f96..3c585005 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -3,6 +3,7 @@ * @copyright defined in eos/LICENSE.txt */ #pragma once +#include "common.hpp" #include #include @@ -27,19 +28,22 @@ namespace eosiosystem { template class delegate_bandwith { public: - static const account_name system_account = SystemAccount; - typedef eosio::generic_currency< eosio::token > currency; - typedef typename currency::token_type system_token_type; + static constexpr account_name system_account = SystemAccount; + using currency = typename common::currency; + using system_token_type = typename common::system_token_type; + using eosio_parameters = typename common::eosio_parameters; + using eosio_parameters_singleton = typename common::eosio_parameters_singleton; struct total_resources { account_name owner; typename currency::token_type total_net_weight; - typename currency::token_type total_cpu_weight; - uint32_t total_ram = 0; + typename currency::token_type total_cpu_weight; + typename currency::token_type total_storage_stake; + uint64_t total_storage_bytes = 0; uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ) + EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_storage_bytes) ) }; @@ -50,7 +54,9 @@ namespace eosiosystem { account_name from; account_name to; typename currency::token_type net_weight; - typename currency::token_type cpu_weight; + typename currency::token_type cpu_weight; + typename currency::token_type storage_stake; + uint64_t storage_bytes = 0; uint32_t start_pending_net_withdraw = 0; typename currency::token_type pending_net_withdraw; @@ -63,7 +69,7 @@ namespace eosiosystem { uint64_t primary_key()const { return to; } - EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) + EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) ) @@ -82,6 +88,7 @@ namespace eosiosystem { account_name receiver; typename currency::token_type stake_net_quantity; typename currency::token_type stake_cpu_quantity; + typename currency::token_type stake_storage_quantity; EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity) ) @@ -92,8 +99,9 @@ namespace eosiosystem { account_name receiver; typename currency::token_type unstake_net_quantity; typename currency::token_type unstake_cpu_quantity; + uint64_t unstake_storage_bytes; - EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) ) + EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity)(unstake_storage_bytes) ) }; /// new id options: @@ -104,7 +112,7 @@ namespace eosiosystem { eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); eosio_assert( del.stake_net_quantity.quantity >= 0, "must stake a positive amount" ); - auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity; + auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); @@ -115,19 +123,38 @@ namespace eosiosystem { //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); + auto parameters = eosio_parameters_singleton::get_or_default(); + auto token_supply = currency::get_total_supply();//.quantity; + //if ( token_supply == 0 || parameters not set) { what to do? } + + //make sure that there is no posibility of overflow here + uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) + * parameters.storage_reserve_ratio * del.stake_storage_quantity + / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + + uint64_t storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) + * parameters.storage_reserve_ratio * del.stake_storage_quantity + / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + + eosio_assert( 0 < storage_bytes, "stake is too small to increase memory even for 1 byte" ); + auto itr = del_index.find( del.receiver); if( itr != nullptr ) { del_index.emplace( del.from, [&]( auto& dbo ){ - dbo.from = del.from; - dbo.to = del.receiver; - dbo.net_weight = del.stake_net_quantity; - dbo.cpu_weight = del.stake_cpu_quantity; + dbo.from = del.from; + dbo.to = del.receiver; + dbo.net_weight = del.stake_net_quantity; + dbo.cpu_weight = del.stake_cpu_quantity; + dbo.storage_stake = del.stake_storage_quantity; + dbo.storage_bytes = storage_bytes; }); } else { del_index.update( *itr, del.from, [&]( auto& dbo ){ - dbo.net_weight = del.stake_net_quantity; - dbo.cpu_weight = del.stake_cpu_quantity; + dbo.net_weight += del.stake_net_quantity; + dbo.cpu_weight += del.stake_cpu_quantity; + dbo.storage_stake += del.stake_storage_quantity; + dbo.storage_bytes += storage_bytes; }); } @@ -135,28 +162,33 @@ namespace eosiosystem { if( tot_itr == nullptr ) { tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { tot.owner = del.receiver; - tot.total_net_weight += del.stake_net_quantity; - tot.total_cpu_weight += del.stake_cpu_quantity; + tot.total_net_weight = del.stake_net_quantity; + tot.total_cpu_weight = del.stake_cpu_quantity; + tot.total_storage_stake = del.stake_storage_quantity; + tot.total_storage_bytes = storage_bytes; }); } else { total_index.update( *tot_itr, 0, [&]( auto& tot ) { - tot.total_net_weight += del.stake_net_quantity; - tot.total_cpu_weight += del.stake_cpu_quantity; + tot.total_net_weight += del.stake_net_quantity; + tot.total_cpu_weight += del.stake_cpu_quantity; + tot.total_storage_stake += del.stake_storage_quantity; + tot.total_storage_bytes += storage_bytes; }); } - set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); + set_resource_limits( tot_itr->owner, tot_itr->total_storage_bytes, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); + + parameters.total_storage_bytes_reserved += storage_bytes; + parameters.total_storage_stake += del.stake_storage_quantity; + eosio_parameters_singleton::set(parameters); } // delegatebw static void on( const undelegatebw& del ) { eosio_assert( del.unstake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); eosio_assert( del.unstake_net_quantity.quantity >= 0, "must stake a positive amount" ); - auto total_stake = del.unstake_cpu_quantity + del.unstake_net_quantity; - eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); - require_auth( del.from ); del_bandwidth_index_type del_index( SystemAccount, del.from ); @@ -168,22 +200,35 @@ namespace eosiosystem { eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); + const auto& totals = total_index.get( del.receiver ); + system_token_type storage_stake_decrease = totals.total_storage_stake * del.unstake_storage_bytes / totals.total_storage_bytes; + + auto total_refund = del.unstake_cpu_quantity + del.unstake_net_quantity + storage_stake_decrease; + eosio_assert( total_refund.quantity >= 0, "must stake a positive amount" ); + del_index.update( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; dbo.cpu_weight -= del.unstake_cpu_quantity; - + dbo.storage_stake -= storage_stake_decrease; + dbo.storage_bytes -= del.unstake_storage_bytes; }); - const auto& totals = total_index.get( del.receiver ); total_index.update( totals, 0, [&]( auto& tot ) { tot.total_net_weight -= del.unstake_net_quantity; tot.total_cpu_weight -= del.unstake_cpu_quantity; + tot.total_storage_stake -= storage_stake_decrease; + tot.total_storage_bytes -= del.unstake_storage_bytes; }); - set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 ); + set_resource_limits( totals.owner, totals.total_storage_bytes, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 ); /// TODO: implement / enforce time delays on withdrawing - currency::inline_transfer( SystemAccount, del.from, total_stake, "unstake bandwidth" ); + currency::inline_transfer( SystemAccount, del.from, total_refund, "unstake bandwidth" ); + + auto parameters = eosio_parameters_singleton::get(); + parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; + parameters.total_storage_stake -= storage_stake_decrease; + eosio_parameters_singleton::set( parameters ); } // undelegatebw }; } diff --git a/voting.hpp b/voting.hpp index 74d0e852..58d67ab7 100644 --- a/voting.hpp +++ b/voting.hpp @@ -3,6 +3,8 @@ * @copyright defined in eos/LICENSE.txt */ #pragma once +#include "common.hpp" + #include #include #include @@ -26,30 +28,25 @@ namespace eosiosystem { using eosio::singleton; using eosio::transaction; + template class voting { public: - static const account_name system_account = SystemAccount; - typedef eosio::generic_currency< eosio::token > currency; - typedef typename currency::token_type system_token_type; + static constexpr account_name system_account = SystemAccount; + using currency = typename common::currency; + using system_token_type = typename common::system_token_type; + using eosio_parameters = typename common::eosio_parameters; + using eosio_parameters_singleton = typename common::eosio_parameters_singleton; static constexpr uint32_t max_unstake_requests = 10; static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week static constexpr uint32_t unstake_payments = 26; // during 26 weeks - struct producer_preferences : eosio::blockchain_parameters { - uint32_t inflation_rate; // inflation coefficient * 10000 (i.e. inflation in percent * 1000) - - producer_preferences() { bzero(this, sizeof(*this)); } - - EOSLIB_SERIALIZE_DERIVED( producer_preferences, eosio::blockchain_parameters, (inflation_rate) ) - }; - struct producer_info { account_name owner; uint64_t padding = 0; uint128_t total_votes = 0; - producer_preferences prefs; + eosio_parameters prefs; eosio::bytes packed_key; /// a packed public key object uint64_t primary_key()const { return owner; } @@ -63,7 +60,6 @@ namespace eosiosystem { indexed_by > > producers_table; - typedef singleton inflation_singleton; struct account_votes { account_name owner = 0; @@ -99,7 +95,7 @@ namespace eosiosystem { ACTION( SystemAccount, register_producer ) { account_name producer; bytes producer_key; - producer_preferences prefs; + eosio_parameters prefs; EOSLIB_SERIALIZE( register_producer, (producer)(producer_key)(prefs) ) }; @@ -132,15 +128,15 @@ namespace eosiosystem { }); } - ACTION( SystemAccount, change_producer_preferences ) { + ACTION( SystemAccount, change_eosio_parameters ) { account_name producer; bytes producer_key; - producer_preferences prefs; + eosio_parameters prefs; EOSLIB_SERIALIZE( register_producer, (producer)(producer_key)(prefs) ) }; - static void on( const change_producer_preferences& change) { + static void on( const change_eosio_parameters& change) { require_auth( change.producer ); producers_table producers_tbl( SystemAccount, SystemAccount ); @@ -218,6 +214,7 @@ namespace eosiosystem { std::array max_inline_action_size; std::array max_generated_transaction_size; std::array inflation_rate; + std::array storage_reserve_ratio; std::array elected; @@ -244,6 +241,7 @@ namespace eosiosystem { max_inline_action_size[n] = it->prefs.max_inline_action_size; max_generated_transaction_size[n] = it->prefs.max_generated_transaction_size; + storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; inflation_rate[n] = it->prefs.inflation_rate; ++n; } @@ -256,25 +254,31 @@ namespace eosiosystem { set_active_producers( elected.data(), n ); size_t median = n/2; - ::blockchain_parameters concensus = { - target_block_size[median], - max_block_size[median], - target_block_acts_per_scope[median], - max_block_acts_per_scope[median], - target_block_acts[median], - max_block_acts[median], - max_storage_size[median], - max_transaction_lifetime[median], - max_transaction_exec_time[median], - max_authority_depth[median], - max_inline_depth[median], - max_inline_action_size[median], - max_generated_transaction_size[median] - }; - - set_blockchain_parameters(&concensus); - - inflation_singleton::set( inflation_rate[median] ); + auto parameters = eosio_parameters_singleton::get(); + + parameters.target_block_size = target_block_size[median]; + parameters.max_block_size = max_block_size[median]; + parameters.target_block_acts_per_scope = target_block_acts_per_scope[median]; + parameters.max_block_acts_per_scope = max_block_acts_per_scope[median]; + parameters.target_block_acts = target_block_acts[median]; + parameters.max_block_acts = max_block_acts[median]; + parameters.max_storage_size = max_storage_size[median]; + parameters.max_transaction_lifetime = max_transaction_lifetime[median]; + parameters.max_transaction_exec_time = max_transaction_exec_time[median]; + parameters.max_authority_depth = max_authority_depth[median]; + parameters.max_inline_depth = max_inline_depth[median]; + parameters.max_inline_action_size = max_inline_action_size[median]; + parameters.max_generated_transaction_size = max_generated_transaction_size[median]; + parameters.storage_reserve_ratio = storage_reserve_ratio[median]; + parameters.inflation_rate = inflation_rate[median]; + + if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { + parameters.max_storage_size = parameters.total_storage_bytes_reserved; + } + + set_blockchain_parameters(¶meters); + + eosio_parameters_singleton::set( parameters ); } static void on( const stake_vote& sv ) { From 680fa9f028f2558b7e9ff5fd175bf7bf3d2098ee Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 1 Mar 2018 09:11:05 -0500 Subject: [PATCH 0046/1048] immediate unstake from voting (temporary solution) --- voting.hpp | 27 +++++++++++++++++++-------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/voting.hpp b/voting.hpp index 58d67ab7..acfb848f 100644 --- a/voting.hpp +++ b/voting.hpp @@ -296,6 +296,12 @@ namespace eosiosystem { EOSLIB_SERIALIZE( unstake_vote, (voter)(amount) ) }; + ACTION( SystemAccount, unstake_vote_deferred ) { + account_name voter; + + EOSLIB_SERIALIZE( unstake_vote_deferred, (voter) ) + }; + static void on( const unstake_vote& usv ) { require_auth( usv.voter ); account_votes_table avotes( SystemAccount, SystemAccount ); @@ -304,12 +310,14 @@ namespace eosiosystem { if ( 0 < usv.amount.quantity ) { eosio_assert( acv->staked < usv.amount, "cannot unstake more than total stake amount" ); - + /* if (acv->deferred_trx_id) { //XXX cancel_deferred_transaction(acv->deferred_trx_id); } - uint32_t new_trx_id = 0;//XXX send_deferred(); + unstake_vote_deferred dt; + dt.voter = usv.voter; + uint32_t new_trx_id = 0;//XXX send_deferred(dt); avotes.update( *acv, 0, [&](account_votes& a) { a.staked -= usv.amount; @@ -319,6 +327,15 @@ namespace eosiosystem { a.deferred_trx_id = new_trx_id; a.last_update = now(); }); + */ + + // Temporary code: immediate unstake + avotes.update( *acv, 0, [&](account_votes& a) { + a.staked -= usv.amount; + a.last_update = now(); + }); + currency::inline_transfer( usv.voter, SystemAccount, usv.amount, "unstake voting" ); + // end of temporary code const std::vector* producers = nullptr; if ( acv->proxy ) { @@ -355,12 +372,6 @@ namespace eosiosystem { } } - ACTION( SystemAccount, unstake_vote_deferred ) { - account_name voter; - - EOSLIB_SERIALIZE( unstake_vote_deferred, (voter) ) - }; - static void on( const unstake_vote_deferred& usv) { require_auth( usv.voter ); account_votes_table avotes( SystemAccount, SystemAccount ); From 544d96b716594cbf4715d1b924cdd84af5d5bf1d Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 1 Mar 2018 10:44:03 -0500 Subject: [PATCH 0047/1048] revert wrong changes related to set_active_producers --- voting.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/voting.hpp b/voting.hpp index acfb848f..8691373b 100644 --- a/voting.hpp +++ b/voting.hpp @@ -251,7 +251,8 @@ namespace eosiosystem { } --it; } - set_active_producers( elected.data(), n ); + // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp + //set_active_producers( elected.data(), n ); size_t median = n/2; auto parameters = eosio_parameters_singleton::get(); From 2433d9c9e97d1f79662efeccc310b3dabc596a29 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 2 Mar 2018 13:45:27 -0500 Subject: [PATCH 0048/1048] abi for eosio.system contract, draft of unit-test, get_blockchain_parameters API function, asset switched to signed int64_t, fixes --- common.hpp | 10 +++- delegate_bandwith.hpp | 108 +++++++++++++++++++----------------------- eosio.system.abi | 74 ++++++++++++++++++++++------- eosio.system.hpp | 4 +- 4 files changed, 117 insertions(+), 79 deletions(-) diff --git a/common.hpp b/common.hpp index a0d25cdb..0266ab94 100644 --- a/common.hpp +++ b/common.hpp @@ -17,15 +17,21 @@ namespace eosiosystem { struct eosio_parameters : eosio::blockchain_parameters { uint32_t inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) - uint32_t storage_reserve_ratio = 1; // ratio * 1000 + uint32_t storage_reserve_ratio = 1000; // ratio * 1000 uint64_t total_storage_bytes_reserved = 0; system_token_type total_storage_stake; - eosio_parameters() { bzero(this, sizeof(*this)); } EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) (storage_reserve_ratio)(total_storage_bytes_reserved)(total_storage_stake) ) }; typedef eosio::singleton eosio_parameters_singleton; + + static eosio_parameters& get_default_parameters() { + static eosio_parameters dp; + get_blockchain_parameters(&dp); + return dp; + } + }; } diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 3c585005..7491708e 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -18,6 +18,7 @@ #include namespace eosiosystem { + using eosio::asset; using eosio::indexed_by; using eosio::const_mem_fun; using eosio::bytes; @@ -36,14 +37,14 @@ namespace eosiosystem { struct total_resources { account_name owner; - typename currency::token_type total_net_weight; - typename currency::token_type total_cpu_weight; - typename currency::token_type total_storage_stake; - uint64_t total_storage_bytes = 0; + typename currency::token_type net_weight; + typename currency::token_type cpu_weight; + typename currency::token_type storage_stake; + uint64_t storage_bytes = 0; uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_storage_bytes) ) + EOSLIB_SERIALIZE( total_resources, (owner)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) }; @@ -57,7 +58,7 @@ namespace eosiosystem { typename currency::token_type cpu_weight; typename currency::token_type storage_stake; uint64_t storage_bytes = 0; - + /* uint32_t start_pending_net_withdraw = 0; typename currency::token_type pending_net_withdraw; uint64_t deferred_net_withdraw_handler = 0; @@ -65,57 +66,48 @@ namespace eosiosystem { uint32_t start_pending_cpu_withdraw = 0; typename currency::token_type pending_cpu_withdraw; uint64_t deferred_cpu_withdraw_handler = 0; - + */ uint64_t primary_key()const { return to; } EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) - (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) - (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler) ) + /* (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) + (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler)*/ ) }; typedef eosio::multi_index< N(totalband), total_resources> total_resources_index_type; typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; - ACTION( SystemAccount, finshundel ) { - account_name from; - account_name to; - }; - ACTION( SystemAccount, delegatebw ) { - account_name from; - account_name receiver; - typename currency::token_type stake_net_quantity; - typename currency::token_type stake_cpu_quantity; - typename currency::token_type stake_storage_quantity; + account_name from; + account_name receiver; + asset stake_net_quantity; + asset stake_cpu_quantity; + asset stake_storage_quantity; - EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity) ) + EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity)(stake_storage_quantity) ) }; ACTION( SystemAccount, undelegatebw ) { - account_name from; - account_name receiver; - typename currency::token_type unstake_net_quantity; - typename currency::token_type unstake_cpu_quantity; - uint64_t unstake_storage_bytes; + account_name from; + account_name receiver; + asset unstake_net_quantity; + asset unstake_cpu_quantity; + uint64_t unstake_storage_bytes; EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity)(unstake_storage_bytes) ) }; - /// new id options: - // 1. hash + collision - // 2. incrementing count (key=> tablename - static void on( const delegatebw& del ) { - eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); - eosio_assert( del.stake_net_quantity.quantity >= 0, "must stake a positive amount" ); + eosio_assert( del.stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); + eosio_assert( del.stake_net_quantity.amount >= 0, "must stake a positive amount" ); + eosio_assert( del.stake_storage_quantity.amount >= 0, "must stake a positive amount" ); - auto total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; + system_token_type total_stake = system_token_type(del.stake_cpu_quantity) + system_token_type(del.stake_net_quantity) + system_token_type(del.stake_storage_quantity); eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); - require_auth( del.from ); del_bandwidth_index_type del_index( SystemAccount, del.from ); @@ -123,20 +115,20 @@ namespace eosiosystem { //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - auto parameters = eosio_parameters_singleton::get_or_default(); + auto parameters = eosio_parameters_singleton::exists() ? eosio_parameters_singleton::get() + : common::get_default_parameters(); auto token_supply = currency::get_total_supply();//.quantity; - //if ( token_supply == 0 || parameters not set) { what to do? } //make sure that there is no posibility of overflow here uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - * parameters.storage_reserve_ratio * del.stake_storage_quantity + * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; uint64_t storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) - * parameters.storage_reserve_ratio * del.stake_storage_quantity + * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - eosio_assert( 0 < storage_bytes, "stake is too small to increase memory even for 1 byte" ); + eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); auto itr = del_index.find( del.receiver); if( itr != nullptr ) { @@ -162,21 +154,21 @@ namespace eosiosystem { if( tot_itr == nullptr ) { tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { tot.owner = del.receiver; - tot.total_net_weight = del.stake_net_quantity; - tot.total_cpu_weight = del.stake_cpu_quantity; - tot.total_storage_stake = del.stake_storage_quantity; - tot.total_storage_bytes = storage_bytes; + tot.net_weight = del.stake_net_quantity; + tot.cpu_weight = del.stake_cpu_quantity; + tot.storage_stake = del.stake_storage_quantity; + tot.storage_bytes = storage_bytes; }); } else { total_index.update( *tot_itr, 0, [&]( auto& tot ) { - tot.total_net_weight += del.stake_net_quantity; - tot.total_cpu_weight += del.stake_cpu_quantity; - tot.total_storage_stake += del.stake_storage_quantity; - tot.total_storage_bytes += storage_bytes; + tot.net_weight += del.stake_net_quantity; + tot.cpu_weight += del.stake_cpu_quantity; + tot.storage_stake += del.stake_storage_quantity; + tot.storage_bytes += storage_bytes; }); } - set_resource_limits( tot_itr->owner, tot_itr->total_storage_bytes, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); + set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity, 0 ); currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); @@ -186,8 +178,8 @@ namespace eosiosystem { } // delegatebw static void on( const undelegatebw& del ) { - eosio_assert( del.unstake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); - eosio_assert( del.unstake_net_quantity.quantity >= 0, "must stake a positive amount" ); + eosio_assert( del.unstake_cpu_quantity.amount >= 0, "must unstake a positive amount" ); + eosio_assert( del.unstake_net_quantity.amount >= 0, "must unstake a positive amount" ); require_auth( del.from ); @@ -201,10 +193,10 @@ namespace eosiosystem { eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); const auto& totals = total_index.get( del.receiver ); - system_token_type storage_stake_decrease = totals.total_storage_stake * del.unstake_storage_bytes / totals.total_storage_bytes; + system_token_type storage_stake_decrease = totals.storage_stake * del.unstake_storage_bytes / totals.storage_bytes; - auto total_refund = del.unstake_cpu_quantity + del.unstake_net_quantity + storage_stake_decrease; - eosio_assert( total_refund.quantity >= 0, "must stake a positive amount" ); + auto total_refund = system_token_type(del.unstake_cpu_quantity) + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; + eosio_assert( total_refund.quantity >= 0, "must unstake a positive amount" ); del_index.update( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; @@ -214,16 +206,16 @@ namespace eosiosystem { }); total_index.update( totals, 0, [&]( auto& tot ) { - tot.total_net_weight -= del.unstake_net_quantity; - tot.total_cpu_weight -= del.unstake_cpu_quantity; - tot.total_storage_stake -= storage_stake_decrease; - tot.total_storage_bytes -= del.unstake_storage_bytes; + tot.net_weight -= del.unstake_net_quantity; + tot.cpu_weight -= del.unstake_cpu_quantity; + tot.storage_stake -= storage_stake_decrease; + tot.storage_bytes -= del.unstake_storage_bytes; }); - set_resource_limits( totals.owner, totals.total_storage_bytes, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 ); + set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity, 0 ); /// TODO: implement / enforce time delays on withdrawing - currency::inline_transfer( SystemAccount, del.from, total_refund, "unstake bandwidth" ); + currency::inline_transfer( SystemAccount, del.from, asset( total_refund.quantity ), "unstake bandwidth" ); auto parameters = eosio_parameters_singleton::get(); parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; diff --git a/eosio.system.abi b/eosio.system.abi index 41278cf6..e797dc57 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -1,5 +1,9 @@ { - "types": [], + "types": [{ + "new_type_name": "account_name", + "type": "name" + } + ], "structs": [{ "name": "transfer", "base": "", @@ -20,31 +24,72 @@ "name": "account", "base": "", "fields": [ - {"name":"key", "type":"name"}, + {"name":"currency", "type":"uint64"}, {"name":"balance", "type":"uint64"} ] },{ - "name": "nonce", + "name": "currency_stats", + "base": "", + "fields": [ + {"name":"currency", "type":"uint64"}, + {"name":"supply", "type":"uint64"} + ] + },{ + "name": "delegatebw", "base": "", "fields": [ - {"name":"value", "type":"string"} + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"stake_net", "type":"asset"}, + {"name":"stake_cpu", "type":"asset"}, + {"name":"stake_storage", "type":"asset"} + ] + },{ + "name": "undelegatebw", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"unstake_net", "type":"asset"}, + {"name":"unstake_cpu", "type":"asset"}, + {"name":"stake_storage_bytes", "type":"uint64"} + ] + },{ + "name": "total_resources", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"net_weight", "type":"uint64"}, + {"name":"cpu_weight", "type":"uint64"}, + {"name":"storage_stake", "type":"uint64"}, + {"name":"storage_bytes", "type":"uint64"} ] },{ "name": "regproducer", "base": "", "fields": [ - {"name":"producer", "type":"account_name"} + {"name":"producer", "type":"account_name"}, {"name":"producer_key", "type":"bytes"} ] },{ "name": "stakevote", "base": "", "fields": [ - {"name":"voter", "type":"account_name"} + {"name":"voter", "type":"account_name"}, {"name":"amount", "type":"asset"} ] + },{ + "name": "delegated_bandwidth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"to", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"storage_stake", "type":"asset"}, + {"name":"storage_bytes", "type":"uint64"} + ] } - ], "actions": [{ "name": "transfer", @@ -53,8 +98,11 @@ "name": "issue", "type": "issue" },{ - "name": "nonce", - "type": "nonce" + "name": "delegatebw", + "type": "delegatebw" + },{ + "name": "undelegatebw", + "type": "undelegatebw" },{ "name": "regproducer", "type": "regproducer" @@ -63,12 +111,6 @@ "type": "stakevote" } ], - "tables": [{ - "name": "account", - "type": "account", - "index_type": "i64", - "key_names" : ["key"], - "key_types" : ["name"] - } + "tables": [ ] } diff --git a/eosio.system.hpp b/eosio.system.hpp index 99e87a79..a0d7b394 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -18,9 +18,7 @@ namespace eosiosystem { using delegate_bandwith::on; using pe = voting; using db = delegate_bandwith; - - static const account_name system_account = SystemAccount; - typedef eosio::generic_currency< eosio::token > currency; + using currency = typename common::currency; ACTION( SystemAccount, nonce ) { eosio::string value; From 04e0ba0248c8c1a805b6cc681f2778f7733f2e17 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 2 Mar 2018 15:08:47 -0500 Subject: [PATCH 0049/1048] system contract test fixes --- delegate_bandwith.hpp | 10 +++++++--- eosio.system.abi | 2 +- eosio.system.cpp | 2 +- eosio.system.hpp | 4 ++-- 4 files changed, 11 insertions(+), 7 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 7491708e..633d6cd0 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -130,6 +130,7 @@ namespace eosiosystem { eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); + print( "delegatebw: from = ", del.from, " receiver = ", del.receiver, "\n" ); auto itr = del_index.find( del.receiver); if( itr != nullptr ) { del_index.emplace( del.from, [&]( auto& dbo ){ @@ -188,7 +189,9 @@ namespace eosiosystem { //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - const auto& dbw = del_index.get(del.receiver); + print ("undelegatebw: from = ", del.from, " receiver = ", del.receiver, "\n"); + const auto& dbw = del_index.get( del.receiver ); + eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); @@ -196,7 +199,7 @@ namespace eosiosystem { system_token_type storage_stake_decrease = totals.storage_stake * del.unstake_storage_bytes / totals.storage_bytes; auto total_refund = system_token_type(del.unstake_cpu_quantity) + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; - eosio_assert( total_refund.quantity >= 0, "must unstake a positive amount" ); + //eosio_assert( total_refund.quantity >= 0, "must unstake a positive amount" ); del_index.update( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; @@ -215,7 +218,8 @@ namespace eosiosystem { set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity, 0 ); /// TODO: implement / enforce time delays on withdrawing - currency::inline_transfer( SystemAccount, del.from, asset( total_refund.quantity ), "unstake bandwidth" ); + print( "undelegatebw: ", total_refund.quantity, "\n" ); + currency::inline_transfer( SystemAccount, del.from, asset( static_cast( total_refund.quantity )), "unstake bandwidth" ); auto parameters = eosio_parameters_singleton::get(); parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; diff --git a/eosio.system.abi b/eosio.system.abi index e797dc57..f205724f 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -52,7 +52,7 @@ {"name":"receiver", "type":"account_name"}, {"name":"unstake_net", "type":"asset"}, {"name":"unstake_cpu", "type":"asset"}, - {"name":"stake_storage_bytes", "type":"uint64"} + {"name":"unstake_bytes", "type":"uint64"} ] },{ "name": "total_resources", diff --git a/eosio.system.cpp b/eosio.system.cpp index 7d905ff0..98df43bc 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -11,7 +11,7 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t code, uint64_t act ) { - print( eosio::name(code), "::", eosio::name(act) ); + //print( eosio::name(code), "::", eosio::name(act) ); eosiosystem::contract::apply( code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index a0d7b394..a3b956b8 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -30,7 +30,8 @@ namespace eosiosystem { } static void apply( account_name code, action_name act ) { - if( !eosio::dispatch::delegatebw, + if ( !eosio::dispatch( code, act ) ) { + if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, typename voting::register_proxy, typename voting::unregister_proxy, @@ -40,7 +41,6 @@ namespace eosiosystem { typename voting::unstake_vote, typename voting::unstake_vote_deferred, nonce>( code, act) ) { - if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); } From 531f46f3835cf97e629eca2d077410730a989db8 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 2 Mar 2018 18:11:52 -0500 Subject: [PATCH 0050/1048] unit-test for system contract (failing) --- delegate_bandwith.hpp | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 633d6cd0..7066cc27 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -110,9 +110,6 @@ namespace eosiosystem { require_auth( del.from ); - del_bandwidth_index_type del_index( SystemAccount, del.from ); - total_resources_index_type total_index( SystemAccount, del.receiver ); - //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); auto parameters = eosio_parameters_singleton::exists() ? eosio_parameters_singleton::get() @@ -130,9 +127,9 @@ namespace eosiosystem { eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); - print( "delegatebw: from = ", del.from, " receiver = ", del.receiver, "\n" ); + del_bandwidth_index_type del_index( SystemAccount, del.from ); auto itr = del_index.find( del.receiver); - if( itr != nullptr ) { + if( itr == nullptr ) { del_index.emplace( del.from, [&]( auto& dbo ){ dbo.from = del.from; dbo.to = del.receiver; @@ -151,6 +148,7 @@ namespace eosiosystem { }); } + total_resources_index_type total_index( SystemAccount, del.receiver ); auto tot_itr = total_index.find( del.receiver ); if( tot_itr == nullptr ) { tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { @@ -184,22 +182,19 @@ namespace eosiosystem { require_auth( del.from ); - del_bandwidth_index_type del_index( SystemAccount, del.from ); - total_resources_index_type total_index( SystemAccount, del.receiver ); - //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - print ("undelegatebw: from = ", del.from, " receiver = ", del.receiver, "\n"); + del_bandwidth_index_type del_index( SystemAccount, del.from ); const auto& dbw = del_index.get( del.receiver ); - eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); + eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); - const auto& totals = total_index.get( del.receiver ); - system_token_type storage_stake_decrease = totals.storage_stake * del.unstake_storage_bytes / totals.storage_bytes; + system_token_type storage_stake_decrease = dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes; auto total_refund = system_token_type(del.unstake_cpu_quantity) + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; - //eosio_assert( total_refund.quantity >= 0, "must unstake a positive amount" ); + + eosio_assert( total_refund.quantity >= 0, "must unstake a positive amount" ); del_index.update( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; @@ -208,6 +203,8 @@ namespace eosiosystem { dbo.storage_bytes -= del.unstake_storage_bytes; }); + total_resources_index_type total_index( SystemAccount, del.receiver ); + const auto& totals = total_index.get( del.receiver ); total_index.update( totals, 0, [&]( auto& tot ) { tot.net_weight -= del.unstake_net_quantity; tot.cpu_weight -= del.unstake_cpu_quantity; @@ -218,7 +215,6 @@ namespace eosiosystem { set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity, 0 ); /// TODO: implement / enforce time delays on withdrawing - print( "undelegatebw: ", total_refund.quantity, "\n" ); currency::inline_transfer( SystemAccount, del.from, asset( static_cast( total_refund.quantity )), "unstake bandwidth" ); auto parameters = eosio_parameters_singleton::get(); From 71fc25b11d90918ad5b1d20d42cfb11783931129 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 5 Mar 2018 12:03:52 -0500 Subject: [PATCH 0051/1048] unit-tests + small bugfixes for system contract (delegate bandwith and storage) --- delegate_bandwith.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 7066cc27..2fd81cf7 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -105,8 +105,9 @@ namespace eosiosystem { eosio_assert( del.stake_net_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( del.stake_storage_quantity.amount >= 0, "must stake a positive amount" ); - system_token_type total_stake = system_token_type(del.stake_cpu_quantity) + system_token_type(del.stake_net_quantity) + system_token_type(del.stake_storage_quantity); - eosio_assert( total_stake.quantity >= 0, "must stake a positive amount" ); + system_token_type total_stake = system_token_type(del.stake_cpu_quantity) + + system_token_type(del.stake_net_quantity) + system_token_type(del.stake_storage_quantity); + eosio_assert( total_stake.quantity > 0, "must stake a positive amount" ); require_auth( del.from ); @@ -190,11 +191,14 @@ namespace eosiosystem { eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); - system_token_type storage_stake_decrease = dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes; + system_token_type storage_stake_decrease = 0 < dbw.storage_bytes ? + dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes + : system_token_type(0); - auto total_refund = system_token_type(del.unstake_cpu_quantity) + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; + auto total_refund = system_token_type(del.unstake_cpu_quantity) + + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; - eosio_assert( total_refund.quantity >= 0, "must unstake a positive amount" ); + eosio_assert( total_refund.quantity > 0, "must unstake a positive amount" ); del_index.update( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; From f9bc40be32fdc1a6ce1024e44152039aeecd1c6e Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 5 Mar 2018 15:07:43 -0500 Subject: [PATCH 0052/1048] unit-tests for system contract --- delegate_bandwith.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 2fd81cf7..46bbf1f1 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -129,7 +129,7 @@ namespace eosiosystem { eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); del_bandwidth_index_type del_index( SystemAccount, del.from ); - auto itr = del_index.find( del.receiver); + auto itr = del_index.find( del.receiver ); if( itr == nullptr ) { del_index.emplace( del.from, [&]( auto& dbo ){ dbo.from = del.from; From db130648c840238842e6f2da6691e2f7f2c5b1f3 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 5 Mar 2018 15:20:17 -0500 Subject: [PATCH 0053/1048] more correct bill_to in system contract --- delegate_bandwith.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 46bbf1f1..a5e3726c 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -160,7 +160,7 @@ namespace eosiosystem { tot.storage_bytes = storage_bytes; }); } else { - total_index.update( *tot_itr, 0, [&]( auto& tot ) { + total_index.update( *tot_itr, del.from == del.receiver ? del.from : 0, [&]( auto& tot ) { tot.net_weight += del.stake_net_quantity; tot.cpu_weight += del.stake_cpu_quantity; tot.storage_stake += del.stake_storage_quantity; From ab46c55271746dc343d7825e6a647ee889a18026 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 5 Mar 2018 18:11:48 -0500 Subject: [PATCH 0054/1048] call set_active_producers right --- voting.hpp | 35 ++++++++++++----------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/voting.hpp b/voting.hpp index 8691373b..3af261e8 100644 --- a/voting.hpp +++ b/voting.hpp @@ -51,9 +51,9 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } - bool active() const { return !packed_key.empty(); } + bool active() const { return packed_key == 4 + 33 /*serialized key size*/; } - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs) ) + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) ) }; typedef eosio::multi_index< N(producervote), producer_info, @@ -81,17 +81,6 @@ namespace eosiosystem { typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_table; - - struct producer_config { - account_name owner; - eosio::bytes packed_key; /// a packed public key object - - uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) - }; - - typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; - ACTION( SystemAccount, register_producer ) { account_name producer; bytes producer_key; @@ -118,13 +107,8 @@ namespace eosiosystem { producers_tbl.emplace( reg.producer, [&]( producer_info& info ){ info.owner = reg.producer; info.total_votes = 0; - info.prefs = reg.prefs; - }); - - producer_config_index_type proconfig( SystemAccount, SystemAccount ); - proconfig.emplace( reg.producer, [&]( auto& pc ) { - pc.owner = reg.producer; - pc.packed_key = reg.producer_key; + info.prefs = reg.prefs; + info.packed_key = reg.producer_key; }); } @@ -216,13 +200,17 @@ namespace eosiosystem { std::array inflation_rate; std::array storage_reserve_ratio; - std::array elected; + eosio::producer_schedule schedule; + schedule.producers.reserve(21); auto it = std::prev( idx.end() ); size_t n = 0; while ( n < 21 ) { if ( it->active() ) { - elected[n] = it->owner; + schedule.producers.emplace_back(); + schedule.producers.back().producer_name = it->owner; + std::copy(it->packed_key.begin(), it->packed_key.end(), + schedule.producers.back().block_signing_key.begin()); target_block_size[n] = it->prefs.target_block_size; max_block_size[n] = it->prefs.max_block_size; @@ -252,7 +240,8 @@ namespace eosiosystem { --it; } // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp - //set_active_producers( elected.data(), n ); + bytes packed_schedule = pack(schedule); + set_active_producers( packed_schedule.data(), packed_schedule.size() ); size_t median = n/2; auto parameters = eosio_parameters_singleton::get(); From b407fca63e92d56074f4f7e39757d0d30d6aebda Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 6 Mar 2018 11:47:25 -0500 Subject: [PATCH 0055/1048] unit-test for system contract (voting, first test), some variables and types renamed --- eosio.system.abi | 30 +++++++++--- eosio.system.hpp | 4 +- voting.hpp | 116 +++++++++++++++++++++++------------------------ 3 files changed, 83 insertions(+), 67 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index f205724f..fcf0e2d3 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -54,6 +54,17 @@ {"name":"unstake_cpu", "type":"asset"}, {"name":"unstake_bytes", "type":"uint64"} ] + },{ + "name": "delegated_bandwidth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"to", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"storage_stake", "type":"asset"}, + {"name":"storage_bytes", "type":"uint64"} + ] },{ "name": "total_resources", "base": "", @@ -79,15 +90,20 @@ {"name":"amount", "type":"asset"} ] },{ - "name": "delegated_bandwidth", + "name": "voter_info", "base": "", "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"storage_stake", "type":"asset"}, - {"name":"storage_bytes", "type":"uint64"} + {"name":"owner", "type":"account_name"}, + {"name":"proxy", "type":"account_name"}, + {"name":"last_update", "type":"uint32"}, + {"name":"is_proxy", "type":"uint32"}, + {"name":"staked", "type":"uint32"}, + {"name":"unstaking", "type":"uint32"}, + {"name":"unstake_per_week", "type":"uint32"}, + {"name":"proxied_votes", "type":"uint128"}, + {"name":"producers", "type":"account_name[]"}, + {"name":"deferred_trx_id", "type":"uint32"}, + {"name":"last_unstake", "type":"uint32"} ] } ], diff --git a/eosio.system.hpp b/eosio.system.hpp index a3b956b8..6846b3c3 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -37,8 +37,8 @@ namespace eosiosystem { typename voting::unregister_proxy, typename voting::register_producer, typename voting::vote_producer, - typename voting::stake_vote, - typename voting::unstake_vote, + typename voting::stakevote, + typename voting::unstakevote, typename voting::unstake_vote_deferred, nonce>( code, act) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); diff --git a/voting.hpp b/voting.hpp index 3af261e8..63f152ac 100644 --- a/voting.hpp +++ b/voting.hpp @@ -51,7 +51,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } - bool active() const { return packed_key == 4 + 33 /*serialized key size*/; } + bool active() const { return packed_key.size() == 4 + 33 /*serialized key size*/; } EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) ) }; @@ -61,7 +61,7 @@ namespace eosiosystem { > producers_table; - struct account_votes { + struct voter_info { account_name owner = 0; account_name proxy = 0; uint32_t last_update = 0; @@ -76,10 +76,10 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } - EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) + EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) }; - typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_table; + typedef eosio::multi_index< N(voters), voter_info> voters_table; ACTION( SystemAccount, register_producer ) { account_name producer; @@ -132,25 +132,25 @@ namespace eosiosystem { }); } - ACTION( SystemAccount, stake_vote ) { + ACTION( SystemAccount, stakevote ) { account_name voter; system_token_type amount; - EOSLIB_SERIALIZE( stake_vote, (voter)(amount) ) + EOSLIB_SERIALIZE( stakevote, (voter)(amount) ) }; - static void increase_voting_power( account_name voter, system_token_type amount ) { - account_votes_table avotes( SystemAccount, SystemAccount ); - const auto* acv = avotes.find( voter ); + static void increase_voting_power( account_name acnt, system_token_type amount ) { + voters_table voters_tbl( SystemAccount, SystemAccount ); + const auto* voter = voters_tbl.find( acnt ); - if( !acv ) { - acv = &avotes.emplace( voter, [&]( account_votes& a ) { - a.owner = voter; + if( !voter ) { + voter = &voters_tbl.emplace( acnt, [&]( voter_info& a ) { + a.owner = acnt; a.last_update = now(); a.staked = amount; }); } else { - avotes.update( *acv, 0, [&]( auto& av ) { + voters_tbl.update( *voter, 0, [&]( auto& av ) { av.last_update = now(); av.staked += amount; }); @@ -158,14 +158,14 @@ namespace eosiosystem { } const std::vector* producers = nullptr; - if ( acv->proxy ) { - auto proxy = avotes.find( acv->proxy ); - avotes.update( *proxy, 0, [&](account_votes& a) { a.proxied_votes += amount.quantity; } ); + if ( voter->proxy ) { + auto proxy = voters_tbl.find( voter->proxy ); + voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.quantity; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } } else { - producers = &acv->producers; + producers = &voter->producers; } if ( producers ) { @@ -271,7 +271,7 @@ namespace eosiosystem { eosio_parameters_singleton::set( parameters ); } - static void on( const stake_vote& sv ) { + static void on( const stakevote& sv ) { eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); require_auth( sv.voter ); @@ -279,11 +279,11 @@ namespace eosiosystem { currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); } - ACTION( SystemAccount, unstake_vote ) { + ACTION( SystemAccount, unstakevote ) { account_name voter; system_token_type amount; - EOSLIB_SERIALIZE( unstake_vote, (voter)(amount) ) + EOSLIB_SERIALIZE( unstakevote, (voter)(amount) ) }; ACTION( SystemAccount, unstake_vote_deferred ) { @@ -292,24 +292,24 @@ namespace eosiosystem { EOSLIB_SERIALIZE( unstake_vote_deferred, (voter) ) }; - static void on( const unstake_vote& usv ) { + static void on( const unstakevote& usv ) { require_auth( usv.voter ); - account_votes_table avotes( SystemAccount, SystemAccount ); - const auto* acv = avotes.find( usv.voter ); - eosio_assert( bool(acv), "stake not found" ); + voters_table voters_tbl( SystemAccount, SystemAccount ); + const auto* voter = voters_tbl.find( usv.voter ); + eosio_assert( bool(voter), "stake not found" ); if ( 0 < usv.amount.quantity ) { - eosio_assert( acv->staked < usv.amount, "cannot unstake more than total stake amount" ); + eosio_assert( voter->staked < usv.amount, "cannot unstake more than total stake amount" ); /* - if (acv->deferred_trx_id) { - //XXX cancel_deferred_transaction(acv->deferred_trx_id); + if (voter->deferred_trx_id) { + //XXX cancel_deferred_transaction(voter->deferred_trx_id); } unstake_vote_deferred dt; dt.voter = usv.voter; uint32_t new_trx_id = 0;//XXX send_deferred(dt); - avotes.update( *acv, 0, [&](account_votes& a) { + avotes.update( *voter, 0, [&](voter_info& a) { a.staked -= usv.amount; a.unstaking += a.unstaking + usv.amount; //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments @@ -320,7 +320,7 @@ namespace eosiosystem { */ // Temporary code: immediate unstake - avotes.update( *acv, 0, [&](account_votes& a) { + voters_tbl.update( *voter, 0, [&](voter_info& a) { a.staked -= usv.amount; a.last_update = now(); }); @@ -328,14 +328,14 @@ namespace eosiosystem { // end of temporary code const std::vector* producers = nullptr; - if ( acv->proxy ) { - auto proxy = avotes.find( acv->proxy ); - avotes.update( *proxy, 0, [&](account_votes& a) { a.proxied_votes -= usv.amount.quantity; } ); + if ( voter->proxy ) { + auto proxy = voters_tbl.find( voter->proxy ); + voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes -= usv.amount.quantity; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } } else { - producers = &acv->producers; + producers = &voter->producers; } if ( producers ) { @@ -349,10 +349,10 @@ namespace eosiosystem { } } } else { - if (acv->deferred_trx_id) { - //XXX cancel_deferred_transaction(acv->deferred_trx_id); + if (voter->deferred_trx_id) { + //XXX cancel_deferred_transaction(voter->deferred_trx_id); } - avotes.update( *acv, 0, [&](account_votes& a) { + voters_tbl.update( *voter, 0, [&](voter_info& a) { a.staked += a.unstaking; a.unstaking.quantity = 0; a.unstake_per_week.quantity = 0; @@ -364,20 +364,20 @@ namespace eosiosystem { static void on( const unstake_vote_deferred& usv) { require_auth( usv.voter ); - account_votes_table avotes( SystemAccount, SystemAccount ); - const auto* acv = avotes.find( usv.voter ); - eosio_assert( bool(acv), "stake not found" ); + voters_table voters_tbl( SystemAccount, SystemAccount ); + const auto* voter = voters_tbl.find( usv.voter ); + eosio_assert( bool(voter), "stake not found" ); - auto weeks = (now() - acv->last_unstake_time) / unstake_pay_period; + auto weeks = (now() - voter->last_unstake_time) / unstake_pay_period; eosio_assert( 0 == weeks, "less than one week passed since last transfer or unstake request" ); - eosio_assert( 0 < acv->unstaking.quantity, "no unstaking money to transfer" ); + eosio_assert( 0 < voter->unstaking.quantity, "no unstaking money to transfer" ); - auto unstake_amount = std::min(weeks * acv->unstake_per_week, acv->unstaking); - uint32_t new_trx_id = unstake_amount < acv->unstaking ? /* XXX send_deferred() */ 0 : 0; + auto unstake_amount = std::min(weeks * voter->unstake_per_week, voter->unstaking); + uint32_t new_trx_id = unstake_amount < voter->unstaking ? /* XXX send_deferred() */ 0 : 0; currency::inline_transfer( usv.voter, SystemAccount, unstake_amount, "unstake voting" ); - avotes.update( *acv, 0, [&](account_votes& a) { + voters_tbl.update( *voter, 0, [&](voter_info& a) { a.unstaking -= unstake_amount; a.deferred_trx_id = new_trx_id; a.last_unstake_time = a.last_unstake_time + weeks * unstake_pay_period; @@ -411,8 +411,8 @@ namespace eosiosystem { eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); } - account_votes_table avotes( SystemAccount, SystemAccount ); - auto voter = avotes.find( vp.voter ); + voters_table voters_tbl( SystemAccount, SystemAccount ); + auto voter = voters_tbl.find( vp.voter ); eosio_assert( bool(voter), "no stake to vote" ); if ( voter->is_proxy ) { @@ -425,8 +425,8 @@ namespace eosiosystem { if ( voter->proxy == vp.proxy ) { return; // nothing changed } - auto old_proxy = avotes.find( voter->proxy ); - avotes.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); + auto old_proxy = voters_tbl.find( voter->proxy ); + voters_tbl.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) old_producers = &old_proxy->producers; } @@ -437,9 +437,9 @@ namespace eosiosystem { //find new producers, update new proxy if needed const std::vector* new_producers = nullptr; if ( vp.proxy ) { - auto new_proxy = avotes.find( vp.proxy ); + auto new_proxy = voters_tbl.find( vp.proxy ); eosio_assert( new_proxy->is_proxy, "selected proxy has not elected to be a proxy" ); - avotes.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); + voters_tbl.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); new_producers = &new_proxy->producers; } else { new_producers = &vp.producers; @@ -471,7 +471,7 @@ namespace eosiosystem { } // save new values to the account itself - avotes.update( *voter, 0, [&](account_votes& a) { + voters_tbl.update( *voter, 0, [&](voter_info& a) { a.proxy = vp.proxy; a.last_update = now(); a.producers = vp.producers; @@ -487,18 +487,18 @@ namespace eosiosystem { static void on( const register_proxy& reg ) { require_auth( reg.proxy_to_register ); - account_votes_table avotes( SystemAccount, SystemAccount ); - auto voter = avotes.find( reg.proxy_to_register ); + voters_table voters_tbl( SystemAccount, SystemAccount ); + auto voter = voters_tbl.find( reg.proxy_to_register ); if ( voter ) { eosio_assert( voter->is_proxy == 0, "account is already a proxy" ); eosio_assert( voter->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - avotes.update( *voter, 0, [&](account_votes& a) { + voters_tbl.update( *voter, 0, [&](voter_info& a) { a.is_proxy = 1; a.last_update = now(); //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value }); } else { - avotes.emplace( reg.proxy_to_register, [&]( account_votes& a ) { + voters_tbl.emplace( reg.proxy_to_register, [&]( voter_info& a ) { a.owner = reg.proxy_to_register; a.last_update = now(); a.proxy = 0; @@ -518,8 +518,8 @@ namespace eosiosystem { static void on( const unregister_proxy& reg ) { require_auth( reg.proxy_to_unregister ); - account_votes_table avotes( SystemAccount, SystemAccount ); - auto proxy = avotes.find( reg.proxy_to_unregister ); + voters_table voters_tbl( SystemAccount, SystemAccount ); + auto proxy = voters_tbl.find( reg.proxy_to_unregister ); eosio_assert( bool(proxy), "proxy not found" ); eosio_assert( proxy->is_proxy == 1, "account is already a proxy" ); @@ -530,7 +530,7 @@ namespace eosiosystem { producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); } - avotes.update( *proxy, 0, [&](account_votes& a) { + voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.is_proxy = 0; a.last_update = now(); //a.proxied_votes should be kept in order to be able to reenable this proxy in the future From 236a46d9c91744e9ecdcf08da01cf338699d1c1e Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 6 Mar 2018 15:47:09 -0500 Subject: [PATCH 0056/1048] system contract bugfixes (stake/unstake to vote), unit-test --- eosio.system.abi | 10 ++++++++++ voting.hpp | 7 +++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index fcf0e2d3..ce271a11 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -89,6 +89,13 @@ {"name":"voter", "type":"account_name"}, {"name":"amount", "type":"asset"} ] + },{ + "name": "unstakevote", + "base": "", + "fields": [ + {"name":"voter", "type":"account_name"}, + {"name":"amount", "type":"asset"} + ] },{ "name": "voter_info", "base": "", @@ -125,6 +132,9 @@ },{ "name": "stakevote", "type": "stakevote" + },{ + "name": "unstakevote", + "type": "unstakevote" } ], "tables": [ diff --git a/voting.hpp b/voting.hpp index 63f152ac..a7f59e4a 100644 --- a/voting.hpp +++ b/voting.hpp @@ -154,7 +154,6 @@ namespace eosiosystem { av.last_update = now(); av.staked += amount; }); - } const std::vector* producers = nullptr; @@ -299,7 +298,7 @@ namespace eosiosystem { eosio_assert( bool(voter), "stake not found" ); if ( 0 < usv.amount.quantity ) { - eosio_assert( voter->staked < usv.amount, "cannot unstake more than total stake amount" ); + eosio_assert( usv.amount <= voter->staked, "cannot unstake more than total stake amount" ); /* if (voter->deferred_trx_id) { //XXX cancel_deferred_transaction(voter->deferred_trx_id); @@ -324,7 +323,7 @@ namespace eosiosystem { a.staked -= usv.amount; a.last_update = now(); }); - currency::inline_transfer( usv.voter, SystemAccount, usv.amount, "unstake voting" ); + currency::inline_transfer( SystemAccount, usv.voter, usv.amount, "unstake voting" ); // end of temporary code const std::vector* producers = nullptr; @@ -375,7 +374,7 @@ namespace eosiosystem { auto unstake_amount = std::min(weeks * voter->unstake_per_week, voter->unstaking); uint32_t new_trx_id = unstake_amount < voter->unstaking ? /* XXX send_deferred() */ 0 : 0; - currency::inline_transfer( usv.voter, SystemAccount, unstake_amount, "unstake voting" ); + currency::inline_transfer( SystemAccount, usv.voter, unstake_amount, "unstake voting" ); voters_tbl.update( *voter, 0, [&](voter_info& a) { a.unstaking -= unstake_amount; From da6c51e61726c0d92391ce3ee6f2cdee183a1872 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 7 Mar 2018 09:54:04 -0500 Subject: [PATCH 0057/1048] system contract fixes --- common.hpp | 15 +++++++---- delegate_bandwith.hpp | 10 ++++---- eosio.system.abi | 32 ++++++++++++++++++++++-- eosio.system.hpp | 2 +- voting.hpp | 58 ++++++++++++++++--------------------------- 5 files changed, 68 insertions(+), 49 deletions(-) diff --git a/common.hpp b/common.hpp index 0266ab94..d7c92df1 100644 --- a/common.hpp +++ b/common.hpp @@ -18,17 +18,22 @@ namespace eosiosystem { struct eosio_parameters : eosio::blockchain_parameters { uint32_t inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) uint32_t storage_reserve_ratio = 1000; // ratio * 1000 + + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) + (storage_reserve_ratio) ) + }; + + struct eosio_global_state : eosio_parameters { uint64_t total_storage_bytes_reserved = 0; system_token_type total_storage_stake; - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) - (storage_reserve_ratio)(total_storage_bytes_reserved)(total_storage_stake) ) + EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) ) }; - typedef eosio::singleton eosio_parameters_singleton; + typedef eosio::singleton global_state_singleton; - static eosio_parameters& get_default_parameters() { - static eosio_parameters dp; + static eosio_global_state& get_default_parameters() { + static eosio_global_state dp; get_blockchain_parameters(&dp); return dp; } diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index a5e3726c..917f3312 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -33,7 +33,7 @@ namespace eosiosystem { using currency = typename common::currency; using system_token_type = typename common::system_token_type; using eosio_parameters = typename common::eosio_parameters; - using eosio_parameters_singleton = typename common::eosio_parameters_singleton; + using global_state_singleton = typename common::global_state_singleton; struct total_resources { account_name owner; @@ -113,7 +113,7 @@ namespace eosiosystem { //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - auto parameters = eosio_parameters_singleton::exists() ? eosio_parameters_singleton::get() + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); auto token_supply = currency::get_total_supply();//.quantity; @@ -174,7 +174,7 @@ namespace eosiosystem { parameters.total_storage_bytes_reserved += storage_bytes; parameters.total_storage_stake += del.stake_storage_quantity; - eosio_parameters_singleton::set(parameters); + global_state_singleton::set(parameters); } // delegatebw static void on( const undelegatebw& del ) { @@ -221,10 +221,10 @@ namespace eosiosystem { /// TODO: implement / enforce time delays on withdrawing currency::inline_transfer( SystemAccount, del.from, asset( static_cast( total_refund.quantity )), "unstake bandwidth" ); - auto parameters = eosio_parameters_singleton::get(); + auto parameters = global_state_singleton::get(); parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; parameters.total_storage_stake -= storage_stake_decrease; - eosio_parameters_singleton::set( parameters ); + global_state_singleton::set( parameters ); } // undelegatebw }; } diff --git a/eosio.system.abi b/eosio.system.abi index ce271a11..e4740bbe 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -75,12 +75,40 @@ {"name":"storage_stake", "type":"uint64"}, {"name":"storage_bytes", "type":"uint64"} ] + },{ + "name": "eosio_parameters", + "base": "", + "fields": [ + {"name":"target_block_size", "type":"uint32"}, + {"name":"max_block_size", "type":"uint32"}, + {"name":"target_block_acts_per_scope", "type":"uint32"}, + {"name":"max_block_acts_per_scope", "type":"uint32"}, + {"name":"target_block_acts", "type":"uint32"}, + {"name":"max_block_acts", "type":"uint32"}, + {"name":"max_storage_size", "type":"uint64"}, + {"name":"max_transaction_lifetime", "type":"uint32"}, + {"name":"max_transaction_exec_time", "type":"uint32"}, + {"name":"max_authority_depth", "type":"uint16"}, + {"name":"max_inline_depth", "type":"uint16"}, + {"name":"max_inline_action_size", "type":"uint32"}, + {"name":"max_generated_transaction_size", "type":"uint32"}, + {"name":"inflation_rate", "type":"uint32"}, + {"name":"storage_reserve_ratio", "type":"uint32"}, + ] + },,{ + "name": "eosio_global_state", + "base": "eosio_parameters", + "fields": [ + {"name":"total_storage_bytes_reserved", "type":"uint64"}, + {"name":"total_storage_stake", "type":"uint64"} + ] },{ "name": "regproducer", "base": "", "fields": [ - {"name":"producer", "type":"account_name"}, - {"name":"producer_key", "type":"bytes"} + {"name":"producer", "type":"account_name"}, + {"name":"producer_key", "type":"bytes"}, + {"name":"prefs", "type":"eosio_parameters"} ] },{ "name": "stakevote", diff --git a/eosio.system.hpp b/eosio.system.hpp index 6846b3c3..e6e2763e 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -35,7 +35,7 @@ namespace eosiosystem { typename delegate_bandwith::undelegatebw, typename voting::register_proxy, typename voting::unregister_proxy, - typename voting::register_producer, + typename voting::regproducer, typename voting::vote_producer, typename voting::stakevote, typename voting::unstakevote, diff --git a/voting.hpp b/voting.hpp index a7f59e4a..01e746a0 100644 --- a/voting.hpp +++ b/voting.hpp @@ -36,7 +36,7 @@ namespace eosiosystem { using currency = typename common::currency; using system_token_type = typename common::system_token_type; using eosio_parameters = typename common::eosio_parameters; - using eosio_parameters_singleton = typename common::eosio_parameters_singleton; + using global_state_singleton = typename common::global_state_singleton; static constexpr uint32_t max_unstake_requests = 10; static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week @@ -51,7 +51,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } - bool active() const { return packed_key.size() == 4 + 33 /*serialized key size*/; } + bool active() const { return packed_key.size() == sizeof(public_key); } EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) ) }; @@ -81,12 +81,12 @@ namespace eosiosystem { typedef eosio::multi_index< N(voters), voter_info> voters_table; - ACTION( SystemAccount, register_producer ) { + ACTION( SystemAccount, regproducer ) { account_name producer; bytes producer_key; eosio_parameters prefs; - EOSLIB_SERIALIZE( register_producer, (producer)(producer_key)(prefs) ) + EOSLIB_SERIALIZE( regproducer, (producer)(producer_key)(prefs) ) }; /** @@ -97,39 +97,24 @@ namespace eosiosystem { * @pre authority of producer to register * */ - static void on( const register_producer& reg ) { + static void on( const regproducer& reg ) { require_auth( reg.producer ); producers_table producers_tbl( SystemAccount, SystemAccount ); - const auto* existing = producers_tbl.find( reg.producer ); - eosio_assert( !existing, "producer already registered" ); - - producers_tbl.emplace( reg.producer, [&]( producer_info& info ){ - info.owner = reg.producer; - info.total_votes = 0; - info.prefs = reg.prefs; - info.packed_key = reg.producer_key; - }); - } - - ACTION( SystemAccount, change_eosio_parameters ) { - account_name producer; - bytes producer_key; - eosio_parameters prefs; - - EOSLIB_SERIALIZE( register_producer, (producer)(producer_key)(prefs) ) - }; + const auto* prod = producers_tbl.find( reg.producer ); - static void on( const change_eosio_parameters& change) { - require_auth( change.producer ); - - producers_table producers_tbl( SystemAccount, SystemAccount ); - const auto* prod = producers_tbl.find( change.producer ); - eosio_assert( bool(prod), "producer is not registered" ); - - producers_tbl.update( *prod, change.producer, [&]( producer_info& info ){ - info.prefs = change.prefs; - }); + if ( prod ) { + producers_tbl.update( *prod, reg.producer, [&]( producer_info& info ){ + info.prefs = reg.prefs; + }); + } else { + producers_tbl.emplace( reg.producer, [&]( producer_info& info ){ + info.owner = reg.producer; + info.total_votes = 0; + info.prefs = reg.prefs; + info.packed_key = reg.producer_key; + }); + } } ACTION( SystemAccount, stakevote ) { @@ -208,8 +193,9 @@ namespace eosiosystem { if ( it->active() ) { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; + eosio_assert( sizeof(schedule.producers) == it->packed_key.size(), "size mismatch" ); std::copy(it->packed_key.begin(), it->packed_key.end(), - schedule.producers.back().block_signing_key.begin()); + schedule.producers); target_block_size[n] = it->prefs.target_block_size; max_block_size[n] = it->prefs.max_block_size; @@ -243,7 +229,7 @@ namespace eosiosystem { set_active_producers( packed_schedule.data(), packed_schedule.size() ); size_t median = n/2; - auto parameters = eosio_parameters_singleton::get(); + auto parameters = global_state_singleton::get(); parameters.target_block_size = target_block_size[median]; parameters.max_block_size = max_block_size[median]; @@ -267,7 +253,7 @@ namespace eosiosystem { set_blockchain_parameters(¶meters); - eosio_parameters_singleton::set( parameters ); + global_state_singleton::set( parameters ); } static void on( const stakevote& sv ) { From 2c14772e72c49d1d9f65b6dccd8f4df2fd178909 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 7 Mar 2018 09:59:08 -0500 Subject: [PATCH 0058/1048] Change multi_index primary find to return iterator rather than pointer. This makes our multi_index interface more consistent with Boost multi_index. --- eosio.system.hpp | 59 ++++++++++++++++++++++++------------------------ 1 file changed, 29 insertions(+), 30 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 9080da09..b1069a76 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -71,8 +71,8 @@ namespace eosiosystem { struct total_resources { account_name owner; - typename currency::token_type total_net_weight; - typename currency::token_type total_cpu_weight; + typename currency::token_type total_net_weight; + typename currency::token_type total_cpu_weight; uint32_t total_ram = 0; uint64_t primary_key()const { return owner; } @@ -87,8 +87,8 @@ namespace eosiosystem { struct delegated_bandwidth { account_name from; account_name to; - typename currency::token_type net_weight; - typename currency::token_type cpu_weight; + typename currency::token_type net_weight; + typename currency::token_type cpu_weight; uint32_t start_pending_net_withdraw = 0; typename currency::token_type pending_net_withdraw; @@ -98,7 +98,7 @@ namespace eosiosystem { typename currency::token_type pending_cpu_withdraw; uint64_t deferred_cpu_withdraw_handler = 0; - + uint64_t primary_key()const { return to; } EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) @@ -156,8 +156,8 @@ namespace eosiosystem { }; /// new id options: - // 1. hash + collision - // 2. incrementing count (key=> tablename + // 1. hash + collision + // 2. incrementing count (key=> tablename static void on( const delegatebw& del ) { eosio_assert( del.stake_cpu_quantity.quantity >= 0, "must stake a positive amount" ); @@ -175,10 +175,10 @@ namespace eosiosystem { //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); auto itr = del_index.find( del.receiver); - if( itr != nullptr ) { + if( itr != del_index.end() ) { del_index.emplace( del.from, [&]( auto& dbo ){ - dbo.from = del.from; - dbo.to = del.receiver; + dbo.from = del.from; + dbo.to = del.receiver; dbo.net_weight = del.stake_net_quantity; dbo.cpu_weight = del.stake_cpu_quantity; }); @@ -191,12 +191,12 @@ namespace eosiosystem { } auto tot_itr = total_index.find( del.receiver ); - if( tot_itr == nullptr ) { - tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { + if( tot_itr == total_index.end() ) { + tot_itr = total_index.iterator_to(total_index.emplace( del.from, [&]( auto& tot ) { tot.owner = del.receiver; tot.total_net_weight += del.stake_net_quantity; tot.total_cpu_weight += del.stake_cpu_quantity; - }); + })); } else { total_index.update( *tot_itr, 0, [&]( auto& tot ) { tot.total_net_weight += del.stake_net_quantity; @@ -252,20 +252,20 @@ namespace eosiosystem { /** - * This method will create a producr_config and producer_votes object for 'producer' + * This method will create a producr_config and producer_votes object for 'producer' * * @pre producer is not already registered * @pre producer to register is an account - * @pre authority of producer to register - * + * @pre authority of producer to register + * */ static void on( const regproducer& reg ) { auto producer = reg.producer; require_auth( producer ); producer_votes_index_type votes( SystemAccount, SystemAccount ); - const auto* existing = votes.find( producer ); - eosio_assert( !existing, "producer already registered" ); + auto existing = votes.find( producer ); + eosio_assert( existing == votes.end(), "producer already registered" ); votes.emplace( producer, [&]( auto& pv ){ pv.owner = producer; @@ -293,13 +293,13 @@ namespace eosiosystem { account_votes_index_type avotes( SystemAccount, SystemAccount ); - const auto* acv = avotes.find( sv.voter ); - if( !acv ) { - acv = &avotes.emplace( sv.voter, [&]( auto& av ) { + auto acv = avotes.find( sv.voter ); + if( acv == avotes.end() ) { + acv = avotes.iterator_to(avotes.emplace( sv.voter, [&]( auto& av ) { av.owner = sv.voter; av.last_update = now(); av.proxy = 0; - }); + })); } uint128_t old_weight = acv->staked.quantity; @@ -318,7 +318,7 @@ namespace eosiosystem { av.last_update = now(); av.staked += sv.amount; }); - + currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); } @@ -354,7 +354,7 @@ namespace eosiosystem { for( const auto& p : existing.producers ) producer_vote_changes[p].first = old_weight; - for( const auto& p : vp.producers ) + for( const auto& p : vp.producers ) producer_vote_changes[p].second = new_weight; producer_votes_index_type votes( SystemAccount, SystemAccount ); @@ -385,9 +385,9 @@ namespace eosiosystem { static void apply( account_name code, action_name act ) { - if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { @@ -396,8 +396,7 @@ namespace eosiosystem { } } - } /// apply + } /// apply }; -} /// eosiosystem - +} /// eosiosystem From 9f421dc499b9d7e8f9a7044135d23cff37eba421 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 5 Mar 2018 18:33:08 -0500 Subject: [PATCH 0059/1048] On-block message progress --- eosio.system.hpp | 92 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index e6e2763e..508d5102 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -11,6 +11,86 @@ namespace eosiosystem { + template + inline eosio::datastream& operator<<(eosio::datastream& ds, const public_key& pk) { + ds.write((const char*)&pk, sizeof(pk)); + return ds; + } + + template + inline eosio::datastream& operator>>(eosio::datastream& ds, public_key& pk) { + ds.read((char*)&pk, sizeof(pk)); + return ds; + } + + struct producer_key { + account_name producer_name; + public_key block_signing_key; + + EOSLIB_SERIALIZE(producer_key, (producer_name)(block_signing_key)) + }; + + struct producer_schedule { + uint32_t version; + std::vector producers; + + EOSLIB_SERIALIZE(producer_schedule, (version)(producers)) + }; + + struct producer_schedule_optional { + uint64_t value[((sizeof(producer_schedule)+7)/8)]; + // producer_schedule value; + bool valid; + // EOSLIB_SERIALIZE(producer_schedule_optional, (value)(valid)) + }; + + template + inline eosio::datastream& operator<<(eosio::datastream& ds, const producer_schedule_optional& op) { + ds.write((const char*)&op.value, sizeof(op.value)); + ds << op.valid; + return ds; + } + + template + inline eosio::datastream& operator>>(eosio::datastream& ds, producer_schedule_optional& op) { + ds.read((char*)&op.value, sizeof(op.value)); + ds >> op.valid; + /* + char opt = 0; + ds >> opt; + if (opt) { + o = producer_schedule_optional(); + ds >> *o; + } + */ + return ds; + } + + /* + template + inline eosio::datastream& operator<<(eosio::datastream& ds, const producer_schedule op) { + ds << op.version << op.producers; + return ds; + } + + template + inline eosio::datastream& operator>>(eosio::datastream& ds, producer_schedule& op) { + ds >> op.version >> op.producers; + return ds; + } + */ + struct block_header { + checksum256 previous; + time timestamp; + checksum256 transaction_mroot; + checksum256 action_mroot; + checksum256 block_mroot; + account_name producer; + // producer_schedule new_producers; + producer_schedule_optional new_producers; + EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot)(producer)(new_producers)) + }; + template class contract : public voting, public delegate_bandwith { public: @@ -29,7 +109,18 @@ namespace eosiosystem { static void on( const nonce& ) { } + ACTION(SystemAccount, onblock) { + block_header header; + // account_name header; + EOSLIB_SERIALIZE(onblock, (header)) + }; + + static void on(const onblock& ob) { + + } + static void apply( account_name code, action_name act ) { +<<<<<<< HEAD if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, @@ -40,6 +131,7 @@ namespace eosiosystem { typename voting::stakevote, typename voting::unstakevote, typename voting::unstake_vote_deferred, + typename voting::onblock, nonce>( code, act) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); From 923daf87ae2542fcbe31d727a61e16819b1b8f01 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 6 Mar 2018 09:20:01 -0500 Subject: [PATCH 0060/1048] On-block message progress 2 --- eosio.system.hpp | 52 +++++------------------------------------------- 1 file changed, 5 insertions(+), 47 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 508d5102..eb77190c 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -6,6 +6,7 @@ #include "voting.hpp" #include "delegate_bandwith.hpp" +#include #include @@ -37,48 +38,6 @@ namespace eosiosystem { EOSLIB_SERIALIZE(producer_schedule, (version)(producers)) }; - struct producer_schedule_optional { - uint64_t value[((sizeof(producer_schedule)+7)/8)]; - // producer_schedule value; - bool valid; - // EOSLIB_SERIALIZE(producer_schedule_optional, (value)(valid)) - }; - - template - inline eosio::datastream& operator<<(eosio::datastream& ds, const producer_schedule_optional& op) { - ds.write((const char*)&op.value, sizeof(op.value)); - ds << op.valid; - return ds; - } - - template - inline eosio::datastream& operator>>(eosio::datastream& ds, producer_schedule_optional& op) { - ds.read((char*)&op.value, sizeof(op.value)); - ds >> op.valid; - /* - char opt = 0; - ds >> opt; - if (opt) { - o = producer_schedule_optional(); - ds >> *o; - } - */ - return ds; - } - - /* - template - inline eosio::datastream& operator<<(eosio::datastream& ds, const producer_schedule op) { - ds << op.version << op.producers; - return ds; - } - - template - inline eosio::datastream& operator>>(eosio::datastream& ds, producer_schedule& op) { - ds >> op.version >> op.producers; - return ds; - } - */ struct block_header { checksum256 previous; time timestamp; @@ -86,9 +45,9 @@ namespace eosiosystem { checksum256 action_mroot; checksum256 block_mroot; account_name producer; - // producer_schedule new_producers; - producer_schedule_optional new_producers; - EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot)(producer)(new_producers)) + optional new_producers; + + EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot)(producer)(new_producers)) }; template @@ -111,7 +70,7 @@ namespace eosiosystem { ACTION(SystemAccount, onblock) { block_header header; - // account_name header; + EOSLIB_SERIALIZE(onblock, (header)) }; @@ -120,7 +79,6 @@ namespace eosiosystem { } static void apply( account_name code, action_name act ) { -<<<<<<< HEAD if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, From 2bb9b87569ae03729d7c46bd59cb1c57a12a92ca Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 6 Mar 2018 15:51:16 -0500 Subject: [PATCH 0061/1048] On-block message progress 3 --- eosio.system.hpp | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index eb77190c..808b28f8 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -12,40 +12,28 @@ namespace eosiosystem { - template - inline eosio::datastream& operator<<(eosio::datastream& ds, const public_key& pk) { - ds.write((const char*)&pk, sizeof(pk)); - return ds; - } - - template - inline eosio::datastream& operator>>(eosio::datastream& ds, public_key& pk) { - ds.read((char*)&pk, sizeof(pk)); - return ds; - } - - struct producer_key { + struct PACKED(producer_key) { account_name producer_name; public_key block_signing_key; EOSLIB_SERIALIZE(producer_key, (producer_name)(block_signing_key)) }; - struct producer_schedule { + struct PACKED(producer_schedule) { uint32_t version; std::vector producers; EOSLIB_SERIALIZE(producer_schedule, (version)(producers)) }; - struct block_header { + struct PACKED(block_header) { checksum256 previous; time timestamp; checksum256 transaction_mroot; checksum256 action_mroot; checksum256 block_mroot; account_name producer; - optional new_producers; + eosio::optional new_producers; EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot)(producer)(new_producers)) }; @@ -72,10 +60,9 @@ namespace eosiosystem { block_header header; EOSLIB_SERIALIZE(onblock, (header)) - }; + }; static void on(const onblock& ob) { - } static void apply( account_name code, action_name act ) { From 6f1bf16791eff1c8f8c4d48071dd3391823bf0b8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 7 Mar 2018 10:19:19 -0500 Subject: [PATCH 0062/1048] Fixed build issue --- eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 808b28f8..77aa28a2 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -76,7 +76,7 @@ namespace eosiosystem { typename voting::stakevote, typename voting::unstakevote, typename voting::unstake_vote_deferred, - typename voting::onblock, + onblock, nonce>( code, act) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); From 33d042016e9ff37fa559b0f9a3a9226d69a267e7 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 7 Mar 2018 11:22:36 -0500 Subject: [PATCH 0063/1048] Change multi_index emplace, update, and remove to use iterators. This makes our multi_index interface a little more consistent with Boost multi_index. --- eosio.system.hpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index b1069a76..1818c5bf 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -184,7 +184,7 @@ namespace eosiosystem { }); } else { - del_index.update( *itr, del.from, [&]( auto& dbo ){ + del_index.update( itr, del.from, [&]( auto& dbo ){ dbo.net_weight = del.stake_net_quantity; dbo.cpu_weight = del.stake_cpu_quantity; }); @@ -192,13 +192,13 @@ namespace eosiosystem { auto tot_itr = total_index.find( del.receiver ); if( tot_itr == total_index.end() ) { - tot_itr = total_index.iterator_to(total_index.emplace( del.from, [&]( auto& tot ) { + tot_itr = total_index.emplace( del.from, [&]( auto& tot ) { tot.owner = del.receiver; tot.total_net_weight += del.stake_net_quantity; tot.total_cpu_weight += del.stake_cpu_quantity; - })); + }); } else { - total_index.update( *tot_itr, 0, [&]( auto& tot ) { + total_index.update( tot_itr, 0, [&]( auto& tot ) { tot.total_net_weight += del.stake_net_quantity; tot.total_cpu_weight += del.stake_cpu_quantity; }); @@ -229,14 +229,14 @@ namespace eosiosystem { eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); - del_index.update( dbw, del.from, [&]( auto& dbo ){ + del_index.update( del_index.iterator_to(dbw), del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; dbo.cpu_weight -= del.unstake_cpu_quantity; }); const auto& totals = total_index.get( del.receiver ); - total_index.update( totals, 0, [&]( auto& tot ) { + total_index.update( total_index.iterator_to(totals), 0, [&]( auto& tot ) { tot.total_net_weight -= del.unstake_net_quantity; tot.total_cpu_weight -= del.unstake_cpu_quantity; }); @@ -295,11 +295,11 @@ namespace eosiosystem { auto acv = avotes.find( sv.voter ); if( acv == avotes.end() ) { - acv = avotes.iterator_to(avotes.emplace( sv.voter, [&]( auto& av ) { + acv = avotes.emplace( sv.voter, [&]( auto& av ) { av.owner = sv.voter; av.last_update = now(); av.proxy = 0; - })); + }); } uint128_t old_weight = acv->staked.quantity; @@ -308,13 +308,13 @@ namespace eosiosystem { producer_votes_index_type votes( SystemAccount, SystemAccount ); for( auto p : acv->producers ) { - votes.update( votes.get( p ), 0, [&]( auto& v ) { + votes.update( votes.find( p ), 0, [&]( auto& v ) { v.total_votes -= old_weight; v.total_votes += new_weight; }); } - avotes.update( *acv, 0, [&]( auto av ) { + avotes.update( acv, 0, [&]( auto av ) { av.last_update = now(); av.staked += sv.amount; }); @@ -361,14 +361,14 @@ namespace eosiosystem { for( const auto& delta : producer_vote_changes ) { if( delta.second.first != delta.second.second ) { const auto& provote = votes.get( delta.first ); - votes.update( provote, 0, [&]( auto& pv ){ + votes.update( votes.iterator_to(provote), 0, [&]( auto& pv ){ pv.total_votes -= delta.second.first; pv.total_votes += delta.second.second; }); } } - avotes.update( existing, 0, [&]( auto& av ) { + avotes.update( avotes.iterator_to(existing), 0, [&]( auto& av ) { av.proxy = vp.proxy; av.last_update = now(); av.producers = vp.producers; From a8a7f4ae2b0a5a982f3c66dd4eccb2c1781c13a6 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 7 Mar 2018 13:52:10 -0500 Subject: [PATCH 0064/1048] Rename update to modify and remove to erase. Also bring back overloads of modify and erase that take a reference to the object. --- eosio.system.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 1818c5bf..84f4c175 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -184,7 +184,7 @@ namespace eosiosystem { }); } else { - del_index.update( itr, del.from, [&]( auto& dbo ){ + del_index.modify( itr, del.from, [&]( auto& dbo ){ dbo.net_weight = del.stake_net_quantity; dbo.cpu_weight = del.stake_cpu_quantity; }); @@ -198,7 +198,7 @@ namespace eosiosystem { tot.total_cpu_weight += del.stake_cpu_quantity; }); } else { - total_index.update( tot_itr, 0, [&]( auto& tot ) { + total_index.modify( tot_itr, 0, [&]( auto& tot ) { tot.total_net_weight += del.stake_net_quantity; tot.total_cpu_weight += del.stake_cpu_quantity; }); @@ -229,14 +229,14 @@ namespace eosiosystem { eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); - del_index.update( del_index.iterator_to(dbw), del.from, [&]( auto& dbo ){ + del_index.modify( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; dbo.cpu_weight -= del.unstake_cpu_quantity; }); const auto& totals = total_index.get( del.receiver ); - total_index.update( total_index.iterator_to(totals), 0, [&]( auto& tot ) { + total_index.modify( totals, 0, [&]( auto& tot ) { tot.total_net_weight -= del.unstake_net_quantity; tot.total_cpu_weight -= del.unstake_cpu_quantity; }); @@ -308,13 +308,13 @@ namespace eosiosystem { producer_votes_index_type votes( SystemAccount, SystemAccount ); for( auto p : acv->producers ) { - votes.update( votes.find( p ), 0, [&]( auto& v ) { + votes.modify( votes.get( p ), 0, [&]( auto& v ) { v.total_votes -= old_weight; v.total_votes += new_weight; }); } - avotes.update( acv, 0, [&]( auto av ) { + avotes.modify( acv, 0, [&]( auto av ) { av.last_update = now(); av.staked += sv.amount; }); @@ -361,14 +361,14 @@ namespace eosiosystem { for( const auto& delta : producer_vote_changes ) { if( delta.second.first != delta.second.second ) { const auto& provote = votes.get( delta.first ); - votes.update( votes.iterator_to(provote), 0, [&]( auto& pv ){ + votes.modify( provote, 0, [&]( auto& pv ){ pv.total_votes -= delta.second.first; pv.total_votes += delta.second.second; }); } } - avotes.update( avotes.iterator_to(existing), 0, [&]( auto& av ) { + avotes.modify( existing, 0, [&]( auto& av ) { av.proxy = vp.proxy; av.last_update = now(); av.producers = vp.producers; From e694526a8b9f16302ad4a7d0161cefdb3d7ab1de Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 7 Mar 2018 16:58:34 -0500 Subject: [PATCH 0065/1048] better way to compare fc::variant in tests --- common.hpp | 3 +-- voting.hpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/common.hpp b/common.hpp index d7c92df1..1e295995 100644 --- a/common.hpp +++ b/common.hpp @@ -19,8 +19,7 @@ namespace eosiosystem { uint32_t inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) uint32_t storage_reserve_ratio = 1000; // ratio * 1000 - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) - (storage_reserve_ratio) ) + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) ) }; struct eosio_global_state : eosio_parameters { diff --git a/voting.hpp b/voting.hpp index 01e746a0..a113f5c7 100644 --- a/voting.hpp +++ b/voting.hpp @@ -56,7 +56,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) ) }; - typedef eosio::multi_index< N(producervote), producer_info, + typedef eosio::multi_index< N(producerinfo), producer_info, indexed_by > > producers_table; From cb127b8487336044146b10cebab071353f104710 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 8 Mar 2018 09:22:52 -0500 Subject: [PATCH 0066/1048] unregister producer, more tests for system contracts, change in static_variant reverted --- eosio.system.abi | 11 ++++++++++- voting.hpp | 31 +++++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index e4740bbe..aa83a00c 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -95,13 +95,22 @@ {"name":"inflation_rate", "type":"uint32"}, {"name":"storage_reserve_ratio", "type":"uint32"}, ] - },,{ + },{ "name": "eosio_global_state", "base": "eosio_parameters", "fields": [ {"name":"total_storage_bytes_reserved", "type":"uint64"}, {"name":"total_storage_stake", "type":"uint64"} ] + },{ + "name": "producer_info", + "base": "", + "fields": [ + {"name":"owner", "type":"uint64"}, + {"name":"total_votes", "type":"uint128"}, + {"name":"prefs", "type":"eosio_parameters"}, + {"name":"packed_key", "type":"uint8[]"} + ] },{ "name": "regproducer", "base": "", diff --git a/voting.hpp b/voting.hpp index a113f5c7..99ed959e 100644 --- a/voting.hpp +++ b/voting.hpp @@ -43,11 +43,11 @@ namespace eosiosystem { static constexpr uint32_t unstake_payments = 26; // during 26 weeks struct producer_info { - account_name owner; - uint64_t padding = 0; - uint128_t total_votes = 0; + account_name owner; + uint64_t padding = 0; + uint128_t total_votes = 0; eosio_parameters prefs; - eosio::bytes packed_key; /// a packed public key object + eosio::bytes packed_key; /// a packed public key object uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } @@ -82,8 +82,8 @@ namespace eosiosystem { typedef eosio::multi_index< N(voters), voter_info> voters_table; ACTION( SystemAccount, regproducer ) { - account_name producer; - bytes producer_key; + account_name producer; + bytes producer_key; eosio_parameters prefs; EOSLIB_SERIALIZE( regproducer, (producer)(producer_key)(prefs) ) @@ -106,6 +106,7 @@ namespace eosiosystem { if ( prod ) { producers_tbl.update( *prod, reg.producer, [&]( producer_info& info ){ info.prefs = reg.prefs; + info.packed_key = reg.producer_key; }); } else { producers_tbl.emplace( reg.producer, [&]( producer_info& info ){ @@ -117,6 +118,24 @@ namespace eosiosystem { } } + ACTION( SystemAccount, unregproducer ) { + account_name producer; + + EOSLIB_SERIALIZE( unregproducer, (producer) ) + }; + + static void on( const unregproducer& unreg ) { + require_auth( unreg.producer ); + + producers_table producers_tbl( SystemAccount, SystemAccount ); + const auto* prod = producers_tbl.find( unreg.producer ); + eosio_assert( bool(prod), "producer not found" ); + + producers_tbl.update( *prod, 0, [&]( producer_info& info ){ + info.packed_key.clear(); + }); + } + ACTION( SystemAccount, stakevote ) { account_name voter; system_token_type amount; From c2c463cf7cca457bce43083ad7b707165768e4f3 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 8 Mar 2018 13:55:57 -0500 Subject: [PATCH 0067/1048] more tests and bugfix in variant comparison --- eosio.system.abi | 9 +++++++++ eosio.system.hpp | 3 ++- voting.hpp | 12 ++++++------ 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index aa83a00c..3aa0eac4 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -119,6 +119,12 @@ {"name":"producer_key", "type":"bytes"}, {"name":"prefs", "type":"eosio_parameters"} ] + },{ + "name": "unregprod", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"} + ] },{ "name": "stakevote", "base": "", @@ -166,6 +172,9 @@ },{ "name": "regproducer", "type": "regproducer" + },{ + "name": "unregprod", + "type": "unregprod" },{ "name": "stakevote", "type": "stakevote" diff --git a/eosio.system.hpp b/eosio.system.hpp index 77aa28a2..bf958dd0 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -72,7 +72,8 @@ namespace eosiosystem { typename voting::register_proxy, typename voting::unregister_proxy, typename voting::regproducer, - typename voting::vote_producer, + typename voting::unregprod, + typename voting::voteproducer, typename voting::stakevote, typename voting::unstakevote, typename voting::unstake_vote_deferred, diff --git a/voting.hpp b/voting.hpp index 99ed959e..4f6c86b9 100644 --- a/voting.hpp +++ b/voting.hpp @@ -118,13 +118,13 @@ namespace eosiosystem { } } - ACTION( SystemAccount, unregproducer ) { + ACTION( SystemAccount, unregprod ) { account_name producer; - EOSLIB_SERIALIZE( unregproducer, (producer) ) + EOSLIB_SERIALIZE( unregprod, (producer) ) }; - static void on( const unregproducer& unreg ) { + static void on( const unregprod& unreg ) { require_auth( unreg.producer ); producers_table producers_tbl( SystemAccount, SystemAccount ); @@ -388,12 +388,12 @@ namespace eosiosystem { }); } - ACTION( SystemAccount, vote_producer ) { + ACTION( SystemAccount, voteproducer ) { account_name voter; account_name proxy; std::vector producers; - EOSLIB_SERIALIZE( vote_producer, (voter)(proxy)(producers) ) + EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) }; /** @@ -403,7 +403,7 @@ namespace eosiosystem { * @pre vp.voter must authorize this action * @pre voter must have previously staked some EOS for voting */ - static void on( const vote_producer& vp ) { + static void on( const voteproducer& vp ) { require_auth( vp.voter ); //validate input From 8b548870d817f044b9e57d3f4d8183fd380e26d8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 8 Mar 2018 18:24:24 -0500 Subject: [PATCH 0068/1048] On-block producer payment --- common.hpp | 35 +++++++++++++++++++++++++++++++++-- eosio.system.hpp | 47 ++++++++++++++++++++++++++++++++++++++++++++--- voting.hpp | 45 ++++++++++++++++++++++++++++++--------------- 3 files changed, 107 insertions(+), 20 deletions(-) diff --git a/common.hpp b/common.hpp index d7c92df1..3927408e 100644 --- a/common.hpp +++ b/common.hpp @@ -14,12 +14,25 @@ namespace eosiosystem { static constexpr account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; typedef typename currency::token_type system_token_type; + static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) + static constexpr uint8_t currency_decimals = currency_symbol & 0xFF; // 4 + static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation +#warning "change to config parameter" + static constexpr uint32_t producer_repititions = 12; + static constexpr uint32_t blocks_per_cycle = 21 * producer_repititions; struct eosio_parameters : eosio::blockchain_parameters { - uint32_t inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) + uint32_t percent_of_max_inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) uint32_t storage_reserve_ratio = 1000; // ratio * 1000 + system_token_type payment_per_block; + system_token_type payment_to_leaky_bucket; + time first_block_time_in_cycle = 0; + + // time last_produced_block_time = 0; + // bool is_begining_of_producer_cycle = true; + // uint32_t blocks_in_producer_cycle = 0; - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) (storage_reserve_ratio) ) }; @@ -39,4 +52,22 @@ namespace eosiosystem { } }; + + std::pair int_logarithm_one_plus(uint32_t x) { + static const uint64_t denom = 10000; + uint64_t ret = 0; + uint64_t x_power = x; + const uint8_t n = 4; + static constexpr uint64_t ten_power = denom * denom * denom * denom; + for (uint64_t i = 0, p = ten_power; i < n; ++i) { + if (i % 2 == 1) + ret -= x_power * p / (i+1); + else + ret += x_power * p / (i+1); + x_power *= x; + p /= denom; + } + return std::make_pair(ret * denom/ten_power, denom); + } + } diff --git a/eosio.system.hpp b/eosio.system.hpp index 77aa28a2..6e35f0f7 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -11,7 +11,7 @@ #include namespace eosiosystem { - + /* struct PACKED(producer_key) { account_name producer_name; public_key block_signing_key; @@ -25,7 +25,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE(producer_schedule, (version)(producers)) }; - + */ struct PACKED(block_header) { checksum256 previous; time timestamp; @@ -33,7 +33,7 @@ namespace eosiosystem { checksum256 action_mroot; checksum256 block_mroot; account_name producer; - eosio::optional new_producers; + eosio::optional new_producers; EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot)(producer)(new_producers)) }; @@ -46,6 +46,9 @@ namespace eosiosystem { using pe = voting; using db = delegate_bandwith; using currency = typename common::currency; + using system_token_type = typename common::system_token_type; + using producers_table = typename pe::producers_table; + using global_state_singleton = typename voting::global_state_singleton; ACTION( SystemAccount, nonce ) { eosio::string value; @@ -56,6 +59,28 @@ namespace eosiosystem { static void on( const nonce& ) { } + static bool is_new_cycle(time block_time) { + auto parameters = global_state_singleton::get(); + if (parameters.first_block_time_in_cycle == 0) { + parameters.first_block_time_in_cycle = block_time; + global_state_singleton::set(parameters); + return true; + } + + static const time slot = 500; + static const uint32_t slots_per_cycle = common::blocks_per_cycle; + const time delta = block_time - parameters.first_block_time_in_cycle; + uint32_t time_slots = delta / slot; + if (time_slots >= common::blocks_per_cycle) { + time beginning_of_cycle = block_time - (time_slots % slots_per_cycle) * slot; + parameters.first_block_time_in_cycle = beginning_of_cycle; + global_state_singleton::set(parameters); + return true; + } + + return false; + } + ACTION(SystemAccount, onblock) { block_header header; @@ -63,6 +88,22 @@ namespace eosiosystem { }; static void on(const onblock& ob) { + if (is_new_cycle(ob.header.timestamp)) { + voting::update_elected_producers(); + } + producers_table producers_tbl(SystemAccount, SystemAccount); + account_name producer = ob.header.producer; + const system_token_type payment = global_state_singleton::get_or_default().payment_per_block; + const auto* prod = producers_tbl.find(producer); + // This check is needed in a real production system + // eosio_assert(prod != nullptr, "something wrong here"); + if (prod != nullptr) { + producers_tbl.update(*prod, 0, [&](auto& p) { + p.per_block_payments += payment; + p.last_produced_block_time = ob.header.timestamp; + }); + } + } static void apply( account_name code, action_name act ) { diff --git a/voting.hpp b/voting.hpp index 01e746a0..27e90727 100644 --- a/voting.hpp +++ b/voting.hpp @@ -38,22 +38,26 @@ namespace eosiosystem { using eosio_parameters = typename common::eosio_parameters; using global_state_singleton = typename common::global_state_singleton; + static const uint32_t max_inflation_rate = common::max_inflation_rate; static constexpr uint32_t max_unstake_requests = 10; static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week static constexpr uint32_t unstake_payments = 26; // during 26 weeks + static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year struct producer_info { account_name owner; uint64_t padding = 0; uint128_t total_votes = 0; - eosio_parameters prefs; + eosio_parameters prefs; eosio::bytes packed_key; /// a packed public key object + system_token_type per_block_payments; + time last_produced_block_time = 0; uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } bool active() const { return packed_key.size() == sizeof(public_key); } - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) ) + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key)(per_block_payments)(last_produced_block_time) ) }; typedef eosio::multi_index< N(producervote), producer_info, @@ -164,9 +168,20 @@ namespace eosiosystem { } } + static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { + const system_token_type token_supply = currency::get_total_supply(); + const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate; + const auto& inflation_ratio = int_logarithm_one_plus(inflation_rate); + return (token_supply * inflation_ratio.first) / (inflation_ratio.second * blocks_per_year); + } + + static system_token_type daily_producer_payment() { + return system_token_type(0); + } + static void update_elected_producers() { producers_table producers_tbl( SystemAccount, SystemAccount ); - auto& idx = producers_tbl.template get<>( N(prototalvote) ); + auto idx = producers_tbl.template get_index(); std::array target_block_size; std::array max_block_size; @@ -181,21 +196,21 @@ namespace eosiosystem { std::array max_inline_depth; std::array max_inline_action_size; std::array max_generated_transaction_size; - std::array inflation_rate; + std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; eosio::producer_schedule schedule; schedule.producers.reserve(21); - auto it = std::prev( idx.end() ); + auto it = idx.end(); + --it; size_t n = 0; while ( n < 21 ) { if ( it->active() ) { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; - eosio_assert( sizeof(schedule.producers) == it->packed_key.size(), "size mismatch" ); - std::copy(it->packed_key.begin(), it->packed_key.end(), - schedule.producers); + eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); + std::copy(it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data); target_block_size[n] = it->prefs.target_block_size; max_block_size[n] = it->prefs.max_block_size; @@ -215,7 +230,7 @@ namespace eosiosystem { max_generated_transaction_size[n] = it->prefs.max_generated_transaction_size; storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; - inflation_rate[n] = it->prefs.inflation_rate; + percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; ++n; } @@ -245,7 +260,12 @@ namespace eosiosystem { parameters.max_inline_action_size = max_inline_action_size[median]; parameters.max_generated_transaction_size = max_generated_transaction_size[median]; parameters.storage_reserve_ratio = storage_reserve_ratio[median]; - parameters.inflation_rate = inflation_rate[median]; + parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; + + // derived parameters + parameters.payment_per_block = payment_per_block(parameters.percent_of_max_inflation_rate / 2); + parameters.payment_to_leaky_bucket = payment_per_block(parameters.percent_of_max_inflation_rate) + - parameters.payment_per_block; if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { parameters.max_storage_size = parameters.total_storage_bytes_reserved; @@ -522,10 +542,5 @@ namespace eosiosystem { }); } - struct block {}; - - static void on( const block& ) { - update_elected_producers(); - } }; } From e79b5b66b4635b5e89f3c371731190963421afa6 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 9 Mar 2018 15:31:55 -0500 Subject: [PATCH 0069/1048] unit test for system contract --- eosio.system.abi | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index 3aa0eac4..069a9957 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -93,7 +93,7 @@ {"name":"max_inline_action_size", "type":"uint32"}, {"name":"max_generated_transaction_size", "type":"uint32"}, {"name":"inflation_rate", "type":"uint32"}, - {"name":"storage_reserve_ratio", "type":"uint32"}, + {"name":"storage_reserve_ratio", "type":"uint32"} ] },{ "name": "eosio_global_state", @@ -139,6 +139,14 @@ {"name":"voter", "type":"account_name"}, {"name":"amount", "type":"asset"} ] + },{ + "name": "voteproducer", + "base": "", + "fields": [ + {"name":"voter", "type":"account_name"}, + {"name":"proxy", "type":"account_name"}, + {"name":"producers", "type":"account_name[]"} + ] },{ "name": "voter_info", "base": "", @@ -181,6 +189,9 @@ },{ "name": "unstakevote", "type": "unstakevote" + },{ + "name": "voteproducer", + "type": "voteproducer" } ], "tables": [ From 5fb723a7358557712312cccd998c1ad385a7a268 Mon Sep 17 00:00:00 2001 From: Jonathan Giszczak Date: Fri, 9 Mar 2018 16:18:58 -0600 Subject: [PATCH 0070/1048] Validate JSON format of contract abi files. From a script by @joneric. --- eosio.system.abi | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 41278cf6..9fa2ef22 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -33,14 +33,14 @@ "name": "regproducer", "base": "", "fields": [ - {"name":"producer", "type":"account_name"} + {"name":"producer", "type":"account_name"}, {"name":"producer_key", "type":"bytes"} ] },{ "name": "stakevote", "base": "", "fields": [ - {"name":"voter", "type":"account_name"} + {"name":"voter", "type":"account_name"}, {"name":"amount", "type":"asset"} ] } From cb562d69d1f218737199424822922e4d5b75353c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 9 Mar 2018 17:39:45 -0500 Subject: [PATCH 0071/1048] Producer payment --- common.hpp | 78 ++++++++++++++++++++--------------------- eosio.system.hpp | 90 +++++++++++++++++++++++++++++++++++++++++------- voting.hpp | 22 +++++++----- 3 files changed, 129 insertions(+), 61 deletions(-) diff --git a/common.hpp b/common.hpp index 3927408e..796fee9f 100644 --- a/common.hpp +++ b/common.hpp @@ -10,47 +10,46 @@ namespace eosiosystem { template class common { - public: - static constexpr account_name system_account = SystemAccount; - typedef eosio::generic_currency< eosio::token > currency; - typedef typename currency::token_type system_token_type; - static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) - static constexpr uint8_t currency_decimals = currency_symbol & 0xFF; // 4 - static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation + public: + static constexpr account_name system_account = SystemAccount; + typedef eosio::generic_currency< eosio::token > currency; + typedef typename currency::token_type system_token_type; + static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) + static constexpr uint8_t currency_decimals = currency_symbol & 0xFF; // 4 + static const uint32_t max_inflation_rate = 5; // 5% annual inflation #warning "change to config parameter" - static constexpr uint32_t producer_repititions = 12; - static constexpr uint32_t blocks_per_cycle = 21 * producer_repititions; + static constexpr uint32_t producer_repititions = 12; + static constexpr uint32_t blocks_per_cycle = 21 * producer_repititions; + static const uint32_t mseconds_per_day = 24 * 3600 * 1000; + static constexpr uint32_t days_per_4years = 1461; + + struct eosio_parameters : eosio::blockchain_parameters { + uint32_t percent_of_max_inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) + uint32_t storage_reserve_ratio = 1000; // ratio * 1000 + system_token_type payment_per_block = system_token_type(); + system_token_type payment_to_eos_bucket = system_token_type(); + time first_block_time_in_cycle = 0; + time last_bucket_fill_time = 0; + system_token_type eos_bucket = system_token_type(); + + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) + (payment_per_block)(last_bucket_fill_time)(eos_bucket) ) + }; - struct eosio_parameters : eosio::blockchain_parameters { - uint32_t percent_of_max_inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) - uint32_t storage_reserve_ratio = 1000; // ratio * 1000 - system_token_type payment_per_block; - system_token_type payment_to_leaky_bucket; - time first_block_time_in_cycle = 0; - - // time last_produced_block_time = 0; - // bool is_begining_of_producer_cycle = true; - // uint32_t blocks_in_producer_cycle = 0; + struct eosio_global_state : eosio_parameters { + uint64_t total_storage_bytes_reserved = 0; + system_token_type total_storage_stake; - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) - (storage_reserve_ratio) ) - }; + EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) ) + }; - struct eosio_global_state : eosio_parameters { - uint64_t total_storage_bytes_reserved = 0; - system_token_type total_storage_stake; - - EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) ) - }; - - typedef eosio::singleton global_state_singleton; - - static eosio_global_state& get_default_parameters() { - static eosio_global_state dp; - get_blockchain_parameters(&dp); - return dp; - } + typedef eosio::singleton global_state_singleton; + static eosio_global_state& get_default_parameters() { + static eosio_global_state dp; + get_blockchain_parameters(&dp); + return dp; + } }; std::pair int_logarithm_one_plus(uint32_t x) { @@ -60,10 +59,9 @@ namespace eosiosystem { const uint8_t n = 4; static constexpr uint64_t ten_power = denom * denom * denom * denom; for (uint64_t i = 0, p = ten_power; i < n; ++i) { - if (i % 2 == 1) - ret -= x_power * p / (i+1); - else - ret += x_power * p / (i+1); + uint64_t factor = x_power * p / (i+1); + ret += factor; + ret -= 2 * (i % 2) * factor; x_power *= x; p /= denom; } diff --git a/eosio.system.hpp b/eosio.system.hpp index 6e35f0f7..956a9657 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -49,6 +49,9 @@ namespace eosiosystem { using system_token_type = typename common::system_token_type; using producers_table = typename pe::producers_table; using global_state_singleton = typename voting::global_state_singleton; + // using mseconds_per_day = typename common::mseconds_per_day; + static const uint32_t max_inflation_rate = common::max_inflation_rate; + static const uint32_t mseconds_per_day = common::mseconds_per_day; ACTION( SystemAccount, nonce ) { eosio::string value; @@ -59,11 +62,10 @@ namespace eosiosystem { static void on( const nonce& ) { } - static bool is_new_cycle(time block_time) { + static bool update_cycle(time block_time) { auto parameters = global_state_singleton::get(); if (parameters.first_block_time_in_cycle == 0) { - parameters.first_block_time_in_cycle = block_time; - global_state_singleton::set(parameters); + voting::update_elected_producers(block_time); return true; } @@ -73,14 +75,33 @@ namespace eosiosystem { uint32_t time_slots = delta / slot; if (time_slots >= common::blocks_per_cycle) { time beginning_of_cycle = block_time - (time_slots % slots_per_cycle) * slot; - parameters.first_block_time_in_cycle = beginning_of_cycle; - global_state_singleton::set(parameters); + voting::update_elected_producers(beginning_of_cycle); return true; } return false; } + /* + static system_token_type daily_payment(uint32_t percent_of_max_inflation_rate) + { + const system_token_type token_supply = currency::get_total_supply(); + const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate; + const auto& inflation_ratio = int_logarithm_one_plus(inflation_rate); + return ((token_supply * inflation_ratio.first * 4) / + (inflation_ratio.second * common::days_per_4years)); + } + static void fill_eos_bucket(time block_time) { + auto parameters = global_state_singleton::get(); + const time delta = block_time - parameters.last_bucket_fill_time; + if (delta >= mseconds_per_day) { + parameters.last_bucket_fill_time = parameters.last_bucket_fill_time + mseconds_per_day; + uint32_t percent = parameters.percent_of_max_inflation_rate - parameters.percent_of_max_inflation_rate / 2; + parameters.eos_bucket += daily_payment(percent); + global_state_singleton::set(parameters); + } + } + */ ACTION(SystemAccount, onblock) { block_header header; @@ -88,22 +109,66 @@ namespace eosiosystem { }; static void on(const onblock& ob) { - if (is_new_cycle(ob.header.timestamp)) { - voting::update_elected_producers(); - } + // update parameters if it's a new cycle + update_cycle(ob.header.timestamp); producers_table producers_tbl(SystemAccount, SystemAccount); account_name producer = ob.header.producer; - const system_token_type payment = global_state_singleton::get_or_default().payment_per_block; + auto parameters = global_state_singleton::get_or_default(); + const system_token_type block_payment = parameters.payment_per_block; const auto* prod = producers_tbl.find(producer); - // This check is needed in a real production system - // eosio_assert(prod != nullptr, "something wrong here"); + // This check is needed when everything works + // eosio_assert(prod != nullptr, "something wrong here"); if (prod != nullptr) { producers_tbl.update(*prod, 0, [&](auto& p) { - p.per_block_payments += payment; + p.per_block_payments += block_payment; p.last_produced_block_time = ob.header.timestamp; }); } + + const uint32_t num_of_payments = (ob.header.timestamp - parameters.last_bucket_fill_time) / 500; + const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; + parameters.last_bucket_fill_time = ob.header.timestamp; + parameters.eos_bucket += to_eos_bucket; + global_state_singleton::set(parameters); + } + ACTION(SystemAccount, claim_rewards) { + account_name owner; + time claim_time; + + EOSLIB_SERIALIZE(claim_rewards, (owner)(claim_time)) + }; + + static void on(const claim_rewards& cr) { + producers_table producers_tbl(SystemAccount, SystemAccount); + const auto* prod = producers_tbl.find(cr.owner); + eosio_assert(prod != nullptr, "account name not proucer list"); + eosio_assert(prod->active(), "producer is not active"); + const time ctime = cr.claim_time; + if (prod->last_rewards_claim > 0) { + eosio_assert(ctime >= prod->last_rewards_claim + mseconds_per_day, "already claimed rewards today"); + } + system_token_type rewards = prod->per_block_payments; + auto idx = producers_tbl.template get_index(); + auto itr = --idx.end(); + + const system_token_type eos_bucket = global_state_singleton::get_or_default().eos_bucket; + uint64_t total_producer_votes = 0; + for (uint32_t i = 0; i < 121; ++i) { + if (itr->active()) { + total_producer_votes += itr->total_votes; + } + if (itr == idx.begin()) { + break; + } + --itr; + } + + rewards += (uint64_t(prod->total_votes) * eos_bucket) / total_producer_votes; + producers_tbl.update(*prod, 0, [&](auto& p) { + p.last_rewards_claim = ctime; + p.per_block_payments = system_token_type(); + }); } static void apply( account_name code, action_name act ) { @@ -118,6 +183,7 @@ namespace eosiosystem { typename voting::unstakevote, typename voting::unstake_vote_deferred, onblock, + claim_rewards, nonce>( code, act) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); diff --git a/voting.hpp b/voting.hpp index 27e90727..29040fdd 100644 --- a/voting.hpp +++ b/voting.hpp @@ -51,13 +51,17 @@ namespace eosiosystem { eosio_parameters prefs; eosio::bytes packed_key; /// a packed public key object system_token_type per_block_payments; + time last_rewards_claim = 0; + time time_became_active = 0; time last_produced_block_time = 0; uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } bool active() const { return packed_key.size() == sizeof(public_key); } - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key)(per_block_payments)(last_produced_block_time) ) + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) + (per_block_payments)(last_rewards_claim) + (time_became_active)(last_produced_block_time) ) }; typedef eosio::multi_index< N(producervote), producer_info, @@ -175,11 +179,7 @@ namespace eosiosystem { return (token_supply * inflation_ratio.first) / (inflation_ratio.second * blocks_per_year); } - static system_token_type daily_producer_payment() { - return system_token_type(0); - } - - static void update_elected_producers() { + static void update_elected_producers(time cycle_time) { producers_table producers_tbl( SystemAccount, SystemAccount ); auto idx = producers_tbl.template get_index(); @@ -262,10 +262,14 @@ namespace eosiosystem { parameters.storage_reserve_ratio = storage_reserve_ratio[median]; parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; + // not voted on + parameters.first_block_time_in_cycle = cycle_time; + // derived parameters - parameters.payment_per_block = payment_per_block(parameters.percent_of_max_inflation_rate / 2); - parameters.payment_to_leaky_bucket = payment_per_block(parameters.percent_of_max_inflation_rate) - - parameters.payment_per_block; + auto half_of_percentage = parameters.percent_of_max_inflation_rate / 2; + auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; + parameters.payment_per_block = payment_per_block(half_of_percentage); + parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { parameters.max_storage_size = parameters.total_storage_bytes_reserved; From 873fcb3be80f2f01c0376cddecf437c40da50cbf Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 9 Mar 2018 17:59:23 -0500 Subject: [PATCH 0072/1048] Producer payment 2 --- eosio.system.hpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 956a9657..23f2f132 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -151,10 +151,14 @@ namespace eosiosystem { system_token_type rewards = prod->per_block_payments; auto idx = producers_tbl.template get_index(); auto itr = --idx.end(); - - const system_token_type eos_bucket = global_state_singleton::get_or_default().eos_bucket; + + bool is_among_payed_producers = false; uint64_t total_producer_votes = 0; for (uint32_t i = 0; i < 121; ++i) { + if (!is_among_payed_producers) { + if (itr->owner == cr.owner) + is_among_payed_producers = true; + } if (itr->active()) { total_producer_votes += itr->total_votes; } @@ -163,12 +167,16 @@ namespace eosiosystem { } --itr; } - - rewards += (uint64_t(prod->total_votes) * eos_bucket) / total_producer_votes; + + if (is_among_payed_producers) { + const system_token_type eos_bucket = global_state_singleton::get_or_default().eos_bucket; + rewards += (uint64_t(prod->total_votes) * eos_bucket) / total_producer_votes; + } producers_tbl.update(*prod, 0, [&](auto& p) { p.last_rewards_claim = ctime; p.per_block_payments = system_token_type(); }); + currency::inline_transfer(cr.owner, SystemAccount, rewards, "producer claiming rewards"); } static void apply( account_name code, action_name act ) { From 4f98a3358523330b896ced513ceeb918e70c3aea Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 9 Mar 2018 18:38:13 -0500 Subject: [PATCH 0073/1048] Fixed merge issue --- common.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.hpp b/common.hpp index 6e0d9dc0..afbbf6a9 100644 --- a/common.hpp +++ b/common.hpp @@ -40,7 +40,7 @@ namespace eosiosystem { uint64_t total_storage_bytes_reserved = 0; system_token_type total_storage_stake; - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (inflation_rate)(storage_reserve_ratio) ) + EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) ) }; typedef eosio::singleton global_state_singleton; From fcb7b0e256f851db85dc457d9c61c6379343dc2e Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 12 Mar 2018 14:42:26 -0400 Subject: [PATCH 0074/1048] starting to integrate voting and delegating bandwith --- delegate_bandwith.hpp | 59 ++++++++------- eosio.system.hpp | 6 +- voting.hpp | 162 ++++++++++++++++++------------------------ 3 files changed, 107 insertions(+), 120 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 917f3312..950add28 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -4,6 +4,7 @@ */ #pragma once #include "common.hpp" +#include "voting.hpp" #include #include @@ -27,7 +28,7 @@ namespace eosiosystem { using std::pair; template - class delegate_bandwith { + class delegate_bandwith : public voting { public: static constexpr account_name system_account = SystemAccount; using currency = typename common::currency; @@ -112,21 +113,27 @@ namespace eosiosystem { require_auth( del.from ); //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); + uint64_t storage_bytes = 0; + if ( 0 < del.stake_storage_quantity.amount ) { + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : common::get_default_parameters(); + auto token_supply = currency::get_total_supply();//.quantity; - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); - auto token_supply = currency::get_total_supply();//.quantity; + //make sure that there is no posibility of overflow here + uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) + * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) + / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - //make sure that there is no posibility of overflow here - uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) - / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) + * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) + / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - uint64_t storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) - * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) - / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); - eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); + parameters.total_storage_bytes_reserved += storage_bytes; + parameters.total_storage_stake += del.stake_storage_quantity; + global_state_singleton::set(parameters); + } del_bandwidth_index_type del_index( SystemAccount, del.from ); auto itr = del_index.find( del.receiver ); @@ -171,10 +178,11 @@ namespace eosiosystem { set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity, 0 ); currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); - - parameters.total_storage_bytes_reserved += storage_bytes; - parameters.total_storage_stake += del.stake_storage_quantity; - global_state_singleton::set(parameters); + /* temporarily commented out + if ( 0 < del.stake_net_quantity + del.stake_cpu_quantity ) { + increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); + } + */ } // delegatebw static void on( const undelegatebw& del ) { @@ -191,9 +199,17 @@ namespace eosiosystem { eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); - system_token_type storage_stake_decrease = 0 < dbw.storage_bytes ? - dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes - : system_token_type(0); + system_token_type storage_stake_decrease = system_token_type(0); + if ( 0 < del.unstake_storage_bytes ) { + storage_stake_decrease = 0 < dbw.storage_bytes ? + dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes + : system_token_type(0); + + auto parameters = global_state_singleton::get(); + parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; + parameters.total_storage_stake -= storage_stake_decrease; + global_state_singleton::set( parameters ); + } auto total_refund = system_token_type(del.unstake_cpu_quantity) + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; @@ -220,11 +236,6 @@ namespace eosiosystem { /// TODO: implement / enforce time delays on withdrawing currency::inline_transfer( SystemAccount, del.from, asset( static_cast( total_refund.quantity )), "unstake bandwidth" ); - - auto parameters = global_state_singleton::get(); - parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; - parameters.total_storage_stake -= storage_stake_decrease; - global_state_singleton::set( parameters ); } // undelegatebw }; } diff --git a/eosio.system.hpp b/eosio.system.hpp index 9d3c94e5..35c4bfcc 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,7 +4,7 @@ */ #pragma once -#include "voting.hpp" +//include "voting.hpp" #include "delegate_bandwith.hpp" #include @@ -39,7 +39,7 @@ namespace eosiosystem { }; template - class contract : public voting, public delegate_bandwith { + class contract : /*public voting,*/ public delegate_bandwith { public: using voting::on; using delegate_bandwith::on; @@ -188,8 +188,6 @@ namespace eosiosystem { typename voting::regproducer, typename voting::unregprod, typename voting::voteproducer, - typename voting::stakevote, - typename voting::unstakevote, typename voting::unstake_vote_deferred, onblock, claim_rewards, diff --git a/voting.hpp b/voting.hpp index 4d30d08c..2fc33075 100644 --- a/voting.hpp +++ b/voting.hpp @@ -144,13 +144,6 @@ namespace eosiosystem { }); } - ACTION( SystemAccount, stakevote ) { - account_name voter; - system_token_type amount; - - EOSLIB_SERIALIZE( stakevote, (voter)(amount) ) - }; - static void increase_voting_power( account_name acnt, system_token_type amount ) { voters_table voters_tbl( SystemAccount, SystemAccount ); const auto* voter = voters_tbl.find( acnt ); @@ -191,6 +184,76 @@ namespace eosiosystem { } } + static void decrease_voting_power( account_name acnt, system_token_type amount ) { + require_auth( acnt ); + voters_table voters_tbl( SystemAccount, SystemAccount ); + const auto* voter = voters_tbl.find( acnt ); + eosio_assert( bool(voter), "stake not found" ); + + if ( 0 < amount.quantity ) { + eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); + /* + if (voter->deferred_trx_id) { + //XXX cancel_deferred_transaction(voter->deferred_trx_id); + } + + unstake_vote_deferred dt; + dt.voter = acnt; + uint32_t new_trx_id = 0;//XXX send_deferred(dt); + + avotes.update( *voter, 0, [&](voter_info& a) { + a.staked -= amount; + a.unstaking += a.unstaking + amount; + //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments + a.unstake_per_week = system_token_type( a.unstaking.quantity /unstake_payments + a.unstaking.quantity % unstake_payments ); + a.deferred_trx_id = new_trx_id; + a.last_update = now(); + }); + */ + + // Temporary code: immediate unstake + voters_tbl.update( *voter, 0, [&](voter_info& a) { + a.staked -= amount; + a.last_update = now(); + }); + //currency::inline_transfer( SystemAccount, acnt, amount, "unstake voting" ); + // end of temporary code + + const std::vector* producers = nullptr; + if ( voter->proxy ) { + auto proxy = voters_tbl.find( voter->proxy ); + voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.quantity; } ); + if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers + producers = &proxy->producers; + } + } else { + producers = &voter->producers; + } + + if ( producers ) { + producers_table producers_tbl( SystemAccount, SystemAccount ); + for( auto p : *producers ) { + auto prod = producers_tbl.find( p ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& v ) { + v.total_votes -= amount.quantity; + }); + } + } + } else { + if (voter->deferred_trx_id) { + //XXX cancel_deferred_transaction(voter->deferred_trx_id); + } + voters_tbl.update( *voter, 0, [&](voter_info& a) { + a.staked += a.unstaking; + a.unstaking.quantity = 0; + a.unstake_per_week.quantity = 0; + a.deferred_trx_id = 0; + a.last_update = now(); + }); + } + } + static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { const system_token_type token_supply = currency::get_total_supply(); const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate; @@ -299,97 +362,12 @@ namespace eosiosystem { global_state_singleton::set( parameters ); } - static void on( const stakevote& sv ) { - eosio_assert( sv.amount.quantity > 0, "must stake some tokens" ); - require_auth( sv.voter ); - - increase_voting_power( sv.voter, sv.amount ); - currency::inline_transfer( sv.voter, SystemAccount, sv.amount, "stake for voting" ); - } - - ACTION( SystemAccount, unstakevote ) { - account_name voter; - system_token_type amount; - - EOSLIB_SERIALIZE( unstakevote, (voter)(amount) ) - }; - ACTION( SystemAccount, unstake_vote_deferred ) { account_name voter; EOSLIB_SERIALIZE( unstake_vote_deferred, (voter) ) }; - static void on( const unstakevote& usv ) { - require_auth( usv.voter ); - voters_table voters_tbl( SystemAccount, SystemAccount ); - const auto* voter = voters_tbl.find( usv.voter ); - eosio_assert( bool(voter), "stake not found" ); - - if ( 0 < usv.amount.quantity ) { - eosio_assert( usv.amount <= voter->staked, "cannot unstake more than total stake amount" ); - /* - if (voter->deferred_trx_id) { - //XXX cancel_deferred_transaction(voter->deferred_trx_id); - } - - unstake_vote_deferred dt; - dt.voter = usv.voter; - uint32_t new_trx_id = 0;//XXX send_deferred(dt); - - avotes.update( *voter, 0, [&](voter_info& a) { - a.staked -= usv.amount; - a.unstaking += a.unstaking + usv.amount; - //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments - a.unstake_per_week = system_token_type( a.unstaking.quantity /unstake_payments + a.unstaking.quantity % unstake_payments ); - a.deferred_trx_id = new_trx_id; - a.last_update = now(); - }); - */ - - // Temporary code: immediate unstake - voters_tbl.update( *voter, 0, [&](voter_info& a) { - a.staked -= usv.amount; - a.last_update = now(); - }); - currency::inline_transfer( SystemAccount, usv.voter, usv.amount, "unstake voting" ); - // end of temporary code - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes -= usv.amount.quantity; } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } - - if ( producers ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& v ) { - v.total_votes -= usv.amount.quantity; - }); - } - } - } else { - if (voter->deferred_trx_id) { - //XXX cancel_deferred_transaction(voter->deferred_trx_id); - } - voters_tbl.update( *voter, 0, [&](voter_info& a) { - a.staked += a.unstaking; - a.unstaking.quantity = 0; - a.unstake_per_week.quantity = 0; - a.deferred_trx_id = 0; - a.last_update = now(); - }); - } - } - static void on( const unstake_vote_deferred& usv) { require_auth( usv.voter ); voters_table voters_tbl( SystemAccount, SystemAccount ); From ce388737cb468aa91071f132137ebf9f2587cb13 Mon Sep 17 00:00:00 2001 From: Jon-Eric Cook Date: Mon, 12 Mar 2018 12:46:45 -0700 Subject: [PATCH 0075/1048] Update README.md Typos --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a954337f..9e5c3160 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ Indicates that a particular account wishes to become a producer Storage changes will be billed to 'account' ## eosio.system::unstake account quantity - - **account** - the account which is requsting their balance be unstaked + - **account** - the account which is requesting their balance be unstaked - **quantity** - the quantity which will be unstaked, unstaked tokens lose voting influence immediately - in order to unstake tokens, an account must request them. The user will receive them over @@ -71,7 +71,7 @@ Indicates that a particular account wishes to become a producer - this special action is triggered when a block is applied by the given producer and cannot be generated from any other source. It is used to pay producers and calculate missed blocks of other producers. - - producer pay is deposited into the prodcer's stake balance and can be withdrawn over time. + - producer pay is deposited into the producer's stake balance and can be withdrawn over time. - if blocknum is the start of a new round this may update the active producer config from the producer votes. From 6951b8ba365b752af3f4b82ee931205aa35d0ca0 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 12 Mar 2018 16:58:51 -0400 Subject: [PATCH 0076/1048] ariphmetic operators for asset, on-block related bug-fixes, stakevote/unstakevote removed --- common.hpp | 16 ++++++++-------- delegate_bandwith.hpp | 3 +-- eosio.system.abi | 20 -------------------- eosio.system.hpp | 6 ++++-- voting.hpp | 6 +++++- 5 files changed, 18 insertions(+), 33 deletions(-) diff --git a/common.hpp b/common.hpp index afbbf6a9..8282f362 100644 --- a/common.hpp +++ b/common.hpp @@ -26,21 +26,21 @@ namespace eosiosystem { struct eosio_parameters : eosio::blockchain_parameters { uint32_t percent_of_max_inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) uint32_t storage_reserve_ratio = 1000; // ratio * 1000 - system_token_type payment_per_block = system_token_type(); - system_token_type payment_to_eos_bucket = system_token_type(); - time first_block_time_in_cycle = 0; - time last_bucket_fill_time = 0; - system_token_type eos_bucket = system_token_type(); - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) - (payment_per_block)(last_bucket_fill_time)(eos_bucket) ) + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) ) }; struct eosio_global_state : eosio_parameters { uint64_t total_storage_bytes_reserved = 0; system_token_type total_storage_stake; + system_token_type payment_per_block = system_token_type(); + system_token_type payment_to_eos_bucket = system_token_type(); + time first_block_time_in_cycle = 0; + time last_bucket_fill_time = 0; + system_token_type eos_bucket = system_token_type(); - EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) ) + EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) + (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(last_bucket_fill_time)(eos_bucket) ) }; typedef eosio::singleton global_state_singleton; diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 950add28..0fd468c9 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -106,8 +106,7 @@ namespace eosiosystem { eosio_assert( del.stake_net_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( del.stake_storage_quantity.amount >= 0, "must stake a positive amount" ); - system_token_type total_stake = system_token_type(del.stake_cpu_quantity) - + system_token_type(del.stake_net_quantity) + system_token_type(del.stake_storage_quantity); + system_token_type total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; eosio_assert( total_stake.quantity > 0, "must stake a positive amount" ); require_auth( del.from ); diff --git a/eosio.system.abi b/eosio.system.abi index 069a9957..d965afff 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -125,20 +125,6 @@ "fields": [ {"name":"producer", "type":"account_name"} ] - },{ - "name": "stakevote", - "base": "", - "fields": [ - {"name":"voter", "type":"account_name"}, - {"name":"amount", "type":"asset"} - ] - },{ - "name": "unstakevote", - "base": "", - "fields": [ - {"name":"voter", "type":"account_name"}, - {"name":"amount", "type":"asset"} - ] },{ "name": "voteproducer", "base": "", @@ -183,12 +169,6 @@ },{ "name": "unregprod", "type": "unregprod" - },{ - "name": "stakevote", - "type": "stakevote" - },{ - "name": "unstakevote", - "type": "unstakevote" },{ "name": "voteproducer", "type": "voteproducer" diff --git a/eosio.system.hpp b/eosio.system.hpp index 35c4bfcc..9ccf32b2 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -63,7 +63,8 @@ namespace eosiosystem { } static bool update_cycle(time block_time) { - auto parameters = global_state_singleton::get(); + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : common::get_default_parameters(); if (parameters.first_block_time_in_cycle == 0) { voting::update_elected_producers(block_time); return true; @@ -113,7 +114,8 @@ namespace eosiosystem { update_cycle(ob.header.timestamp); producers_table producers_tbl(SystemAccount, SystemAccount); account_name producer = ob.header.producer; - auto parameters = global_state_singleton::get_or_default(); + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : common::get_default_parameters(); const system_token_type block_payment = parameters.payment_per_block; const auto* prod = producers_tbl.find(producer); // This check is needed when everything works diff --git a/voting.hpp b/voting.hpp index 2fc33075..78942d61 100644 --- a/voting.hpp +++ b/voting.hpp @@ -285,6 +285,9 @@ namespace eosiosystem { schedule.producers.reserve(21); auto it = idx.end(); + if (it == idx.begin()) { + return; + } --it; size_t n = 0; while ( n < 21 ) { @@ -326,7 +329,8 @@ namespace eosiosystem { set_active_producers( packed_schedule.data(), packed_schedule.size() ); size_t median = n/2; - auto parameters = global_state_singleton::get(); + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : common::get_default_parameters(); parameters.target_block_size = target_block_size[median]; parameters.max_block_size = max_block_size[median]; From fc8b3aa18d3328f0f26c37ef0c6d1d11cf228e12 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 12 Mar 2018 17:44:36 -0400 Subject: [PATCH 0077/1048] comparison operators for asset, check how staking for bandwith increases stake for voting (fails) --- delegate_bandwith.hpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 0fd468c9..9b18e4c9 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -177,11 +177,9 @@ namespace eosiosystem { set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity, 0 ); currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); - /* temporarily commented out - if ( 0 < del.stake_net_quantity + del.stake_cpu_quantity ) { - increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); + if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { + voting::increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); } - */ } // delegatebw static void on( const undelegatebw& del ) { @@ -234,7 +232,11 @@ namespace eosiosystem { set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity, 0 ); /// TODO: implement / enforce time delays on withdrawing - currency::inline_transfer( SystemAccount, del.from, asset( static_cast( total_refund.quantity )), "unstake bandwidth" ); + currency::inline_transfer( SystemAccount, del.from, total_refund, "unstake bandwidth" ); + if ( asset(0) < del.unstake_net_quantity + del.unstake_cpu_quantity ) { + voting::decrease_voting_power( del.from, del.unstake_net_quantity + del.unstake_cpu_quantity ); + } + } // undelegatebw }; } From 40a3641aa78e0adc2436e6982ee5e1ede5f9f497 Mon Sep 17 00:00:00 2001 From: Jon-Eric Cook Date: Mon, 12 Mar 2018 17:26:28 -0700 Subject: [PATCH 0078/1048] Update eosio.system.hpp Added a missing action in "apply" function. Fixed a potential typo in an action struct and action name. Fixed typo in comment. --- eosio.system.hpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 84f4c175..486f457e 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -112,7 +112,7 @@ namespace eosiosystem { typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; - ACTION( SystemAccount, finshundel ) { + ACTION( SystemAccount, finishundel ) { account_name from; account_name to; }; @@ -252,7 +252,7 @@ namespace eosiosystem { /** - * This method will create a producr_config and producer_votes object for 'producer' + * This method will create a producer_config and producer_votes object for 'producer' * * @pre producer is not already registered * @pre producer to register is an account @@ -382,13 +382,16 @@ namespace eosiosystem { static void on( const nonce& ) { } + + static void on( const finishundel& ) { + } static void apply( account_name code, action_name act ) { if( !eosio::dispatch( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); From 54c2a11e559ca969b3b59d4fa36191122f6d99c9 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 12 Mar 2018 23:00:30 -0400 Subject: [PATCH 0079/1048] progress on inheritance redesign of multi_index Tests fail: `call_indirect to function with wrong signature` --- eosio.system.hpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 84f4c175..1ce3b0d8 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -24,6 +24,7 @@ namespace eosiosystem { using std::map; using std::pair; using eosio::print; + using eosio::table_row; template class contract { @@ -32,13 +33,13 @@ namespace eosiosystem { typedef eosio::generic_currency< eosio::token > currency; typedef typename currency::token_type system_token_type; - struct producer_votes { + struct producer_votes : public table_row { account_name owner; uint64_t padding = 0; uint128_t total_votes; - uint64_t primary_key()const { return owner; } - uint128_t by_votes()const { return total_votes; } + virtual uint64_t primary_key()const override { return owner; } + uint128_t by_votes()const { return total_votes; } EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ) }; @@ -46,36 +47,36 @@ namespace eosiosystem { indexed_by > > producer_votes_index_type; - struct account_votes { + struct account_votes : public table_row { account_name owner; account_name proxy; uint32_t last_update; system_token_type staked; std::vector producers; - uint64_t primary_key()const { return owner; } + virtual uint64_t primary_key()const override { return owner; } EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ) }; typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; - struct producer_config { + struct producer_config : public table_row { account_name owner; eosio::bytes packed_key; /// a packed public key object - uint64_t primary_key()const { return owner; } + virtual uint64_t primary_key()const override { return owner; } EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) }; typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; - struct total_resources { + struct total_resources : public table_row { account_name owner; typename currency::token_type total_net_weight; typename currency::token_type total_cpu_weight; uint32_t total_ram = 0; - uint64_t primary_key()const { return owner; } + virtual uint64_t primary_key()const override { return owner; } EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ) }; @@ -84,7 +85,7 @@ namespace eosiosystem { /** * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. */ - struct delegated_bandwidth { + struct delegated_bandwidth : public table_row { account_name from; account_name to; typename currency::token_type net_weight; @@ -99,7 +100,7 @@ namespace eosiosystem { uint64_t deferred_cpu_withdraw_handler = 0; - uint64_t primary_key()const { return to; } + virtual uint64_t primary_key()const override { return to; } EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) From a2d5441923da9b7a968ea0b7efd25731c5419e09 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 13 Mar 2018 15:00:30 -0400 Subject: [PATCH 0080/1048] Revert "progress on inheritance redesign of multi_index" This reverts commit 53350a479a9aed339130dfd3ed22489f544dcf84. --- eosio.system.hpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 1ce3b0d8..84f4c175 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -24,7 +24,6 @@ namespace eosiosystem { using std::map; using std::pair; using eosio::print; - using eosio::table_row; template class contract { @@ -33,13 +32,13 @@ namespace eosiosystem { typedef eosio::generic_currency< eosio::token > currency; typedef typename currency::token_type system_token_type; - struct producer_votes : public table_row { + struct producer_votes { account_name owner; uint64_t padding = 0; uint128_t total_votes; - virtual uint64_t primary_key()const override { return owner; } - uint128_t by_votes()const { return total_votes; } + uint64_t primary_key()const { return owner; } + uint128_t by_votes()const { return total_votes; } EOSLIB_SERIALIZE( producer_votes, (owner)(total_votes) ) }; @@ -47,36 +46,36 @@ namespace eosiosystem { indexed_by > > producer_votes_index_type; - struct account_votes : public table_row { + struct account_votes { account_name owner; account_name proxy; uint32_t last_update; system_token_type staked; std::vector producers; - virtual uint64_t primary_key()const override { return owner; } + uint64_t primary_key()const { return owner; } EOSLIB_SERIALIZE( account_votes, (owner)(proxy)(last_update)(staked)(producers) ) }; typedef eosio::multi_index< N(accountvotes), account_votes> account_votes_index_type; - struct producer_config : public table_row { + struct producer_config { account_name owner; eosio::bytes packed_key; /// a packed public key object - virtual uint64_t primary_key()const override { return owner; } + uint64_t primary_key()const { return owner; } EOSLIB_SERIALIZE( producer_config, (owner)(packed_key) ) }; typedef eosio::multi_index< N(producercfg), producer_config> producer_config_index_type; - struct total_resources : public table_row { + struct total_resources { account_name owner; typename currency::token_type total_net_weight; typename currency::token_type total_cpu_weight; uint32_t total_ram = 0; - virtual uint64_t primary_key()const override { return owner; } + uint64_t primary_key()const { return owner; } EOSLIB_SERIALIZE( total_resources, (owner)(total_net_weight)(total_cpu_weight)(total_ram) ) }; @@ -85,7 +84,7 @@ namespace eosiosystem { /** * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. */ - struct delegated_bandwidth : public table_row { + struct delegated_bandwidth { account_name from; account_name to; typename currency::token_type net_weight; @@ -100,7 +99,7 @@ namespace eosiosystem { uint64_t deferred_cpu_withdraw_handler = 0; - virtual uint64_t primary_key()const override { return to; } + uint64_t primary_key()const { return to; } EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) From 935f9bcb1ac8d201edbdd3d12be409bf05682df9 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 13 Mar 2018 15:33:48 -0400 Subject: [PATCH 0081/1048] abi for register/unregister proxy, first proxy test --- eosio.system.abi | 18 ++++++++++++++++++ eosio.system.hpp | 4 ++-- voting.hpp | 32 ++++++++++++++++---------------- 3 files changed, 36 insertions(+), 18 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index d965afff..cd19dc1f 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -125,6 +125,18 @@ "fields": [ {"name":"producer", "type":"account_name"} ] + },{ + "name": "regproxy", + "base": "", + "fields": [ + {"name":"proxy", "type":"account_name"} + ] + },{ + "name": "unregproxy", + "base": "", + "fields": [ + {"name":"proxy", "type":"account_name"} + ] },{ "name": "voteproducer", "base": "", @@ -169,6 +181,12 @@ },{ "name": "unregprod", "type": "unregprod" + },{ + "name": "regproxy", + "type": "regproxy" + },{ + "name": "unregproxy", + "type": "unregproxy" },{ "name": "voteproducer", "type": "voteproducer" diff --git a/eosio.system.hpp b/eosio.system.hpp index 9ccf32b2..27f53fd1 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -185,8 +185,8 @@ namespace eosiosystem { if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, - typename voting::register_proxy, - typename voting::unregister_proxy, + typename voting::regproxy, + typename voting::unregproxy, typename voting::regproducer, typename voting::unregprod, typename voting::voteproducer, diff --git a/voting.hpp b/voting.hpp index 78942d61..9e19ce1d 100644 --- a/voting.hpp +++ b/voting.hpp @@ -473,9 +473,9 @@ namespace eosiosystem { auto end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); for ( auto it = elected.begin(); it != end_it; ++it ) { auto prod = producers_tbl.find( *it ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption + eosio_assert( bool(prod), "producer is not registered" ); if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers - eosio_assert( prod->active(), "can vote only for active producers" ); + eosio_assert( prod->active(), "producer is not currently registered" ); } producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += voter->staked.quantity; }); } @@ -488,17 +488,17 @@ namespace eosiosystem { }); } - ACTION( SystemAccount, register_proxy ) { - account_name proxy_to_register; + ACTION( SystemAccount, regproxy ) { + account_name proxy; - EOSLIB_SERIALIZE( register_proxy, (proxy_to_register) ) + EOSLIB_SERIALIZE( regproxy, (proxy) ) }; - static void on( const register_proxy& reg ) { - require_auth( reg.proxy_to_register ); + static void on( const regproxy& reg ) { + require_auth( reg.proxy ); voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( reg.proxy_to_register ); + auto voter = voters_tbl.find( reg.proxy ); if ( voter ) { eosio_assert( voter->is_proxy == 0, "account is already a proxy" ); eosio_assert( voter->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); @@ -508,8 +508,8 @@ namespace eosiosystem { //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value }); } else { - voters_tbl.emplace( reg.proxy_to_register, [&]( voter_info& a ) { - a.owner = reg.proxy_to_register; + voters_tbl.emplace( reg.proxy, [&]( voter_info& a ) { + a.owner = reg.proxy; a.last_update = now(); a.proxy = 0; a.is_proxy = 1; @@ -519,17 +519,17 @@ namespace eosiosystem { } } - ACTION( SystemAccount, unregister_proxy ) { - account_name proxy_to_unregister; + ACTION( SystemAccount, unregproxy ) { + account_name proxy; - EOSLIB_SERIALIZE( unregister_proxy, (proxy_to_unregister) ) + EOSLIB_SERIALIZE( unregproxy, (proxy) ) }; - static void on( const unregister_proxy& reg ) { - require_auth( reg.proxy_to_unregister ); + static void on( const unregproxy& reg ) { + require_auth( reg.proxy ); voters_table voters_tbl( SystemAccount, SystemAccount ); - auto proxy = voters_tbl.find( reg.proxy_to_unregister ); + auto proxy = voters_tbl.find( reg.proxy ); eosio_assert( bool(proxy), "proxy not found" ); eosio_assert( proxy->is_proxy == 1, "account is already a proxy" ); From a6764bccafcd755068a5b90804ed45b313b74bf9 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 13 Mar 2018 18:12:32 -0400 Subject: [PATCH 0082/1048] disallow voting for the same producer multiple times, tests, convinience function stake() --- voting.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/voting.hpp b/voting.hpp index 9e19ce1d..879f184e 100644 --- a/voting.hpp +++ b/voting.hpp @@ -418,7 +418,9 @@ namespace eosiosystem { require_recipient( vp.proxy ); } else { eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); - eosio_assert( std::is_sorted( vp.producers.begin(), vp.producers.end() ), "producer votes must be sorted" ); + for( size_t i = 1; i < vp.producers.size(); ++i ) { + eosio_assert( vp.producers[i-1] < vp.producers[i], "producer votes must be unique and sorted" ); + } } voters_table voters_tbl( SystemAccount, SystemAccount ); From 60ce5ebaf2057109560130587daae8c6bc6050ac Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 14 Mar 2018 14:35:52 -0400 Subject: [PATCH 0083/1048] REQUIRE_MATCHING_OBJECT, system contract ABI fix --- eosio.system.abi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index cd19dc1f..79e67142 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -153,9 +153,9 @@ {"name":"proxy", "type":"account_name"}, {"name":"last_update", "type":"uint32"}, {"name":"is_proxy", "type":"uint32"}, - {"name":"staked", "type":"uint32"}, - {"name":"unstaking", "type":"uint32"}, - {"name":"unstake_per_week", "type":"uint32"}, + {"name":"staked", "type":"uint64"}, + {"name":"unstaking", "type":"uint64"}, + {"name":"unstake_per_week", "type":"uint64"}, {"name":"proxied_votes", "type":"uint128"}, {"name":"producers", "type":"account_name[]"}, {"name":"deferred_trx_id", "type":"uint32"}, From 90fffcab3245cc700713809e9e9678eb96810cee Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 14 Mar 2018 19:01:52 -0400 Subject: [PATCH 0084/1048] bugfix in staking for storage, test for proxies --- delegate_bandwith.hpp | 4 ++-- voting.hpp | 4 +++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 9b18e4c9..acbdd886 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -120,11 +120,11 @@ namespace eosiosystem { //make sure that there is no posibility of overflow here uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) + * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) - * parameters.storage_reserve_ratio * system_token_type(del.stake_cpu_quantity) + * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); diff --git a/voting.hpp b/voting.hpp index 879f184e..259b676b 100644 --- a/voting.hpp +++ b/voting.hpp @@ -164,6 +164,7 @@ namespace eosiosystem { const std::vector* producers = nullptr; if ( voter->proxy ) { auto proxy = voters_tbl.find( voter->proxy ); + eosio_assert( bool(proxy), "selected proxy not found" ); //data corruption voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.quantity; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; @@ -438,6 +439,7 @@ namespace eosiosystem { return; // nothing changed } auto old_proxy = voters_tbl.find( voter->proxy ); + eosio_assert( bool(old_proxy), "old proxy not found" ); //data corruption voters_tbl.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) old_producers = &old_proxy->producers; @@ -450,7 +452,7 @@ namespace eosiosystem { const std::vector* new_producers = nullptr; if ( vp.proxy ) { auto new_proxy = voters_tbl.find( vp.proxy ); - eosio_assert( new_proxy->is_proxy, "selected proxy has not elected to be a proxy" ); + eosio_assert( new_proxy && new_proxy->is_proxy, "proxy not found" ); voters_tbl.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); new_producers = &new_proxy->producers; } else { From 7aa819dca70d6f78eeebdcb6258c826baa6d450f Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 15 Mar 2018 11:36:05 -0400 Subject: [PATCH 0085/1048] bugfixes and tests for proxy voting --- eosio.system.abi | 2 +- voting.hpp | 44 +++++++++++++++++++++++++++++--------------- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 79e67142..946fc108 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -106,7 +106,7 @@ "name": "producer_info", "base": "", "fields": [ - {"name":"owner", "type":"uint64"}, + {"name":"owner", "type":"account_name"}, {"name":"total_votes", "type":"uint128"}, {"name":"prefs", "type":"eosio_parameters"}, {"name":"packed_key", "type":"uint8[]"} diff --git a/voting.hpp b/voting.hpp index 259b676b..08d44a8e 100644 --- a/voting.hpp +++ b/voting.hpp @@ -427,7 +427,7 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto voter = voters_tbl.find( vp.voter ); - eosio_assert( bool(voter), "no stake to vote" ); + eosio_assert( bool(voter) && ( 0 < voter->staked.quantity || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); if ( voter->is_proxy ) { eosio_assert( vp.proxy == 0 , "accounts elected to be proxy are not allowed to use another proxy" ); } @@ -460,6 +460,10 @@ namespace eosiosystem { } producers_table producers_tbl( SystemAccount, SystemAccount ); + uint128_t votes = voter->staked.quantity; + if ( voter->is_proxy ) { + votes += voter->proxied_votes; + } if ( old_producers ) { //old_producers == 0 if proxy has stoped being a proxy and votes were taken back from producers at that moment //revoke votes only from no longer elected @@ -468,7 +472,7 @@ namespace eosiosystem { for ( auto it = revoked.begin(); it != end_it; ++it ) { auto prod = producers_tbl.find( *it ); eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= voter->staked.quantity; }); + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); } } @@ -481,7 +485,7 @@ namespace eosiosystem { if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers eosio_assert( prod->active(), "producer is not currently registered" ); } - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += voter->staked.quantity; }); + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); } // save new values to the account itself @@ -502,15 +506,23 @@ namespace eosiosystem { require_auth( reg.proxy ); voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( reg.proxy ); - if ( voter ) { - eosio_assert( voter->is_proxy == 0, "account is already a proxy" ); - eosio_assert( voter->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - voters_tbl.update( *voter, 0, [&](voter_info& a) { + auto proxy = voters_tbl.find( reg.proxy ); + if ( proxy ) { + eosio_assert( proxy->is_proxy == 0, "account is already a proxy" ); + eosio_assert( proxy->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); + voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.is_proxy = 1; a.last_update = now(); //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value }); + if ( 0 < proxy->proxied_votes ) { + producers_table producers_tbl( SystemAccount, SystemAccount ); + for ( auto p : proxy->producers ) { + auto prod = producers_tbl.find( p ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += proxy->proxied_votes; }); + } + } } else { voters_tbl.emplace( reg.proxy, [&]( voter_info& a ) { a.owner = reg.proxy; @@ -537,18 +549,20 @@ namespace eosiosystem { eosio_assert( bool(proxy), "proxy not found" ); eosio_assert( proxy->is_proxy == 1, "account is already a proxy" ); - producers_table producers_tbl( SystemAccount, SystemAccount ); - for ( auto p : proxy->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); - } - voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.is_proxy = 0; a.last_update = now(); //a.proxied_votes should be kept in order to be able to reenable this proxy in the future }); + + if ( 0 < proxy->proxied_votes ) { + producers_table producers_tbl( SystemAccount, SystemAccount ); + for ( auto p : proxy->producers ) { + auto prod = producers_tbl.find( p ); + eosio_assert( bool(prod), "never existed producer" ); //data corruption + producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); + } + } } }; From 8618961c16f5ba4e1cad742c4afc7db7d5d38f6b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 15 Mar 2018 14:27:08 -0400 Subject: [PATCH 0086/1048] more tests for voting --- voting.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.hpp b/voting.hpp index 08d44a8e..64b72eff 100644 --- a/voting.hpp +++ b/voting.hpp @@ -547,7 +547,7 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto proxy = voters_tbl.find( reg.proxy ); eosio_assert( bool(proxy), "proxy not found" ); - eosio_assert( proxy->is_proxy == 1, "account is already a proxy" ); + eosio_assert( proxy->is_proxy == 1, "account is not a proxy" ); voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.is_proxy = 0; From 89d21e90533785a12509ae49c7710095c455329b Mon Sep 17 00:00:00 2001 From: Jon-Eric Cook Date: Thu, 15 Mar 2018 12:03:27 -0700 Subject: [PATCH 0087/1048] Update eosio.system.hpp --- eosio.system.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index 486f457e..2b0691e6 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -115,6 +115,8 @@ namespace eosiosystem { ACTION( SystemAccount, finishundel ) { account_name from; account_name to; + + EOSLIB_SERIALIZE( finishundel, (from)(to) ) }; ACTION( SystemAccount, regproducer ) { From 3649ed9e2306ef32ba7b832ea58b40bf445d9a95 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 15 Mar 2018 15:32:56 -0400 Subject: [PATCH 0088/1048] more tests for system contract --- voting.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.hpp b/voting.hpp index 64b72eff..227a8058 100644 --- a/voting.hpp +++ b/voting.hpp @@ -429,7 +429,7 @@ namespace eosiosystem { eosio_assert( bool(voter) && ( 0 < voter->staked.quantity || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); if ( voter->is_proxy ) { - eosio_assert( vp.proxy == 0 , "accounts elected to be proxy are not allowed to use another proxy" ); + eosio_assert( vp.proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); } //find old producers, update old proxy if needed From 20ea0ebcca3329e5412e5c89f0c7fd7d127a897b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 15 Mar 2018 20:03:58 -0400 Subject: [PATCH 0089/1048] more tests and bugfixes for producer voting --- delegate_bandwith.hpp | 2 +- voting.hpp | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index acbdd886..98cedb4d 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -116,7 +116,7 @@ namespace eosiosystem { if ( 0 < del.stake_storage_quantity.amount ) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - auto token_supply = currency::get_total_supply();//.quantity; + auto token_supply = currency::get_total_supply(); //make sure that there is no posibility of overflow here uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) diff --git a/voting.hpp b/voting.hpp index 227a8058..e20e9b64 100644 --- a/voting.hpp +++ b/voting.hpp @@ -284,14 +284,19 @@ namespace eosiosystem { eosio::producer_schedule schedule; schedule.producers.reserve(21); - + /* + for (auto it = idx.begin(); it != idx.end(); ++it) { + print( it->total_votes, ", " ); + } + print ("\n"); + */ auto it = idx.end(); if (it == idx.begin()) { - return; + return; } --it; size_t n = 0; - while ( n < 21 ) { + while ( n < 21 && 0 < it->total_votes ) { if ( it->active() ) { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; @@ -325,6 +330,9 @@ namespace eosiosystem { } --it; } + if ( n == 0 ) { //no active producers with votes > 0 + return; + } // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp bytes packed_schedule = pack(schedule); set_active_producers( packed_schedule.data(), packed_schedule.size() ); @@ -465,7 +473,7 @@ namespace eosiosystem { votes += voter->proxied_votes; } - if ( old_producers ) { //old_producers == 0 if proxy has stoped being a proxy and votes were taken back from producers at that moment + if ( old_producers ) { //old_producers == 0 if proxy has stoped being a proxy and votes were taken back from the producers at that moment //revoke votes only from no longer elected std::vector revoked( old_producers->size() ); auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); From 351b04311801b4e37d783b078dd792f06b129ef5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 16 Mar 2018 09:41:51 -0400 Subject: [PATCH 0090/1048] Producer pay fixes, token issuing --- common.hpp | 44 ++++++++++--------- eosio.system.abi | 24 ++++++++--- eosio.system.hpp | 109 ++++++++++++++++++++--------------------------- voting.hpp | 22 ++++++++-- 4 files changed, 106 insertions(+), 93 deletions(-) diff --git a/common.hpp b/common.hpp index 8282f362..e614d615 100644 --- a/common.hpp +++ b/common.hpp @@ -13,34 +13,36 @@ namespace eosiosystem { public: static constexpr account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; - typedef typename currency::token_type system_token_type; - static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) - static constexpr uint8_t currency_decimals = currency_symbol & 0xFF; // 4 - static const uint32_t max_inflation_rate = 5; // 5% annual inflation -#warning "change to config parameter" - static constexpr uint32_t producer_repititions = 12; - static constexpr uint32_t blocks_per_cycle = 21 * producer_repititions; - static const uint32_t mseconds_per_day = 24 * 3600 * 1000; - static constexpr uint32_t days_per_4years = 1461; + typedef typename currency::token_type system_token_type; + + static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) + static constexpr uint8_t currency_decimals = currency_symbol & 0xFF; // 4 + static const uint32_t max_inflation_rate = 5; // 5% annual inflation + + static const uint32_t blocks_per_producer = 6; + static const uint32_t seconds_per_day = 24 * 3600; + static constexpr uint32_t days_per_4years = 1461; struct eosio_parameters : eosio::blockchain_parameters { - uint32_t percent_of_max_inflation_rate = 0; // inflation coefficient * 10000 (i.e. inflation in percent * 100) + uint32_t percent_of_max_inflation_rate = 0; uint32_t storage_reserve_ratio = 1000; // ratio * 1000 EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) ) }; struct eosio_global_state : eosio_parameters { - uint64_t total_storage_bytes_reserved = 0; - system_token_type total_storage_stake; - system_token_type payment_per_block = system_token_type(); - system_token_type payment_to_eos_bucket = system_token_type(); - time first_block_time_in_cycle = 0; - time last_bucket_fill_time = 0; - system_token_type eos_bucket = system_token_type(); + uint64_t total_storage_bytes_reserved = 0; + system_token_type total_storage_stake; + system_token_type payment_per_block = system_token_type(); + system_token_type payment_to_eos_bucket = system_token_type(); + time first_block_time_in_cycle = 0; + uint32_t blocks_per_cycle = 0; //6 * 21; + time last_bucket_fill_time = 0; + system_token_type eos_bucket = system_token_type(); EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) - (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(last_bucket_fill_time)(eos_bucket) ) + (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) + (last_bucket_fill_time)(eos_bucket) ) }; typedef eosio::singleton global_state_singleton; @@ -56,8 +58,8 @@ namespace eosiosystem { static const uint64_t denom = 10000; uint64_t ret = 0; uint64_t x_power = x; - const uint8_t n = 4; - static constexpr uint64_t ten_power = denom * denom * denom * denom; + const uint64_t n = 4; + static const uint64_t ten_power = denom * denom * denom * denom; for (uint64_t i = 0, p = ten_power; i < n; ++i) { uint64_t factor = x_power * p / (i+1); ret += factor; @@ -65,7 +67,7 @@ namespace eosiosystem { x_power *= x; p /= denom; } - return std::make_pair(ret * denom/ten_power, denom); + return std::make_pair(ret / (denom * denom * denom), denom); } } diff --git a/eosio.system.abi b/eosio.system.abi index d965afff..416e85d9 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -92,7 +92,7 @@ {"name":"max_inline_depth", "type":"uint16"}, {"name":"max_inline_action_size", "type":"uint32"}, {"name":"max_generated_transaction_size", "type":"uint32"}, - {"name":"inflation_rate", "type":"uint32"}, + {"name":"percent_of_max_inflation_rate", "type":"uint32"}, {"name":"storage_reserve_ratio", "type":"uint32"} ] },{ @@ -100,16 +100,19 @@ "base": "eosio_parameters", "fields": [ {"name":"total_storage_bytes_reserved", "type":"uint64"}, - {"name":"total_storage_stake", "type":"uint64"} + {"name":"total_storage_stake", "type":"uint64"}, + {"name":"payment_per_block", "type":"uint64"} ] },{ "name": "producer_info", "base": "", "fields": [ - {"name":"owner", "type":"uint64"}, - {"name":"total_votes", "type":"uint128"}, - {"name":"prefs", "type":"eosio_parameters"}, - {"name":"packed_key", "type":"uint8[]"} + {"name":"owner", "type":"uint64"}, + {"name":"total_votes", "type":"uint128"}, + {"name":"prefs", "type":"eosio_parameters"}, + {"name":"packed_key", "type":"uint8[]"}, + {"name":"per_block_payments", "type":"uint64"}, + {"name":"last_claim_time", "type":"uint32"} ] },{ "name": "regproducer", @@ -149,6 +152,12 @@ {"name":"deferred_trx_id", "type":"uint32"}, {"name":"last_unstake", "type":"uint32"} ] + },{ + "name": "claimrewards", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] } ], "actions": [{ @@ -172,6 +181,9 @@ },{ "name": "voteproducer", "type": "voteproducer" + },{ + "name": "claimrewards", + "type": "claimrewards" } ], "tables": [ diff --git a/eosio.system.hpp b/eosio.system.hpp index 9ccf32b2..7d716f6f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -11,21 +11,7 @@ #include namespace eosiosystem { - /* - struct PACKED(producer_key) { - account_name producer_name; - public_key block_signing_key; - EOSLIB_SERIALIZE(producer_key, (producer_name)(block_signing_key)) - }; - - struct PACKED(producer_schedule) { - uint32_t version; - std::vector producers; - - EOSLIB_SERIALIZE(producer_schedule, (version)(producers)) - }; - */ struct PACKED(block_header) { checksum256 previous; time timestamp; @@ -49,9 +35,10 @@ namespace eosiosystem { using system_token_type = typename common::system_token_type; using producers_table = typename pe::producers_table; using global_state_singleton = typename voting::global_state_singleton; - // using mseconds_per_day = typename common::mseconds_per_day; static const uint32_t max_inflation_rate = common::max_inflation_rate; - static const uint32_t mseconds_per_day = common::mseconds_per_day; + static const uint32_t seconds_per_day = common::seconds_per_day; + static const uint32_t num_of_payed_producers = 121; + static const uint32_t slot = 1; ACTION( SystemAccount, nonce ) { eosio::string value; @@ -63,46 +50,24 @@ namespace eosiosystem { } static bool update_cycle(time block_time) { - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : common::get_default_parameters(); if (parameters.first_block_time_in_cycle == 0) { voting::update_elected_producers(block_time); return true; } - - static const time slot = 500; - static const uint32_t slots_per_cycle = common::blocks_per_cycle; - const time delta = block_time - parameters.first_block_time_in_cycle; - uint32_t time_slots = delta / slot; - if (time_slots >= common::blocks_per_cycle) { - time beginning_of_cycle = block_time - (time_slots % slots_per_cycle) * slot; + + static const uint32_t slots_per_cycle = parameters.blocks_per_cycle; + const uint32_t time_slots = block_time - parameters.first_block_time_in_cycle; + if (time_slots >= slots_per_cycle) { + time beginning_of_cycle = block_time - (time_slots % slots_per_cycle); voting::update_elected_producers(beginning_of_cycle); return true; } return false; } - /* - static system_token_type daily_payment(uint32_t percent_of_max_inflation_rate) - { - const system_token_type token_supply = currency::get_total_supply(); - const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate; - const auto& inflation_ratio = int_logarithm_one_plus(inflation_rate); - return ((token_supply * inflation_ratio.first * 4) / - (inflation_ratio.second * common::days_per_4years)); - } - static void fill_eos_bucket(time block_time) { - auto parameters = global_state_singleton::get(); - const time delta = block_time - parameters.last_bucket_fill_time; - if (delta >= mseconds_per_day) { - parameters.last_bucket_fill_time = parameters.last_bucket_fill_time + mseconds_per_day; - uint32_t percent = parameters.percent_of_max_inflation_rate - parameters.percent_of_max_inflation_rate / 2; - parameters.eos_bucket += daily_payment(percent); - global_state_singleton::set(parameters); - } - } - */ ACTION(SystemAccount, onblock) { block_header header; @@ -111,7 +76,9 @@ namespace eosiosystem { static void on(const onblock& ob) { // update parameters if it's a new cycle - update_cycle(ob.header.timestamp); + if (update_cycle(ob.header.timestamp)) { + // prints("\nNew Cycle!\n\n"); + } producers_table producers_tbl(SystemAccount, SystemAccount); account_name producer = ob.header.producer; auto parameters = global_state_singleton::exists() ? global_state_singleton::get() @@ -119,36 +86,44 @@ namespace eosiosystem { const system_token_type block_payment = parameters.payment_per_block; const auto* prod = producers_tbl.find(producer); // This check is needed when everything works - // eosio_assert(prod != nullptr, "something wrong here"); + // eosio_assert(prod != nullptr, "something wrong here"); if (prod != nullptr) { + // prints("Producer found\n"); producers_tbl.update(*prod, 0, [&](auto& p) { + // printi((uint64_t)p.per_block_payments.quantity); + // prints("\n"); p.per_block_payments += block_payment; + // printi((uint64_t)p.per_block_payments.quantity); + // prints("\n"); p.last_produced_block_time = ob.header.timestamp; }); } - - const uint32_t num_of_payments = (ob.header.timestamp - parameters.last_bucket_fill_time) / 500; + + // prints("payments to eos bucket\n"); + const uint32_t num_of_payments = ob.header.timestamp - parameters.last_bucket_fill_time; const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; + // printi(to_eos_bucket.quantity); + // prints("\n"); parameters.last_bucket_fill_time = ob.header.timestamp; parameters.eos_bucket += to_eos_bucket; global_state_singleton::set(parameters); } - ACTION(SystemAccount, claim_rewards) { + ACTION(SystemAccount, claimrewards) { account_name owner; - time claim_time; - EOSLIB_SERIALIZE(claim_rewards, (owner)(claim_time)) + EOSLIB_SERIALIZE(claimrewards, (owner)) }; - static void on(const claim_rewards& cr) { + static void on(const claimrewards& cr) { + require_auth(cr.owner); + eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); producers_table producers_tbl(SystemAccount, SystemAccount); const auto* prod = producers_tbl.find(cr.owner); - eosio_assert(prod != nullptr, "account name not proucer list"); + eosio_assert(prod != nullptr, "account name not producer list"); eosio_assert(prod->active(), "producer is not active"); - const time ctime = cr.claim_time; if (prod->last_rewards_claim > 0) { - eosio_assert(ctime >= prod->last_rewards_claim + mseconds_per_day, "already claimed rewards today"); + eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } system_token_type rewards = prod->per_block_payments; auto idx = producers_tbl.template get_index(); @@ -156,13 +131,15 @@ namespace eosiosystem { bool is_among_payed_producers = false; uint64_t total_producer_votes = 0; - for (uint32_t i = 0; i < 121; ++i) { + uint32_t n = 0; + while (n < num_of_payed_producers) { if (!is_among_payed_producers) { if (itr->owner == cr.owner) is_among_payed_producers = true; } if (itr->active()) { total_producer_votes += itr->total_votes; + ++n; } if (itr == idx.begin()) { break; @@ -170,14 +147,20 @@ namespace eosiosystem { --itr; } - if (is_among_payed_producers) { - const system_token_type eos_bucket = global_state_singleton::get_or_default().eos_bucket; - rewards += (uint64_t(prod->total_votes) * eos_bucket) / total_producer_votes; + if (is_among_payed_producers && total_producer_votes > 0) { + if (global_state_singleton::exists()) { + auto parameters = global_state_singleton::get(); + auto share_of_eos_bucket = (uint64_t(prod->total_votes) * parameters.eos_bucket) / total_producer_votes; + rewards += share_of_eos_bucket; + parameters.eos_bucket -= share_of_eos_bucket; + global_state_singleton::set(parameters); + } } producers_tbl.update(*prod, 0, [&](auto& p) { - p.last_rewards_claim = ctime; - p.per_block_payments = system_token_type(); + p.last_rewards_claim = now(); + p.per_block_payments.quantity = 0; }); + currency::inline_transfer(cr.owner, SystemAccount, rewards, "producer claiming rewards"); } @@ -192,7 +175,7 @@ namespace eosiosystem { typename voting::voteproducer, typename voting::unstake_vote_deferred, onblock, - claim_rewards, + claimrewards, nonce>( code, act) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); eosio_assert( false, "received unexpected action"); diff --git a/voting.hpp b/voting.hpp index 78942d61..a0419c3a 100644 --- a/voting.hpp +++ b/voting.hpp @@ -39,6 +39,7 @@ namespace eosiosystem { using global_state_singleton = typename common::global_state_singleton; static const uint32_t max_inflation_rate = common::max_inflation_rate; + // static const uint32_t blocks_per_cycle = common::blocks_per_cycle; static constexpr uint32_t max_unstake_requests = 10; static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week static constexpr uint32_t unstake_payments = 26; // during 26 weeks @@ -256,8 +257,21 @@ namespace eosiosystem { static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { const system_token_type token_supply = currency::get_total_supply(); + /* + prints("token_supply\n"); + printi(token_supply.quantity); + prints("\ntoken_supply\n"); + */ const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate; const auto& inflation_ratio = int_logarithm_one_plus(inflation_rate); + /* + printi(inflation_rate); + prints("\n"); + printi(inflation_ratio.first); + prints("/"); + printi(inflation_ratio.second); + prints("\n"); + */ return (token_supply * inflation_ratio.first) / (inflation_ratio.second * blocks_per_year); } @@ -356,14 +370,16 @@ namespace eosiosystem { auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; parameters.payment_per_block = payment_per_block(half_of_percentage); parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); + parameters.blocks_per_cycle = 6 * schedule.producers.size(); if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { parameters.max_storage_size = parameters.total_storage_bytes_reserved; } - + + auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); + currency::inline_issue(SystemAccount, issue_quantity); set_blockchain_parameters(¶meters); - - global_state_singleton::set( parameters ); + global_state_singleton::set(parameters); } ACTION( SystemAccount, unstake_vote_deferred ) { From bc6f2ecd1e20a60a6daa12ee588539801960d4ce Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Thu, 22 Feb 2018 14:52:44 -0600 Subject: [PATCH 0091/1048] Rename read_action to read_action_data. Rename action_size to action_data_size. --- eosio.system.hpp | 76 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2b0691e6..04d2ce39 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,6 +4,8 @@ */ #include #include +#include +#include #include #include #include @@ -111,6 +113,17 @@ namespace eosiosystem { typedef eosio::multi_index< N(totalband), total_resources> total_resources_index_type; typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; + struct genesis_balance { + checksum256 pubkey_hash; + typename currency::token_type balance; + + checksum256 primary_key()const { return pubkey_hash; } + + EOSLIB_SERIALIZE( genesis_balance, (pubkey_hash)(balance) ) + }; +//TODO typedef eosio::multi_index< N(genbal), genesis_balance> genesis_balance_index_type; + //indexed_by > > genesis_balance_index_type; + ACTION( SystemAccount, finishundel ) { account_name from; @@ -151,6 +164,29 @@ namespace eosiosystem { EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) ) }; + ACTION( SystemAccount, setgen ) { + std::map genesis_balances; + + EOSLIB_SERIALIZE( setgen, (genesis_balances) ) + }; + + ACTION( SystemAccount, claimgen ) { + account_name name; + checksum256 pubkey_hash; + uint32_t cfa_idx; // context free action index + + EOSLIB_SERIALIZE( claimgen, (name)(pubkey_hash)(cfa_idx) ) + }; + + // context free action + ACTION( SystemAccount, keyproof ) { + checksum256 pubkey_hash; + checksum256 digest; // hash of purchase agreement + uint32_t cfd_idx; // context free data index + + EOSLIB_SERIALIZE( keyproof, (pubkey_hash)(digest)(cfd_idx) ) + }; + ACTION( SystemAccount, nonce ) { eosio::string value; @@ -382,6 +418,45 @@ namespace eosiosystem { } + /** + * @pre setgen not previously applied + * @param gen the map of pubkey to balance of genesis + */ + static void on( const setgen& gen ) { + require_auth( system_account ); +/* + genesis_balance_index_type genesis_balances( system_account, system_account ); + eosio_assert( genesis_balances.begin() != genesis_balances.end(), "setgen already applied." ); + + for( const auto& gb : gen.genesis_balances ) { + genesis_balances.emplace( system_account, [&]( auto& v ) { + v.pubkey_hash = gb.first; + v.balance = gb.second; + }); + } + */ + } + + static void on( const claimgen& cg ) { + + } + + /** + * Context free action. + * Verifies associated context free data signature matches provided hashed public key. + * @param kp + */ + static void on( const keyproof& kp ) { + signature sig; + int size = get_context_free_data( kp.cfd_idx, reinterpret_cast(&sig), sizeof(sig) ); + eosio_assert( size == sizeof(sig), "keyproof associated context free signature data wrong size" ); + + public_key pk; + recover_key( &kp.digest, reinterpret_cast(&sig), sizeof(sig), reinterpret_cast(&pk), sizeof(pk) ); + + assert_sha256(reinterpret_cast(&pk), sizeof(pk), &kp.pubkey_hash ); + } + static void on( const nonce& ) { } @@ -394,6 +469,7 @@ namespace eosiosystem { regproducer, regproxy, delegatebw, undelegatebw, finishundel, voteproducer, stakevote, + setgen, claimgen, keyproof, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); From 7958ac007fdf8631beaf484249c6e56456f4d91d Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 23 Feb 2018 14:57:51 -0600 Subject: [PATCH 0092/1048] Action interface work in progress --- eosio.system.hpp | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 04d2ce39..27614a25 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,7 +4,7 @@ */ #include #include -#include +#include #include #include #include @@ -424,9 +424,9 @@ namespace eosiosystem { */ static void on( const setgen& gen ) { require_auth( system_account ); -/* +/* TODO - waiting on multi-index support for checksum256 genesis_balance_index_type genesis_balances( system_account, system_account ); - eosio_assert( genesis_balances.begin() != genesis_balances.end(), "setgen already applied." ); + eosio_assert( genesis_balances.begin() == genesis_balances.end(), "setgen already applied." ); for( const auto& gb : gen.genesis_balances ) { genesis_balances.emplace( system_account, [&]( auto& v ) { @@ -434,11 +434,29 @@ namespace eosiosystem { v.balance = gb.second; }); } - */ + */ } + /** + * @pre in transaction with an associated keyproof context free action + * @param cg action to claim genesis balance for given account + */ static void on( const claimgen& cg ) { + // verify associated keyproof context free action contains same pubkey_hash + eosio::action cfa = eosio::get_action ( 0, 0 ); + keyproof kp = cfa.data_as(); + eosio_assert( kp.pubkey_hash == cg.pubkey_hash, "claimgen pubkey_hash not equal to keyproof pubkey_hash" ); + +// genesis_balance_index_type genesis_balances( system_account, system_account ); +// const genesis_balance* gb = genesis_balances.find(cg.pubkey_hash); + const genesis_balance* gb = nullptr; + + eosio_assert( gb != nullptr, "unable to find genesis pubkey_hash" ); + + currency::inline_transfer( system_account, cg.name, gb->balance, "claimed genesis balance" ); + // remove genesis balance from claimable table +// genesis_balances.remove(*gb); } /** From 60ad32008ef26278adcb389ca46675feb845be58 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 5 Mar 2018 20:17:09 -0600 Subject: [PATCH 0093/1048] First impl of setgen/claimgen --- eosio.system.hpp | 45 +++++++++++++++++++++++++++++---------------- 1 file changed, 29 insertions(+), 16 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 27614a25..df3ebd4e 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -3,6 +3,7 @@ * @copyright defined in eos/LICENSE.txt */ #include +#include #include #include #include @@ -16,6 +17,7 @@ #include #include +#include #include #include @@ -33,6 +35,7 @@ namespace eosiosystem { static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; typedef typename currency::token_type system_token_type; + using key256 = eosio::key256; struct producer_votes { account_name owner; @@ -114,15 +117,18 @@ namespace eosiosystem { typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; struct genesis_balance { - checksum256 pubkey_hash; - typename currency::token_type balance; + uint64_t id; // required by multi_index, auto incremented + key256 pubkey_hash; + typename currency::token_type balance; - checksum256 primary_key()const { return pubkey_hash; } + uint64_t primary_key()const { return id; } + const key256& get_pubkey_hash()const { return pubkey_hash; } - EOSLIB_SERIALIZE( genesis_balance, (pubkey_hash)(balance) ) + EOSLIB_SERIALIZE( genesis_balance, (id)(pubkey_hash)(balance) ) }; -//TODO typedef eosio::multi_index< N(genbal), genesis_balance> genesis_balance_index_type; - //indexed_by > > genesis_balance_index_type; + typedef eosio::multi_index< N(genbal), genesis_balance, + indexed_by > + > genesis_balance_index_type; ACTION( SystemAccount, finishundel ) { @@ -418,23 +424,30 @@ namespace eosiosystem { } + static key256 to_key256(const checksum256& key) { + std::array raw; + std::copy( std::begin( key.hash ), std::end( key.hash ), std::begin( raw ) ); + return key256(raw); + } + /** * @pre setgen not previously applied * @param gen the map of pubkey to balance of genesis */ static void on( const setgen& gen ) { require_auth( system_account ); -/* TODO - waiting on multi-index support for checksum256 genesis_balance_index_type genesis_balances( system_account, system_account ); eosio_assert( genesis_balances.begin() == genesis_balances.end(), "setgen already applied." ); + auto pubkeyidx = genesis_balances.template get_index(); + for( const auto& gb : gen.genesis_balances ) { - genesis_balances.emplace( system_account, [&]( auto& v ) { - v.pubkey_hash = gb.first; + key256 key = to_key256( gb.first ); + genesis_balances.emplace( system_account, [&key, &gb]( auto& v ) { + v.pubkey_hash = key; v.balance = gb.second; }); } - */ } /** @@ -447,16 +460,16 @@ namespace eosiosystem { keyproof kp = cfa.data_as(); eosio_assert( kp.pubkey_hash == cg.pubkey_hash, "claimgen pubkey_hash not equal to keyproof pubkey_hash" ); -// genesis_balance_index_type genesis_balances( system_account, system_account ); -// const genesis_balance* gb = genesis_balances.find(cg.pubkey_hash); - const genesis_balance* gb = nullptr; + genesis_balance_index_type genesis_balances( system_account, system_account ); + auto pubkeyidx = genesis_balances.template get_index(); + auto gbitr = pubkeyidx.find( to_key256(cg.pubkey_hash)); - eosio_assert( gb != nullptr, "unable to find genesis pubkey_hash" ); + eosio_assert( gbitr != pubkeyidx.end(), "unable to find genesis pubkey_hash" ); - currency::inline_transfer( system_account, cg.name, gb->balance, "claimed genesis balance" ); + currency::inline_transfer( system_account, cg.name, gbitr->balance, "claimed genesis balance" ); // remove genesis balance from claimable table -// genesis_balances.remove(*gb); + genesis_balances.remove(*gbitr); } /** From b96aa25b5a2dd11d892325c94149366756f4b8c8 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 9 Mar 2018 11:56:46 -0600 Subject: [PATCH 0094/1048] Add tests for context free actions --- eosio.system.hpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index df3ebd4e..f375898c 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -439,8 +439,6 @@ namespace eosiosystem { genesis_balance_index_type genesis_balances( system_account, system_account ); eosio_assert( genesis_balances.begin() == genesis_balances.end(), "setgen already applied." ); - auto pubkeyidx = genesis_balances.template get_index(); - for( const auto& gb : gen.genesis_balances ) { key256 key = to_key256( gb.first ); genesis_balances.emplace( system_account, [&key, &gb]( auto& v ) { @@ -456,7 +454,7 @@ namespace eosiosystem { */ static void on( const claimgen& cg ) { // verify associated keyproof context free action contains same pubkey_hash - eosio::action cfa = eosio::get_action ( 0, 0 ); + eosio::action cfa = eosio::get_action( 0, 0 ); keyproof kp = cfa.data_as(); eosio_assert( kp.pubkey_hash == cg.pubkey_hash, "claimgen pubkey_hash not equal to keyproof pubkey_hash" ); @@ -469,13 +467,13 @@ namespace eosiosystem { currency::inline_transfer( system_account, cg.name, gbitr->balance, "claimed genesis balance" ); // remove genesis balance from claimable table - genesis_balances.remove(*gbitr); + genesis_balances.remove( *gbitr ); } /** * Context free action. * Verifies associated context free data signature matches provided hashed public key. - * @param kp + * @param kp the context free action data */ static void on( const keyproof& kp ) { signature sig; From 4b073abdd3383f225bcd6617785f16c8907cc08c Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 12 Mar 2018 10:48:22 -0500 Subject: [PATCH 0095/1048] Update for new multi-index interface --- eosio.system.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index f375898c..58404cb9 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -460,14 +460,14 @@ namespace eosiosystem { genesis_balance_index_type genesis_balances( system_account, system_account ); auto pubkeyidx = genesis_balances.template get_index(); - auto gbitr = pubkeyidx.find( to_key256(cg.pubkey_hash)); + auto gbitr = pubkeyidx.find( to_key256(cg.pubkey_hash) ); eosio_assert( gbitr != pubkeyidx.end(), "unable to find genesis pubkey_hash" ); currency::inline_transfer( system_account, cg.name, gbitr->balance, "claimed genesis balance" ); // remove genesis balance from claimable table - genesis_balances.remove( *gbitr ); + pubkeyidx.erase( gbitr ); } /** From e4c2037013cc6376d0cfcb9816b848d4768508c8 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 16 Mar 2018 09:51:31 -0500 Subject: [PATCH 0096/1048] Revert work in progress of DAWN-617 --- eosio.system.hpp | 105 ----------------------------------------------- 1 file changed, 105 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 58404cb9..2b0691e6 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -3,10 +3,7 @@ * @copyright defined in eos/LICENSE.txt */ #include -#include #include -#include -#include #include #include #include @@ -17,7 +14,6 @@ #include #include -#include #include #include @@ -35,7 +31,6 @@ namespace eosiosystem { static const account_name system_account = SystemAccount; typedef eosio::generic_currency< eosio::token > currency; typedef typename currency::token_type system_token_type; - using key256 = eosio::key256; struct producer_votes { account_name owner; @@ -116,20 +111,6 @@ namespace eosiosystem { typedef eosio::multi_index< N(totalband), total_resources> total_resources_index_type; typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; - struct genesis_balance { - uint64_t id; // required by multi_index, auto incremented - key256 pubkey_hash; - typename currency::token_type balance; - - uint64_t primary_key()const { return id; } - const key256& get_pubkey_hash()const { return pubkey_hash; } - - EOSLIB_SERIALIZE( genesis_balance, (id)(pubkey_hash)(balance) ) - }; - typedef eosio::multi_index< N(genbal), genesis_balance, - indexed_by > - > genesis_balance_index_type; - ACTION( SystemAccount, finishundel ) { account_name from; @@ -170,29 +151,6 @@ namespace eosiosystem { EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity) ) }; - ACTION( SystemAccount, setgen ) { - std::map genesis_balances; - - EOSLIB_SERIALIZE( setgen, (genesis_balances) ) - }; - - ACTION( SystemAccount, claimgen ) { - account_name name; - checksum256 pubkey_hash; - uint32_t cfa_idx; // context free action index - - EOSLIB_SERIALIZE( claimgen, (name)(pubkey_hash)(cfa_idx) ) - }; - - // context free action - ACTION( SystemAccount, keyproof ) { - checksum256 pubkey_hash; - checksum256 digest; // hash of purchase agreement - uint32_t cfd_idx; // context free data index - - EOSLIB_SERIALIZE( keyproof, (pubkey_hash)(digest)(cfd_idx) ) - }; - ACTION( SystemAccount, nonce ) { eosio::string value; @@ -424,68 +382,6 @@ namespace eosiosystem { } - static key256 to_key256(const checksum256& key) { - std::array raw; - std::copy( std::begin( key.hash ), std::end( key.hash ), std::begin( raw ) ); - return key256(raw); - } - - /** - * @pre setgen not previously applied - * @param gen the map of pubkey to balance of genesis - */ - static void on( const setgen& gen ) { - require_auth( system_account ); - genesis_balance_index_type genesis_balances( system_account, system_account ); - eosio_assert( genesis_balances.begin() == genesis_balances.end(), "setgen already applied." ); - - for( const auto& gb : gen.genesis_balances ) { - key256 key = to_key256( gb.first ); - genesis_balances.emplace( system_account, [&key, &gb]( auto& v ) { - v.pubkey_hash = key; - v.balance = gb.second; - }); - } - } - - /** - * @pre in transaction with an associated keyproof context free action - * @param cg action to claim genesis balance for given account - */ - static void on( const claimgen& cg ) { - // verify associated keyproof context free action contains same pubkey_hash - eosio::action cfa = eosio::get_action( 0, 0 ); - keyproof kp = cfa.data_as(); - eosio_assert( kp.pubkey_hash == cg.pubkey_hash, "claimgen pubkey_hash not equal to keyproof pubkey_hash" ); - - genesis_balance_index_type genesis_balances( system_account, system_account ); - auto pubkeyidx = genesis_balances.template get_index(); - auto gbitr = pubkeyidx.find( to_key256(cg.pubkey_hash) ); - - eosio_assert( gbitr != pubkeyidx.end(), "unable to find genesis pubkey_hash" ); - - currency::inline_transfer( system_account, cg.name, gbitr->balance, "claimed genesis balance" ); - - // remove genesis balance from claimable table - pubkeyidx.erase( gbitr ); - } - - /** - * Context free action. - * Verifies associated context free data signature matches provided hashed public key. - * @param kp the context free action data - */ - static void on( const keyproof& kp ) { - signature sig; - int size = get_context_free_data( kp.cfd_idx, reinterpret_cast(&sig), sizeof(sig) ); - eosio_assert( size == sizeof(sig), "keyproof associated context free signature data wrong size" ); - - public_key pk; - recover_key( &kp.digest, reinterpret_cast(&sig), sizeof(sig), reinterpret_cast(&pk), sizeof(pk) ); - - assert_sha256(reinterpret_cast(&pk), sizeof(pk), &kp.pubkey_hash ); - } - static void on( const nonce& ) { } @@ -498,7 +394,6 @@ namespace eosiosystem { regproducer, regproxy, delegatebw, undelegatebw, finishundel, voteproducer, stakevote, - setgen, claimgen, keyproof, nonce>( code, act) ) { if ( !eosio::dispatch( code, act ) ) { eosio::print("Unexpected action: ", eosio::name(act), "\n"); From bf36e2a0224c85d4b70e68f98e2f5cf8da1ec18c Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 16 Mar 2018 11:04:08 -0400 Subject: [PATCH 0097/1048] failing test for producers election (secondary index in multi_index is not soreted properly) --- eosio.system.hpp | 2 +- voting.hpp | 33 +++++++++++++++++++++++++++------ 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 27f53fd1..cdac8664 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -65,7 +65,7 @@ namespace eosiosystem { static bool update_cycle(time block_time) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - if (parameters.first_block_time_in_cycle == 0) { + if (1/*parameters.first_block_time_in_cycle == 0*/) { voting::update_elected_producers(block_time); return true; } diff --git a/voting.hpp b/voting.hpp index e20e9b64..acfebe95 100644 --- a/voting.hpp +++ b/voting.hpp @@ -17,6 +17,7 @@ #include #include +#include #include namespace eosiosystem { @@ -285,16 +286,17 @@ namespace eosiosystem { eosio::producer_schedule schedule; schedule.producers.reserve(21); /* + print ("Producers: "); for (auto it = idx.begin(); it != idx.end(); ++it) { - print( it->total_votes, ", " ); + print( it->owner, " (", it->total_votes, "), " ); } print ("\n"); */ - auto it = idx.end(); - if (it == idx.begin()) { + auto it = idx.begin(); + if (it == idx.end()) { return; } - --it; + //++it; size_t n = 0; while ( n < 21 && 0 < it->total_votes ) { if ( it->active() ) { @@ -325,16 +327,35 @@ namespace eosiosystem { ++n; } - if (it == idx.begin()) { + ++it; + if (it == idx.end()) { break; } - --it; } if ( n == 0 ) { //no active producers with votes > 0 return; } + if ( 1 < n ) { + std::sort( target_block_size.begin(), target_block_size.begin()+n ); + std::sort( max_block_size.begin(), max_block_size.begin()+n ); + std::sort( target_block_acts_per_scope.begin(), target_block_acts_per_scope.begin()+n ); + std::sort( max_block_acts_per_scope.begin(), max_block_acts_per_scope.begin()+n ); + std::sort( target_block_acts.begin(), target_block_acts.begin()+n ); + std::sort( max_block_acts.begin(), max_block_acts.begin()+n ); + std::sort( max_storage_size.begin(), max_storage_size.begin()+n ); + std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); + std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); + std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); + std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); + std::sort( max_generated_transaction_size.begin(), max_generated_transaction_size.begin()+n ); + std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); + std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); + } + // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp bytes packed_schedule = pack(schedule); + //print( "schedule size = ", schedule.producers.size(), "\n" ); + //print( "set_active_producers( ... , ", packed_schedule.size(), " );\n" ); set_active_producers( packed_schedule.data(), packed_schedule.size() ); size_t median = n/2; From abacb0ff062358ca4bb6a5135d8d0ad89b4d6c56 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Mon, 12 Mar 2018 15:57:35 -0500 Subject: [PATCH 0098/1048] Removed unneeded api contract headers. --- eosio.system.hpp | 1 - 1 file changed, 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2b0691e6..1d0d6a7a 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,7 +4,6 @@ */ #include #include -#include #include #include From 2874af8e4e2de718565b0168ba6962e1f4af47b8 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 16 Mar 2018 16:33:48 -0400 Subject: [PATCH 0099/1048] compilation fixes after merge --- delegate_bandwith.hpp | 14 +++---- eosio.system.hpp | 15 +++----- voting.hpp | 86 +++++++++++++++++++++---------------------- 3 files changed, 56 insertions(+), 59 deletions(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 98cedb4d..5ccf8fb5 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -136,7 +136,7 @@ namespace eosiosystem { del_bandwidth_index_type del_index( SystemAccount, del.from ); auto itr = del_index.find( del.receiver ); - if( itr == nullptr ) { + if( itr == del_index.end() ) { del_index.emplace( del.from, [&]( auto& dbo ){ dbo.from = del.from; dbo.to = del.receiver; @@ -147,7 +147,7 @@ namespace eosiosystem { }); } else { - del_index.update( *itr, del.from, [&]( auto& dbo ){ + del_index.modify( itr, del.from, [&]( auto& dbo ){ dbo.net_weight += del.stake_net_quantity; dbo.cpu_weight += del.stake_cpu_quantity; dbo.storage_stake += del.stake_storage_quantity; @@ -157,8 +157,8 @@ namespace eosiosystem { total_resources_index_type total_index( SystemAccount, del.receiver ); auto tot_itr = total_index.find( del.receiver ); - if( tot_itr == nullptr ) { - tot_itr = &total_index.emplace( del.from, [&]( auto& tot ) { + if( tot_itr == total_index.end() ) { + tot_itr = total_index.emplace( del.from, [&]( auto& tot ) { tot.owner = del.receiver; tot.net_weight = del.stake_net_quantity; tot.cpu_weight = del.stake_cpu_quantity; @@ -166,7 +166,7 @@ namespace eosiosystem { tot.storage_bytes = storage_bytes; }); } else { - total_index.update( *tot_itr, del.from == del.receiver ? del.from : 0, [&]( auto& tot ) { + total_index.modify( tot_itr, del.from == del.receiver ? del.from : 0, [&]( auto& tot ) { tot.net_weight += del.stake_net_quantity; tot.cpu_weight += del.stake_cpu_quantity; tot.storage_stake += del.stake_storage_quantity; @@ -213,7 +213,7 @@ namespace eosiosystem { eosio_assert( total_refund.quantity > 0, "must unstake a positive amount" ); - del_index.update( dbw, del.from, [&]( auto& dbo ){ + del_index.modify( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; dbo.cpu_weight -= del.unstake_cpu_quantity; dbo.storage_stake -= storage_stake_decrease; @@ -222,7 +222,7 @@ namespace eosiosystem { total_resources_index_type total_index( SystemAccount, del.receiver ); const auto& totals = total_index.get( del.receiver ); - total_index.update( totals, 0, [&]( auto& tot ) { + total_index.modify( totals, 0, [&]( auto& tot ) { tot.net_weight -= del.unstake_net_quantity; tot.cpu_weight -= del.unstake_cpu_quantity; tot.storage_stake -= storage_stake_decrease; diff --git a/eosio.system.hpp b/eosio.system.hpp index ef13c037..f8203a0f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -84,12 +84,12 @@ namespace eosiosystem { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); const system_token_type block_payment = parameters.payment_per_block; - const auto* prod = producers_tbl.find(producer); + auto prod = producers_tbl.find(producer); // This check is needed when everything works // eosio_assert(prod != nullptr, "something wrong here"); - if (prod != nullptr) { + if ( prod != producers_tbl.end() ) { // prints("Producer found\n"); - producers_tbl.update(*prod, 0, [&](auto& p) { + producers_tbl.modify( prod, 0, [&](auto& p) { // printi((uint64_t)p.per_block_payments.quantity); // prints("\n"); p.per_block_payments += block_payment; @@ -119,8 +119,8 @@ namespace eosiosystem { require_auth(cr.owner); eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); producers_table producers_tbl(SystemAccount, SystemAccount); - const auto* prod = producers_tbl.find(cr.owner); - eosio_assert(prod != nullptr, "account name not producer list"); + auto prod = producers_tbl.find(cr.owner); + eosio_assert(prod != producers_tbl.end(), "account name not producer list"); eosio_assert(prod->active(), "producer is not active"); if (prod->last_rewards_claim > 0) { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); @@ -156,7 +156,7 @@ namespace eosiosystem { global_state_singleton::set(parameters); } } - producers_tbl.update(*prod, 0, [&](auto& p) { + producers_tbl.modify( prod, 0, [&](auto& p) { p.last_rewards_claim = now(); p.per_block_payments.quantity = 0; }); @@ -164,9 +164,6 @@ namespace eosiosystem { currency::inline_transfer(cr.owner, SystemAccount, rewards, "producer claiming rewards"); } - static void on( const finishundel& ) { - } - static void apply( account_name code, action_name act ) { if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, diff --git a/voting.hpp b/voting.hpp index 3052f6e4..c650c7bc 100644 --- a/voting.hpp +++ b/voting.hpp @@ -111,10 +111,10 @@ namespace eosiosystem { require_auth( reg.producer ); producers_table producers_tbl( SystemAccount, SystemAccount ); - const auto* prod = producers_tbl.find( reg.producer ); + auto prod = producers_tbl.find( reg.producer ); - if ( prod ) { - producers_tbl.update( *prod, reg.producer, [&]( producer_info& info ){ + if ( prod != producers_tbl.end() ) { + producers_tbl.modify( prod, reg.producer, [&]( producer_info& info ){ info.prefs = reg.prefs; info.packed_key = reg.producer_key; }); @@ -138,26 +138,26 @@ namespace eosiosystem { require_auth( unreg.producer ); producers_table producers_tbl( SystemAccount, SystemAccount ); - const auto* prod = producers_tbl.find( unreg.producer ); - eosio_assert( bool(prod), "producer not found" ); + auto prod = producers_tbl.find( unreg.producer ); + eosio_assert( prod != producers_tbl.end(), "producer not found" ); - producers_tbl.update( *prod, 0, [&]( producer_info& info ){ + producers_tbl.modify( prod, 0, [&]( producer_info& info ){ info.packed_key.clear(); }); } static void increase_voting_power( account_name acnt, system_token_type amount ) { voters_table voters_tbl( SystemAccount, SystemAccount ); - const auto* voter = voters_tbl.find( acnt ); + auto voter = voters_tbl.find( acnt ); - if( !voter ) { - voter = &voters_tbl.emplace( acnt, [&]( voter_info& a ) { + if( voter == voters_tbl.end() ) { + voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { a.owner = acnt; a.last_update = now(); a.staked = amount; }); } else { - voters_tbl.update( *voter, 0, [&]( auto& av ) { + voters_tbl.modify( voter, 0, [&]( auto& av ) { av.last_update = now(); av.staked += amount; }); @@ -166,8 +166,8 @@ namespace eosiosystem { const std::vector* producers = nullptr; if ( voter->proxy ) { auto proxy = voters_tbl.find( voter->proxy ); - eosio_assert( bool(proxy), "selected proxy not found" ); //data corruption - voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.quantity; } ); + eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.quantity; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } @@ -179,8 +179,8 @@ namespace eosiosystem { producers_table producers_tbl( SystemAccount, SystemAccount ); for( auto p : *producers ) { auto prod = producers_tbl.find( p ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& v ) { + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& v ) { v.total_votes += amount.quantity; }); } @@ -190,8 +190,8 @@ namespace eosiosystem { static void decrease_voting_power( account_name acnt, system_token_type amount ) { require_auth( acnt ); voters_table voters_tbl( SystemAccount, SystemAccount ); - const auto* voter = voters_tbl.find( acnt ); - eosio_assert( bool(voter), "stake not found" ); + auto voter = voters_tbl.find( acnt ); + eosio_assert( voter != voters_tbl.end(), "stake not found" ); if ( 0 < amount.quantity ) { eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); @@ -204,7 +204,7 @@ namespace eosiosystem { dt.voter = acnt; uint32_t new_trx_id = 0;//XXX send_deferred(dt); - avotes.update( *voter, 0, [&](voter_info& a) { + avotes.modify( voter, 0, [&](voter_info& a) { a.staked -= amount; a.unstaking += a.unstaking + amount; //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments @@ -215,7 +215,7 @@ namespace eosiosystem { */ // Temporary code: immediate unstake - voters_tbl.update( *voter, 0, [&](voter_info& a) { + voters_tbl.modify( voter, 0, [&](voter_info& a) { a.staked -= amount; a.last_update = now(); }); @@ -225,7 +225,7 @@ namespace eosiosystem { const std::vector* producers = nullptr; if ( voter->proxy ) { auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.update( *proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.quantity; } ); + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.quantity; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } @@ -237,8 +237,8 @@ namespace eosiosystem { producers_table producers_tbl( SystemAccount, SystemAccount ); for( auto p : *producers ) { auto prod = producers_tbl.find( p ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& v ) { + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& v ) { v.total_votes -= amount.quantity; }); } @@ -247,7 +247,7 @@ namespace eosiosystem { if (voter->deferred_trx_id) { //XXX cancel_deferred_transaction(voter->deferred_trx_id); } - voters_tbl.update( *voter, 0, [&](voter_info& a) { + voters_tbl.modify( voter, 0, [&](voter_info& a) { a.staked += a.unstaking; a.unstaking.quantity = 0; a.unstake_per_week.quantity = 0; @@ -421,8 +421,8 @@ namespace eosiosystem { static void on( const unstake_vote_deferred& usv) { require_auth( usv.voter ); voters_table voters_tbl( SystemAccount, SystemAccount ); - const auto* voter = voters_tbl.find( usv.voter ); - eosio_assert( bool(voter), "stake not found" ); + auto voter = voters_tbl.find( usv.voter ); + eosio_assert( voter != voters_tbl.end(), "stake not found" ); auto weeks = (now() - voter->last_unstake_time) / unstake_pay_period; eosio_assert( 0 == weeks, "less than one week passed since last transfer or unstake request" ); @@ -433,7 +433,7 @@ namespace eosiosystem { currency::inline_transfer( SystemAccount, usv.voter, unstake_amount, "unstake voting" ); - voters_tbl.update( *voter, 0, [&](voter_info& a) { + voters_tbl.modify( voter, 0, [&](voter_info& a) { a.unstaking -= unstake_amount; a.deferred_trx_id = new_trx_id; a.last_unstake_time = a.last_unstake_time + weeks * unstake_pay_period; @@ -472,7 +472,7 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto voter = voters_tbl.find( vp.voter ); - eosio_assert( bool(voter) && ( 0 < voter->staked.quantity || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); + eosio_assert( voter != voters_tbl.end() && ( 0 < voter->staked.quantity || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); if ( voter->is_proxy ) { eosio_assert( vp.proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); } @@ -484,8 +484,8 @@ namespace eosiosystem { return; // nothing changed } auto old_proxy = voters_tbl.find( voter->proxy ); - eosio_assert( bool(old_proxy), "old proxy not found" ); //data corruption - voters_tbl.update( *old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); + eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption + voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) old_producers = &old_proxy->producers; } @@ -497,8 +497,8 @@ namespace eosiosystem { const std::vector* new_producers = nullptr; if ( vp.proxy ) { auto new_proxy = voters_tbl.find( vp.proxy ); - eosio_assert( new_proxy && new_proxy->is_proxy, "proxy not found" ); - voters_tbl.update( *new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); + eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); + voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); new_producers = &new_proxy->producers; } else { new_producers = &vp.producers; @@ -516,8 +516,8 @@ namespace eosiosystem { auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); for ( auto it = revoked.begin(); it != end_it; ++it ) { auto prod = producers_tbl.find( *it ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); } } @@ -526,15 +526,15 @@ namespace eosiosystem { auto end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); for ( auto it = elected.begin(); it != end_it; ++it ) { auto prod = producers_tbl.find( *it ); - eosio_assert( bool(prod), "producer is not registered" ); + eosio_assert( prod != producers_tbl.end(), "producer is not registered" ); if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers eosio_assert( prod->active(), "producer is not currently registered" ); } - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); + producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); } // save new values to the account itself - voters_tbl.update( *voter, 0, [&](voter_info& a) { + voters_tbl.modify( voter, 0, [&](voter_info& a) { a.proxy = vp.proxy; a.last_update = now(); a.producers = vp.producers; @@ -552,10 +552,10 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto proxy = voters_tbl.find( reg.proxy ); - if ( proxy ) { + if ( proxy != voters_tbl.end() ) { eosio_assert( proxy->is_proxy == 0, "account is already a proxy" ); eosio_assert( proxy->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - voters_tbl.update( *proxy, 0, [&](voter_info& a) { + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.is_proxy = 1; a.last_update = now(); //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value @@ -564,8 +564,8 @@ namespace eosiosystem { producers_table producers_tbl( SystemAccount, SystemAccount ); for ( auto p : proxy->producers ) { auto prod = producers_tbl.find( p ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes += proxy->proxied_votes; }); + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += proxy->proxied_votes; }); } } } else { @@ -591,10 +591,10 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto proxy = voters_tbl.find( reg.proxy ); - eosio_assert( bool(proxy), "proxy not found" ); + eosio_assert( proxy == voters_tbl.end(), "proxy not found" ); eosio_assert( proxy->is_proxy == 1, "account is not a proxy" ); - voters_tbl.update( *proxy, 0, [&](voter_info& a) { + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.is_proxy = 0; a.last_update = now(); //a.proxied_votes should be kept in order to be able to reenable this proxy in the future @@ -604,8 +604,8 @@ namespace eosiosystem { producers_table producers_tbl( SystemAccount, SystemAccount ); for ( auto p : proxy->producers ) { auto prod = producers_tbl.find( p ); - eosio_assert( bool(prod), "never existed producer" ); //data corruption - producers_tbl.update( *prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); } } } From 033c1fa56f23e9c4ed3dde435501ab07c4ce7924 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 16 Mar 2018 18:07:51 -0400 Subject: [PATCH 0100/1048] fixes to make system contract tests working after merge --- voting.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.hpp b/voting.hpp index c650c7bc..978759cf 100644 --- a/voting.hpp +++ b/voting.hpp @@ -591,7 +591,7 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto proxy = voters_tbl.find( reg.proxy ); - eosio_assert( proxy == voters_tbl.end(), "proxy not found" ); + eosio_assert( proxy != voters_tbl.end(), "proxy not found" ); eosio_assert( proxy->is_proxy == 1, "account is not a proxy" ); voters_tbl.modify( proxy, 0, [&](voter_info& a) { From b52b861fbf17ac6dbdeeda7c1dd150870eb2aa40 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 19 Mar 2018 11:49:02 -0400 Subject: [PATCH 0101/1048] update_elected_producer updated to work with latest fix in DBAPI --- voting.hpp | 22 +++------------------- 1 file changed, 3 insertions(+), 19 deletions(-) diff --git a/voting.hpp b/voting.hpp index 978759cf..ed446330 100644 --- a/voting.hpp +++ b/voting.hpp @@ -299,25 +299,13 @@ namespace eosiosystem { eosio::producer_schedule schedule; schedule.producers.reserve(21); - /* - print ("Producers: "); - for (auto it = idx.begin(); it != idx.end(); ++it) { - print( it->owner, " (", it->total_votes, "), " ); - } - print ("\n"); - */ - auto it = idx.begin(); - if (it == idx.end()) { - return; - } - //++it; size_t n = 0; - while ( n < 21 && 0 < it->total_votes ) { + for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { if ( it->active() ) { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); - std::copy(it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data); + std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data ); target_block_size[n] = it->prefs.target_block_size; max_block_size[n] = it->prefs.max_block_size; @@ -340,11 +328,6 @@ namespace eosiosystem { percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; ++n; } - - ++it; - if (it == idx.end()) { - break; - } } if ( n == 0 ) { //no active producers with votes > 0 return; @@ -361,6 +344,7 @@ namespace eosiosystem { std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); + std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); std::sort( max_generated_transaction_size.begin(), max_generated_transaction_size.begin()+n ); std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); From e75721be7af63c6b498bc29f6221c236b5cce654 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 19 Mar 2018 11:58:20 -0400 Subject: [PATCH 0102/1048] little code cleanup in the system contract --- eosio.system.hpp | 3 +-- voting.hpp | 2 -- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index f8203a0f..f709fc31 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,7 +4,6 @@ */ #pragma once -//include "voting.hpp" #include "delegate_bandwith.hpp" #include @@ -25,7 +24,7 @@ namespace eosiosystem { }; template - class contract : /*public voting,*/ public delegate_bandwith { + class contract : public delegate_bandwith { public: using voting::on; using delegate_bandwith::on; diff --git a/voting.hpp b/voting.hpp index ed446330..e515b506 100644 --- a/voting.hpp +++ b/voting.hpp @@ -352,8 +352,6 @@ namespace eosiosystem { // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp bytes packed_schedule = pack(schedule); - //print( "schedule size = ", schedule.producers.size(), "\n" ); - //print( "set_active_producers( ... , ", packed_schedule.size(), " );\n" ); set_active_producers( packed_schedule.data(), packed_schedule.size() ); size_t median = n/2; From d2ef9b67bf698a3c82d9ae0ab2684351ffd8749f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 19 Mar 2018 14:08:53 -0400 Subject: [PATCH 0103/1048] Code cleaning --- common.hpp | 3 +-- eosio.system.hpp | 16 ++-------------- voting.hpp | 14 -------------- 3 files changed, 3 insertions(+), 30 deletions(-) diff --git a/common.hpp b/common.hpp index e614d615..9e22169a 100644 --- a/common.hpp +++ b/common.hpp @@ -16,7 +16,6 @@ namespace eosiosystem { typedef typename currency::token_type system_token_type; static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) - static constexpr uint8_t currency_decimals = currency_symbol & 0xFF; // 4 static const uint32_t max_inflation_rate = 5; // 5% annual inflation static const uint32_t blocks_per_producer = 6; @@ -36,7 +35,7 @@ namespace eosiosystem { system_token_type payment_per_block = system_token_type(); system_token_type payment_to_eos_bucket = system_token_type(); time first_block_time_in_cycle = 0; - uint32_t blocks_per_cycle = 0; //6 * 21; + uint32_t blocks_per_cycle = 0; time last_bucket_fill_time = 0; system_token_type eos_bucket = system_token_type(); diff --git a/eosio.system.hpp b/eosio.system.hpp index f8203a0f..faf17019 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -38,7 +38,6 @@ namespace eosiosystem { static const uint32_t max_inflation_rate = common::max_inflation_rate; static const uint32_t seconds_per_day = common::seconds_per_day; static const uint32_t num_of_payed_producers = 121; - static const uint32_t slot = 1; ACTION( SystemAccount, nonce ) { eosio::string value; @@ -76,34 +75,23 @@ namespace eosiosystem { static void on(const onblock& ob) { // update parameters if it's a new cycle - if (update_cycle(ob.header.timestamp)) { - // prints("\nNew Cycle!\n\n"); - } + update_cycle(ob.header.timestamp); + producers_table producers_tbl(SystemAccount, SystemAccount); account_name producer = ob.header.producer; auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); const system_token_type block_payment = parameters.payment_per_block; auto prod = producers_tbl.find(producer); - // This check is needed when everything works - // eosio_assert(prod != nullptr, "something wrong here"); if ( prod != producers_tbl.end() ) { - // prints("Producer found\n"); producers_tbl.modify( prod, 0, [&](auto& p) { - // printi((uint64_t)p.per_block_payments.quantity); - // prints("\n"); p.per_block_payments += block_payment; - // printi((uint64_t)p.per_block_payments.quantity); - // prints("\n"); p.last_produced_block_time = ob.header.timestamp; }); } - // prints("payments to eos bucket\n"); const uint32_t num_of_payments = ob.header.timestamp - parameters.last_bucket_fill_time; const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; - // printi(to_eos_bucket.quantity); - // prints("\n"); parameters.last_bucket_fill_time = ob.header.timestamp; parameters.eos_bucket += to_eos_bucket; global_state_singleton::set(parameters); diff --git a/voting.hpp b/voting.hpp index 978759cf..dd528d23 100644 --- a/voting.hpp +++ b/voting.hpp @@ -40,7 +40,6 @@ namespace eosiosystem { using global_state_singleton = typename common::global_state_singleton; static const uint32_t max_inflation_rate = common::max_inflation_rate; - // static const uint32_t blocks_per_cycle = common::blocks_per_cycle; static constexpr uint32_t max_unstake_requests = 10; static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week static constexpr uint32_t unstake_payments = 26; // during 26 weeks @@ -259,21 +258,8 @@ namespace eosiosystem { static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { const system_token_type token_supply = currency::get_total_supply(); - /* - prints("token_supply\n"); - printi(token_supply.quantity); - prints("\ntoken_supply\n"); - */ const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate; const auto& inflation_ratio = int_logarithm_one_plus(inflation_rate); - /* - printi(inflation_rate); - prints("\n"); - printi(inflation_ratio.first); - prints("/"); - printi(inflation_ratio.second); - prints("\n"); - */ return (token_supply * inflation_ratio.first) / (inflation_ratio.second * blocks_per_year); } From da760889dcc0a2c8cb7e974800d2b3996a30aa56 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 19 Mar 2018 15:26:18 -0400 Subject: [PATCH 0104/1048] system contract code cleanup --- voting.hpp | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/voting.hpp b/voting.hpp index a5cc443f..7a1c282c 100644 --- a/voting.hpp +++ b/voting.hpp @@ -194,32 +194,10 @@ namespace eosiosystem { if ( 0 < amount.quantity ) { eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); - /* - if (voter->deferred_trx_id) { - //XXX cancel_deferred_transaction(voter->deferred_trx_id); - } - - unstake_vote_deferred dt; - dt.voter = acnt; - uint32_t new_trx_id = 0;//XXX send_deferred(dt); - - avotes.modify( voter, 0, [&](voter_info& a) { - a.staked -= amount; - a.unstaking += a.unstaking + amount; - //round up to guarantee that there will be no unpaid balance after 26 weeks, and we are able refund amount < unstake_payments - a.unstake_per_week = system_token_type( a.unstaking.quantity /unstake_payments + a.unstaking.quantity % unstake_payments ); - a.deferred_trx_id = new_trx_id; - a.last_update = now(); - }); - */ - - // Temporary code: immediate unstake voters_tbl.modify( voter, 0, [&](voter_info& a) { a.staked -= amount; a.last_update = now(); }); - //currency::inline_transfer( SystemAccount, acnt, amount, "unstake voting" ); - // end of temporary code const std::vector* producers = nullptr; if ( voter->proxy ) { From f47b23231b516c1e61089c4bf7e9d52ca0ab2bf3 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 16 Mar 2018 14:39:41 -0400 Subject: [PATCH 0105/1048] Rebase onto master branch --- eosio.system.hpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 7a28da17..b998606d 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -12,15 +12,17 @@ namespace eosiosystem { struct PACKED(block_header) { - checksum256 previous; - time timestamp; - checksum256 transaction_mroot; - checksum256 action_mroot; - checksum256 block_mroot; - account_name producer; - eosio::optional new_producers; + checksum256 previous; + time timestamp; + checksum256 transaction_mroot; + checksum256 action_mroot; + checksum256 block_mroot; + account_name producer; + uint32_t schedule_version; + eosio::optional new_producers; - EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot)(producer)(new_producers)) + EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot) + (producer)(schedule_version)(new_producers)) }; template From 1ab70051c3534b9d2758f1a9e2db32e192b0796d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 19 Mar 2018 15:52:29 -0400 Subject: [PATCH 0106/1048] Fixed build issue --- eosio.system.hpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index b998606d..0d81aee1 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -12,14 +12,14 @@ namespace eosiosystem { struct PACKED(block_header) { - checksum256 previous; - time timestamp; - checksum256 transaction_mroot; - checksum256 action_mroot; - checksum256 block_mroot; - account_name producer; - uint32_t schedule_version; - eosio::optional new_producers; + checksum256 previous; + time timestamp; + checksum256 transaction_mroot; + checksum256 action_mroot; + checksum256 block_mroot; + account_name producer; + uint32_t schedule_version; + eosio::optional new_producers; EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot) (producer)(schedule_version)(new_producers)) From e93dacd03365c75225468e9eda6bbc76a131d3cc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 19 Mar 2018 18:20:34 -0400 Subject: [PATCH 0107/1048] Temporarily disable block tests, abi serialization for onblock --- eosio.system.abi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index 441c0827..1d9d979c 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -170,6 +170,24 @@ "fields": [ {"name":"owner", "type":"account_name"} ] + },{ + "name": "block_header", + "base": "", + "fields": [ + {"name":"previous", "type":"uint8[]"}, + {"name":"timestamp", "type":"uint32"}, + {"name":"transaction_mroot", "type":"uint8[]"}, + {"name":"action_mroot", "type":"uint8[]"}, + {"name":"block_mroot", "type":"uint8[]"}, + {"name":"producer", "type":"account_name"}, + {"name":"schedule_version", "type":"uint32"} + ] + },{ + "name": "onblock", + "base": "", + "fields": [ + {"name":"header", "type":"block_header"} + ] } ], "actions": [{ @@ -202,6 +220,9 @@ },{ "name": "claimrewards", "type": "claimrewards" + },{ + "name": "onblock", + "type": "onblock" } ], "tables": [ From 62d1367f185d4a3fe27f19da48b0e00f97d65180 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 20 Mar 2018 09:32:48 -0400 Subject: [PATCH 0108/1048] Fix for onblock abi serialization --- eosio.system.abi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 1d9d979c..515f618e 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -174,11 +174,11 @@ "name": "block_header", "base": "", "fields": [ - {"name":"previous", "type":"uint8[]"}, + {"name":"previous", "type":"checksum256"}, {"name":"timestamp", "type":"uint32"}, - {"name":"transaction_mroot", "type":"uint8[]"}, - {"name":"action_mroot", "type":"uint8[]"}, - {"name":"block_mroot", "type":"uint8[]"}, + {"name":"transaction_mroot", "type":"checksum256"}, + {"name":"action_mroot", "type":"checksum256"}, + {"name":"block_mroot", "type":"checksum256"}, {"name":"producer", "type":"account_name"}, {"name":"schedule_version", "type":"uint32"} ] From 669a5fe187bbc0292da9b87c67ba54c55ad1e743 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 20 Mar 2018 10:42:47 -0400 Subject: [PATCH 0109/1048] Move onblock abi serialization to native side --- eosio.system.abi | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 515f618e..441c0827 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -170,24 +170,6 @@ "fields": [ {"name":"owner", "type":"account_name"} ] - },{ - "name": "block_header", - "base": "", - "fields": [ - {"name":"previous", "type":"checksum256"}, - {"name":"timestamp", "type":"uint32"}, - {"name":"transaction_mroot", "type":"checksum256"}, - {"name":"action_mroot", "type":"checksum256"}, - {"name":"block_mroot", "type":"checksum256"}, - {"name":"producer", "type":"account_name"}, - {"name":"schedule_version", "type":"uint32"} - ] - },{ - "name": "onblock", - "base": "", - "fields": [ - {"name":"header", "type":"block_header"} - ] } ], "actions": [{ @@ -220,9 +202,6 @@ },{ "name": "claimrewards", "type": "claimrewards" - },{ - "name": "onblock", - "type": "onblock" } ], "tables": [ From bd9d5ee477c4bcef012d0bf6e2950b75c99dc74c Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 20 Mar 2018 11:26:59 -0400 Subject: [PATCH 0110/1048] deferred unstaking first draft --- common.hpp | 8 ++-- delegate_bandwith.hpp | 107 +++++++++++++++++++++++++++++------------- eosio.system.hpp | 2 +- voting.hpp | 33 +------------ 4 files changed, 81 insertions(+), 69 deletions(-) diff --git a/common.hpp b/common.hpp index 9e22169a..f85e8ac6 100644 --- a/common.hpp +++ b/common.hpp @@ -16,10 +16,10 @@ namespace eosiosystem { typedef typename currency::token_type system_token_type; static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) - static const uint32_t max_inflation_rate = 5; // 5% annual inflation + static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation - static const uint32_t blocks_per_producer = 6; - static const uint32_t seconds_per_day = 24 * 3600; + static constexpr uint32_t blocks_per_producer = 6; + static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint32_t days_per_4years = 1461; struct eosio_parameters : eosio::blockchain_parameters { @@ -42,7 +42,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) (last_bucket_fill_time)(eos_bucket) ) - }; + }; typedef eosio::singleton global_state_singleton; diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 5ccf8fb5..4d4bf59d 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include @@ -24,6 +25,7 @@ namespace eosiosystem { using eosio::const_mem_fun; using eosio::bytes; using eosio::print; + using eosio::permission_level; using std::map; using std::pair; @@ -31,6 +33,8 @@ namespace eosiosystem { class delegate_bandwith : public voting { public: static constexpr account_name system_account = SystemAccount; + static constexpr time refund_delay = 3*24*3600; + static constexpr time refund_expiration_time = 3600; using currency = typename common::currency; using system_token_type = typename common::system_token_type; using eosio_parameters = typename common::eosio_parameters; @@ -59,26 +63,26 @@ namespace eosiosystem { typename currency::token_type cpu_weight; typename currency::token_type storage_stake; uint64_t storage_bytes = 0; - /* - uint32_t start_pending_net_withdraw = 0; - typename currency::token_type pending_net_withdraw; - uint64_t deferred_net_withdraw_handler = 0; - - uint32_t start_pending_cpu_withdraw = 0; - typename currency::token_type pending_cpu_withdraw; - uint64_t deferred_cpu_withdraw_handler = 0; - */ uint64_t primary_key()const { return to; } - EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) - /* (start_pending_net_withdraw)(pending_net_withdraw)(deferred_net_withdraw_handler) - (start_pending_cpu_withdraw)(pending_cpu_withdraw)(deferred_cpu_withdraw_handler)*/ ) + EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) }; - typedef eosio::multi_index< N(totalband), total_resources> total_resources_index_type; - typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_index_type; + struct refund_request { + account_name owner; + time request_time; + typename currency::token_type amount; + + uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(amount) ) + }; + + typedef eosio::multi_index< N(totalband), total_resources> total_resources_table; + typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_table; + typedef eosio::multi_index< N(refunds), refund_request> refunds_table; ACTION( SystemAccount, delegatebw ) { account_name from; @@ -101,6 +105,12 @@ namespace eosiosystem { EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity)(unstake_storage_bytes) ) }; + ACTION( SystemAccount, refund ) { + account_name owner; + + EOSLIB_SERIALIZE( refund, (owner) ) + }; + static void on( const delegatebw& del ) { eosio_assert( del.stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( del.stake_net_quantity.amount >= 0, "must stake a positive amount" ); @@ -134,10 +144,10 @@ namespace eosiosystem { global_state_singleton::set(parameters); } - del_bandwidth_index_type del_index( SystemAccount, del.from ); - auto itr = del_index.find( del.receiver ); - if( itr == del_index.end() ) { - del_index.emplace( del.from, [&]( auto& dbo ){ + del_bandwidth_table del_tbl( SystemAccount, del.from ); + auto itr = del_tbl.find( del.receiver ); + if( itr == del_tbl.end() ) { + del_tbl.emplace( del.from, [&]( auto& dbo ){ dbo.from = del.from; dbo.to = del.receiver; dbo.net_weight = del.stake_net_quantity; @@ -147,7 +157,7 @@ namespace eosiosystem { }); } else { - del_index.modify( itr, del.from, [&]( auto& dbo ){ + del_tbl.modify( itr, del.from, [&]( auto& dbo ){ dbo.net_weight += del.stake_net_quantity; dbo.cpu_weight += del.stake_cpu_quantity; dbo.storage_stake += del.stake_storage_quantity; @@ -155,10 +165,10 @@ namespace eosiosystem { }); } - total_resources_index_type total_index( SystemAccount, del.receiver ); - auto tot_itr = total_index.find( del.receiver ); - if( tot_itr == total_index.end() ) { - tot_itr = total_index.emplace( del.from, [&]( auto& tot ) { + total_resources_table totals_tbl( SystemAccount, del.receiver ); + auto tot_itr = totals_tbl.find( del.receiver ); + if( tot_itr == totals_tbl.end() ) { + tot_itr = totals_tbl.emplace( del.from, [&]( auto& tot ) { tot.owner = del.receiver; tot.net_weight = del.stake_net_quantity; tot.cpu_weight = del.stake_cpu_quantity; @@ -166,7 +176,7 @@ namespace eosiosystem { tot.storage_bytes = storage_bytes; }); } else { - total_index.modify( tot_itr, del.from == del.receiver ? del.from : 0, [&]( auto& tot ) { + totals_tbl.modify( tot_itr, del.from == del.receiver ? del.from : 0, [&]( auto& tot ) { tot.net_weight += del.stake_net_quantity; tot.cpu_weight += del.stake_cpu_quantity; tot.storage_stake += del.stake_storage_quantity; @@ -190,8 +200,8 @@ namespace eosiosystem { //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - del_bandwidth_index_type del_index( SystemAccount, del.from ); - const auto& dbw = del_index.get( del.receiver ); + del_bandwidth_table del_tbl( SystemAccount, del.from ); + const auto& dbw = del_tbl.get( del.receiver ); eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); @@ -213,16 +223,16 @@ namespace eosiosystem { eosio_assert( total_refund.quantity > 0, "must unstake a positive amount" ); - del_index.modify( dbw, del.from, [&]( auto& dbo ){ + del_tbl.modify( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; dbo.cpu_weight -= del.unstake_cpu_quantity; dbo.storage_stake -= storage_stake_decrease; dbo.storage_bytes -= del.unstake_storage_bytes; }); - total_resources_index_type total_index( SystemAccount, del.receiver ); - const auto& totals = total_index.get( del.receiver ); - total_index.modify( totals, 0, [&]( auto& tot ) { + total_resources_table totals_tbl( SystemAccount, del.receiver ); + const auto& totals = totals_tbl.get( del.receiver ); + totals_tbl.modify( totals, 0, [&]( auto& tot ) { tot.net_weight -= del.unstake_net_quantity; tot.cpu_weight -= del.unstake_cpu_quantity; tot.storage_stake -= storage_stake_decrease; @@ -231,12 +241,45 @@ namespace eosiosystem { set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity, 0 ); - /// TODO: implement / enforce time delays on withdrawing - currency::inline_transfer( SystemAccount, del.from, total_refund, "unstake bandwidth" ); + refunds_table refunds_tbl( SystemAccount, del.from ); + //create refund request + auto req = refunds_tbl.find( del.from ); + if ( req != refunds_tbl.end() ) { + refunds_tbl.modify( req, 0, [&]( refund_request& r ) { + r.amount += del.unstake_net_quantity + del.unstake_cpu_quantity + storage_stake_decrease; + r.request_time = now(); + }); + } else { + refunds_tbl.emplace( del.from, [&]( refund_request& r ) { + r.amount = del.unstake_net_quantity + del.unstake_cpu_quantity + storage_stake_decrease; + r.request_time = now(); + }); + } + //cancel previous deferred transaction if we have one + cancel_deferred( del.from ); + + //create new deferred transaction + const auto self = current_receiver(); + refund act; + act.owner = del.from; + transaction out( now() + refund_delay + refund_expiration_time ); + out.actions.emplace_back( permission_level{ self, N(active) }, self, N(refund), act ); + out.send( del.from, now() + refund_delay ); + if ( asset(0) < del.unstake_net_quantity + del.unstake_cpu_quantity ) { voting::decrease_voting_power( del.from, del.unstake_net_quantity + del.unstake_cpu_quantity ); } } // undelegatebw + + static void on( const refund& r ) { + refunds_table refunds_tbl( SystemAccount, r.owner ); + auto req = refunds_tbl.find( r.owner ); + eosio_assert( req != refunds_tbl.end(), "refund request not found" ); + eosio_assert( req->request_time + refund_delay <= now(), "refund is not available yet" ); + + currency::inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); + refunds_tbl.erase( req ); + } }; } diff --git a/eosio.system.hpp b/eosio.system.hpp index 0d81aee1..d94785b0 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -157,12 +157,12 @@ namespace eosiosystem { if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwith::undelegatebw, + typename delegate_bandwith::refund, typename voting::regproxy, typename voting::unregproxy, typename voting::regproducer, typename voting::unregprod, typename voting::voteproducer, - typename voting::unstake_vote_deferred, onblock, claimrewards, nonce>( code, act) ) { diff --git a/voting.hpp b/voting.hpp index 7a1c282c..1010e377 100644 --- a/voting.hpp +++ b/voting.hpp @@ -39,10 +39,7 @@ namespace eosiosystem { using eosio_parameters = typename common::eosio_parameters; using global_state_singleton = typename common::global_state_singleton; - static const uint32_t max_inflation_rate = common::max_inflation_rate; - static constexpr uint32_t max_unstake_requests = 10; - static constexpr uint32_t unstake_pay_period = 7*24*3600; // one per week - static constexpr uint32_t unstake_payments = 26; // during 26 weeks + static constexpr uint32_t max_inflation_rate = common::max_inflation_rate; static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year struct producer_info { @@ -358,34 +355,6 @@ namespace eosiosystem { global_state_singleton::set(parameters); } - ACTION( SystemAccount, unstake_vote_deferred ) { - account_name voter; - - EOSLIB_SERIALIZE( unstake_vote_deferred, (voter) ) - }; - - static void on( const unstake_vote_deferred& usv) { - require_auth( usv.voter ); - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( usv.voter ); - eosio_assert( voter != voters_tbl.end(), "stake not found" ); - - auto weeks = (now() - voter->last_unstake_time) / unstake_pay_period; - eosio_assert( 0 == weeks, "less than one week passed since last transfer or unstake request" ); - eosio_assert( 0 < voter->unstaking.quantity, "no unstaking money to transfer" ); - - auto unstake_amount = std::min(weeks * voter->unstake_per_week, voter->unstaking); - uint32_t new_trx_id = unstake_amount < voter->unstaking ? /* XXX send_deferred() */ 0 : 0; - - currency::inline_transfer( SystemAccount, usv.voter, unstake_amount, "unstake voting" ); - - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.unstaking -= unstake_amount; - a.deferred_trx_id = new_trx_id; - a.last_unstake_time = a.last_unstake_time + weeks * unstake_pay_period; - }); - } - ACTION( SystemAccount, voteproducer ) { account_name voter; account_name proxy; From 6949975201f1ce833a2a21a2e3f6a00c5eaf154f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 20 Mar 2018 14:09:07 -0400 Subject: [PATCH 0111/1048] Fixed serialization bug --- eosio.system.abi | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 441c0827..566da455 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -1,9 +1,5 @@ { - "types": [{ - "new_type_name": "account_name", - "type": "name" - } - ], + "types": [], "structs": [{ "name": "transfer", "base": "", From de637244809e6f9d690115dbf388f3fc4d82deeb Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 21 Mar 2018 15:39:07 -0400 Subject: [PATCH 0112/1048] deferred unstaking fix and tests --- delegate_bandwith.hpp | 6 +++++- eosio.system.abi | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/delegate_bandwith.hpp b/delegate_bandwith.hpp index 4d4bf59d..d630075d 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwith.hpp @@ -251,12 +251,16 @@ namespace eosiosystem { }); } else { refunds_tbl.emplace( del.from, [&]( refund_request& r ) { + r.owner = del.from; r.amount = del.unstake_net_quantity + del.unstake_cpu_quantity + storage_stake_decrease; r.request_time = now(); }); } //cancel previous deferred transaction if we have one - cancel_deferred( del.from ); + //because of an implementation bug currently it would cancel transaction + //that will be created later in this action + //commenting out for now + //cancel_deferred( del.from ); //create new deferred transaction const auto self = current_receiver(); diff --git a/eosio.system.abi b/eosio.system.abi index 566da455..8197f8e1 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -50,6 +50,12 @@ {"name":"unstake_cpu", "type":"asset"}, {"name":"unstake_bytes", "type":"uint64"} ] + },{ + "name": "refund", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] },{ "name": "delegated_bandwidth", "base": "", @@ -180,6 +186,9 @@ },{ "name": "undelegatebw", "type": "undelegatebw" + },{ + "name": "refund", + "type": "refund" },{ "name": "regproducer", "type": "regproducer" From ab84bc1f4ff7c75b3c393860bb667279b2e4dd7b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 21 Mar 2018 17:51:28 -0400 Subject: [PATCH 0113/1048] nonce serialization --- eosio.system.abi | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 566da455..314d4a40 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -1,13 +1,19 @@ { "types": [], "structs": [{ + "name": "nonce", + "base": "", + "fields": [ + {"name":"value", "type":"string"} + ] + },{ "name": "transfer", "base": "", "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"quantity", "type":"asset"}, - {"name":"memo", "type":"string"} + {"name":"from", "type":"account_name"}, + {"name":"to", "type":"account_name"}, + {"name":"quantity", "type":"asset"}, + {"name":"memo", "type":"string"} ] },{ "name": "issue", @@ -198,6 +204,9 @@ },{ "name": "claimrewards", "type": "claimrewards" + },{ + "name": "nonce", + "type": "nonce" } ], "tables": [ From 5761727a505c85a988f1cb658b7b546ffb5349dc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 22 Mar 2018 13:29:54 -0400 Subject: [PATCH 0114/1048] Use floating point in payment calculations --- common.hpp | 16 ---------------- voting.hpp | 8 +++++--- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/common.hpp b/common.hpp index f85e8ac6..fa977233 100644 --- a/common.hpp +++ b/common.hpp @@ -53,20 +53,4 @@ namespace eosiosystem { } }; - std::pair int_logarithm_one_plus(uint32_t x) { - static const uint64_t denom = 10000; - uint64_t ret = 0; - uint64_t x_power = x; - const uint64_t n = 4; - static const uint64_t ten_power = denom * denom * denom * denom; - for (uint64_t i = 0, p = ten_power; i < n; ++i) { - uint64_t factor = x_power * p / (i+1); - ret += factor; - ret -= 2 * (i % 2) * factor; - x_power *= x; - p /= denom; - } - return std::make_pair(ret / (denom * denom * denom), denom); - } - } diff --git a/voting.hpp b/voting.hpp index 1010e377..b2668072 100644 --- a/voting.hpp +++ b/voting.hpp @@ -19,6 +19,7 @@ #include #include +#include namespace eosiosystem { using eosio::indexed_by; @@ -233,9 +234,10 @@ namespace eosiosystem { static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { const system_token_type token_supply = currency::get_total_supply(); - const auto inflation_rate = max_inflation_rate * percent_of_max_inflation_rate; - const auto& inflation_ratio = int_logarithm_one_plus(inflation_rate); - return (token_supply * inflation_ratio.first) / (inflation_ratio.second * blocks_per_year); + const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); + double continuous_rate = std::log1p(annual_rate); + uint64_t payment = static_cast((continuous_rate * double(token_supply.quantity)) / double(blocks_per_year)); + return (system_token_type(payment)); } static void update_elected_producers(time cycle_time) { From bf8cc3c1d4bf8231134b25a7a1f3b308e935179b Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 21 Mar 2018 16:36:42 -0400 Subject: [PATCH 0115/1048] minor changes: typos, removed PACKED, use time typedef in voter_info, remove unnecessary padding --- ...ate_bandwith.hpp => delegate_bandwidth.hpp | 6 ++--- eosio.system.hpp | 24 +++++++++---------- voting.hpp | 12 ++++------ 3 files changed, 20 insertions(+), 22 deletions(-) rename delegate_bandwith.hpp => delegate_bandwidth.hpp (99%) diff --git a/delegate_bandwith.hpp b/delegate_bandwidth.hpp similarity index 99% rename from delegate_bandwith.hpp rename to delegate_bandwidth.hpp index d630075d..0a221dd6 100644 --- a/delegate_bandwith.hpp +++ b/delegate_bandwidth.hpp @@ -30,7 +30,7 @@ namespace eosiosystem { using std::pair; template - class delegate_bandwith : public voting { + class delegate_bandwidth : public voting { public: static constexpr account_name system_account = SystemAccount; static constexpr time refund_delay = 3*24*3600; @@ -59,11 +59,11 @@ namespace eosiosystem { struct delegated_bandwidth { account_name from; account_name to; - typename currency::token_type net_weight; + typename currency::token_type net_weight; typename currency::token_type cpu_weight; typename currency::token_type storage_stake; uint64_t storage_bytes = 0; - + uint64_t primary_key()const { return to; } EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) diff --git a/eosio.system.hpp b/eosio.system.hpp index d94785b0..2ea199d6 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,14 +4,14 @@ */ #pragma once -#include "delegate_bandwith.hpp" +#include "delegate_bandwidth.hpp" #include #include namespace eosiosystem { - struct PACKED(block_header) { + struct block_header { checksum256 previous; time timestamp; checksum256 transaction_mroot; @@ -20,18 +20,18 @@ namespace eosiosystem { account_name producer; uint32_t schedule_version; eosio::optional new_producers; - + EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot) (producer)(schedule_version)(new_producers)) }; template - class contract : public delegate_bandwith { + class contract : public delegate_bandwidth { public: using voting::on; - using delegate_bandwith::on; + using delegate_bandwidth::on; using pe = voting; - using db = delegate_bandwith; + using db = delegate_bandwidth; using currency = typename common::currency; using system_token_type = typename common::system_token_type; using producers_table = typename pe::producers_table; @@ -56,7 +56,7 @@ namespace eosiosystem { voting::update_elected_producers(block_time); return true; } - + static const uint32_t slots_per_cycle = parameters.blocks_per_cycle; const uint32_t time_slots = block_time - parameters.first_block_time_in_cycle; if (time_slots >= slots_per_cycle) { @@ -149,15 +149,15 @@ namespace eosiosystem { p.last_rewards_claim = now(); p.per_block_payments.quantity = 0; }); - + currency::inline_transfer(cr.owner, SystemAccount, rewards, "producer claiming rewards"); } - + static void apply( account_name code, action_name act ) { if ( !eosio::dispatch( code, act ) ) { - if( !eosio::dispatch::delegatebw, - typename delegate_bandwith::undelegatebw, - typename delegate_bandwith::refund, + if( !eosio::dispatch::delegatebw, + typename delegate_bandwidth::undelegatebw, + typename delegate_bandwidth::refund, typename voting::regproxy, typename voting::unregproxy, typename voting::regproducer, diff --git a/voting.hpp b/voting.hpp index b2668072..87d98a6a 100644 --- a/voting.hpp +++ b/voting.hpp @@ -24,7 +24,6 @@ namespace eosiosystem { using eosio::indexed_by; using eosio::const_mem_fun; - using eosio::member; using eosio::bytes; using eosio::print; using eosio::singleton; @@ -45,7 +44,6 @@ namespace eosiosystem { struct producer_info { account_name owner; - uint64_t padding = 0; uint128_t total_votes = 0; eosio_parameters prefs; eosio::bytes packed_key; /// a packed public key object @@ -71,7 +69,7 @@ namespace eosiosystem { struct voter_info { account_name owner = 0; account_name proxy = 0; - uint32_t last_update = 0; + time last_update = 0; uint32_t is_proxy = 0; system_token_type staked; system_token_type unstaking; @@ -97,12 +95,12 @@ namespace eosiosystem { }; /** - * This method will create a producer_config and producer_info object for 'producer' + * This method will create a producer_config and producer_info object for 'producer' * * @pre producer is not already registered * @pre producer to register is an account - * @pre authority of producer to register - * + * @pre authority of producer to register + * */ static void on( const regproducer& reg ) { require_auth( reg.producer ); @@ -350,7 +348,7 @@ namespace eosiosystem { if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { parameters.max_storage_size = parameters.total_storage_bytes_reserved; } - + auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); currency::inline_issue(SystemAccount, issue_quantity); set_blockchain_parameters(¶meters); From 44e4059f35d30f89576b21ba345fc45fe716a8d5 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 22 Mar 2018 11:16:55 -0400 Subject: [PATCH 0116/1048] Separate out C++ blockchain parameter setter/getter helper functions from C privileged API --- common.hpp | 6 +++--- voting.hpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common.hpp b/common.hpp index fa977233..ac73218f 100644 --- a/common.hpp +++ b/common.hpp @@ -21,11 +21,11 @@ namespace eosiosystem { static constexpr uint32_t blocks_per_producer = 6; static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint32_t days_per_4years = 1461; - + struct eosio_parameters : eosio::blockchain_parameters { uint32_t percent_of_max_inflation_rate = 0; uint32_t storage_reserve_ratio = 1000; // ratio * 1000 - + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) ) }; @@ -48,7 +48,7 @@ namespace eosiosystem { static eosio_global_state& get_default_parameters() { static eosio_global_state dp; - get_blockchain_parameters(&dp); + get_blockchain_parameters(dp); return dp; } }; diff --git a/voting.hpp b/voting.hpp index 87d98a6a..eb271499 100644 --- a/voting.hpp +++ b/voting.hpp @@ -351,7 +351,7 @@ namespace eosiosystem { auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); currency::inline_issue(SystemAccount, issue_quantity); - set_blockchain_parameters(¶meters); + set_blockchain_parameters(parameters); global_state_singleton::set(parameters); } From 0d89aee2b4a4dd2e98cbe9909a2e0f6880ebe043 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 22 Mar 2018 14:30:47 -0400 Subject: [PATCH 0117/1048] fix nullptr dereference if updating votes after prev proxy unregistered --- voting.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/voting.hpp b/voting.hpp index eb271499..a8a36673 100644 --- a/voting.hpp +++ b/voting.hpp @@ -425,7 +425,7 @@ namespace eosiosystem { votes += voter->proxied_votes; } - if ( old_producers ) { //old_producers == 0 if proxy has stoped being a proxy and votes were taken back from the producers at that moment + if ( old_producers ) { //old_producers == nullptr if proxy has stopped being a proxy and votes were taken back from the producers at that moment //revoke votes only from no longer elected std::vector revoked( old_producers->size() ); auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); @@ -438,7 +438,12 @@ namespace eosiosystem { //update newly elected std::vector elected( new_producers->size() ); - auto end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); + auto end_it = elected.begin(); + if( old_producers ) { + end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); + } else { + end_it = std::copy( new_producers->begin(), new_producers->end(), elected.begin() ); + } for ( auto it = elected.begin(); it != end_it; ++it ) { auto prod = producers_tbl.find( *it ); eosio_assert( prod != producers_tbl.end(), "producer is not registered" ); From 6ae4bc978f15bf230286cff485398e148550ca00 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 22 Mar 2018 15:34:44 -0400 Subject: [PATCH 0118/1048] Minor changes: use block_per_producer constant, and reorder values in median_properties_test to match reorder of chain_config. --- voting.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.hpp b/voting.hpp index a8a36673..c580f3c3 100644 --- a/voting.hpp +++ b/voting.hpp @@ -343,7 +343,7 @@ namespace eosiosystem { auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; parameters.payment_per_block = payment_per_block(half_of_percentage); parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); - parameters.blocks_per_cycle = 6 * schedule.producers.size(); + parameters.blocks_per_cycle = common::blocks_per_producer * schedule.producers.size(); if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { parameters.max_storage_size = parameters.total_storage_bytes_reserved; From 1182f6da76943ba20ba477681bade843ebcb0622 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 22 Mar 2018 18:09:52 -0400 Subject: [PATCH 0119/1048] Allow no one else other than owner to initiate the refund. (Allowing the owner to claim refund provides an alternative so that the owner can get their stake after the necessary delay even if the deferred transaction fails.) --- delegate_bandwidth.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index 0a221dd6..73435df2 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -267,7 +267,7 @@ namespace eosiosystem { refund act; act.owner = del.from; transaction out( now() + refund_delay + refund_expiration_time ); - out.actions.emplace_back( permission_level{ self, N(active) }, self, N(refund), act ); + out.actions.emplace_back( permission_level{ del.from, N(active) }, self, N(refund), act ); out.send( del.from, now() + refund_delay ); if ( asset(0) < del.unstake_net_quantity + del.unstake_cpu_quantity ) { @@ -277,10 +277,15 @@ namespace eosiosystem { } // undelegatebw static void on( const refund& r ) { + require_auth( r.owner ); + refunds_table refunds_tbl( SystemAccount, r.owner ); auto req = refunds_tbl.find( r.owner ); eosio_assert( req != refunds_tbl.end(), "refund request not found" ); eosio_assert( req->request_time + refund_delay <= now(), "refund is not available yet" ); + // Until now() becomes NOW, the fact that now() is the timestamp of the previous block could in theory + // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many + // consecutive missed blocks. currency::inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); refunds_tbl.erase( req ); From fc7806c2b3cdcfcce61b49ce16ce35cb045fd1e9 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 22 Mar 2018 19:30:52 -0400 Subject: [PATCH 0120/1048] initialize last_bucket_fill_time the very first time onblock is called and fix claimrewards --- eosio.system.hpp | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2ea199d6..0c03e154 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -53,6 +53,9 @@ namespace eosiosystem { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); if (parameters.first_block_time_in_cycle == 0) { + // This is the first time onblock is called in the blockchain. + parameters.last_bucket_fill_time = block_time; + global_state_singleton::set(parameters); voting::update_elected_producers(block_time); return true; } @@ -109,9 +112,9 @@ namespace eosiosystem { eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); producers_table producers_tbl(SystemAccount, SystemAccount); auto prod = producers_tbl.find(cr.owner); - eosio_assert(prod != producers_tbl.end(), "account name not producer list"); - eosio_assert(prod->active(), "producer is not active"); - if (prod->last_rewards_claim > 0) { + eosio_assert(prod != producers_tbl.end(), "account name is not in producer list"); + eosio_assert(prod->active(), "producer is not active"); // QUESTION: Why do we want to prevent inactive producers from claiming their earned rewards? + if( prod->last_rewards_claim > 0 ) { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } system_token_type rewards = prod->per_block_payments; @@ -119,32 +122,35 @@ namespace eosiosystem { auto itr = --idx.end(); bool is_among_payed_producers = false; - uint64_t total_producer_votes = 0; + uint128_t total_producer_votes = 0; uint32_t n = 0; - while (n < num_of_payed_producers) { - if (!is_among_payed_producers) { - if (itr->owner == cr.owner) + while( n < num_of_payed_producers ) { + if( !is_among_payed_producers ) { + if( itr->owner == cr.owner ) is_among_payed_producers = true; } - if (itr->active()) { + if( itr->active() ) { total_producer_votes += itr->total_votes; ++n; } - if (itr == idx.begin()) { + if( itr == idx.begin() ) { break; } --itr; } if (is_among_payed_producers && total_producer_votes > 0) { - if (global_state_singleton::exists()) { + if( global_state_singleton::exists() ) { auto parameters = global_state_singleton::get(); - auto share_of_eos_bucket = (uint64_t(prod->total_votes) * parameters.eos_bucket) / total_producer_votes; + auto share_of_eos_bucket = system_token_type( static_cast( (prod->total_votes * parameters.eos_bucket.quantity) / total_producer_votes ) ); // This will be improved in the future when total_votes becomes a double type. rewards += share_of_eos_bucket; parameters.eos_bucket -= share_of_eos_bucket; global_state_singleton::set(parameters); } } + + eosio_assert( rewards > system_token_type(), "no rewards available to claim" ); + producers_tbl.modify( prod, 0, [&](auto& p) { p.last_rewards_claim = now(); p.per_block_payments.quantity = 0; From beccd5763f40a278438c6f762eb4f147d4fa19b9 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 23 Mar 2018 16:56:39 -0400 Subject: [PATCH 0121/1048] update blocks_per_producer to reflect actual value in the chain --- common.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common.hpp b/common.hpp index ac73218f..d2e972c3 100644 --- a/common.hpp +++ b/common.hpp @@ -18,7 +18,7 @@ namespace eosiosystem { static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation - static constexpr uint32_t blocks_per_producer = 6; + static constexpr uint32_t blocks_per_producer = 12; static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint32_t days_per_4years = 1461; From e775b221a630b4bea13d47004448a069e61decc4 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sat, 24 Mar 2018 21:26:08 -0400 Subject: [PATCH 0122/1048] Cleanup Tests - disable mongo test that doesn't work - remove extra param from set_resource_limits --- eosio.system.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 1d0d6a7a..dbf7b813 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -205,7 +205,7 @@ namespace eosiosystem { }); } - set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity, 0 ); + set_resource_limits( tot_itr->owner, tot_itr->total_ram, tot_itr->total_net_weight.quantity, tot_itr->total_cpu_weight.quantity ); currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); } // delegatebw @@ -242,7 +242,7 @@ namespace eosiosystem { tot.total_cpu_weight -= del.unstake_cpu_quantity; }); - set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity, 0 ); + set_resource_limits( totals.owner, totals.total_ram, totals.total_net_weight.quantity, totals.total_cpu_weight.quantity ); /// TODO: implement / enforce time delays on withdrawing currency::inline_transfer( SystemAccount, del.from, total_stake, "unstake bandwidth" ); From 24976a0eab502a5ee40a4d6fbe7b625453ecac35 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 26 Mar 2018 19:50:35 -0400 Subject: [PATCH 0123/1048] producers vote on max_generated_transaction_count, check max_generated_transaction_count and max_generated_transaction_size right #1735 --- voting.hpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/voting.hpp b/voting.hpp index c580f3c3..52fec40b 100644 --- a/voting.hpp +++ b/voting.hpp @@ -255,6 +255,7 @@ namespace eosiosystem { std::array max_inline_depth; std::array max_inline_action_size; std::array max_generated_transaction_size; + std::array max_generated_transaction_count; std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; @@ -284,6 +285,7 @@ namespace eosiosystem { max_inline_depth[n] = it->prefs.max_inline_depth; max_inline_action_size[n] = it->prefs.max_inline_action_size; max_generated_transaction_size[n] = it->prefs.max_generated_transaction_size; + max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; @@ -307,6 +309,7 @@ namespace eosiosystem { std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); std::sort( max_generated_transaction_size.begin(), max_generated_transaction_size.begin()+n ); + std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); } @@ -332,6 +335,7 @@ namespace eosiosystem { parameters.max_inline_depth = max_inline_depth[median]; parameters.max_inline_action_size = max_inline_action_size[median]; parameters.max_generated_transaction_size = max_generated_transaction_size[median]; + parameters.max_generated_transaction_count = max_generated_transaction_count[median]; parameters.storage_reserve_ratio = storage_reserve_ratio[median]; parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; From 852ec1e876efcfa27e7eb72cece2b555ce60dc9c Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Thu, 22 Mar 2018 06:53:42 -0300 Subject: [PATCH 0124/1048] Update apply function signature for every contract --- eosio.system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 98df43bc..7e8709f3 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -10,7 +10,7 @@ using namespace eosiosystem; extern "C" { /// The apply method implements the dispatch of events to this contract - void apply( uint64_t code, uint64_t act ) { + void apply( uint64_t receiver, uint64_t code, uint64_t act ) { //print( eosio::name(code), "::", eosio::name(act) ); eosiosystem::contract::apply( code, act ); } From 15366fdf82f519322bd0eb853322abeb495140ad Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Tue, 27 Mar 2018 06:48:10 -0300 Subject: [PATCH 0125/1048] Modify eosio.system to handle current_receiver API removal --- delegate_bandwidth.hpp | 4 ++-- eosio.system.cpp | 2 +- eosio.system.hpp | 13 +++++++++---- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index 342fcba0..d55ba958 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -192,7 +192,7 @@ namespace eosiosystem { } } // delegatebw - static void on( const undelegatebw& del ) { + static void on( account_name receiver, const undelegatebw& del ) { eosio_assert( del.unstake_cpu_quantity.amount >= 0, "must unstake a positive amount" ); eosio_assert( del.unstake_net_quantity.amount >= 0, "must unstake a positive amount" ); @@ -263,7 +263,7 @@ namespace eosiosystem { //cancel_deferred( del.from ); //create new deferred transaction - const auto self = current_receiver(); + const auto self = receiver; //current_receiver(); refund act; act.owner = del.from; transaction out( now() + refund_delay + refund_expiration_time ); diff --git a/eosio.system.cpp b/eosio.system.cpp index 7e8709f3..d5986a1f 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -12,6 +12,6 @@ extern "C" { /// The apply method implements the dispatch of events to this contract void apply( uint64_t receiver, uint64_t code, uint64_t act ) { //print( eosio::name(code), "::", eosio::name(act) ); - eosiosystem::contract::apply( code, act ); + eosiosystem::contract::apply( receiver, code, act ); } } diff --git a/eosio.system.hpp b/eosio.system.hpp index 0c03e154..2a995a21 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -159,10 +159,9 @@ namespace eosiosystem { currency::inline_transfer(cr.owner, SystemAccount, rewards, "producer claiming rewards"); } - static void apply( account_name code, action_name act ) { + static void apply( account_name receiver, account_name code, action_name act ) { if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, - typename delegate_bandwidth::undelegatebw, typename delegate_bandwidth::refund, typename voting::regproxy, typename voting::unregproxy, @@ -172,8 +171,14 @@ namespace eosiosystem { onblock, claimrewards, nonce>( code, act) ) { - eosio::print("Unexpected action: ", eosio::name(act), "\n"); - eosio_assert( false, "received unexpected action"); + //TODO: Small hack until we refactor eosio.system like eosio.token + using undelegatebw = typename delegate_bandwidth::undelegatebw; + if(code == undelegatebw::get_account() && act == undelegatebw::get_name() ){ + contract().on( receiver, eosio::unpack_action_data() ); + } else { + eosio::print("Unexpected action: ", eosio::name(act), "\n"); + eosio_assert( false, "received unexpected action"); + } } } From 21735feb86c22052ae1a2b5b88ee78a67c3deff8 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 28 Mar 2018 17:53:46 -0400 Subject: [PATCH 0126/1048] Implmeent eosio.any link #1030 implment stub of new eosio.msig contract using new contract structure define eosio.msig abi eoslib name class now uses {} rather than constructor and uses magic_get serialization --- eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2a995a21..d9cbe751 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -176,7 +176,7 @@ namespace eosiosystem { if(code == undelegatebw::get_account() && act == undelegatebw::get_name() ){ contract().on( receiver, eosio::unpack_action_data() ); } else { - eosio::print("Unexpected action: ", eosio::name(act), "\n"); + eosio::print("Unexpected action: ", eosio::name{act}, "\n"); eosio_assert( false, "received unexpected action"); } } From cd6a246ac3fc7d4b1118e1905c8aae41e20d8210 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 29 Mar 2018 15:02:43 -0400 Subject: [PATCH 0127/1048] Removed conciseness checks and code --- eosio.system.hpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 2a995a21..c43d49fe 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -5,6 +5,7 @@ #pragma once #include "delegate_bandwidth.hpp" +#include "native.hpp" #include #include @@ -26,10 +27,11 @@ namespace eosiosystem { }; template - class contract : public delegate_bandwidth { + class contract : public delegate_bandwidth, public native { public: using voting::on; using delegate_bandwidth::on; + using native::on; using pe = voting; using db = delegate_bandwidth; using currency = typename common::currency; @@ -170,6 +172,16 @@ namespace eosiosystem { typename voting::voteproducer, onblock, claimrewards, + typename native::newaccount, + typename native::updateauth, + typename native::deleteauth, + typename native::linkauth, + typename native::unlinkauth, + typename native::postrecovery, + typename native::passrecovery, + typename native::vetorecovery, + typename native::setabi, + typename native::onerror, nonce>( code, act) ) { //TODO: Small hack until we refactor eosio.system like eosio.token using undelegatebw = typename delegate_bandwidth::undelegatebw; From a89b4276f720df553f3040c16faa8f2b10c29aed Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 29 Mar 2018 09:35:19 -0400 Subject: [PATCH 0128/1048] GH#1938 - Add handlers for native actions in system contract --- eosio.system.hpp | 14 +++++++- native.hpp | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 native.hpp diff --git a/eosio.system.hpp b/eosio.system.hpp index d9cbe751..ce69c871 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -5,6 +5,7 @@ #pragma once #include "delegate_bandwidth.hpp" +#include "native.hpp" #include #include @@ -26,10 +27,11 @@ namespace eosiosystem { }; template - class contract : public delegate_bandwidth { + class contract : public delegate_bandwidth, public native { public: using voting::on; using delegate_bandwidth::on; + using native::on; using pe = voting; using db = delegate_bandwidth; using currency = typename common::currency; @@ -170,6 +172,16 @@ namespace eosiosystem { typename voting::voteproducer, onblock, claimrewards, + typename native::newaccount, + typename native::updateauth, + typename native::deleteauth, + typename native::linkauth, + typename native::unlinkauth, + typename native::postrecovery, + typename native::passrecovery, + typename native::vetorecovery, + typename native::setabi, + typename native::onerror, nonce>( code, act) ) { //TODO: Small hack until we refactor eosio.system like eosio.token using undelegatebw = typename delegate_bandwidth::undelegatebw; diff --git a/native.hpp b/native.hpp new file mode 100644 index 00000000..b82e314f --- /dev/null +++ b/native.hpp @@ -0,0 +1,83 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include + +namespace eosiosystem { + template + class native { + public: + ACTION(SystemAccount, newaccount) { + EOSLIB_SERIALIZE(newaccount, BOOST_PP_SEQ_NIL) + }; + + static void on( const newaccount& ) { + } + + ACTION( SystemAccount, updateauth ) { + EOSLIB_SERIALIZE( updateauth, BOOST_PP_SEQ_NIL ) + }; + + static void on( const updateauth& ) { + } + + ACTION( SystemAccount, deleteauth ) { + EOSLIB_SERIALIZE( deleteauth, BOOST_PP_SEQ_NIL ) + }; + + static void on( const deleteauth& ) { + } + + ACTION( SystemAccount, linkauth ) { + EOSLIB_SERIALIZE( linkauth, BOOST_PP_SEQ_NIL ) + }; + + static void on( const linkauth& ) { + } + + ACTION( SystemAccount, unlinkauth ) { + EOSLIB_SERIALIZE( unlinkauth, BOOST_PP_SEQ_NIL ) + }; + + static void on( const unlinkauth& ) { + } + + ACTION( SystemAccount, postrecovery ) { + EOSLIB_SERIALIZE( postrecovery, BOOST_PP_SEQ_NIL ) + }; + + static void on( const postrecovery& ) { + } + + ACTION( SystemAccount, passrecovery ) { + EOSLIB_SERIALIZE( passrecovery, BOOST_PP_SEQ_NIL ) + }; + + static void on( const passrecovery& ) { + } + + ACTION( SystemAccount, vetorecovery ) { + EOSLIB_SERIALIZE( vetorecovery, BOOST_PP_SEQ_NIL ) + }; + + static void on( const vetorecovery& ) { + } + + ACTION( SystemAccount, setabi ) { + EOSLIB_SERIALIZE( setabi, BOOST_PP_SEQ_NIL ) + }; + + static void on( const setabi& ) { + } + + ACTION( SystemAccount, onerror ) { + EOSLIB_SERIALIZE( onerror, BOOST_PP_SEQ_NIL ) + }; + + static void on( const onerror& ) { + } + }; +} From 7b5a57144568ded80df64a50135c4ecbd1b762b0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 29 Mar 2018 14:26:59 -0400 Subject: [PATCH 0129/1048] GH#1938 - Added native action fields in system contract --- native.hpp | 133 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 121 insertions(+), 12 deletions(-) diff --git a/native.hpp b/native.hpp index b82e314f..35a302a9 100644 --- a/native.hpp +++ b/native.hpp @@ -7,74 +7,183 @@ #include namespace eosiosystem { + + typedef std::vector bytes; + typedef std::string type_name; + typedef std::string field_name; + + struct permission_level_weight { + permission_level permission; + weight_type weight; + + EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) + }; + + struct key_weight { + public_key key; + weight_type weight; + + EOSLIB_SERIALIZE( key_weight, (key)(weight) ) + }; + + struct authority { + uint32_t threshold; + std::vector keys; + std::vector accounts; + + EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) + }; + + struct type_def { + type_name new_type_name; + type_name type; + + EOSLIB_SERIALIZE( type_def, (new_type_name)(type) ) + }; + + struct field_def { + field_name name; + type_name type; + + EOSLIB_SERIALIZE( field_def, (name)(type) ) + }; + + struct struct_def { + type_name name; + type_name base; + std::vector fields; + + EOSLIB_SERIALIZE( struct_def, (name)(base)(fields) ) + }; + + struct action_def { + action_name name; + type_name type; + + EOSLIB_SERIALIZE(action_def, (name)(type) ) + }; + + struct table_def { + table_name name; + type_name index_type; + std::vector key_names; + std::vector key_types; + type_name type; + + EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) ) + }; + + struct abi_def { + std::vector types; + std::vector structs; + std::vector actions; + std::vector tables; + + EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables) ) + }; + template class native { public: - ACTION(SystemAccount, newaccount) { - EOSLIB_SERIALIZE(newaccount, BOOST_PP_SEQ_NIL) + ACTION( SystemAccount, newaccount ) { + account_name creator; + account_name name; + authority owner; + authority active; + authority recovery; + + EOSLIB_SERIALIZE( newaccount, (creator)(name)(owner)(active)(recovery) ) }; static void on( const newaccount& ) { } ACTION( SystemAccount, updateauth ) { - EOSLIB_SERIALIZE( updateauth, BOOST_PP_SEQ_NIL ) + account_name account; + permission_name permission; + permission_name parent; + authority data; + + EOSLIB_SERIALIZE( updateauth, (account)(permission)(parent)(data) ) }; static void on( const updateauth& ) { } ACTION( SystemAccount, deleteauth ) { - EOSLIB_SERIALIZE( deleteauth, BOOST_PP_SEQ_NIL ) + account_name account; + permission_name permission; + + EOSLIB_SERIALIZE( deleteauth, (account)(permission) ) }; static void on( const deleteauth& ) { } ACTION( SystemAccount, linkauth ) { - EOSLIB_SERIALIZE( linkauth, BOOST_PP_SEQ_NIL ) + account_name account; + account_name code; + action_name type; + permission_name requirement; + + EOSLIB_SERIALIZE( linkauth, (account)(code)(type)(requirement) ) }; static void on( const linkauth& ) { } ACTION( SystemAccount, unlinkauth ) { - EOSLIB_SERIALIZE( unlinkauth, BOOST_PP_SEQ_NIL ) + account_name account; + account_name code; + action_name type; + + EOSLIB_SERIALIZE( unlinkauth, (account)(code)(type) ) }; static void on( const unlinkauth& ) { } ACTION( SystemAccount, postrecovery ) { - EOSLIB_SERIALIZE( postrecovery, BOOST_PP_SEQ_NIL ) + account_name account; + authority data; + std::string memo; + + EOSLIB_SERIALIZE( postrecovery, (account)(data)(memo) ) }; static void on( const postrecovery& ) { } ACTION( SystemAccount, passrecovery ) { - EOSLIB_SERIALIZE( passrecovery, BOOST_PP_SEQ_NIL ) + account_name account; + + EOSLIB_SERIALIZE( passrecovery, (account) ) }; static void on( const passrecovery& ) { } ACTION( SystemAccount, vetorecovery ) { - EOSLIB_SERIALIZE( vetorecovery, BOOST_PP_SEQ_NIL ) + account_name account; + + EOSLIB_SERIALIZE( vetorecovery, (account) ) }; static void on( const vetorecovery& ) { } ACTION( SystemAccount, setabi ) { - EOSLIB_SERIALIZE( setabi, BOOST_PP_SEQ_NIL ) + account_name account; + abi_def abi; + + EOSLIB_SERIALIZE( setabi, (account)(abi) ) }; static void on( const setabi& ) { } - ACTION( SystemAccount, onerror ) { - EOSLIB_SERIALIZE( onerror, BOOST_PP_SEQ_NIL ) + struct onerror: eosio::action_meta, bytes { + EOSLIB_SERIALIZE_DERIVED( onerror, bytes, BOOST_PP_SEQ_NIL ) }; static void on( const onerror& ) { From 19045eaf9ef0c97c22fca1091d6969bd04954328 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 29 Mar 2018 16:04:21 -0400 Subject: [PATCH 0130/1048] GH#1938 - Handlers for canceldelay and mindelay --- eosio.system.hpp | 2 ++ native.hpp | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index ce69c871..67607a02 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -182,6 +182,8 @@ namespace eosiosystem { typename native::vetorecovery, typename native::setabi, typename native::onerror, + typename native::canceldelay, + typename native::mindelay, nonce>( code, act) ) { //TODO: Small hack until we refactor eosio.system like eosio.token using undelegatebw = typename delegate_bandwidth::undelegatebw; diff --git a/native.hpp b/native.hpp index 35a302a9..ca9c0ace 100644 --- a/native.hpp +++ b/native.hpp @@ -188,5 +188,23 @@ namespace eosiosystem { static void on( const onerror& ) { } + + ACTION( SystemAccount, canceldelay ) { + uint32_t sender_id; + + EOSLIB_SERIALIZE( canceldelay, (sender_id) ) + }; + + static void on( const canceldelay& ) { + } + + ACTION ( SystemAccount, mindelay ) { + uint32_t delay; + + EOSLIB_SERIALIZE( mindelay, (delay) ) + }; + + static void on( const mindelay& ) { + } }; } From f8485225d7fb6efd20e74fe150a9be7757f52707 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 29 Mar 2018 16:32:31 -0400 Subject: [PATCH 0131/1048] GH#1938 - Ignore unexpected actions in system contract instead of failing --- eosio.system.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 67607a02..8787f26b 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -189,9 +189,6 @@ namespace eosiosystem { using undelegatebw = typename delegate_bandwidth::undelegatebw; if(code == undelegatebw::get_account() && act == undelegatebw::get_name() ){ contract().on( receiver, eosio::unpack_action_data() ); - } else { - eosio::print("Unexpected action: ", eosio::name{act}, "\n"); - eosio_assert( false, "received unexpected action"); } } } From 7c9b13746dee1c58a0ff6187c07fbe8236eb2586 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 29 Mar 2018 16:32:40 -0400 Subject: [PATCH 0132/1048] Removed some more things and fixed some tests to work with the new checks --- eosio.system.hpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index ce69c871..d9cbe751 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -5,7 +5,6 @@ #pragma once #include "delegate_bandwidth.hpp" -#include "native.hpp" #include #include @@ -27,11 +26,10 @@ namespace eosiosystem { }; template - class contract : public delegate_bandwidth, public native { + class contract : public delegate_bandwidth { public: using voting::on; using delegate_bandwidth::on; - using native::on; using pe = voting; using db = delegate_bandwidth; using currency = typename common::currency; @@ -172,16 +170,6 @@ namespace eosiosystem { typename voting::voteproducer, onblock, claimrewards, - typename native::newaccount, - typename native::updateauth, - typename native::deleteauth, - typename native::linkauth, - typename native::unlinkauth, - typename native::postrecovery, - typename native::passrecovery, - typename native::vetorecovery, - typename native::setabi, - typename native::onerror, nonce>( code, act) ) { //TODO: Small hack until we refactor eosio.system like eosio.token using undelegatebw = typename delegate_bandwidth::undelegatebw; From b8596dc2f4dd0fcb668fb472b7e84045a5d29832 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Thu, 29 Mar 2018 20:06:20 -0400 Subject: [PATCH 0133/1048] merging master at 895f207c and fixing lots of bugs. eosio system tests are failing because they are actually assigning resources to people --- common.hpp | 1 + delegate_bandwidth.hpp | 2 +- eosio.system.abi | 12 +++++----- voting.hpp | 51 +++++++++++++++++------------------------- 4 files changed, 27 insertions(+), 39 deletions(-) diff --git a/common.hpp b/common.hpp index d2e972c3..bcf797a3 100644 --- a/common.hpp +++ b/common.hpp @@ -23,6 +23,7 @@ namespace eosiosystem { static constexpr uint32_t days_per_4years = 1461; struct eosio_parameters : eosio::blockchain_parameters { + uint64_t max_storage_size = 10 * 1024 * 1024; uint32_t percent_of_max_inflation_rate = 0; uint32_t storage_reserve_ratio = 1000; // ratio * 1000 diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index cc218a43..12777d4c 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -262,7 +262,7 @@ namespace eosiosystem { act.owner = del.from; transaction out( now() + refund_delay + refund_expiration_time ); out.actions.emplace_back( permission_level{ del.from, N(active) }, self, N(refund), act ); - out.send( del.from, now() + refund_delay ); + out.send( del.from, 0, now() + refund_delay ); if ( asset(0) < del.unstake_net_quantity + del.unstake_cpu_quantity ) { voting::decrease_voting_power( del.from, del.unstake_net_quantity + del.unstake_cpu_quantity ); diff --git a/eosio.system.abi b/eosio.system.abi index e71d5eca..658741de 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -87,13 +87,11 @@ "name": "eosio_parameters", "base": "", "fields": [ - {"name":"target_block_size", "type":"uint32"}, - {"name":"max_block_size", "type":"uint32"}, - {"name":"target_block_acts_per_scope", "type":"uint32"}, - {"name":"max_block_acts_per_scope", "type":"uint32"}, - {"name":"target_block_acts", "type":"uint32"}, - {"name":"max_block_acts", "type":"uint32"}, - {"name":"max_storage_size", "type":"uint64"}, + {"name":"base_per_transaction_net_usage", "type":"uint32"}, + {"name":"base_per_transaction_cpu_usage", "type":"uint32"}, + {"name":"base_per_action_cpu_usage", "type":"uint32"}, + {"name":"base_setcode_cpu_usage", "type":"uint32"}, + {"name":"per_signature_cpu_usage", "type":"uint32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, {"name":"max_transaction_exec_time", "type":"uint32"}, {"name":"max_authority_depth", "type":"uint16"}, diff --git a/voting.hpp b/voting.hpp index 52fec40b..481aafd5 100644 --- a/voting.hpp +++ b/voting.hpp @@ -242,13 +242,11 @@ namespace eosiosystem { producers_table producers_tbl( SystemAccount, SystemAccount ); auto idx = producers_tbl.template get_index(); - std::array target_block_size; - std::array max_block_size; - std::array target_block_acts_per_scope; - std::array max_block_acts_per_scope; - std::array target_block_acts; - std::array max_block_acts; - std::array max_storage_size; + std::array base_per_transaction_net_usage; + std::array base_per_transaction_cpu_usage; + std::array base_per_action_cpu_usage; + std::array base_setcode_cpu_usage; + std::array per_signature_cpu_usage; std::array max_transaction_lifetime; std::array max_authority_depth; std::array max_transaction_exec_time; @@ -269,16 +267,11 @@ namespace eosiosystem { eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data ); - target_block_size[n] = it->prefs.target_block_size; - max_block_size[n] = it->prefs.max_block_size; - - target_block_acts_per_scope[n] = it->prefs.target_block_acts_per_scope; - max_block_acts_per_scope[n] = it->prefs.max_block_acts_per_scope; - - target_block_acts[n] = it->prefs.target_block_acts; - max_block_acts[n] = it->prefs.max_block_acts; - - max_storage_size[n] = it->prefs.max_storage_size; + base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; + base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; + base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; + base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; + per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; max_authority_depth[n] = it->prefs.max_authority_depth; max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; @@ -296,13 +289,11 @@ namespace eosiosystem { return; } if ( 1 < n ) { - std::sort( target_block_size.begin(), target_block_size.begin()+n ); - std::sort( max_block_size.begin(), max_block_size.begin()+n ); - std::sort( target_block_acts_per_scope.begin(), target_block_acts_per_scope.begin()+n ); - std::sort( max_block_acts_per_scope.begin(), max_block_acts_per_scope.begin()+n ); - std::sort( target_block_acts.begin(), target_block_acts.begin()+n ); - std::sort( max_block_acts.begin(), max_block_acts.begin()+n ); - std::sort( max_storage_size.begin(), max_storage_size.begin()+n ); + std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); + std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); + std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); + std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); + std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); @@ -322,13 +313,11 @@ namespace eosiosystem { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - parameters.target_block_size = target_block_size[median]; - parameters.max_block_size = max_block_size[median]; - parameters.target_block_acts_per_scope = target_block_acts_per_scope[median]; - parameters.max_block_acts_per_scope = max_block_acts_per_scope[median]; - parameters.target_block_acts = target_block_acts[median]; - parameters.max_block_acts = max_block_acts[median]; - parameters.max_storage_size = max_storage_size[median]; + parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; + parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; + parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; + parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; + parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; parameters.max_transaction_lifetime = max_transaction_lifetime[median]; parameters.max_transaction_exec_time = max_transaction_exec_time[median]; parameters.max_authority_depth = max_authority_depth[median]; From d9c1ce889c221c9ff7fff2d1c7719fd948bbf9d6 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Thu, 29 Mar 2018 20:17:51 -0400 Subject: [PATCH 0134/1048] disable system contract from manipulating actual resources until tests are straightened out... reverted tests to the minimal change to make them work --- delegate_bandwidth.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index 12777d4c..a2eb46ac 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -184,7 +184,7 @@ namespace eosiosystem { }); } - set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); + //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { @@ -239,7 +239,7 @@ namespace eosiosystem { tot.storage_bytes -= del.unstake_storage_bytes; }); - set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity ); + //set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity ); refunds_table refunds_tbl( SystemAccount, del.from ); //create refund request From 68cba6242a237d305703576dc1cbd21231bb9f3b Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Fri, 30 Mar 2018 09:39:39 -0400 Subject: [PATCH 0135/1048] - added in per lock net usage - added CFA cpu usage discount - added max transaction net and cpu usage - refactored trace data structures to resolve cyclic dependencies in header files - refactored accounting code in chain controller for a little more clarity - refactored lock processing and put them in the associated block/transaction traces --- eosio.system.abi | 5 +++++ voting.hpp | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index 658741de..f522133b 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -92,6 +92,11 @@ {"name":"base_per_action_cpu_usage", "type":"uint32"}, {"name":"base_setcode_cpu_usage", "type":"uint32"}, {"name":"per_signature_cpu_usage", "type":"uint32"}, + {"name":"per_lock_net_usage", "type":"uint32"}, + {"name":"context_free_discount_cpu_usage_num", "type":"uint64"}, + {"name":"context_free_discount_cpu_usage_den", "type":"uint64"}, + {"name":"max_transaction_cpu_usage", "type":"uint32"}, + {"name":"max_transaction_net_usage", "type":"uint32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, {"name":"max_transaction_exec_time", "type":"uint32"}, {"name":"max_authority_depth", "type":"uint16"}, diff --git a/voting.hpp b/voting.hpp index 481aafd5..c1b1a72e 100644 --- a/voting.hpp +++ b/voting.hpp @@ -247,6 +247,11 @@ namespace eosiosystem { std::array base_per_action_cpu_usage; std::array base_setcode_cpu_usage; std::array per_signature_cpu_usage; + std::array per_lock_net_usage; + std::array context_free_discount_cpu_usage_num; + std::array context_free_discount_cpu_usage_den; + std::array max_transaction_cpu_usage; + std::array max_transaction_net_usage; std::array max_transaction_lifetime; std::array max_authority_depth; std::array max_transaction_exec_time; @@ -272,6 +277,11 @@ namespace eosiosystem { base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; + per_lock_net_usage[n] = it->prefs.per_lock_net_usage; + context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; + context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; + max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; + max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; max_authority_depth[n] = it->prefs.max_authority_depth; max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; @@ -294,6 +304,11 @@ namespace eosiosystem { std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); + std::sort( per_lock_net_usage.begin(), per_lock_net_usage.begin()+n ); + std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); + std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); + std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); + std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); @@ -318,6 +333,11 @@ namespace eosiosystem { parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; + parameters.per_lock_net_usage = per_lock_net_usage[median]; + parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; + parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; + parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; + parameters.max_transaction_net_usage = max_transaction_net_usage[median]; parameters.max_transaction_lifetime = max_transaction_lifetime[median]; parameters.max_transaction_exec_time = max_transaction_exec_time[median]; parameters.max_authority_depth = max_authority_depth[median]; From 28a2e2dcc38517b6bec25215c6129c642775dc2f Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Mon, 2 Apr 2018 13:03:01 -0400 Subject: [PATCH 0136/1048] Disallow usage of 0 as implicit `receiver` for `send_deferred` EOSIO/eos#2031 --- delegate_bandwidth.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index a2eb46ac..1e54188b 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -262,7 +262,7 @@ namespace eosiosystem { act.owner = del.from; transaction out( now() + refund_delay + refund_expiration_time ); out.actions.emplace_back( permission_level{ del.from, N(active) }, self, N(refund), act ); - out.send( del.from, 0, now() + refund_delay ); + out.send( del.from, receiver, now() + refund_delay ); if ( asset(0) < del.unstake_net_quantity + del.unstake_cpu_quantity ) { voting::decrease_voting_power( del.from, del.unstake_net_quantity + del.unstake_cpu_quantity ); From fe0ea0b11fc293cbe93bb96363ef14c03a2cc049 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 2 Apr 2018 17:26:01 -0400 Subject: [PATCH 0137/1048] Changed canceldelay to take a transaction id --- native.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/native.hpp b/native.hpp index ca9c0ace..2650c856 100644 --- a/native.hpp +++ b/native.hpp @@ -190,9 +190,9 @@ namespace eosiosystem { } ACTION( SystemAccount, canceldelay ) { - uint32_t sender_id; + checksum256 trx_id; - EOSLIB_SERIALIZE( canceldelay, (sender_id) ) + EOSLIB_SERIALIZE( canceldelay, (trx_id) ) }; static void on( const canceldelay& ) { From 7dee062c8596d3b86ed005806d3166e6ec416695 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Tue, 3 Apr 2018 11:11:38 -0400 Subject: [PATCH 0138/1048] add new config parameters for elastic rate limits parameters EOSIO/eos#2031 --- eosio.system.abi | 4 ++++ voting.hpp | 16 ++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index f522133b..a4d00184 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -97,6 +97,10 @@ {"name":"context_free_discount_cpu_usage_den", "type":"uint64"}, {"name":"max_transaction_cpu_usage", "type":"uint32"}, {"name":"max_transaction_net_usage", "type":"uint32"}, + {"name":"max_block_cpu_usage", "type": "uint64"}, + {"name":"target_block_cpu_usage_pct", "type": "int32"}, + {"name":"max_block_net_usage", "type": "uint64"}, + {"name":"target_block_net_usage_pct", "type": "int32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, {"name":"max_transaction_exec_time", "type":"uint32"}, {"name":"max_authority_depth", "type":"uint16"}, diff --git a/voting.hpp b/voting.hpp index c1b1a72e..05fc759e 100644 --- a/voting.hpp +++ b/voting.hpp @@ -252,6 +252,10 @@ namespace eosiosystem { std::array context_free_discount_cpu_usage_den; std::array max_transaction_cpu_usage; std::array max_transaction_net_usage; + std::array max_block_cpu_usage; + std::array target_block_cpu_usage_pct; + std::array max_block_net_usage; + std::array target_block_net_usage_pct; std::array max_transaction_lifetime; std::array max_authority_depth; std::array max_transaction_exec_time; @@ -282,6 +286,10 @@ namespace eosiosystem { context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; + max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; + target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; + max_block_net_usage[n] = it->prefs.max_block_net_usage; + target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; max_authority_depth[n] = it->prefs.max_authority_depth; max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; @@ -309,6 +317,10 @@ namespace eosiosystem { std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); + std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); + std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); + std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); + std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); @@ -338,6 +350,10 @@ namespace eosiosystem { parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; parameters.max_transaction_net_usage = max_transaction_net_usage[median]; + parameters.max_block_cpu_usage = max_block_cpu_usage[median]; + parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; + parameters.max_block_net_usage = max_block_net_usage[median]; + parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; parameters.max_transaction_lifetime = max_transaction_lifetime[median]; parameters.max_transaction_exec_time = max_transaction_exec_time[median]; parameters.max_authority_depth = max_authority_depth[median]; From 5f6834eac68137167f968179eb8fe72c04a12e77 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Tue, 3 Apr 2018 14:36:13 -0400 Subject: [PATCH 0139/1048] re-type the pct variables --- eosio.system.abi | 4 ++-- voting.hpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index a4d00184..32fa4eb0 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -98,9 +98,9 @@ {"name":"max_transaction_cpu_usage", "type":"uint32"}, {"name":"max_transaction_net_usage", "type":"uint32"}, {"name":"max_block_cpu_usage", "type": "uint64"}, - {"name":"target_block_cpu_usage_pct", "type": "int32"}, + {"name":"target_block_cpu_usage_pct", "type": "uint32"}, {"name":"max_block_net_usage", "type": "uint64"}, - {"name":"target_block_net_usage_pct", "type": "int32"}, + {"name":"target_block_net_usage_pct", "type": "uint32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, {"name":"max_transaction_exec_time", "type":"uint32"}, {"name":"max_authority_depth", "type":"uint16"}, diff --git a/voting.hpp b/voting.hpp index 05fc759e..7010f4b8 100644 --- a/voting.hpp +++ b/voting.hpp @@ -253,9 +253,9 @@ namespace eosiosystem { std::array max_transaction_cpu_usage; std::array max_transaction_net_usage; std::array max_block_cpu_usage; - std::array target_block_cpu_usage_pct; + std::array target_block_cpu_usage_pct; std::array max_block_net_usage; - std::array target_block_net_usage_pct; + std::array target_block_net_usage_pct; std::array max_transaction_lifetime; std::array max_authority_depth; std::array max_transaction_exec_time; From f61772d7b7d9f9043d34436f24e4cf1ecf2ce28c Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 3 Apr 2018 14:59:51 -0400 Subject: [PATCH 0140/1048] remove max_generated_transaction_size #1030 --- eosio.system.abi | 1 - voting.hpp | 4 ---- 2 files changed, 5 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index f522133b..2f054d9a 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -102,7 +102,6 @@ {"name":"max_authority_depth", "type":"uint16"}, {"name":"max_inline_depth", "type":"uint16"}, {"name":"max_inline_action_size", "type":"uint32"}, - {"name":"max_generated_transaction_size", "type":"uint32"}, {"name":"max_generated_transaction_count", "type":"uint32"}, {"name":"percent_of_max_inflation_rate", "type":"uint32"}, {"name":"storage_reserve_ratio", "type":"uint32"} diff --git a/voting.hpp b/voting.hpp index c1b1a72e..2f791717 100644 --- a/voting.hpp +++ b/voting.hpp @@ -257,7 +257,6 @@ namespace eosiosystem { std::array max_transaction_exec_time; std::array max_inline_depth; std::array max_inline_action_size; - std::array max_generated_transaction_size; std::array max_generated_transaction_count; std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; @@ -287,7 +286,6 @@ namespace eosiosystem { max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; max_inline_depth[n] = it->prefs.max_inline_depth; max_inline_action_size[n] = it->prefs.max_inline_action_size; - max_generated_transaction_size[n] = it->prefs.max_generated_transaction_size; max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; @@ -314,7 +312,6 @@ namespace eosiosystem { std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); - std::sort( max_generated_transaction_size.begin(), max_generated_transaction_size.begin()+n ); std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); @@ -343,7 +340,6 @@ namespace eosiosystem { parameters.max_authority_depth = max_authority_depth[median]; parameters.max_inline_depth = max_inline_depth[median]; parameters.max_inline_action_size = max_inline_action_size[median]; - parameters.max_generated_transaction_size = max_generated_transaction_size[median]; parameters.max_generated_transaction_count = max_generated_transaction_count[median]; parameters.storage_reserve_ratio = storage_reserve_ratio[median]; parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; From 66f717788cd51d9f96d8159cdd6581d7106f5921 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 3 Apr 2018 18:47:49 -0400 Subject: [PATCH 0141/1048] Changing sender_id_type back and other comments --- native.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native.hpp b/native.hpp index 2650c856..bf6d3e76 100644 --- a/native.hpp +++ b/native.hpp @@ -190,7 +190,7 @@ namespace eosiosystem { } ACTION( SystemAccount, canceldelay ) { - checksum256 trx_id; + transaction_id trx_id; EOSLIB_SERIALIZE( canceldelay, (trx_id) ) }; From d2c2056b188ac88ab46e037c498178f65f960021 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 3 Apr 2018 22:43:43 -0400 Subject: [PATCH 0142/1048] Added support for ricardian contracts and clauses --- native.hpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/native.hpp b/native.hpp index ca9c0ace..e7fd830d 100644 --- a/native.hpp +++ b/native.hpp @@ -59,8 +59,9 @@ namespace eosiosystem { struct action_def { action_name name; type_name type; + std::string ricardian_contract; - EOSLIB_SERIALIZE(action_def, (name)(type) ) + EOSLIB_SERIALIZE(action_def, (name)(type)(ricardian_contract) ) }; struct table_def { @@ -72,14 +73,21 @@ namespace eosiosystem { EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) ) }; + struct clause_pair { + std::string clause_id; + std::string clause_body; + + EOSLIB_SERIALIZE( clause_pair, (clause_id)(clause_body) ) + }; struct abi_def { std::vector types; std::vector structs; std::vector actions; std::vector tables; + std::vector clauses; - EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables) ) + EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables)(clauses) ) }; template From 7a26b3288eb57cd4e289f7e1b7519b236a82315d Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 3 Apr 2018 23:03:58 -0400 Subject: [PATCH 0143/1048] fixes for delayed input transactions (use delay_sec field in trx) Removed mindelay action since the `delay_sec` field makes it unnecessary. Additional unit tests to test the new semantics of delay_sec are needed. Also, apply_block and push_transaction now respect the skip_authority_check flag. --- eosio.system.hpp | 1 - native.hpp | 34 +++++++++++++--------------------- 2 files changed, 13 insertions(+), 22 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 8787f26b..1122e742 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -183,7 +183,6 @@ namespace eosiosystem { typename native::setabi, typename native::onerror, typename native::canceldelay, - typename native::mindelay, nonce>( code, act) ) { //TODO: Small hack until we refactor eosio.system like eosio.token using undelegatebw = typename delegate_bandwidth::undelegatebw; diff --git a/native.hpp b/native.hpp index ca9c0ace..5df0e1ae 100644 --- a/native.hpp +++ b/native.hpp @@ -15,14 +15,14 @@ namespace eosiosystem { struct permission_level_weight { permission_level permission; weight_type weight; - + EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) }; struct key_weight { public_key key; weight_type weight; - + EOSLIB_SERIALIZE( key_weight, (key)(weight) ) }; @@ -30,7 +30,7 @@ namespace eosiosystem { uint32_t threshold; std::vector keys; std::vector accounts; - + EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) }; @@ -52,14 +52,14 @@ namespace eosiosystem { type_name name; type_name base; std::vector fields; - + EOSLIB_SERIALIZE( struct_def, (name)(base)(fields) ) }; struct action_def { action_name name; type_name type; - + EOSLIB_SERIALIZE(action_def, (name)(type) ) }; @@ -69,7 +69,7 @@ namespace eosiosystem { std::vector key_names; std::vector key_types; type_name type; - + EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) ) }; @@ -78,7 +78,7 @@ namespace eosiosystem { std::vector structs; std::vector actions; std::vector tables; - + EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables) ) }; @@ -131,12 +131,12 @@ namespace eosiosystem { static void on( const linkauth& ) { } - + ACTION( SystemAccount, unlinkauth ) { account_name account; account_name code; action_name type; - + EOSLIB_SERIALIZE( unlinkauth, (account)(code)(type) ) }; @@ -175,7 +175,7 @@ namespace eosiosystem { ACTION( SystemAccount, setabi ) { account_name account; abi_def abi; - + EOSLIB_SERIALIZE( setabi, (account)(abi) ) }; @@ -188,23 +188,15 @@ namespace eosiosystem { static void on( const onerror& ) { } - + ACTION( SystemAccount, canceldelay ) { uint32_t sender_id; - + EOSLIB_SERIALIZE( canceldelay, (sender_id) ) }; - + static void on( const canceldelay& ) { } - ACTION ( SystemAccount, mindelay ) { - uint32_t delay; - - EOSLIB_SERIALIZE( mindelay, (delay) ) - }; - - static void on( const mindelay& ) { - } }; } From cc62f045c5e23fc2f597a357c25a89ac288977da Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 4 Apr 2018 09:50:40 -0400 Subject: [PATCH 0144/1048] Removed setabi stuff from system contract --- eosio.system.hpp | 1 - native.hpp | 66 ------------------------------------------------ 2 files changed, 67 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 8787f26b..3e943440 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -180,7 +180,6 @@ namespace eosiosystem { typename native::postrecovery, typename native::passrecovery, typename native::vetorecovery, - typename native::setabi, typename native::onerror, typename native::canceldelay, typename native::mindelay, diff --git a/native.hpp b/native.hpp index e7fd830d..565f3d6a 100644 --- a/native.hpp +++ b/native.hpp @@ -34,62 +34,6 @@ namespace eosiosystem { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) }; - struct type_def { - type_name new_type_name; - type_name type; - - EOSLIB_SERIALIZE( type_def, (new_type_name)(type) ) - }; - - struct field_def { - field_name name; - type_name type; - - EOSLIB_SERIALIZE( field_def, (name)(type) ) - }; - - struct struct_def { - type_name name; - type_name base; - std::vector fields; - - EOSLIB_SERIALIZE( struct_def, (name)(base)(fields) ) - }; - - struct action_def { - action_name name; - type_name type; - std::string ricardian_contract; - - EOSLIB_SERIALIZE(action_def, (name)(type)(ricardian_contract) ) - }; - - struct table_def { - table_name name; - type_name index_type; - std::vector key_names; - std::vector key_types; - type_name type; - - EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) ) - }; - struct clause_pair { - std::string clause_id; - std::string clause_body; - - EOSLIB_SERIALIZE( clause_pair, (clause_id)(clause_body) ) - }; - - struct abi_def { - std::vector types; - std::vector structs; - std::vector actions; - std::vector tables; - std::vector clauses; - - EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables)(clauses) ) - }; - template class native { public: @@ -180,16 +124,6 @@ namespace eosiosystem { static void on( const vetorecovery& ) { } - ACTION( SystemAccount, setabi ) { - account_name account; - abi_def abi; - - EOSLIB_SERIALIZE( setabi, (account)(abi) ) - }; - - static void on( const setabi& ) { - } - struct onerror: eosio::action_meta, bytes { EOSLIB_SERIALIZE_DERIVED( onerror, bytes, BOOST_PP_SEQ_NIL ) }; From 3779101e304a0cf9ad7cc762ff4c57b090087932 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 4 Apr 2018 10:05:03 -0400 Subject: [PATCH 0145/1048] Forgot one rename --- native.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/native.hpp b/native.hpp index bf6d3e76..4037539c 100644 --- a/native.hpp +++ b/native.hpp @@ -190,7 +190,7 @@ namespace eosiosystem { } ACTION( SystemAccount, canceldelay ) { - transaction_id trx_id; + transaction_id_type trx_id; EOSLIB_SERIALIZE( canceldelay, (trx_id) ) }; From c70b19f297112004c99894416b7e93c2c66ce1cb Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 4 Apr 2018 10:52:11 -0400 Subject: [PATCH 0146/1048] Addressed comments, might need to leave setabi in system contract --- native.hpp | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/native.hpp b/native.hpp index 565f3d6a..c5137bc2 100644 --- a/native.hpp +++ b/native.hpp @@ -33,6 +33,55 @@ namespace eosiosystem { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) }; + struct type_def { + type_name new_type_name; + type_name type; + + EOSLIB_SERIALIZE( type_def, (new_type_name)(type) ) + }; + + struct field_def { + field_name name; + type_name type; + + EOSLIB_SERIALIZE( field_def, (name)(type) ) + }; + + struct struct_def { + type_name name; + type_name base; + std::vector fields; + + EOSLIB_SERIALIZE( struct_def, (name)(base)(fields) ) + }; + + struct action_def { + action_name name; + type_name type; + + EOSLIB_SERIALIZE(action_def, (name)(type) ) + }; + + struct table_def { + table_name name; + type_name index_type; + std::vector key_names; + std::vector key_types; + type_name type; + + EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) ) + }; + + struct abi_def { + std::vector types; + std::vector structs; + std::vector actions; + std::vector tables; + + EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables) ) + }; + + template class native { @@ -49,6 +98,15 @@ namespace eosiosystem { static void on( const newaccount& ) { } + ACTION( SystemAccount, setabi ) { + account_name account; + abi_def abi; + + EOSLIB_SERIALIZE( setabi, (account)(abi) ) + }; + + static void on( const setabi& ) { + } ACTION( SystemAccount, updateauth ) { account_name account; From d42cc2460429efc6b6cbaf78d7633a62735c8735 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 4 Apr 2018 11:18:00 -0400 Subject: [PATCH 0147/1048] added back setabi action to system contract --- eosio.system.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index 3e943440..8787f26b 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -180,6 +180,7 @@ namespace eosiosystem { typename native::postrecovery, typename native::passrecovery, typename native::vetorecovery, + typename native::setabi, typename native::onerror, typename native::canceldelay, typename native::mindelay, From 3c01807e9ba61d31051923c875f19154f07e4e2d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 4 Apr 2018 11:32:07 -0400 Subject: [PATCH 0148/1048] enforce `delay_sec` of generated transactions in the same way as input transactions Also, `execute_after` (or `delay_until`) parameter is removed from the `send_deferred` contract API since that can be specified using the `delay_sec` field in the transaction header. --- delegate_bandwidth.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index 1e54188b..07c7de68 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -262,7 +262,8 @@ namespace eosiosystem { act.owner = del.from; transaction out( now() + refund_delay + refund_expiration_time ); out.actions.emplace_back( permission_level{ del.from, N(active) }, self, N(refund), act ); - out.send( del.from, receiver, now() + refund_delay ); + out.delay_sec = refund_delay; + out.send( del.from, receiver ); if ( asset(0) < del.unstake_net_quantity + del.unstake_cpu_quantity ) { voting::decrease_voting_power( del.from, del.unstake_net_quantity + del.unstake_cpu_quantity ); From 49eeb3dacfe0655cd791dbbf9e8434999f1e2bd7 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 4 Apr 2018 13:20:34 -0400 Subject: [PATCH 0149/1048] Fully added back the abi_def stuff to system contract, will work on the errors later --- eosio.system.abi | 39 ++++++++++++++++++++++++++------------- native.hpp | 14 ++++++++++---- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 32fa4eb0..3d1ba553 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -190,42 +190,55 @@ ], "actions": [{ "name": "transfer", - "type": "transfer" + "type": "transfer", + "ricardian_contract": "" },{ "name": "issue", - "type": "issue" + "type": "issue", + "ricardian_contract": "" },{ "name": "delegatebw", - "type": "delegatebw" + "type": "delegatebw", + "ricardian_contract": "" },{ "name": "undelegatebw", - "type": "undelegatebw" + "type": "undelegatebw", + "ricardian_contract": "" },{ "name": "refund", - "type": "refund" + "type": "refund", + "ricardian_contract": "" },{ "name": "regproducer", - "type": "regproducer" + "type": "regproducer", + "ricardian_contract": "" },{ "name": "unregprod", - "type": "unregprod" + "type": "unregprod", + "ricardian_contract": "" },{ "name": "regproxy", - "type": "regproxy" + "type": "regproxy", + "ricardian_contract": "" },{ "name": "unregproxy", - "type": "unregproxy" + "type": "unregproxy", + "ricardian_contract": "" },{ "name": "voteproducer", - "type": "voteproducer" + "type": "voteproducer", + "ricardian_contract": "" },{ "name": "claimrewards", - "type": "claimrewards" + "type": "claimrewards", + "ricardian_contract": "" },{ "name": "nonce", - "type": "nonce" + "type": "nonce", + "ricardian_contract": "" } ], "tables": [ - ] + ], + "clauses": [{}] } diff --git a/native.hpp b/native.hpp index c5137bc2..d178f679 100644 --- a/native.hpp +++ b/native.hpp @@ -58,8 +58,8 @@ namespace eosiosystem { struct action_def { action_name name; type_name type; - - EOSLIB_SERIALIZE(action_def, (name)(type) ) + std::string ricardian_contract; + EOSLIB_SERIALIZE(action_def, (name)(type)(ricardian_contract) ) }; struct table_def { @@ -71,14 +71,20 @@ namespace eosiosystem { EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) ) }; - + + struct clause_pair { + std::string id; + std::string body; + EOSLIB_SERIALIZE( clause_pair, (id)(body) ) + }; struct abi_def { std::vector types; std::vector structs; std::vector actions; std::vector tables; + std::vector clauses; - EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables) ) + EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables)(clauses) ) }; From 70bf3e7fee9f328546d161b0305fc868aad81a75 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 4 Apr 2018 15:14:10 -0400 Subject: [PATCH 0150/1048] Fixed issue with nodeos_run_test and removed setabi system contract handler --- eosio.system.abi | 2 +- eosio.system.hpp | 1 - native.hpp | 65 ------------------------------------------------ 3 files changed, 1 insertion(+), 67 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 3d1ba553..6472b6bb 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -240,5 +240,5 @@ ], "tables": [ ], - "clauses": [{}] + "clauses": [] } diff --git a/eosio.system.hpp b/eosio.system.hpp index 1122e742..9208d71c 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -180,7 +180,6 @@ namespace eosiosystem { typename native::postrecovery, typename native::passrecovery, typename native::vetorecovery, - typename native::setabi, typename native::onerror, typename native::canceldelay, nonce>( code, act) ) { diff --git a/native.hpp b/native.hpp index 805b0a44..28cf5e48 100644 --- a/native.hpp +++ b/native.hpp @@ -33,61 +33,6 @@ namespace eosiosystem { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) }; - struct type_def { - type_name new_type_name; - type_name type; - - EOSLIB_SERIALIZE( type_def, (new_type_name)(type) ) - }; - - struct field_def { - field_name name; - type_name type; - - EOSLIB_SERIALIZE( field_def, (name)(type) ) - }; - - struct struct_def { - type_name name; - type_name base; - std::vector fields; - - EOSLIB_SERIALIZE( struct_def, (name)(base)(fields) ) - }; - - struct action_def { - action_name name; - type_name type; - std::string ricardian_contract; - EOSLIB_SERIALIZE(action_def, (name)(type)(ricardian_contract) ) - }; - - struct table_def { - table_name name; - type_name index_type; - std::vector key_names; - std::vector key_types; - type_name type; - - EOSLIB_SERIALIZE(table_def, (name)(index_type)(key_names)(key_types)(type) ) - }; - - struct clause_pair { - std::string id; - std::string body; - EOSLIB_SERIALIZE( clause_pair, (id)(body) ) - }; - struct abi_def { - std::vector types; - std::vector structs; - std::vector actions; - std::vector tables; - std::vector clauses; - - EOSLIB_SERIALIZE( abi_def, (types)(structs)(actions)(tables)(clauses) ) - }; - - template class native { @@ -179,16 +124,6 @@ namespace eosiosystem { static void on( const vetorecovery& ) { } - ACTION( SystemAccount, setabi ) { - account_name account; - abi_def abi; - - EOSLIB_SERIALIZE( setabi, (account)(abi) ) - }; - - static void on( const setabi& ) { - } - struct onerror: eosio::action_meta, bytes { EOSLIB_SERIALIZE_DERIVED( onerror, bytes, BOOST_PP_SEQ_NIL ) }; From e0bbfabd2bbdeb08c1dc6c893d3806aa34aab9fb Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 12 Apr 2018 23:53:29 -0400 Subject: [PATCH 0151/1048] Renamed clauses to ricardian_clauses --- eosio.system.abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index e338998e..1d47e2e0 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -239,5 +239,5 @@ ], "tables": [ ], - "clauses": [] + "ricardian_clauses": [] } From 2f588ae985f5a25166ec301faca946f4f6928024 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 13 Apr 2018 11:04:00 -0400 Subject: [PATCH 0152/1048] changes to canceldelay to fix #1994 and additional tests on canceldelay --- native.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/native.hpp b/native.hpp index 28cf5e48..43e25c5b 100644 --- a/native.hpp +++ b/native.hpp @@ -132,9 +132,10 @@ namespace eosiosystem { } ACTION( SystemAccount, canceldelay ) { + permission_level canceling_auth; transaction_id_type trx_id; - EOSLIB_SERIALIZE( canceldelay, (trx_id) ) + EOSLIB_SERIALIZE( canceldelay, (canceling_auth)(trx_id) ) }; static void on( const canceldelay& ) { From 78519d7c245b1f8683fae245231b73d268aab644 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Apr 2018 18:58:54 -0400 Subject: [PATCH 0153/1048] Move system contract to eosio.token - #1889, #2231 --- CMakeLists.txt | 2 +- common.hpp | 22 +++++++---- delegate_bandwidth.hpp | 83 +++++++++++++++++++++++++++--------------- eosio.system.hpp | 41 ++++++++++++++------- voting.hpp | 61 +++++++++++++++++-------------- 5 files changed, 130 insertions(+), 79 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f75591e..eb4ff749 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,6 +3,6 @@ configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} - LIBRARIES libc++ libc eosiolib + LIBRARIES libc++ libc eosiolib eosio.token DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} ) diff --git a/common.hpp b/common.hpp index bcf797a3..ee407118 100644 --- a/common.hpp +++ b/common.hpp @@ -1,21 +1,27 @@ #pragma once #include -#include +//#include #include #include #include +#include + +#include namespace eosiosystem { + eosio::token _system_token(N(eosio)); + template class common { public: static constexpr account_name system_account = SystemAccount; - typedef eosio::generic_currency< eosio::token > currency; - typedef typename currency::token_type system_token_type; + // typedef eosio::generic_currency< eosio::token > currency; + // typedef typename currency::token_type system_token_type; + + // static constexpr eosio::symbol_type system_symbol(S(4,EOS)); - static constexpr uint64_t currency_symbol = currency::symbol; // S(4,EOS) static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t blocks_per_producer = 12; @@ -32,13 +38,13 @@ namespace eosiosystem { struct eosio_global_state : eosio_parameters { uint64_t total_storage_bytes_reserved = 0; - system_token_type total_storage_stake; - system_token_type payment_per_block = system_token_type(); - system_token_type payment_to_eos_bucket = system_token_type(); + eosio::asset total_storage_stake; + eosio::asset payment_per_block; + eosio::asset payment_to_eos_bucket; time first_block_time_in_cycle = 0; uint32_t blocks_per_cycle = 0; time last_bucket_fill_time = 0; - system_token_type eos_bucket = system_token_type(); + eosio::asset eos_bucket; EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index 07c7de68..50a7fe60 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -7,10 +7,10 @@ #include "voting.hpp" #include -#include +//#include #include -#include +//#include #include #include #include @@ -35,17 +35,20 @@ namespace eosiosystem { static constexpr account_name system_account = SystemAccount; static constexpr time refund_delay = 3*24*3600; static constexpr time refund_expiration_time = 3600; - using currency = typename common::currency; - using system_token_type = typename common::system_token_type; + // using currency = typename common::currency; + // using system_token_type = typename common::system_token_type; using eosio_parameters = typename common::eosio_parameters; using global_state_singleton = typename common::global_state_singleton; struct total_resources { - account_name owner; - typename currency::token_type net_weight; - typename currency::token_type cpu_weight; - typename currency::token_type storage_stake; - uint64_t storage_bytes = 0; + account_name owner; + // typename currency::token_type net_weight; + // typename currency::token_type cpu_weight; + // typename currency::token_type storage_stake; + eosio::asset net_weight; + eosio::asset cpu_weight; + eosio::asset storage_stake; + uint64_t storage_bytes = 0; uint64_t primary_key()const { return owner; } @@ -57,12 +60,15 @@ namespace eosiosystem { * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. */ struct delegated_bandwidth { - account_name from; - account_name to; - typename currency::token_type net_weight; - typename currency::token_type cpu_weight; - typename currency::token_type storage_stake; - uint64_t storage_bytes = 0; + account_name from; + account_name to; + // typename currency::token_type net_weight; + // typename currency::token_type cpu_weight; + // typename currency::token_type storage_stake; + eosio::asset net_weight; + eosio::asset cpu_weight; + eosio::asset storage_stake; + uint64_t storage_bytes = 0; uint64_t primary_key()const { return to; } @@ -71,9 +77,10 @@ namespace eosiosystem { }; struct refund_request { - account_name owner; - time request_time; - typename currency::token_type amount; + account_name owner; + time request_time; + // typename currency::token_type amount; + eosio::asset amount; uint64_t primary_key()const { return owner; } @@ -116,8 +123,9 @@ namespace eosiosystem { eosio_assert( del.stake_net_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( del.stake_storage_quantity.amount >= 0, "must stake a positive amount" ); - system_token_type total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; - eosio_assert( total_stake.quantity > 0, "must stake a positive amount" ); + // system_token_type total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; + asset total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; + eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); require_auth( del.from ); @@ -126,15 +134,25 @@ namespace eosiosystem { if ( 0 < del.stake_storage_quantity.amount ) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - auto token_supply = currency::get_total_supply(); +#warning "FIX THIS!" + // auto token_supply = currency::get_total_supply(); + eosio::asset token_supply(0, S(4,EOS)); //make sure that there is no posibility of overflow here + // uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) + // * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) + // / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) + * parameters.storage_reserve_ratio * del.stake_storage_quantity / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + // storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) + // * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) + // / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) - * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) + * parameters.storage_reserve_ratio * del.stake_storage_quantity / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); @@ -186,7 +204,8 @@ namespace eosiosystem { //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); - currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); + // currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); + _system_token.inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { voting::increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); } @@ -206,11 +225,12 @@ namespace eosiosystem { eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); - system_token_type storage_stake_decrease = system_token_type(0); + // system_token_type storage_stake_decrease = system_token_type(0); + eosio::asset storage_stake_decrease(0, S(4,EOS)); if ( 0 < del.unstake_storage_bytes ) { storage_stake_decrease = 0 < dbw.storage_bytes ? dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes - : system_token_type(0); + : eosio::asset(0, S(4,EOS)); auto parameters = global_state_singleton::get(); parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; @@ -218,10 +238,12 @@ namespace eosiosystem { global_state_singleton::set( parameters ); } - auto total_refund = system_token_type(del.unstake_cpu_quantity) - + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; + // auto total_refund = system_token_type(del.unstake_cpu_quantity) + // + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; + + eosio::asset total_refund = del.unstake_cpu_quantity + del.unstake_net_quantity + storage_stake_decrease; - eosio_assert( total_refund.quantity > 0, "must unstake a positive amount" ); + eosio_assert( total_refund.amount > 0, "must unstake a positive amount" ); del_tbl.modify( dbw, del.from, [&]( auto& dbo ){ dbo.net_weight -= del.unstake_net_quantity; @@ -282,7 +304,8 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - currency::inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); + // currency::inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); + _system_token.inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); refunds_tbl.erase( req ); } }; diff --git a/eosio.system.hpp b/eosio.system.hpp index 9208d71c..c92dd5c3 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -8,7 +8,9 @@ #include "native.hpp" #include -#include +//#include + +#include namespace eosiosystem { @@ -27,15 +29,23 @@ namespace eosiosystem { }; template - class contract : public delegate_bandwidth, public native { + class contract : eosio::contract, public delegate_bandwidth, public native { + // private: + // eosio::token _system_token; public: + + contract(account_name self = SystemAccount): + eosio::contract(self) + { + } + using voting::on; using delegate_bandwidth::on; using native::on; using pe = voting; using db = delegate_bandwidth; - using currency = typename common::currency; - using system_token_type = typename common::system_token_type; + // using currency = typename common::currency; + // using system_token_type = typename common::system_token_type; using producers_table = typename pe::producers_table; using global_state_singleton = typename voting::global_state_singleton; static const uint32_t max_inflation_rate = common::max_inflation_rate; @@ -87,7 +97,8 @@ namespace eosiosystem { account_name producer = ob.header.producer; auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - const system_token_type block_payment = parameters.payment_per_block; + // const system_token_type block_payment = parameters.payment_per_block; + const asset block_payment = parameters.payment_per_block; auto prod = producers_tbl.find(producer); if ( prod != producers_tbl.end() ) { producers_tbl.modify( prod, 0, [&](auto& p) { @@ -97,7 +108,8 @@ namespace eosiosystem { } const uint32_t num_of_payments = ob.header.timestamp - parameters.last_bucket_fill_time; - const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; + // const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; + const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; parameters.last_bucket_fill_time = ob.header.timestamp; parameters.eos_bucket += to_eos_bucket; global_state_singleton::set(parameters); @@ -119,7 +131,8 @@ namespace eosiosystem { if( prod->last_rewards_claim > 0 ) { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } - system_token_type rewards = prod->per_block_payments; + // system_token_type rewards = prod->per_block_payments; + eosio::asset rewards = prod->per_block_payments; auto idx = producers_tbl.template get_index(); auto itr = --idx.end(); @@ -144,25 +157,27 @@ namespace eosiosystem { if (is_among_payed_producers && total_producer_votes > 0) { if( global_state_singleton::exists() ) { auto parameters = global_state_singleton::get(); - auto share_of_eos_bucket = system_token_type( static_cast( (prod->total_votes * parameters.eos_bucket.quantity) / total_producer_votes ) ); // This will be improved in the future when total_votes becomes a double type. + // auto share_of_eos_bucket = system_token_type( static_cast( (prod->total_votes * parameters.eos_bucket.quantity) / total_producer_votes ) ); // This will be improved in the future when total_votes becomes a double type. + auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * parameters.eos_bucket.amount) / total_producer_votes ) ); rewards += share_of_eos_bucket; parameters.eos_bucket -= share_of_eos_bucket; global_state_singleton::set(parameters); } } - eosio_assert( rewards > system_token_type(), "no rewards available to claim" ); + // eosio_assert( rewards > system_token_type(), "no rewards available to claim" ); + eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); producers_tbl.modify( prod, 0, [&](auto& p) { p.last_rewards_claim = now(); - p.per_block_payments.quantity = 0; + p.per_block_payments.amount = 0; }); - currency::inline_transfer(cr.owner, SystemAccount, rewards, "producer claiming rewards"); + _system_token.inline_transfer(SystemAccount, cr.owner, rewards, "producer claiming rewards"); } static void apply( account_name receiver, account_name code, action_name act ) { - if ( !eosio::dispatch( code, act ) ) { + // if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwidth::refund, typename voting::regproxy, @@ -189,7 +204,7 @@ namespace eosiosystem { contract().on( receiver, eosio::unpack_action_data() ); } } - } + // } } /// apply }; diff --git a/voting.hpp b/voting.hpp index b99390de..433593a9 100644 --- a/voting.hpp +++ b/voting.hpp @@ -6,10 +6,10 @@ #include "common.hpp" #include -#include +//#include #include -#include +//#include #include #include #include @@ -17,6 +17,8 @@ #include #include +#include + #include #include #include @@ -33,9 +35,10 @@ namespace eosiosystem { template class voting { public: + static constexpr account_name system_account = SystemAccount; - using currency = typename common::currency; - using system_token_type = typename common::system_token_type; + // using currency = typename common::currency; + // using system_token_type = typename common::system_token_type; using eosio_parameters = typename common::eosio_parameters; using global_state_singleton = typename common::global_state_singleton; @@ -47,7 +50,7 @@ namespace eosiosystem { uint128_t total_votes = 0; eosio_parameters prefs; eosio::bytes packed_key; /// a packed public key object - system_token_type per_block_payments; + eosio::asset per_block_payments; time last_rewards_claim = 0; time time_became_active = 0; time last_produced_block_time = 0; @@ -71,9 +74,9 @@ namespace eosiosystem { account_name proxy = 0; time last_update = 0; uint32_t is_proxy = 0; - system_token_type staked; - system_token_type unstaking; - system_token_type unstake_per_week; + eosio::asset staked; + eosio::asset unstaking; + eosio::asset unstake_per_week; uint128_t proxied_votes = 0; std::vector producers; uint32_t deferred_trx_id = 0; @@ -141,7 +144,7 @@ namespace eosiosystem { }); } - static void increase_voting_power( account_name acnt, system_token_type amount ) { + static void increase_voting_power( account_name acnt, const eosio::asset& amount ) { voters_table voters_tbl( SystemAccount, SystemAccount ); auto voter = voters_tbl.find( acnt ); @@ -162,7 +165,7 @@ namespace eosiosystem { if ( voter->proxy ) { auto proxy = voters_tbl.find( voter->proxy ); eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.quantity; } ); + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.amount; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } @@ -176,19 +179,19 @@ namespace eosiosystem { auto prod = producers_tbl.find( p ); eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes += amount.quantity; + v.total_votes += amount.amount; }); } } } - static void decrease_voting_power( account_name acnt, system_token_type amount ) { + static void decrease_voting_power( account_name acnt, const eosio::asset& amount ) { require_auth( acnt ); voters_table voters_tbl( SystemAccount, SystemAccount ); auto voter = voters_tbl.find( acnt ); eosio_assert( voter != voters_tbl.end(), "stake not found" ); - if ( 0 < amount.quantity ) { + if ( 0 < amount.amount ) { eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); voters_tbl.modify( voter, 0, [&](voter_info& a) { a.staked -= amount; @@ -198,7 +201,7 @@ namespace eosiosystem { const std::vector* producers = nullptr; if ( voter->proxy ) { auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.quantity; } ); + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.amount; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } @@ -212,7 +215,7 @@ namespace eosiosystem { auto prod = producers_tbl.find( p ); eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes -= amount.quantity; + v.total_votes -= amount.amount; }); } } @@ -222,20 +225,22 @@ namespace eosiosystem { } voters_tbl.modify( voter, 0, [&](voter_info& a) { a.staked += a.unstaking; - a.unstaking.quantity = 0; - a.unstake_per_week.quantity = 0; + a.unstaking.amount = 0; + a.unstake_per_week.amount = 0; a.deferred_trx_id = 0; a.last_update = now(); }); } } - static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { - const system_token_type token_supply = currency::get_total_supply(); + static eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate) { +#warning "FIX THIS!" + // const system_token_type token_supply = currency::get_total_supply(); + const eosio::asset token_supply = _system_token.get_total_supply(S(4,EOS)); const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); double continuous_rate = std::log1p(annual_rate); - uint64_t payment = static_cast((continuous_rate * double(token_supply.quantity)) / double(blocks_per_year)); - return (system_token_type(payment)); + int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); + return (eosio::asset(payment, S(4,EOS))); } static void update_elected_producers(time cycle_time) { @@ -375,7 +380,9 @@ namespace eosiosystem { } auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); - currency::inline_issue(SystemAccount, issue_quantity); + // currency::inline_issue(SystemAccount, issue_quantity); +#warning "FIX THIS!" + _system_token.inlineissue(issue_quantity, "producer pay"); set_blockchain_parameters(parameters); global_state_singleton::set(parameters); } @@ -412,7 +419,7 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto voter = voters_tbl.find( vp.voter ); - eosio_assert( voter != voters_tbl.end() && ( 0 < voter->staked.quantity || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); + eosio_assert( voter != voters_tbl.end() && ( 0 < voter->staked.amount || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); if ( voter->is_proxy ) { eosio_assert( vp.proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); } @@ -425,7 +432,7 @@ namespace eosiosystem { } auto old_proxy = voters_tbl.find( voter->proxy ); eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption - voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); + voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.amount; } ); if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) old_producers = &old_proxy->producers; } @@ -438,14 +445,14 @@ namespace eosiosystem { if ( vp.proxy ) { auto new_proxy = voters_tbl.find( vp.proxy ); eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); - voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); + voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.amount; } ); new_producers = &new_proxy->producers; } else { new_producers = &vp.producers; } producers_table producers_tbl( SystemAccount, SystemAccount ); - uint128_t votes = voter->staked.quantity; + uint128_t votes = voter->staked.amount; if ( voter->is_proxy ) { votes += voter->proxied_votes; } @@ -520,7 +527,7 @@ namespace eosiosystem { a.proxy = 0; a.is_proxy = 1; a.proxied_votes = 0; - a.staked.quantity = 0; + a.staked.amount = 0; }); } } From 2ba78017b3a09cb5ad4781035d226a9cf929da8d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 12 Apr 2018 09:43:05 -0400 Subject: [PATCH 0154/1048] Small changes --- common.hpp | 2 +- voting.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/common.hpp b/common.hpp index ee407118..ba3f2156 100644 --- a/common.hpp +++ b/common.hpp @@ -11,7 +11,7 @@ namespace eosiosystem { - eosio::token _system_token(N(eosio)); + eosio::token _system_token(N(eosio.system)); template class common { diff --git a/voting.hpp b/voting.hpp index 433593a9..888bb749 100644 --- a/voting.hpp +++ b/voting.hpp @@ -382,7 +382,7 @@ namespace eosiosystem { auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); // currency::inline_issue(SystemAccount, issue_quantity); #warning "FIX THIS!" - _system_token.inlineissue(issue_quantity, "producer pay"); + _system_token.inline_issue(issue_quantity, "producer pay"); set_blockchain_parameters(parameters); global_state_singleton::set(parameters); } From 5dbb6e3d2353b83944f47a34ed4c35cbed238501 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 13 Apr 2018 19:42:10 -0400 Subject: [PATCH 0155/1048] Migrate system contract to the new currency - progress --- common.hpp | 2 +- delegate_bandwidth.hpp | 21 +++++++++++++++------ eosio.system.abi | 1 + eosio.system.hpp | 6 +++++- voting.hpp | 12 +++++++++--- 5 files changed, 31 insertions(+), 11 deletions(-) diff --git a/common.hpp b/common.hpp index ba3f2156..4d707729 100644 --- a/common.hpp +++ b/common.hpp @@ -33,7 +33,7 @@ namespace eosiosystem { uint32_t percent_of_max_inflation_rate = 0; uint32_t storage_reserve_ratio = 1000; // ratio * 1000 - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (percent_of_max_inflation_rate)(storage_reserve_ratio) ) + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_storage_size)(percent_of_max_inflation_rate)(storage_reserve_ratio) ) }; struct eosio_global_state : eosio_parameters { diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index 50a7fe60..df8e2356 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -65,9 +65,9 @@ namespace eosiosystem { // typename currency::token_type net_weight; // typename currency::token_type cpu_weight; // typename currency::token_type storage_stake; - eosio::asset net_weight; - eosio::asset cpu_weight; - eosio::asset storage_stake; + asset net_weight; + asset cpu_weight; + asset storage_stake; uint64_t storage_bytes = 0; uint64_t primary_key()const { return to; } @@ -136,7 +136,7 @@ namespace eosiosystem { : common::get_default_parameters(); #warning "FIX THIS!" // auto token_supply = currency::get_total_supply(); - eosio::asset token_supply(0, S(4,EOS)); + asset token_supply(1000000000, S(4,EOS)); //make sure that there is no posibility of overflow here // uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) @@ -205,10 +205,15 @@ namespace eosiosystem { //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); // currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); - _system_token.inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); + + eosio::action act( eosio::permission_level{/*N(eosio.system)*//* N(eosio)*/ del.from,N(active)}, N(eosio.token), N(inlinetransfer), + std::make_tuple( del.from, /*N(eosio.system)*/ N(eosio), total_stake, std::string("stake bandwidth") ) ); + act.send(); + if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { voting::increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); } + } // delegatebw static void on( account_name receiver, const undelegatebw& del ) { @@ -305,7 +310,11 @@ namespace eosiosystem { // consecutive missed blocks. // currency::inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); - _system_token.inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); + { + eosio::action act( eosio::permission_level{N(eosio.system),N(active)}, N(eosio.token), N(inlinetransfer), + std::make_tuple( N(eosio.system), req->owner, req->amount, std::string("unstake") ) ); + act.send(); + } refunds_tbl.erase( req ); } }; diff --git a/eosio.system.abi b/eosio.system.abi index 1d47e2e0..b04ff0cb 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -107,6 +107,7 @@ {"name":"max_inline_depth", "type":"uint16"}, {"name":"max_inline_action_size", "type":"uint32"}, {"name":"max_generated_transaction_count", "type":"uint32"}, + {"name":"max_storage_size", "type":"uint64"}, {"name":"percent_of_max_inflation_rate", "type":"uint32"}, {"name":"storage_reserve_ratio", "type":"uint32"} ] diff --git a/eosio.system.hpp b/eosio.system.hpp index c92dd5c3..c685b417 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -173,7 +173,11 @@ namespace eosiosystem { p.per_block_payments.amount = 0; }); - _system_token.inline_transfer(SystemAccount, cr.owner, rewards, "producer claiming rewards"); + { + eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(inlinetransfer), + std::make_tuple( N(eosio), cr.owner, rewards, std::string("producer claiming rewards") ) ); + act.send(); + } } static void apply( account_name receiver, account_name code, action_name act ) { diff --git a/voting.hpp b/voting.hpp index 888bb749..8da29d7e 100644 --- a/voting.hpp +++ b/voting.hpp @@ -236,11 +236,13 @@ namespace eosiosystem { static eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate) { #warning "FIX THIS!" // const system_token_type token_supply = currency::get_total_supply(); - const eosio::asset token_supply = _system_token.get_total_supply(S(4,EOS)); + const eosio::asset token_supply(10000000000, S(4,EOS)); // = _system_token.get_total_supply(S(4,EOS)); const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); double continuous_rate = std::log1p(annual_rate); + print("rate = "); + print(continuous_rate); int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); - return (eosio::asset(payment, S(4,EOS))); + return eosio::asset(payment, S(4,EOS)); } static void update_elected_producers(time cycle_time) { @@ -382,7 +384,11 @@ namespace eosiosystem { auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); // currency::inline_issue(SystemAccount, issue_quantity); #warning "FIX THIS!" - _system_token.inline_issue(issue_quantity, "producer pay"); + { + eosio::action act( eosio::permission_level{N(eosio.system),N(active)}, N(eosio.token), N(inline_issue), + std::make_tuple( issue_quantity, std::string("producer pay") ) ); + act.send(); + } set_blockchain_parameters(parameters); global_state_singleton::set(parameters); } From 03c02de262fdaf359e936575b3bf38c9af5fcc81 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 16 Apr 2018 15:20:50 -0400 Subject: [PATCH 0156/1048] Fixed system contract unit tests - #1889, #2231 --- delegate_bandwidth.hpp | 14 +++++++------- eosio.system.abi | 12 ++++++------ eosio.system.hpp | 5 ----- voting.hpp | 2 -- 4 files changed, 13 insertions(+), 20 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index df8e2356..da6af89f 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -45,9 +45,9 @@ namespace eosiosystem { // typename currency::token_type net_weight; // typename currency::token_type cpu_weight; // typename currency::token_type storage_stake; - eosio::asset net_weight; - eosio::asset cpu_weight; - eosio::asset storage_stake; + asset net_weight; + asset cpu_weight; + asset storage_stake; uint64_t storage_bytes = 0; uint64_t primary_key()const { return owner; } @@ -206,8 +206,8 @@ namespace eosiosystem { // currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); - eosio::action act( eosio::permission_level{/*N(eosio.system)*//* N(eosio)*/ del.from,N(active)}, N(eosio.token), N(inlinetransfer), - std::make_tuple( del.from, /*N(eosio.system)*/ N(eosio), total_stake, std::string("stake bandwidth") ) ); + eosio::action act( eosio::permission_level{del.from,N(active)}, N(eosio.token), N(inlinetransfer), + std::make_tuple( del.from, N(eosio), total_stake, std::string("stake bandwidth") ) ); act.send(); if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { @@ -311,8 +311,8 @@ namespace eosiosystem { // currency::inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); { - eosio::action act( eosio::permission_level{N(eosio.system),N(active)}, N(eosio.token), N(inlinetransfer), - std::make_tuple( N(eosio.system), req->owner, req->amount, std::string("unstake") ) ); + eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(inlinetransfer), + std::make_tuple( N(eosio), req->owner, req->amount, std::string("unstake") ) ); act.send(); } refunds_tbl.erase( req ); diff --git a/eosio.system.abi b/eosio.system.abi index b04ff0cb..8b97d9fa 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -78,9 +78,9 @@ "base": "", "fields": [ {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"uint64"}, - {"name":"cpu_weight", "type":"uint64"}, - {"name":"storage_stake", "type":"uint64"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"storage_stake", "type":"asset"}, {"name":"storage_bytes", "type":"uint64"} ] },{ @@ -172,9 +172,9 @@ {"name":"proxy", "type":"account_name"}, {"name":"last_update", "type":"uint32"}, {"name":"is_proxy", "type":"uint32"}, - {"name":"staked", "type":"uint64"}, - {"name":"unstaking", "type":"uint64"}, - {"name":"unstake_per_week", "type":"uint64"}, + {"name":"staked", "type":"asset"}, + {"name":"unstaking", "type":"asset"}, + {"name":"unstake_per_week", "type":"asset"}, {"name":"proxied_votes", "type":"uint128"}, {"name":"producers", "type":"account_name[]"}, {"name":"deferred_trx_id", "type":"uint32"}, diff --git a/eosio.system.hpp b/eosio.system.hpp index c685b417..2a053c30 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -30,8 +30,6 @@ namespace eosiosystem { template class contract : eosio::contract, public delegate_bandwidth, public native { - // private: - // eosio::token _system_token; public: contract(account_name self = SystemAccount): @@ -97,7 +95,6 @@ namespace eosiosystem { account_name producer = ob.header.producer; auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - // const system_token_type block_payment = parameters.payment_per_block; const asset block_payment = parameters.payment_per_block; auto prod = producers_tbl.find(producer); if ( prod != producers_tbl.end() ) { @@ -108,7 +105,6 @@ namespace eosiosystem { } const uint32_t num_of_payments = ob.header.timestamp - parameters.last_bucket_fill_time; - // const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; parameters.last_bucket_fill_time = ob.header.timestamp; parameters.eos_bucket += to_eos_bucket; @@ -165,7 +161,6 @@ namespace eosiosystem { } } - // eosio_assert( rewards > system_token_type(), "no rewards available to claim" ); eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); producers_tbl.modify( prod, 0, [&](auto& p) { diff --git a/voting.hpp b/voting.hpp index 8da29d7e..b8951132 100644 --- a/voting.hpp +++ b/voting.hpp @@ -239,8 +239,6 @@ namespace eosiosystem { const eosio::asset token_supply(10000000000, S(4,EOS)); // = _system_token.get_total_supply(S(4,EOS)); const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); double continuous_rate = std::log1p(annual_rate); - print("rate = "); - print(continuous_rate); int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); return eosio::asset(payment, S(4,EOS)); } From e390c0cfd8017a87e826d74c8b4a75cb79431182 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 17 Apr 2018 12:46:50 -0400 Subject: [PATCH 0157/1048] Fixed producer pay and delegatebw, code cleaning - #1889 --- common.hpp | 22 +++++++++------------- delegate_bandwidth.hpp | 35 ++++------------------------------- eosio.system.hpp | 10 +++------- voting.hpp | 18 ++++++------------ 4 files changed, 22 insertions(+), 63 deletions(-) diff --git a/common.hpp b/common.hpp index 4d707729..ee0f8d6f 100644 --- a/common.hpp +++ b/common.hpp @@ -1,7 +1,10 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ #pragma once -#include -//#include +#include #include #include #include @@ -11,22 +14,15 @@ namespace eosiosystem { - eosio::token _system_token(N(eosio.system)); - template class common { public: static constexpr account_name system_account = SystemAccount; - // typedef eosio::generic_currency< eosio::token > currency; - // typedef typename currency::token_type system_token_type; - - // static constexpr eosio::symbol_type system_symbol(S(4,EOS)); - - static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation + static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation - static constexpr uint32_t blocks_per_producer = 12; - static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr uint32_t days_per_4years = 1461; + static constexpr uint32_t blocks_per_producer = 12; + static constexpr uint32_t seconds_per_day = 24 * 3600; + static constexpr uint32_t days_per_4years = 1461; struct eosio_parameters : eosio::blockchain_parameters { uint64_t max_storage_size = 10 * 1024 * 1024; diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index da6af89f..bcbe0fe2 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -7,10 +7,7 @@ #include "voting.hpp" #include -//#include #include - -//#include #include #include #include @@ -35,16 +32,11 @@ namespace eosiosystem { static constexpr account_name system_account = SystemAccount; static constexpr time refund_delay = 3*24*3600; static constexpr time refund_expiration_time = 3600; - // using currency = typename common::currency; - // using system_token_type = typename common::system_token_type; using eosio_parameters = typename common::eosio_parameters; using global_state_singleton = typename common::global_state_singleton; struct total_resources { account_name owner; - // typename currency::token_type net_weight; - // typename currency::token_type cpu_weight; - // typename currency::token_type storage_stake; asset net_weight; asset cpu_weight; asset storage_stake; @@ -62,9 +54,6 @@ namespace eosiosystem { struct delegated_bandwidth { account_name from; account_name to; - // typename currency::token_type net_weight; - // typename currency::token_type cpu_weight; - // typename currency::token_type storage_stake; asset net_weight; asset cpu_weight; asset storage_stake; @@ -79,7 +68,6 @@ namespace eosiosystem { struct refund_request { account_name owner; time request_time; - // typename currency::token_type amount; eosio::asset amount; uint64_t primary_key()const { return owner; } @@ -123,7 +111,6 @@ namespace eosiosystem { eosio_assert( del.stake_net_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( del.stake_storage_quantity.amount >= 0, "must stake a positive amount" ); - // system_token_type total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; asset total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); @@ -134,23 +121,16 @@ namespace eosiosystem { if ( 0 < del.stake_storage_quantity.amount ) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); -#warning "FIX THIS!" - // auto token_supply = currency::get_total_supply(); - asset token_supply(1000000000, S(4,EOS)); + eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); + eosio::token::stats stats_tbl(N(eosio.token), sym); + const auto& st = stats_tbl.get(sym); + const eosio::asset token_supply = st.supply; //make sure that there is no posibility of overflow here - // uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - // * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) - // / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) * parameters.storage_reserve_ratio * del.stake_storage_quantity / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - // storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) - // * parameters.storage_reserve_ratio * system_token_type(del.stake_storage_quantity) - // / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) * parameters.storage_reserve_ratio * del.stake_storage_quantity / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; @@ -203,8 +183,6 @@ namespace eosiosystem { } //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); - - // currency::inline_transfer( del.from, SystemAccount, total_stake, "stake bandwidth" ); eosio::action act( eosio::permission_level{del.from,N(active)}, N(eosio.token), N(inlinetransfer), std::make_tuple( del.from, N(eosio), total_stake, std::string("stake bandwidth") ) ); @@ -230,7 +208,6 @@ namespace eosiosystem { eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); - // system_token_type storage_stake_decrease = system_token_type(0); eosio::asset storage_stake_decrease(0, S(4,EOS)); if ( 0 < del.unstake_storage_bytes ) { storage_stake_decrease = 0 < dbw.storage_bytes ? @@ -243,9 +220,6 @@ namespace eosiosystem { global_state_singleton::set( parameters ); } - // auto total_refund = system_token_type(del.unstake_cpu_quantity) - // + system_token_type(del.unstake_net_quantity) + storage_stake_decrease; - eosio::asset total_refund = del.unstake_cpu_quantity + del.unstake_net_quantity + storage_stake_decrease; eosio_assert( total_refund.amount > 0, "must unstake a positive amount" ); @@ -309,7 +283,6 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - // currency::inline_transfer( SystemAccount, req->owner, req->amount, "unstake" ); { eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(inlinetransfer), std::make_tuple( N(eosio), req->owner, req->amount, std::string("unstake") ) ); diff --git a/eosio.system.hpp b/eosio.system.hpp index 2a053c30..f2e07ca9 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -6,10 +6,8 @@ #include "delegate_bandwidth.hpp" #include "native.hpp" -#include - -//#include +#include #include namespace eosiosystem { @@ -42,8 +40,6 @@ namespace eosiosystem { using native::on; using pe = voting; using db = delegate_bandwidth; - // using currency = typename common::currency; - // using system_token_type = typename common::system_token_type; using producers_table = typename pe::producers_table; using global_state_singleton = typename voting::global_state_singleton; static const uint32_t max_inflation_rate = common::max_inflation_rate; @@ -127,7 +123,7 @@ namespace eosiosystem { if( prod->last_rewards_claim > 0 ) { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } - // system_token_type rewards = prod->per_block_payments; + eosio::asset rewards = prod->per_block_payments; auto idx = producers_tbl.template get_index(); auto itr = --idx.end(); @@ -153,7 +149,7 @@ namespace eosiosystem { if (is_among_payed_producers && total_producer_votes > 0) { if( global_state_singleton::exists() ) { auto parameters = global_state_singleton::get(); - // auto share_of_eos_bucket = system_token_type( static_cast( (prod->total_votes * parameters.eos_bucket.quantity) / total_producer_votes ) ); // This will be improved in the future when total_votes becomes a double type. + // This will be improved in the future when total_votes becomes a double type. auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * parameters.eos_bucket.amount) / total_producer_votes ) ); rewards += share_of_eos_bucket; parameters.eos_bucket -= share_of_eos_bucket; diff --git a/voting.hpp b/voting.hpp index b8951132..eca27e6b 100644 --- a/voting.hpp +++ b/voting.hpp @@ -3,13 +3,11 @@ * @copyright defined in eos/LICENSE.txt */ #pragma once + #include "common.hpp" #include -//#include #include - -//#include #include #include #include @@ -17,8 +15,6 @@ #include #include -#include - #include #include #include @@ -35,10 +31,7 @@ namespace eosiosystem { template class voting { public: - static constexpr account_name system_account = SystemAccount; - // using currency = typename common::currency; - // using system_token_type = typename common::system_token_type; using eosio_parameters = typename common::eosio_parameters; using global_state_singleton = typename common::global_state_singleton; @@ -234,9 +227,10 @@ namespace eosiosystem { } static eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate) { -#warning "FIX THIS!" - // const system_token_type token_supply = currency::get_total_supply(); - const eosio::asset token_supply(10000000000, S(4,EOS)); // = _system_token.get_total_supply(S(4,EOS)); + eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); + eosio::token::stats stats_tbl(N(eosio.token), sym); + const auto& st = stats_tbl.get(sym); + const eosio::asset token_supply = st.supply; const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); double continuous_rate = std::log1p(annual_rate); int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); @@ -383,7 +377,7 @@ namespace eosiosystem { // currency::inline_issue(SystemAccount, issue_quantity); #warning "FIX THIS!" { - eosio::action act( eosio::permission_level{N(eosio.system),N(active)}, N(eosio.token), N(inline_issue), + eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(inlineissue), std::make_tuple( issue_quantity, std::string("producer pay") ) ); act.send(); } From cadb4737f4c7618ba75bd77324a366d5779f1914 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 17 Apr 2018 15:57:05 -0400 Subject: [PATCH 0158/1048] Deleted inlinetransfer and inlineissue --- delegate_bandwidth.hpp | 4 ++-- eosio.system.hpp | 2 +- voting.hpp | 6 ++---- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index bcbe0fe2..d4aa07db 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -184,7 +184,7 @@ namespace eosiosystem { //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); - eosio::action act( eosio::permission_level{del.from,N(active)}, N(eosio.token), N(inlinetransfer), + eosio::action act( eosio::permission_level{del.from,N(active)}, N(eosio.token), N(transfer), std::make_tuple( del.from, N(eosio), total_stake, std::string("stake bandwidth") ) ); act.send(); @@ -284,7 +284,7 @@ namespace eosiosystem { // consecutive missed blocks. { - eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(inlinetransfer), + eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(transfer), std::make_tuple( N(eosio), req->owner, req->amount, std::string("unstake") ) ); act.send(); } diff --git a/eosio.system.hpp b/eosio.system.hpp index f2e07ca9..541e9173 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -165,7 +165,7 @@ namespace eosiosystem { }); { - eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(inlinetransfer), + eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(transfer), std::make_tuple( N(eosio), cr.owner, rewards, std::string("producer claiming rewards") ) ); act.send(); } diff --git a/voting.hpp b/voting.hpp index eca27e6b..3e074a09 100644 --- a/voting.hpp +++ b/voting.hpp @@ -374,11 +374,9 @@ namespace eosiosystem { } auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); - // currency::inline_issue(SystemAccount, issue_quantity); -#warning "FIX THIS!" { - eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(inlineissue), - std::make_tuple( issue_quantity, std::string("producer pay") ) ); + eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(issue), + std::make_tuple( N(eosio), issue_quantity, std::string("producer pay") ) ); act.send(); } set_blockchain_parameters(parameters); From c04ab86385e748b7db6c68e92a9e5686cc1dcf77 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 17 Apr 2018 19:36:22 -0400 Subject: [PATCH 0159/1048] Rebase on master, code cleaning --- delegate_bandwidth.hpp | 13 +++++-------- eosio.system.hpp | 10 ++-------- voting.hpp | 8 +++++--- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index d4aa07db..91ccc67a 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -184,9 +184,8 @@ namespace eosiosystem { //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); - eosio::action act( eosio::permission_level{del.from,N(active)}, N(eosio.token), N(transfer), - std::make_tuple( del.from, N(eosio), total_stake, std::string("stake bandwidth") ) ); - act.send(); + eosio::inline_transfer(eosio::permission_level{del.from,N(active)}, N(eosio.token), + { del.from, N(eosio), total_stake, std::string("stake bandwidth") } ); if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { voting::increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); @@ -283,11 +282,9 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - { - eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(transfer), - std::make_tuple( N(eosio), req->owner, req->amount, std::string("unstake") ) ); - act.send(); - } + eosio::inline_transfer( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), + { N(eosio), req->owner, req->amount, std::string("unstake") }); + refunds_tbl.erase( req ); } }; diff --git a/eosio.system.hpp b/eosio.system.hpp index 541e9173..bc4f0620 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -164,15 +164,11 @@ namespace eosiosystem { p.per_block_payments.amount = 0; }); - { - eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(transfer), - std::make_tuple( N(eosio), cr.owner, rewards, std::string("producer claiming rewards") ) ); - act.send(); - } + eosio::inline_transfer(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), + { N(eosio), cr.owner, rewards, std::string("producer claiming rewards") } ); } static void apply( account_name receiver, account_name code, action_name act ) { - // if ( !eosio::dispatch( code, act ) ) { if( !eosio::dispatch::delegatebw, typename delegate_bandwidth::refund, typename voting::regproxy, @@ -199,8 +195,6 @@ namespace eosiosystem { contract().on( receiver, eosio::unpack_action_data() ); } } - // } - } /// apply }; diff --git a/voting.hpp b/voting.hpp index 3e074a09..687b8720 100644 --- a/voting.hpp +++ b/voting.hpp @@ -375,9 +375,11 @@ namespace eosiosystem { auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); { - eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(issue), - std::make_tuple( N(eosio), issue_quantity, std::string("producer pay") ) ); - act.send(); + // eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(issue), + // std::make_tuple( N(eosio), issue_quantity, std::string("producer pay") ) ); + // act.send(); + eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), + { N(eosio), issue_quantity, std::string("producer pay") }); } set_blockchain_parameters(parameters); global_state_singleton::set(parameters); From d192c30786a5338b3731e0daf56015d117add58d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Apr 2018 13:43:15 -0400 Subject: [PATCH 0160/1048] Fixed warnings - #1889 --- delegate_bandwidth.hpp | 22 +++++++++++----------- eosio.system.hpp | 2 +- voting.hpp | 17 ++++++++++------- 3 files changed, 22 insertions(+), 19 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index 91ccc67a..ff1b6003 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -117,7 +117,7 @@ namespace eosiosystem { require_auth( del.from ); //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - uint64_t storage_bytes = 0; + int64_t storage_bytes = 0; if ( 0 < del.stake_storage_quantity.amount ) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); @@ -127,17 +127,17 @@ namespace eosiosystem { const eosio::asset token_supply = st.supply; //make sure that there is no posibility of overflow here - uint64_t storage_bytes_estimated = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - * parameters.storage_reserve_ratio * del.stake_storage_quantity + int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) + * int64_t(parameters.storage_reserve_ratio) * del.stake_storage_quantity / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - storage_bytes = ( parameters.max_storage_size - parameters.total_storage_bytes_reserved - storage_bytes_estimated ) - * parameters.storage_reserve_ratio * del.stake_storage_quantity + storage_bytes = ( int64_t(parameters.max_storage_size) - int64_t(parameters.total_storage_bytes_reserved) - storage_bytes_estimated ) + * int64_t(parameters.storage_reserve_ratio) * del.stake_storage_quantity / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); - parameters.total_storage_bytes_reserved += storage_bytes; + parameters.total_storage_bytes_reserved += uint64_t(storage_bytes); parameters.total_storage_stake += del.stake_storage_quantity; global_state_singleton::set(parameters); } @@ -151,7 +151,7 @@ namespace eosiosystem { dbo.net_weight = del.stake_net_quantity; dbo.cpu_weight = del.stake_cpu_quantity; dbo.storage_stake = del.stake_storage_quantity; - dbo.storage_bytes = storage_bytes; + dbo.storage_bytes = uint64_t(storage_bytes); }); } else { @@ -159,7 +159,7 @@ namespace eosiosystem { dbo.net_weight += del.stake_net_quantity; dbo.cpu_weight += del.stake_cpu_quantity; dbo.storage_stake += del.stake_storage_quantity; - dbo.storage_bytes += storage_bytes; + dbo.storage_bytes += uint64_t(storage_bytes); }); } @@ -171,14 +171,14 @@ namespace eosiosystem { tot.net_weight = del.stake_net_quantity; tot.cpu_weight = del.stake_cpu_quantity; tot.storage_stake = del.stake_storage_quantity; - tot.storage_bytes = storage_bytes; + tot.storage_bytes = uint64_t(storage_bytes); }); } else { totals_tbl.modify( tot_itr, del.from == del.receiver ? del.from : 0, [&]( auto& tot ) { tot.net_weight += del.stake_net_quantity; tot.cpu_weight += del.stake_cpu_quantity; tot.storage_stake += del.stake_storage_quantity; - tot.storage_bytes += storage_bytes; + tot.storage_bytes += uint64_t(storage_bytes); }); } @@ -210,7 +210,7 @@ namespace eosiosystem { eosio::asset storage_stake_decrease(0, S(4,EOS)); if ( 0 < del.unstake_storage_bytes ) { storage_stake_decrease = 0 < dbw.storage_bytes ? - dbw.storage_stake * del.unstake_storage_bytes / dbw.storage_bytes + dbw.storage_stake * int64_t(del.unstake_storage_bytes) / int64_t(dbw.storage_bytes) : eosio::asset(0, S(4,EOS)); auto parameters = global_state_singleton::get(); diff --git a/eosio.system.hpp b/eosio.system.hpp index bc4f0620..eeed12b9 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -150,7 +150,7 @@ namespace eosiosystem { if( global_state_singleton::exists() ) { auto parameters = global_state_singleton::get(); // This will be improved in the future when total_votes becomes a double type. - auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * parameters.eos_bucket.amount) / total_producer_votes ) ); + auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * uint64_t(parameters.eos_bucket.amount) ) / total_producer_votes ) ); rewards += share_of_eos_bucket; parameters.eos_bucket -= share_of_eos_bucket; global_state_singleton::set(parameters); diff --git a/voting.hpp b/voting.hpp index 687b8720..a63fe84b 100644 --- a/voting.hpp +++ b/voting.hpp @@ -141,6 +141,8 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto voter = voters_tbl.find( acnt ); + eosio_assert( 0 <= amount.amount, "negative asset" ); + if( voter == voters_tbl.end() ) { voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { a.owner = acnt; @@ -158,7 +160,7 @@ namespace eosiosystem { if ( voter->proxy ) { auto proxy = voters_tbl.find( voter->proxy ); eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.amount; } ); + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += uint64_t(amount.amount); } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } @@ -172,7 +174,7 @@ namespace eosiosystem { auto prod = producers_tbl.find( p ); eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes += amount.amount; + v.total_votes += uint64_t(amount.amount); }); } } @@ -194,7 +196,7 @@ namespace eosiosystem { const std::vector* producers = nullptr; if ( voter->proxy ) { auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.amount; } ); + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= uint64_t(amount.amount); } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } @@ -208,7 +210,7 @@ namespace eosiosystem { auto prod = producers_tbl.find( p ); eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes -= amount.amount; + v.total_votes -= uint64_t(amount.amount); }); } } @@ -417,6 +419,7 @@ namespace eosiosystem { voters_table voters_tbl( SystemAccount, SystemAccount ); auto voter = voters_tbl.find( vp.voter ); + eosio_assert( 0 <= voter->staked.amount, "negative stake" ); eosio_assert( voter != voters_tbl.end() && ( 0 < voter->staked.amount || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); if ( voter->is_proxy ) { eosio_assert( vp.proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); @@ -430,7 +433,7 @@ namespace eosiosystem { } auto old_proxy = voters_tbl.find( voter->proxy ); eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption - voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.amount; } ); + voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= uint64_t(voter->staked.amount); } ); if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) old_producers = &old_proxy->producers; } @@ -443,14 +446,14 @@ namespace eosiosystem { if ( vp.proxy ) { auto new_proxy = voters_tbl.find( vp.proxy ); eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); - voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.amount; } ); + voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += uint64_t(voter->staked.amount); } ); new_producers = &new_proxy->producers; } else { new_producers = &vp.producers; } producers_table producers_tbl( SystemAccount, SystemAccount ); - uint128_t votes = voter->staked.amount; + uint128_t votes = uint64_t(voter->staked.amount); if ( voter->is_proxy ) { votes += voter->proxied_votes; } From 88891d1ef8b1fdc13c0323bae565c936de054009 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Apr 2018 14:00:27 -0400 Subject: [PATCH 0161/1048] Code cleaning --- voting.hpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/voting.hpp b/voting.hpp index a63fe84b..a1a20d85 100644 --- a/voting.hpp +++ b/voting.hpp @@ -376,13 +376,9 @@ namespace eosiosystem { } auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); - { - // eosio::action act( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), N(issue), - // std::make_tuple( N(eosio), issue_quantity, std::string("producer pay") ) ); - // act.send(); - eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), - { N(eosio), issue_quantity, std::string("producer pay") }); - } + eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), + { N(eosio), issue_quantity, std::string("producer pay") }); + set_blockchain_parameters(parameters); global_state_singleton::set(parameters); } From 5df2caf922c21784fe6aa4781cfc29488829ae20 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 16 Apr 2018 15:41:41 -0400 Subject: [PATCH 0162/1048] producers vote on authority delay limit, eosio.system unit-test updated #1902 --- eosio.system.abi | 1 + voting.hpp | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index 8b97d9fa..63fb2c31 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -107,6 +107,7 @@ {"name":"max_inline_depth", "type":"uint16"}, {"name":"max_inline_action_size", "type":"uint32"}, {"name":"max_generated_transaction_count", "type":"uint32"}, + {"name":"max_transaction_delay", "type":"uint32"}, {"name":"max_storage_size", "type":"uint64"}, {"name":"percent_of_max_inflation_rate", "type":"uint32"}, {"name":"storage_reserve_ratio", "type":"uint32"} diff --git a/voting.hpp b/voting.hpp index a1a20d85..e5a5fb39 100644 --- a/voting.hpp +++ b/voting.hpp @@ -263,6 +263,7 @@ namespace eosiosystem { std::array max_inline_depth; std::array max_inline_action_size; std::array max_generated_transaction_count; + std::array max_transaction_delay; std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; @@ -296,6 +297,7 @@ namespace eosiosystem { max_inline_depth[n] = it->prefs.max_inline_depth; max_inline_action_size[n] = it->prefs.max_inline_action_size; max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; + max_transaction_delay[n] = it->prefs.max_transaction_delay; storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; @@ -326,6 +328,7 @@ namespace eosiosystem { std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); + std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); } @@ -358,6 +361,7 @@ namespace eosiosystem { parameters.max_inline_depth = max_inline_depth[median]; parameters.max_inline_action_size = max_inline_action_size[median]; parameters.max_generated_transaction_count = max_generated_transaction_count[median]; + parameters.max_transaction_delay = max_transaction_delay[median]; parameters.storage_reserve_ratio = storage_reserve_ratio[median]; parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; From 997014ffbcacad688a35a901b682962c26ab1a77 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 19 Apr 2018 18:37:07 -0400 Subject: [PATCH 0163/1048] system contract refactoring - move code from .hpp to .cpp, use new dispatcher (some code temporarily commented out) #2227 --- CMakeLists.txt | 1 + apply.cpp | 17 ++ common.hpp | 27 +- delegate_bandwidth.cpp | 272 ++++++++++++++++++++ delegate_bandwidth.hpp | 291 --------------------- eosio.system.hpp | 279 ++++++++------------ native.hpp | 124 ++------- producer_pay.cpp | 118 +++++++++ voting.cpp | 501 ++++++++++++++++++++++++++++++++++++ voting.hpp | 567 ----------------------------------------- 10 files changed, 1045 insertions(+), 1152 deletions(-) create mode 100644 apply.cpp create mode 100644 delegate_bandwidth.cpp delete mode 100644 delegate_bandwidth.hpp create mode 100644 producer_pay.cpp create mode 100644 voting.cpp delete mode 100644 voting.hpp diff --git a/CMakeLists.txt b/CMakeLists.txt index eb4ff749..6de72324 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,7 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system + SOURCE_FILES apply.cpp delegate_bandwidth.cpp voting.cpp producer_pay.cpp INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} LIBRARIES libc++ libc eosiolib eosio.token DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} diff --git a/apply.cpp b/apply.cpp new file mode 100644 index 00000000..19c7f4a5 --- /dev/null +++ b/apply.cpp @@ -0,0 +1,17 @@ +#include "eosio.system.hpp" + +#include + +EOSIO_ABI( eosiosystem::system_contract, + // delegate_bandwith.cpp + (delegatebw)(undelegatebw)(refund) + (regproxy) + // voting.cpp + (unregproxy)(regproducer)(unregprod)(voteproducer)(onblock) + // producer_pay.cpp + (claimrewards) + // native.hpp + //(newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) + // defined in eosio.system.hpp + (nonce) +) diff --git a/common.hpp b/common.hpp index ee0f8d6f..42be96e8 100644 --- a/common.hpp +++ b/common.hpp @@ -18,37 +18,12 @@ namespace eosiosystem { class common { public: static constexpr account_name system_account = SystemAccount; - static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation + static constexpr uint32_t blocks_per_producer = 12; static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint32_t days_per_4years = 1461; - struct eosio_parameters : eosio::blockchain_parameters { - uint64_t max_storage_size = 10 * 1024 * 1024; - uint32_t percent_of_max_inflation_rate = 0; - uint32_t storage_reserve_ratio = 1000; // ratio * 1000 - - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_storage_size)(percent_of_max_inflation_rate)(storage_reserve_ratio) ) - }; - - struct eosio_global_state : eosio_parameters { - uint64_t total_storage_bytes_reserved = 0; - eosio::asset total_storage_stake; - eosio::asset payment_per_block; - eosio::asset payment_to_eos_bucket; - time first_block_time_in_cycle = 0; - uint32_t blocks_per_cycle = 0; - time last_bucket_fill_time = 0; - eosio::asset eos_bucket; - - EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) - (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) - (last_bucket_fill_time)(eos_bucket) ) - }; - - typedef eosio::singleton global_state_singleton; - static eosio_global_state& get_default_parameters() { static eosio_global_state dp; get_blockchain_parameters(dp); diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp new file mode 100644 index 00000000..e2110562 --- /dev/null +++ b/delegate_bandwidth.cpp @@ -0,0 +1,272 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#include "eosio.system.hpp" + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +namespace eosiosystem { + using eosio::asset; + using eosio::indexed_by; + using eosio::const_mem_fun; + using eosio::bytes; + using eosio::print; + using eosio::permission_level; + using std::map; + using std::pair; + + //static constexpr account_name system_account = SystemAccount; + static constexpr time refund_delay = 3*24*3600; + static constexpr time refund_expiration_time = 3600; + //using eosio_parameters = typename common::eosio_parameters; + //using global_state_singleton = typename common::global_state_singleton; + + struct total_resources { + account_name owner; + asset net_weight; + asset cpu_weight; + asset storage_stake; + uint64_t storage_bytes = 0; + + uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( total_resources, (owner)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) + }; + + + /** + * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. + */ + struct delegated_bandwidth { + account_name from; + account_name to; + asset net_weight; + asset cpu_weight; + asset storage_stake; + uint64_t storage_bytes = 0; + + uint64_t primary_key()const { return to; } + + EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) + + }; + + struct refund_request { + account_name owner; + time request_time; + eosio::asset amount; + + uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(amount) ) + }; + + typedef eosio::multi_index< N(totalband), total_resources> total_resources_table; + typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_table; + typedef eosio::multi_index< N(refunds), refund_request> refunds_table; + + void system_contract::delegatebw( const account_name from, const account_name receiver, + const asset stake_net_quantity, const asset stake_cpu_quantity, + const asset stake_storage_quantity ) + { + eosio_assert( stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); + eosio_assert( stake_net_quantity.amount >= 0, "must stake a positive amount" ); + eosio_assert( stake_storage_quantity.amount >= 0, "must stake a positive amount" ); + + asset total_stake = stake_cpu_quantity + stake_net_quantity + stake_storage_quantity; + eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); + + require_auth( from ); + + //eosio_assert( is_account( receiver ), "can only delegate resources to an existing account" ); + int64_t storage_bytes = 0; + if ( 0 < stake_storage_quantity.amount ) { + /* XXX + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : common::get_default_parameters(); + eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); + eosio::token::stats stats_tbl(N(eosio.token), sym); + const auto& st = stats_tbl.get(sym); + const eosio::asset token_supply = st.supply; + + //make sure that there is no posibility of overflow here + int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) + * int64_t(parameters.storage_reserve_ratio) * stake_storage_quantity + / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient * /; + + storage_bytes = ( int64_t(parameters.max_storage_size) - int64_t(parameters.total_storage_bytes_reserved) - storage_bytes_estimated ) + * int64_t(parameters.storage_reserve_ratio) * stake_storage_quantity + / ( token_supply - stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient * /; + + eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); + + parameters.total_storage_bytes_reserved += uint64_t(storage_bytes); + parameters.total_storage_stake += stake_storage_quantity; + global_state_singleton::set(parameters); + */ + } + + del_bandwidth_table del_tbl( _self, from ); + auto itr = del_tbl.find( receiver ); + if( itr == del_tbl.end() ) { + del_tbl.emplace( from, [&]( auto& dbo ){ + dbo.from = from; + dbo.to = receiver; + dbo.net_weight = stake_net_quantity; + dbo.cpu_weight = stake_cpu_quantity; + dbo.storage_stake = stake_storage_quantity; + dbo.storage_bytes = uint64_t(storage_bytes); + }); + } + else { + del_tbl.modify( itr, from, [&]( auto& dbo ){ + dbo.net_weight += stake_net_quantity; + dbo.cpu_weight += stake_cpu_quantity; + dbo.storage_stake += stake_storage_quantity; + dbo.storage_bytes += uint64_t(storage_bytes); + }); + } + + total_resources_table totals_tbl( _self, receiver ); + auto tot_itr = totals_tbl.find( receiver ); + if( tot_itr == totals_tbl.end() ) { + tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { + tot.owner = receiver; + tot.net_weight = stake_net_quantity; + tot.cpu_weight = stake_cpu_quantity; + tot.storage_stake = stake_storage_quantity; + tot.storage_bytes = uint64_t(storage_bytes); + }); + } else { + totals_tbl.modify( tot_itr, from == receiver ? from : 0, [&]( auto& tot ) { + tot.net_weight += stake_net_quantity; + tot.cpu_weight += stake_cpu_quantity; + tot.storage_stake += stake_storage_quantity; + tot.storage_bytes += uint64_t(storage_bytes); + }); + } + + //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); + + eosio::inline_transfer(eosio::permission_level{from,N(active)}, N(eosio.token), + { from, N(eosio), total_stake, std::string("stake bandwidth") } ); + + if ( asset(0) < stake_net_quantity + stake_cpu_quantity ) { + increase_voting_power( from, stake_net_quantity + stake_cpu_quantity ); + } + + } // delegatebw + + + void system_contract::undelegatebw( const account_name from, const account_name receiver, + const asset unstake_net_quantity, const asset unstake_cpu_quantity, + const uint64_t unstake_storage_bytes ) + { + eosio_assert( unstake_cpu_quantity.amount >= 0, "must unstake a positive amount" ); + eosio_assert( unstake_net_quantity.amount >= 0, "must unstake a positive amount" ); + + require_auth( from ); + + //eosio_assert( is_account( receiver ), "can only delegate resources to an existing account" ); + + del_bandwidth_table del_tbl( _self, from ); + const auto& dbw = del_tbl.get( receiver ); + eosio_assert( dbw.net_weight >= unstake_net_quantity, "insufficient staked net bandwidth" ); + eosio_assert( dbw.cpu_weight >= unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); + eosio_assert( dbw.storage_bytes >= unstake_storage_bytes, "insufficient staked storage" ); + + eosio::asset storage_stake_decrease(0, S(4,EOS)); + if ( 0 < unstake_storage_bytes ) { + storage_stake_decrease = 0 < dbw.storage_bytes ? + dbw.storage_stake * int64_t(unstake_storage_bytes) / int64_t(dbw.storage_bytes) + : eosio::asset(0, S(4,EOS)); + /* XXX + auto parameters = global_state_singleton::get(); + parameters.total_storage_bytes_reserved -= unstake_storage_bytes; + parameters.total_storage_stake -= storage_stake_decrease; + global_state_singleton::set( parameters ); + */ + } + + eosio::asset total_refund = unstake_cpu_quantity + unstake_net_quantity + storage_stake_decrease; + + eosio_assert( total_refund.amount > 0, "must unstake a positive amount" ); + + del_tbl.modify( dbw, from, [&]( auto& dbo ){ + dbo.net_weight -= unstake_net_quantity; + dbo.cpu_weight -= unstake_cpu_quantity; + dbo.storage_stake -= storage_stake_decrease; + dbo.storage_bytes -= unstake_storage_bytes; + }); + + total_resources_table totals_tbl( _self, receiver ); + const auto& totals = totals_tbl.get( receiver ); + totals_tbl.modify( totals, 0, [&]( auto& tot ) { + tot.net_weight -= unstake_net_quantity; + tot.cpu_weight -= unstake_cpu_quantity; + tot.storage_stake -= storage_stake_decrease; + tot.storage_bytes -= unstake_storage_bytes; + }); + + //set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity ); + + refunds_table refunds_tbl( _self, from ); + //create refund request + auto req = refunds_tbl.find( from ); + if ( req != refunds_tbl.end() ) { + refunds_tbl.modify( req, 0, [&]( refund_request& r ) { + r.amount += unstake_net_quantity + unstake_cpu_quantity + storage_stake_decrease; + r.request_time = now(); + }); + } else { + refunds_tbl.emplace( from, [&]( refund_request& r ) { + r.owner = from; + r.amount = unstake_net_quantity + unstake_cpu_quantity + storage_stake_decrease; + r.request_time = now(); + }); + } + //create or replace deferred transaction + /* XXX + refund act; + act.owner = from; + eosio::transaction out( now() + refund_delay + refund_expiration_time ); + out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), act ); + out.delay_sec = refund_delay; + out.send( from, receiver ); + */ + if ( asset(0) < unstake_net_quantity + unstake_cpu_quantity ) { + decrease_voting_power( from, unstake_net_quantity + unstake_cpu_quantity ); + } + + } // undelegatebw + + + void system_contract::refund( const account_name owner ) { + require_auth( owner ); + + refunds_table refunds_tbl( _self, owner ); + auto req = refunds_tbl.find( owner ); + eosio_assert( req != refunds_tbl.end(), "refund request not found" ); + eosio_assert( req->request_time + refund_delay <= now(), "refund is not available yet" ); + // Until now() becomes NOW, the fact that now() is the timestamp of the previous block could in theory + // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many + // consecutive missed blocks. + + eosio::inline_transfer( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), + { N(eosio), req->owner, req->amount, std::string("unstake") }); + + refunds_tbl.erase( req ); + } + +} //namespace eosiosystem diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp deleted file mode 100644 index ff1b6003..00000000 --- a/delegate_bandwidth.hpp +++ /dev/null @@ -1,291 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once -#include "common.hpp" -#include "voting.hpp" - -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace eosiosystem { - using eosio::asset; - using eosio::indexed_by; - using eosio::const_mem_fun; - using eosio::bytes; - using eosio::print; - using eosio::permission_level; - using std::map; - using std::pair; - - template - class delegate_bandwidth : public voting { - public: - static constexpr account_name system_account = SystemAccount; - static constexpr time refund_delay = 3*24*3600; - static constexpr time refund_expiration_time = 3600; - using eosio_parameters = typename common::eosio_parameters; - using global_state_singleton = typename common::global_state_singleton; - - struct total_resources { - account_name owner; - asset net_weight; - asset cpu_weight; - asset storage_stake; - uint64_t storage_bytes = 0; - - uint64_t primary_key()const { return owner; } - - EOSLIB_SERIALIZE( total_resources, (owner)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) - }; - - - /** - * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. - */ - struct delegated_bandwidth { - account_name from; - account_name to; - asset net_weight; - asset cpu_weight; - asset storage_stake; - uint64_t storage_bytes = 0; - - uint64_t primary_key()const { return to; } - - EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) - - }; - - struct refund_request { - account_name owner; - time request_time; - eosio::asset amount; - - uint64_t primary_key()const { return owner; } - - EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(amount) ) - }; - - typedef eosio::multi_index< N(totalband), total_resources> total_resources_table; - typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_table; - typedef eosio::multi_index< N(refunds), refund_request> refunds_table; - - ACTION( SystemAccount, delegatebw ) { - account_name from; - account_name receiver; - asset stake_net_quantity; - asset stake_cpu_quantity; - asset stake_storage_quantity; - - - EOSLIB_SERIALIZE( delegatebw, (from)(receiver)(stake_net_quantity)(stake_cpu_quantity)(stake_storage_quantity) ) - }; - - ACTION( SystemAccount, undelegatebw ) { - account_name from; - account_name receiver; - asset unstake_net_quantity; - asset unstake_cpu_quantity; - uint64_t unstake_storage_bytes; - - EOSLIB_SERIALIZE( undelegatebw, (from)(receiver)(unstake_net_quantity)(unstake_cpu_quantity)(unstake_storage_bytes) ) - }; - - ACTION( SystemAccount, refund ) { - account_name owner; - - EOSLIB_SERIALIZE( refund, (owner) ) - }; - - static void on( const delegatebw& del ) { - eosio_assert( del.stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); - eosio_assert( del.stake_net_quantity.amount >= 0, "must stake a positive amount" ); - eosio_assert( del.stake_storage_quantity.amount >= 0, "must stake a positive amount" ); - - asset total_stake = del.stake_cpu_quantity + del.stake_net_quantity + del.stake_storage_quantity; - eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); - - require_auth( del.from ); - - //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - int64_t storage_bytes = 0; - if ( 0 < del.stake_storage_quantity.amount ) { - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); - eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); - eosio::token::stats stats_tbl(N(eosio.token), sym); - const auto& st = stats_tbl.get(sym); - const eosio::asset token_supply = st.supply; - - //make sure that there is no posibility of overflow here - int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - * int64_t(parameters.storage_reserve_ratio) * del.stake_storage_quantity - / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - - storage_bytes = ( int64_t(parameters.max_storage_size) - int64_t(parameters.total_storage_bytes_reserved) - storage_bytes_estimated ) - * int64_t(parameters.storage_reserve_ratio) * del.stake_storage_quantity - / ( token_supply - del.stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; - - eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); - - parameters.total_storage_bytes_reserved += uint64_t(storage_bytes); - parameters.total_storage_stake += del.stake_storage_quantity; - global_state_singleton::set(parameters); - } - - del_bandwidth_table del_tbl( SystemAccount, del.from ); - auto itr = del_tbl.find( del.receiver ); - if( itr == del_tbl.end() ) { - del_tbl.emplace( del.from, [&]( auto& dbo ){ - dbo.from = del.from; - dbo.to = del.receiver; - dbo.net_weight = del.stake_net_quantity; - dbo.cpu_weight = del.stake_cpu_quantity; - dbo.storage_stake = del.stake_storage_quantity; - dbo.storage_bytes = uint64_t(storage_bytes); - }); - } - else { - del_tbl.modify( itr, del.from, [&]( auto& dbo ){ - dbo.net_weight += del.stake_net_quantity; - dbo.cpu_weight += del.stake_cpu_quantity; - dbo.storage_stake += del.stake_storage_quantity; - dbo.storage_bytes += uint64_t(storage_bytes); - }); - } - - total_resources_table totals_tbl( SystemAccount, del.receiver ); - auto tot_itr = totals_tbl.find( del.receiver ); - if( tot_itr == totals_tbl.end() ) { - tot_itr = totals_tbl.emplace( del.from, [&]( auto& tot ) { - tot.owner = del.receiver; - tot.net_weight = del.stake_net_quantity; - tot.cpu_weight = del.stake_cpu_quantity; - tot.storage_stake = del.stake_storage_quantity; - tot.storage_bytes = uint64_t(storage_bytes); - }); - } else { - totals_tbl.modify( tot_itr, del.from == del.receiver ? del.from : 0, [&]( auto& tot ) { - tot.net_weight += del.stake_net_quantity; - tot.cpu_weight += del.stake_cpu_quantity; - tot.storage_stake += del.stake_storage_quantity; - tot.storage_bytes += uint64_t(storage_bytes); - }); - } - - //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); - - eosio::inline_transfer(eosio::permission_level{del.from,N(active)}, N(eosio.token), - { del.from, N(eosio), total_stake, std::string("stake bandwidth") } ); - - if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { - voting::increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); - } - - } // delegatebw - - static void on( account_name receiver, const undelegatebw& del ) { - eosio_assert( del.unstake_cpu_quantity.amount >= 0, "must unstake a positive amount" ); - eosio_assert( del.unstake_net_quantity.amount >= 0, "must unstake a positive amount" ); - - require_auth( del.from ); - - //eosio_assert( is_account( del.receiver ), "can only delegate resources to an existing account" ); - - del_bandwidth_table del_tbl( SystemAccount, del.from ); - const auto& dbw = del_tbl.get( del.receiver ); - eosio_assert( dbw.net_weight >= del.unstake_net_quantity, "insufficient staked net bandwidth" ); - eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); - eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); - - eosio::asset storage_stake_decrease(0, S(4,EOS)); - if ( 0 < del.unstake_storage_bytes ) { - storage_stake_decrease = 0 < dbw.storage_bytes ? - dbw.storage_stake * int64_t(del.unstake_storage_bytes) / int64_t(dbw.storage_bytes) - : eosio::asset(0, S(4,EOS)); - - auto parameters = global_state_singleton::get(); - parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; - parameters.total_storage_stake -= storage_stake_decrease; - global_state_singleton::set( parameters ); - } - - eosio::asset total_refund = del.unstake_cpu_quantity + del.unstake_net_quantity + storage_stake_decrease; - - eosio_assert( total_refund.amount > 0, "must unstake a positive amount" ); - - del_tbl.modify( dbw, del.from, [&]( auto& dbo ){ - dbo.net_weight -= del.unstake_net_quantity; - dbo.cpu_weight -= del.unstake_cpu_quantity; - dbo.storage_stake -= storage_stake_decrease; - dbo.storage_bytes -= del.unstake_storage_bytes; - }); - - total_resources_table totals_tbl( SystemAccount, del.receiver ); - const auto& totals = totals_tbl.get( del.receiver ); - totals_tbl.modify( totals, 0, [&]( auto& tot ) { - tot.net_weight -= del.unstake_net_quantity; - tot.cpu_weight -= del.unstake_cpu_quantity; - tot.storage_stake -= storage_stake_decrease; - tot.storage_bytes -= del.unstake_storage_bytes; - }); - - //set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity ); - - refunds_table refunds_tbl( SystemAccount, del.from ); - //create refund request - auto req = refunds_tbl.find( del.from ); - if ( req != refunds_tbl.end() ) { - refunds_tbl.modify( req, 0, [&]( refund_request& r ) { - r.amount += del.unstake_net_quantity + del.unstake_cpu_quantity + storage_stake_decrease; - r.request_time = now(); - }); - } else { - refunds_tbl.emplace( del.from, [&]( refund_request& r ) { - r.owner = del.from; - r.amount = del.unstake_net_quantity + del.unstake_cpu_quantity + storage_stake_decrease; - r.request_time = now(); - }); - } - //create or replace deferred transaction - const auto self = receiver; //current_receiver(); - refund act; - act.owner = del.from; - transaction out( now() + refund_delay + refund_expiration_time ); - out.actions.emplace_back( permission_level{ del.from, N(active) }, self, N(refund), act ); - out.delay_sec = refund_delay; - out.send( del.from, receiver ); - - if ( asset(0) < del.unstake_net_quantity + del.unstake_cpu_quantity ) { - voting::decrease_voting_power( del.from, del.unstake_net_quantity + del.unstake_cpu_quantity ); - } - - } // undelegatebw - - static void on( const refund& r ) { - require_auth( r.owner ); - - refunds_table refunds_tbl( SystemAccount, r.owner ); - auto req = refunds_tbl.find( r.owner ); - eosio_assert( req != refunds_tbl.end(), "refund request not found" ); - eosio_assert( req->request_time + refund_delay <= now(), "refund is not available yet" ); - // Until now() becomes NOW, the fact that now() is the timestamp of the previous block could in theory - // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many - // consecutive missed blocks. - - eosio::inline_transfer( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), - { N(eosio), req->owner, req->amount, std::string("unstake") }); - - refunds_tbl.erase( req ); - } - }; -} diff --git a/eosio.system.hpp b/eosio.system.hpp index eeed12b9..f8037fa4 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,14 +4,22 @@ */ #pragma once -#include "delegate_bandwidth.hpp" #include "native.hpp" +#include +#include #include -#include +#include +#include + +#include namespace eosiosystem { + using eosio::asset; + using eosio::indexed_by; + using eosio::const_mem_fun; + struct block_header { checksum256 previous; time timestamp; @@ -26,176 +34,103 @@ namespace eosiosystem { (producer)(schedule_version)(new_producers)) }; - template - class contract : eosio::contract, public delegate_bandwidth, public native { - public: - - contract(account_name self = SystemAccount): - eosio::contract(self) - { - } - - using voting::on; - using delegate_bandwidth::on; - using native::on; - using pe = voting; - using db = delegate_bandwidth; - using producers_table = typename pe::producers_table; - using global_state_singleton = typename voting::global_state_singleton; - static const uint32_t max_inflation_rate = common::max_inflation_rate; - static const uint32_t seconds_per_day = common::seconds_per_day; - static const uint32_t num_of_payed_producers = 121; - - ACTION( SystemAccount, nonce ) { - eosio::string value; - - EOSLIB_SERIALIZE( nonce, (value) ) - }; - - static void on( const nonce& ) { - } - - static bool update_cycle(time block_time) { - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); - if (parameters.first_block_time_in_cycle == 0) { - // This is the first time onblock is called in the blockchain. - parameters.last_bucket_fill_time = block_time; - global_state_singleton::set(parameters); - voting::update_elected_producers(block_time); - return true; - } - - static const uint32_t slots_per_cycle = parameters.blocks_per_cycle; - const uint32_t time_slots = block_time - parameters.first_block_time_in_cycle; - if (time_slots >= slots_per_cycle) { - time beginning_of_cycle = block_time - (time_slots % slots_per_cycle); - voting::update_elected_producers(beginning_of_cycle); - return true; - } - - return false; - } - - ACTION(SystemAccount, onblock) { - block_header header; - - EOSLIB_SERIALIZE(onblock, (header)) - }; - - static void on(const onblock& ob) { - // update parameters if it's a new cycle - update_cycle(ob.header.timestamp); - - producers_table producers_tbl(SystemAccount, SystemAccount); - account_name producer = ob.header.producer; - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); - const asset block_payment = parameters.payment_per_block; - auto prod = producers_tbl.find(producer); - if ( prod != producers_tbl.end() ) { - producers_tbl.modify( prod, 0, [&](auto& p) { - p.per_block_payments += block_payment; - p.last_produced_block_time = ob.header.timestamp; - }); - } - - const uint32_t num_of_payments = ob.header.timestamp - parameters.last_bucket_fill_time; - const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; - parameters.last_bucket_fill_time = ob.header.timestamp; - parameters.eos_bucket += to_eos_bucket; - global_state_singleton::set(parameters); - } - - ACTION(SystemAccount, claimrewards) { - account_name owner; - - EOSLIB_SERIALIZE(claimrewards, (owner)) - }; - - static void on(const claimrewards& cr) { - require_auth(cr.owner); - eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); - producers_table producers_tbl(SystemAccount, SystemAccount); - auto prod = producers_tbl.find(cr.owner); - eosio_assert(prod != producers_tbl.end(), "account name is not in producer list"); - eosio_assert(prod->active(), "producer is not active"); // QUESTION: Why do we want to prevent inactive producers from claiming their earned rewards? - if( prod->last_rewards_claim > 0 ) { - eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); - } - - eosio::asset rewards = prod->per_block_payments; - auto idx = producers_tbl.template get_index(); - auto itr = --idx.end(); - - bool is_among_payed_producers = false; - uint128_t total_producer_votes = 0; - uint32_t n = 0; - while( n < num_of_payed_producers ) { - if( !is_among_payed_producers ) { - if( itr->owner == cr.owner ) - is_among_payed_producers = true; - } - if( itr->active() ) { - total_producer_votes += itr->total_votes; - ++n; - } - if( itr == idx.begin() ) { - break; - } - --itr; - } - - if (is_among_payed_producers && total_producer_votes > 0) { - if( global_state_singleton::exists() ) { - auto parameters = global_state_singleton::get(); - // This will be improved in the future when total_votes becomes a double type. - auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * uint64_t(parameters.eos_bucket.amount) ) / total_producer_votes ) ); - rewards += share_of_eos_bucket; - parameters.eos_bucket -= share_of_eos_bucket; - global_state_singleton::set(parameters); - } - } - - eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); - - producers_tbl.modify( prod, 0, [&](auto& p) { - p.last_rewards_claim = now(); - p.per_block_payments.amount = 0; - }); - - eosio::inline_transfer(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), - { N(eosio), cr.owner, rewards, std::string("producer claiming rewards") } ); - } - - static void apply( account_name receiver, account_name code, action_name act ) { - if( !eosio::dispatch::delegatebw, - typename delegate_bandwidth::refund, - typename voting::regproxy, - typename voting::unregproxy, - typename voting::regproducer, - typename voting::unregprod, - typename voting::voteproducer, - onblock, - claimrewards, - typename native::newaccount, - typename native::updateauth, - typename native::deleteauth, - typename native::linkauth, - typename native::unlinkauth, - typename native::postrecovery, - typename native::passrecovery, - typename native::vetorecovery, - typename native::onerror, - typename native::canceldelay, - nonce>( code, act) ) { - //TODO: Small hack until we refactor eosio.system like eosio.token - using undelegatebw = typename delegate_bandwidth::undelegatebw; - if(code == undelegatebw::get_account() && act == undelegatebw::get_name() ){ - contract().on( receiver, eosio::unpack_action_data() ); - } - } - } /// apply + struct eosio_parameters : eosio::blockchain_parameters { + uint64_t max_storage_size = 10 * 1024 * 1024; + uint32_t percent_of_max_inflation_rate = 0; + uint32_t storage_reserve_ratio = 1000; // ratio * 1000 + + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_storage_size)(percent_of_max_inflation_rate)(storage_reserve_ratio) ) + }; + + struct eosio_global_state : eosio_parameters { + uint64_t total_storage_bytes_reserved = 0; + eosio::asset total_storage_stake; + eosio::asset payment_per_block; + eosio::asset payment_to_eos_bucket; + time first_block_time_in_cycle = 0; + uint32_t blocks_per_cycle = 0; + time last_bucket_fill_time = 0; + eosio::asset eos_bucket; + + EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) + (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) + (last_bucket_fill_time)(eos_bucket) ) + }; + + struct producer_info { + account_name owner; + uint128_t total_votes = 0; + eosio_parameters prefs; + eosio::bytes packed_key; /// a packed public key object + eosio::asset per_block_payments; + time last_rewards_claim = 0; + time time_became_active = 0; + time last_produced_block_time = 0; + + uint64_t primary_key()const { return owner; } + uint128_t by_votes()const { return total_votes; } + bool active() const { return packed_key.size() == sizeof(public_key); } + + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) + (per_block_payments)(last_rewards_claim) + (time_became_active)(last_produced_block_time) ) + }; + + typedef eosio::multi_index< N(producerinfo), producer_info, + indexed_by > + > producers_table; + + //typedef eosio::singleton global_state_singleton; + + static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation + static constexpr uint32_t seconds_per_day = 24 * 3600; + + class system_contract : public native, private eosio::contract { + public: + + using eosio::contract::contract; + + // functions defined in delegate_bandwidth.cpp + void delegatebw( const account_name from, const account_name receiver, + const asset stake_net_quantity, const asset stake_cpu_quantity, + const asset stake_storage_quantity ); + + void undelegatebw( const account_name from, const account_name receiver, + const asset unstake_net_quantity, const asset unstake_cpu_quantity, + const uint64_t unstake_storage_bytes ); + + void refund( const account_name owner ); + + // functions defined in voting.cpp + + void regproducer( const account_name producer, const bytes& producer_key, const eosio_parameters& prefs ); + + void unregprod( const account_name producer ); + + void increase_voting_power( account_name acnt, const eosio::asset& amount ); + + void decrease_voting_power( account_name acnt, const eosio::asset& amount ); + + eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate); + + void update_elected_producers(time cycle_time); + + void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); + + void regproxy( const account_name proxy ); + + void unregproxy( const account_name proxy ); + + void nonce( const std::string& value ) {} + + // functions defined in producer_pay.cpp + + bool update_cycle( time block_time ); + + void onblock( const block_header& header ); + + void claimrewards( const account_name& owner ); + }; } /// eosiosystem diff --git a/native.hpp b/native.hpp index 43e25c5b..fb14cd04 100644 --- a/native.hpp +++ b/native.hpp @@ -4,13 +4,15 @@ */ #pragma once +#include +#include #include namespace eosiosystem { + using eosio::permission_level; + using eosio::public_key; typedef std::vector bytes; - typedef std::string type_name; - typedef std::string field_name; struct permission_level_weight { permission_level permission; @@ -34,112 +36,42 @@ namespace eosiosystem { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) }; - template class native { public: - ACTION( SystemAccount, newaccount ) { - account_name creator; - account_name name; - authority owner; - authority active; - authority recovery; - EOSLIB_SERIALIZE( newaccount, (creator)(name)(owner)(active)(recovery) ) - }; + static void newaccount( account_name creator, + account_name name, + const authority& owner, + const authority& active, + const authority& recovery ) {} - static void on( const newaccount& ) { - } + static void updateauth( account_name account, + permission_name permission, + permission_name parent, + const authority& data ) {} - ACTION( SystemAccount, updateauth ) { - account_name account; - permission_name permission; - permission_name parent; - authority data; + static void deleteauth( account_name account, permission_name permission ) {} - EOSLIB_SERIALIZE( updateauth, (account)(permission)(parent)(data) ) - }; + static void linkauth( account_name account, + account_name code, + action_name type, + permission_name requirement ) {} - static void on( const updateauth& ) { - } + static void unlinkauth( account_name account, + account_name code, + action_name type ) {} - ACTION( SystemAccount, deleteauth ) { - account_name account; - permission_name permission; + static void postrecovery( account_name account, + const authority& data, + const std::string& memo ) {} - EOSLIB_SERIALIZE( deleteauth, (account)(permission) ) - }; + static void passrecovery( account_name account ) {} - static void on( const deleteauth& ) { - } + static void vetorecovery( account_name account ) {} - ACTION( SystemAccount, linkauth ) { - account_name account; - account_name code; - action_name type; - permission_name requirement; + static void onerror( const bytes& ) {} - EOSLIB_SERIALIZE( linkauth, (account)(code)(type)(requirement) ) - }; - - static void on( const linkauth& ) { - } - - ACTION( SystemAccount, unlinkauth ) { - account_name account; - account_name code; - action_name type; - - EOSLIB_SERIALIZE( unlinkauth, (account)(code)(type) ) - }; - - static void on( const unlinkauth& ) { - } - - ACTION( SystemAccount, postrecovery ) { - account_name account; - authority data; - std::string memo; - - EOSLIB_SERIALIZE( postrecovery, (account)(data)(memo) ) - }; - - static void on( const postrecovery& ) { - } - - ACTION( SystemAccount, passrecovery ) { - account_name account; - - EOSLIB_SERIALIZE( passrecovery, (account) ) - }; - - static void on( const passrecovery& ) { - } - - ACTION( SystemAccount, vetorecovery ) { - account_name account; - - EOSLIB_SERIALIZE( vetorecovery, (account) ) - }; - - static void on( const vetorecovery& ) { - } - - struct onerror: eosio::action_meta, bytes { - EOSLIB_SERIALIZE_DERIVED( onerror, bytes, BOOST_PP_SEQ_NIL ) - }; - - static void on( const onerror& ) { - } - - ACTION( SystemAccount, canceldelay ) { - permission_level canceling_auth; - transaction_id_type trx_id; - - EOSLIB_SERIALIZE( canceldelay, (canceling_auth)(trx_id) ) - }; - - static void on( const canceldelay& ) { - } + static void canceldelay( permission_level canceling_auth, transaction_id_type trx_id ) {} }; } diff --git a/producer_pay.cpp b/producer_pay.cpp new file mode 100644 index 00000000..6184a108 --- /dev/null +++ b/producer_pay.cpp @@ -0,0 +1,118 @@ +#include "eosio.system.hpp" + +#include + +namespace eosiosystem { + +static const uint32_t num_of_payed_producers = 121; + +bool system_contract::update_cycle(time block_time) { + /* XXX + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : get_default_parameters(); + if (parameters.first_block_time_in_cycle == 0) { + // This is the first time onblock is called in the blockchain. + parameters.last_bucket_fill_time = block_time; + global_state_singleton::set(parameters); + update_elected_producers(block_time); + return true; + } + + static const uint32_t slots_per_cycle = parameters.blocks_per_cycle; + const uint32_t time_slots = block_time - parameters.first_block_time_in_cycle; + if (time_slots >= slots_per_cycle) { + time beginning_of_cycle = block_time - (time_slots % slots_per_cycle); + update_elected_producers(beginning_of_cycle); + return true; + } + */ + return false; +} + +void system_contract::onblock(const block_header& header) { + // update parameters if it's a new cycle + update_cycle(header.timestamp); + + producers_table producers_tbl( _self, _self ); + account_name producer = header.producer; + /* XXX + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : get_default_parameters(); + // const system_token_type block_payment = parameters.payment_per_block; + const asset block_payment = parameters.payment_per_block; + auto prod = producers_tbl.find(producer); + if ( prod != producers_tbl.end() ) { + producers_tbl.modify( prod, 0, [&](auto& p) { + p.per_block_payments += block_payment; + p.last_produced_block_time = header.timestamp; + }); + } + + const uint32_t num_of_payments = header.timestamp - parameters.last_bucket_fill_time; + // const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; + const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; + parameters.last_bucket_fill_time = header.timestamp; + parameters.eos_bucket += to_eos_bucket; + global_state_singleton::set(parameters); + */ +} + +void system_contract::claimrewards(const account_name& owner) { + require_auth(owner); + eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); + producers_table producers_tbl( _self, _self ); + auto prod = producers_tbl.find(owner); + eosio_assert(prod != producers_tbl.end(), "account name is not in producer list"); + eosio_assert(prod->active(), "producer is not active"); // QUESTION: Why do we want to prevent inactive producers from claiming their earned rewards? + if( prod->last_rewards_claim > 0 ) { + eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); + } + // system_token_type rewards = prod->per_block_payments; + eosio::asset rewards = prod->per_block_payments; + auto idx = producers_tbl.template get_index(); + auto itr = --idx.end(); + + bool is_among_payed_producers = false; + uint128_t total_producer_votes = 0; + uint32_t n = 0; + while( n < num_of_payed_producers ) { + if( !is_among_payed_producers ) { + if( itr->owner == owner ) + is_among_payed_producers = true; + } + if( itr->active() ) { + total_producer_votes += itr->total_votes; + ++n; + } + if( itr == idx.begin() ) { + break; + } + --itr; + } + + if (is_among_payed_producers && total_producer_votes > 0) { + /* + if( global_state_singleton::exists() ) { + auto parameters = global_state_singleton::get(); + // auto share_of_eos_bucket = system_token_type( static_cast( (prod->total_votes * parameters.eos_bucket.quantity) / total_producer_votes ) ); // This will be improved in the future when total_votes becomes a double type. + auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * parameters.eos_bucket.amount) / total_producer_votes ) ); + rewards += share_of_eos_bucket; + parameters.eos_bucket -= share_of_eos_bucket; + global_state_singleton::set(parameters); + } + */ + } + + // eosio_assert( rewards > system_token_type(), "no rewards available to claim" ); + eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); + + producers_tbl.modify( prod, 0, [&](auto& p) { + p.last_rewards_claim = now(); + p.per_block_payments.amount = 0; + }); + + eosio::inline_transfer(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), + { N(eosio), owner, rewards, std::string("producer claiming rewards") } ); +} + +} //namespace eosiosystem diff --git a/voting.cpp b/voting.cpp new file mode 100644 index 00000000..8285bc75 --- /dev/null +++ b/voting.cpp @@ -0,0 +1,501 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#include "eosio.system.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +namespace eosiosystem { + using eosio::indexed_by; + using eosio::const_mem_fun; + using eosio::bytes; + using eosio::print; + using eosio::singleton; + using eosio::transaction; + + + static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year + static constexpr uint32_t blocks_per_producer = 12; + + struct voter_info { + account_name owner = 0; + account_name proxy = 0; + time last_update = 0; + uint32_t is_proxy = 0; + eosio::asset staked; + eosio::asset unstaking; + eosio::asset unstake_per_week; + uint128_t proxied_votes = 0; + std::vector producers; + uint32_t deferred_trx_id = 0; + time last_unstake_time = 0; //uint32 + + uint64_t primary_key()const { return owner; } + + EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) + }; + + typedef eosio::multi_index< N(voters), voter_info> voters_table; + + /** + * This method will create a producer_config and producer_info object for 'producer' + * + * @pre producer is not already registered + * @pre producer to register is an account + * @pre authority of producer to register + * + */ + void system_contract::regproducer( const account_name producer, const bytes& producer_key, const eosio_parameters& prefs ) { + require_auth( producer ); + + producers_table producers_tbl( _self, _self ); + auto prod = producers_tbl.find( producer ); + + if ( prod != producers_tbl.end() ) { + producers_tbl.modify( prod, producer, [&]( producer_info& info ){ + info.prefs = prefs; + info.packed_key = producer_key; + }); + } else { + producers_tbl.emplace( producer, [&]( producer_info& info ){ + info.owner = producer; + info.total_votes = 0; + info.prefs = prefs; + info.packed_key = producer_key; + }); + } + } + + void system_contract::unregprod( const account_name producer ) { + require_auth( producer ); + + producers_table producers_tbl( _self, _self ); + auto prod = producers_tbl.find( producer ); + eosio_assert( prod != producers_tbl.end(), "producer not found" ); + + producers_tbl.modify( prod, 0, [&]( producer_info& info ){ + info.packed_key.clear(); + }); + } + + void system_contract::increase_voting_power( account_name acnt, const eosio::asset& amount ) { + voters_table voters_tbl( _self, _self ); + auto voter = voters_tbl.find( acnt ); + + eosio_assert( 0 <= amount.amount, "negative asset" ); + + if( voter == voters_tbl.end() ) { + voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { + a.owner = acnt; + a.last_update = now(); + a.staked = amount; + }); + } else { + voters_tbl.modify( voter, 0, [&]( auto& av ) { + av.last_update = now(); + av.staked += amount; + }); + } + + const std::vector* producers = nullptr; + if ( voter->proxy ) { + auto proxy = voters_tbl.find( voter->proxy ); + eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += uint64_t(amount.amount); } ); + if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers + producers = &proxy->producers; + } + } else { + producers = &voter->producers; + } + + if ( producers ) { + producers_table producers_tbl( _self, _self ); + for( auto p : *producers ) { + auto prod = producers_tbl.find( p ); + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& v ) { + v.total_votes += uint64_t(amount.amount); + }); + } + } + } + + void system_contract::decrease_voting_power( account_name acnt, const eosio::asset& amount ) { + require_auth( acnt ); + voters_table voters_tbl( _self, _self ); + auto voter = voters_tbl.find( acnt ); + eosio_assert( voter != voters_tbl.end(), "stake not found" ); + + if ( 0 < amount.amount ) { + eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); + voters_tbl.modify( voter, 0, [&](voter_info& a) { + a.staked -= amount; + a.last_update = now(); + }); + + const std::vector* producers = nullptr; + if ( voter->proxy ) { + auto proxy = voters_tbl.find( voter->proxy ); + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= uint64_t(amount.amount); } ); + if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers + producers = &proxy->producers; + } + } else { + producers = &voter->producers; + } + + if ( producers ) { + producers_table producers_tbl( _self, _self ); + for( auto p : *producers ) { + auto prod = producers_tbl.find( p ); + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& v ) { + v.total_votes -= uint64_t(amount.amount); + }); + } + } + } else { + if (voter->deferred_trx_id) { + //XXX cancel_deferred_transaction(voter->deferred_trx_id); + } + voters_tbl.modify( voter, 0, [&](voter_info& a) { + a.staked += a.unstaking; + a.unstaking.amount = 0; + a.unstake_per_week.amount = 0; + a.deferred_trx_id = 0; + a.last_update = now(); + }); + } + } + + eosio::asset system_contract::payment_per_block(uint32_t percent_of_max_inflation_rate) { + eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); + eosio::token::stats stats_tbl(N(eosio.token), sym); + const auto& st = stats_tbl.get(sym); + const eosio::asset token_supply = st.supply; + const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); + double continuous_rate = std::log1p(annual_rate); + int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); + return eosio::asset(payment, S(4,EOS)); + } + + void system_contract::update_elected_producers(time cycle_time) { + producers_table producers_tbl( _self, _self ); + auto idx = producers_tbl.template get_index(); + + std::array base_per_transaction_net_usage; + std::array base_per_transaction_cpu_usage; + std::array base_per_action_cpu_usage; + std::array base_setcode_cpu_usage; + std::array per_signature_cpu_usage; + std::array per_lock_net_usage; + std::array context_free_discount_cpu_usage_num; + std::array context_free_discount_cpu_usage_den; + std::array max_transaction_cpu_usage; + std::array max_transaction_net_usage; + std::array max_block_cpu_usage; + std::array target_block_cpu_usage_pct; + std::array max_block_net_usage; + std::array target_block_net_usage_pct; + std::array max_transaction_lifetime; + std::array max_authority_depth; + std::array max_transaction_exec_time; + std::array max_inline_depth; + std::array max_inline_action_size; + std::array max_generated_transaction_count; + std::array max_transaction_delay; + std::array percent_of_max_inflation_rate; + std::array storage_reserve_ratio; + + eosio::producer_schedule schedule; + schedule.producers.reserve(21); + size_t n = 0; + for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { + if ( it->active() ) { + schedule.producers.emplace_back(); + schedule.producers.back().producer_name = it->owner; + eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); + std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data.data() ); + + base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; + base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; + base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; + base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; + per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; + per_lock_net_usage[n] = it->prefs.per_lock_net_usage; + context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; + context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; + max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; + max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; + max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; + target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; + max_block_net_usage[n] = it->prefs.max_block_net_usage; + target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; + max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; + max_authority_depth[n] = it->prefs.max_authority_depth; + max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; + max_inline_depth[n] = it->prefs.max_inline_depth; + max_inline_action_size[n] = it->prefs.max_inline_action_size; + max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; + max_transaction_delay[n] = it->prefs.max_transaction_delay; + + storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; + percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; + ++n; + } + } + if ( n == 0 ) { //no active producers with votes > 0 + return; + } + if ( 1 < n ) { + std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); + std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); + std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); + std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); + std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); + std::sort( per_lock_net_usage.begin(), per_lock_net_usage.begin()+n ); + std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); + std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); + std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); + std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); + std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); + std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); + std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); + std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); + std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); + std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); + std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); + std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); + std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); + std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); + std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); + std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); + std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); + } + + // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp + bytes packed_schedule = pack(schedule); + set_active_producers( packed_schedule.data(), packed_schedule.size() ); + size_t median = n/2; + /* XXX + auto parameters = global_state_singleton::exists() ? global_state_singleton::get() + : get_default_parameters(); + + parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; + parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; + parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; + parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; + parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; + parameters.per_lock_net_usage = per_lock_net_usage[median]; + parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; + parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; + parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; + parameters.max_transaction_net_usage = max_transaction_net_usage[median]; + parameters.max_block_cpu_usage = max_block_cpu_usage[median]; + parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; + parameters.max_block_net_usage = max_block_net_usage[median]; + parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; + parameters.max_transaction_lifetime = max_transaction_lifetime[median]; + parameters.max_transaction_exec_time = max_transaction_exec_time[median]; + parameters.max_authority_depth = max_authority_depth[median]; + parameters.max_inline_depth = max_inline_depth[median]; + parameters.max_inline_action_size = max_inline_action_size[median]; + parameters.max_generated_transaction_count = max_generated_transaction_count[median]; + parameters.max_transaction_delay = max_transaction_delay[median]; + parameters.storage_reserve_ratio = storage_reserve_ratio[median]; + parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; + + // not voted on + parameters.first_block_time_in_cycle = cycle_time; + + // derived parameters + auto half_of_percentage = parameters.percent_of_max_inflation_rate / 2; + auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; + parameters.payment_per_block = payment_per_block(half_of_percentage); + parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); + parameters.blocks_per_cycle = blocks_per_producer * schedule.producers.size(); + + if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { + parameters.max_storage_size = parameters.total_storage_bytes_reserved; + } + + auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); + eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), + { N(eosio), issue_quantity, std::string("producer pay") }); + + set_blockchain_parameters(parameters); + global_state_singleton::set(parameters); + */ + } + + /** + * @pre producers must be sorted from lowest to highest + * @pre if proxy is set then no producers can be voted for + * @pre every listed producer or proxy must have been previously registered + * @pre voter must authorize this action + * @pre voter must have previously staked some EOS for voting + */ + void system_contract::voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ) { + require_auth( voter ); + + //validate input + if ( proxy ) { + eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" ); + require_recipient( proxy ); + } else { + eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" ); + for( size_t i = 1; i < producers.size(); ++i ) { + eosio_assert( producers[i-1] < producers[i], "producer votes must be unique and sorted" ); + } + } + + voters_table voters_tbl( _self, _self ); + auto voter_it = voters_tbl.find( voter ); + + eosio_assert( 0 <= voter_it->staked.amount, "negative stake" ); + eosio_assert( voter_it != voters_tbl.end() && ( 0 < voter_it->staked.amount || ( voter_it->is_proxy && 0 < voter_it->proxied_votes ) ), "no stake to vote" ); + if ( voter_it->is_proxy ) { + eosio_assert( proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); + } + + //find old producers, update old proxy if needed + const std::vector* old_producers = nullptr; + if( voter_it->proxy ) { + if ( voter_it->proxy == proxy ) { + return; // nothing changed + } + auto old_proxy = voters_tbl.find( voter_it->proxy ); + eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption + voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= uint64_t(voter_it->staked.amount); } ); + if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) + old_producers = &old_proxy->producers; + } + } else { + old_producers = &voter_it->producers; + } + + //find new producers, update new proxy if needed + const std::vector* new_producers = nullptr; + if ( proxy ) { + auto new_proxy = voters_tbl.find( proxy ); + eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); + voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += uint64_t(voter_it->staked.amount); } ); + new_producers = &new_proxy->producers; + } else { + new_producers = &producers; + } + + producers_table producers_tbl( _self, _self ); + uint128_t votes = uint64_t(voter_it->staked.amount); + if ( voter_it->is_proxy ) { + votes += voter_it->proxied_votes; + } + + if ( old_producers ) { //old_producers == nullptr if proxy has stopped being a proxy and votes were taken back from the producers at that moment + //revoke votes only from no longer elected + std::vector revoked( old_producers->size() ); + auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); + for ( auto it = revoked.begin(); it != end_it; ++it ) { + auto prod = producers_tbl.find( *it ); + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); + } + } + + //update newly elected + std::vector elected( new_producers->size() ); + auto end_it = elected.begin(); + if( old_producers ) { + end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); + } else { + end_it = std::copy( new_producers->begin(), new_producers->end(), elected.begin() ); + } + for ( auto it = elected.begin(); it != end_it; ++it ) { + auto prod = producers_tbl.find( *it ); + eosio_assert( prod != producers_tbl.end(), "producer is not registered" ); + if ( proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers + eosio_assert( prod->active(), "producer is not currently registered" ); + } + producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); + } + + // save new values to the account itself + voters_tbl.modify( voter_it, 0, [&](voter_info& a) { + a.proxy = proxy; + a.last_update = now(); + a.producers = producers; + }); + } + + void system_contract::regproxy( const account_name proxy ) { + require_auth( proxy ); + + voters_table voters_tbl( _self, _self ); + auto proxy_it = voters_tbl.find( proxy ); + if ( proxy_it != voters_tbl.end() ) { + eosio_assert( proxy_it->is_proxy == 0, "account is already a proxy" ); + eosio_assert( proxy_it->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); + voters_tbl.modify( proxy_it, 0, [&](voter_info& a) { + a.is_proxy = 1; + a.last_update = now(); + //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value + }); + if ( 0 < proxy_it->proxied_votes ) { + producers_table producers_tbl( _self, _self ); + for ( auto p : proxy_it->producers ) { + auto prod = producers_tbl.find( p ); + eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += proxy_it->proxied_votes; }); + } + } + } else { + voters_tbl.emplace( proxy, [&]( voter_info& a ) { + a.owner = proxy; + a.last_update = now(); + a.proxy = 0; + a.is_proxy = 1; + a.proxied_votes = 0; + a.staked.amount = 0; + }); + } + } + + void system_contract::unregproxy( const account_name proxy ) { + require_auth( proxy ); + + voters_table voters_tbl( _self, _self ); + auto proxy_it = voters_tbl.find( proxy ); + eosio_assert( proxy_it != voters_tbl.end(), "proxy not found" ); + eosio_assert( proxy_it->is_proxy == 1, "account is not a proxy" ); + + voters_tbl.modify( proxy_it, 0, [&](voter_info& a) { + a.is_proxy = 0; + a.last_update = now(); + //a.proxied_votes should be kept in order to be able to reenable this proxy in the future + }); + + if ( 0 < proxy_it->proxied_votes ) { + producers_table producers_tbl( _self, _self ); + for ( auto p : proxy_it->producers ) { + auto prod_it = producers_tbl.find( p ); + eosio_assert( prod_it != producers_tbl.end(), "never existed producer" ); //data corruption + producers_tbl.modify( prod_it, 0, [&]( auto& pi ) { pi.total_votes -= proxy_it->proxied_votes; }); + } + } + } + +} diff --git a/voting.hpp b/voting.hpp deleted file mode 100644 index e5a5fb39..00000000 --- a/voting.hpp +++ /dev/null @@ -1,567 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -#include "common.hpp" - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace eosiosystem { - using eosio::indexed_by; - using eosio::const_mem_fun; - using eosio::bytes; - using eosio::print; - using eosio::singleton; - using eosio::transaction; - - - template - class voting { - public: - static constexpr account_name system_account = SystemAccount; - using eosio_parameters = typename common::eosio_parameters; - using global_state_singleton = typename common::global_state_singleton; - - static constexpr uint32_t max_inflation_rate = common::max_inflation_rate; - static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year - - struct producer_info { - account_name owner; - uint128_t total_votes = 0; - eosio_parameters prefs; - eosio::bytes packed_key; /// a packed public key object - eosio::asset per_block_payments; - time last_rewards_claim = 0; - time time_became_active = 0; - time last_produced_block_time = 0; - - uint64_t primary_key()const { return owner; } - uint128_t by_votes()const { return total_votes; } - bool active() const { return packed_key.size() == sizeof(public_key); } - - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) - (per_block_payments)(last_rewards_claim) - (time_became_active)(last_produced_block_time) ) - }; - - typedef eosio::multi_index< N(producerinfo), producer_info, - indexed_by > - > producers_table; - - - struct voter_info { - account_name owner = 0; - account_name proxy = 0; - time last_update = 0; - uint32_t is_proxy = 0; - eosio::asset staked; - eosio::asset unstaking; - eosio::asset unstake_per_week; - uint128_t proxied_votes = 0; - std::vector producers; - uint32_t deferred_trx_id = 0; - time last_unstake_time = 0; //uint32 - - uint64_t primary_key()const { return owner; } - - EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) - }; - - typedef eosio::multi_index< N(voters), voter_info> voters_table; - - ACTION( SystemAccount, regproducer ) { - account_name producer; - bytes producer_key; - eosio_parameters prefs; - - EOSLIB_SERIALIZE( regproducer, (producer)(producer_key)(prefs) ) - }; - - /** - * This method will create a producer_config and producer_info object for 'producer' - * - * @pre producer is not already registered - * @pre producer to register is an account - * @pre authority of producer to register - * - */ - static void on( const regproducer& reg ) { - require_auth( reg.producer ); - - producers_table producers_tbl( SystemAccount, SystemAccount ); - auto prod = producers_tbl.find( reg.producer ); - - if ( prod != producers_tbl.end() ) { - producers_tbl.modify( prod, reg.producer, [&]( producer_info& info ){ - info.prefs = reg.prefs; - info.packed_key = reg.producer_key; - }); - } else { - producers_tbl.emplace( reg.producer, [&]( producer_info& info ){ - info.owner = reg.producer; - info.total_votes = 0; - info.prefs = reg.prefs; - info.packed_key = reg.producer_key; - }); - } - } - - ACTION( SystemAccount, unregprod ) { - account_name producer; - - EOSLIB_SERIALIZE( unregprod, (producer) ) - }; - - static void on( const unregprod& unreg ) { - require_auth( unreg.producer ); - - producers_table producers_tbl( SystemAccount, SystemAccount ); - auto prod = producers_tbl.find( unreg.producer ); - eosio_assert( prod != producers_tbl.end(), "producer not found" ); - - producers_tbl.modify( prod, 0, [&]( producer_info& info ){ - info.packed_key.clear(); - }); - } - - static void increase_voting_power( account_name acnt, const eosio::asset& amount ) { - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( acnt ); - - eosio_assert( 0 <= amount.amount, "negative asset" ); - - if( voter == voters_tbl.end() ) { - voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { - a.owner = acnt; - a.last_update = now(); - a.staked = amount; - }); - } else { - voters_tbl.modify( voter, 0, [&]( auto& av ) { - av.last_update = now(); - av.staked += amount; - }); - } - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += uint64_t(amount.amount); } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } - - if ( producers ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes += uint64_t(amount.amount); - }); - } - } - } - - static void decrease_voting_power( account_name acnt, const eosio::asset& amount ) { - require_auth( acnt ); - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( acnt ); - eosio_assert( voter != voters_tbl.end(), "stake not found" ); - - if ( 0 < amount.amount ) { - eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked -= amount; - a.last_update = now(); - }); - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= uint64_t(amount.amount); } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } - - if ( producers ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes -= uint64_t(amount.amount); - }); - } - } - } else { - if (voter->deferred_trx_id) { - //XXX cancel_deferred_transaction(voter->deferred_trx_id); - } - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked += a.unstaking; - a.unstaking.amount = 0; - a.unstake_per_week.amount = 0; - a.deferred_trx_id = 0; - a.last_update = now(); - }); - } - } - - static eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate) { - eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); - eosio::token::stats stats_tbl(N(eosio.token), sym); - const auto& st = stats_tbl.get(sym); - const eosio::asset token_supply = st.supply; - const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); - double continuous_rate = std::log1p(annual_rate); - int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); - return eosio::asset(payment, S(4,EOS)); - } - - static void update_elected_producers(time cycle_time) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - auto idx = producers_tbl.template get_index(); - - std::array base_per_transaction_net_usage; - std::array base_per_transaction_cpu_usage; - std::array base_per_action_cpu_usage; - std::array base_setcode_cpu_usage; - std::array per_signature_cpu_usage; - std::array per_lock_net_usage; - std::array context_free_discount_cpu_usage_num; - std::array context_free_discount_cpu_usage_den; - std::array max_transaction_cpu_usage; - std::array max_transaction_net_usage; - std::array max_block_cpu_usage; - std::array target_block_cpu_usage_pct; - std::array max_block_net_usage; - std::array target_block_net_usage_pct; - std::array max_transaction_lifetime; - std::array max_authority_depth; - std::array max_transaction_exec_time; - std::array max_inline_depth; - std::array max_inline_action_size; - std::array max_generated_transaction_count; - std::array max_transaction_delay; - std::array percent_of_max_inflation_rate; - std::array storage_reserve_ratio; - - eosio::producer_schedule schedule; - schedule.producers.reserve(21); - size_t n = 0; - for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { - if ( it->active() ) { - schedule.producers.emplace_back(); - schedule.producers.back().producer_name = it->owner; - eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); - std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data ); - - base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; - base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; - base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; - base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; - per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; - per_lock_net_usage[n] = it->prefs.per_lock_net_usage; - context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; - context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; - max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; - max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; - max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; - target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; - max_block_net_usage[n] = it->prefs.max_block_net_usage; - target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; - max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; - max_authority_depth[n] = it->prefs.max_authority_depth; - max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; - max_inline_depth[n] = it->prefs.max_inline_depth; - max_inline_action_size[n] = it->prefs.max_inline_action_size; - max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; - max_transaction_delay[n] = it->prefs.max_transaction_delay; - - storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; - percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; - ++n; - } - } - if ( n == 0 ) { //no active producers with votes > 0 - return; - } - if ( 1 < n ) { - std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); - std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); - std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); - std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); - std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); - std::sort( per_lock_net_usage.begin(), per_lock_net_usage.begin()+n ); - std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); - std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); - std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); - std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); - std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); - std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); - std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); - std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); - std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); - std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); - std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); - std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); - std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); - std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); - std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); - std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); - std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); - } - - // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp - bytes packed_schedule = pack(schedule); - set_active_producers( packed_schedule.data(), packed_schedule.size() ); - size_t median = n/2; - - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); - - parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; - parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; - parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; - parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; - parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; - parameters.per_lock_net_usage = per_lock_net_usage[median]; - parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; - parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; - parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; - parameters.max_transaction_net_usage = max_transaction_net_usage[median]; - parameters.max_block_cpu_usage = max_block_cpu_usage[median]; - parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; - parameters.max_block_net_usage = max_block_net_usage[median]; - parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; - parameters.max_transaction_lifetime = max_transaction_lifetime[median]; - parameters.max_transaction_exec_time = max_transaction_exec_time[median]; - parameters.max_authority_depth = max_authority_depth[median]; - parameters.max_inline_depth = max_inline_depth[median]; - parameters.max_inline_action_size = max_inline_action_size[median]; - parameters.max_generated_transaction_count = max_generated_transaction_count[median]; - parameters.max_transaction_delay = max_transaction_delay[median]; - parameters.storage_reserve_ratio = storage_reserve_ratio[median]; - parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; - - // not voted on - parameters.first_block_time_in_cycle = cycle_time; - - // derived parameters - auto half_of_percentage = parameters.percent_of_max_inflation_rate / 2; - auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; - parameters.payment_per_block = payment_per_block(half_of_percentage); - parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); - parameters.blocks_per_cycle = common::blocks_per_producer * schedule.producers.size(); - - if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { - parameters.max_storage_size = parameters.total_storage_bytes_reserved; - } - - auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); - eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), - { N(eosio), issue_quantity, std::string("producer pay") }); - - set_blockchain_parameters(parameters); - global_state_singleton::set(parameters); - } - - ACTION( SystemAccount, voteproducer ) { - account_name voter; - account_name proxy; - std::vector producers; - - EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) - }; - - /** - * @pre vp.producers must be sorted from lowest to highest - * @pre if proxy is set then no producers can be voted for - * @pre every listed producer or proxy must have been previously registered - * @pre vp.voter must authorize this action - * @pre voter must have previously staked some EOS for voting - */ - static void on( const voteproducer& vp ) { - require_auth( vp.voter ); - - //validate input - if ( vp.proxy ) { - eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); - require_recipient( vp.proxy ); - } else { - eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); - for( size_t i = 1; i < vp.producers.size(); ++i ) { - eosio_assert( vp.producers[i-1] < vp.producers[i], "producer votes must be unique and sorted" ); - } - } - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( vp.voter ); - - eosio_assert( 0 <= voter->staked.amount, "negative stake" ); - eosio_assert( voter != voters_tbl.end() && ( 0 < voter->staked.amount || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); - if ( voter->is_proxy ) { - eosio_assert( vp.proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); - } - - //find old producers, update old proxy if needed - const std::vector* old_producers = nullptr; - if( voter->proxy ) { - if ( voter->proxy == vp.proxy ) { - return; // nothing changed - } - auto old_proxy = voters_tbl.find( voter->proxy ); - eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption - voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= uint64_t(voter->staked.amount); } ); - if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) - old_producers = &old_proxy->producers; - } - } else { - old_producers = &voter->producers; - } - - //find new producers, update new proxy if needed - const std::vector* new_producers = nullptr; - if ( vp.proxy ) { - auto new_proxy = voters_tbl.find( vp.proxy ); - eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); - voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += uint64_t(voter->staked.amount); } ); - new_producers = &new_proxy->producers; - } else { - new_producers = &vp.producers; - } - - producers_table producers_tbl( SystemAccount, SystemAccount ); - uint128_t votes = uint64_t(voter->staked.amount); - if ( voter->is_proxy ) { - votes += voter->proxied_votes; - } - - if ( old_producers ) { //old_producers == nullptr if proxy has stopped being a proxy and votes were taken back from the producers at that moment - //revoke votes only from no longer elected - std::vector revoked( old_producers->size() ); - auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); - for ( auto it = revoked.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); - } - } - - //update newly elected - std::vector elected( new_producers->size() ); - auto end_it = elected.begin(); - if( old_producers ) { - end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); - } else { - end_it = std::copy( new_producers->begin(), new_producers->end(), elected.begin() ); - } - for ( auto it = elected.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "producer is not registered" ); - if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers - eosio_assert( prod->active(), "producer is not currently registered" ); - } - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); - } - - // save new values to the account itself - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.proxy = vp.proxy; - a.last_update = now(); - a.producers = vp.producers; - }); - } - - ACTION( SystemAccount, regproxy ) { - account_name proxy; - - EOSLIB_SERIALIZE( regproxy, (proxy) ) - }; - - static void on( const regproxy& reg ) { - require_auth( reg.proxy ); - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto proxy = voters_tbl.find( reg.proxy ); - if ( proxy != voters_tbl.end() ) { - eosio_assert( proxy->is_proxy == 0, "account is already a proxy" ); - eosio_assert( proxy->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { - a.is_proxy = 1; - a.last_update = now(); - //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value - }); - if ( 0 < proxy->proxied_votes ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for ( auto p : proxy->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += proxy->proxied_votes; }); - } - } - } else { - voters_tbl.emplace( reg.proxy, [&]( voter_info& a ) { - a.owner = reg.proxy; - a.last_update = now(); - a.proxy = 0; - a.is_proxy = 1; - a.proxied_votes = 0; - a.staked.amount = 0; - }); - } - } - - ACTION( SystemAccount, unregproxy ) { - account_name proxy; - - EOSLIB_SERIALIZE( unregproxy, (proxy) ) - }; - - static void on( const unregproxy& reg ) { - require_auth( reg.proxy ); - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto proxy = voters_tbl.find( reg.proxy ); - eosio_assert( proxy != voters_tbl.end(), "proxy not found" ); - eosio_assert( proxy->is_proxy == 1, "account is not a proxy" ); - - voters_tbl.modify( proxy, 0, [&](voter_info& a) { - a.is_proxy = 0; - a.last_update = now(); - //a.proxied_votes should be kept in order to be able to reenable this proxy in the future - }); - - if ( 0 < proxy->proxied_votes ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for ( auto p : proxy->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); - } - } - } - - }; -} From 11119d64c0de0f871c8eb6ec991617945b79b867 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 19 Apr 2018 20:17:11 -0400 Subject: [PATCH 0164/1048] generalize sending inline actions through templates and macros --- delegate_bandwidth.hpp | 12 ++++++------ eosio.system.hpp | 8 ++++---- voting.hpp | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index ff1b6003..be023549 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -39,7 +39,7 @@ namespace eosiosystem { account_name owner; asset net_weight; asset cpu_weight; - asset storage_stake; + asset storage_stake; uint64_t storage_bytes = 0; uint64_t primary_key()const { return owner; } @@ -183,9 +183,9 @@ namespace eosiosystem { } //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); - - eosio::inline_transfer(eosio::permission_level{del.from,N(active)}, N(eosio.token), - { del.from, N(eosio), total_stake, std::string("stake bandwidth") } ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {del.from,N(active)}, + { del.from, N(eosio), total_stake, std::string("stake bandwidth") } ); if ( asset(0) < del.stake_net_quantity + del.stake_cpu_quantity ) { voting::increase_voting_power( del.from, del.stake_net_quantity + del.stake_cpu_quantity ); @@ -282,8 +282,8 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - eosio::inline_transfer( eosio::permission_level{N(eosio),N(active)}, N(eosio.token), - { N(eosio), req->owner, req->amount, std::string("unstake") }); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), req->owner, req->amount, std::string("unstake") } ); refunds_tbl.erase( req ); } diff --git a/eosio.system.hpp b/eosio.system.hpp index eeed12b9..d03f810e 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -29,8 +29,8 @@ namespace eosiosystem { template class contract : eosio::contract, public delegate_bandwidth, public native { public: - - contract(account_name self = SystemAccount): + + contract(account_name self = SystemAccount): eosio::contract(self) { } @@ -164,8 +164,8 @@ namespace eosiosystem { p.per_block_payments.amount = 0; }); - eosio::inline_transfer(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), - { N(eosio), cr.owner, rewards, std::string("producer claiming rewards") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), cr.owner, rewards, std::string("producer claiming rewards") } ); } static void apply( account_name receiver, account_name code, action_name act ) { diff --git a/voting.hpp b/voting.hpp index a1a20d85..d04d81e1 100644 --- a/voting.hpp +++ b/voting.hpp @@ -376,8 +376,8 @@ namespace eosiosystem { } auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); - eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), - { N(eosio), issue_quantity, std::string("producer pay") }); + INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, + {N(eosio), issue_quantity, std::string("producer pay")} ); set_blockchain_parameters(parameters); global_state_singleton::set(parameters); From dfcfc1da43af971ee77145757bd418ff270711dd Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 20 Apr 2018 10:00:04 -0400 Subject: [PATCH 0165/1048] put EOS symbol into common and other minor fixes --- common.hpp | 2 ++ delegate_bandwidth.hpp | 8 +++++--- voting.hpp | 6 ++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/common.hpp b/common.hpp index ee0f8d6f..6d4efce4 100644 --- a/common.hpp +++ b/common.hpp @@ -24,6 +24,8 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint32_t days_per_4years = 1461; + static constexpr uint64_t system_token_symbol = S(4,EOS); + struct eosio_parameters : eosio::blockchain_parameters { uint64_t max_storage_size = 10 * 1024 * 1024; uint32_t percent_of_max_inflation_rate = 0; diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index be023549..1e15c459 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -35,6 +35,8 @@ namespace eosiosystem { using eosio_parameters = typename common::eosio_parameters; using global_state_singleton = typename common::global_state_singleton; + using voting::system_token_symbol; + struct total_resources { account_name owner; asset net_weight; @@ -121,7 +123,7 @@ namespace eosiosystem { if ( 0 < del.stake_storage_quantity.amount ) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); + eosio::symbol_name sym = eosio::symbol_type(system_token_symbol).name(); eosio::token::stats stats_tbl(N(eosio.token), sym); const auto& st = stats_tbl.get(sym); const eosio::asset token_supply = st.supply; @@ -207,11 +209,11 @@ namespace eosiosystem { eosio_assert( dbw.cpu_weight >= del.unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); eosio_assert( dbw.storage_bytes >= del.unstake_storage_bytes, "insufficient staked storage" ); - eosio::asset storage_stake_decrease(0, S(4,EOS)); + eosio::asset storage_stake_decrease(0, system_token_symbol); if ( 0 < del.unstake_storage_bytes ) { storage_stake_decrease = 0 < dbw.storage_bytes ? dbw.storage_stake * int64_t(del.unstake_storage_bytes) / int64_t(dbw.storage_bytes) - : eosio::asset(0, S(4,EOS)); + : eosio::asset(0, system_token_symbol); auto parameters = global_state_singleton::get(); parameters.total_storage_bytes_reserved -= del.unstake_storage_bytes; diff --git a/voting.hpp b/voting.hpp index d04d81e1..fc5548bb 100644 --- a/voting.hpp +++ b/voting.hpp @@ -38,6 +38,8 @@ namespace eosiosystem { static constexpr uint32_t max_inflation_rate = common::max_inflation_rate; static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year + static constexpr uint64_t system_token_symbol = common::system_token_symbol; + struct producer_info { account_name owner; uint128_t total_votes = 0; @@ -229,14 +231,14 @@ namespace eosiosystem { } static eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate) { - eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); + eosio::symbol_name sym = eosio::symbol_type(system_token_symbol).name(); eosio::token::stats stats_tbl(N(eosio.token), sym); const auto& st = stats_tbl.get(sym); const eosio::asset token_supply = st.supply; const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); double continuous_rate = std::log1p(annual_rate); int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); - return eosio::asset(payment, S(4,EOS)); + return eosio::asset(payment, system_token_symbol); } static void update_elected_producers(time cycle_time) { From 0745841b1214d4c5c1c2bf2660de85182be6a4b0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 20 Apr 2018 11:06:33 -0400 Subject: [PATCH 0166/1048] Added get_supply and get_balance methods to token contract --- delegate_bandwidth.hpp | 6 ++---- voting.hpp | 10 ++++------ 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index be023549..3adb2d6a 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -121,10 +121,8 @@ namespace eosiosystem { if ( 0 < del.stake_storage_quantity.amount ) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); - eosio::token::stats stats_tbl(N(eosio.token), sym); - const auto& st = stats_tbl.get(sym); - const eosio::asset token_supply = st.supply; + + const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(S(4,EOS)); //make sure that there is no posibility of overflow here int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) diff --git a/voting.hpp b/voting.hpp index d04d81e1..b8c3b473 100644 --- a/voting.hpp +++ b/voting.hpp @@ -229,14 +229,12 @@ namespace eosiosystem { } static eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate) { - eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); - eosio::token::stats stats_tbl(N(eosio.token), sym); - const auto& st = stats_tbl.get(sym); - const eosio::asset token_supply = st.supply; + eosio::symbol_type sym(S(4,EOS)); + const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(sym); const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); - double continuous_rate = std::log1p(annual_rate); + const double continuous_rate = std::log1p(annual_rate); int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); - return eosio::asset(payment, S(4,EOS)); + return eosio::asset(payment, sym); } static void update_elected_producers(time cycle_time) { From a1d5ac41df77c0cc5ff568bc6f3d2d52db8eac34 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 20 Apr 2018 11:34:53 -0400 Subject: [PATCH 0167/1048] Change get_supply and get_balance to use symbol code --- delegate_bandwidth.hpp | 2 +- voting.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.hpp b/delegate_bandwidth.hpp index f139a7af..844e5ccf 100644 --- a/delegate_bandwidth.hpp +++ b/delegate_bandwidth.hpp @@ -123,7 +123,7 @@ namespace eosiosystem { if ( 0 < del.stake_storage_quantity.amount ) { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); - const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(S(4,EOS)); + const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); //make sure that there is no posibility of overflow here int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) * int64_t(parameters.storage_reserve_ratio) * del.stake_storage_quantity diff --git a/voting.hpp b/voting.hpp index a8e23caa..e43b2cf1 100644 --- a/voting.hpp +++ b/voting.hpp @@ -231,7 +231,7 @@ namespace eosiosystem { } static eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate) { - const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(system_token_symbol); + const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); const double continuous_rate = std::log1p(annual_rate); int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); From 55823664d514eb49d830792a2ecb275deb5bb162 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 20 Apr 2018 12:05:44 -0400 Subject: [PATCH 0168/1048] singleton takes code and scope as runtime-parameters, global_state_singleton restored in system contract, hack to prevent llvm-linker from removing apply function #2227 --- apply.cpp | 1 + delegate_bandwidth.cpp | 22 ++++++++-------------- eosio.system.hpp | 13 ++++++++++++- producer_pay.cpp | 28 ++++++++++++---------------- voting.cpp | 17 +++++++++++------ 5 files changed, 44 insertions(+), 37 deletions(-) diff --git a/apply.cpp b/apply.cpp index 19c7f4a5..9141eb33 100644 --- a/apply.cpp +++ b/apply.cpp @@ -11,6 +11,7 @@ EOSIO_ABI( eosiosystem::system_contract, // producer_pay.cpp (claimrewards) // native.hpp + //XXX //(newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) // defined in eosio.system.hpp (nonce) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index e2110562..8db3204d 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -26,11 +26,8 @@ namespace eosiosystem { using std::map; using std::pair; - //static constexpr account_name system_account = SystemAccount; static constexpr time refund_delay = 3*24*3600; static constexpr time refund_expiration_time = 3600; - //using eosio_parameters = typename common::eosio_parameters; - //using global_state_singleton = typename common::global_state_singleton; struct total_resources { account_name owner; @@ -92,9 +89,8 @@ namespace eosiosystem { //eosio_assert( is_account( receiver ), "can only delegate resources to an existing account" ); int64_t storage_bytes = 0; if ( 0 < stake_storage_quantity.amount ) { - /* XXX - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); + global_state_singleton gs( _self, _self ); + auto parameters = gs.exists() ? gs.get() : get_default_parameters(); eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); eosio::token::stats stats_tbl(N(eosio.token), sym); const auto& st = stats_tbl.get(sym); @@ -103,18 +99,17 @@ namespace eosiosystem { //make sure that there is no posibility of overflow here int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) * int64_t(parameters.storage_reserve_ratio) * stake_storage_quantity - / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient * /; + / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; storage_bytes = ( int64_t(parameters.max_storage_size) - int64_t(parameters.total_storage_bytes_reserved) - storage_bytes_estimated ) * int64_t(parameters.storage_reserve_ratio) * stake_storage_quantity - / ( token_supply - stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient * /; + / ( token_supply - stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); parameters.total_storage_bytes_reserved += uint64_t(storage_bytes); parameters.total_storage_stake += stake_storage_quantity; - global_state_singleton::set(parameters); - */ + gs.set( parameters, _self ); } del_bandwidth_table del_tbl( _self, from ); @@ -191,12 +186,11 @@ namespace eosiosystem { storage_stake_decrease = 0 < dbw.storage_bytes ? dbw.storage_stake * int64_t(unstake_storage_bytes) / int64_t(dbw.storage_bytes) : eosio::asset(0, S(4,EOS)); - /* XXX - auto parameters = global_state_singleton::get(); + global_state_singleton gs( _self, _self ); + auto parameters = gs.get(); //it should exist if user staked for bandwith parameters.total_storage_bytes_reserved -= unstake_storage_bytes; parameters.total_storage_stake -= storage_stake_decrease; - global_state_singleton::set( parameters ); - */ + gs.set( parameters, _self ); } eosio::asset total_refund = unstake_cpu_quantity + unstake_net_quantity + storage_stake_decrease; diff --git a/eosio.system.hpp b/eosio.system.hpp index f8037fa4..c47134bf 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -80,7 +80,7 @@ namespace eosiosystem { indexed_by > > producers_table; - //typedef eosio::singleton global_state_singleton; + typedef eosio::singleton global_state_singleton; static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; @@ -111,6 +111,8 @@ namespace eosiosystem { void decrease_voting_power( account_name acnt, const eosio::asset& amount ); + static eosio_global_state get_default_parameters(); + eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate); void update_elected_producers(time cycle_time); @@ -134,3 +136,12 @@ namespace eosiosystem { }; } /// eosiosystem + +//hack to prevent linker from removing apply function +extern "C" { + void apply( uint64_t receiver, uint64_t code, uint64_t action ); +} + +void call_apply() { + apply( 0, 0, 0 ); +} diff --git a/producer_pay.cpp b/producer_pay.cpp index 6184a108..8e272946 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -7,14 +7,13 @@ namespace eosiosystem { static const uint32_t num_of_payed_producers = 121; bool system_contract::update_cycle(time block_time) { - /* XXX - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : get_default_parameters(); + global_state_singleton gs( _self, _self ); + auto parameters = gs.exists() ? gs.get() : get_default_parameters(); if (parameters.first_block_time_in_cycle == 0) { // This is the first time onblock is called in the blockchain. parameters.last_bucket_fill_time = block_time; - global_state_singleton::set(parameters); - update_elected_producers(block_time); + gs.set( parameters, _self ); + update_elected_producers( block_time ); return true; } @@ -25,7 +24,6 @@ bool system_contract::update_cycle(time block_time) { update_elected_producers(beginning_of_cycle); return true; } - */ return false; } @@ -35,9 +33,9 @@ void system_contract::onblock(const block_header& header) { producers_table producers_tbl( _self, _self ); account_name producer = header.producer; - /* XXX - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : get_default_parameters(); + + global_state_singleton gs( _self, _self ); + auto parameters = gs.exists() ? gs.get() : get_default_parameters(); // const system_token_type block_payment = parameters.payment_per_block; const asset block_payment = parameters.payment_per_block; auto prod = producers_tbl.find(producer); @@ -53,8 +51,7 @@ void system_contract::onblock(const block_header& header) { const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; parameters.last_bucket_fill_time = header.timestamp; parameters.eos_bucket += to_eos_bucket; - global_state_singleton::set(parameters); - */ + gs.set( parameters, _self ); } void system_contract::claimrewards(const account_name& owner) { @@ -91,16 +88,15 @@ void system_contract::claimrewards(const account_name& owner) { } if (is_among_payed_producers && total_producer_votes > 0) { - /* - if( global_state_singleton::exists() ) { - auto parameters = global_state_singleton::get(); + global_state_singleton gs( _self, _self ); + if( gs.exists() ) { + auto parameters = gs.get(); // auto share_of_eos_bucket = system_token_type( static_cast( (prod->total_votes * parameters.eos_bucket.quantity) / total_producer_votes ) ); // This will be improved in the future when total_votes becomes a double type. auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * parameters.eos_bucket.amount) / total_producer_votes ) ); rewards += share_of_eos_bucket; parameters.eos_bucket -= share_of_eos_bucket; - global_state_singleton::set(parameters); + gs.set( parameters, _self ); } - */ } // eosio_assert( rewards > system_token_type(), "no rewards available to claim" ); diff --git a/voting.cpp b/voting.cpp index 8285bc75..e4fd92e4 100644 --- a/voting.cpp +++ b/voting.cpp @@ -182,6 +182,12 @@ namespace eosiosystem { } } + eosio_global_state system_contract::get_default_parameters() { + eosio_global_state dp; + get_blockchain_parameters(dp); + return dp; + } + eosio::asset system_contract::payment_per_block(uint32_t percent_of_max_inflation_rate) { eosio::symbol_name sym = eosio::symbol_type(S(4,EOS)).name(); eosio::token::stats stats_tbl(N(eosio.token), sym); @@ -291,9 +297,9 @@ namespace eosiosystem { bytes packed_schedule = pack(schedule); set_active_producers( packed_schedule.data(), packed_schedule.size() ); size_t median = n/2; - /* XXX - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : get_default_parameters(); + + global_state_singleton gs( _self, _self ); + auto parameters = gs.exists() ? gs.get() : get_default_parameters(); parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; @@ -337,9 +343,8 @@ namespace eosiosystem { eosio::inline_issue(eosio::permission_level{N(eosio),N(active)}, N(eosio.token), { N(eosio), issue_quantity, std::string("producer pay") }); - set_blockchain_parameters(parameters); - global_state_singleton::set(parameters); - */ + set_blockchain_parameters( parameters ); + gs.set( parameters, _self ); } /** From e71f052296327571b3931d8b88d46e5ba76b86d8 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 20 Apr 2018 12:18:09 -0400 Subject: [PATCH 0169/1048] rearranged system contract .cpp files in CMake to fix linker problem #2227 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6de72324..5e518312 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system - SOURCE_FILES apply.cpp delegate_bandwidth.cpp voting.cpp producer_pay.cpp + SOURCE_FILES apply.cpp delegate_bandwidth.cpp producer_pay.cpp voting.cpp INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} LIBRARIES libc++ libc eosiolib eosio.token DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} From 80189ad602c947f45539277a8bf3e868c85368e2 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 20 Apr 2018 19:28:34 -0400 Subject: [PATCH 0170/1048] fixed check in produce_info::active, unpack producer_key, send deferred transaction draft #2227 --- delegate_bandwidth.cpp | 9 ++++----- eosio.system.hpp | 2 +- voting.cpp | 13 +++++++++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 297623f1..dceca34b 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -227,14 +227,13 @@ namespace eosiosystem { }); } //create or replace deferred transaction - /* XXX - refund act; - act.owner = from; + //refund act; + //act.owner = from; eosio::transaction out( now() + refund_delay + refund_expiration_time ); - out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), act ); + out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); out.delay_sec = refund_delay; out.send( from, receiver ); - */ + if ( asset(0) < unstake_net_quantity + unstake_cpu_quantity ) { decrease_voting_power( from, unstake_net_quantity + unstake_cpu_quantity ); } diff --git a/eosio.system.hpp b/eosio.system.hpp index b6ce09a2..962aef8b 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -69,7 +69,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } - bool active() const { return packed_key.size() == sizeof(public_key); } + bool active() const { return 0 < packed_key.size(); } EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) (per_block_payments)(last_rewards_claim) diff --git a/voting.cpp b/voting.cpp index 2423de77..4d47da4c 100644 --- a/voting.cpp +++ b/voting.cpp @@ -58,23 +58,27 @@ namespace eosiosystem { * @pre authority of producer to register * */ - void system_contract::regproducer( const account_name producer, const bytes& producer_key, const eosio_parameters& prefs ) { + void system_contract::regproducer( const account_name producer, const bytes& packed_producer_key, const eosio_parameters& prefs ) { + //eosio::print("produce_key: ", producer_key.size(), ", sizeof(public_key): ", sizeof(public_key), "\n"); require_auth( producer ); producers_table producers_tbl( _self, _self ); auto prod = producers_tbl.find( producer ); + //check that we can unpack producer key + public_key producer_key = eosio::unpack( packed_producer_key ); + if ( prod != producers_tbl.end() ) { producers_tbl.modify( prod, producer, [&]( producer_info& info ){ info.prefs = prefs; - info.packed_key = producer_key; + info.packed_key = eosio::pack( producer_key ); }); } else { producers_tbl.emplace( producer, [&]( producer_info& info ){ info.owner = producer; info.total_votes = 0; info.prefs = prefs; - info.packed_key = producer_key; + info.packed_key = eosio::pack( producer_key ); }); } } @@ -232,7 +236,8 @@ namespace eosiosystem { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); - std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data.data() ); + schedule.producers.back().block_signing_key = eosio::unpack( it->packed_key ); + //std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data.data() ); base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; From a98c123a664dbf75d1a593c308abe6e5a3f781cd Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 21 Apr 2018 16:12:01 -0400 Subject: [PATCH 0171/1048] move authorization code into its own class (authorization_manager) Also update native action handlers to reflect changes in PR #2440. --- native.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/native.hpp b/native.hpp index 28cf5e48..43e25c5b 100644 --- a/native.hpp +++ b/native.hpp @@ -132,9 +132,10 @@ namespace eosiosystem { } ACTION( SystemAccount, canceldelay ) { + permission_level canceling_auth; transaction_id_type trx_id; - EOSLIB_SERIALIZE( canceldelay, (trx_id) ) + EOSLIB_SERIALIZE( canceldelay, (canceling_auth)(trx_id) ) }; static void on( const canceldelay& ) { From 41a1e658b5c505f69cfdc8242919ae481a1f2f5d Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 23 Apr 2018 10:57:30 -0400 Subject: [PATCH 0172/1048] small fix #2227 --- voting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 4d47da4c..58373666 100644 --- a/voting.cpp +++ b/voting.cpp @@ -235,7 +235,7 @@ namespace eosiosystem { if ( it->active() ) { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; - eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); + //eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); schedule.producers.back().block_signing_key = eosio::unpack( it->packed_key ); //std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data.data() ); From a62e32300638986e10512f974e88c9e22b9b59c9 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 23 Apr 2018 16:59:59 -0400 Subject: [PATCH 0173/1048] compile entire system contract as single file, native actions fix #2227 --- CMakeLists.txt | 2 +- apply.cpp | 7 +++++-- eosio.system.hpp | 12 +----------- native.hpp | 34 +++++++++++++++++++--------------- 4 files changed, 26 insertions(+), 29 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e518312..18c013ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,7 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system - SOURCE_FILES apply.cpp delegate_bandwidth.cpp producer_pay.cpp voting.cpp + SOURCE_FILES apply.cpp INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} LIBRARIES libc++ libc eosiolib eosio.token DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} diff --git a/apply.cpp b/apply.cpp index 9141eb33..6dfcd869 100644 --- a/apply.cpp +++ b/apply.cpp @@ -1,7 +1,10 @@ #include "eosio.system.hpp" - #include +#include "delegate_bandwidth.cpp" +#include "producer_pay.cpp" +#include "voting.cpp" + EOSIO_ABI( eosiosystem::system_contract, // delegate_bandwith.cpp (delegatebw)(undelegatebw)(refund) @@ -12,7 +15,7 @@ EOSIO_ABI( eosiosystem::system_contract, (claimrewards) // native.hpp //XXX - //(newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) + (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) // defined in eosio.system.hpp (nonce) ) diff --git a/eosio.system.hpp b/eosio.system.hpp index 962aef8b..c89f39f7 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -124,7 +124,7 @@ namespace eosiosystem { void unregproxy( const account_name proxy ); - void nonce( const std::string& value ) {} + void nonce( const std::string& /*value*/ ) {} // functions defined in producer_pay.cpp @@ -133,16 +133,6 @@ namespace eosiosystem { void onblock( const block_header& header ); void claimrewards( const account_name& owner ); - }; } /// eosiosystem - -//hack to prevent linker from removing apply function -extern "C" { - void apply( uint64_t receiver, uint64_t code, uint64_t action ); -} - -void call_apply() { - apply( 0, 0, 0 ); -} diff --git a/native.hpp b/native.hpp index fb14cd04..774b0acb 100644 --- a/native.hpp +++ b/native.hpp @@ -36,42 +36,46 @@ namespace eosiosystem { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) }; + /* + * Empty handlers for native messages. + * Method parameters commented out to prevent generation of code that parses input data. + */ class native { public: - static void newaccount( account_name creator, + void newaccount( /*account_name creator, account_name name, const authority& owner, const authority& active, - const authority& recovery ) {} + const authority& recovery*/ ) {} - static void updateauth( account_name account, + void updateauth( /*account_name account, permission_name permission, permission_name parent, - const authority& data ) {} + const authority& data*/ ) {} - static void deleteauth( account_name account, permission_name permission ) {} + void deleteauth( /*account_name account, permission_name permission*/ ) {} - static void linkauth( account_name account, + void linkauth( /*account_name account, account_name code, action_name type, - permission_name requirement ) {} + permission_name requirement*/ ) {} - static void unlinkauth( account_name account, + void unlinkauth( /*account_name account, account_name code, - action_name type ) {} + action_name type*/ ) {} - static void postrecovery( account_name account, + void postrecovery( /*account_name account, const authority& data, - const std::string& memo ) {} + const std::string& memo*/ ) {} - static void passrecovery( account_name account ) {} + void passrecovery( /*account_name account*/ ) {} - static void vetorecovery( account_name account ) {} + void vetorecovery( /*account_name account*/ ) {} - static void onerror( const bytes& ) {} + void onerror( /*const bytes&*/ ) {} - static void canceldelay( permission_level canceling_auth, transaction_id_type trx_id ) {} + void canceldelay( /*permission_level canceling_auth, transaction_id_type trx_id*/ ) {} }; } From dd2f34288d4648b0105d50a3a2992ca346f98da6 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 23 Apr 2018 17:05:56 -0400 Subject: [PATCH 0174/1048] apply.cpp renamed to eosio.system.cpp #2227 --- CMakeLists.txt | 1 - apply.cpp | 21 --------------------- eosio.system.cpp | 34 +++++++++++++++++++--------------- 3 files changed, 19 insertions(+), 37 deletions(-) delete mode 100644 apply.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 18c013ab..eb4ff749 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,6 @@ file(GLOB ABI_FILES "*.abi") configure_file("${ABI_FILES}" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_wast_executable(TARGET eosio.system - SOURCE_FILES apply.cpp INCLUDE_FOLDERS ${STANDARD_INCLUDE_FOLDERS} LIBRARIES libc++ libc eosiolib eosio.token DESTINATION_FOLDER ${CMAKE_CURRENT_BINARY_DIR} diff --git a/apply.cpp b/apply.cpp deleted file mode 100644 index 6dfcd869..00000000 --- a/apply.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include "eosio.system.hpp" -#include - -#include "delegate_bandwidth.cpp" -#include "producer_pay.cpp" -#include "voting.cpp" - -EOSIO_ABI( eosiosystem::system_contract, - // delegate_bandwith.cpp - (delegatebw)(undelegatebw)(refund) - (regproxy) - // voting.cpp - (unregproxy)(regproducer)(unregprod)(voteproducer)(onblock) - // producer_pay.cpp - (claimrewards) - // native.hpp - //XXX - (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) - // defined in eosio.system.hpp - (nonce) -) diff --git a/eosio.system.cpp b/eosio.system.cpp index d5986a1f..6dfcd869 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -1,17 +1,21 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ +#include "eosio.system.hpp" +#include -#include +#include "delegate_bandwidth.cpp" +#include "producer_pay.cpp" +#include "voting.cpp" -using namespace eosiosystem; - -extern "C" { - - /// The apply method implements the dispatch of events to this contract - void apply( uint64_t receiver, uint64_t code, uint64_t act ) { - //print( eosio::name(code), "::", eosio::name(act) ); - eosiosystem::contract::apply( receiver, code, act ); - } -} +EOSIO_ABI( eosiosystem::system_contract, + // delegate_bandwith.cpp + (delegatebw)(undelegatebw)(refund) + (regproxy) + // voting.cpp + (unregproxy)(regproducer)(unregprod)(voteproducer)(onblock) + // producer_pay.cpp + (claimrewards) + // native.hpp + //XXX + (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) + // defined in eosio.system.hpp + (nonce) +) From 4a571837ff12c8ff051dacb0d87fa427fbccd003 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 23 Apr 2018 18:25:59 -0400 Subject: [PATCH 0175/1048] public/private functions separated, code-style fixes #2227 --- delegate_bandwidth.cpp | 4 +-- eosio.system.hpp | 61 ++++++++++++++++++++++++------------------ 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index dceca34b..cc1522ea 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -74,8 +74,8 @@ namespace eosiosystem { typedef eosio::multi_index< N(refunds), refund_request> refunds_table; void system_contract::delegatebw( const account_name from, const account_name receiver, - const asset stake_net_quantity, const asset stake_cpu_quantity, - const asset stake_storage_quantity ) + const asset stake_net_quantity, const asset stake_cpu_quantity, + const asset stake_storage_quantity ) { eosio_assert( stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( stake_net_quantity.amount >= 0, "must stake a positive amount" ); diff --git a/eosio.system.hpp b/eosio.system.hpp index c89f39f7..5bc503ad 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -87,52 +87,61 @@ namespace eosiosystem { static constexpr uint64_t system_token_symbol = S(4,EOS); class system_contract : public native, private eosio::contract { - public: + public: - using eosio::contract::contract; + using eosio::contract::contract; - // functions defined in delegate_bandwidth.cpp - void delegatebw( const account_name from, const account_name receiver, - const asset stake_net_quantity, const asset stake_cpu_quantity, - const asset stake_storage_quantity ); + // Actions: - void undelegatebw( const account_name from, const account_name receiver, - const asset unstake_net_quantity, const asset unstake_cpu_quantity, - const uint64_t unstake_storage_bytes ); + // functions defined in delegate_bandwidth.cpp + void delegatebw( const account_name from, const account_name receiver, + const asset stake_net_quantity, const asset stake_cpu_quantity, + const asset stake_storage_quantity ); - void refund( const account_name owner ); + void undelegatebw( const account_name from, const account_name receiver, + const asset unstake_net_quantity, const asset unstake_cpu_quantity, + const uint64_t unstake_storage_bytes ); - // functions defined in voting.cpp + void refund( const account_name owner ); - void regproducer( const account_name producer, const bytes& producer_key, const eosio_parameters& prefs ); + // functions defined in voting.cpp - void unregprod( const account_name producer ); + void regproducer( const account_name producer, const bytes& producer_key, const eosio_parameters& prefs ); - void increase_voting_power( account_name acnt, const eosio::asset& amount ); + void unregprod( const account_name producer ); - void decrease_voting_power( account_name acnt, const eosio::asset& amount ); + eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate); - static eosio_global_state get_default_parameters(); + void update_elected_producers(time cycle_time); - eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate); + void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); - void update_elected_producers(time cycle_time); + void regproxy( const account_name proxy ); - void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); + void unregproxy( const account_name proxy ); - void regproxy( const account_name proxy ); + void nonce( const std::string& /*value*/ ) {} - void unregproxy( const account_name proxy ); + // functions defined in producer_pay.cpp - void nonce( const std::string& /*value*/ ) {} + void onblock( const block_header& header ); - // functions defined in producer_pay.cpp + void claimrewards( const account_name& owner ); - bool update_cycle( time block_time ); + private: + // Implementation details: - void onblock( const block_header& header ); + //defined in voting.hpp + static eosio_global_state get_default_parameters(); + + // defined in voting.cpp + void increase_voting_power( account_name acnt, const eosio::asset& amount ); + + void decrease_voting_power( account_name acnt, const eosio::asset& amount ); + + // defined in producer_pay.cpp + bool update_cycle( time block_time ); - void claimrewards( const account_name& owner ); }; } /// eosiosystem From 30dbfcf5b2d67bf7bb69a993f2ab7714111f9636 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Tue, 24 Apr 2018 09:31:05 -0400 Subject: [PATCH 0176/1048] comment added #2227 --- delegate_bandwidth.cpp | 3 +++ eosio.system.hpp | 4 ++++ native.hpp | 3 +++ voting.cpp | 1 + 4 files changed, 11 insertions(+) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index cc1522ea..07077f4f 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -38,6 +38,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( total_resources, (owner)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) }; @@ -55,6 +56,7 @@ namespace eosiosystem { uint64_t primary_key()const { return to; } + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) }; @@ -66,6 +68,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(amount) ) }; diff --git a/eosio.system.hpp b/eosio.system.hpp index 5bc503ad..d62f15d4 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -30,6 +30,7 @@ namespace eosiosystem { uint32_t schedule_version; eosio::optional new_producers; + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot) (producer)(schedule_version)(new_producers)) }; @@ -39,6 +40,7 @@ namespace eosiosystem { uint32_t percent_of_max_inflation_rate = 0; uint32_t storage_reserve_ratio = 1000; // ratio * 1000 + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_storage_size)(percent_of_max_inflation_rate)(storage_reserve_ratio) ) }; @@ -52,6 +54,7 @@ namespace eosiosystem { time last_bucket_fill_time = 0; eosio::asset eos_bucket; + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) (last_bucket_fill_time)(eos_bucket) ) @@ -71,6 +74,7 @@ namespace eosiosystem { uint128_t by_votes()const { return total_votes; } bool active() const { return 0 < packed_key.size(); } + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) (per_block_payments)(last_rewards_claim) (time_became_active)(last_produced_block_time) ) diff --git a/native.hpp b/native.hpp index 774b0acb..fd7bfe66 100644 --- a/native.hpp +++ b/native.hpp @@ -18,6 +18,7 @@ namespace eosiosystem { permission_level permission; weight_type weight; + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) }; @@ -25,6 +26,7 @@ namespace eosiosystem { public_key key; weight_type weight; + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( key_weight, (key)(weight) ) }; @@ -33,6 +35,7 @@ namespace eosiosystem { std::vector keys; std::vector accounts; + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) }; diff --git a/voting.cpp b/voting.cpp index 58373666..1408bbc2 100644 --- a/voting.cpp +++ b/voting.cpp @@ -45,6 +45,7 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) }; From b6540b876d0998be23b6e725683b0b8d1e435c59 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 24 Apr 2018 16:11:58 -0400 Subject: [PATCH 0177/1048] set_active_producers instrinsic should return false rather than throw Also, it now checks to ensure the proposed producer schedule would actually change the schedule. --- eosio.system.hpp | 1 + voting.hpp | 15 +++++++-------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 9208d71c..3b2bf868 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -6,6 +6,7 @@ #include "delegate_bandwidth.hpp" #include "native.hpp" +#include #include #include diff --git a/voting.hpp b/voting.hpp index b99390de..09b512e5 100644 --- a/voting.hpp +++ b/voting.hpp @@ -265,15 +265,15 @@ namespace eosiosystem { std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; - eosio::producer_schedule schedule; - schedule.producers.reserve(21); + std::vector schedule; + schedule.reserve(21); size_t n = 0; for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { if ( it->active() ) { - schedule.producers.emplace_back(); - schedule.producers.back().producer_name = it->owner; - eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); - std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data ); + schedule.emplace_back(); + schedule.back().producer_name = it->owner; + eosio_assert( sizeof(schedule.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); + std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.back().block_signing_key.data ); base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; @@ -329,7 +329,6 @@ namespace eosiosystem { std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); } - // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp bytes packed_schedule = pack(schedule); set_active_producers( packed_schedule.data(), packed_schedule.size() ); size_t median = n/2; @@ -368,7 +367,7 @@ namespace eosiosystem { auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; parameters.payment_per_block = payment_per_block(half_of_percentage); parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); - parameters.blocks_per_cycle = common::blocks_per_producer * schedule.producers.size(); + parameters.blocks_per_cycle = common::blocks_per_producer * schedule.size(); if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { parameters.max_storage_size = parameters.total_storage_bytes_reserved; From dc33ba459cc9ddd30cea234f98a240a4d77fe074 Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Wed, 18 Apr 2018 15:06:14 -0500 Subject: [PATCH 0178/1048] Added cleos commands for regproducer and unregprod. GH #2257 --- eosio.system.abi | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 63fb2c31..62132e6a 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -84,7 +84,7 @@ {"name":"storage_bytes", "type":"uint64"} ] },{ - "name": "eosio_parameters", + "name": "blockchain_parameters", "base": "", "fields": [ {"name":"base_per_transaction_net_usage", "type":"uint32"}, @@ -107,7 +107,12 @@ {"name":"max_inline_depth", "type":"uint16"}, {"name":"max_inline_action_size", "type":"uint32"}, {"name":"max_generated_transaction_count", "type":"uint32"}, - {"name":"max_transaction_delay", "type":"uint32"}, + {"name":"max_transaction_delay", "type":"uint32"} + ] + },{ + "name": "eosio_parameters", + "base": "blockchain_parameters", + "fields": [ {"name":"max_storage_size", "type":"uint64"}, {"name":"percent_of_max_inflation_rate", "type":"uint32"}, {"name":"storage_reserve_ratio", "type":"uint32"} @@ -239,7 +244,13 @@ "ricardian_contract": "" } ], - "tables": [ + "tables": [{ + "name": "producerinfo", + "type": "producer_info", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + } ], "ricardian_clauses": [] } From f5aa97cb014606d1ccffcc3e3f60a6c4f5f45bbd Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Fri, 20 Apr 2018 14:47:21 -0500 Subject: [PATCH 0179/1048] Fixed abi not matching struct and fixed tests. GH #2257 --- eosio.system.abi | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 62132e6a..e353e612 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -42,9 +42,9 @@ "fields": [ {"name":"from", "type":"account_name"}, {"name":"receiver", "type":"account_name"}, - {"name":"stake_net", "type":"asset"}, - {"name":"stake_cpu", "type":"asset"}, - {"name":"stake_storage", "type":"asset"} + {"name":"stake_net_quantity", "type":"asset"}, + {"name":"stake_cpu_quantity", "type":"asset"}, + {"name":"stake_storage_quantity", "type":"asset"} ] },{ "name": "undelegatebw", @@ -52,9 +52,9 @@ "fields": [ {"name":"from", "type":"account_name"}, {"name":"receiver", "type":"account_name"}, - {"name":"unstake_net", "type":"asset"}, - {"name":"unstake_cpu", "type":"asset"}, - {"name":"unstake_bytes", "type":"uint64"} + {"name":"unstake_net_quantity", "type":"asset"}, + {"name":"unstake_cpu_quantity", "type":"asset"}, + {"name":"unstake_storage_bytes", "type":"uint64"} ] },{ "name": "refund", From 92669b6591649a1dd3aa180ddcec1e72b3a4d76d Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Fri, 20 Apr 2018 14:48:37 -0500 Subject: [PATCH 0180/1048] Fixed abi struct parameter types, added missing structs and missing tables. GH #2257 --- eosio.system.abi | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index e353e612..759eadde 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -68,9 +68,9 @@ "fields": [ {"name":"from", "type":"account_name"}, {"name":"to", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"storage_stake", "type":"asset"}, + {"name":"net_weight", "type":"uint64"}, + {"name":"cpu_weight", "type":"uint64"}, + {"name":"storage_stake", "type":"uint64"}, {"name":"storage_bytes", "type":"uint64"} ] },{ @@ -83,6 +83,14 @@ {"name":"storage_stake", "type":"asset"}, {"name":"storage_bytes", "type":"uint64"} ] + },{ + "name": "refund_request", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"request_time", "type":"time"}, + {"name":"amount", "type":"uint64"} + ] },{ "name": "blockchain_parameters", "base": "", @@ -250,6 +258,24 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["uint64"] + },{ + "name": "totalband", + "type": "total_resources", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "delband", + "type": "delegated_bandwidth", + "index_type": "i64", + "key_names" : ["to"], + "key_types" : ["uint64"] + },{ + "name": "refunds", + "type": "refund_request", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] } ], "ricardian_clauses": [] From 06220119969ee913e2386961c553ab612c6bb29f Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Mon, 23 Apr 2018 19:41:56 -0500 Subject: [PATCH 0181/1048] Peer Review changes and other comment cleanup. GH #2257 --- voting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 1408bbc2..b7ecdfa5 100644 --- a/voting.cpp +++ b/voting.cpp @@ -389,7 +389,7 @@ namespace eosiosystem { auto old_proxy = voters_tbl.find( voter_it->proxy ); eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= uint64_t(voter_it->staked.amount); } ); - if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) + if ( old_proxy->is_proxy ) { //if proxy stopped being a proxy, the votes were already taken back from producers by on( const unregister_proxy& ) old_producers = &old_proxy->producers; } } else { From a4648f75c0c40e9e4b296062af7c0f318f475812 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Tue, 24 Apr 2018 19:14:50 -0400 Subject: [PATCH 0182/1048] Remove current_sender from tests --- eosio.system.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 3b2bf868..0593bee9 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -112,7 +112,8 @@ namespace eosiosystem { static void on(const claimrewards& cr) { require_auth(cr.owner); - eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); + // TODO: current_sender() removed. Need to determine deferred transaction some other way. + // TODO: eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); producers_table producers_tbl(SystemAccount, SystemAccount); auto prod = producers_tbl.find(cr.owner); eosio_assert(prod != producers_tbl.end(), "account name is not in producer list"); From 19cfc2983e9579a2ce5e0d092ee5b8f5fdf384dd Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 25 Apr 2018 14:35:43 -0400 Subject: [PATCH 0183/1048] Add delay_sec to authority, rename data to auth --- native.hpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/native.hpp b/native.hpp index 43e25c5b..b2928459 100644 --- a/native.hpp +++ b/native.hpp @@ -28,10 +28,11 @@ namespace eosiosystem { struct authority { uint32_t threshold; + uint32_t delay_sec; std::vector keys; std::vector accounts; - EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts) ) + EOSLIB_SERIALIZE( authority, (threshold)(delay_sec)(keys)(accounts) ) }; template @@ -54,9 +55,9 @@ namespace eosiosystem { account_name account; permission_name permission; permission_name parent; - authority data; + authority auth; - EOSLIB_SERIALIZE( updateauth, (account)(permission)(parent)(data) ) + EOSLIB_SERIALIZE( updateauth, (account)(permission)(parent)(auth) ) }; static void on( const updateauth& ) { @@ -97,10 +98,10 @@ namespace eosiosystem { ACTION( SystemAccount, postrecovery ) { account_name account; - authority data; + authority auth; std::string memo; - EOSLIB_SERIALIZE( postrecovery, (account)(data)(memo) ) + EOSLIB_SERIALIZE( postrecovery, (account)(auth)(memo) ) }; static void on( const postrecovery& ) { From 2ffd6f2be85db212cde6c3a20423223d97a4a64f Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Fri, 27 Apr 2018 12:40:58 -0500 Subject: [PATCH 0184/1048] Porting over to unittests and getting part of eosio.system_tests to pass. --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 07077f4f..95cc6c61 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -232,7 +232,7 @@ namespace eosiosystem { //create or replace deferred transaction //refund act; //act.owner = from; - eosio::transaction out( now() + refund_delay + refund_expiration_time ); + eosio::transaction out; out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); out.delay_sec = refund_delay; out.send( from, receiver ); From c6a143a133f5f4a3c98f27f2594f598a3c7c5e1d Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 27 Apr 2018 22:14:02 -0400 Subject: [PATCH 0185/1048] several changes: * clean up configuration parameters * use dynamic max_inline_action_size configuration parameter to limit size of inline actions * use dynamic max_inline_action_depth to limit recursion depth of inline actions * change deferred_trx_expiration_window parameter into a dynamic configuration parameter * add numerator and denominator configuration parameters for later context free data discount implementation * bill delayed transaction for the additional net usage of the eventual retirement of the deferred transaction --- eosio.system.abi | 25 +++++------ voting.cpp | 107 ++++++++++++++++++++++++++++------------------- voting.hpp | 107 +++++++++++++++++++++++++++++------------------ 3 files changed, 143 insertions(+), 96 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 759eadde..f7aebf4c 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -95,27 +95,28 @@ "name": "blockchain_parameters", "base": "", "fields": [ + {"name":"max_block_net_usage", "type": "uint64"}, + {"name":"target_block_net_usage_pct", "type": "uint32"}, + {"name":"max_transaction_net_usage", "type":"uint32"}, {"name":"base_per_transaction_net_usage", "type":"uint32"}, + {"name":"context_free_discount_net_usage_num", "type":"uint64"}, + {"name":"context_free_discount_net_usage_den", "type":"uint64"}, + {"name":"max_block_cpu_usage", "type": "uint64"}, + {"name":"target_block_cpu_usage_pct", "type": "uint32"}, + {"name":"max_transaction_cpu_usage", "type":"uint32"}, {"name":"base_per_transaction_cpu_usage", "type":"uint32"}, {"name":"base_per_action_cpu_usage", "type":"uint32"}, {"name":"base_setcode_cpu_usage", "type":"uint32"}, {"name":"per_signature_cpu_usage", "type":"uint32"}, - {"name":"per_lock_net_usage", "type":"uint32"}, {"name":"context_free_discount_cpu_usage_num", "type":"uint64"}, {"name":"context_free_discount_cpu_usage_den", "type":"uint64"}, - {"name":"max_transaction_cpu_usage", "type":"uint32"}, - {"name":"max_transaction_net_usage", "type":"uint32"}, - {"name":"max_block_cpu_usage", "type": "uint64"}, - {"name":"target_block_cpu_usage_pct", "type": "uint32"}, - {"name":"max_block_net_usage", "type": "uint64"}, - {"name":"target_block_net_usage_pct", "type": "uint32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, - {"name":"max_transaction_exec_time", "type":"uint32"}, - {"name":"max_authority_depth", "type":"uint16"}, - {"name":"max_inline_depth", "type":"uint16"}, + {"name":"deferred_trx_expiration_window", "type":"uint32"}, + {"name":"max_transaction_delay", "type":"uint32"}, {"name":"max_inline_action_size", "type":"uint32"}, - {"name":"max_generated_transaction_count", "type":"uint32"}, - {"name":"max_transaction_delay", "type":"uint32"} + {"name":"max_inline_action_depth", "type":"uint16"}, + {"name":"max_authority_depth", "type":"uint16"}, + {"name":"max_generated_transaction_count", "type":"uint32"} ] },{ "name": "eosio_parameters", diff --git a/voting.cpp b/voting.cpp index b7ecdfa5..c1a66c04 100644 --- a/voting.cpp +++ b/voting.cpp @@ -205,27 +205,32 @@ namespace eosiosystem { producers_table producers_tbl( _self, _self ); auto idx = producers_tbl.template get_index(); + std::array max_block_net_usage; + std::array target_block_net_usage_pct; std::array base_per_transaction_net_usage; + std::array max_transaction_net_usage; + std::array context_free_discount_net_usage_num; + std::array context_free_discount_net_usage_den; + + std::array max_block_cpu_usage; + std::array target_block_cpu_usage_pct; + std::array max_transaction_cpu_usage; std::array base_per_transaction_cpu_usage; std::array base_per_action_cpu_usage; std::array base_setcode_cpu_usage; std::array per_signature_cpu_usage; - std::array per_lock_net_usage; std::array context_free_discount_cpu_usage_num; std::array context_free_discount_cpu_usage_den; - std::array max_transaction_cpu_usage; - std::array max_transaction_net_usage; - std::array max_block_cpu_usage; - std::array target_block_cpu_usage_pct; - std::array max_block_net_usage; - std::array target_block_net_usage_pct; + std::array max_transaction_lifetime; - std::array max_authority_depth; - std::array max_transaction_exec_time; - std::array max_inline_depth; + std::array deferred_trx_expiration_window; + std::array max_transaction_delay; std::array max_inline_action_size; + std::array max_inline_action_depth; + std::array max_authority_depth; std::array max_generated_transaction_count; - std::array max_transaction_delay; + + std::array max_storage_size; std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; @@ -240,28 +245,32 @@ namespace eosiosystem { schedule.producers.back().block_signing_key = eosio::unpack( it->packed_key ); //std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data.data() ); + max_block_net_usage[n] = it->prefs.max_block_net_usage; + target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; + max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; + context_free_discount_net_usage_num[n] = it->prefs.context_free_discount_net_usage_num; + context_free_discount_net_usage_den[n] = it->prefs.context_free_discount_net_usage_den; + + max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; + target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; + max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; - per_lock_net_usage[n] = it->prefs.per_lock_net_usage; context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; - max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; - max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; - max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; - target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; - max_block_net_usage[n] = it->prefs.max_block_net_usage; - target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; + max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; - max_authority_depth[n] = it->prefs.max_authority_depth; - max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; - max_inline_depth[n] = it->prefs.max_inline_depth; + deferred_trx_expiration_window[n] = it->prefs.deferred_trx_expiration_window; + max_transaction_delay[n] = it->prefs.max_transaction_delay; max_inline_action_size[n] = it->prefs.max_inline_action_size; + max_inline_action_depth[n] = it->prefs.max_inline_action_depth; + max_authority_depth[n] = it->prefs.max_authority_depth; max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; - max_transaction_delay[n] = it->prefs.max_transaction_delay; + max_storage_size[n] = it->prefs.max_storage_size; storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; ++n; @@ -271,27 +280,32 @@ namespace eosiosystem { return; } if ( 1 < n ) { + std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); + std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); + std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); + std::sort( context_free_discount_net_usage_num.begin(), context_free_discount_net_usage_num.begin()+n ); + std::sort( context_free_discount_net_usage_den.begin(), context_free_discount_net_usage_den.begin()+n ); + + std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); + std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); + std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); - std::sort( per_lock_net_usage.begin(), per_lock_net_usage.begin()+n ); std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); - std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); - std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); - std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); - std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); - std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); - std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); + std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); - std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); - std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); - std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); + std::sort( deferred_trx_expiration_window.begin(), deferred_trx_expiration_window.begin()+n ); + std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); + std::sort( max_inline_action_depth.begin(), max_inline_action_depth.begin()+n ); + std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); - std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); + + std::sort( max_storage_size.begin(), max_storage_size.begin()+n ); std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); } @@ -304,27 +318,32 @@ namespace eosiosystem { global_state_singleton gs( _self, _self ); auto parameters = gs.exists() ? gs.get() : get_default_parameters(); + parameters.max_block_net_usage = max_block_net_usage[median]; + parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; + parameters.max_transaction_net_usage = max_transaction_net_usage[median]; parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; + parameters.context_free_discount_net_usage_num = context_free_discount_net_usage_num[median]; + parameters.context_free_discount_net_usage_den = context_free_discount_net_usage_den[median]; + + parameters.max_block_cpu_usage = max_block_cpu_usage[median]; + parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; + parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; - parameters.per_lock_net_usage = per_lock_net_usage[median]; parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; - parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; - parameters.max_transaction_net_usage = max_transaction_net_usage[median]; - parameters.max_block_cpu_usage = max_block_cpu_usage[median]; - parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; - parameters.max_block_net_usage = max_block_net_usage[median]; - parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; + parameters.max_transaction_lifetime = max_transaction_lifetime[median]; - parameters.max_transaction_exec_time = max_transaction_exec_time[median]; - parameters.max_authority_depth = max_authority_depth[median]; - parameters.max_inline_depth = max_inline_depth[median]; + parameters.deferred_trx_expiration_window = deferred_trx_expiration_window[median]; + parameters.max_transaction_delay = max_transaction_delay[median]; parameters.max_inline_action_size = max_inline_action_size[median]; + parameters.max_inline_action_depth = max_inline_action_depth[median]; + parameters.max_authority_depth = max_authority_depth[median]; parameters.max_generated_transaction_count = max_generated_transaction_count[median]; - parameters.max_transaction_delay = max_transaction_delay[median]; + + parameters.max_storage_size = max_storage_size[median]; parameters.storage_reserve_ratio = storage_reserve_ratio[median]; parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; diff --git a/voting.hpp b/voting.hpp index 09b512e5..ed521d83 100644 --- a/voting.hpp +++ b/voting.hpp @@ -238,30 +238,39 @@ namespace eosiosystem { return (system_token_type(payment)); } + static void update_elected_producers(time cycle_time); + +#if 0 static void update_elected_producers(time cycle_time) { producers_table producers_tbl( SystemAccount, SystemAccount ); auto idx = producers_tbl.template get_index(); + std::array max_block_net_usage; + std::array target_block_net_usage_pct; std::array base_per_transaction_net_usage; + std::array max_transaction_net_usage; + std::array context_free_discount_net_usage_num; + std::array context_free_discount_net_usage_den; + + std::array max_block_cpu_usage; + std::array target_block_cpu_usage_pct; + std::array max_transaction_cpu_usage; std::array base_per_transaction_cpu_usage; std::array base_per_action_cpu_usage; std::array base_setcode_cpu_usage; std::array per_signature_cpu_usage; - std::array per_lock_net_usage; std::array context_free_discount_cpu_usage_num; std::array context_free_discount_cpu_usage_den; - std::array max_transaction_cpu_usage; - std::array max_transaction_net_usage; - std::array max_block_cpu_usage; - std::array target_block_cpu_usage_pct; - std::array max_block_net_usage; - std::array target_block_net_usage_pct; + std::array max_transaction_lifetime; - std::array max_authority_depth; - std::array max_transaction_exec_time; - std::array max_inline_depth; + std::array deferred_trx_expiration_window; + std::array max_transaction_delay; std::array max_inline_action_size; + std::array max_inline_action_depth; + std::array max_authority_depth; std::array max_generated_transaction_count; + + std::array max_storage_size; std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; @@ -275,27 +284,32 @@ namespace eosiosystem { eosio_assert( sizeof(schedule.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.back().block_signing_key.data ); + max_block_net_usage[n] = it->prefs.max_block_net_usage; + target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; + max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; + context_free_discount_net_usage_num[n] = it->prefs.context_free_discount_net_usage_num; + context_free_discount_net_usage_den[n] = it->prefs.context_free_discount_net_usage_den; + + max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; + target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; + max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; - per_lock_net_usage[n] = it->prefs.per_lock_net_usage; context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; - max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; - max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; - max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; - target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; - max_block_net_usage[n] = it->prefs.max_block_net_usage; - target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; + max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; - max_authority_depth[n] = it->prefs.max_authority_depth; - max_transaction_exec_time[n] = it->prefs.max_transaction_exec_time; - max_inline_depth[n] = it->prefs.max_inline_depth; + deferred_trx_expiration_window[n] = it->prefs.deferred_trx_expiration_window; + max_transaction_delay[n] = it->prefs.max_transaction_delay; max_inline_action_size[n] = it->prefs.max_inline_action_size; + max_inline_action_depth[n] = it->prefs.max_inline_action_depth; + max_authority_depth[n] = it->prefs.max_authority_depth; max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; + max_storage_size[n] = it->prefs.max_storage_size; storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; ++n; @@ -305,26 +319,32 @@ namespace eosiosystem { return; } if ( 1 < n ) { + std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); + std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); + std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); + std::sort( context_free_discount_net_usage_num.begin(), context_free_discount_net_usage_num.begin()+n ); + std::sort( context_free_discount_net_usage_den.begin(), context_free_discount_net_usage_den.begin()+n ); + + std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); + std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); + std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); - std::sort( per_lock_net_usage.begin(), per_lock_net_usage.begin()+n ); std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); - std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); - std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); - std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); - std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); - std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); - std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); + std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); - std::sort( max_transaction_exec_time.begin(), max_transaction_exec_time.begin()+n ); - std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); - std::sort( max_inline_depth.begin(), max_inline_depth.begin()+n ); + std::sort( deferred_trx_expiration_window.begin(), deferred_trx_expiration_window.begin()+n ); + std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); + std::sort( max_inline_action_depth.begin(), max_inline_action_depth.begin()+n ); + std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); + + std::sort( max_storage_size.begin(), max_storage_size.begin()+n ); std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); } @@ -336,26 +356,32 @@ namespace eosiosystem { auto parameters = global_state_singleton::exists() ? global_state_singleton::get() : common::get_default_parameters(); + parameters.max_block_net_usage = max_block_net_usage[median]; + parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; + parameters.max_transaction_net_usage = max_transaction_net_usage[median]; parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; + parameters.context_free_discount_net_usage_num = context_free_discount_net_usage_num[median]; + parameters.context_free_discount_net_usage_den = context_free_discount_net_usage_den[median]; + + parameters.max_block_cpu_usage = max_block_cpu_usage[median]; + parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; + parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; - parameters.per_lock_net_usage = per_lock_net_usage[median]; parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; - parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; - parameters.max_transaction_net_usage = max_transaction_net_usage[median]; - parameters.max_block_cpu_usage = max_block_cpu_usage[median]; - parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; - parameters.max_block_net_usage = max_block_net_usage[median]; - parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; + parameters.max_transaction_lifetime = max_transaction_lifetime[median]; - parameters.max_transaction_exec_time = max_transaction_exec_time[median]; - parameters.max_authority_depth = max_authority_depth[median]; - parameters.max_inline_depth = max_inline_depth[median]; + parameters.deferred_trx_expiration_window = deferred_trx_expiration_window[median]; + parameters.max_transaction_delay = max_transaction_delay[median]; parameters.max_inline_action_size = max_inline_action_size[median]; + parameters.max_inline_action_depth = max_inline_action_depth[median]; + parameters.max_authority_depth = max_authority_depth[median]; parameters.max_generated_transaction_count = max_generated_transaction_count[median]; + + parameters.max_storage_size = max_storage_size[median]; parameters.storage_reserve_ratio = storage_reserve_ratio[median]; parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; @@ -378,6 +404,7 @@ namespace eosiosystem { set_blockchain_parameters(parameters); global_state_singleton::set(parameters); } +#endif ACTION( SystemAccount, voteproducer ) { account_name voter; From e1d24083702447a1ab2f0c77c5cba13637a9f944 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 29 Apr 2018 14:51:50 -0400 Subject: [PATCH 0186/1048] Update System Contract & cleos - udpate system contract to set initial account bw to 0 - update system contract to process new on block header - update cleos api and get info api --- delegate_bandwidth.cpp | 12 +++++++++--- eosio.system.cpp | 3 ++- eosio.system.hpp | 14 +++++++------- native.hpp | 12 +++++++++--- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 95cc6c61..dce34efe 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -77,14 +77,16 @@ namespace eosiosystem { typedef eosio::multi_index< N(refunds), refund_request> refunds_table; void system_contract::delegatebw( const account_name from, const account_name receiver, - const asset stake_net_quantity, const asset stake_cpu_quantity, - const asset stake_storage_quantity ) + const asset& stake_net_quantity, const asset& stake_cpu_quantity, + const asset& stake_storage_quantity ) { eosio_assert( stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( stake_net_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( stake_storage_quantity.amount >= 0, "must stake a positive amount" ); + print( "adding stake...", stake_net_quantity, " ", stake_cpu_quantity, " ", stake_storage_quantity ); asset total_stake = stake_cpu_quantity + stake_net_quantity + stake_storage_quantity; + print( "\ntotal stake: ", total_stake ); eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); require_auth( from ); @@ -95,6 +97,9 @@ namespace eosiosystem { global_state_singleton gs( _self, _self ); auto parameters = gs.exists() ? gs.get() : get_default_parameters(); const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); + + print( "token supply: ", token_supply, " " ); + //make sure that there is no posibility of overflow here int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) * int64_t(parameters.storage_reserve_ratio) * stake_storage_quantity @@ -107,6 +112,7 @@ namespace eosiosystem { eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); parameters.total_storage_bytes_reserved += uint64_t(storage_bytes); + print( "\ntotal storage stake: ", parameters.total_storage_stake ); parameters.total_storage_stake += stake_storage_quantity; gs.set( parameters, _self ); } @@ -151,7 +157,7 @@ namespace eosiosystem { }); } - //set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.quantity, tot_itr->cpu_weight.quantity ); + set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio), total_stake, std::string("stake bandwidth") } ); diff --git a/eosio.system.cpp b/eosio.system.cpp index 6dfcd869..7091b4e0 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -10,7 +10,8 @@ EOSIO_ABI( eosiosystem::system_contract, (delegatebw)(undelegatebw)(refund) (regproxy) // voting.cpp - (unregproxy)(regproducer)(unregprod)(voteproducer)(onblock) + (unregproxy)(regproducer)(unregprod)(voteproducer) + (onblock) // producer_pay.cpp (claimrewards) // native.hpp diff --git a/eosio.system.hpp b/eosio.system.hpp index c994b5c0..1acf3f83 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -25,13 +25,12 @@ namespace eosiosystem { time timestamp; checksum256 transaction_mroot; checksum256 action_mroot; - checksum256 block_mroot; account_name producer; uint32_t schedule_version; eosio::optional new_producers; // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot)(block_mroot) + EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot) (producer)(schedule_version)(new_producers)) }; @@ -99,8 +98,8 @@ namespace eosiosystem { // functions defined in delegate_bandwidth.cpp void delegatebw( const account_name from, const account_name receiver, - const asset stake_net_quantity, const asset stake_cpu_quantity, - const asset stake_storage_quantity ); + const asset& stake_net_quantity, const asset& stake_cpu_quantity, + const asset& stake_storage_quantity ); void undelegatebw( const account_name from, const account_name receiver, const asset unstake_net_quantity, const asset unstake_cpu_quantity, @@ -114,9 +113,6 @@ namespace eosiosystem { void unregprod( const account_name producer ); - eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate); - - void update_elected_producers(time cycle_time); void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); @@ -133,6 +129,10 @@ namespace eosiosystem { void claimrewards( const account_name& owner ); private: + eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate); + + void update_elected_producers(time cycle_time); + // Implementation details: //defined in voting.hpp diff --git a/native.hpp b/native.hpp index 872ae49b..1c09567a 100644 --- a/native.hpp +++ b/native.hpp @@ -7,6 +7,8 @@ #include #include #include +#include +#include namespace eosiosystem { using eosio::permission_level; @@ -47,11 +49,15 @@ namespace eosiosystem { class native { public: - void newaccount( /*account_name creator, - account_name name, + void newaccount( account_name creator, + account_name newact + /* const authority& owner, const authority& active, - const authority& recovery*/ ) {} + const authority& recovery*/ ) { + eosio::print( eosio::name{creator}, " created ", eosio::name{newact}); + set_resource_limits( newact, 1000, 0, 0 ); + } void updateauth( /*account_name account, permission_name permission, From 6ac31172188b8fa5ca8bf5fbcb743b16ff8e5bdc Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 29 Apr 2018 16:17:40 -0400 Subject: [PATCH 0187/1048] clean up producer reg and producer info table --- delegate_bandwidth.cpp | 22 +++++++++++++--- eosio.system.abi | 20 ++++++++++---- eosio.system.cpp | 1 + eosio.system.hpp | 15 ++++++----- voting.cpp | 60 ++++++++++++------------------------------ voting.hpp | 58 ++-------------------------------------- 6 files changed, 62 insertions(+), 114 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index dce34efe..bc22840f 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -98,7 +98,9 @@ namespace eosiosystem { auto parameters = gs.exists() ? gs.get() : get_default_parameters(); const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); - print( "token supply: ", token_supply, " " ); + print( " token supply: ", token_supply, " \n" ); + print( " max storage size: ", parameters.max_storage_size, "\n"); + print( " total reserved: ", parameters.total_storage_bytes_reserved, "\n"); //make sure that there is no posibility of overflow here int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) @@ -112,7 +114,7 @@ namespace eosiosystem { eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); parameters.total_storage_bytes_reserved += uint64_t(storage_bytes); - print( "\ntotal storage stake: ", parameters.total_storage_stake ); + print( "\ntotal storage stake: ", parameters.total_storage_stake, "\n" ); parameters.total_storage_stake += stake_storage_quantity; gs.set( parameters, _self ); } @@ -168,6 +170,20 @@ namespace eosiosystem { } // delegatebw + void system_contract::setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ) { + require_auth( _self ); + + eosio_assert( storage_reserve_ratio > 0, "invalid reserve ratio" ); + + global_state_singleton gs( _self, _self ); + auto parameters = gs.exists() ? gs.get() : get_default_parameters(); + + eosio_assert( max_storage_size > parameters.total_storage_bytes_reserved, "attempt to set max below reserved" ); + + parameters.max_storage_size = max_storage_size; + parameters.storage_reserve_ratio = storage_reserve_ratio; + gs.set( parameters, _self ); + } void system_contract::undelegatebw( const account_name from, const account_name receiver, const asset unstake_net_quantity, const asset unstake_cpu_quantity, @@ -218,7 +234,7 @@ namespace eosiosystem { tot.storage_bytes -= unstake_storage_bytes; }); - //set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.quantity, totals.cpu_weight.quantity ); + set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.amount, totals.cpu_weight.amount ); refunds_table refunds_tbl( _self, from ); //create refund request diff --git a/eosio.system.abi b/eosio.system.abi index f7aebf4c..092fce99 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -140,18 +140,17 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"total_votes", "type":"uint128"}, - {"name":"prefs", "type":"eosio_parameters"}, - {"name":"packed_key", "type":"uint8[]"}, + {"name":"packed_key", "type":"public_key"}, {"name":"per_block_payments", "type":"uint64"}, - {"name":"last_claim_time", "type":"uint32"} + {"name":"last_claim_time", "type":"time"} ] },{ "name": "regproducer", "base": "", "fields": [ {"name":"producer", "type":"account_name"}, - {"name":"producer_key", "type":"bytes"}, - {"name":"prefs", "type":"eosio_parameters"} + {"name":"producer_key", "type":"public_key"}, + {"name":"url", "type":"string"} ] },{ "name": "unregprod", @@ -159,6 +158,13 @@ "fields": [ {"name":"producer", "type":"account_name"} ] + },{ + "name": "setparams", + "base": "", + "fields": [ + {"name":"max_ram_size", "type":"uint64"} + {"name":"ram_reserve_ratio", "type":"uint32"} + ] },{ "name": "regproxy", "base": "", @@ -227,6 +233,10 @@ "name": "regproducer", "type": "regproducer", "ricardian_contract": "" + },{ + "name": "setparams", + "type": "setparams", + "ricardian_contract": "" },{ "name": "unregprod", "type": "unregprod", diff --git a/eosio.system.cpp b/eosio.system.cpp index 7091b4e0..08074ea6 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -6,6 +6,7 @@ #include "voting.cpp" EOSIO_ABI( eosiosystem::system_contract, + (setparams) // delegate_bandwith.cpp (delegatebw)(undelegatebw)(refund) (regproxy) diff --git a/eosio.system.hpp b/eosio.system.hpp index 1acf3f83..50e8ab7f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -35,9 +35,9 @@ namespace eosiosystem { }; struct eosio_parameters : eosio::blockchain_parameters { - uint64_t max_storage_size = 10 * 1024 * 1024; + uint64_t max_storage_size = 1024 * 1024 * 1024; uint32_t percent_of_max_inflation_rate = 0; - uint32_t storage_reserve_ratio = 1000; // ratio * 1000 + uint32_t storage_reserve_ratio = 2000; // ratio * 1000 // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_storage_size)(percent_of_max_inflation_rate)(storage_reserve_ratio) ) @@ -62,8 +62,7 @@ namespace eosiosystem { struct producer_info { account_name owner; uint128_t total_votes = 0; - eosio_parameters prefs; - eosio::bytes packed_key; /// a packed public key object + eosio::public_key producer_key; /// a packed public key object eosio::asset per_block_payments; time last_rewards_claim = 0; time time_became_active = 0; @@ -71,10 +70,10 @@ namespace eosiosystem { uint64_t primary_key()const { return owner; } uint128_t by_votes()const { return total_votes; } - bool active() const { return 0 < packed_key.size(); } + bool active() const { return producer_key != public_key(); } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key) (per_block_payments)(last_rewards_claim) (time_became_active)(last_produced_block_time) ) }; @@ -109,10 +108,12 @@ namespace eosiosystem { // functions defined in voting.cpp - void regproducer( const account_name producer, const bytes& producer_key, const eosio_parameters& prefs ); + void regproducer( const account_name producer, const public_key& producer_key, const std::string& url ); void unregprod( const account_name producer ); + void setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ); + void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); diff --git a/voting.cpp b/voting.cpp index c1a66c04..ab1462f0 100644 --- a/voting.cpp +++ b/voting.cpp @@ -59,27 +59,25 @@ namespace eosiosystem { * @pre authority of producer to register * */ - void system_contract::regproducer( const account_name producer, const bytes& packed_producer_key, const eosio_parameters& prefs ) { + void system_contract::regproducer( const account_name producer, const public_key& producer_key, const std::string& url ) { //, const eosio_parameters& prefs ) { + eosio_assert( url.size() < 1024, "url too long" ); //eosio::print("produce_key: ", producer_key.size(), ", sizeof(public_key): ", sizeof(public_key), "\n"); require_auth( producer ); producers_table producers_tbl( _self, _self ); auto prod = producers_tbl.find( producer ); - //check that we can unpack producer key - public_key producer_key = eosio::unpack( packed_producer_key ); - if ( prod != producers_tbl.end() ) { - producers_tbl.modify( prod, producer, [&]( producer_info& info ){ - info.prefs = prefs; - info.packed_key = eosio::pack( producer_key ); - }); + if( producer_key != prod->producer_key ) { + producers_tbl.modify( prod, producer, [&]( producer_info& info ){ + info.producer_key = producer_key; + }); + } } else { producers_tbl.emplace( producer, [&]( producer_info& info ){ info.owner = producer; info.total_votes = 0; - info.prefs = prefs; - info.packed_key = eosio::pack( producer_key ); + info.producer_key = producer_key; }); } } @@ -92,7 +90,7 @@ namespace eosiosystem { eosio_assert( prod != producers_tbl.end(), "producer not found" ); producers_tbl.modify( prod, 0, [&]( producer_info& info ){ - info.packed_key.clear(); + info.producer_key = public_key(); }); } @@ -205,6 +203,7 @@ namespace eosiosystem { producers_table producers_tbl( _self, _self ); auto idx = producers_tbl.template get_index(); + /* std::array max_block_net_usage; std::array target_block_net_usage_pct; std::array base_per_transaction_net_usage; @@ -233,6 +232,7 @@ namespace eosiosystem { std::array max_storage_size; std::array percent_of_max_inflation_rate; std::array storage_reserve_ratio; + */ eosio::producer_schedule schedule; schedule.producers.reserve(21); @@ -242,9 +242,10 @@ namespace eosiosystem { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; //eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); - schedule.producers.back().block_signing_key = eosio::unpack( it->packed_key ); + schedule.producers.back().block_signing_key = it->producer_key; //std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data.data() ); + /* max_block_net_usage[n] = it->prefs.max_block_net_usage; target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; @@ -273,51 +274,23 @@ namespace eosiosystem { max_storage_size[n] = it->prefs.max_storage_size; storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; + */ ++n; } } if ( n == 0 ) { //no active producers with votes > 0 return; } - if ( 1 < n ) { - std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); - std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); - std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); - std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); - std::sort( context_free_discount_net_usage_num.begin(), context_free_discount_net_usage_num.begin()+n ); - std::sort( context_free_discount_net_usage_den.begin(), context_free_discount_net_usage_den.begin()+n ); - - std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); - std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); - std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); - std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); - std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); - std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); - std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); - std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); - std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); - - std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); - std::sort( deferred_trx_expiration_window.begin(), deferred_trx_expiration_window.begin()+n ); - std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); - std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); - std::sort( max_inline_action_depth.begin(), max_inline_action_depth.begin()+n ); - std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); - std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); - - std::sort( max_storage_size.begin(), max_storage_size.begin()+n ); - std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); - std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); - } // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp bytes packed_schedule = pack(schedule); set_active_producers( packed_schedule.data(), packed_schedule.size() ); - size_t median = n/2; + // size_t median = n/2; global_state_singleton gs( _self, _self ); auto parameters = gs.exists() ? gs.get() : get_default_parameters(); + /* parameters.max_block_net_usage = max_block_net_usage[median]; parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; parameters.max_transaction_net_usage = max_transaction_net_usage[median]; @@ -346,6 +319,7 @@ namespace eosiosystem { parameters.max_storage_size = max_storage_size[median]; parameters.storage_reserve_ratio = storage_reserve_ratio[median]; parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; + */ // not voted on parameters.first_block_time_in_cycle = cycle_time; diff --git a/voting.hpp b/voting.hpp index ed521d83..acd7fc18 100644 --- a/voting.hpp +++ b/voting.hpp @@ -45,7 +45,7 @@ namespace eosiosystem { struct producer_info { account_name owner; uint128_t total_votes = 0; - eosio_parameters prefs; + // eosio_parameters prefs; eosio::bytes packed_key; /// a packed public key object system_token_type per_block_payments; time last_rewards_claim = 0; @@ -56,7 +56,7 @@ namespace eosiosystem { uint128_t by_votes()const { return total_votes; } bool active() const { return packed_key.size() == sizeof(public_key); } - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(prefs)(packed_key) + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(packed_key) (per_block_payments)(last_rewards_claim) (time_became_active)(last_produced_block_time) ) }; @@ -86,60 +86,6 @@ namespace eosiosystem { typedef eosio::multi_index< N(voters), voter_info> voters_table; - ACTION( SystemAccount, regproducer ) { - account_name producer; - bytes producer_key; - eosio_parameters prefs; - - EOSLIB_SERIALIZE( regproducer, (producer)(producer_key)(prefs) ) - }; - - /** - * This method will create a producer_config and producer_info object for 'producer' - * - * @pre producer is not already registered - * @pre producer to register is an account - * @pre authority of producer to register - * - */ - static void on( const regproducer& reg ) { - require_auth( reg.producer ); - - producers_table producers_tbl( SystemAccount, SystemAccount ); - auto prod = producers_tbl.find( reg.producer ); - - if ( prod != producers_tbl.end() ) { - producers_tbl.modify( prod, reg.producer, [&]( producer_info& info ){ - info.prefs = reg.prefs; - info.packed_key = reg.producer_key; - }); - } else { - producers_tbl.emplace( reg.producer, [&]( producer_info& info ){ - info.owner = reg.producer; - info.total_votes = 0; - info.prefs = reg.prefs; - info.packed_key = reg.producer_key; - }); - } - } - - ACTION( SystemAccount, unregprod ) { - account_name producer; - - EOSLIB_SERIALIZE( unregprod, (producer) ) - }; - - static void on( const unregprod& unreg ) { - require_auth( unreg.producer ); - - producers_table producers_tbl( SystemAccount, SystemAccount ); - auto prod = producers_tbl.find( unreg.producer ); - eosio_assert( prod != producers_tbl.end(), "producer not found" ); - - producers_tbl.modify( prod, 0, [&]( producer_info& info ){ - info.packed_key.clear(); - }); - } static void increase_voting_power( account_name acnt, system_token_type amount ) { voters_table voters_tbl( SystemAccount, SystemAccount ); From 9b4b52ebe233a8f1015b5b2f29aaa37aaa0e26c3 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 29 Apr 2018 16:55:04 -0400 Subject: [PATCH 0188/1048] update abi for system contract to support voters table --- eosio.system.abi | 8 +++++++- voting.cpp | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 092fce99..aa964db3 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -191,7 +191,7 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"proxy", "type":"account_name"}, - {"name":"last_update", "type":"uint32"}, + {"name":"last_update", "type":"time"}, {"name":"is_proxy", "type":"uint32"}, {"name":"staked", "type":"asset"}, {"name":"unstaking", "type":"asset"}, @@ -269,6 +269,12 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["uint64"] + },{ + "name": "voters", + "type": "voter_info", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["account_name"] },{ "name": "totalband", "type": "total_resources", diff --git a/voting.cpp b/voting.cpp index ab1462f0..1779cb74 100644 --- a/voting.cpp +++ b/voting.cpp @@ -60,7 +60,7 @@ namespace eosiosystem { * */ void system_contract::regproducer( const account_name producer, const public_key& producer_key, const std::string& url ) { //, const eosio_parameters& prefs ) { - eosio_assert( url.size() < 1024, "url too long" ); + eosio_assert( url.size() < 512, "url too long" ); //eosio::print("produce_key: ", producer_key.size(), ", sizeof(public_key): ", sizeof(public_key), "\n"); require_auth( producer ); From e3fa1e0e84ab163106ad9a9977e01e92bce8a21f Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 29 Apr 2018 17:55:09 -0400 Subject: [PATCH 0189/1048] you may only delegate storage to yourself --- delegate_bandwidth.cpp | 7 ++- eosio.system.abi | 6 +++ voting.cpp | 96 ------------------------------------------ 3 files changed, 12 insertions(+), 97 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index bc22840f..3e5ebf75 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -80,16 +80,21 @@ namespace eosiosystem { const asset& stake_net_quantity, const asset& stake_cpu_quantity, const asset& stake_storage_quantity ) { + require_auth( from ); + eosio_assert( stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( stake_net_quantity.amount >= 0, "must stake a positive amount" ); eosio_assert( stake_storage_quantity.amount >= 0, "must stake a positive amount" ); + if( stake_storage_quantity.amount > 0 ) { + eosio_assert( from == receiver, "you may only stake storage to yourself" ); + } + print( "adding stake...", stake_net_quantity, " ", stake_cpu_quantity, " ", stake_storage_quantity ); asset total_stake = stake_cpu_quantity + stake_net_quantity + stake_storage_quantity; print( "\ntotal stake: ", total_stake ); eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); - require_auth( from ); //eosio_assert( is_account( receiver ), "can only delegate resources to an existing account" ); int64_t storage_bytes = 0; diff --git a/eosio.system.abi b/eosio.system.abi index aa964db3..f231f700 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -269,6 +269,12 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["uint64"] + },{ + "name": "global", + "type": "eosio_global_state", + "index_type": "i64", + "key_names" : [], + "key_types" : [] },{ "name": "voters", "type": "voter_info", diff --git a/voting.cpp b/voting.cpp index 1779cb74..3a1f6db2 100644 --- a/voting.cpp +++ b/voting.cpp @@ -203,37 +203,6 @@ namespace eosiosystem { producers_table producers_tbl( _self, _self ); auto idx = producers_tbl.template get_index(); - /* - std::array max_block_net_usage; - std::array target_block_net_usage_pct; - std::array base_per_transaction_net_usage; - std::array max_transaction_net_usage; - std::array context_free_discount_net_usage_num; - std::array context_free_discount_net_usage_den; - - std::array max_block_cpu_usage; - std::array target_block_cpu_usage_pct; - std::array max_transaction_cpu_usage; - std::array base_per_transaction_cpu_usage; - std::array base_per_action_cpu_usage; - std::array base_setcode_cpu_usage; - std::array per_signature_cpu_usage; - std::array context_free_discount_cpu_usage_num; - std::array context_free_discount_cpu_usage_den; - - std::array max_transaction_lifetime; - std::array deferred_trx_expiration_window; - std::array max_transaction_delay; - std::array max_inline_action_size; - std::array max_inline_action_depth; - std::array max_authority_depth; - std::array max_generated_transaction_count; - - std::array max_storage_size; - std::array percent_of_max_inflation_rate; - std::array storage_reserve_ratio; - */ - eosio::producer_schedule schedule; schedule.producers.reserve(21); size_t n = 0; @@ -241,40 +210,7 @@ namespace eosiosystem { if ( it->active() ) { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; - //eosio_assert( sizeof(schedule.producers.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); schedule.producers.back().block_signing_key = it->producer_key; - //std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.producers.back().block_signing_key.data.data() ); - - /* - max_block_net_usage[n] = it->prefs.max_block_net_usage; - target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; - max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; - base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; - context_free_discount_net_usage_num[n] = it->prefs.context_free_discount_net_usage_num; - context_free_discount_net_usage_den[n] = it->prefs.context_free_discount_net_usage_den; - - max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; - target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; - max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; - base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; - base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; - base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; - per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; - context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; - context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; - - max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; - deferred_trx_expiration_window[n] = it->prefs.deferred_trx_expiration_window; - max_transaction_delay[n] = it->prefs.max_transaction_delay; - max_inline_action_size[n] = it->prefs.max_inline_action_size; - max_inline_action_depth[n] = it->prefs.max_inline_action_depth; - max_authority_depth[n] = it->prefs.max_authority_depth; - max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; - - max_storage_size[n] = it->prefs.max_storage_size; - storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; - percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; - */ ++n; } } @@ -285,42 +221,10 @@ namespace eosiosystem { // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp bytes packed_schedule = pack(schedule); set_active_producers( packed_schedule.data(), packed_schedule.size() ); - // size_t median = n/2; global_state_singleton gs( _self, _self ); auto parameters = gs.exists() ? gs.get() : get_default_parameters(); - /* - parameters.max_block_net_usage = max_block_net_usage[median]; - parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; - parameters.max_transaction_net_usage = max_transaction_net_usage[median]; - parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; - parameters.context_free_discount_net_usage_num = context_free_discount_net_usage_num[median]; - parameters.context_free_discount_net_usage_den = context_free_discount_net_usage_den[median]; - - parameters.max_block_cpu_usage = max_block_cpu_usage[median]; - parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; - parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; - parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; - parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; - parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; - parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; - parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; - parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; - - parameters.max_transaction_lifetime = max_transaction_lifetime[median]; - parameters.deferred_trx_expiration_window = deferred_trx_expiration_window[median]; - parameters.max_transaction_delay = max_transaction_delay[median]; - parameters.max_inline_action_size = max_inline_action_size[median]; - parameters.max_inline_action_depth = max_inline_action_depth[median]; - parameters.max_authority_depth = max_authority_depth[median]; - parameters.max_generated_transaction_count = max_generated_transaction_count[median]; - - parameters.max_storage_size = max_storage_size[median]; - parameters.storage_reserve_ratio = storage_reserve_ratio[median]; - parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; - */ - // not voted on parameters.first_block_time_in_cycle = cycle_time; From 91cf9208f1fece398fbb9a92b1aa622716e009f5 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Mon, 30 Apr 2018 11:32:20 -0400 Subject: [PATCH 0190/1048] Fix missing comma --- eosio.system.abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index f231f700..1b807381 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -162,7 +162,7 @@ "name": "setparams", "base": "", "fields": [ - {"name":"max_ram_size", "type":"uint64"} + {"name":"max_ram_size", "type":"uint64"}, {"name":"ram_reserve_ratio", "type":"uint32"} ] },{ From e5b1193b49e1a2dd7d0458d6ee0c24d66aa8e735 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 30 Apr 2018 18:39:22 -0400 Subject: [PATCH 0191/1048] progressS --- eosio.system.hpp | 94 ++++++++++++++++++++++++----------------- native.hpp | 107 +++++++++++++++++++++++++++++------------------ 2 files changed, 123 insertions(+), 78 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 50e8ab7f..6e244658 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -4,7 +4,7 @@ */ #pragma once -#include "native.hpp" +#include #include #include #include @@ -20,20 +20,6 @@ namespace eosiosystem { using eosio::indexed_by; using eosio::const_mem_fun; - struct block_header { - checksum256 previous; - time timestamp; - checksum256 transaction_mroot; - checksum256 action_mroot; - account_name producer; - uint32_t schedule_version; - eosio::optional new_producers; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot) - (producer)(schedule_version)(new_producers)) - }; - struct eosio_parameters : eosio::blockchain_parameters { uint64_t max_storage_size = 1024 * 1024 * 1024; uint32_t percent_of_max_inflation_rate = 0; @@ -60,17 +46,17 @@ namespace eosiosystem { }; struct producer_info { - account_name owner; - uint128_t total_votes = 0; - eosio::public_key producer_key; /// a packed public key object - eosio::asset per_block_payments; - time last_rewards_claim = 0; - time time_became_active = 0; - time last_produced_block_time = 0; - - uint64_t primary_key()const { return owner; } - uint128_t by_votes()const { return total_votes; } - bool active() const { return producer_key != public_key(); } + account_name owner; + double total_votes = 0; + eosio::public_key producer_key; /// a packed public key object + eosio::asset per_block_payments; + time last_rewards_claim = 0; + time time_became_active = 0; + time last_produced_block_time = 0; + + uint64_t primary_key()const { return owner; } + double by_votes()const { return -total_votes; } + bool active() const { return producer_key != public_key(); } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key) @@ -79,7 +65,7 @@ namespace eosiosystem { }; typedef eosio::multi_index< N(producerinfo), producer_info, - indexed_by > + indexed_by > > producers_table; typedef eosio::singleton global_state_singleton; @@ -88,23 +74,55 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint64_t system_token_symbol = S(4,EOS); - class system_contract : public native, private eosio::contract { + class system_contract : public native { public: - using eosio::contract::contract; // Actions: // functions defined in delegate_bandwidth.cpp - void delegatebw( const account_name from, const account_name receiver, - const asset& stake_net_quantity, const asset& stake_cpu_quantity, - const asset& stake_storage_quantity ); - - void undelegatebw( const account_name from, const account_name receiver, - const asset unstake_net_quantity, const asset unstake_cpu_quantity, - const uint64_t unstake_storage_bytes ); - - void refund( const account_name owner ); + void delegatebw( account_name from, account_name receiver, + asset stake_net_quantity, asset stake_cpu_quantity ); + + + /** + * Decreases the total tokens delegated by from to receiver and/or + * frees the memory associated with the delegation if there is nothing + * left to delegate. + * + * This will cause an immediate reduction in net/cpu bandwidth of the + * receiver. + * + * A transaction is scheduled to send the tokens back to 'from' after + * the staking period has passed. If existing transaction is scheduled, it + * will be canceled and a new transaction issued that has the combined + * undelegated amount. + * + * The 'from' account loses voting power as a result of this call and + * all producer tallies are updated. + */ + void undelegatebw( account_name from, account_name receiver, + asset unstake_net_quantity, asset unstake_cpu_quantity ); + + + /** + * Increases receiver's ram quota based upon current price and quantity of + * tokens provided. An inline transfer from receiver to system contract of + * tokens will be executed. + */ + void buyram( account_name buyer, account_name receiver, asset tokens ); + + /** + * Reduces quota my bytes and then performs an inline transfer of tokens + * to receiver based upon the average purchase price of the original quota. + */ + void sellram( account_name receiver, uint32_t bytes ); + + /** + * This action is called after the delegation-period to claim all pending + * unstaked tokens belonging to owner + */ + void refund( account_name owner ); // functions defined in voting.cpp diff --git a/native.hpp b/native.hpp index 1c09567a..749ce6bb 100644 --- a/native.hpp +++ b/native.hpp @@ -42,50 +42,77 @@ namespace eosiosystem { EOSLIB_SERIALIZE( authority, (threshold)(delay_sec)(keys)(accounts) ) }; + struct block_header { + checksum256 previous; + time timestamp; + checksum256 transaction_mroot; + checksum256 action_mroot; + account_name producer; + uint32_t schedule_version; + eosio::optional new_producers; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot) + (producer)(schedule_version)(new_producers)) + }; + + /* - * Empty handlers for native messages. * Method parameters commented out to prevent generation of code that parses input data. */ - class native { + class native : public eosio::contract { public: - - void newaccount( account_name creator, - account_name newact - /* - const authority& owner, - const authority& active, - const authority& recovery*/ ) { - eosio::print( eosio::name{creator}, " created ", eosio::name{newact}); - set_resource_limits( newact, 1000, 0, 0 ); - } - - void updateauth( /*account_name account, - permission_name permission, - permission_name parent, - const authority& data*/ ) {} - - void deleteauth( /*account_name account, permission_name permission*/ ) {} - - void linkauth( /*account_name account, - account_name code, - action_name type, - permission_name requirement*/ ) {} - - void unlinkauth( /*account_name account, - account_name code, - action_name type*/ ) {} - - void postrecovery( /*account_name account, - const authority& data, - const std::string& memo*/ ) {} - - void passrecovery( /*account_name account*/ ) {} - - void vetorecovery( /*account_name account*/ ) {} - - void onerror( /*const bytes&*/ ) {} - - void canceldelay( /*permission_level canceling_auth, transaction_id_type trx_id*/ ) {} + using eosio::contract::contract; + + /** + * Called after a new account is created. This code enforces resource-limits rules + * for new accounts as well as new account naming conventions. + * + * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 + * characters long without '.' until a future account auction process is implemented + * which prevents name squatting. + * + * 2. new accounts must stake a minimal number of tokens (as set in system parameters) + * therefore, this method will execute an inline buyram from receiver for newacnt in + * an amount equal to the current new account creation fee. + */ + void newaccount( account_name creator, + account_name newact + /* no need to parse authorites + const authority& owner, + const authority& active, + const authority& recovery*/ ) { + eosio::print( eosio::name{creator}, " created ", eosio::name{newact}); + set_resource_limits( newact, 1000, 0, 0 ); + } + + void updateauth( /*account_name account, + permission_name permission, + permission_name parent, + const authority& data*/ ) {} + + void deleteauth( /*account_name account, permission_name permission*/ ) {} + + void linkauth( /*account_name account, + account_name code, + action_name type, + permission_name requirement*/ ) {} + + void unlinkauth( /*account_name account, + account_name code, + action_name type*/ ) {} + + void postrecovery( /*account_name account, + const authority& data, + const std::string& memo*/ ) {} + + void passrecovery( /*account_name account*/ ) {} + + void vetorecovery( /*account_name account*/ ) {} + + void onerror( /*const bytes&*/ ) {} + + void canceldelay( /*permission_level canceling_auth, transaction_id_type trx_id*/ ) {} }; } From 88584c56eafc26e993002a8f17f4e6769d71bb2e Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 30 Apr 2018 21:12:48 -0400 Subject: [PATCH 0192/1048] replace eager memory usage checks with a deferred check at the end of the transaction --- native.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/native.hpp b/native.hpp index 1c09567a..0855f7f2 100644 --- a/native.hpp +++ b/native.hpp @@ -56,7 +56,10 @@ namespace eosiosystem { const authority& active, const authority& recovery*/ ) { eosio::print( eosio::name{creator}, " created ", eosio::name{newact}); - set_resource_limits( newact, 1000, 0, 0 ); + set_resource_limits( newact, 3000, 0, 0 ); + // TODO: The 3000 initial ram usage is a hack to get tests to work for now. + // When we add support in the system contract to buy storage for another user, we will need to replace the + // 3000 with 0 and modify the tester to gift the necessary storage amount to all created accounts. } void updateauth( /*account_name account, From c6922ee25c27b1d9f6df47ec89ee3cfd544018ec Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 30 Apr 2018 23:31:30 -0400 Subject: [PATCH 0193/1048] clean up eosio.system contract - buy & sell ram using bancor algorithm - ram is no longer delgated - fixed warning with double secondary index - add block_timestamp_type --- delegate_bandwidth.cpp | 235 ++++++++++++++++++++++++----------------- eosio.system.cpp | 3 +- eosio.system.hpp | 24 ++--- native.hpp | 16 +-- producer_pay.cpp | 40 +++---- voting.cpp | 21 ++-- 6 files changed, 184 insertions(+), 155 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 3e5ebf75..09537444 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -14,6 +14,8 @@ #include + +#include #include namespace eosiosystem { @@ -29,17 +31,16 @@ namespace eosiosystem { static constexpr time refund_delay = 3*24*3600; static constexpr time refund_expiration_time = 3600; - struct total_resources { + struct user_resources { account_name owner; asset net_weight; asset cpu_weight; - asset storage_stake; uint64_t storage_bytes = 0; uint64_t primary_key()const { return owner; } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( total_resources, (owner)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) + EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(storage_bytes) ) }; @@ -51,13 +52,11 @@ namespace eosiosystem { account_name to; asset net_weight; asset cpu_weight; - asset storage_stake; - uint64_t storage_bytes = 0; uint64_t primary_key()const { return to; } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight)(storage_stake)(storage_bytes) ) + EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) ) }; @@ -72,57 +71,124 @@ namespace eosiosystem { EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(amount) ) }; - typedef eosio::multi_index< N(totalband), total_resources> total_resources_table; + typedef eosio::multi_index< N(userres), user_resources> user_resources_table; typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_table; typedef eosio::multi_index< N(refunds), refund_request> refunds_table; - void system_contract::delegatebw( const account_name from, const account_name receiver, - const asset& stake_net_quantity, const asset& stake_cpu_quantity, - const asset& stake_storage_quantity ) + + + /** + * When buying ram the payer irreversiblly transfers quant to system contract and only + * the receiver may reclaim the tokens via the sellram action. The receiver pays for the + * storage of all database records associated with this action. + * + * RAM is a scarce resource whose supply is defined by global properties max_storage_size. RAM is + * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. + */ + void system_contract::buyram( account_name payer, account_name receiver, asset quant ) { - require_auth( from ); + require_auth( payer ); + eosio_assert( quant.amount > 0, "must purchase a positive amount" ); - eosio_assert( stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); - eosio_assert( stake_net_quantity.amount >= 0, "must stake a positive amount" ); - eosio_assert( stake_storage_quantity.amount >= 0, "must stake a positive amount" ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, + { payer, N(eosio), quant, std::string("buy ram") } ); + + global_state_singleton gstate_table( _self, _self ); + auto gstate = gstate_table.exists() ? gstate_table.get() : get_default_parameters(); - if( stake_storage_quantity.amount > 0 ) { - eosio_assert( from == receiver, "you may only stake storage to yourself" ); + const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; + const double unstaked_token_supply = system_token_supply - gstate.total_storage_stake.amount; + + const double E = quant.amount; + const double R = unstaked_token_supply - E; + const double C = gstate.free_ram(); //free_ram; + const double F = .10; /// 10% reserve ratio pricing, assumes only 10% of tokens will ever want to stake for ram + const double ONE(1.0); + + double T = C * (std::pow( ONE + E/R, F ) - ONE); + T *= .99; /// 1% fee on every conversion + int64_t bytes_out = static_cast(T); + + eosio_assert( bytes_out > 0, "must reserve a positive amount" ); + + gstate.total_storage_bytes_reserved += uint64_t(bytes_out); + gstate.total_storage_stake.amount += quant.amount; + + gstate_table.set( gstate, _self ); + + user_resources_table userres( _self, receiver ); + auto res_itr = userres.find( receiver ); + if( res_itr == userres.end() ) { + res_itr = userres.emplace( receiver, [&]( auto& res ) { + res.owner = receiver; + res.storage_bytes = uint64_t(bytes_out); + }); + } else { + userres.modify( res_itr, receiver, [&]( auto& res ) { + res.storage_bytes += uint64_t(bytes_out); + }); } + set_resource_limits( res_itr->owner, res_itr->storage_bytes, uint64_t(res_itr->net_weight.amount), uint64_t(res_itr->cpu_weight.amount) ); + } - print( "adding stake...", stake_net_quantity, " ", stake_cpu_quantity, " ", stake_storage_quantity ); - asset total_stake = stake_cpu_quantity + stake_net_quantity + stake_storage_quantity; - print( "\ntotal stake: ", total_stake ); - eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); + /** + * While buying ram uses the current market price according to the bancor-algorithm, selling ram only + * refunds the purchase price to the account. In this way there is no profit to be made through buying + * and selling ram. + */ + void system_contract::sellram( account_name account, uint64_t bytes ) { + user_resources_table userres( _self, account ); + auto res_itr = userres.find( account ); + eosio_assert( res_itr != userres.end(), "no resource row" ); + eosio_assert( res_itr->storage_bytes >= bytes, "insufficient quota" ); - //eosio_assert( is_account( receiver ), "can only delegate resources to an existing account" ); - int64_t storage_bytes = 0; - if ( 0 < stake_storage_quantity.amount ) { - global_state_singleton gs( _self, _self ); - auto parameters = gs.exists() ? gs.get() : get_default_parameters(); - const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); + global_state_singleton gstate_table( _self, _self ); + auto gstate = gstate_table.exists() ? gstate_table.get() : get_default_parameters(); - print( " token supply: ", token_supply, " \n" ); - print( " max storage size: ", parameters.max_storage_size, "\n"); - print( " total reserved: ", parameters.total_storage_bytes_reserved, "\n"); + const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; + const double unstaked_token_supply = system_token_supply - gstate.total_storage_stake.amount; - //make sure that there is no posibility of overflow here - int64_t storage_bytes_estimated = int64_t( parameters.max_storage_size - parameters.total_storage_bytes_reserved ) - * int64_t(parameters.storage_reserve_ratio) * stake_storage_quantity - / ( token_supply - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + const double R = unstaked_token_supply; + const double C = gstate.free_ram() + bytes; + const double F = .10; + const double T = bytes; + const double ONE(1.0); - storage_bytes = ( int64_t(parameters.max_storage_size) - int64_t(parameters.total_storage_bytes_reserved) - storage_bytes_estimated ) - * int64_t(parameters.storage_reserve_ratio) * stake_storage_quantity - / ( token_supply - stake_storage_quantity - parameters.total_storage_stake ) / 1000 /* reserve ratio coefficient */; + double E = -R * (ONE - std::pow( ONE + T/C, F ) ); - eosio_assert( 0 < storage_bytes, "stake is too small to increase storage even by 1 byte" ); + E *= .99; /// 1% fee on every conversion, + /// let the system contract profit on speculation while preventing abuse caused by rounding errors + + int64_t tokens_out = int64_t(E); + eosio_assert( tokens_out > 0, "must free at least one token" ); - parameters.total_storage_bytes_reserved += uint64_t(storage_bytes); - print( "\ntotal storage stake: ", parameters.total_storage_stake, "\n" ); - parameters.total_storage_stake += stake_storage_quantity; - gs.set( parameters, _self ); - } + gstate.total_storage_bytes_reserved -= bytes; + gstate.total_storage_stake.amount -= tokens_out; + + gstate_table.set( gstate, _self ); + + userres.modify( res_itr, account, [&]( auto& res ) { + res.storage_bytes -= bytes; + }); + set_resource_limits( res_itr->owner, res_itr->storage_bytes, uint64_t(res_itr->net_weight.amount), uint64_t(res_itr->cpu_weight.amount) ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), account, asset(tokens_out), std::string("sell ram") } ); + } + + void system_contract::delegatebw( account_name from, account_name receiver, + asset stake_net_quantity, + asset stake_cpu_quantity ) + + { + require_auth( from ); + + eosio_assert( stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); + eosio_assert( stake_net_quantity.amount >= 0, "must stake a positive amount" ); + + asset total_stake = stake_cpu_quantity + stake_net_quantity; + eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); del_bandwidth_table del_tbl( _self, from ); auto itr = del_tbl.find( receiver ); @@ -132,67 +198,40 @@ namespace eosiosystem { dbo.to = receiver; dbo.net_weight = stake_net_quantity; dbo.cpu_weight = stake_cpu_quantity; - dbo.storage_stake = stake_storage_quantity; - dbo.storage_bytes = uint64_t(storage_bytes); }); } else { del_tbl.modify( itr, from, [&]( auto& dbo ){ dbo.net_weight += stake_net_quantity; dbo.cpu_weight += stake_cpu_quantity; - dbo.storage_stake += stake_storage_quantity; - dbo.storage_bytes += uint64_t(storage_bytes); }); } - total_resources_table totals_tbl( _self, receiver ); + user_resources_table totals_tbl( _self, receiver ); auto tot_itr = totals_tbl.find( receiver ); if( tot_itr == totals_tbl.end() ) { tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { tot.owner = receiver; tot.net_weight = stake_net_quantity; tot.cpu_weight = stake_cpu_quantity; - tot.storage_stake = stake_storage_quantity; - tot.storage_bytes = uint64_t(storage_bytes); }); } else { totals_tbl.modify( tot_itr, from == receiver ? from : 0, [&]( auto& tot ) { tot.net_weight += stake_net_quantity; tot.cpu_weight += stake_cpu_quantity; - tot.storage_stake += stake_storage_quantity; - tot.storage_bytes += uint64_t(storage_bytes); }); } - set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, uint64_t(tot_itr->net_weight.amount), uint64_t(tot_itr->cpu_weight.amount) ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio), total_stake, std::string("stake bandwidth") } ); - if ( asset(0) < stake_net_quantity + stake_cpu_quantity ) { - increase_voting_power( from, stake_net_quantity + stake_cpu_quantity ); - } - + adjust_voting_power( from, (stake_net_quantity.amount + stake_cpu_quantity.amount) ); } // delegatebw - void system_contract::setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ) { - require_auth( _self ); - - eosio_assert( storage_reserve_ratio > 0, "invalid reserve ratio" ); - - global_state_singleton gs( _self, _self ); - auto parameters = gs.exists() ? gs.get() : get_default_parameters(); - - eosio_assert( max_storage_size > parameters.total_storage_bytes_reserved, "attempt to set max below reserved" ); - - parameters.max_storage_size = max_storage_size; - parameters.storage_reserve_ratio = storage_reserve_ratio; - gs.set( parameters, _self ); - } - - void system_contract::undelegatebw( const account_name from, const account_name receiver, - const asset unstake_net_quantity, const asset unstake_cpu_quantity, - const uint64_t unstake_storage_bytes ) + void system_contract::undelegatebw( account_name from, account_name receiver, + asset unstake_net_quantity, asset unstake_cpu_quantity ) { eosio_assert( unstake_cpu_quantity.amount >= 0, "must unstake a positive amount" ); eosio_assert( unstake_net_quantity.amount >= 0, "must unstake a positive amount" ); @@ -205,54 +244,38 @@ namespace eosiosystem { const auto& dbw = del_tbl.get( receiver ); eosio_assert( dbw.net_weight >= unstake_net_quantity, "insufficient staked net bandwidth" ); eosio_assert( dbw.cpu_weight >= unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); - eosio_assert( dbw.storage_bytes >= unstake_storage_bytes, "insufficient staked storage" ); - - eosio::asset storage_stake_decrease(0, system_token_symbol); - if ( 0 < unstake_storage_bytes ) { - storage_stake_decrease = 0 < dbw.storage_bytes ? - dbw.storage_stake * int64_t(unstake_storage_bytes) / int64_t(dbw.storage_bytes) - : eosio::asset(0, system_token_symbol); - global_state_singleton gs( _self, _self ); - auto parameters = gs.get(); //it should exist if user staked for bandwith - parameters.total_storage_bytes_reserved -= unstake_storage_bytes; - parameters.total_storage_stake -= storage_stake_decrease; - gs.set( parameters, _self ); - } - eosio::asset total_refund = unstake_cpu_quantity + unstake_net_quantity + storage_stake_decrease; + eosio::asset total_refund = unstake_cpu_quantity + unstake_net_quantity; eosio_assert( total_refund.amount > 0, "must unstake a positive amount" ); del_tbl.modify( dbw, from, [&]( auto& dbo ){ dbo.net_weight -= unstake_net_quantity; dbo.cpu_weight -= unstake_cpu_quantity; - dbo.storage_stake -= storage_stake_decrease; - dbo.storage_bytes -= unstake_storage_bytes; }); - total_resources_table totals_tbl( _self, receiver ); + user_resources_table totals_tbl( _self, receiver ); + const auto& totals = totals_tbl.get( receiver ); totals_tbl.modify( totals, 0, [&]( auto& tot ) { tot.net_weight -= unstake_net_quantity; tot.cpu_weight -= unstake_cpu_quantity; - tot.storage_stake -= storage_stake_decrease; - tot.storage_bytes -= unstake_storage_bytes; }); - set_resource_limits( totals.owner, totals.storage_bytes, totals.net_weight.amount, totals.cpu_weight.amount ); + set_resource_limits( totals.owner, totals.storage_bytes, uint64_t(totals.net_weight.amount), uint64_t(totals.cpu_weight.amount) ); refunds_table refunds_tbl( _self, from ); //create refund request auto req = refunds_tbl.find( from ); if ( req != refunds_tbl.end() ) { refunds_tbl.modify( req, 0, [&]( refund_request& r ) { - r.amount += unstake_net_quantity + unstake_cpu_quantity + storage_stake_decrease; + r.amount += unstake_net_quantity + unstake_cpu_quantity; r.request_time = now(); }); } else { refunds_tbl.emplace( from, [&]( refund_request& r ) { r.owner = from; - r.amount = unstake_net_quantity + unstake_cpu_quantity + storage_stake_decrease; + r.amount = unstake_net_quantity + unstake_cpu_quantity; r.request_time = now(); }); } @@ -264,9 +287,7 @@ namespace eosiosystem { out.delay_sec = refund_delay; out.send( from, receiver ); - if ( asset(0) < unstake_net_quantity + unstake_cpu_quantity ) { - decrease_voting_power( from, unstake_net_quantity + unstake_cpu_quantity ); - } + adjust_voting_power( from, -(unstake_net_quantity.amount + unstake_cpu_quantity.amount) ); } // undelegatebw @@ -288,4 +309,20 @@ namespace eosiosystem { refunds_tbl.erase( req ); } + + void system_contract::setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ) { + require_auth( _self ); + + eosio_assert( storage_reserve_ratio > 0, "invalid reserve ratio" ); + + global_state_singleton gs( _self, _self ); + auto parameters = gs.exists() ? gs.get() : get_default_parameters(); + + eosio_assert( max_storage_size > parameters.total_storage_bytes_reserved, "attempt to set max below reserved" ); + + parameters.max_storage_size = max_storage_size; + parameters.storage_reserve_ratio = storage_reserve_ratio; + gs.set( parameters, _self ); + } + } //namespace eosiosystem diff --git a/eosio.system.cpp b/eosio.system.cpp index 08074ea6..08a52754 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -9,14 +9,15 @@ EOSIO_ABI( eosiosystem::system_contract, (setparams) // delegate_bandwith.cpp (delegatebw)(undelegatebw)(refund) + (buyram)(sellram) (regproxy) // voting.cpp (unregproxy)(regproducer)(unregprod)(voteproducer) - (onblock) // producer_pay.cpp (claimrewards) // native.hpp //XXX + (onblock) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) // defined in eosio.system.hpp (nonce) diff --git a/eosio.system.hpp b/eosio.system.hpp index 6e244658..48fb5ca0 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -5,10 +5,7 @@ #pragma once #include -#include #include -#include -#include #include #include @@ -30,13 +27,17 @@ namespace eosiosystem { }; struct eosio_global_state : eosio_parameters { + uint64_t free_ram()const { return max_storage_size - total_storage_bytes_reserved; } + uint64_t total_storage_bytes_reserved = 0; eosio::asset total_storage_stake; eosio::asset payment_per_block; eosio::asset payment_to_eos_bucket; + time first_block_time_in_cycle = 0; uint32_t blocks_per_cycle = 0; time last_bucket_fill_time = 0; + eosio::asset eos_bucket; // explicit serialization macro is not necessary, used here only to improve compilation time @@ -76,9 +77,11 @@ namespace eosiosystem { class system_contract : public native { public: - using eosio::contract::contract; + using native::native; // Actions: + void onblock( const block_id_type&, uint32_t timestamp_slot, account_name producer ); + // const block_header& header ); /// only parse first 3 fields of block header // functions defined in delegate_bandwidth.cpp void delegatebw( account_name from, account_name receiver, @@ -116,7 +119,7 @@ namespace eosiosystem { * Reduces quota my bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. */ - void sellram( account_name receiver, uint32_t bytes ); + void sellram( account_name receiver, uint64_t bytes ); /** * This action is called after the delegation-period to claim all pending @@ -142,9 +145,6 @@ namespace eosiosystem { void nonce( const std::string& /*value*/ ) {} // functions defined in producer_pay.cpp - - void onblock( const block_header& header ); - void claimrewards( const account_name& owner ); private: @@ -158,13 +158,7 @@ namespace eosiosystem { static eosio_global_state get_default_parameters(); // defined in voting.cpp - void increase_voting_power( account_name acnt, const eosio::asset& amount ); - - void decrease_voting_power( account_name acnt, const eosio::asset& amount ); - - // defined in producer_pay.cpp - bool update_cycle( time block_time ); - + void adjust_voting_power( account_name acnt, int64_t delta ); }; } /// eosiosystem diff --git a/native.hpp b/native.hpp index 749ce6bb..d8fce79c 100644 --- a/native.hpp +++ b/native.hpp @@ -9,6 +9,9 @@ #include #include #include +#include +#include +#include namespace eosiosystem { using eosio::permission_level; @@ -43,17 +46,17 @@ namespace eosiosystem { }; struct block_header { - checksum256 previous; - time timestamp; + block_id_type previous; + uint32_t timestamp; + account_name producer; + uint32_t schedule_version = 0; checksum256 transaction_mroot; checksum256 action_mroot; - account_name producer; - uint32_t schedule_version; eosio::optional new_producers; // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(transaction_mroot)(action_mroot) - (producer)(schedule_version)(new_producers)) + EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(producer)(schedule_version)(transaction_mroot)(action_mroot) + (new_producers)) }; @@ -86,6 +89,7 @@ namespace eosiosystem { set_resource_limits( newact, 1000, 0, 0 ); } + void updateauth( /*account_name account, permission_name permission, permission_name parent, diff --git a/producer_pay.cpp b/producer_pay.cpp index 0feba7ca..c0402687 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -6,67 +6,55 @@ namespace eosiosystem { static const uint32_t num_of_payed_producers = 121; -bool system_contract::update_cycle(time block_time) { + +void system_contract::onblock( const block_id_type&, block_timestamp timestamp, account_name producer ) { + global_state_singleton gs( _self, _self ); auto parameters = gs.exists() ? gs.get() : get_default_parameters(); - if (parameters.first_block_time_in_cycle == 0) { + if( parameters.first_block_time_in_cycle == 0 ) { // This is the first time onblock is called in the blockchain. - parameters.last_bucket_fill_time = block_time; + parameters.last_bucket_fill_time = timestamp; gs.set( parameters, _self ); - update_elected_producers( block_time ); - return true; + update_elected_producers( timestamp ); } static const uint32_t slots_per_cycle = parameters.blocks_per_cycle; - const uint32_t time_slots = block_time - parameters.first_block_time_in_cycle; + const uint32_t time_slots = timestamp - parameters.first_block_time_in_cycle; if (time_slots >= slots_per_cycle) { - time beginning_of_cycle = block_time - (time_slots % slots_per_cycle); + auto beginning_of_cycle = timestamp - (time_slots % slots_per_cycle); update_elected_producers(beginning_of_cycle); - return true; } - return false; -} - -void system_contract::onblock(const block_header& header) { - // update parameters if it's a new cycle - update_cycle(header.timestamp); producers_table producers_tbl( _self, _self ); - account_name producer = header.producer; - global_state_singleton gs( _self, _self ); - auto parameters = gs.exists() ? gs.get() : get_default_parameters(); - // const system_token_type block_payment = parameters.payment_per_block; + // const system_token_type block_payment = parameters.payment_per_block; const asset block_payment = parameters.payment_per_block; auto prod = producers_tbl.find(producer); if ( prod != producers_tbl.end() ) { producers_tbl.modify( prod, 0, [&](auto& p) { p.per_block_payments += block_payment; - p.last_produced_block_time = header.timestamp; + p.last_produced_block_time = timestamp; }); } - const uint32_t num_of_payments = header.timestamp - parameters.last_bucket_fill_time; + const uint32_t num_of_payments = timestamp - parameters.last_bucket_fill_time; // const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; - parameters.last_bucket_fill_time = header.timestamp; + parameters.last_bucket_fill_time = timestamp; parameters.eos_bucket += to_eos_bucket; gs.set( parameters, _self ); } void system_contract::claimrewards(const account_name& owner) { require_auth(owner); - // We don't have current_sender() anymore. We don't have a good way to determine if the transaction was a deferred one. - // publication_time() could be used but it is not any guarantee that a transaction is or is not deferred. - // Do we really need to prevent users from using contracts to claim their rewards? - //eosio_assert(current_sender() == account_name(), "claimrewards can not be part of a deferred transaction"); + producers_table producers_tbl( _self, _self ); auto prod = producers_tbl.find(owner); eosio_assert(prod != producers_tbl.end(), "account name is not in producer list"); - eosio_assert(prod->active(), "producer is not active"); // QUESTION: Why do we want to prevent inactive producers from claiming their earned rewards? if( prod->last_rewards_claim > 0 ) { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } + // system_token_type rewards = prod->per_block_payments; eosio::asset rewards = prod->per_block_payments; auto idx = producers_tbl.template get_index(); diff --git a/voting.cpp b/voting.cpp index 3a1f6db2..889f941b 100644 --- a/voting.cpp +++ b/voting.cpp @@ -35,7 +35,7 @@ namespace eosiosystem { account_name proxy = 0; time last_update = 0; uint32_t is_proxy = 0; - eosio::asset staked; + eosio::asset staked; /// total staked across all delegations eosio::asset unstaking; eosio::asset unstake_per_week; uint128_t proxied_votes = 0; @@ -94,33 +94,36 @@ namespace eosiosystem { }); } - void system_contract::increase_voting_power( account_name acnt, const eosio::asset& amount ) { + void system_contract::adjust_voting_power( account_name acnt, int64_t delta ) { voters_table voters_tbl( _self, _self ); auto voter = voters_tbl.find( acnt ); - eosio_assert( 0 <= amount.amount, "negative asset" ); - if( voter == voters_tbl.end() ) { voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { a.owner = acnt; a.last_update = now(); - a.staked = amount; + a.staked.amount = delta; + eosio_assert( a.staked.amount >= 0, "underflow" ); }); } else { voters_tbl.modify( voter, 0, [&]( auto& av ) { av.last_update = now(); - av.staked += amount; + av.staked.amount += delta; + eosio_assert( av.staked.amount >= 0, "underflow" ); }); } const std::vector* producers = nullptr; if ( voter->proxy ) { + /* TODO: disabled until we can switch proxied votes to double auto proxy = voters_tbl.find( voter->proxy ); eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += uint64_t(amount.amount); } ); + voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += delta; } ); if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers producers = &proxy->producers; } + */ + } else { producers = &voter->producers; } @@ -131,12 +134,13 @@ namespace eosiosystem { auto prod = producers_tbl.find( p ); eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes += uint64_t(amount.amount); + v.total_votes += delta; }); } } } + /* void system_contract::decrease_voting_power( account_name acnt, const eosio::asset& amount ) { require_auth( acnt ); voters_table voters_tbl( _self, _self ); @@ -184,6 +188,7 @@ namespace eosiosystem { }); } } + */ eosio_global_state system_contract::get_default_parameters() { eosio_global_state dp; From 464f25082689f77491e89e58f85c006a3ea8ad9a Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 1 May 2018 18:23:43 -0400 Subject: [PATCH 0194/1048] progress --- delegate_bandwidth.cpp | 30 +-- eosio.system.cpp | 45 ++-- eosio.system.hpp | 44 +++- voting.cpp | 239 ++++++++----------- voting.hpp | 531 ----------------------------------------- 5 files changed, 188 insertions(+), 701 deletions(-) delete mode 100644 voting.hpp diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 09537444..851bd81c 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -71,6 +71,10 @@ namespace eosiosystem { EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(amount) ) }; + /** + * These tables are designed to be constructed in the scope of the relevant user, this + * facilitates simpler API for per-user queries + */ typedef eosio::multi_index< N(userres), user_resources> user_resources_table; typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_table; typedef eosio::multi_index< N(refunds), refund_request> refunds_table; @@ -93,15 +97,12 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, { payer, N(eosio), quant, std::string("buy ram") } ); - global_state_singleton gstate_table( _self, _self ); - auto gstate = gstate_table.exists() ? gstate_table.get() : get_default_parameters(); - const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; - const double unstaked_token_supply = system_token_supply - gstate.total_storage_stake.amount; + const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; const double E = quant.amount; const double R = unstaked_token_supply - E; - const double C = gstate.free_ram(); //free_ram; + const double C = _gstate.free_ram(); //free_ram; const double F = .10; /// 10% reserve ratio pricing, assumes only 10% of tokens will ever want to stake for ram const double ONE(1.0); @@ -111,10 +112,8 @@ namespace eosiosystem { eosio_assert( bytes_out > 0, "must reserve a positive amount" ); - gstate.total_storage_bytes_reserved += uint64_t(bytes_out); - gstate.total_storage_stake.amount += quant.amount; - - gstate_table.set( gstate, _self ); + _gstate.total_storage_bytes_reserved += uint64_t(bytes_out); + _gstate.total_storage_stake.amount += quant.amount; user_resources_table userres( _self, receiver ); auto res_itr = userres.find( receiver ); @@ -143,14 +142,11 @@ namespace eosiosystem { eosio_assert( res_itr != userres.end(), "no resource row" ); eosio_assert( res_itr->storage_bytes >= bytes, "insufficient quota" ); - global_state_singleton gstate_table( _self, _self ); - auto gstate = gstate_table.exists() ? gstate_table.get() : get_default_parameters(); - const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; - const double unstaked_token_supply = system_token_supply - gstate.total_storage_stake.amount; + const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; const double R = unstaked_token_supply; - const double C = gstate.free_ram() + bytes; + const double C = _gstate.free_ram() + bytes; const double F = .10; const double T = bytes; const double ONE(1.0); @@ -163,10 +159,8 @@ namespace eosiosystem { int64_t tokens_out = int64_t(E); eosio_assert( tokens_out > 0, "must free at least one token" ); - gstate.total_storage_bytes_reserved -= bytes; - gstate.total_storage_stake.amount -= tokens_out; - - gstate_table.set( gstate, _self ); + _gstate.total_storage_bytes_reserved -= bytes; + _gstate.total_storage_stake.amount -= tokens_out; userres.modify( res_itr, account, [&]( auto& res ) { res.storage_bytes -= bytes; diff --git a/eosio.system.cpp b/eosio.system.cpp index 08a52754..e8908d6a 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -5,20 +5,35 @@ #include "producer_pay.cpp" #include "voting.cpp" +system_contract::system_contract( account_name s ) +:native(s), + _voters(_self,_self), + _producers(_self,_self), + _global(_self,_self) +{ + _gstate = _global.exists() ? _global.get() : get_default_parameters(); +} + +system_contract::~system_contract() { + _global.set( _gstate, _self ); + eosio_exit(0); +} + + EOSIO_ABI( eosiosystem::system_contract, - (setparams) - // delegate_bandwith.cpp - (delegatebw)(undelegatebw)(refund) - (buyram)(sellram) - (regproxy) - // voting.cpp - (unregproxy)(regproducer)(unregprod)(voteproducer) - // producer_pay.cpp - (claimrewards) - // native.hpp - //XXX - (onblock) - (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) - // defined in eosio.system.hpp - (nonce) + (setparams) + // delegate_bandwith.cpp + (delegatebw)(undelegatebw)(refund) + (buyram)(sellram) + (regproxy) + // voting.cpp + (unregproxy)(regproducer)(unregprod)(voteproducer) + // producer_pay.cpp + (claimrewards) + // native.hpp + //XXX + (onblock) + (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) + // defined in eosio.system.hpp + (nonce) ) diff --git a/eosio.system.hpp b/eosio.system.hpp index 48fb5ca0..e08eb698 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -65,6 +65,40 @@ namespace eosiosystem { (time_became_active)(last_produced_block_time) ) }; + struct voter_info { + account_name owner = 0; /// the voter + account_name proxy = 0; /// the proxy set by the voter, if any + std::vector producers; /// the producers approved by this voter if no proxy set + uint64_t staked; + + /** + * Every time a vote is cast we must first "undo" the last vote weight, before casting the + * new vote weight. Vote weight is calculated as: + * + * stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) + */ + double last_vote_weight; /// the vote weight cast the last time the vote was updated + + /** + * Total vote weight delegated to this voter. + */ + double proxied_vote_weight= 0; /// the total vote weight delegated to this voter as a proxy + bool is_proxy = 0; /// whether the voter is a proxy for others + + + uint32_t deferred_trx_id = 0; /// the ID of the 3-day delay deferred transaction + time last_unstake_time = 0; /// the time when the deferred_trx_id was sent + eosio::asset unstaking; /// the total unstaking (pending 3 day delay) + + uint64_t primary_key()const { return owner; } + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(deferred_trx_id)(last_unstake_time)(unstaking) ) + }; + + typedef eosio::multi_index< N(voters), voter_info> voters_table; + + typedef eosio::multi_index< N(producerinfo), producer_info, indexed_by > > producers_table; @@ -76,8 +110,16 @@ namespace eosiosystem { static constexpr uint64_t system_token_symbol = S(4,EOS); class system_contract : public native { + private: + voters_table _voters; + producers_table _producers; + global_state_singleton _global; + + eosio_global_state _gstate; + public: - using native::native; + system_contract( account_name s ); + ~system_contract(); // Actions: void onblock( const block_id_type&, uint32_t timestamp_slot, account_name producer ); diff --git a/voting.cpp b/voting.cpp index 889f941b..c5941908 100644 --- a/voting.cpp +++ b/voting.cpp @@ -30,26 +30,6 @@ namespace eosiosystem { static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year static constexpr uint32_t blocks_per_producer = 12; - struct voter_info { - account_name owner = 0; - account_name proxy = 0; - time last_update = 0; - uint32_t is_proxy = 0; - eosio::asset staked; /// total staked across all delegations - eosio::asset unstaking; - eosio::asset unstake_per_week; - uint128_t proxied_votes = 0; - std::vector producers; - uint32_t deferred_trx_id = 0; - time last_unstake_time = 0; //uint32 - - uint64_t primary_key()const { return owner; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) - }; - - typedef eosio::multi_index< N(voters), voter_info> voters_table; /** * This method will create a producer_config and producer_info object for 'producer' @@ -64,131 +44,73 @@ namespace eosiosystem { //eosio::print("produce_key: ", producer_key.size(), ", sizeof(public_key): ", sizeof(public_key), "\n"); require_auth( producer ); - producers_table producers_tbl( _self, _self ); - auto prod = producers_tbl.find( producer ); + auto prod = _producers.find( producer ); - if ( prod != producers_tbl.end() ) { + if ( prod != _producers.end() ) { if( producer_key != prod->producer_key ) { - producers_tbl.modify( prod, producer, [&]( producer_info& info ){ + _producers.modify( prod, producer, [&]( producer_info& info ){ info.producer_key = producer_key; - }); + }); } } else { - producers_tbl.emplace( producer, [&]( producer_info& info ){ + _producers.emplace( producer, [&]( producer_info& info ){ info.owner = producer; info.total_votes = 0; info.producer_key = producer_key; - }); + }); } } void system_contract::unregprod( const account_name producer ) { require_auth( producer ); - producers_table producers_tbl( _self, _self ); - auto prod = producers_tbl.find( producer ); + auto prod = _producers.find( producer ); eosio_assert( prod != producers_tbl.end(), "producer not found" ); - producers_tbl.modify( prod, 0, [&]( producer_info& info ){ - info.producer_key = public_key(); - }); + _producers.modify( prod, 0, [&]( producer_info& info ){ + info.producer_key = public_key(); + }); } void system_contract::adjust_voting_power( account_name acnt, int64_t delta ) { - voters_table voters_tbl( _self, _self ); - auto voter = voters_tbl.find( acnt ); - - if( voter == voters_tbl.end() ) { - voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { - a.owner = acnt; - a.last_update = now(); - a.staked.amount = delta; - eosio_assert( a.staked.amount >= 0, "underflow" ); - }); - } else { - voters_tbl.modify( voter, 0, [&]( auto& av ) { - av.last_update = now(); - av.staked.amount += delta; - eosio_assert( av.staked.amount >= 0, "underflow" ); - }); - } + auto voter = _voters.find( acnt ); - const std::vector* producers = nullptr; - if ( voter->proxy ) { - /* TODO: disabled until we can switch proxied votes to double - auto proxy = voters_tbl.find( voter->proxy ); - eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += delta; } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - */ + if( voter == _voters.end() ) { + voter = _voters.emplace( acnt, [&]( voter_info& a ) { + a.owner = acnt; + a.staked.amount = delta; + }); + } - } else { - producers = &voter->producers; - } + auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); + double new_vote_weight = double(voter->staked.amount + delta) * std::pow(2,weight) + voter->proxied_vote_weight; - if ( producers ) { - producers_table producers_tbl( _self, _self ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes += delta; - }); - } - } - } + auto delta_vote_weight = new_vote_weight - voter->last_vote_weight; - /* - void system_contract::decrease_voting_power( account_name acnt, const eosio::asset& amount ) { - require_auth( acnt ); - voters_table voters_tbl( _self, _self ); - auto voter = voters_tbl.find( acnt ); - eosio_assert( voter != voters_tbl.end(), "stake not found" ); + _voters.modify( voter, 0, [&]( auto& av ) { + av.staked.amount += delta; + av.last_vote_weight = new_vote_weight; + eosio_assert( av.staked.amount >= 0, "underflow" ); + }); - if ( 0 < amount.amount ) { - eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked -= amount; - a.last_update = now(); - }); + const std::vector* producers = nullptr; + if ( voter->proxy ) { + auto proxy = voters_tbl.find( voter->proxy ); + eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= uint64_t(amount.amount); } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } + _voters.modify( proxy, 0, [&](voter_info& a) { + a.proxied_vote_weight += delta_vote_weight; + } ); - if ( producers ) { - producers_table producers_tbl( _self, _self ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes -= uint64_t(amount.amount); - }); - } - } } else { - if (voter->deferred_trx_id) { - //XXX cancel_deferred_transaction(voter->deferred_trx_id); - } - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked += a.unstaking; - a.unstaking.amount = 0; - a.unstake_per_week.amount = 0; - a.deferred_trx_id = 0; - a.last_update = now(); + for( auto p : voter->producers ) { + auto prod = _producers.find( p ); + _producers.modify( prod, 0, [&]( auto& pro ) { + pro.total_votes += delta_vote_weight; }); + } } } - */ eosio_global_state system_contract::get_default_parameters() { eosio_global_state dp; @@ -196,6 +118,7 @@ namespace eosiosystem { return dp; } + eosio::asset system_contract::payment_per_block(uint32_t percent_of_max_inflation_rate) { const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); @@ -205,8 +128,7 @@ namespace eosiosystem { } void system_contract::update_elected_producers(time cycle_time) { - producers_table producers_tbl( _self, _self ); - auto idx = producers_tbl.template get_index(); + auto idx = _producers.get_index(); eosio::producer_schedule schedule; schedule.producers.reserve(21); @@ -227,29 +149,25 @@ namespace eosiosystem { bytes packed_schedule = pack(schedule); set_active_producers( packed_schedule.data(), packed_schedule.size() ); - global_state_singleton gs( _self, _self ); - auto parameters = gs.exists() ? gs.get() : get_default_parameters(); - // not voted on - parameters.first_block_time_in_cycle = cycle_time; + _gstate.first_block_time_in_cycle = cycle_time; // derived parameters - auto half_of_percentage = parameters.percent_of_max_inflation_rate / 2; - auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; - parameters.payment_per_block = payment_per_block(half_of_percentage); - parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); - parameters.blocks_per_cycle = blocks_per_producer * schedule.producers.size(); - - if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { - parameters.max_storage_size = parameters.total_storage_bytes_reserved; + auto half_of_percentage = _gstate.percent_of_max_inflation_rate / 2; + auto other_half_of_percentage = _gstate.percent_of_max_inflation_rate - half_of_percentage; + _gstate.payment_per_block = payment_per_block(half_of_percentage); + _gstate.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); + _gstate.blocks_per_cycle = blocks_per_producer * schedule.producers.size(); + + if (_gstate.max_storage_size <_gstate.total_storage_bytes_reserved ) { + _gstate.max_storage_size =_gstate.total_storage_bytes_reserved; } - auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); + auto issue_quantity =_gstate.blocks_per_cycle * (_gstate.payment_per_block +_gstate.payment_to_eos_bucket); INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), issue_quantity, std::string("producer pay")} ); - set_blockchain_parameters( parameters ); - gs.set( parameters, _self ); + set_blockchain_parameters( _gstate ); } /** @@ -259,12 +177,13 @@ namespace eosiosystem { * @pre voter must authorize this action * @pre voter must have previously staked some EOS for voting */ - void system_contract::voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ) { - require_auth( voter ); + void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector& producers ) { + require_auth( voter_name ); //validate input if ( proxy ) { eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" ); + eosio_assert( voter_name != proxy, "cannot proxy to self" ); require_recipient( proxy ); } else { eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" ); @@ -273,8 +192,56 @@ namespace eosiosystem { } } - voters_table voters_tbl( _self, _self ); - auto voter_it = voters_tbl.find( voter ); + auto voter = _voters.find(voter_name); + eosio_assert( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object + + auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); + double new_vote_weight = double(voter->staked) * std::pow(2,weight) + voter->proxied_vote_weight; + + + flat_map producer_deltas; + for( const auto& p : voter->producers ) { + producer_deltas[p] -= voter->last_vote_weight; + } + + for( const auto& p : producers ) { + producer_deltas[p] += voter->last_vote_weight; + } + + if( voter->proxy ) { + if( voter->proxy != proxy ) { + + } else { + + } + } else { + + } + + + _voters.modify( voter, 0, [&]( auto& av ) { + av.last_vote_weight = new_vote_weight; + av.producers = producers; + av.proxy = proxy; + }); + + + + auto voter_it = _voters.find( voter ); + + /// remove all votes from existing producers or proxy + adjust_voting_power( voter, -voter_it->staked.amount ); + + /// update producer list + + + /// add all votes to new producers or proxy + adjust_voting_power( voter, voter_it->staked.amount ); + + + + + eosio_assert( 0 <= voter_it->staked.amount, "negative stake" ); eosio_assert( voter_it != voters_tbl.end() && ( 0 < voter_it->staked.amount || ( voter_it->is_proxy && 0 < voter_it->proxied_votes ) ), "no stake to vote" ); diff --git a/voting.hpp b/voting.hpp deleted file mode 100644 index acd7fc18..00000000 --- a/voting.hpp +++ /dev/null @@ -1,531 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once -#include "common.hpp" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace eosiosystem { - using eosio::indexed_by; - using eosio::const_mem_fun; - using eosio::bytes; - using eosio::print; - using eosio::singleton; - using eosio::transaction; - - - template - class voting { - public: - static constexpr account_name system_account = SystemAccount; - using currency = typename common::currency; - using system_token_type = typename common::system_token_type; - using eosio_parameters = typename common::eosio_parameters; - using global_state_singleton = typename common::global_state_singleton; - - static constexpr uint32_t max_inflation_rate = common::max_inflation_rate; - static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year - - struct producer_info { - account_name owner; - uint128_t total_votes = 0; - // eosio_parameters prefs; - eosio::bytes packed_key; /// a packed public key object - system_token_type per_block_payments; - time last_rewards_claim = 0; - time time_became_active = 0; - time last_produced_block_time = 0; - - uint64_t primary_key()const { return owner; } - uint128_t by_votes()const { return total_votes; } - bool active() const { return packed_key.size() == sizeof(public_key); } - - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(packed_key) - (per_block_payments)(last_rewards_claim) - (time_became_active)(last_produced_block_time) ) - }; - - typedef eosio::multi_index< N(producerinfo), producer_info, - indexed_by > - > producers_table; - - - struct voter_info { - account_name owner = 0; - account_name proxy = 0; - time last_update = 0; - uint32_t is_proxy = 0; - system_token_type staked; - system_token_type unstaking; - system_token_type unstake_per_week; - uint128_t proxied_votes = 0; - std::vector producers; - uint32_t deferred_trx_id = 0; - time last_unstake_time = 0; //uint32 - - uint64_t primary_key()const { return owner; } - - EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) - }; - - typedef eosio::multi_index< N(voters), voter_info> voters_table; - - - static void increase_voting_power( account_name acnt, system_token_type amount ) { - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( acnt ); - - if( voter == voters_tbl.end() ) { - voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { - a.owner = acnt; - a.last_update = now(); - a.staked = amount; - }); - } else { - voters_tbl.modify( voter, 0, [&]( auto& av ) { - av.last_update = now(); - av.staked += amount; - }); - } - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.quantity; } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } - - if ( producers ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes += amount.quantity; - }); - } - } - } - - static void decrease_voting_power( account_name acnt, system_token_type amount ) { - require_auth( acnt ); - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( acnt ); - eosio_assert( voter != voters_tbl.end(), "stake not found" ); - - if ( 0 < amount.quantity ) { - eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked -= amount; - a.last_update = now(); - }); - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.quantity; } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } - - if ( producers ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes -= amount.quantity; - }); - } - } - } else { - if (voter->deferred_trx_id) { - //XXX cancel_deferred_transaction(voter->deferred_trx_id); - } - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked += a.unstaking; - a.unstaking.quantity = 0; - a.unstake_per_week.quantity = 0; - a.deferred_trx_id = 0; - a.last_update = now(); - }); - } - } - - static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { - const system_token_type token_supply = currency::get_total_supply(); - const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); - double continuous_rate = std::log1p(annual_rate); - uint64_t payment = static_cast((continuous_rate * double(token_supply.quantity)) / double(blocks_per_year)); - return (system_token_type(payment)); - } - - static void update_elected_producers(time cycle_time); - -#if 0 - static void update_elected_producers(time cycle_time) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - auto idx = producers_tbl.template get_index(); - - std::array max_block_net_usage; - std::array target_block_net_usage_pct; - std::array base_per_transaction_net_usage; - std::array max_transaction_net_usage; - std::array context_free_discount_net_usage_num; - std::array context_free_discount_net_usage_den; - - std::array max_block_cpu_usage; - std::array target_block_cpu_usage_pct; - std::array max_transaction_cpu_usage; - std::array base_per_transaction_cpu_usage; - std::array base_per_action_cpu_usage; - std::array base_setcode_cpu_usage; - std::array per_signature_cpu_usage; - std::array context_free_discount_cpu_usage_num; - std::array context_free_discount_cpu_usage_den; - - std::array max_transaction_lifetime; - std::array deferred_trx_expiration_window; - std::array max_transaction_delay; - std::array max_inline_action_size; - std::array max_inline_action_depth; - std::array max_authority_depth; - std::array max_generated_transaction_count; - - std::array max_storage_size; - std::array percent_of_max_inflation_rate; - std::array storage_reserve_ratio; - - std::vector schedule; - schedule.reserve(21); - size_t n = 0; - for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { - if ( it->active() ) { - schedule.emplace_back(); - schedule.back().producer_name = it->owner; - eosio_assert( sizeof(schedule.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); - std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.back().block_signing_key.data ); - - max_block_net_usage[n] = it->prefs.max_block_net_usage; - target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; - max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; - base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; - context_free_discount_net_usage_num[n] = it->prefs.context_free_discount_net_usage_num; - context_free_discount_net_usage_den[n] = it->prefs.context_free_discount_net_usage_den; - - max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; - target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; - max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; - base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; - base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; - base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; - per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; - context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; - context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; - - max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; - deferred_trx_expiration_window[n] = it->prefs.deferred_trx_expiration_window; - max_transaction_delay[n] = it->prefs.max_transaction_delay; - max_inline_action_size[n] = it->prefs.max_inline_action_size; - max_inline_action_depth[n] = it->prefs.max_inline_action_depth; - max_authority_depth[n] = it->prefs.max_authority_depth; - max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; - - max_storage_size[n] = it->prefs.max_storage_size; - storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; - percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; - ++n; - } - } - if ( n == 0 ) { //no active producers with votes > 0 - return; - } - if ( 1 < n ) { - std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); - std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); - std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); - std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); - std::sort( context_free_discount_net_usage_num.begin(), context_free_discount_net_usage_num.begin()+n ); - std::sort( context_free_discount_net_usage_den.begin(), context_free_discount_net_usage_den.begin()+n ); - - std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); - std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); - std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); - std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); - std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); - std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); - std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); - std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); - std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); - - std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); - std::sort( deferred_trx_expiration_window.begin(), deferred_trx_expiration_window.begin()+n ); - std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); - std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); - std::sort( max_inline_action_depth.begin(), max_inline_action_depth.begin()+n ); - std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); - std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); - - std::sort( max_storage_size.begin(), max_storage_size.begin()+n ); - std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); - std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); - } - - bytes packed_schedule = pack(schedule); - set_active_producers( packed_schedule.data(), packed_schedule.size() ); - size_t median = n/2; - - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); - - parameters.max_block_net_usage = max_block_net_usage[median]; - parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; - parameters.max_transaction_net_usage = max_transaction_net_usage[median]; - parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; - parameters.context_free_discount_net_usage_num = context_free_discount_net_usage_num[median]; - parameters.context_free_discount_net_usage_den = context_free_discount_net_usage_den[median]; - - parameters.max_block_cpu_usage = max_block_cpu_usage[median]; - parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; - parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; - parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; - parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; - parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; - parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; - parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; - parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; - - parameters.max_transaction_lifetime = max_transaction_lifetime[median]; - parameters.deferred_trx_expiration_window = deferred_trx_expiration_window[median]; - parameters.max_transaction_delay = max_transaction_delay[median]; - parameters.max_inline_action_size = max_inline_action_size[median]; - parameters.max_inline_action_depth = max_inline_action_depth[median]; - parameters.max_authority_depth = max_authority_depth[median]; - parameters.max_generated_transaction_count = max_generated_transaction_count[median]; - - parameters.max_storage_size = max_storage_size[median]; - parameters.storage_reserve_ratio = storage_reserve_ratio[median]; - parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; - - // not voted on - parameters.first_block_time_in_cycle = cycle_time; - - // derived parameters - auto half_of_percentage = parameters.percent_of_max_inflation_rate / 2; - auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; - parameters.payment_per_block = payment_per_block(half_of_percentage); - parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); - parameters.blocks_per_cycle = common::blocks_per_producer * schedule.size(); - - if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { - parameters.max_storage_size = parameters.total_storage_bytes_reserved; - } - - auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); - currency::inline_issue(SystemAccount, issue_quantity); - set_blockchain_parameters(parameters); - global_state_singleton::set(parameters); - } -#endif - - ACTION( SystemAccount, voteproducer ) { - account_name voter; - account_name proxy; - std::vector producers; - - EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) - }; - - /** - * @pre vp.producers must be sorted from lowest to highest - * @pre if proxy is set then no producers can be voted for - * @pre every listed producer or proxy must have been previously registered - * @pre vp.voter must authorize this action - * @pre voter must have previously staked some EOS for voting - */ - static void on( const voteproducer& vp ) { - require_auth( vp.voter ); - - //validate input - if ( vp.proxy ) { - eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); - require_recipient( vp.proxy ); - } else { - eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); - for( size_t i = 1; i < vp.producers.size(); ++i ) { - eosio_assert( vp.producers[i-1] < vp.producers[i], "producer votes must be unique and sorted" ); - } - } - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( vp.voter ); - - eosio_assert( voter != voters_tbl.end() && ( 0 < voter->staked.quantity || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); - if ( voter->is_proxy ) { - eosio_assert( vp.proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); - } - - //find old producers, update old proxy if needed - const std::vector* old_producers = nullptr; - if( voter->proxy ) { - if ( voter->proxy == vp.proxy ) { - return; // nothing changed - } - auto old_proxy = voters_tbl.find( voter->proxy ); - eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption - voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); - if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) - old_producers = &old_proxy->producers; - } - } else { - old_producers = &voter->producers; - } - - //find new producers, update new proxy if needed - const std::vector* new_producers = nullptr; - if ( vp.proxy ) { - auto new_proxy = voters_tbl.find( vp.proxy ); - eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); - voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); - new_producers = &new_proxy->producers; - } else { - new_producers = &vp.producers; - } - - producers_table producers_tbl( SystemAccount, SystemAccount ); - uint128_t votes = voter->staked.quantity; - if ( voter->is_proxy ) { - votes += voter->proxied_votes; - } - - if ( old_producers ) { //old_producers == nullptr if proxy has stopped being a proxy and votes were taken back from the producers at that moment - //revoke votes only from no longer elected - std::vector revoked( old_producers->size() ); - auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); - for ( auto it = revoked.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); - } - } - - //update newly elected - std::vector elected( new_producers->size() ); - auto end_it = elected.begin(); - if( old_producers ) { - end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); - } else { - end_it = std::copy( new_producers->begin(), new_producers->end(), elected.begin() ); - } - for ( auto it = elected.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "producer is not registered" ); - if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers - eosio_assert( prod->active(), "producer is not currently registered" ); - } - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); - } - - // save new values to the account itself - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.proxy = vp.proxy; - a.last_update = now(); - a.producers = vp.producers; - }); - } - - ACTION( SystemAccount, regproxy ) { - account_name proxy; - - EOSLIB_SERIALIZE( regproxy, (proxy) ) - }; - - static void on( const regproxy& reg ) { - require_auth( reg.proxy ); - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto proxy = voters_tbl.find( reg.proxy ); - if ( proxy != voters_tbl.end() ) { - eosio_assert( proxy->is_proxy == 0, "account is already a proxy" ); - eosio_assert( proxy->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { - a.is_proxy = 1; - a.last_update = now(); - //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value - }); - if ( 0 < proxy->proxied_votes ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for ( auto p : proxy->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += proxy->proxied_votes; }); - } - } - } else { - voters_tbl.emplace( reg.proxy, [&]( voter_info& a ) { - a.owner = reg.proxy; - a.last_update = now(); - a.proxy = 0; - a.is_proxy = 1; - a.proxied_votes = 0; - a.staked.quantity = 0; - }); - } - } - - ACTION( SystemAccount, unregproxy ) { - account_name proxy; - - EOSLIB_SERIALIZE( unregproxy, (proxy) ) - }; - - static void on( const unregproxy& reg ) { - require_auth( reg.proxy ); - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto proxy = voters_tbl.find( reg.proxy ); - eosio_assert( proxy != voters_tbl.end(), "proxy not found" ); - eosio_assert( proxy->is_proxy == 1, "account is not a proxy" ); - - voters_tbl.modify( proxy, 0, [&](voter_info& a) { - a.is_proxy = 0; - a.last_update = now(); - //a.proxied_votes should be kept in order to be able to reenable this proxy in the future - }); - - if ( 0 < proxy->proxied_votes ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for ( auto p : proxy->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); - } - } - } - - }; -} From 58c0e1152ee79609a2dad2d1892140dd9faeb0ee Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 1 May 2018 23:50:36 -0400 Subject: [PATCH 0195/1048] progess on system contract staking/buying ram --- delegate_bandwidth.cpp | 118 ++++++++++++++----- eosio.system.abi | 77 +++--------- eosio.system.cpp | 41 ++++--- eosio.system.hpp | 17 ++- native.hpp | 5 +- voting.cpp | 259 +++++++++-------------------------------- 6 files changed, 199 insertions(+), 318 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 851bd81c..8dc91cca 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -80,6 +80,40 @@ namespace eosiosystem { typedef eosio::multi_index< N(refunds), refund_request> refunds_table; + /** + * Called after a new account is created. This code enforces resource-limits rules + * for new accounts as well as new account naming conventions. + * + * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 + * characters long without '.' until a future account auction process is implemented + * which prevents name squatting. + * + * 2. new accounts must stake a minimal number of tokens (as set in system parameters) + * therefore, this method will execute an inline buyram from receiver for newacnt in + * an amount equal to the current new account creation fee. + */ + void native::newaccount( account_name creator, + account_name newact + /* no need to parse authorites + const authority& owner, + const authority& active, + const authority& recovery*/ ) { + eosio::print( eosio::name{creator}, " created ", eosio::name{newact}, "\n"); + + user_resources_table userres( _self, newact); + + auto r = userres.emplace( newact, [&]( auto& res ) { + res.owner = newact; + }); + + set_resource_limits( newact, + 0,// r->storage_bytes, + 0, 0 ); + // r->net_weight.amount, + // r->cpu_weight.amount ); + } + + /** * When buying ram the payer irreversiblly transfers quant to system contract and only @@ -91,6 +125,7 @@ namespace eosiosystem { */ void system_contract::buyram( account_name payer, account_name receiver, asset quant ) { + print( "\n payer: ", eosio::name{payer}, " buys ram for ", eosio::name{receiver}, " with ", quant, "\n" ); require_auth( payer ); eosio_assert( quant.amount > 0, "must purchase a positive amount" ); @@ -100,15 +135,18 @@ namespace eosiosystem { const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; + print( "free ram: ", _gstate.free_ram(), " tokens: ", system_token_supply, " unstaked: ", unstaked_token_supply, "\n" ); + const double E = quant.amount; const double R = unstaked_token_supply - E; const double C = _gstate.free_ram(); //free_ram; - const double F = .10; /// 10% reserve ratio pricing, assumes only 10% of tokens will ever want to stake for ram + const double F = 1./(_gstate.storage_reserve_ratio/10000.0); /// 10% reserve ratio pricing, assumes only 10% of tokens will ever want to stake for ram const double ONE(1.0); double T = C * (std::pow( ONE + E/R, F ) - ONE); T *= .99; /// 1% fee on every conversion int64_t bytes_out = static_cast(T); + print( "ram bytes out: ", bytes_out, "\n" ); eosio_assert( bytes_out > 0, "must reserve a positive amount" ); @@ -147,7 +185,7 @@ namespace eosiosystem { const double R = unstaked_token_supply; const double C = _gstate.free_ram() + bytes; - const double F = .10; + const double F = _gstate.storage_reserve_ratio / 10000.0; const double T = bytes; const double ONE(1.0); @@ -177,13 +215,15 @@ namespace eosiosystem { { require_auth( from ); + print( "from: ", eosio::name{from}, " to: ", eosio::name{receiver}, " net: ", stake_net_quantity, " cpu: ", stake_cpu_quantity ); - eosio_assert( stake_cpu_quantity.amount >= 0, "must stake a positive amount" ); - eosio_assert( stake_net_quantity.amount >= 0, "must stake a positive amount" ); + eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); + eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); - asset total_stake = stake_cpu_quantity + stake_net_quantity; - eosio_assert( total_stake.amount > 0, "must stake a positive amount" ); + auto total_stake = stake_cpu_quantity.amount + stake_net_quantity.amount; + eosio_assert( total_stake > 0, "must stake a positive amount" ); + print( "deltable" ); del_bandwidth_table del_tbl( _self, from ); auto itr = del_tbl.find( receiver ); if( itr == del_tbl.end() ) { @@ -201,6 +241,7 @@ namespace eosiosystem { }); } + print( "totals" ); user_resources_table totals_tbl( _self, receiver ); auto tot_itr = totals_tbl.find( receiver ); if( tot_itr == totals_tbl.end() ) { @@ -219,34 +260,52 @@ namespace eosiosystem { set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, uint64_t(tot_itr->net_weight.amount), uint64_t(tot_itr->cpu_weight.amount) ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio), total_stake, std::string("stake bandwidth") } ); + { from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); + + print( "voters" ); + auto from_voter = _voters.find(from); + if( from_voter == _voters.end() ) { + print( " create voter" ); + from_voter = _voters.emplace( from, [&]( auto& v ) { + v.owner = from; + v.staked = uint64_t(total_stake); + }); + } else { + _voters.modify( from_voter, 0, [&]( auto& v ) { + v.staked += uint64_t(total_stake); + }); + } - adjust_voting_power( from, (stake_net_quantity.amount + stake_cpu_quantity.amount) ); + print( "voteproducer" ); + voteproducer( from, from_voter->proxy, from_voter->producers ); } // delegatebw void system_contract::undelegatebw( account_name from, account_name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ) { - eosio_assert( unstake_cpu_quantity.amount >= 0, "must unstake a positive amount" ); - eosio_assert( unstake_net_quantity.amount >= 0, "must unstake a positive amount" ); + eosio_assert( unstake_cpu_quantity >= asset(), "must unstake a positive amount" ); + eosio_assert( unstake_net_quantity >= asset(), "must unstake a positive amount" ); require_auth( from ); - //eosio_assert( is_account( receiver ), "can only delegate resources to an existing account" ); - del_bandwidth_table del_tbl( _self, from ); const auto& dbw = del_tbl.get( receiver ); - eosio_assert( dbw.net_weight >= unstake_net_quantity, "insufficient staked net bandwidth" ); - eosio_assert( dbw.cpu_weight >= unstake_cpu_quantity, "insufficient staked cpu bandwidth" ); + eosio_assert( dbw.net_weight.amount >= unstake_net_quantity.amount, "insufficient staked net bandwidth" ); + eosio_assert( dbw.cpu_weight.amount >= unstake_cpu_quantity.amount, "insufficient staked cpu bandwidth" ); - eosio::asset total_refund = unstake_cpu_quantity + unstake_net_quantity; + auto total_refund = unstake_cpu_quantity.amount + unstake_net_quantity.amount; + + _voters.modify( _voters.get(from), 0, [&]( auto& v ) { + v.staked -= uint64_t(total_refund); + }); - eosio_assert( total_refund.amount > 0, "must unstake a positive amount" ); + + eosio_assert( total_refund > 0, "must unstake a positive amount" ); del_tbl.modify( dbw, from, [&]( auto& dbo ){ dbo.net_weight -= unstake_net_quantity; dbo.cpu_weight -= unstake_cpu_quantity; - }); + }); user_resources_table totals_tbl( _self, receiver ); @@ -254,9 +313,9 @@ namespace eosiosystem { totals_tbl.modify( totals, 0, [&]( auto& tot ) { tot.net_weight -= unstake_net_quantity; tot.cpu_weight -= unstake_cpu_quantity; - }); + }); - set_resource_limits( totals.owner, totals.storage_bytes, uint64_t(totals.net_weight.amount), uint64_t(totals.cpu_weight.amount) ); + set_resource_limits( receiver, totals.storage_bytes, totals.net_weight.amount, totals.cpu_weight.amount ); refunds_table refunds_tbl( _self, from ); //create refund request @@ -273,6 +332,7 @@ namespace eosiosystem { r.request_time = now(); }); } + //create or replace deferred transaction //refund act; //act.owner = from; @@ -281,8 +341,8 @@ namespace eosiosystem { out.delay_sec = refund_delay; out.send( from, receiver ); - adjust_voting_power( from, -(unstake_net_quantity.amount + unstake_cpu_quantity.amount) ); - + const auto& fromv = _voters.get( from ); + voteproducer( from, fromv.proxy, fromv.producers ); } // undelegatebw @@ -303,20 +363,16 @@ namespace eosiosystem { refunds_tbl.erase( req ); } - void system_contract::setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ) { - require_auth( _self ); - - eosio_assert( storage_reserve_ratio > 0, "invalid reserve ratio" ); + require_auth( _self ); - global_state_singleton gs( _self, _self ); - auto parameters = gs.exists() ? gs.get() : get_default_parameters(); + eosio_assert( storage_reserve_ratio > 0, "invalid reserve ratio" ); - eosio_assert( max_storage_size > parameters.total_storage_bytes_reserved, "attempt to set max below reserved" ); + eosio_assert( max_storage_size > _gstate.total_storage_bytes_reserved, "attempt to set max below reserved" ); - parameters.max_storage_size = max_storage_size; - parameters.storage_reserve_ratio = storage_reserve_ratio; - gs.set( parameters, _self ); + _gstate.max_storage_size = max_storage_size; + _gstate.storage_reserve_ratio = storage_reserve_ratio; + _global.set( _gstate, _self ); } } //namespace eosiosystem diff --git a/eosio.system.abi b/eosio.system.abi index 1b807381..e30c84a7 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -7,34 +7,12 @@ {"name":"value", "type":"string"} ] },{ - "name": "transfer", + "name": "buyram", "base": "", "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"quantity", "type":"asset"}, - {"name":"memo", "type":"string"} - ] - },{ - "name": "issue", - "base": "", - "fields": [ - {"name":"to", "type":"account_name"}, - {"name":"quantity", "type":"asset"} - ] - },{ - "name": "account", - "base": "", - "fields": [ - {"name":"currency", "type":"uint64"}, - {"name":"balance", "type":"uint64"} - ] - },{ - "name": "currency_stats", - "base": "", - "fields": [ - {"name":"currency", "type":"uint64"}, - {"name":"supply", "type":"uint64"} + {"name":"payer", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"quant", "type":"asset"} ] },{ "name": "delegatebw", @@ -44,7 +22,6 @@ {"name":"receiver", "type":"account_name"}, {"name":"stake_net_quantity", "type":"asset"}, {"name":"stake_cpu_quantity", "type":"asset"}, - {"name":"stake_storage_quantity", "type":"asset"} ] },{ "name": "undelegatebw", @@ -54,7 +31,6 @@ {"name":"receiver", "type":"account_name"}, {"name":"unstake_net_quantity", "type":"asset"}, {"name":"unstake_cpu_quantity", "type":"asset"}, - {"name":"unstake_storage_bytes", "type":"uint64"} ] },{ "name": "refund", @@ -70,7 +46,6 @@ {"name":"to", "type":"account_name"}, {"name":"net_weight", "type":"uint64"}, {"name":"cpu_weight", "type":"uint64"}, - {"name":"storage_stake", "type":"uint64"}, {"name":"storage_bytes", "type":"uint64"} ] },{ @@ -80,7 +55,6 @@ {"name":"owner", "type":"account_name"}, {"name":"net_weight", "type":"asset"}, {"name":"cpu_weight", "type":"asset"}, - {"name":"storage_stake", "type":"asset"}, {"name":"storage_bytes", "type":"uint64"} ] },{ @@ -170,12 +144,7 @@ "base": "", "fields": [ {"name":"proxy", "type":"account_name"} - ] - },{ - "name": "unregproxy", - "base": "", - "fields": [ - {"name":"proxy", "type":"account_name"} + {"name":"isproxy", "type":"bool"} ] },{ "name": "voteproducer", @@ -189,17 +158,16 @@ "name": "voter_info", "base": "", "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"last_update", "type":"time"}, - {"name":"is_proxy", "type":"uint32"}, - {"name":"staked", "type":"asset"}, - {"name":"unstaking", "type":"asset"}, - {"name":"unstake_per_week", "type":"asset"}, - {"name":"proxied_votes", "type":"uint128"}, - {"name":"producers", "type":"account_name[]"}, - {"name":"deferred_trx_id", "type":"uint32"}, - {"name":"last_unstake", "type":"uint32"} + {"name":"owner", "type":"account_name"}, + {"name":"proxy", "type":"account_name"}, + {"name":"producers", "type":"account_name[]"}, + {"name":"staked", "type":"uint64"}, + {"name":"last_vote_weight", "type":"float64"}, + {"name":"proxied_vote_weight", "type":"float64"}, + {"name":"is_proxy", "type":"bool"}, + {"name":"deferred_trx_id", "type":"uint32"}, + {"name":"last_unstake_time", "type":"time"}, + {"name":"unstaking", "type":"asset"}, ] },{ "name": "claimrewards", @@ -209,13 +177,10 @@ ] } ], - "actions": [{ - "name": "transfer", - "type": "transfer", - "ricardian_contract": "" - },{ - "name": "issue", - "type": "issue", + "actions": [ + { + "name": "buyram", + "type": "buyram", "ricardian_contract": "" },{ "name": "delegatebw", @@ -245,10 +210,6 @@ "name": "regproxy", "type": "regproxy", "ricardian_contract": "" - },{ - "name": "unregproxy", - "type": "unregproxy", - "ricardian_contract": "" },{ "name": "voteproducer", "type": "voteproducer", diff --git a/eosio.system.cpp b/eosio.system.cpp index e8908d6a..cb16ba19 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -5,29 +5,42 @@ #include "producer_pay.cpp" #include "voting.cpp" -system_contract::system_contract( account_name s ) -:native(s), - _voters(_self,_self), - _producers(_self,_self), - _global(_self,_self) -{ - _gstate = _global.exists() ? _global.get() : get_default_parameters(); -} -system_contract::~system_contract() { - _global.set( _gstate, _self ); - eosio_exit(0); -} +namespace eosiosystem { + system_contract::system_contract( account_name s ) + :native(s), + _voters(_self,_self), + _producers(_self,_self), + _global(_self,_self) + { + print( "construct system\n" ); + _gstate = _global.exists() ? _global.get() : get_default_parameters(); + } + + eosio_global_state system_contract::get_default_parameters() { + eosio_global_state dp; + get_blockchain_parameters(dp); + return dp; + } + + + system_contract::~system_contract() { + print( "destruct system\n" ); + _global.set( _gstate, _self ); + eosio_exit(0); + } + +} /// eosio.system + EOSIO_ABI( eosiosystem::system_contract, (setparams) // delegate_bandwith.cpp (delegatebw)(undelegatebw)(refund) (buyram)(sellram) - (regproxy) // voting.cpp - (unregproxy)(regproducer)(unregprod)(voteproducer) + (regproxy)(regproducer)(unregprod)(voteproducer) // producer_pay.cpp (claimrewards) // native.hpp diff --git a/eosio.system.hpp b/eosio.system.hpp index e08eb698..7d5e8f0f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -18,9 +18,9 @@ namespace eosiosystem { using eosio::const_mem_fun; struct eosio_parameters : eosio::blockchain_parameters { - uint64_t max_storage_size = 1024 * 1024 * 1024; + uint64_t max_storage_size = 64ll*1024 * 1024 * 1024; uint32_t percent_of_max_inflation_rate = 0; - uint32_t storage_reserve_ratio = 2000; // ratio * 1000 + uint32_t storage_reserve_ratio = 100; // ratio * 10000 // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_storage_size)(percent_of_max_inflation_rate)(storage_reserve_ratio) ) @@ -69,7 +69,7 @@ namespace eosiosystem { account_name owner = 0; /// the voter account_name proxy = 0; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set - uint64_t staked; + uint64_t staked = 0; /** * Every time a vote is cast we must first "undo" the last vote weight, before casting the @@ -77,7 +77,7 @@ namespace eosiosystem { * * stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) */ - double last_vote_weight; /// the vote weight cast the last time the vote was updated + double last_vote_weight = 0; /// the vote weight cast the last time the vote was updated /** * Total vote weight delegated to this voter. @@ -99,7 +99,7 @@ namespace eosiosystem { typedef eosio::multi_index< N(voters), voter_info> voters_table; - typedef eosio::multi_index< N(producerinfo), producer_info, + typedef eosio::multi_index< N(producers), producer_info, indexed_by > > producers_table; @@ -119,7 +119,7 @@ namespace eosiosystem { public: system_contract( account_name s ); - ~system_contract(); + [[noreturn]] ~system_contract(); // Actions: void onblock( const block_id_type&, uint32_t timestamp_slot, account_name producer ); @@ -177,12 +177,9 @@ namespace eosiosystem { void setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ); - void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); - void regproxy( const account_name proxy ); - - void unregproxy( const account_name proxy ); + void regproxy( const account_name proxy, bool isproxy ); void nonce( const std::string& /*value*/ ) {} diff --git a/native.hpp b/native.hpp index ef8695ff..2100b65d 100644 --- a/native.hpp +++ b/native.hpp @@ -85,10 +85,7 @@ namespace eosiosystem { /* no need to parse authorites const authority& owner, const authority& active, - const authority& recovery*/ ) { - eosio::print( eosio::name{creator}, " created ", eosio::name{newact}); - set_resource_limits( newact, 3000, 0, 0 ); - } + const authority& recovery*/ ); void updateauth( /*account_name account, diff --git a/voting.cpp b/voting.cpp index c5941908..30ab32fd 100644 --- a/voting.cpp +++ b/voting.cpp @@ -64,60 +64,13 @@ namespace eosiosystem { void system_contract::unregprod( const account_name producer ) { require_auth( producer ); - auto prod = _producers.find( producer ); - eosio_assert( prod != producers_tbl.end(), "producer not found" ); + const auto& prod = _producers.get( producer ); _producers.modify( prod, 0, [&]( producer_info& info ){ info.producer_key = public_key(); }); } - void system_contract::adjust_voting_power( account_name acnt, int64_t delta ) { - auto voter = _voters.find( acnt ); - - if( voter == _voters.end() ) { - voter = _voters.emplace( acnt, [&]( voter_info& a ) { - a.owner = acnt; - a.staked.amount = delta; - }); - } - - auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); - double new_vote_weight = double(voter->staked.amount + delta) * std::pow(2,weight) + voter->proxied_vote_weight; - - auto delta_vote_weight = new_vote_weight - voter->last_vote_weight; - - _voters.modify( voter, 0, [&]( auto& av ) { - av.staked.amount += delta; - av.last_vote_weight = new_vote_weight; - eosio_assert( av.staked.amount >= 0, "underflow" ); - }); - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); - - _voters.modify( proxy, 0, [&](voter_info& a) { - a.proxied_vote_weight += delta_vote_weight; - } ); - - } else { - for( auto p : voter->producers ) { - auto prod = _producers.find( p ); - _producers.modify( prod, 0, [&]( auto& pro ) { - pro.total_votes += delta_vote_weight; - }); - } - } - } - - eosio_global_state system_contract::get_default_parameters() { - eosio_global_state dp; - get_blockchain_parameters(dp); - return dp; - } - eosio::asset system_contract::payment_per_block(uint32_t percent_of_max_inflation_rate) { const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); @@ -171,11 +124,20 @@ namespace eosiosystem { } /** - * @pre producers must be sorted from lowest to highest + * @pre producers must be sorted from lowest to highest and must be registered and active * @pre if proxy is set then no producers can be voted for + * @pre if proxy is set then proxy account must exist and be registered as a proxy * @pre every listed producer or proxy must have been previously registered * @pre voter must authorize this action * @pre voter must have previously staked some EOS for voting + * @pre voter->staked must be up to date + * + * @post every producer previously voted for will have vote reduced by previous vote weight + * @post every producer newly voted for will have vote increased by new vote amount + * @post prior proxy will proxied_vote_weight decremented by previous vote weight + * @post new proxy will proxied_vote_weight incremented by new vote weight + * + * If voting for a proxy, the producer votes will not change until the proxy updates their own vote. */ void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector& producers ) { require_auth( voter_name ); @@ -192,32 +154,42 @@ namespace eosiosystem { } } + print( __FILE__, ":", __LINE__, " "); auto voter = _voters.find(voter_name); eosio_assert( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); - double new_vote_weight = double(voter->staked) * std::pow(2,weight) + voter->proxied_vote_weight; + double new_vote_weight = double(voter->staked) * std::pow(2,weight); + if( voter->is_proxy ) { + new_vote_weight += voter->proxied_vote_weight; + } - flat_map producer_deltas; + boost::container::flat_map producer_deltas; for( const auto& p : voter->producers ) { producer_deltas[p] -= voter->last_vote_weight; } - for( const auto& p : producers ) { - producer_deltas[p] += voter->last_vote_weight; - } - - if( voter->proxy ) { - if( voter->proxy != proxy ) { - - } else { - + if( new_vote_weight >= 0 ) { + for( const auto& p : producers ) { + producer_deltas[p] += new_vote_weight; } - } else { + } + if( voter->proxy != account_name() ) { + auto old_proxy = _voters.find( voter->proxy ); + _voters.modify( old_proxy, 0, [&]( auto& vp ) { + vp.proxied_vote_weight -= voter->last_vote_weight; + }); } + if( proxy != account_name() && new_vote_weight > 0 ) { + auto new_proxy = _voters.find( voter->proxy ); + eosio_assert( new_proxy != _voters.end() && new_proxy->is_proxy, "invalid proxy specified" ); + _voters.modify( new_proxy, 0, [&]( auto& vp ) { + vp.proxied_vote_weight += new_vote_weight; + }); + } _voters.modify( voter, 0, [&]( auto& av ) { av.last_vote_weight = new_vote_weight; @@ -225,154 +197,39 @@ namespace eosiosystem { av.proxy = proxy; }); - - - auto voter_it = _voters.find( voter ); - - /// remove all votes from existing producers or proxy - adjust_voting_power( voter, -voter_it->staked.amount ); - - /// update producer list - - - /// add all votes to new producers or proxy - adjust_voting_power( voter, voter_it->staked.amount ); - - - - - - - eosio_assert( 0 <= voter_it->staked.amount, "negative stake" ); - eosio_assert( voter_it != voters_tbl.end() && ( 0 < voter_it->staked.amount || ( voter_it->is_proxy && 0 < voter_it->proxied_votes ) ), "no stake to vote" ); - if ( voter_it->is_proxy ) { - eosio_assert( proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); - } - - //find old producers, update old proxy if needed - const std::vector* old_producers = nullptr; - if( voter_it->proxy ) { - if ( voter_it->proxy == proxy ) { - return; // nothing changed - } - auto old_proxy = voters_tbl.find( voter_it->proxy ); - eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption - voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= uint64_t(voter_it->staked.amount); } ); - if ( old_proxy->is_proxy ) { //if proxy stopped being a proxy, the votes were already taken back from producers by on( const unregister_proxy& ) - old_producers = &old_proxy->producers; - } - } else { - old_producers = &voter_it->producers; - } - - //find new producers, update new proxy if needed - const std::vector* new_producers = nullptr; - if ( proxy ) { - auto new_proxy = voters_tbl.find( proxy ); - eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); - voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += uint64_t(voter_it->staked.amount); } ); - new_producers = &new_proxy->producers; - } else { - new_producers = &producers; - } - - producers_table producers_tbl( _self, _self ); - uint128_t votes = uint64_t(voter_it->staked.amount); - if ( voter_it->is_proxy ) { - votes += voter_it->proxied_votes; - } - - if ( old_producers ) { //old_producers == nullptr if proxy has stopped being a proxy and votes were taken back from the producers at that moment - //revoke votes only from no longer elected - std::vector revoked( old_producers->size() ); - auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); - for ( auto it = revoked.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); - } - } - - //update newly elected - std::vector elected( new_producers->size() ); - auto end_it = elected.begin(); - if( old_producers ) { - end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); - } else { - end_it = std::copy( new_producers->begin(), new_producers->end(), elected.begin() ); - } - for ( auto it = elected.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "producer is not registered" ); - if ( proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers - eosio_assert( prod->active(), "producer is not currently registered" ); - } - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); - } - - // save new values to the account itself - voters_tbl.modify( voter_it, 0, [&](voter_info& a) { - a.proxy = proxy; - a.last_update = now(); - a.producers = producers; - }); - } - - void system_contract::regproxy( const account_name proxy ) { - require_auth( proxy ); - - voters_table voters_tbl( _self, _self ); - auto proxy_it = voters_tbl.find( proxy ); - if ( proxy_it != voters_tbl.end() ) { - eosio_assert( proxy_it->is_proxy == 0, "account is already a proxy" ); - eosio_assert( proxy_it->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - voters_tbl.modify( proxy_it, 0, [&](voter_info& a) { - a.is_proxy = 1; - a.last_update = now(); - //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value + print( __FILE__, ":", __LINE__, " "); + for( const auto& pd : producer_deltas ) { + auto pitr = _producers.find( pd.first ); + if( pitr != _producers.end() ) { + _producers.modify( pitr, 0, [&]( auto& p ) { + p.total_votes += pd.second; + eosio_assert( p.total_votes >= 0, "something bad happened" ); + eosio_assert( p.active(), "producer is not active" ); }); - if ( 0 < proxy_it->proxied_votes ) { - producers_table producers_tbl( _self, _self ); - for ( auto p : proxy_it->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += proxy_it->proxied_votes; }); - } } - } else { - voters_tbl.emplace( proxy, [&]( voter_info& a ) { - a.owner = proxy; - a.last_update = now(); - a.proxy = 0; - a.is_proxy = 1; - a.proxied_votes = 0; - a.staked.amount = 0; - }); } } - void system_contract::unregproxy( const account_name proxy ) { + /** + * An account marked as a proxy can vote with the weight of other accounts which + * have selected it as a proxy. Other accounts must refresh their voteproducer to + * update the proxy's weight. + * + * @param isproxy - true if proxy wishes to vote on behalf of others, false otherwise + * @pre proxy must have something staked (existing row in voters table) + * @pre new state must be different than current state + */ + void system_contract::regproxy( const account_name proxy, bool isproxy ) { require_auth( proxy ); - voters_table voters_tbl( _self, _self ); - auto proxy_it = voters_tbl.find( proxy ); - eosio_assert( proxy_it != voters_tbl.end(), "proxy not found" ); - eosio_assert( proxy_it->is_proxy == 1, "account is not a proxy" ); + auto pitr = _voters.find(proxy); + eosio_assert( pitr != _voters.end(), "proxy must have some stake first" ); + eosio_assert( !pitr->is_proxy, "account is already a proxy" ); + eosio_assert( pitr->is_proxy != isproxy, "action has no effect" ); - voters_tbl.modify( proxy_it, 0, [&](voter_info& a) { - a.is_proxy = 0; - a.last_update = now(); - //a.proxied_votes should be kept in order to be able to reenable this proxy in the future - }); - - if ( 0 < proxy_it->proxied_votes ) { - producers_table producers_tbl( _self, _self ); - for ( auto p : proxy_it->producers ) { - auto prod_it = producers_tbl.find( p ); - eosio_assert( prod_it != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod_it, 0, [&]( auto& pi ) { pi.total_votes -= proxy_it->proxied_votes; }); - } - } + _voters.modify( pitr, 0, [&]( auto& p ) { + p.is_proxy = isproxy; + }); } } From cdee4ac567abf4684c211dd76e834cac24316806 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 1 May 2018 23:59:44 -0400 Subject: [PATCH 0196/1048] bill discounted cpu usage rates for context free actions --- eosio.system.abi | 10 +++++----- voting.hpp | 12 ++++++------ 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 1b807381..9d612bcf 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -95,12 +95,12 @@ "name": "blockchain_parameters", "base": "", "fields": [ - {"name":"max_block_net_usage", "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":"context_free_discount_net_usage_num", "type":"uint64"}, - {"name":"context_free_discount_net_usage_den", "type":"uint64"}, + {"name":"context_free_discount_net_usage_num", "type":"uint32"}, + {"name":"context_free_discount_net_usage_den", "type":"uint32"}, {"name":"max_block_cpu_usage", "type": "uint64"}, {"name":"target_block_cpu_usage_pct", "type": "uint32"}, {"name":"max_transaction_cpu_usage", "type":"uint32"}, @@ -108,8 +108,8 @@ {"name":"base_per_action_cpu_usage", "type":"uint32"}, {"name":"base_setcode_cpu_usage", "type":"uint32"}, {"name":"per_signature_cpu_usage", "type":"uint32"}, - {"name":"context_free_discount_cpu_usage_num", "type":"uint64"}, - {"name":"context_free_discount_cpu_usage_den", "type":"uint64"}, + {"name":"context_free_discount_cpu_usage_num", "type":"uint32"}, + {"name":"context_free_discount_cpu_usage_den", "type":"uint32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, {"name":"deferred_trx_expiration_window", "type":"uint32"}, {"name":"max_transaction_delay", "type":"uint32"}, diff --git a/voting.hpp b/voting.hpp index acd7fc18..a72d0567 100644 --- a/voting.hpp +++ b/voting.hpp @@ -191,22 +191,22 @@ namespace eosiosystem { producers_table producers_tbl( SystemAccount, SystemAccount ); auto idx = producers_tbl.template get_index(); - std::array max_block_net_usage; + std::array max_block_net_usage; std::array target_block_net_usage_pct; std::array base_per_transaction_net_usage; std::array max_transaction_net_usage; - std::array context_free_discount_net_usage_num; - std::array context_free_discount_net_usage_den; + std::array context_free_discount_net_usage_num; + std::array context_free_discount_net_usage_den; - std::array max_block_cpu_usage; + std::array max_block_cpu_usage; std::array target_block_cpu_usage_pct; std::array max_transaction_cpu_usage; std::array base_per_transaction_cpu_usage; std::array base_per_action_cpu_usage; std::array base_setcode_cpu_usage; std::array per_signature_cpu_usage; - std::array context_free_discount_cpu_usage_num; - std::array context_free_discount_cpu_usage_den; + std::array context_free_discount_cpu_usage_num; + std::array context_free_discount_cpu_usage_den; std::array max_transaction_lifetime; std::array deferred_trx_expiration_window; From 4decf990f26c91f5b1b22a7ecafda332f409e06c Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 May 2018 15:22:02 -0400 Subject: [PATCH 0197/1048] delete accidentially undeleted voting.hpp --- voting.hpp | 531 ----------------------------------------------------- 1 file changed, 531 deletions(-) delete mode 100644 voting.hpp diff --git a/voting.hpp b/voting.hpp deleted file mode 100644 index a72d0567..00000000 --- a/voting.hpp +++ /dev/null @@ -1,531 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once -#include "common.hpp" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -namespace eosiosystem { - using eosio::indexed_by; - using eosio::const_mem_fun; - using eosio::bytes; - using eosio::print; - using eosio::singleton; - using eosio::transaction; - - - template - class voting { - public: - static constexpr account_name system_account = SystemAccount; - using currency = typename common::currency; - using system_token_type = typename common::system_token_type; - using eosio_parameters = typename common::eosio_parameters; - using global_state_singleton = typename common::global_state_singleton; - - static constexpr uint32_t max_inflation_rate = common::max_inflation_rate; - static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year - - struct producer_info { - account_name owner; - uint128_t total_votes = 0; - // eosio_parameters prefs; - eosio::bytes packed_key; /// a packed public key object - system_token_type per_block_payments; - time last_rewards_claim = 0; - time time_became_active = 0; - time last_produced_block_time = 0; - - uint64_t primary_key()const { return owner; } - uint128_t by_votes()const { return total_votes; } - bool active() const { return packed_key.size() == sizeof(public_key); } - - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(packed_key) - (per_block_payments)(last_rewards_claim) - (time_became_active)(last_produced_block_time) ) - }; - - typedef eosio::multi_index< N(producerinfo), producer_info, - indexed_by > - > producers_table; - - - struct voter_info { - account_name owner = 0; - account_name proxy = 0; - time last_update = 0; - uint32_t is_proxy = 0; - system_token_type staked; - system_token_type unstaking; - system_token_type unstake_per_week; - uint128_t proxied_votes = 0; - std::vector producers; - uint32_t deferred_trx_id = 0; - time last_unstake_time = 0; //uint32 - - uint64_t primary_key()const { return owner; } - - EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(last_update)(is_proxy)(staked)(unstaking)(unstake_per_week)(proxied_votes)(producers)(deferred_trx_id)(last_unstake_time) ) - }; - - typedef eosio::multi_index< N(voters), voter_info> voters_table; - - - static void increase_voting_power( account_name acnt, system_token_type amount ) { - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( acnt ); - - if( voter == voters_tbl.end() ) { - voter = voters_tbl.emplace( acnt, [&]( voter_info& a ) { - a.owner = acnt; - a.last_update = now(); - a.staked = amount; - }); - } else { - voters_tbl.modify( voter, 0, [&]( auto& av ) { - av.last_update = now(); - av.staked += amount; - }); - } - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - eosio_assert( proxy != voters_tbl.end(), "selected proxy not found" ); //data corruption - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes += amount.quantity; } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } - - if ( producers ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes += amount.quantity; - }); - } - } - } - - static void decrease_voting_power( account_name acnt, system_token_type amount ) { - require_auth( acnt ); - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( acnt ); - eosio_assert( voter != voters_tbl.end(), "stake not found" ); - - if ( 0 < amount.quantity ) { - eosio_assert( amount <= voter->staked, "cannot unstake more than total stake amount" ); - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked -= amount; - a.last_update = now(); - }); - - const std::vector* producers = nullptr; - if ( voter->proxy ) { - auto proxy = voters_tbl.find( voter->proxy ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { a.proxied_votes -= amount.quantity; } ); - if ( proxy->is_proxy ) { //only if proxy is still active. if proxy has been unregistered, we update proxied_votes, but don't propagate to producers - producers = &proxy->producers; - } - } else { - producers = &voter->producers; - } - - if ( producers ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for( auto p : *producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& v ) { - v.total_votes -= amount.quantity; - }); - } - } - } else { - if (voter->deferred_trx_id) { - //XXX cancel_deferred_transaction(voter->deferred_trx_id); - } - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.staked += a.unstaking; - a.unstaking.quantity = 0; - a.unstake_per_week.quantity = 0; - a.deferred_trx_id = 0; - a.last_update = now(); - }); - } - } - - static system_token_type payment_per_block(uint32_t percent_of_max_inflation_rate) { - const system_token_type token_supply = currency::get_total_supply(); - const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); - double continuous_rate = std::log1p(annual_rate); - uint64_t payment = static_cast((continuous_rate * double(token_supply.quantity)) / double(blocks_per_year)); - return (system_token_type(payment)); - } - - static void update_elected_producers(time cycle_time); - -#if 0 - static void update_elected_producers(time cycle_time) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - auto idx = producers_tbl.template get_index(); - - std::array max_block_net_usage; - std::array target_block_net_usage_pct; - std::array base_per_transaction_net_usage; - std::array max_transaction_net_usage; - std::array context_free_discount_net_usage_num; - std::array context_free_discount_net_usage_den; - - std::array max_block_cpu_usage; - std::array target_block_cpu_usage_pct; - std::array max_transaction_cpu_usage; - std::array base_per_transaction_cpu_usage; - std::array base_per_action_cpu_usage; - std::array base_setcode_cpu_usage; - std::array per_signature_cpu_usage; - std::array context_free_discount_cpu_usage_num; - std::array context_free_discount_cpu_usage_den; - - std::array max_transaction_lifetime; - std::array deferred_trx_expiration_window; - std::array max_transaction_delay; - std::array max_inline_action_size; - std::array max_inline_action_depth; - std::array max_authority_depth; - std::array max_generated_transaction_count; - - std::array max_storage_size; - std::array percent_of_max_inflation_rate; - std::array storage_reserve_ratio; - - std::vector schedule; - schedule.reserve(21); - size_t n = 0; - for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { - if ( it->active() ) { - schedule.emplace_back(); - schedule.back().producer_name = it->owner; - eosio_assert( sizeof(schedule.back().block_signing_key) == it->packed_key.size(), "size mismatch" ); - std::copy( it->packed_key.begin(), it->packed_key.end(), schedule.back().block_signing_key.data ); - - max_block_net_usage[n] = it->prefs.max_block_net_usage; - target_block_net_usage_pct[n] = it->prefs.target_block_net_usage_pct; - max_transaction_net_usage[n] = it->prefs.max_transaction_net_usage; - base_per_transaction_net_usage[n] = it->prefs.base_per_transaction_net_usage; - context_free_discount_net_usage_num[n] = it->prefs.context_free_discount_net_usage_num; - context_free_discount_net_usage_den[n] = it->prefs.context_free_discount_net_usage_den; - - max_block_cpu_usage[n] = it->prefs.max_block_cpu_usage; - target_block_cpu_usage_pct[n] = it->prefs.target_block_cpu_usage_pct; - max_transaction_cpu_usage[n] = it->prefs.max_transaction_cpu_usage; - base_per_transaction_cpu_usage[n] = it->prefs.base_per_transaction_cpu_usage; - base_per_action_cpu_usage[n] = it->prefs.base_per_action_cpu_usage; - base_setcode_cpu_usage[n] = it->prefs.base_setcode_cpu_usage; - per_signature_cpu_usage[n] = it->prefs.per_signature_cpu_usage; - context_free_discount_cpu_usage_num[n] = it->prefs.context_free_discount_cpu_usage_num; - context_free_discount_cpu_usage_den[n] = it->prefs.context_free_discount_cpu_usage_den; - - max_transaction_lifetime[n] = it->prefs.max_transaction_lifetime; - deferred_trx_expiration_window[n] = it->prefs.deferred_trx_expiration_window; - max_transaction_delay[n] = it->prefs.max_transaction_delay; - max_inline_action_size[n] = it->prefs.max_inline_action_size; - max_inline_action_depth[n] = it->prefs.max_inline_action_depth; - max_authority_depth[n] = it->prefs.max_authority_depth; - max_generated_transaction_count[n] = it->prefs.max_generated_transaction_count; - - max_storage_size[n] = it->prefs.max_storage_size; - storage_reserve_ratio[n] = it->prefs.storage_reserve_ratio; - percent_of_max_inflation_rate[n] = it->prefs.percent_of_max_inflation_rate; - ++n; - } - } - if ( n == 0 ) { //no active producers with votes > 0 - return; - } - if ( 1 < n ) { - std::sort( max_block_net_usage.begin(), max_block_net_usage.begin()+n ); - std::sort( target_block_net_usage_pct.begin(), target_block_net_usage_pct.begin()+n ); - std::sort( max_transaction_net_usage.begin(), max_transaction_net_usage.begin()+n ); - std::sort( base_per_transaction_net_usage.begin(), base_per_transaction_net_usage.begin()+n ); - std::sort( context_free_discount_net_usage_num.begin(), context_free_discount_net_usage_num.begin()+n ); - std::sort( context_free_discount_net_usage_den.begin(), context_free_discount_net_usage_den.begin()+n ); - - std::sort( max_block_cpu_usage.begin(), max_block_cpu_usage.begin()+n ); - std::sort( target_block_cpu_usage_pct.begin(), target_block_cpu_usage_pct.begin()+n ); - std::sort( max_transaction_cpu_usage.begin(), max_transaction_cpu_usage.begin()+n ); - std::sort( base_per_transaction_cpu_usage.begin(), base_per_transaction_cpu_usage.begin()+n ); - std::sort( base_per_action_cpu_usage.begin(), base_per_action_cpu_usage.begin()+n ); - std::sort( base_setcode_cpu_usage.begin(), base_setcode_cpu_usage.begin()+n ); - std::sort( per_signature_cpu_usage.begin(), per_signature_cpu_usage.begin()+n ); - std::sort( context_free_discount_cpu_usage_num.begin(), context_free_discount_cpu_usage_num.begin()+n ); - std::sort( context_free_discount_cpu_usage_den.begin(), context_free_discount_cpu_usage_den.begin()+n ); - - std::sort( max_transaction_lifetime.begin(), max_transaction_lifetime.begin()+n ); - std::sort( deferred_trx_expiration_window.begin(), deferred_trx_expiration_window.begin()+n ); - std::sort( max_transaction_delay.begin(), max_transaction_delay.begin()+n ); - std::sort( max_inline_action_size.begin(), max_inline_action_size.begin()+n ); - std::sort( max_inline_action_depth.begin(), max_inline_action_depth.begin()+n ); - std::sort( max_authority_depth.begin(), max_authority_depth.begin()+n ); - std::sort( max_generated_transaction_count.begin(), max_generated_transaction_count.begin()+n ); - - std::sort( max_storage_size.begin(), max_storage_size.begin()+n ); - std::sort( storage_reserve_ratio.begin(), storage_reserve_ratio.begin()+n ); - std::sort( percent_of_max_inflation_rate.begin(), percent_of_max_inflation_rate.begin()+n ); - } - - bytes packed_schedule = pack(schedule); - set_active_producers( packed_schedule.data(), packed_schedule.size() ); - size_t median = n/2; - - auto parameters = global_state_singleton::exists() ? global_state_singleton::get() - : common::get_default_parameters(); - - parameters.max_block_net_usage = max_block_net_usage[median]; - parameters.target_block_net_usage_pct = target_block_net_usage_pct[median]; - parameters.max_transaction_net_usage = max_transaction_net_usage[median]; - parameters.base_per_transaction_net_usage = base_per_transaction_net_usage[median]; - parameters.context_free_discount_net_usage_num = context_free_discount_net_usage_num[median]; - parameters.context_free_discount_net_usage_den = context_free_discount_net_usage_den[median]; - - parameters.max_block_cpu_usage = max_block_cpu_usage[median]; - parameters.target_block_cpu_usage_pct = target_block_cpu_usage_pct[median]; - parameters.max_transaction_cpu_usage = max_transaction_cpu_usage[median]; - parameters.base_per_transaction_cpu_usage = base_per_transaction_cpu_usage[median]; - parameters.base_per_action_cpu_usage = base_per_action_cpu_usage[median]; - parameters.base_setcode_cpu_usage = base_setcode_cpu_usage[median]; - parameters.per_signature_cpu_usage = per_signature_cpu_usage[median]; - parameters.context_free_discount_cpu_usage_num = context_free_discount_cpu_usage_num[median]; - parameters.context_free_discount_cpu_usage_den = context_free_discount_cpu_usage_den[median]; - - parameters.max_transaction_lifetime = max_transaction_lifetime[median]; - parameters.deferred_trx_expiration_window = deferred_trx_expiration_window[median]; - parameters.max_transaction_delay = max_transaction_delay[median]; - parameters.max_inline_action_size = max_inline_action_size[median]; - parameters.max_inline_action_depth = max_inline_action_depth[median]; - parameters.max_authority_depth = max_authority_depth[median]; - parameters.max_generated_transaction_count = max_generated_transaction_count[median]; - - parameters.max_storage_size = max_storage_size[median]; - parameters.storage_reserve_ratio = storage_reserve_ratio[median]; - parameters.percent_of_max_inflation_rate = percent_of_max_inflation_rate[median]; - - // not voted on - parameters.first_block_time_in_cycle = cycle_time; - - // derived parameters - auto half_of_percentage = parameters.percent_of_max_inflation_rate / 2; - auto other_half_of_percentage = parameters.percent_of_max_inflation_rate - half_of_percentage; - parameters.payment_per_block = payment_per_block(half_of_percentage); - parameters.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); - parameters.blocks_per_cycle = common::blocks_per_producer * schedule.size(); - - if ( parameters.max_storage_size < parameters.total_storage_bytes_reserved ) { - parameters.max_storage_size = parameters.total_storage_bytes_reserved; - } - - auto issue_quantity = parameters.blocks_per_cycle * (parameters.payment_per_block + parameters.payment_to_eos_bucket); - currency::inline_issue(SystemAccount, issue_quantity); - set_blockchain_parameters(parameters); - global_state_singleton::set(parameters); - } -#endif - - ACTION( SystemAccount, voteproducer ) { - account_name voter; - account_name proxy; - std::vector producers; - - EOSLIB_SERIALIZE( voteproducer, (voter)(proxy)(producers) ) - }; - - /** - * @pre vp.producers must be sorted from lowest to highest - * @pre if proxy is set then no producers can be voted for - * @pre every listed producer or proxy must have been previously registered - * @pre vp.voter must authorize this action - * @pre voter must have previously staked some EOS for voting - */ - static void on( const voteproducer& vp ) { - require_auth( vp.voter ); - - //validate input - if ( vp.proxy ) { - eosio_assert( vp.producers.size() == 0, "cannot vote for producers and proxy at same time" ); - require_recipient( vp.proxy ); - } else { - eosio_assert( vp.producers.size() <= 30, "attempt to vote for too many producers" ); - for( size_t i = 1; i < vp.producers.size(); ++i ) { - eosio_assert( vp.producers[i-1] < vp.producers[i], "producer votes must be unique and sorted" ); - } - } - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto voter = voters_tbl.find( vp.voter ); - - eosio_assert( voter != voters_tbl.end() && ( 0 < voter->staked.quantity || ( voter->is_proxy && 0 < voter->proxied_votes ) ), "no stake to vote" ); - if ( voter->is_proxy ) { - eosio_assert( vp.proxy == 0 , "account registered as a proxy is not allowed to use a proxy" ); - } - - //find old producers, update old proxy if needed - const std::vector* old_producers = nullptr; - if( voter->proxy ) { - if ( voter->proxy == vp.proxy ) { - return; // nothing changed - } - auto old_proxy = voters_tbl.find( voter->proxy ); - eosio_assert( old_proxy != voters_tbl.end(), "old proxy not found" ); //data corruption - voters_tbl.modify( old_proxy, 0, [&](auto& a) { a.proxied_votes -= voter->staked.quantity; } ); - if ( old_proxy->is_proxy ) { //if proxy stoped being proxy, the votes were already taken back from producers by on( const unregister_proxy& ) - old_producers = &old_proxy->producers; - } - } else { - old_producers = &voter->producers; - } - - //find new producers, update new proxy if needed - const std::vector* new_producers = nullptr; - if ( vp.proxy ) { - auto new_proxy = voters_tbl.find( vp.proxy ); - eosio_assert( new_proxy != voters_tbl.end() && new_proxy->is_proxy, "proxy not found" ); - voters_tbl.modify( new_proxy, 0, [&](auto& a) { a.proxied_votes += voter->staked.quantity; } ); - new_producers = &new_proxy->producers; - } else { - new_producers = &vp.producers; - } - - producers_table producers_tbl( SystemAccount, SystemAccount ); - uint128_t votes = voter->staked.quantity; - if ( voter->is_proxy ) { - votes += voter->proxied_votes; - } - - if ( old_producers ) { //old_producers == nullptr if proxy has stopped being a proxy and votes were taken back from the producers at that moment - //revoke votes only from no longer elected - std::vector revoked( old_producers->size() ); - auto end_it = std::set_difference( old_producers->begin(), old_producers->end(), new_producers->begin(), new_producers->end(), revoked.begin() ); - for ( auto it = revoked.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= votes; } ); - } - } - - //update newly elected - std::vector elected( new_producers->size() ); - auto end_it = elected.begin(); - if( old_producers ) { - end_it = std::set_difference( new_producers->begin(), new_producers->end(), old_producers->begin(), old_producers->end(), elected.begin() ); - } else { - end_it = std::copy( new_producers->begin(), new_producers->end(), elected.begin() ); - } - for ( auto it = elected.begin(); it != end_it; ++it ) { - auto prod = producers_tbl.find( *it ); - eosio_assert( prod != producers_tbl.end(), "producer is not registered" ); - if ( vp.proxy == 0 ) { //direct voting, in case of proxy voting update total_votes even for inactive producers - eosio_assert( prod->active(), "producer is not currently registered" ); - } - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += votes; } ); - } - - // save new values to the account itself - voters_tbl.modify( voter, 0, [&](voter_info& a) { - a.proxy = vp.proxy; - a.last_update = now(); - a.producers = vp.producers; - }); - } - - ACTION( SystemAccount, regproxy ) { - account_name proxy; - - EOSLIB_SERIALIZE( regproxy, (proxy) ) - }; - - static void on( const regproxy& reg ) { - require_auth( reg.proxy ); - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto proxy = voters_tbl.find( reg.proxy ); - if ( proxy != voters_tbl.end() ) { - eosio_assert( proxy->is_proxy == 0, "account is already a proxy" ); - eosio_assert( proxy->proxy == 0, "account that uses a proxy is not allowed to become a proxy" ); - voters_tbl.modify( proxy, 0, [&](voter_info& a) { - a.is_proxy = 1; - a.last_update = now(); - //a.proxied_votes may be > 0, if the proxy has been unregistered, so we had to keep the value - }); - if ( 0 < proxy->proxied_votes ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for ( auto p : proxy->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes += proxy->proxied_votes; }); - } - } - } else { - voters_tbl.emplace( reg.proxy, [&]( voter_info& a ) { - a.owner = reg.proxy; - a.last_update = now(); - a.proxy = 0; - a.is_proxy = 1; - a.proxied_votes = 0; - a.staked.quantity = 0; - }); - } - } - - ACTION( SystemAccount, unregproxy ) { - account_name proxy; - - EOSLIB_SERIALIZE( unregproxy, (proxy) ) - }; - - static void on( const unregproxy& reg ) { - require_auth( reg.proxy ); - - voters_table voters_tbl( SystemAccount, SystemAccount ); - auto proxy = voters_tbl.find( reg.proxy ); - eosio_assert( proxy != voters_tbl.end(), "proxy not found" ); - eosio_assert( proxy->is_proxy == 1, "account is not a proxy" ); - - voters_tbl.modify( proxy, 0, [&](voter_info& a) { - a.is_proxy = 0; - a.last_update = now(); - //a.proxied_votes should be kept in order to be able to reenable this proxy in the future - }); - - if ( 0 < proxy->proxied_votes ) { - producers_table producers_tbl( SystemAccount, SystemAccount ); - for ( auto p : proxy->producers ) { - auto prod = producers_tbl.find( p ); - eosio_assert( prod != producers_tbl.end(), "never existed producer" ); //data corruption - producers_tbl.modify( prod, 0, [&]( auto& pi ) { pi.total_votes -= proxy->proxied_votes; }); - } - } - } - - }; -} From cb380182970bce3eca3d02cb173efc9ec84197d6 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 May 2018 15:51:33 -0400 Subject: [PATCH 0198/1048] fix validate_eosio.system_abi --- eosio.system.abi | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 8c8bb211..e64ed4d7 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -21,7 +21,7 @@ {"name":"from", "type":"account_name"}, {"name":"receiver", "type":"account_name"}, {"name":"stake_net_quantity", "type":"asset"}, - {"name":"stake_cpu_quantity", "type":"asset"}, + {"name":"stake_cpu_quantity", "type":"asset"} ] },{ "name": "undelegatebw", @@ -30,7 +30,7 @@ {"name":"from", "type":"account_name"}, {"name":"receiver", "type":"account_name"}, {"name":"unstake_net_quantity", "type":"asset"}, - {"name":"unstake_cpu_quantity", "type":"asset"}, + {"name":"unstake_cpu_quantity", "type":"asset"} ] },{ "name": "refund", @@ -143,7 +143,7 @@ "name": "regproxy", "base": "", "fields": [ - {"name":"proxy", "type":"account_name"} + {"name":"proxy", "type":"account_name"}, {"name":"isproxy", "type":"bool"} ] },{ @@ -167,7 +167,7 @@ {"name":"is_proxy", "type":"bool"}, {"name":"deferred_trx_id", "type":"uint32"}, {"name":"last_unstake_time", "type":"time"}, - {"name":"unstaking", "type":"asset"}, + {"name":"unstaking", "type":"asset"} ] },{ "name": "claimrewards", From 7c4bc03470f2904ade2d75290b56bb03c472818d Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 2 May 2018 16:16:06 -0400 Subject: [PATCH 0199/1048] Fix bugs with system staking 1. transfers are now prevented where from/to are same 2. inline transfers to self are now skipped (eosio staking for others) 3. unit test updated to demonstrate staking works --- delegate_bandwidth.cpp | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 8dc91cca..205f4dca 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -129,8 +129,10 @@ namespace eosiosystem { require_auth( payer ); eosio_assert( quant.amount > 0, "must purchase a positive amount" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, - { payer, N(eosio), quant, std::string("buy ram") } ); + if( payer != N(eosio) ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, + { payer, N(eosio), quant, std::string("buy ram") } ); + } const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; @@ -205,8 +207,10 @@ namespace eosiosystem { }); set_resource_limits( res_itr->owner, res_itr->storage_bytes, uint64_t(res_itr->net_weight.amount), uint64_t(res_itr->cpu_weight.amount) ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), account, asset(tokens_out), std::string("sell ram") } ); + if( N(eosio) != account ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), account, asset(tokens_out), std::string("sell ram") } ); + } } void system_contract::delegatebw( account_name from, account_name receiver, @@ -259,8 +263,10 @@ namespace eosiosystem { set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, uint64_t(tot_itr->net_weight.amount), uint64_t(tot_itr->cpu_weight.amount) ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); + if( N(eosio) != from) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); + } print( "voters" ); auto from_voter = _voters.find(from); From ec159ddf2a65b94dfbc93ace2e31bb7b8bde1083 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 2 May 2018 23:36:18 -0400 Subject: [PATCH 0200/1048] Fix #2718 - Multiple Conflicting Last Irreversible Blocks --- delegate_bandwidth.cpp | 2 +- eosio.system.hpp | 2 +- native.hpp | 9 +++++---- producer_pay.cpp | 2 +- 4 files changed, 8 insertions(+), 7 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 205f4dca..35f4d332 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -167,7 +167,7 @@ namespace eosiosystem { res.storage_bytes += uint64_t(bytes_out); }); } - set_resource_limits( res_itr->owner, res_itr->storage_bytes, uint64_t(res_itr->net_weight.amount), uint64_t(res_itr->cpu_weight.amount) ); + set_resource_limits( res_itr->owner, res_itr->storage_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } diff --git a/eosio.system.hpp b/eosio.system.hpp index 7d5e8f0f..7dd21720 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -122,7 +122,7 @@ namespace eosiosystem { [[noreturn]] ~system_contract(); // Actions: - void onblock( const block_id_type&, uint32_t timestamp_slot, account_name producer ); + void onblock( uint32_t timestamp_slot, account_name producer ); // const block_header& header ); /// only parse first 3 fields of block header // functions defined in delegate_bandwidth.cpp diff --git a/native.hpp b/native.hpp index 2100b65d..18c89cdc 100644 --- a/native.hpp +++ b/native.hpp @@ -46,17 +46,18 @@ namespace eosiosystem { }; struct block_header { - block_id_type previous; uint32_t timestamp; account_name producer; - uint32_t schedule_version = 0; + uint16_t confirmed = 0; + block_id_type previous; checksum256 transaction_mroot; checksum256 action_mroot; + uint32_t schedule_version = 0; eosio::optional new_producers; // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE(block_header, (previous)(timestamp)(producer)(schedule_version)(transaction_mroot)(action_mroot) - (new_producers)) + EOSLIB_SERIALIZE(block_header, (timestamp)(producer)(confirmed)(previous)(transaction_mroot)(action_mroot) + (schedule_version)(new_producers)) }; diff --git a/producer_pay.cpp b/producer_pay.cpp index c0402687..a8b1c9f2 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -7,7 +7,7 @@ namespace eosiosystem { static const uint32_t num_of_payed_producers = 121; -void system_contract::onblock( const block_id_type&, block_timestamp timestamp, account_name producer ) { +void system_contract::onblock( block_timestamp timestamp, account_name producer ) { global_state_singleton gs( _self, _self ); auto parameters = gs.exists() ? gs.get() : get_default_parameters(); From f618449d343b72fac8d760428d8cb812ce5770f2 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 3 May 2018 12:14:47 -0400 Subject: [PATCH 0201/1048] allow for block producer configurable leeway for cpu and net usage during execution (still checks against new limits without the leeway at the end of the transaction) --- eosio.system.abi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index e64ed4d7..c3695f3a 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -73,6 +73,7 @@ {"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": "uint64"}, @@ -82,6 +83,7 @@ {"name":"base_per_action_cpu_usage", "type":"uint32"}, {"name":"base_setcode_cpu_usage", "type":"uint32"}, {"name":"per_signature_cpu_usage", "type":"uint32"}, + {"name":"cpu_usage_leeway", "type":"uint32"}, {"name":"context_free_discount_cpu_usage_num", "type":"uint32"}, {"name":"context_free_discount_cpu_usage_den", "type":"uint32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, From a750cd4b7261a8ebc1b7736f2d83a91fb2d9fba8 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 3 May 2018 13:50:37 -0400 Subject: [PATCH 0202/1048] update system contract with buy with bytes and test selling --- delegate_bandwidth.cpp | 22 +++++++++++++++++++++- eosio.system.abi | 23 +++++++++++++++++++++++ eosio.system.cpp | 2 +- eosio.system.hpp | 3 ++- 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 35f4d332..b9cd9aa5 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -113,6 +113,26 @@ namespace eosiosystem { // r->cpu_weight.amount ); } + /** + * This action will buy an exact amount of ram and bill the payer the current market price. + */ + void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { + const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; + const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; + + const double R = unstaked_token_supply; + const double C = _gstate.free_ram() + bytes; + const double F = _gstate.storage_reserve_ratio / 10000.0; + const double T = bytes; + const double ONE(1.0); + + double E = -R * (ONE - std::pow( ONE + T/C, F ) ); + + int64_t tokens_out = int64_t(E*1.0105); + print( "desired ram: ", bytes, "\n" ); + + buyram( payer, receiver, asset(tokens_out) ); + } /** @@ -176,7 +196,7 @@ namespace eosiosystem { * refunds the purchase price to the account. In this way there is no profit to be made through buying * and selling ram. */ - void system_contract::sellram( account_name account, uint64_t bytes ) { + void system_contract::sellram( account_name account, uint32_t bytes ) { user_resources_table userres( _self, account ); auto res_itr = userres.find( account ); eosio_assert( res_itr != userres.end(), "no resource row" ); diff --git a/eosio.system.abi b/eosio.system.abi index e64ed4d7..0b0b31e0 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -6,6 +6,21 @@ "fields": [ {"name":"value", "type":"string"} ] + },{ + "name": "buyrambytes", + "base": "", + "fields": [ + {"name":"payer", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"bytes", "type":"uint32"} + ] + },{ + "name": "sellram", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"bytes", "type":"uint32"} + ] },{ "name": "buyram", "base": "", @@ -179,9 +194,17 @@ ], "actions": [ { + "name": "buyrambytes", + "type": "buyrambytes", + "ricardian_contract": "" + },{ "name": "buyram", "type": "buyram", "ricardian_contract": "" + },{ + "name": "sellram", + "type": "sellram", + "ricardian_contract": "" },{ "name": "delegatebw", "type": "delegatebw", diff --git a/eosio.system.cpp b/eosio.system.cpp index cb16ba19..96d8c4f4 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -38,7 +38,7 @@ EOSIO_ABI( eosiosystem::system_contract, (setparams) // delegate_bandwith.cpp (delegatebw)(undelegatebw)(refund) - (buyram)(sellram) + (buyram)(buyrambytes)(sellram) // voting.cpp (regproxy)(regproducer)(unregprod)(voteproducer) // producer_pay.cpp diff --git a/eosio.system.hpp b/eosio.system.hpp index 7dd21720..d5cab5ee 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -156,12 +156,13 @@ namespace eosiosystem { * tokens will be executed. */ void buyram( account_name buyer, account_name receiver, asset tokens ); + void buyrambytes( account_name buyer, account_name receiver, uint32_t bytes ); /** * Reduces quota my bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. */ - void sellram( account_name receiver, uint64_t bytes ); + void sellram( account_name receiver, uint32_t bytes ); /** * This action is called after the delegation-period to claim all pending From 4e7d0e0766071ad2407acb5ce3a8c6612d8467f8 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 3 May 2018 14:23:12 -0700 Subject: [PATCH 0203/1048] add the VOTEPRODUCER Ricardian contract partially satisfies #1948 --- eosio.system.voteproducer-rc.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 eosio.system.voteproducer-rc.md diff --git a/eosio.system.voteproducer-rc.md b/eosio.system.voteproducer-rc.md new file mode 100644 index 00000000..670cb99f --- /dev/null +++ b/eosio.system.voteproducer-rc.md @@ -0,0 +1,13 @@ +#Ricardian Contract for VOTEPRODUCER +This Ricardian contract for the system command VOTEPRODUCER is legally binding and can be used in the event of a dispute. Disputes shall be settled in this system's default arbitration forum. + + +VOTEPRODUCER (voter; array:producers) +Intent: cast a valid vote for up to 30 BP candidates +As an authorized party I {{ signer }} wish to vote on behalf of {{ voter }} in favor of the block producer candidates {{ array:producers }} with a voting weight equal to all tokens currently owned by {{ voter }} and staked for CPU or bandwidth. + +If I am not the beneficial owner of these shares I stipulate I have proof that I’ve been authorized to vote these shares by their beneficial owner(s). + +I stipulate I have not and will not accept anything of value in exchange for these votes, on penalty of confiscation of these tokens, and other penalties. + +I acknowledge that using any system of automatic voting, re-voting, or vote refreshing, or allowing such a system to be used on my behalf or on behalf of another, is forbidden and doing so violates this contract. \ No newline at end of file From cc963202b09f86d787f529532d0bd12da9b8ade5 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 4 May 2018 09:52:07 -0400 Subject: [PATCH 0204/1048] fix pricing model on RAM --- delegate_bandwidth.cpp | 79 ++++++++++++++++-------------------------- eosio.system.cpp | 20 ++++++++++- eosio.system.hpp | 2 ++ exchange_state.cpp | 79 ++++++++++++++++++++++++++++++++++++++++++ exchange_state.hpp | 40 +++++++++++++++++++++ voting.cpp | 4 +-- 6 files changed, 172 insertions(+), 52 deletions(-) create mode 100644 exchange_state.cpp create mode 100644 exchange_state.hpp diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index b9cd9aa5..d29aa72d 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -35,7 +35,7 @@ namespace eosiosystem { account_name owner; asset net_weight; asset cpu_weight; - uint64_t storage_bytes = 0; + int64_t storage_bytes = 0; uint64_t primary_key()const { return owner; } @@ -102,7 +102,7 @@ namespace eosiosystem { user_resources_table userres( _self, newact); - auto r = userres.emplace( newact, [&]( auto& res ) { + userres.emplace( newact, [&]( auto& res ) { res.owner = newact; }); @@ -117,21 +117,12 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; - const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; - - const double R = unstaked_token_supply; - const double C = _gstate.free_ram() + bytes; - const double F = _gstate.storage_reserve_ratio / 10000.0; - const double T = bytes; - const double ONE(1.0); - - double E = -R * (ONE - std::pow( ONE + T/C, F ) ); - - int64_t tokens_out = int64_t(E*1.0105); - print( "desired ram: ", bytes, "\n" ); - - buyram( payer, receiver, asset(tokens_out) ); + auto itr = _rammarket.find(S(4,RAMEOS)); + auto tmp = *itr; + auto eosout = tmp.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); + print( "eosout: ", eosout, "\n" ); + + buyram( payer, receiver, eosout ); } @@ -154,20 +145,15 @@ namespace eosiosystem { { payer, N(eosio), quant, std::string("buy ram") } ); } - const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; - const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; + print( "free ram: ", _gstate.free_ram(), "\n"); - print( "free ram: ", _gstate.free_ram(), " tokens: ", system_token_supply, " unstaked: ", unstaked_token_supply, "\n" ); + int64_t bytes_out; - const double E = quant.amount; - const double R = unstaked_token_supply - E; - const double C = _gstate.free_ram(); //free_ram; - const double F = 1./(_gstate.storage_reserve_ratio/10000.0); /// 10% reserve ratio pricing, assumes only 10% of tokens will ever want to stake for ram - const double ONE(1.0); + auto itr = _rammarket.find(S(4,RAMEOS)); + _rammarket.modify( itr, 0, [&]( auto& es ) { + bytes_out = es.convert( quant, S(0,RAM) ).amount; + }); - double T = C * (std::pow( ONE + E/R, F ) - ONE); - T *= .99; /// 1% fee on every conversion - int64_t bytes_out = static_cast(T); print( "ram bytes out: ", bytes_out, "\n" ); eosio_assert( bytes_out > 0, "must reserve a positive amount" ); @@ -180,11 +166,11 @@ namespace eosiosystem { if( res_itr == userres.end() ) { res_itr = userres.emplace( receiver, [&]( auto& res ) { res.owner = receiver; - res.storage_bytes = uint64_t(bytes_out); + res.storage_bytes = bytes_out; }); } else { userres.modify( res_itr, receiver, [&]( auto& res ) { - res.storage_bytes += uint64_t(bytes_out); + res.storage_bytes += bytes_out; }); } set_resource_limits( res_itr->owner, res_itr->storage_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); @@ -197,35 +183,30 @@ namespace eosiosystem { * and selling ram. */ void system_contract::sellram( account_name account, uint32_t bytes ) { + require_auth( account ); + user_resources_table userres( _self, account ); auto res_itr = userres.find( account ); eosio_assert( res_itr != userres.end(), "no resource row" ); eosio_assert( res_itr->storage_bytes >= bytes, "insufficient quota" ); - const double system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; - const double unstaked_token_supply = system_token_supply - _gstate.total_storage_stake.amount; - - const double R = unstaked_token_supply; - const double C = _gstate.free_ram() + bytes; - const double F = _gstate.storage_reserve_ratio / 10000.0; - const double T = bytes; - const double ONE(1.0); - - double E = -R * (ONE - std::pow( ONE + T/C, F ) ); - - E *= .99; /// 1% fee on every conversion, - /// let the system contract profit on speculation while preventing abuse caused by rounding errors - - int64_t tokens_out = int64_t(E); - eosio_assert( tokens_out > 0, "must free at least one token" ); + asset tokens_out; + auto itr = _rammarket.find(S(4,RAMEOS)); + _rammarket.modify( itr, 0, [&]( auto& es ) { + tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); + print( "out: ", tokens_out, "\n" ); + }); _gstate.total_storage_bytes_reserved -= bytes; - _gstate.total_storage_stake.amount -= tokens_out; + _gstate.total_storage_stake.amount -= tokens_out.amount; + + //// this shouldn't happen, but just in case it does we should prevent it + eosio_assert( _gstate.total_storage_stake.amount >= 0, "error, attempt to unstake more tokens than previously staked" ); userres.modify( res_itr, account, [&]( auto& res ) { res.storage_bytes -= bytes; }); - set_resource_limits( res_itr->owner, res_itr->storage_bytes, uint64_t(res_itr->net_weight.amount), uint64_t(res_itr->cpu_weight.amount) ); + set_resource_limits( res_itr->owner, res_itr->storage_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); if( N(eosio) != account ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, @@ -281,7 +262,7 @@ namespace eosiosystem { }); } - set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, uint64_t(tot_itr->net_weight.amount), uint64_t(tot_itr->cpu_weight.amount) ); + set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); if( N(eosio) != from) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, diff --git a/eosio.system.cpp b/eosio.system.cpp index 96d8c4f4..9cf2cc31 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -4,6 +4,7 @@ #include "delegate_bandwidth.cpp" #include "producer_pay.cpp" #include "voting.cpp" +#include "exchange_state.cpp" namespace eosiosystem { @@ -12,10 +13,27 @@ namespace eosiosystem { :native(s), _voters(_self,_self), _producers(_self,_self), - _global(_self,_self) + _global(_self,_self), + _rammarket(_self,_self) { print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); + + auto itr = _rammarket.find(S(4,RAMEOS)); + + if( itr == _rammarket.end() ) { + auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; + itr = _rammarket.emplace( _self, [&]( auto& m ) { + m.supply.amount = 100000000000000ll; + m.supply.symbol = S(4,RAMEOS); + m.base.balance.amount = int64_t(_gstate.free_ram()); + m.base.balance.symbol = S(0,RAM); + m.quote.balance.amount = system_token_supply / 1000; + m.quote.balance.symbol = S(4,EOS); + }); + } else { + print( "ram market already created" ); + } } eosio_global_state system_contract::get_default_parameters() { diff --git a/eosio.system.hpp b/eosio.system.hpp index d5cab5ee..a4b639f7 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -8,6 +8,7 @@ #include #include #include +#include #include @@ -116,6 +117,7 @@ namespace eosiosystem { global_state_singleton _global; eosio_global_state _gstate; + rammarket _rammarket; public: system_contract( account_name s ); diff --git a/exchange_state.cpp b/exchange_state.cpp new file mode 100644 index 00000000..90a945ff --- /dev/null +++ b/exchange_state.cpp @@ -0,0 +1,79 @@ +#include + +namespace eosiosystem { + asset exchange_state::convert_to_exchange( connector& c, asset in ) { + + real_type R(supply.amount); + real_type C(c.balance.amount+in.amount); + real_type F(c.weight/1000.0); + real_type T(in.amount); + real_type ONE(1.0); + + real_type E = -R * (ONE - std::pow( ONE + T / C, F) ); + //print( "E: ", E, "\n"); + int64_t issued = int64_t(E); + + supply.amount += issued; + c.balance.amount += in.amount; + + return asset( issued, supply.symbol ); + } + + asset exchange_state::convert_from_exchange( connector& c, asset in ) { + eosio_assert( in.symbol== supply.symbol, "unexpected asset symbol input" ); + + real_type R(supply.amount - in.amount); + real_type C(c.balance.amount); + real_type F(1000.0/c.weight); + real_type E(in.amount); + real_type ONE(1.0); + + + real_type T = C * (std::pow( ONE + E/R, F) - ONE); + //print( "T: ", T, "\n"); + int64_t out = int64_t(T); + + supply.amount -= in.amount; + c.balance.amount -= out; + + return asset( out, c.balance.symbol ); + } + + asset exchange_state::convert( asset from, symbol_type to ) { + auto sell_symbol = from.symbol; + auto ex_symbol = supply.symbol; + auto base_symbol = base.balance.symbol; + auto quote_symbol = quote.balance.symbol; + + //print( "From: ", from, " TO ", asset( 0,to), "\n" ); + //print( "base: ", base_symbol, "\n" ); + //print( "quote: ", quote_symbol, "\n" ); + //print( "ex: ", supply.symbol, "\n" ); + + if( sell_symbol != ex_symbol ) { + if( sell_symbol == base_symbol ) { + from = convert_to_exchange( base, from ); + } else if( sell_symbol == quote_symbol ) { + from = convert_to_exchange( quote, from ); + } else { + eosio_assert( false, "invalid sell" ); + } + } else { + if( to == base_symbol ) { + from = convert_from_exchange( base, from ); + } else if( to == quote_symbol ) { + from = convert_from_exchange( quote, from ); + } else { + eosio_assert( false, "invalid conversion" ); + } + } + + if( to != from.symbol ) + return convert( from, to ); + + return from; + } + + + +} /// namespace eosiosystem diff --git a/exchange_state.hpp b/exchange_state.hpp new file mode 100644 index 00000000..3705a9b8 --- /dev/null +++ b/exchange_state.hpp @@ -0,0 +1,40 @@ +#pragma once + +#include + +namespace eosiosystem { + using eosio::asset; + using eosio::symbol_type; + + typedef double real_type; + + /** + * Uses Bancor math to create a 50/50 relay between two asset types. The state of the + * bancor exchange is entirely contained within this struct. There are no external + * side effects associated with using this API. + */ + struct exchange_state { + asset supply; + + struct connector { + asset balance; + double weight = .5; + + EOSLIB_SERIALIZE( connector, (balance)(weight) ) + }; + + connector base; + connector quote; + + uint64_t primary_key()const { return supply.symbol; } + + asset convert_to_exchange( connector& c, asset in ); + asset convert_from_exchange( connector& c, asset in ); + asset convert( asset from, symbol_type to ); + + EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) + }; + + typedef eosio::multi_index rammarket; + +} /// namespace eosiosystem diff --git a/voting.cpp b/voting.cpp index 30ab32fd..fda3c8cb 100644 --- a/voting.cpp +++ b/voting.cpp @@ -39,7 +39,7 @@ namespace eosiosystem { * @pre authority of producer to register * */ - void system_contract::regproducer( const account_name producer, const public_key& producer_key, const std::string& url ) { //, const eosio_parameters& prefs ) { + void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url ) { //, const eosio_parameters& prefs ) { eosio_assert( url.size() < 512, "url too long" ); //eosio::print("produce_key: ", producer_key.size(), ", sizeof(public_key): ", sizeof(public_key), "\n"); require_auth( producer ); @@ -67,7 +67,7 @@ namespace eosiosystem { const auto& prod = _producers.get( producer ); _producers.modify( prod, 0, [&]( producer_info& info ){ - info.producer_key = public_key(); + info.producer_key = eosio::public_key(); }); } From bb44601660906f583c75b6fb2ce3c72296bf8fc5 Mon Sep 17 00:00:00 2001 From: Matt Witherspoon <32485495+spoonincode@users.noreply.github.com> Date: Fri, 4 May 2018 12:01:16 -0400 Subject: [PATCH 0205/1048] Remove nonce on the system contracts --- eosio.system.abi | 10 ---------- eosio.system.cpp | 2 -- eosio.system.hpp | 2 -- 3 files changed, 14 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index fd9ea622..d8373865 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -1,12 +1,6 @@ { "types": [], "structs": [{ - "name": "nonce", - "base": "", - "fields": [ - {"name":"value", "type":"string"} - ] - },{ "name": "buyrambytes", "base": "", "fields": [ @@ -243,10 +237,6 @@ "name": "claimrewards", "type": "claimrewards", "ricardian_contract": "" - },{ - "name": "nonce", - "type": "nonce", - "ricardian_contract": "" } ], "tables": [{ diff --git a/eosio.system.cpp b/eosio.system.cpp index 9cf2cc31..1d746418 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -65,6 +65,4 @@ EOSIO_ABI( eosiosystem::system_contract, //XXX (onblock) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) - // defined in eosio.system.hpp - (nonce) ) diff --git a/eosio.system.hpp b/eosio.system.hpp index a4b639f7..a1855086 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -184,8 +184,6 @@ namespace eosiosystem { void regproxy( const account_name proxy, bool isproxy ); - void nonce( const std::string& /*value*/ ) {} - // functions defined in producer_pay.cpp void claimrewards( const account_name& owner ); From 1df7239a947fd1574a4690c5dacae8d9e266399f Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 4 May 2018 13:35:22 -0400 Subject: [PATCH 0206/1048] missing table userres added to system contract ABI #2661 --- eosio.system.abi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index fd9ea622..048b75b8 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -63,6 +63,15 @@ {"name":"cpu_weight", "type":"uint64"}, {"name":"storage_bytes", "type":"uint64"} ] + },{ + "name": "user_resources", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"storage_bytes", "type":"uint64"} + ] },{ "name": "total_resources", "base": "", @@ -267,6 +276,12 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["account_name"] + },{ + "name": "userres", + "type": "user_resources", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] },{ "name": "totalband", "type": "total_resources", From 1d1b8418f4ecd5eb20822e92a1febfafc421f2dd Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sat, 5 May 2018 12:41:51 -0400 Subject: [PATCH 0207/1048] fix token tests and some system tests --- delegate_bandwidth.cpp | 18 +++++++++++++----- voting.cpp | 6 +++++- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index d29aa72d..42d3d02a 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -269,22 +269,26 @@ namespace eosiosystem { { from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); } - print( "voters" ); + print( "voters \n" ); auto from_voter = _voters.find(from); if( from_voter == _voters.end() ) { - print( " create voter" ); + print( " create voter \n" ); from_voter = _voters.emplace( from, [&]( auto& v ) { v.owner = from; v.staked = uint64_t(total_stake); + print( " vote weight: ", v.last_vote_weight, "\n" ); }); } else { _voters.modify( from_voter, 0, [&]( auto& v ) { v.staked += uint64_t(total_stake); + print( " vote weight: ", v.last_vote_weight, "\n" ); }); } - print( "voteproducer" ); - voteproducer( from, from_voter->proxy, from_voter->producers ); + print( "voteproducer\n" ); + if( from_voter->producers.size() || from_voter->proxy ) { + voteproducer( from, from_voter->proxy, from_voter->producers ); + } } // delegatebw void system_contract::undelegatebw( account_name from, account_name receiver, @@ -304,6 +308,7 @@ namespace eosiosystem { _voters.modify( _voters.get(from), 0, [&]( auto& v ) { v.staked -= uint64_t(total_refund); + print( " vote weight: ", v.last_vote_weight, "\n" ); }); @@ -349,7 +354,10 @@ namespace eosiosystem { out.send( from, receiver ); const auto& fromv = _voters.get( from ); - voteproducer( from, fromv.proxy, fromv.producers ); + + if( fromv.producers.size() || fromv.proxy ) { + voteproducer( from, fromv.proxy, fromv.producers ); + } } // undelegatebw diff --git a/voting.cpp b/voting.cpp index fda3c8cb..991e30c1 100644 --- a/voting.cpp +++ b/voting.cpp @@ -154,7 +154,6 @@ namespace eosiosystem { } } - print( __FILE__, ":", __LINE__, " "); auto voter = _voters.find(voter_name); eosio_assert( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object @@ -180,6 +179,7 @@ namespace eosiosystem { auto old_proxy = _voters.find( voter->proxy ); _voters.modify( old_proxy, 0, [&]( auto& vp ) { vp.proxied_vote_weight -= voter->last_vote_weight; + print( " vote weight: ", vp.last_vote_weight, "\n" ); }); } @@ -188,13 +188,16 @@ namespace eosiosystem { eosio_assert( new_proxy != _voters.end() && new_proxy->is_proxy, "invalid proxy specified" ); _voters.modify( new_proxy, 0, [&]( auto& vp ) { vp.proxied_vote_weight += new_vote_weight; + print( " vote weight: ", vp.last_vote_weight, "\n" ); }); } _voters.modify( voter, 0, [&]( auto& av ) { + print( "new_vote_weight: ", new_vote_weight, "\n" ); av.last_vote_weight = new_vote_weight; av.producers = producers; av.proxy = proxy; + print( " vote weight: ", av.last_vote_weight, "\n" ); }); print( __FILE__, ":", __LINE__, " "); @@ -229,6 +232,7 @@ namespace eosiosystem { _voters.modify( pitr, 0, [&]( auto& p ) { p.is_proxy = isproxy; + print( " vote weight: ", p.last_vote_weight, "\n" ); }); } From 608b2f2b2b1eff72140cff51a3d07429b61ebbe1 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sat, 5 May 2018 15:17:35 -0400 Subject: [PATCH 0208/1048] Add extensions field to block_header, block, and transaction - update system contract with setram that properly updates market pricing --- delegate_bandwidth.cpp | 45 ++++++++++++++++-------------------------- eosio.system.abi | 24 +++++++++++----------- eosio.system.cpp | 23 ++++++++++++++++++++- eosio.system.hpp | 15 +++++++------- voting.cpp | 4 ++-- 5 files changed, 59 insertions(+), 52 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 42d3d02a..29d0ba27 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -35,12 +35,12 @@ namespace eosiosystem { account_name owner; asset net_weight; asset cpu_weight; - int64_t storage_bytes = 0; + int64_t ram_bytes = 0; uint64_t primary_key()const { return owner; } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(storage_bytes) ) + EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(ram_bytes) ) }; @@ -107,7 +107,7 @@ namespace eosiosystem { }); set_resource_limits( newact, - 0,// r->storage_bytes, + 0,// r->ram_bytes, 0, 0 ); // r->net_weight.amount, // r->cpu_weight.amount ); @@ -131,7 +131,7 @@ namespace eosiosystem { * the receiver may reclaim the tokens via the sellram action. The receiver pays for the * storage of all database records associated with this action. * - * RAM is a scarce resource whose supply is defined by global properties max_storage_size. RAM is + * RAM is a scarce resource whose supply is defined by global properties max_ram_size. RAM is * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. */ void system_contract::buyram( account_name payer, account_name receiver, asset quant ) @@ -158,22 +158,22 @@ namespace eosiosystem { eosio_assert( bytes_out > 0, "must reserve a positive amount" ); - _gstate.total_storage_bytes_reserved += uint64_t(bytes_out); - _gstate.total_storage_stake.amount += quant.amount; + _gstate.total_ram_bytes_reserved += uint64_t(bytes_out); + _gstate.total_ram_stake.amount += quant.amount; user_resources_table userres( _self, receiver ); auto res_itr = userres.find( receiver ); if( res_itr == userres.end() ) { res_itr = userres.emplace( receiver, [&]( auto& res ) { res.owner = receiver; - res.storage_bytes = bytes_out; + res.ram_bytes = bytes_out; }); } else { userres.modify( res_itr, receiver, [&]( auto& res ) { - res.storage_bytes += bytes_out; + res.ram_bytes += bytes_out; }); } - set_resource_limits( res_itr->owner, res_itr->storage_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } @@ -188,7 +188,7 @@ namespace eosiosystem { user_resources_table userres( _self, account ); auto res_itr = userres.find( account ); eosio_assert( res_itr != userres.end(), "no resource row" ); - eosio_assert( res_itr->storage_bytes >= bytes, "insufficient quota" ); + eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; auto itr = _rammarket.find(S(4,RAMEOS)); @@ -197,16 +197,16 @@ namespace eosiosystem { print( "out: ", tokens_out, "\n" ); }); - _gstate.total_storage_bytes_reserved -= bytes; - _gstate.total_storage_stake.amount -= tokens_out.amount; + _gstate.total_ram_bytes_reserved -= bytes; + _gstate.total_ram_stake.amount -= tokens_out.amount; //// this shouldn't happen, but just in case it does we should prevent it - eosio_assert( _gstate.total_storage_stake.amount >= 0, "error, attempt to unstake more tokens than previously staked" ); + eosio_assert( _gstate.total_ram_stake.amount >= 0, "error, attempt to unstake more tokens than previously staked" ); userres.modify( res_itr, account, [&]( auto& res ) { - res.storage_bytes -= bytes; + res.ram_bytes -= bytes; }); - set_resource_limits( res_itr->owner, res_itr->storage_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); if( N(eosio) != account ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, @@ -262,7 +262,7 @@ namespace eosiosystem { }); } - set_resource_limits( tot_itr->owner, tot_itr->storage_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + set_resource_limits( tot_itr->owner, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); if( N(eosio) != from) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, @@ -327,7 +327,7 @@ namespace eosiosystem { tot.cpu_weight -= unstake_cpu_quantity; }); - set_resource_limits( receiver, totals.storage_bytes, totals.net_weight.amount, totals.cpu_weight.amount ); + set_resource_limits( receiver, totals.ram_bytes, totals.net_weight.amount, totals.cpu_weight.amount ); refunds_table refunds_tbl( _self, from ); //create refund request @@ -378,16 +378,5 @@ namespace eosiosystem { refunds_tbl.erase( req ); } - void system_contract::setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ) { - require_auth( _self ); - - eosio_assert( storage_reserve_ratio > 0, "invalid reserve ratio" ); - - eosio_assert( max_storage_size > _gstate.total_storage_bytes_reserved, "attempt to set max below reserved" ); - - _gstate.max_storage_size = max_storage_size; - _gstate.storage_reserve_ratio = storage_reserve_ratio; - _global.set( _gstate, _self ); - } } //namespace eosiosystem diff --git a/eosio.system.abi b/eosio.system.abi index 5f2f2822..f76d3178 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -55,7 +55,7 @@ {"name":"to", "type":"account_name"}, {"name":"net_weight", "type":"uint64"}, {"name":"cpu_weight", "type":"uint64"}, - {"name":"storage_bytes", "type":"uint64"} + {"name":"ram_bytes", "type":"uint64"} ] },{ "name": "user_resources", @@ -64,7 +64,7 @@ {"name":"owner", "type":"account_name"}, {"name":"net_weight", "type":"asset"}, {"name":"cpu_weight", "type":"asset"}, - {"name":"storage_bytes", "type":"uint64"} + {"name":"ram_bytes", "type":"uint64"} ] },{ "name": "total_resources", @@ -73,7 +73,7 @@ {"name":"owner", "type":"account_name"}, {"name":"net_weight", "type":"asset"}, {"name":"cpu_weight", "type":"asset"}, - {"name":"storage_bytes", "type":"uint64"} + {"name":"ram_bytes", "type":"uint64"} ] },{ "name": "refund_request", @@ -116,16 +116,15 @@ "name": "eosio_parameters", "base": "blockchain_parameters", "fields": [ - {"name":"max_storage_size", "type":"uint64"}, - {"name":"percent_of_max_inflation_rate", "type":"uint32"}, - {"name":"storage_reserve_ratio", "type":"uint32"} + {"name":"max_ram_size", "type":"uint64"}, + {"name":"percent_of_max_inflation_rate", "type":"uint32"} ] },{ "name": "eosio_global_state", "base": "eosio_parameters", "fields": [ - {"name":"total_storage_bytes_reserved", "type":"uint64"}, - {"name":"total_storage_stake", "type":"uint64"}, + {"name":"total_ram_bytes_reserved", "type":"uint64"}, + {"name":"total_ram_stake", "type":"uint64"}, {"name":"payment_per_block", "type":"uint64"} ] },{ @@ -153,11 +152,10 @@ {"name":"producer", "type":"account_name"} ] },{ - "name": "setparams", + "name": "setram", "base": "", "fields": [ - {"name":"max_ram_size", "type":"uint64"}, - {"name":"ram_reserve_ratio", "type":"uint32"} + {"name":"max_ram_size", "type":"uint64"} ] },{ "name": "regproxy", @@ -227,8 +225,8 @@ "type": "regproducer", "ricardian_contract": "" },{ - "name": "setparams", - "type": "setparams", + "name": "setram", + "type": "setram", "ricardian_contract": "" },{ "name": "unregprod", diff --git a/eosio.system.cpp b/eosio.system.cpp index 1d746418..1eb3c37a 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -49,11 +49,32 @@ namespace eosiosystem { eosio_exit(0); } + void system_contract::setram( uint64_t max_ram_size ) { + require_auth( _self ); + + eosio_assert( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" ); + eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); + + auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size); + auto itr = _rammarket.find(S(4,RAMEOS)); + + /** + * Increase or decrease the amount of ram for sale based upon the change in max + * ram size. + */ + _rammarket.modify( itr, 0, [&]( auto& m ) { + m.base.balance.amount += delta; + }); + + _gstate.max_ram_size = max_ram_size; + _global.set( _gstate, _self ); + } + } /// eosio.system EOSIO_ABI( eosiosystem::system_contract, - (setparams) + (setram) // delegate_bandwith.cpp (delegatebw)(undelegatebw)(refund) (buyram)(buyrambytes)(sellram) diff --git a/eosio.system.hpp b/eosio.system.hpp index a1855086..7f2de2fd 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -19,19 +19,18 @@ namespace eosiosystem { using eosio::const_mem_fun; struct eosio_parameters : eosio::blockchain_parameters { - uint64_t max_storage_size = 64ll*1024 * 1024 * 1024; + uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; uint32_t percent_of_max_inflation_rate = 0; - uint32_t storage_reserve_ratio = 100; // ratio * 10000 // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_storage_size)(percent_of_max_inflation_rate)(storage_reserve_ratio) ) + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_ram_size)(percent_of_max_inflation_rate) ) }; struct eosio_global_state : eosio_parameters { - uint64_t free_ram()const { return max_storage_size - total_storage_bytes_reserved; } + uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } - uint64_t total_storage_bytes_reserved = 0; - eosio::asset total_storage_stake; + uint64_t total_ram_bytes_reserved = 0; + eosio::asset total_ram_stake; eosio::asset payment_per_block; eosio::asset payment_to_eos_bucket; @@ -42,7 +41,7 @@ namespace eosiosystem { eosio::asset eos_bucket; // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_storage_bytes_reserved)(total_storage_stake) + EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) (last_bucket_fill_time)(eos_bucket) ) }; @@ -178,7 +177,7 @@ namespace eosiosystem { void unregprod( const account_name producer ); - void setparams( uint64_t max_storage_size, uint32_t storage_reserve_ratio ); + void setram( uint64_t max_ram_size ); void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); diff --git a/voting.cpp b/voting.cpp index 991e30c1..06ea8f26 100644 --- a/voting.cpp +++ b/voting.cpp @@ -112,8 +112,8 @@ namespace eosiosystem { _gstate.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); _gstate.blocks_per_cycle = blocks_per_producer * schedule.producers.size(); - if (_gstate.max_storage_size <_gstate.total_storage_bytes_reserved ) { - _gstate.max_storage_size =_gstate.total_storage_bytes_reserved; + if (_gstate.max_ram_size <_gstate.total_ram_bytes_reserved ) { + _gstate.max_ram_size =_gstate.total_ram_bytes_reserved; } auto issue_quantity =_gstate.blocks_per_cycle * (_gstate.payment_per_block +_gstate.payment_to_eos_bucket); From 2c39e98d3719e86785727dadeb9371f8ee3ce7c6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sat, 5 May 2018 19:32:40 -0400 Subject: [PATCH 0209/1048] Fix EOS_PERCENT int mult overflow - target CPU usage is now 10% rather than 0 - eosio.system now uses "ram" rather than "storage" - increased max virtual cpu usage to 10000x from 1000x so that 1 staked EOS is able to transact - updated bootseq contract with more realistic use case including - staking almost all 1B users - setting system contract and msig contract - allocating resources to staked accounts --- voting.cpp | 6 ------ 1 file changed, 6 deletions(-) diff --git a/voting.cpp b/voting.cpp index 06ea8f26..d9982934 100644 --- a/voting.cpp +++ b/voting.cpp @@ -112,15 +112,10 @@ namespace eosiosystem { _gstate.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); _gstate.blocks_per_cycle = blocks_per_producer * schedule.producers.size(); - if (_gstate.max_ram_size <_gstate.total_ram_bytes_reserved ) { - _gstate.max_ram_size =_gstate.total_ram_bytes_reserved; - } - auto issue_quantity =_gstate.blocks_per_cycle * (_gstate.payment_per_block +_gstate.payment_to_eos_bucket); INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), issue_quantity, std::string("producer pay")} ); - set_blockchain_parameters( _gstate ); } /** @@ -200,7 +195,6 @@ namespace eosiosystem { print( " vote weight: ", av.last_vote_weight, "\n" ); }); - print( __FILE__, ":", __LINE__, " "); for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { From ee61543f896e2ad41dbbe39f875dc4c11cf35f7d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 4 May 2018 19:17:36 -0400 Subject: [PATCH 0210/1048] Refactored stanby producer payment --- common.hpp | 34 --------------- eosio.system.hpp | 6 ++- producer_pay.cpp | 105 +++++++++++++++++++++++++++++------------------ voting.cpp | 10 ----- 4 files changed, 70 insertions(+), 85 deletions(-) delete mode 100644 common.hpp diff --git a/common.hpp b/common.hpp deleted file mode 100644 index 42be96e8..00000000 --- a/common.hpp +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ -#pragma once - -#include -#include -#include -#include -#include - -#include - -namespace eosiosystem { - - template - class common { - public: - static constexpr account_name system_account = SystemAccount; - - - static constexpr uint32_t blocks_per_producer = 12; - static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr uint32_t days_per_4years = 1461; - - static eosio_global_state& get_default_parameters() { - static eosio_global_state dp; - get_blockchain_parameters(dp); - return dp; - } - }; - -} diff --git a/eosio.system.hpp b/eosio.system.hpp index 7f2de2fd..c5a26d2a 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -105,7 +105,7 @@ namespace eosiosystem { typedef eosio::singleton global_state_singleton; - static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation + // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint64_t system_token_symbol = S(4,EOS); @@ -187,7 +187,9 @@ namespace eosiosystem { void claimrewards( const account_name& owner ); private: - eosio::asset payment_per_block(uint32_t percent_of_max_inflation_rate); + eosio::asset payment_per_block( double rate ); + + eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ); void update_elected_producers(time cycle_time); diff --git a/producer_pay.cpp b/producer_pay.cpp index a8b1c9f2..69d9634d 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -4,8 +4,16 @@ namespace eosiosystem { -static const uint32_t num_of_payed_producers = 121; - +const int64_t min_daily_tokens = 100; +const double continuous_rate = std::log1p(5); +const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year +const uint32_t blocks_per_hour = 2 * 3600; + +eosio::asset system_contract::payment_per_block( double rate ) { + const eosio::asset token_supply = eosio::token( N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name() ); + const int64_t payment = static_cast( (rate * double(token_supply.amount)) / double(blocks_per_year) ); + return eosio::asset(payment, system_token_symbol); +} void system_contract::onblock( block_timestamp timestamp, account_name producer ) { @@ -27,7 +35,6 @@ void system_contract::onblock( block_timestamp timestamp, account_name producer producers_table producers_tbl( _self, _self ); - // const system_token_type block_payment = parameters.payment_per_block; const asset block_payment = parameters.payment_per_block; auto prod = producers_tbl.find(producer); if ( prod != producers_tbl.end() ) { @@ -38,68 +45,88 @@ void system_contract::onblock( block_timestamp timestamp, account_name producer } const uint32_t num_of_payments = timestamp - parameters.last_bucket_fill_time; - // const system_token_type to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; parameters.last_bucket_fill_time = timestamp; parameters.eos_bucket += to_eos_bucket; gs.set( parameters, _self ); } -void system_contract::claimrewards(const account_name& owner) { +eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) { + eosio::asset payment(0, S(4,EOS)); + if (eos_bucket < threshold) { + return payment; + } + + auto idx = _producers.template get_index(); + + double total_producer_votes = 0; + double running_payment_amount = 0; + bool to_be_payed = false; + for ( auto itr = idx.begin(); itr != idx.end(); ++itr ) { + if ( !(itr->total_votes > 0) ) { + break; + } + if ( !(itr->active()) && !(itr->owner != owner) ) { + continue; + } + + if ( itr->owner == owner ) { + to_be_payed = true; + } + + total_producer_votes += itr->total_votes; + running_payment_amount = (itr->total_votes) * double(eos_bucket.amount) / total_producer_votes; + if ( running_payment_amount < min_daily_tokens ) { + if ( itr->owner == owner ) { + to_be_payed = false; + } + total_producer_votes -= itr->total_votes; + break; + } + } + + if ( to_be_payed ) { + payment.amount = static_cast( (double(eos_bucket.amount) * owners_votes) / total_producer_votes ); + } + + return payment; +} + +void system_contract::claimrewards( const account_name& owner ) { require_auth(owner); producers_table producers_tbl( _self, _self ); - auto prod = producers_tbl.find(owner); + auto prod = producers_tbl.find( owner ); eosio_assert(prod != producers_tbl.end(), "account name is not in producer list"); if( prod->last_rewards_claim > 0 ) { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } - // system_token_type rewards = prod->per_block_payments; eosio::asset rewards = prod->per_block_payments; - auto idx = producers_tbl.template get_index(); - auto itr = --idx.end(); - - bool is_among_payed_producers = false; - uint128_t total_producer_votes = 0; - uint32_t n = 0; - while( n < num_of_payed_producers ) { - if( !is_among_payed_producers ) { - if( itr->owner == owner ) - is_among_payed_producers = true; - } - if( itr->active() ) { - total_producer_votes += itr->total_votes; - ++n; - } - if( itr == idx.begin() ) { - break; - } - --itr; - } - if (is_among_payed_producers && total_producer_votes > 0) { - global_state_singleton gs( _self, _self ); - if( gs.exists() ) { - auto parameters = gs.get(); - // auto share_of_eos_bucket = system_token_type( static_cast( (prod->total_votes * parameters.eos_bucket.quantity) / total_producer_votes ) ); // This will be improved in the future when total_votes becomes a double type. - auto share_of_eos_bucket = eosio::asset( static_cast( (prod->total_votes * parameters.eos_bucket.amount) / total_producer_votes ) ); - rewards += share_of_eos_bucket; - parameters.eos_bucket -= share_of_eos_bucket; - gs.set( parameters, _self ); + global_state_singleton gs( _self, _self ); + if ( gs.exists() ) { + auto parameters = gs.get(); + if ( parameters.eos_bucket.amount > 0 && prod->total_votes > 0 ) { + eosio::asset standby_payment = payment_per_vote( owner, prod->total_votes, parameters.eos_bucket ); + if ( standby_payment.amount > 0 ) { + rewards += standby_payment; + parameters.eos_bucket -= standby_payment; + gs.set( parameters, _self ); + } } } - // eosio_assert( rewards > system_token_type(), "no rewards available to claim" ); eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); - + producers_tbl.modify( prod, 0, [&](auto& p) { p.last_rewards_claim = now(); p.per_block_payments.amount = 0; }); - + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, { N(eosio), owner, rewards, std::string("producer claiming rewards") } ); + } } //namespace eosiosystem diff --git a/voting.cpp b/voting.cpp index d9982934..e55a7ec4 100644 --- a/voting.cpp +++ b/voting.cpp @@ -27,7 +27,6 @@ namespace eosiosystem { using eosio::transaction; - static constexpr uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year static constexpr uint32_t blocks_per_producer = 12; @@ -71,15 +70,6 @@ namespace eosiosystem { }); } - - eosio::asset system_contract::payment_per_block(uint32_t percent_of_max_inflation_rate) { - const eosio::asset token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()); - const double annual_rate = double(max_inflation_rate * percent_of_max_inflation_rate) / double(10000); - const double continuous_rate = std::log1p(annual_rate); - int64_t payment = static_cast((continuous_rate * double(token_supply.amount)) / double(blocks_per_year)); - return eosio::asset(payment, system_token_symbol); - } - void system_contract::update_elected_producers(time cycle_time) { auto idx = _producers.get_index(); From 308680bacb8710076305bac1320adb43d9518a4e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sat, 5 May 2018 22:06:02 -0400 Subject: [PATCH 0211/1048] Updated system contract onblock action --- eosio.system.hpp | 19 ++-- producer_pay.cpp | 219 +++++++++++++++++++++++------------------------ voting.cpp | 22 +---- 3 files changed, 119 insertions(+), 141 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index c5a26d2a..8d9fe96a 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -31,19 +31,14 @@ namespace eosiosystem { uint64_t total_ram_bytes_reserved = 0; eosio::asset total_ram_stake; - eosio::asset payment_per_block; - eosio::asset payment_to_eos_bucket; - - time first_block_time_in_cycle = 0; - uint32_t blocks_per_cycle = 0; - time last_bucket_fill_time = 0; + block_timestamp last_producer_schedule_update = 0; eosio::asset eos_bucket; + eosio::asset savings; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) - (payment_per_block)(payment_to_eos_bucket)(first_block_time_in_cycle)(blocks_per_cycle) - (last_bucket_fill_time)(eos_bucket) ) + (last_producer_schedule_update)(eos_bucket)(savings) ) }; struct producer_info { @@ -52,8 +47,8 @@ namespace eosiosystem { eosio::public_key producer_key; /// a packed public key object eosio::asset per_block_payments; time last_rewards_claim = 0; - time time_became_active = 0; - time last_produced_block_time = 0; + block_timestamp time_became_active = 0; + block_timestamp last_produced_block_time = 0; uint64_t primary_key()const { return owner; } double by_votes()const { return -total_votes; } @@ -187,11 +182,11 @@ namespace eosiosystem { void claimrewards( const account_name& owner ); private: - eosio::asset payment_per_block( double rate ); + eosio::asset payment_per_block( double rate, const eosio::asset& token_supply ); eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ); - void update_elected_producers(time cycle_time); + void update_elected_producers( block_timestamp timestamp ); // Implementation details: diff --git a/producer_pay.cpp b/producer_pay.cpp index 69d9634d..10c97f71 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -4,129 +4,128 @@ namespace eosiosystem { -const int64_t min_daily_tokens = 100; -const double continuous_rate = std::log1p(5); -const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year -const uint32_t blocks_per_hour = 2 * 3600; - -eosio::asset system_contract::payment_per_block( double rate ) { - const eosio::asset token_supply = eosio::token( N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name() ); - const int64_t payment = static_cast( (rate * double(token_supply.amount)) / double(blocks_per_year) ); - return eosio::asset(payment, system_token_symbol); -} - -void system_contract::onblock( block_timestamp timestamp, account_name producer ) { - - global_state_singleton gs( _self, _self ); - auto parameters = gs.exists() ? gs.get() : get_default_parameters(); - if( parameters.first_block_time_in_cycle == 0 ) { - // This is the first time onblock is called in the blockchain. - parameters.last_bucket_fill_time = timestamp; - gs.set( parameters, _self ); - update_elected_producers( timestamp ); - } - - static const uint32_t slots_per_cycle = parameters.blocks_per_cycle; - const uint32_t time_slots = timestamp - parameters.first_block_time_in_cycle; - if (time_slots >= slots_per_cycle) { - auto beginning_of_cycle = timestamp - (time_slots % slots_per_cycle); - update_elected_producers(beginning_of_cycle); - } - - producers_table producers_tbl( _self, _self ); - - const asset block_payment = parameters.payment_per_block; - auto prod = producers_tbl.find(producer); - if ( prod != producers_tbl.end() ) { - producers_tbl.modify( prod, 0, [&](auto& p) { - p.per_block_payments += block_payment; - p.last_produced_block_time = timestamp; - }); - } - - const uint32_t num_of_payments = timestamp - parameters.last_bucket_fill_time; - const asset to_eos_bucket = num_of_payments * parameters.payment_to_eos_bucket; - parameters.last_bucket_fill_time = timestamp; - parameters.eos_bucket += to_eos_bucket; - gs.set( parameters, _self ); -} - -eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) { - eosio::asset payment(0, S(4,EOS)); - if (eos_bucket < threshold) { - return payment; + const int64_t min_daily_tokens = 100; + const double continuous_rate = std::log1p(0.05); // 5% annual rate + const double per_block_rate = 0.0025; // 0.25% + const double standby_rate = 0.0075; // 0.75% + const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year + const uint32_t blocks_per_hour = 2 * 3600; + + eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply ) { + const int64_t payment = static_cast( (rate * double(token_supply.amount)) / double(blocks_per_year) ); + return eosio::asset( payment, token_supply.symbol ); } - auto idx = _producers.template get_index(); - - double total_producer_votes = 0; - double running_payment_amount = 0; - bool to_be_payed = false; - for ( auto itr = idx.begin(); itr != idx.end(); ++itr ) { - if ( !(itr->total_votes > 0) ) { - break; - } - if ( !(itr->active()) && !(itr->owner != owner) ) { - continue; + void system_contract::onblock( block_timestamp timestamp, account_name producer ) { + + using namespace eosio; + + const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); + const asset issued = payment_per_block( continuous_rate, token_supply ); + const asset producer_payment = payment_per_block( per_block_rate, token_supply ); + const asset to_eos_bucket = payment_per_block( standby_rate, token_supply ); + const asset to_savings = issued - (producer_payment + to_eos_bucket); + + INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, + {N(eosio), issued, std::string("issue tokens per block")} ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio),N(active)}}, + {N(eosio), N(eosio), to_savings, std::string("transfer to savings per block")} ); + // update producer info and balance + auto prod = _producers.find(producer); + if ( prod != _producers.end() ) { + _producers.modify( prod, 0, [&](auto& p) { + p.per_block_payments += producer_payment; + p.last_produced_block_time = timestamp; + }); } - if ( itr->owner == owner ) { - to_be_payed = true; + auto parameters = _global.exists() ? _global.get() : get_default_parameters(); + parameters.eos_bucket += to_eos_bucket; + parameters.savings += to_savings; + _global.set ( parameters, _self ); + + const auto& producer_schedule_update = parameters.last_producer_schedule_update; + if ( producer_schedule_update == 0 || producer_schedule_update < timestamp + blocks_per_hour ) { + update_elected_producers( producer_schedule_update ); } - total_producer_votes += itr->total_votes; - running_payment_amount = (itr->total_votes) * double(eos_bucket.amount) / total_producer_votes; - if ( running_payment_amount < min_daily_tokens ) { + } + + eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) { + eosio::asset payment(0, S(4,EOS)); + if ( eos_bucket.amount < min_daily_tokens ) { + return payment; + } + + auto idx = _producers.template get_index(); + + double total_producer_votes = 0; + double running_payment_amount = 0; + bool to_be_payed = false; + for ( auto itr = idx.cbegin(); itr != idx.cend(); ++itr ) { + if ( !(itr->total_votes > 0) ) { + break; + } + if ( !(itr->active()) && !(itr->owner != owner) ) { + continue; + } + if ( itr->owner == owner ) { - to_be_payed = false; + to_be_payed = true; + } + + total_producer_votes += itr->total_votes; + running_payment_amount = (itr->total_votes) * double(eos_bucket.amount) / total_producer_votes; + if ( running_payment_amount < min_daily_tokens ) { + if ( itr->owner == owner ) { + to_be_payed = false; + } + total_producer_votes -= itr->total_votes; + break; } - total_producer_votes -= itr->total_votes; - break; } + + if ( to_be_payed ) { + payment.amount = static_cast( (double(eos_bucket.amount) * owners_votes) / total_producer_votes ); + } + + return payment; } - if ( to_be_payed ) { - payment.amount = static_cast( (double(eos_bucket.amount) * owners_votes) / total_producer_votes ); - } - - return payment; -} - -void system_contract::claimrewards( const account_name& owner ) { - require_auth(owner); - - producers_table producers_tbl( _self, _self ); - auto prod = producers_tbl.find( owner ); - eosio_assert(prod != producers_tbl.end(), "account name is not in producer list"); - if( prod->last_rewards_claim > 0 ) { - eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); - } - - eosio::asset rewards = prod->per_block_payments; - - global_state_singleton gs( _self, _self ); - if ( gs.exists() ) { - auto parameters = gs.get(); - if ( parameters.eos_bucket.amount > 0 && prod->total_votes > 0 ) { - eosio::asset standby_payment = payment_per_vote( owner, prod->total_votes, parameters.eos_bucket ); - if ( standby_payment.amount > 0 ) { - rewards += standby_payment; - parameters.eos_bucket -= standby_payment; - gs.set( parameters, _self ); + void system_contract::claimrewards( const account_name& owner ) { + require_auth(owner); + + auto prod = _producers.find( owner ); + eosio_assert( prod != _producers.end(), "account name is not in producer list" ); + if( prod->last_rewards_claim > 0 ) { + eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); + } + + eosio::asset rewards = prod->per_block_payments; + + if ( _global.exists() ) { + auto parameters = _global.get(); + if ( parameters.eos_bucket.amount > 0 && prod->total_votes > 0 ) { + eosio::asset standby_payment = payment_per_vote( owner, prod->total_votes, parameters.eos_bucket ); + if ( standby_payment.amount > 0 ) { + rewards += standby_payment; + parameters.eos_bucket -= standby_payment; + _global.set( parameters, _self ); + } } } + + eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); + + _producers.modify( prod, 0, [&](auto& p) { + p.last_rewards_claim = now(); + p.per_block_payments.amount = 0; + }); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), owner, rewards, std::string("producer claiming rewards") } ); + } - eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); - - producers_tbl.modify( prod, 0, [&](auto& p) { - p.last_rewards_claim = now(); - p.per_block_payments.amount = 0; - }); - - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), owner, rewards, std::string("producer claiming rewards") } ); - -} - } //namespace eosiosystem diff --git a/voting.cpp b/voting.cpp index e55a7ec4..c5ea8b69 100644 --- a/voting.cpp +++ b/voting.cpp @@ -26,10 +26,6 @@ namespace eosiosystem { using eosio::singleton; using eosio::transaction; - - static constexpr uint32_t blocks_per_producer = 12; - - /** * This method will create a producer_config and producer_info object for 'producer' * @@ -70,7 +66,7 @@ namespace eosiosystem { }); } - void system_contract::update_elected_producers(time cycle_time) { + void system_contract::update_elected_producers(block_timestamp block_time) { auto idx = _producers.get_index(); eosio::producer_schedule schedule; @@ -93,19 +89,7 @@ namespace eosiosystem { set_active_producers( packed_schedule.data(), packed_schedule.size() ); // not voted on - _gstate.first_block_time_in_cycle = cycle_time; - - // derived parameters - auto half_of_percentage = _gstate.percent_of_max_inflation_rate / 2; - auto other_half_of_percentage = _gstate.percent_of_max_inflation_rate - half_of_percentage; - _gstate.payment_per_block = payment_per_block(half_of_percentage); - _gstate.payment_to_eos_bucket = payment_per_block(other_half_of_percentage); - _gstate.blocks_per_cycle = blocks_per_producer * schedule.producers.size(); - - auto issue_quantity =_gstate.blocks_per_cycle * (_gstate.payment_per_block +_gstate.payment_to_eos_bucket); - INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - {N(eosio), issue_quantity, std::string("producer pay")} ); - + _gstate.last_producer_schedule_update = block_time; } /** @@ -220,4 +204,4 @@ namespace eosiosystem { }); } -} +} /// namespace eosiosystem From f192406699f26b3b517e5e29890318d8f6fa7cac Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 6 May 2018 09:57:46 -0400 Subject: [PATCH 0212/1048] Inactive producers --- eosio.system.hpp | 3 +-- producer_pay.cpp | 3 ++- voting.cpp | 23 +++++++++++++++++++++-- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 8d9fe96a..bde9ea7f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -20,10 +20,9 @@ namespace eosiosystem { struct eosio_parameters : eosio::blockchain_parameters { uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; - uint32_t percent_of_max_inflation_rate = 0; // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_ram_size)(percent_of_max_inflation_rate) ) + EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_ram_size) ) }; struct eosio_global_state : eosio_parameters { diff --git a/producer_pay.cpp b/producer_pay.cpp index 10c97f71..b60b9766 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -9,8 +9,9 @@ namespace eosiosystem { const double per_block_rate = 0.0025; // 0.25% const double standby_rate = 0.0075; // 0.75% const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year + const uint32_t blocks_per_day = 2 * 24 * 3600; const uint32_t blocks_per_hour = 2 * 3600; - + eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply ) { const int64_t payment = static_cast( (rate * double(token_supply.amount)) / double(blocks_per_year) ); return eosio::asset( payment, token_supply.symbol ); diff --git a/voting.cpp b/voting.cpp index c5ea8b69..e24baeb5 100644 --- a/voting.cpp +++ b/voting.cpp @@ -15,7 +15,6 @@ #include #include -#include #include namespace eosiosystem { @@ -66,13 +65,33 @@ namespace eosiosystem { }); } - void system_contract::update_elected_producers(block_timestamp block_time) { + void system_contract::update_elected_producers( block_timestamp block_time ) { auto idx = _producers.get_index(); eosio::producer_schedule schedule; schedule.producers.reserve(21); size_t n = 0; for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { + if ( it->active() && + it->time_became_active == 0 ) { + + _producers.modify( *it, 0, [&](auto& p) { + p.time_became_active = block_time; + }); + + } else if ( it->active() && + block_time > 21 * 12 + it->time_became_active && + block_time > it->last_produced_block_time + blocks_per_day ) { + + _producers.modify( *it, 0, [&](auto& p) { + p.producer_key = public_key(); + p.time_became_active = 0; + p.last_produced_block_time = 0; + }); + + continue; + } + if ( it->active() ) { schedule.producers.emplace_back(); schedule.producers.back().producer_name = it->owner; From 17a0da654ab8e88a7a1a38dd07c35c372f6a425d Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 6 May 2018 12:19:43 -0400 Subject: [PATCH 0213/1048] start work on b1 vesting and network activation --- delegate_bandwidth.cpp | 15 ++++++++++++++- eosio.system.hpp | 3 ++- voting.cpp | 14 ++++++++++++-- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 29d0ba27..177fcb11 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -291,6 +291,17 @@ namespace eosiosystem { } } // delegatebw + + void validate_b1_vesting( uint64_t stake ) { + const int64_t seconds_per_year = 60*60*24*365; + const int64_t base_time = 1527811200; /// 2018-06-01 + const int64_t end_time = seconds_per_year*10 + 1527811200; /// 2018-06-01 + const int64_t max_claimable = 100'000'000'0000ll; + const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / seconds_per_year); + + eosio_assert( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); + } + void system_contract::undelegatebw( account_name from, account_name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ) { @@ -308,7 +319,9 @@ namespace eosiosystem { _voters.modify( _voters.get(from), 0, [&]( auto& v ) { v.staked -= uint64_t(total_refund); - print( " vote weight: ", v.last_vote_weight, "\n" ); + if( from == N(b1) ) { + validate_b1_vesting( v.staked ); + } }); diff --git a/eosio.system.hpp b/eosio.system.hpp index bde9ea7f..3cd444e7 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -34,10 +34,11 @@ namespace eosiosystem { block_timestamp last_producer_schedule_update = 0; eosio::asset eos_bucket; eosio::asset savings; + int64_t total_activiated_stake = 0; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) - (last_producer_schedule_update)(eos_bucket)(savings) ) + (last_producer_schedule_update)(eos_bucket)(savings)(total_activiated_stake) ) }; struct producer_info { diff --git a/voting.cpp b/voting.cpp index e24baeb5..a9d9cda6 100644 --- a/voting.cpp +++ b/voting.cpp @@ -71,7 +71,7 @@ namespace eosiosystem { eosio::producer_schedule schedule; schedule.producers.reserve(21); size_t n = 0; - for ( auto it = idx.crbegin(); it != idx.crend() && n < 21 && 0 < it->total_votes; ++it ) { + for ( auto it = idx.cbegin(); it != idx.cend() && n < 21 && 0 < it->total_votes; ++it ) { if ( it->active() && it->time_became_active == 0 ) { @@ -104,13 +104,14 @@ namespace eosiosystem { } // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp - bytes packed_schedule = pack(schedule); + bytes packed_schedule = pack(schedule.producers); set_active_producers( packed_schedule.data(), packed_schedule.size() ); // not voted on _gstate.last_producer_schedule_update = block_time; } + /** * @pre producers must be sorted from lowest to highest and must be registered and active * @pre if proxy is set then no producers can be voted for @@ -145,6 +146,15 @@ namespace eosiosystem { auto voter = _voters.find(voter_name); eosio_assert( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object + /** + * The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until + * after total_activiated_stake hits threshold, we can use last_vote_weight to determine that this is + * their first vote and should consider their stake activated. + */ + if( voter->last_vote_weight <= 0.0 ) { + _gstate.total_activiated_stake += voter->staked; + } + auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); double new_vote_weight = double(voter->staked) * std::pow(2,weight); From 15b73f930c9e381a00b14fd0854d4c9284853047 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 6 May 2018 15:48:42 -0400 Subject: [PATCH 0214/1048] cleanup system contract --- delegate_bandwidth.cpp | 11 ++++----- eosio.system.hpp | 14 ++++++++--- exchange_state.cpp | 6 +++++ producer_pay.cpp | 43 ++++++++++++++++++++++++--------- voting.cpp | 55 +++++++++++++++++------------------------- 5 files changed, 75 insertions(+), 54 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 177fcb11..0014108e 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -275,12 +275,12 @@ namespace eosiosystem { print( " create voter \n" ); from_voter = _voters.emplace( from, [&]( auto& v ) { v.owner = from; - v.staked = uint64_t(total_stake); + v.staked = total_stake; print( " vote weight: ", v.last_vote_weight, "\n" ); }); } else { _voters.modify( from_voter, 0, [&]( auto& v ) { - v.staked += uint64_t(total_stake); + v.staked += total_stake; print( " vote weight: ", v.last_vote_weight, "\n" ); }); } @@ -292,12 +292,11 @@ namespace eosiosystem { } // delegatebw - void validate_b1_vesting( uint64_t stake ) { + void validate_b1_vesting( int64_t stake ) { const int64_t seconds_per_year = 60*60*24*365; const int64_t base_time = 1527811200; /// 2018-06-01 - const int64_t end_time = seconds_per_year*10 + 1527811200; /// 2018-06-01 const int64_t max_claimable = 100'000'000'0000ll; - const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / seconds_per_year); + const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / (10*seconds_per_year) ); eosio_assert( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } @@ -318,7 +317,7 @@ namespace eosiosystem { auto total_refund = unstake_cpu_quantity.amount + unstake_net_quantity.amount; _voters.modify( _voters.get(from), 0, [&]( auto& v ) { - v.staked -= uint64_t(total_refund); + v.staked -= total_refund; if( from == N(b1) ) { validate_b1_vesting( v.staked ); } diff --git a/eosio.system.hpp b/eosio.system.hpp index 3cd444e7..3b8eb743 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -32,21 +32,27 @@ namespace eosiosystem { eosio::asset total_ram_stake; block_timestamp last_producer_schedule_update = 0; + block_timestamp last_pervote_bucket_fill = 0; eosio::asset eos_bucket; eosio::asset savings; + checksum160 last_producer_schedule_id; + int64_t total_activiated_stake = 0; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) - (last_producer_schedule_update)(eos_bucket)(savings)(total_activiated_stake) ) + (last_producer_schedule_update) + (last_pervote_bucket_fill) + (eos_bucket)(savings)(last_producer_schedule_id)(total_activiated_stake) ) }; struct producer_info { account_name owner; double total_votes = 0; eosio::public_key producer_key; /// a packed public key object - eosio::asset per_block_payments; + uint32_t produced_blocks; time last_rewards_claim = 0; + uint16_t location = 0; block_timestamp time_became_active = 0; block_timestamp last_produced_block_time = 0; @@ -56,7 +62,7 @@ namespace eosiosystem { // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key) - (per_block_payments)(last_rewards_claim) + (produced_blocks)(last_rewards_claim) (time_became_active)(last_produced_block_time) ) }; @@ -64,7 +70,7 @@ namespace eosiosystem { account_name owner = 0; /// the voter account_name proxy = 0; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set - uint64_t staked = 0; + int64_t staked = 0; /** * Every time a vote is cast we must first "undo" the last vote weight, before casting the diff --git a/exchange_state.cpp b/exchange_state.cpp index 90a945ff..b621bdef 100644 --- a/exchange_state.cpp +++ b/exchange_state.cpp @@ -29,6 +29,12 @@ namespace eosiosystem { real_type ONE(1.0); + // potentially more accurate: + // The functions std::expm1 and std::log1p are useful for financial calculations, for example, + // when calculating small daily interest rates: (1+x)n + // -1 can be expressed as std::expm1(n * std::log1p(x)). + // real_type T = C * std::expm1( F * std::log1p(E/R) ); + real_type T = C * (std::pow( ONE + E/R, F) - ONE); //print( "T: ", T, "\n"); int64_t out = int64_t(T); diff --git a/producer_pay.cpp b/producer_pay.cpp index b60b9766..6c478c48 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -5,6 +5,7 @@ namespace eosiosystem { const int64_t min_daily_tokens = 100; + /* const double continuous_rate = std::log1p(0.05); // 5% annual rate const double per_block_rate = 0.0025; // 0.25% const double standby_rate = 0.0075; // 0.75% @@ -16,11 +17,32 @@ namespace eosiosystem { const int64_t payment = static_cast( (rate * double(token_supply.amount)) / double(blocks_per_year) ); return eosio::asset( payment, token_supply.symbol ); } + */ void system_contract::onblock( block_timestamp timestamp, account_name producer ) { - using namespace eosio; + /** until activated stake crosses this threshold no new rewards are paid */ + if( _gstate.total_activiated_stake < 150'000'000'0000 ) + return; + + if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses + _gstate.last_pervote_bucket_fill = timestamp; + + _producers.modify( _producers.get(producer), 0, [&](auto& p ) { + p.produced_blocks++; + p.last_produced_block_time = timestamp; + }); + + if( timestamp - _gstate.last_producer_schedule_update > 120 ) { + update_elected_producers( timestamp ); + } + + /// only update block producers once every minute, block_timestamp is in half seconds + /* + if( timestamp % 120 != 0 ) + return; + const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); const asset issued = payment_per_block( continuous_rate, token_supply ); const asset producer_payment = payment_per_block( per_block_rate, token_supply ); @@ -29,17 +51,12 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), issued, std::string("issue tokens per block")} ); + */ + /* INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), N(eosio), to_savings, std::string("transfer to savings per block")} ); - // update producer info and balance - auto prod = _producers.find(producer); - if ( prod != _producers.end() ) { - _producers.modify( prod, 0, [&](auto& p) { - p.per_block_payments += producer_payment; - p.last_produced_block_time = timestamp; - }); - } + auto parameters = _global.exists() ? _global.get() : get_default_parameters(); parameters.eos_bucket += to_eos_bucket; @@ -50,7 +67,7 @@ namespace eosiosystem { if ( producer_schedule_update == 0 || producer_schedule_update < timestamp + blocks_per_hour ) { update_elected_producers( producer_schedule_update ); } - + */ } eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) { @@ -102,7 +119,10 @@ namespace eosiosystem { if( prod->last_rewards_claim > 0 ) { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } + + /// calcualte the price-per-block + /* eosio::asset rewards = prod->per_block_payments; if ( _global.exists() ) { @@ -121,12 +141,13 @@ namespace eosiosystem { _producers.modify( prod, 0, [&](auto& p) { p.last_rewards_claim = now(); - p.per_block_payments.amount = 0; + p.produced_blocks = 0; }); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, { N(eosio), owner, rewards, std::string("producer claiming rewards") } ); + */ } } //namespace eosiosystem diff --git a/voting.cpp b/voting.cpp index a9d9cda6..d5435fd0 100644 --- a/voting.cpp +++ b/voting.cpp @@ -5,6 +5,7 @@ #include "eosio.system.hpp" #include +#include #include #include #include @@ -66,48 +67,36 @@ namespace eosiosystem { } void system_contract::update_elected_producers( block_timestamp block_time ) { + _gstate.last_producer_schedule_update = block_time; + auto idx = _producers.get_index(); - eosio::producer_schedule schedule; - schedule.producers.reserve(21); - size_t n = 0; - for ( auto it = idx.cbegin(); it != idx.cend() && n < 21 && 0 < it->total_votes; ++it ) { - if ( it->active() && - it->time_became_active == 0 ) { + std::vector< std::pair > top_producers; + top_producers.reserve(21); - _producers.modify( *it, 0, [&](auto& p) { - p.time_became_active = block_time; - }); + for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) { + if( !it->active() ) continue; + top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location})); + } - } else if ( it->active() && - block_time > 21 * 12 + it->time_became_active && - block_time > it->last_produced_block_time + blocks_per_day ) { - _producers.modify( *it, 0, [&](auto& p) { - p.producer_key = public_key(); - p.time_became_active = 0; - p.last_produced_block_time = 0; - }); + /// sort by producer name + std::sort( top_producers.begin(), top_producers.end() ); - continue; - } + std::vector producers; - if ( it->active() ) { - schedule.producers.emplace_back(); - schedule.producers.back().producer_name = it->owner; - schedule.producers.back().block_signing_key = it->producer_key; - ++n; - } - } - if ( n == 0 ) { //no active producers with votes > 0 - return; - } + producers.reserve(top_producers.size()); + for( const auto& item : top_producers ) + producers.push_back(item.first); - // should use producer_schedule_type from libraries/chain/include/eosio/chain/producer_schedule.hpp - bytes packed_schedule = pack(schedule.producers); - set_active_producers( packed_schedule.data(), packed_schedule.size() ); + bytes packed_schedule = pack(producers); + checksum160 new_id; + sha1( packed_schedule.data(), packed_schedule.size(), &new_id ); - // not voted on + if( new_id != _gstate.last_producer_schedule_id ) { + _gstate.last_producer_schedule_id = new_id; + set_active_producers( packed_schedule.data(), packed_schedule.size() ); + } _gstate.last_producer_schedule_update = block_time; } From e719466106a8f1f5c3cfcc51c0a2499c716d223b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 6 May 2018 17:39:17 -0400 Subject: [PATCH 0215/1048] Move issue and payment calculations from onblock to claimrewards --- eosio.system.hpp | 6 ++- producer_pay.cpp | 96 +++++++++++++++++++----------------------------- 2 files changed, 41 insertions(+), 61 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 3b8eb743..19b5e5fc 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -32,7 +32,7 @@ namespace eosiosystem { eosio::asset total_ram_stake; block_timestamp last_producer_schedule_update = 0; - block_timestamp last_pervote_bucket_fill = 0; + time last_pervote_bucket_fill = 0; eosio::asset eos_bucket; eosio::asset savings; checksum160 last_producer_schedule_id; @@ -188,9 +188,11 @@ namespace eosiosystem { void claimrewards( const account_name& owner ); private: - eosio::asset payment_per_block( double rate, const eosio::asset& token_supply ); + eosio::asset payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ); eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ); + + eosio::asset supply_growth( double rate, const eosio::asset& token_supply, time seconds ); void update_elected_producers( block_timestamp timestamp ); diff --git a/producer_pay.cpp b/producer_pay.cpp index 6c478c48..862087a1 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -5,20 +5,25 @@ namespace eosiosystem { const int64_t min_daily_tokens = 100; - /* - const double continuous_rate = std::log1p(0.05); // 5% annual rate - const double per_block_rate = 0.0025; // 0.25% + + const double continuous_rate = 0.04879; // 5% annual rate + const double perblock_rate = 0.0025; // 0.25% const double standby_rate = 0.0075; // 0.75% const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year + const uint32_t seconds_per_year = 52*7*24*3600; const uint32_t blocks_per_day = 2 * 24 * 3600; const uint32_t blocks_per_hour = 2 * 3600; + + eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ) { + const int64_t payment = static_cast( (rate * double(token_supply.amount) * double(num_blocks)) / double(blocks_per_year) ); + return eosio::asset( payment, token_supply.symbol ); + } - eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply ) { - const int64_t payment = static_cast( (rate * double(token_supply.amount)) / double(blocks_per_year) ); + eosio::asset system_contract::supply_growth( double rate, const eosio::asset& token_supply, time seconds ) { + const int64_t payment = static_cast( (rate * double(token_supply.amount) * double(seconds)) / double(seconds_per_year) ); return eosio::asset( payment, token_supply.symbol ); } - */ - + void system_contract::onblock( block_timestamp timestamp, account_name producer ) { using namespace eosio; @@ -34,40 +39,11 @@ namespace eosiosystem { p.last_produced_block_time = timestamp; }); + /// only update block producers once every minute, block_timestamp is in half seconds if( timestamp - _gstate.last_producer_schedule_update > 120 ) { update_elected_producers( timestamp ); } - /// only update block producers once every minute, block_timestamp is in half seconds - /* - if( timestamp % 120 != 0 ) - return; - - const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); - const asset issued = payment_per_block( continuous_rate, token_supply ); - const asset producer_payment = payment_per_block( per_block_rate, token_supply ); - const asset to_eos_bucket = payment_per_block( standby_rate, token_supply ); - const asset to_savings = issued - (producer_payment + to_eos_bucket); - - INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - {N(eosio), issued, std::string("issue tokens per block")} ); - */ - - /* - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio),N(active)}}, - {N(eosio), N(eosio), to_savings, std::string("transfer to savings per block")} ); - - - auto parameters = _global.exists() ? _global.get() : get_default_parameters(); - parameters.eos_bucket += to_eos_bucket; - parameters.savings += to_savings; - _global.set ( parameters, _self ); - - const auto& producer_schedule_update = parameters.last_producer_schedule_update; - if ( producer_schedule_update == 0 || producer_schedule_update < timestamp + blocks_per_hour ) { - update_elected_producers( producer_schedule_update ); - } - */ } eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) { @@ -112,6 +88,8 @@ namespace eosiosystem { } void system_contract::claimrewards( const account_name& owner ) { + using namespace eosio; + require_auth(owner); auto prod = _producers.find( owner ); @@ -120,34 +98,34 @@ namespace eosiosystem { eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); } - /// calcualte the price-per-block - - /* - eosio::asset rewards = prod->per_block_payments; - - if ( _global.exists() ) { - auto parameters = _global.get(); - if ( parameters.eos_bucket.amount > 0 && prod->total_votes > 0 ) { - eosio::asset standby_payment = payment_per_vote( owner, prod->total_votes, parameters.eos_bucket ); - if ( standby_payment.amount > 0 ) { - rewards += standby_payment; - parameters.eos_bucket -= standby_payment; - _global.set( parameters, _self ); - } - } - } + auto parameters = _global.get(); + const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); + const time time_since_last_fill = now() - parameters.last_pervote_bucket_fill; + + const asset to_eos_bucket = supply_growth( standby_rate, token_supply, time_since_last_fill ); + const asset to_savings = supply_growth( continuous_rate - (perblock_rate + standby_rate), token_supply, time_since_last_fill ); + const asset perblock_pay = payment_per_block( perblock_rate, token_supply, prod->produced_blocks ); + const asset issue_amount = to_eos_bucket + to_savings + perblock_pay; - eosio_assert( rewards > asset(0, S(4,EOS)), "no rewards available to claim" ); + INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, + {N(eosio), issue_amount, std::string("issue tokens for producer pay")} ); + + const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + parameters.eos_bucket ); + + parameters.eos_bucket += ( to_eos_bucket - pervote_pay ); + parameters.last_pervote_bucket_fill = now(); + _global.set( parameters, _self ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), owner, perblock_pay + perblock_pay, std::string("producer claiming rewards") } ); + _producers.modify( prod, 0, [&](auto& p) { p.last_rewards_claim = now(); p.produced_blocks = 0; }); - - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), owner, rewards, std::string("producer claiming rewards") } ); - - */ + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio),N(active)}}, + { N(eosio), N(eosio), to_savings, std::string("transfer to savings") } ); } } //namespace eosiosystem From bc06cbeda9b827393abce8a50180e70e84d0a386 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 6 May 2018 17:59:00 -0400 Subject: [PATCH 0216/1048] Changes following code review --- producer_pay.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 862087a1..e6066621 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -108,12 +108,13 @@ namespace eosiosystem { const asset issue_amount = to_eos_bucket + to_savings + perblock_pay; INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - {N(eosio), issue_amount, std::string("issue tokens for producer pay")} ); + {N(eosio), issue_amount, std::string("issue tokens for producer pay and savings")} ); const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + parameters.eos_bucket ); parameters.eos_bucket += ( to_eos_bucket - pervote_pay ); parameters.last_pervote_bucket_fill = now(); + parameters.savings += to_savings; _global.set( parameters, _self ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, @@ -124,8 +125,6 @@ namespace eosiosystem { p.produced_blocks = 0; }); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio),N(active)}}, - { N(eosio), N(eosio), to_savings, std::string("transfer to savings") } ); } } //namespace eosiosystem From a372776d44832181246a760ebd1a70540007e642 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 6 May 2018 19:59:25 -0400 Subject: [PATCH 0217/1048] Fixed producer_info abi, bug in claimrewards --- eosio.system.abi | 13 ++++++++----- eosio.system.hpp | 4 ++-- producer_pay.cpp | 8 ++++---- 3 files changed, 14 insertions(+), 11 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index f76d3178..ad5cee28 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -131,11 +131,14 @@ "name": "producer_info", "base": "", "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"total_votes", "type":"uint128"}, - {"name":"packed_key", "type":"public_key"}, - {"name":"per_block_payments", "type":"uint64"}, - {"name":"last_claim_time", "type":"time"} + {"name":"owner", "type":"account_name"}, + {"name":"total_votes", "type":"float64"}, + {"name":"producer_key", "type":"public_key"}, + {"name":"produced_blocks", "type":"uint32"}, + {"name":"last_claim_time", "type":"time"}, + {"name":"location", "type":"uint16"}, + {"name":"time_became_active", "type":"time"}, + {"name":"last_produced_block_time", "type":"time"} ] },{ "name": "regproducer", diff --git a/eosio.system.hpp b/eosio.system.hpp index 19b5e5fc..a3f1acdc 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -51,7 +51,7 @@ namespace eosiosystem { double total_votes = 0; eosio::public_key producer_key; /// a packed public key object uint32_t produced_blocks; - time last_rewards_claim = 0; + time last_claim_time = 0; uint16_t location = 0; block_timestamp time_became_active = 0; block_timestamp last_produced_block_time = 0; @@ -62,7 +62,7 @@ namespace eosiosystem { // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key) - (produced_blocks)(last_rewards_claim) + (produced_blocks)(last_claim_time)(location) (time_became_active)(last_produced_block_time) ) }; diff --git a/producer_pay.cpp b/producer_pay.cpp index e6066621..3f7e6aa2 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -94,8 +94,8 @@ namespace eosiosystem { auto prod = _producers.find( owner ); eosio_assert( prod != _producers.end(), "account name is not in producer list" ); - if( prod->last_rewards_claim > 0 ) { - eosio_assert(now() >= prod->last_rewards_claim + seconds_per_day, "already claimed rewards within a day"); + if( prod->last_claim_time > 0 ) { + eosio_assert(now() >= prod->last_claim_time + seconds_per_day, "already claimed rewards within a day"); } auto parameters = _global.get(); @@ -118,10 +118,10 @@ namespace eosiosystem { _global.set( parameters, _self ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), owner, perblock_pay + perblock_pay, std::string("producer claiming rewards") } ); + { N(eosio), owner, perblock_pay + pervote_pay, std::string("producer claiming rewards") } ); _producers.modify( prod, 0, [&](auto& p) { - p.last_rewards_claim = now(); + p.last_claim_time = now(); p.produced_blocks = 0; }); From 049ec43f51f56fc2ee6966c642079ad783658c90 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 7 May 2018 13:45:35 -0400 Subject: [PATCH 0218/1048] Small fixes --- eosio.system.abi | 13 +++++++++---- eosio.system.hpp | 4 ++-- producer_pay.cpp | 17 ++++++++++------- voting.cpp | 4 ++-- 4 files changed, 23 insertions(+), 15 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index ad5cee28..e4ac2ea1 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -123,9 +123,14 @@ "name": "eosio_global_state", "base": "eosio_parameters", "fields": [ - {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"uint64"}, - {"name":"payment_per_block", "type":"uint64"} + {"name":"total_ram_bytes_reserved", "type":"uint64"}, + {"name":"total_ram_stake", "type":"asset"}, + {"name":"last_producer_schedule_update", "type":"time"}, + {"name":"last_pervote_bucket_fill", "type":"time"}, + {"name":"eos_bucket", "type":"asset"}, + {"name":"savings", "type":"asset"}, + {"name":"last_producer_schedule_id", "type":"checksum160"}, + {"name":"total_activatied_stake", "type":"int64"} ] },{ "name": "producer_info", @@ -182,7 +187,7 @@ {"name":"owner", "type":"account_name"}, {"name":"proxy", "type":"account_name"}, {"name":"producers", "type":"account_name[]"}, - {"name":"staked", "type":"uint64"}, + {"name":"staked", "type":"int64"}, {"name":"last_vote_weight", "type":"float64"}, {"name":"proxied_vote_weight", "type":"float64"}, {"name":"is_proxy", "type":"bool"}, diff --git a/eosio.system.hpp b/eosio.system.hpp index a3f1acdc..82f38c25 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -37,13 +37,13 @@ namespace eosiosystem { eosio::asset savings; checksum160 last_producer_schedule_id; - int64_t total_activiated_stake = 0; + int64_t total_activated_stake = 0; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update) (last_pervote_bucket_fill) - (eos_bucket)(savings)(last_producer_schedule_id)(total_activiated_stake) ) + (eos_bucket)(savings)(last_producer_schedule_id)(total_activated_stake) ) }; struct producer_info { diff --git a/producer_pay.cpp b/producer_pay.cpp index 3f7e6aa2..9173f82a 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -26,18 +26,21 @@ namespace eosiosystem { void system_contract::onblock( block_timestamp timestamp, account_name producer ) { using namespace eosio; - + /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activiated_stake < 150'000'000'0000 ) + if( _gstate.total_activated_stake < 150'000'000'0000 ) return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses _gstate.last_pervote_bucket_fill = timestamp; - _producers.modify( _producers.get(producer), 0, [&](auto& p ) { - p.produced_blocks++; - p.last_produced_block_time = timestamp; - }); + auto prod = _producers.find(producer); + if ( prod != _producers.end() ) { + _producers.modify( prod, 0, [&](auto& p ) { + p.produced_blocks++; + p.last_produced_block_time = timestamp; + }); + } /// only update block producers once every minute, block_timestamp is in half seconds if( timestamp - _gstate.last_producer_schedule_update > 120 ) { @@ -91,7 +94,7 @@ namespace eosiosystem { using namespace eosio; require_auth(owner); - + auto prod = _producers.find( owner ); eosio_assert( prod != _producers.end(), "account name is not in producer list" ); if( prod->last_claim_time > 0 ) { diff --git a/voting.cpp b/voting.cpp index d5435fd0..f95b7056 100644 --- a/voting.cpp +++ b/voting.cpp @@ -137,11 +137,11 @@ namespace eosiosystem { /** * The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until - * after total_activiated_stake hits threshold, we can use last_vote_weight to determine that this is + * after total_activated_stake hits threshold, we can use last_vote_weight to determine that this is * their first vote and should consider their stake activated. */ if( voter->last_vote_weight <= 0.0 ) { - _gstate.total_activiated_stake += voter->staked; + _gstate.total_activated_stake += voter->staked; } auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); From cbae3c522a27db8781ef40d4ee59ac0f8dcd0fb0 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 7 May 2018 17:17:21 -0400 Subject: [PATCH 0219/1048] cleos listproducers #2807 --- eosio.system.abi | 13 ++++++++----- eosio.system.hpp | 3 ++- voting.cpp | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index f76d3178..32080cfb 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -132,10 +132,13 @@ "base": "", "fields": [ {"name":"owner", "type":"account_name"}, - {"name":"total_votes", "type":"uint128"}, - {"name":"packed_key", "type":"public_key"}, - {"name":"per_block_payments", "type":"uint64"}, - {"name":"last_claim_time", "type":"time"} + {"name":"total_votes", "type":"float64"}, + {"name":"producer_key", "type":"public_key"}, + {"name":"url", "type":"string"}, + {"name":"last_rewards_claim", "type":"uint32"}, + {"name":"location", "type":"uint16"}, + {"name":"time_became_active", "type":"uint32"}, + {"name":"time_produced_block_time", "type":"uint32"} ] },{ "name": "regproducer", @@ -247,7 +250,7 @@ } ], "tables": [{ - "name": "producerinfo", + "name": "producers", "type": "producer_info", "index_type": "i64", "key_names" : ["owner"], diff --git a/eosio.system.hpp b/eosio.system.hpp index 3b8eb743..6984b4af 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -50,6 +50,7 @@ namespace eosiosystem { account_name owner; double total_votes = 0; eosio::public_key producer_key; /// a packed public key object + std::string url; uint32_t produced_blocks; time last_rewards_claim = 0; uint16_t location = 0; @@ -61,7 +62,7 @@ namespace eosiosystem { bool active() const { return producer_key != public_key(); } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key) + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(url) (produced_blocks)(last_rewards_claim) (time_became_active)(last_produced_block_time) ) }; diff --git a/voting.cpp b/voting.cpp index d5435fd0..1cea2f49 100644 --- a/voting.cpp +++ b/voting.cpp @@ -45,6 +45,7 @@ namespace eosiosystem { if( producer_key != prod->producer_key ) { _producers.modify( prod, producer, [&]( producer_info& info ){ info.producer_key = producer_key; + info.url = url; }); } } else { @@ -52,6 +53,7 @@ namespace eosiosystem { info.owner = producer; info.total_votes = 0; info.producer_key = producer_key; + info.url = url; }); } } From 5a31835f0500fd1c4e18fadb180ed6a4ea9b9504 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 7 May 2018 17:39:28 -0400 Subject: [PATCH 0220/1048] Replace now() with current_time(), other fixes --- eosio.system.abi | 8 ++++---- eosio.system.hpp | 4 ++-- producer_pay.cpp | 15 ++++++++------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index e4ac2ea1..60d90442 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -126,7 +126,7 @@ {"name":"total_ram_bytes_reserved", "type":"uint64"}, {"name":"total_ram_stake", "type":"asset"}, {"name":"last_producer_schedule_update", "type":"time"}, - {"name":"last_pervote_bucket_fill", "type":"time"}, + {"name":"last_pervote_bucket_fill", "type":"uint64"}, {"name":"eos_bucket", "type":"asset"}, {"name":"savings", "type":"asset"}, {"name":"last_producer_schedule_id", "type":"checksum160"}, @@ -140,10 +140,10 @@ {"name":"total_votes", "type":"float64"}, {"name":"producer_key", "type":"public_key"}, {"name":"produced_blocks", "type":"uint32"}, - {"name":"last_claim_time", "type":"time"}, + {"name":"last_claim_time", "type":"uint64"}, {"name":"location", "type":"uint16"}, - {"name":"time_became_active", "type":"time"}, - {"name":"last_produced_block_time", "type":"time"} + {"name":"time_became_active", "type":"uint32"}, + {"name":"last_produced_block_time", "type":"uint32"} ] },{ "name": "regproducer", diff --git a/eosio.system.hpp b/eosio.system.hpp index 82f38c25..0657c822 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -32,7 +32,7 @@ namespace eosiosystem { eosio::asset total_ram_stake; block_timestamp last_producer_schedule_update = 0; - time last_pervote_bucket_fill = 0; + uint64_t last_pervote_bucket_fill = 0; eosio::asset eos_bucket; eosio::asset savings; checksum160 last_producer_schedule_id; @@ -51,7 +51,7 @@ namespace eosiosystem { double total_votes = 0; eosio::public_key producer_key; /// a packed public key object uint32_t produced_blocks; - time last_claim_time = 0; + uint64_t last_claim_time = 0; uint16_t location = 0; block_timestamp time_became_active = 0; block_timestamp last_produced_block_time = 0; diff --git a/producer_pay.cpp b/producer_pay.cpp index 9173f82a..f5b853e3 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -13,6 +13,7 @@ namespace eosiosystem { const uint32_t seconds_per_year = 52*7*24*3600; const uint32_t blocks_per_day = 2 * 24 * 3600; const uint32_t blocks_per_hour = 2 * 3600; + const uint64_t useconds_per_day = 24 * 3600 * uint64_t(1000000); eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ) { const int64_t payment = static_cast( (rate * double(token_supply.amount) * double(num_blocks)) / double(blocks_per_year) ); @@ -98,15 +99,15 @@ namespace eosiosystem { auto prod = _producers.find( owner ); eosio_assert( prod != _producers.end(), "account name is not in producer list" ); if( prod->last_claim_time > 0 ) { - eosio_assert(now() >= prod->last_claim_time + seconds_per_day, "already claimed rewards within a day"); + eosio_assert(current_time() >= prod->last_claim_time + useconds_per_day, "already claimed rewards within a day"); } - auto parameters = _global.get(); + auto parameters = _global.get(); const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); - const time time_since_last_fill = now() - parameters.last_pervote_bucket_fill; + const uint32_t secs_since_last_fill = static_cast( (current_time() - parameters.last_pervote_bucket_fill) / 1000000 ); - const asset to_eos_bucket = supply_growth( standby_rate, token_supply, time_since_last_fill ); - const asset to_savings = supply_growth( continuous_rate - (perblock_rate + standby_rate), token_supply, time_since_last_fill ); + const asset to_eos_bucket = supply_growth( standby_rate, token_supply, secs_since_last_fill ); + const asset to_savings = supply_growth( continuous_rate - (perblock_rate + standby_rate), token_supply, secs_since_last_fill ); const asset perblock_pay = payment_per_block( perblock_rate, token_supply, prod->produced_blocks ); const asset issue_amount = to_eos_bucket + to_savings + perblock_pay; @@ -116,7 +117,7 @@ namespace eosiosystem { const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + parameters.eos_bucket ); parameters.eos_bucket += ( to_eos_bucket - pervote_pay ); - parameters.last_pervote_bucket_fill = now(); + parameters.last_pervote_bucket_fill = current_time(); parameters.savings += to_savings; _global.set( parameters, _self ); @@ -124,7 +125,7 @@ namespace eosiosystem { { N(eosio), owner, perblock_pay + pervote_pay, std::string("producer claiming rewards") } ); _producers.modify( prod, 0, [&](auto& p) { - p.last_claim_time = now(); + p.last_claim_time = current_time(); p.produced_blocks = 0; }); From ad1fd10221ac32fc144d872ab2f3bf93c8331bc7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 8 May 2018 09:30:40 -0400 Subject: [PATCH 0221/1048] Fixed unit test --- producer_pay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index f5b853e3..4f2cd0ac 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -29,7 +29,7 @@ namespace eosiosystem { using namespace eosio; /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < 150'000'000'0000 ) + if( _gstate.total_activated_stake < 1500000000000 /* 150'000'000'0000 */ ) return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses From f33f39f5d6ae815ec3cb21bb83b8f6321a2a1a6b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 9 May 2018 16:46:53 -0400 Subject: [PATCH 0222/1048] draft of votes propagation for new system contract, fixing tests #2682 --- voting.cpp | 124 +++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 86 insertions(+), 38 deletions(-) diff --git a/voting.cpp b/voting.cpp index 3b7da613..287a027f 100644 --- a/voting.cpp +++ b/voting.cpp @@ -61,7 +61,7 @@ namespace eosiosystem { void system_contract::unregprod( const account_name producer ) { require_auth( producer ); - const auto& prod = _producers.get( producer ); + const auto& prod = _producers.get( producer, "producer not found" ); _producers.modify( prod, 0, [&]( producer_info& info ){ info.producer_key = eosio::public_key(); @@ -102,7 +102,10 @@ namespace eosiosystem { _gstate.last_producer_schedule_update = block_time; } - + double stake2vote( int64_t staked ) { + double weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); + return double(staked) * std::pow( 2, weight ); + } /** * @pre producers must be sorted from lowest to highest and must be registered and active * @pre if proxy is set then no producers can be voted for @@ -146,59 +149,71 @@ namespace eosiosystem { _gstate.total_activated_stake += voter->staked; } - auto weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); - double new_vote_weight = double(voter->staked) * std::pow(2,weight); - + auto new_vote_weight = stake2vote( voter->staked ); if( voter->is_proxy ) { new_vote_weight += voter->proxied_vote_weight; } - boost::container::flat_map producer_deltas; - for( const auto& p : voter->producers ) { - producer_deltas[p] -= voter->last_vote_weight; - } - - if( new_vote_weight >= 0 ) { - for( const auto& p : producers ) { - producer_deltas[p] += new_vote_weight; + boost::container::flat_map > producer_deltas; + if ( voter->last_vote_weight != 0 ) { + if( voter->proxy ) { + auto old_proxy = _voters.find( voter->proxy ); + eosio_assert( old_proxy != _voters.end(), "old proxy not found" ); //data corruption + _voters.modify( old_proxy, 0, [&]( auto& vp ) { + vp.proxied_vote_weight -= voter->last_vote_weight; + }); + propagate_weight_change( *old_proxy ); + } else { + for( const auto& p : voter->producers ) { + auto& d = producer_deltas[p]; + d.first -= voter->last_vote_weight; + d.second = false; + } } } - if( voter->proxy != account_name() ) { - auto old_proxy = _voters.find( voter->proxy ); - _voters.modify( old_proxy, 0, [&]( auto& vp ) { - vp.proxied_vote_weight -= voter->last_vote_weight; - print( " vote weight: ", vp.last_vote_weight, "\n" ); - }); - } - - if( proxy != account_name() && new_vote_weight > 0 ) { + if( proxy ) { auto new_proxy = _voters.find( voter->proxy ); eosio_assert( new_proxy != _voters.end() && new_proxy->is_proxy, "invalid proxy specified" ); - _voters.modify( new_proxy, 0, [&]( auto& vp ) { - vp.proxied_vote_weight += new_vote_weight; - print( " vote weight: ", vp.last_vote_weight, "\n" ); - }); + if ( new_vote_weight >= 0 ) { + _voters.modify( new_proxy, 0, [&]( auto& vp ) { + vp.proxied_vote_weight += new_vote_weight; + }); + propagate_weight_change( *new_proxy ); + } + } else { + if( new_vote_weight >= 0 ) { + for( const auto& p : producers ) { + auto& d = producer_deltas[p]; + d.first += new_vote_weight; + d.second = true; + } + } } - _voters.modify( voter, 0, [&]( auto& av ) { - print( "new_vote_weight: ", new_vote_weight, "\n" ); - av.last_vote_weight = new_vote_weight; - av.producers = producers; - av.proxy = proxy; - print( " vote weight: ", av.last_vote_weight, "\n" ); - }); - for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { + eosio_assert( pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); _producers.modify( pitr, 0, [&]( auto& p ) { - p.total_votes += pd.second; - eosio_assert( p.total_votes >= 0, "something bad happened" ); - eosio_assert( p.active(), "producer is not active" ); + print( "orig total_votes: ", p.total_votes, " delta: ", pd.second.first, "\n" ); + p.total_votes += pd.second.first; + print( "new total_votes: ", p.total_votes, "\n" ); + //eosio_assert( p.total_votes >= 0, "something bad happened" ); }); + } else { + eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); } } + + _voters.modify( voter, 0, [&]( auto& av ) { + print( "last_vote_weight: ", av.last_vote_weight, "\n" ); + print( "new_vote_weight: ", new_vote_weight, "\n" ); + av.last_vote_weight = new_vote_weight; + av.producers = producers; + av.proxy = proxy; + print( " vote weight: ", av.last_vote_weight, "\n" ); + }); } /** @@ -215,13 +230,46 @@ namespace eosiosystem { auto pitr = _voters.find(proxy); eosio_assert( pitr != _voters.end(), "proxy must have some stake first" ); - eosio_assert( !pitr->is_proxy, "account is already a proxy" ); + //eosio_assert( !pitr->is_proxy, "account is already a proxy" ); eosio_assert( pitr->is_proxy != isproxy, "action has no effect" ); _voters.modify( pitr, 0, [&]( auto& p ) { p.is_proxy = isproxy; print( " vote weight: ", p.last_vote_weight, "\n" ); }); + + propagate_weight_change( *pitr ); + } + + void system_contract::propagate_weight_change( const voter_info& voter ) { + eosio_assert( voter.proxy == 0 || !voter.is_proxy, "account registered as a proxy is not allowed to use a proxy" ); + double new_weight = stake2vote( voter.staked ); + if ( voter.is_proxy ) { + new_weight += voter.proxied_vote_weight; + } + + if ( new_weight != voter.last_vote_weight ) { + if ( voter.proxy ) { + auto& proxy = _voters.get( voter.proxy, "proxy not found" ); //data corruption + _voters.modify( proxy, 0, [&]( auto& p ) { + p.proxied_vote_weight += new_weight - voter.last_vote_weight; + } + ); + propagate_weight_change( proxy ); + } else { + for ( auto acnt : voter.producers ) { + auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption + _producers.modify( pitr, 0, [&]( auto& p ) { + p.total_votes += new_weight - voter.last_vote_weight; + } + ); + } + } + } + _voters.modify( voter, 0, [&]( auto& v ) { + v.last_vote_weight = new_weight; + } + ); } } /// namespace eosiosystem From 6af1c19c9473be9693e8ce9a2fa9b93fdb0c455b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 9 May 2018 16:50:55 -0400 Subject: [PATCH 0223/1048] draft of votes propagation for new system contract (missing changes) #2682 --- eosio.system.cpp | 8 ++++---- eosio.system.hpp | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 1eb3c37a..d3c550ac 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -16,7 +16,7 @@ namespace eosiosystem { _global(_self,_self), _rammarket(_self,_self) { - print( "construct system\n" ); + //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); auto itr = _rammarket.find(S(4,RAMEOS)); @@ -32,7 +32,7 @@ namespace eosiosystem { m.quote.balance.symbol = S(4,EOS); }); } else { - print( "ram market already created" ); + //print( "ram market already created" ); } } @@ -44,9 +44,9 @@ namespace eosiosystem { system_contract::~system_contract() { - print( "destruct system\n" ); + //print( "destruct system\n" ); _global.set( _gstate, _self ); - eosio_exit(0); + //eosio_exit(0); } void system_contract::setram( uint64_t max_ram_size ) { diff --git a/eosio.system.hpp b/eosio.system.hpp index f58c5c86..91321e2c 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -122,7 +122,7 @@ namespace eosiosystem { public: system_contract( account_name s ); - [[noreturn]] ~system_contract(); + ~system_contract(); // Actions: void onblock( uint32_t timestamp_slot, account_name producer ); @@ -203,7 +203,7 @@ namespace eosiosystem { static eosio_global_state get_default_parameters(); // defined in voting.cpp - void adjust_voting_power( account_name acnt, int64_t delta ); + void propagate_weight_change( const voter_info& voter ); }; } /// eosiosystem From b975e0ee798344f6ff73e0478469b5a6994ba494 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 8 May 2018 18:19:46 -0400 Subject: [PATCH 0224/1048] More producer pay testing, fixes --- eosio.system.abi | 3 +-- producer_pay.cpp | 14 ++++++-------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 0e85935a..5e479f41 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -116,8 +116,7 @@ "name": "eosio_parameters", "base": "blockchain_parameters", "fields": [ - {"name":"max_ram_size", "type":"uint64"}, - {"name":"percent_of_max_inflation_rate", "type":"uint32"} + {"name":"max_ram_size", "type":"uint64"} ] },{ "name": "eosio_global_state", diff --git a/producer_pay.cpp b/producer_pay.cpp index 4f2cd0ac..c69f5e2c 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -33,7 +33,7 @@ namespace eosiosystem { return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses - _gstate.last_pervote_bucket_fill = timestamp; + _gstate.last_pervote_bucket_fill = current_time(); auto prod = _producers.find(producer); if ( prod != _producers.end() ) { @@ -102,9 +102,8 @@ namespace eosiosystem { eosio_assert(current_time() >= prod->last_claim_time + useconds_per_day, "already claimed rewards within a day"); } - auto parameters = _global.get(); const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); - const uint32_t secs_since_last_fill = static_cast( (current_time() - parameters.last_pervote_bucket_fill) / 1000000 ); + const uint32_t secs_since_last_fill = static_cast( (current_time() - _gstate.last_pervote_bucket_fill) / 1000000 ); const asset to_eos_bucket = supply_growth( standby_rate, token_supply, secs_since_last_fill ); const asset to_savings = supply_growth( continuous_rate - (perblock_rate + standby_rate), token_supply, secs_since_last_fill ); @@ -114,12 +113,11 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), issue_amount, std::string("issue tokens for producer pay and savings")} ); - const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + parameters.eos_bucket ); + const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + _gstate.eos_bucket ); - parameters.eos_bucket += ( to_eos_bucket - pervote_pay ); - parameters.last_pervote_bucket_fill = current_time(); - parameters.savings += to_savings; - _global.set( parameters, _self ); + _gstate.eos_bucket += ( to_eos_bucket - pervote_pay ); + _gstate.last_pervote_bucket_fill = current_time(); + _gstate.savings += to_savings; INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, { N(eosio), owner, perblock_pay + pervote_pay, std::string("producer claiming rewards") } ); From 4f1da21cb0497f7fa154c575d290568c7d78fd5b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 9 May 2018 17:04:10 -0400 Subject: [PATCH 0225/1048] Test producer pay with 21 producers in addition to standbys --- producer_pay.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index c69f5e2c..348c50ea 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -52,6 +52,7 @@ namespace eosiosystem { eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) { eosio::asset payment(0, S(4,EOS)); + const int64_t min_daily_amount = 100 * 10000; if ( eos_bucket.amount < min_daily_tokens ) { return payment; } @@ -75,7 +76,7 @@ namespace eosiosystem { total_producer_votes += itr->total_votes; running_payment_amount = (itr->total_votes) * double(eos_bucket.amount) / total_producer_votes; - if ( running_payment_amount < min_daily_tokens ) { + if ( running_payment_amount < min_daily_amount ) { if ( itr->owner == owner ) { to_be_payed = false; } @@ -110,11 +111,18 @@ namespace eosiosystem { const asset perblock_pay = payment_per_block( perblock_rate, token_supply, prod->produced_blocks ); const asset issue_amount = to_eos_bucket + to_savings + perblock_pay; + const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + _gstate.eos_bucket ); + + if ( perblock_pay.amount + pervote_pay.amount == 0 ) { + _producers.modify( prod, 0, [&](auto& p) { + p.last_claim_time = current_time(); + }); + return; + } + INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), issue_amount, std::string("issue tokens for producer pay and savings")} ); - const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + _gstate.eos_bucket ); - _gstate.eos_bucket += ( to_eos_bucket - pervote_pay ); _gstate.last_pervote_bucket_fill = current_time(); _gstate.savings += to_savings; From ffd8243e12c227a53c4251678a78761d4fffe5e2 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 9 May 2018 17:38:01 -0400 Subject: [PATCH 0226/1048] Rename eos_bucket to pervote_bucket --- eosio.system.abi | 2 +- eosio.system.hpp | 6 +++--- producer_pay.cpp | 18 +++++++++--------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 5e479f41..19ee9c25 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -126,7 +126,7 @@ {"name":"total_ram_stake", "type":"asset"}, {"name":"last_producer_schedule_update", "type":"time"}, {"name":"last_pervote_bucket_fill", "type":"uint64"}, - {"name":"eos_bucket", "type":"asset"}, + {"name":"pervote_bucket", "type":"asset"}, {"name":"savings", "type":"asset"}, {"name":"last_producer_schedule_id", "type":"checksum160"}, {"name":"total_activatied_stake", "type":"int64"} diff --git a/eosio.system.hpp b/eosio.system.hpp index 91321e2c..66dd837a 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -33,7 +33,7 @@ namespace eosiosystem { block_timestamp last_producer_schedule_update = 0; uint64_t last_pervote_bucket_fill = 0; - eosio::asset eos_bucket; + eosio::asset pervote_bucket; eosio::asset savings; checksum160 last_producer_schedule_id; @@ -43,7 +43,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update) (last_pervote_bucket_fill) - (eos_bucket)(savings)(last_producer_schedule_id)(total_activated_stake) ) + (pervote_bucket)(savings)(last_producer_schedule_id)(total_activated_stake) ) }; struct producer_info { @@ -191,7 +191,7 @@ namespace eosiosystem { private: eosio::asset payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ); - eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ); + eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ); eosio::asset supply_growth( double rate, const eosio::asset& token_supply, time seconds ); diff --git a/producer_pay.cpp b/producer_pay.cpp index 348c50ea..fb0abc41 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -29,7 +29,7 @@ namespace eosiosystem { using namespace eosio; /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < 1500000000000 /* 150'000'000'0000 */ ) + if( _gstate.total_activated_stake < 150'000'000'0000 ) return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses @@ -50,10 +50,10 @@ namespace eosiosystem { } - eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& eos_bucket ) { + eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) { eosio::asset payment(0, S(4,EOS)); const int64_t min_daily_amount = 100 * 10000; - if ( eos_bucket.amount < min_daily_tokens ) { + if ( pervote_bucket.amount < min_daily_tokens ) { return payment; } @@ -75,7 +75,7 @@ namespace eosiosystem { } total_producer_votes += itr->total_votes; - running_payment_amount = (itr->total_votes) * double(eos_bucket.amount) / total_producer_votes; + running_payment_amount = (itr->total_votes) * double(pervote_bucket.amount) / total_producer_votes; if ( running_payment_amount < min_daily_amount ) { if ( itr->owner == owner ) { to_be_payed = false; @@ -86,7 +86,7 @@ namespace eosiosystem { } if ( to_be_payed ) { - payment.amount = static_cast( (double(eos_bucket.amount) * owners_votes) / total_producer_votes ); + payment.amount = static_cast( (double(pervote_bucket.amount) * owners_votes) / total_producer_votes ); } return payment; @@ -106,12 +106,12 @@ namespace eosiosystem { const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); const uint32_t secs_since_last_fill = static_cast( (current_time() - _gstate.last_pervote_bucket_fill) / 1000000 ); - const asset to_eos_bucket = supply_growth( standby_rate, token_supply, secs_since_last_fill ); + const asset to_pervote_bucket = supply_growth( standby_rate, token_supply, secs_since_last_fill ); const asset to_savings = supply_growth( continuous_rate - (perblock_rate + standby_rate), token_supply, secs_since_last_fill ); const asset perblock_pay = payment_per_block( perblock_rate, token_supply, prod->produced_blocks ); - const asset issue_amount = to_eos_bucket + to_savings + perblock_pay; + const asset issue_amount = to_pervote_bucket + to_savings + perblock_pay; - const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_eos_bucket + _gstate.eos_bucket ); + const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_pervote_bucket + _gstate.pervote_bucket ); if ( perblock_pay.amount + pervote_pay.amount == 0 ) { _producers.modify( prod, 0, [&](auto& p) { @@ -123,7 +123,7 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), issue_amount, std::string("issue tokens for producer pay and savings")} ); - _gstate.eos_bucket += ( to_eos_bucket - pervote_pay ); + _gstate.pervote_bucket += ( to_pervote_bucket - pervote_pay ); _gstate.last_pervote_bucket_fill = current_time(); _gstate.savings += to_savings; From 0f1a79738ecd95d442926cbc8ea93edfaa53bc92 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 9 May 2018 18:21:53 -0400 Subject: [PATCH 0227/1048] Enable undelegate to differ from delegator #2859 --- delegate_bandwidth.cpp | 15 +++++++++------ eosio.system.abi | 3 ++- eosio.system.hpp | 8 +++++++- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 0014108e..d3e1810b 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -216,7 +216,7 @@ namespace eosiosystem { void system_contract::delegatebw( account_name from, account_name receiver, asset stake_net_quantity, - asset stake_cpu_quantity ) + asset stake_cpu_quantity, bool transfer ) { require_auth( from ); @@ -228,8 +228,11 @@ namespace eosiosystem { auto total_stake = stake_cpu_quantity.amount + stake_net_quantity.amount; eosio_assert( total_stake > 0, "must stake a positive amount" ); - print( "deltable" ); - del_bandwidth_table del_tbl( _self, from ); + account_name source_stake_from = from; + + if( transfer ) from = receiver; + + del_bandwidth_table del_tbl( _self, from); auto itr = del_tbl.find( receiver ); if( itr == del_tbl.end() ) { del_tbl.emplace( from, [&]( auto& dbo ){ @@ -240,7 +243,7 @@ namespace eosiosystem { }); } else { - del_tbl.modify( itr, from, [&]( auto& dbo ){ + del_tbl.modify( itr, 0, [&]( auto& dbo ){ dbo.net_weight += stake_net_quantity; dbo.cpu_weight += stake_cpu_quantity; }); @@ -264,9 +267,9 @@ namespace eosiosystem { set_resource_limits( tot_itr->owner, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - if( N(eosio) != from) { + if( N(eosio) != source_stake_from ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); + { source_stake_from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); } print( "voters \n" ); diff --git a/eosio.system.abi b/eosio.system.abi index 0e85935a..3157d8ba 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -30,7 +30,8 @@ {"name":"from", "type":"account_name"}, {"name":"receiver", "type":"account_name"}, {"name":"stake_net_quantity", "type":"asset"}, - {"name":"stake_cpu_quantity", "type":"asset"} + {"name":"stake_cpu_quantity", "type":"asset"}, + {"name":"transfer", "type":"bool"} ] },{ "name": "undelegatebw", diff --git a/eosio.system.hpp b/eosio.system.hpp index 91321e2c..4093d5cb 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -129,8 +129,14 @@ namespace eosiosystem { // const block_header& header ); /// only parse first 3 fields of block header // functions defined in delegate_bandwidth.cpp + + /** + * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. + * If transfer == true, then 'receiver' can unstake to their account + * Else 'from' can unstake at any time. + */ void delegatebw( account_name from, account_name receiver, - asset stake_net_quantity, asset stake_cpu_quantity ); + asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); /** From b5528dccb97682a7dd0be365237c2421f8577297 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 9 May 2018 20:01:23 -0400 Subject: [PATCH 0228/1048] small bugfix, system contract tests fix + stake2votes function #2682 --- voting.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/voting.cpp b/voting.cpp index 287a027f..06642efd 100644 --- a/voting.cpp +++ b/voting.cpp @@ -173,7 +173,7 @@ namespace eosiosystem { } if( proxy ) { - auto new_proxy = _voters.find( voter->proxy ); + auto new_proxy = _voters.find( proxy ); eosio_assert( new_proxy != _voters.end() && new_proxy->is_proxy, "invalid proxy specified" ); if ( new_vote_weight >= 0 ) { _voters.modify( new_proxy, 0, [&]( auto& vp ) { @@ -229,16 +229,22 @@ namespace eosiosystem { require_auth( proxy ); auto pitr = _voters.find(proxy); - eosio_assert( pitr != _voters.end(), "proxy must have some stake first" ); + //eosio_assert( pitr != _voters.end(), "proxy must have some stake first" ); //eosio_assert( !pitr->is_proxy, "account is already a proxy" ); eosio_assert( pitr->is_proxy != isproxy, "action has no effect" ); - _voters.modify( pitr, 0, [&]( auto& p ) { - p.is_proxy = isproxy; - print( " vote weight: ", p.last_vote_weight, "\n" ); - }); - - propagate_weight_change( *pitr ); + if ( pitr != _voters.end() ) { + _voters.modify( pitr, 0, [&]( auto& p ) { + p.is_proxy = isproxy; + print( " vote weight: ", p.last_vote_weight, "\n" ); + }); + propagate_weight_change( *pitr ); + } else { + _voters.emplace( proxy, [&]( auto& p ) { + p.owner = proxy; + p.is_proxy = isproxy; + }); + } } void system_contract::propagate_weight_change( const voter_info& voter ) { From 5958a66a92571c1ea24b90008bf888bb82f99b66 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 10 May 2018 10:59:05 -0400 Subject: [PATCH 0229/1048] fixing system contract tests #2682 --- voting.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/voting.cpp b/voting.cpp index 06642efd..3da5b0f1 100644 --- a/voting.cpp +++ b/voting.cpp @@ -139,6 +139,7 @@ namespace eosiosystem { auto voter = _voters.find(voter_name); eosio_assert( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object + eosio_assert( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" ); /** * The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until @@ -229,11 +230,9 @@ namespace eosiosystem { require_auth( proxy ); auto pitr = _voters.find(proxy); - //eosio_assert( pitr != _voters.end(), "proxy must have some stake first" ); - //eosio_assert( !pitr->is_proxy, "account is already a proxy" ); - eosio_assert( pitr->is_proxy != isproxy, "action has no effect" ); - if ( pitr != _voters.end() ) { + eosio_assert( isproxy != pitr->is_proxy, "action has no effect" ); + eosio_assert( !isproxy || !pitr->proxy, "account that uses a proxy is not allowed to become a proxy" ); _voters.modify( pitr, 0, [&]( auto& p ) { p.is_proxy = isproxy; print( " vote weight: ", p.last_vote_weight, "\n" ); From 7319254a88216adab4ed9fe9ea97ce0e8b65db03 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 10 May 2018 10:56:07 -0400 Subject: [PATCH 0230/1048] Ram Buy/Sell Test - #2914 Added a unit test that would buy/sell a small amount of RAM and a large amount of RAM. This test showed unexpected behavior due to attempting to sell over 2^32 RAM. I updated the sellram action to enable selling more than 2^32 bytes at once. Test results show that for both large and small quantities, the user losses a small amount of tokens and does not profit. (cherry picked from commit 10273fa2d180f81769516b507bfdff68f06b7f87) --- delegate_bandwidth.cpp | 2 +- eosio.system.abi | 2 +- eosio.system.hpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index d3e1810b..b2cdc7c7 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -182,7 +182,7 @@ namespace eosiosystem { * refunds the purchase price to the account. In this way there is no profit to be made through buying * and selling ram. */ - void system_contract::sellram( account_name account, uint32_t bytes ) { + void system_contract::sellram( account_name account, uint64_t bytes ) { require_auth( account ); user_resources_table userres( _self, account ); diff --git a/eosio.system.abi b/eosio.system.abi index 91d6d718..234a9776 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -13,7 +13,7 @@ "base": "", "fields": [ {"name":"account", "type":"account_name"}, - {"name":"bytes", "type":"uint32"} + {"name":"bytes", "type":"uint64"} ] },{ "name": "buyram", diff --git a/eosio.system.hpp b/eosio.system.hpp index 67042a23..41a10d79 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -171,7 +171,7 @@ namespace eosiosystem { * Reduces quota my bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. */ - void sellram( account_name receiver, uint32_t bytes ); + void sellram( account_name receiver, uint64_t bytes ); /** * This action is called after the delegation-period to claim all pending From adeee40e32c1b24aadfdacaaf01f07a32193fb19 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 10 May 2018 20:11:00 -0400 Subject: [PATCH 0231/1048] Inactive producers - incomplete --- producer_pay.cpp | 8 +++++--- voting.cpp | 17 +++++++++++++++++ 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index fb0abc41..18a17fbf 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -28,8 +28,10 @@ namespace eosiosystem { void system_contract::onblock( block_timestamp timestamp, account_name producer ) { using namespace eosio; + require_auth(N(eosio)); + /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < 150'000'000'0000 ) + if( _gstate.total_activated_stake < 1500000000000 /* 150'000'000'0000 */ ) return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses @@ -53,7 +55,7 @@ namespace eosiosystem { eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) { eosio::asset payment(0, S(4,EOS)); const int64_t min_daily_amount = 100 * 10000; - if ( pervote_bucket.amount < min_daily_tokens ) { + if ( pervote_bucket.amount < min_daily_amount ) { return payment; } @@ -66,7 +68,7 @@ namespace eosiosystem { if ( !(itr->total_votes > 0) ) { break; } - if ( !(itr->active()) && !(itr->owner != owner) ) { + if ( !itr->active() ) { continue; } diff --git a/voting.cpp b/voting.cpp index 3da5b0f1..4c08afcc 100644 --- a/voting.cpp +++ b/voting.cpp @@ -78,8 +78,25 @@ namespace eosiosystem { for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) { if( !it->active() ) continue; + + if ( it->active() && it->time_became_active == 0 ) { + _producers.modify( *it, 0, [&](auto& p) { + p.time_became_active = block_time; + }); + } else if ( it->active() && block_time > 21 * 12 + it->time_became_active && + block_time > it->last_produced_block_time + blocks_per_day ) { + _producers.modify( *it, 0, [&](auto& p) { + p.producer_key = public_key(); + p.time_became_active = 0; + p.last_produced_block_time = 0; + }); + + continue; + } + top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location})); } + /// sort by producer name From 9b344e07bfe3d9ed8419b20f487eb721017e4f4b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 10 May 2018 23:31:43 -0400 Subject: [PATCH 0232/1048] Inactive producers - finished implementation --- producer_pay.cpp | 12 ++++++------ voting.cpp | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 18a17fbf..61f74e2f 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -37,6 +37,11 @@ namespace eosiosystem { if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses _gstate.last_pervote_bucket_fill = current_time(); + /// only update block producers once every minute, block_timestamp is in half seconds + if( timestamp - _gstate.last_producer_schedule_update > 120 ) { + update_elected_producers( timestamp ); + } + auto prod = _producers.find(producer); if ( prod != _producers.end() ) { _producers.modify( prod, 0, [&](auto& p ) { @@ -44,12 +49,6 @@ namespace eosiosystem { p.last_produced_block_time = timestamp; }); } - - /// only update block producers once every minute, block_timestamp is in half seconds - if( timestamp - _gstate.last_producer_schedule_update > 120 ) { - update_elected_producers( timestamp ); - } - } eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) { @@ -101,6 +100,7 @@ namespace eosiosystem { auto prod = _producers.find( owner ); eosio_assert( prod != _producers.end(), "account name is not in producer list" ); + eosio_assert( prod->active(), "producer does not have an active key" ); if( prod->last_claim_time > 0 ) { eosio_assert(current_time() >= prod->last_claim_time + useconds_per_day, "already claimed rewards within a day"); } diff --git a/voting.cpp b/voting.cpp index 4c08afcc..3adc08aa 100644 --- a/voting.cpp +++ b/voting.cpp @@ -79,11 +79,11 @@ namespace eosiosystem { for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) { if( !it->active() ) continue; - if ( it->active() && it->time_became_active == 0 ) { + if ( it->time_became_active == 0 ) { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); - } else if ( it->active() && block_time > 21 * 12 + it->time_became_active && + } else if ( block_time > 2 * 21 * 12 + it->time_became_active && block_time > it->last_produced_block_time + blocks_per_day ) { _producers.modify( *it, 0, [&](auto& p) { p.producer_key = public_key(); From bc7512f401659191287db2e643ca2b9172ddc505 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 11 May 2018 00:39:40 -0400 Subject: [PATCH 0233/1048] Inactive producers - testing --- producer_pay.cpp | 11 ++++++----- voting.cpp | 2 +- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 61f74e2f..4be19859 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -37,11 +37,6 @@ namespace eosiosystem { if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses _gstate.last_pervote_bucket_fill = current_time(); - /// only update block producers once every minute, block_timestamp is in half seconds - if( timestamp - _gstate.last_producer_schedule_update > 120 ) { - update_elected_producers( timestamp ); - } - auto prod = _producers.find(producer); if ( prod != _producers.end() ) { _producers.modify( prod, 0, [&](auto& p ) { @@ -49,6 +44,12 @@ namespace eosiosystem { p.last_produced_block_time = timestamp; }); } + + /// only update block producers once every minute, block_timestamp is in half seconds + if( timestamp - _gstate.last_producer_schedule_update > 120 ) { + update_elected_producers( timestamp ); + } + } eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) { diff --git a/voting.cpp b/voting.cpp index 3adc08aa..2f9701c4 100644 --- a/voting.cpp +++ b/voting.cpp @@ -83,7 +83,7 @@ namespace eosiosystem { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); - } else if ( block_time > 2 * 21 * 12 + it->time_became_active && + } else if ( block_time > 2 * 21 * 12 + it->time_became_active && block_time > it->last_produced_block_time + blocks_per_day ) { _producers.modify( *it, 0, [&](auto& p) { p.producer_key = public_key(); From 5ce904ac8e6977760811867cbd3ac8355644ddfe Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 11 May 2018 09:50:48 -0400 Subject: [PATCH 0234/1048] cleanup cleos and make system contract more robust when set before currency issued --- delegate_bandwidth.cpp | 2 +- eosio.system.cpp | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index b2cdc7c7..43482a0c 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -120,7 +120,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMEOS)); auto tmp = *itr; auto eosout = tmp.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); - print( "eosout: ", eosout, "\n" ); + print( "eosout: ", eosout, " ", tmp.base.balance, " ", tmp.quote.balance, "\n" ); buyram( payer, receiver, eosout ); } diff --git a/eosio.system.cpp b/eosio.system.cpp index d3c550ac..efaaccc2 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -23,14 +23,16 @@ namespace eosiosystem { if( itr == _rammarket.end() ) { auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; - itr = _rammarket.emplace( _self, [&]( auto& m ) { - m.supply.amount = 100000000000000ll; - m.supply.symbol = S(4,RAMEOS); - m.base.balance.amount = int64_t(_gstate.free_ram()); - m.base.balance.symbol = S(0,RAM); - m.quote.balance.amount = system_token_supply / 1000; - m.quote.balance.symbol = S(4,EOS); - }); + if( system_token_supply > 0 ) { + itr = _rammarket.emplace( _self, [&]( auto& m ) { + m.supply.amount = 100000000000000ll; + m.supply.symbol = S(4,RAMEOS); + m.base.balance.amount = int64_t(_gstate.free_ram()); + m.base.balance.symbol = S(0,RAM); + m.quote.balance.amount = system_token_supply / 1000; + m.quote.balance.symbol = S(4,EOS); + }); + } } else { //print( "ram market already created" ); } From f31946ecfdb54c0100278765a87be5923cb73b8f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 11 May 2018 10:44:15 -0400 Subject: [PATCH 0235/1048] Small change --- producer_pay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 4be19859..9022ca03 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -31,7 +31,7 @@ namespace eosiosystem { require_auth(N(eosio)); /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < 1500000000000 /* 150'000'000'0000 */ ) + if( _gstate.total_activated_stake < 150'000'000'0000 ) return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses From a4d39c286afb3c6de5de7fa58c70ea26a023abc5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 11 May 2018 11:49:22 -0400 Subject: [PATCH 0236/1048] Changes following code review, merge conflict --- voting.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 2f9701c4..99f43ecb 100644 --- a/voting.cpp +++ b/voting.cpp @@ -88,7 +88,6 @@ namespace eosiosystem { _producers.modify( *it, 0, [&](auto& p) { p.producer_key = public_key(); p.time_became_active = 0; - p.last_produced_block_time = 0; }); continue; From 3439331d9debc3f53f27dbadd429a0ef58423758 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 11 May 2018 17:09:58 -0400 Subject: [PATCH 0237/1048] send_deferred_transaction paramter replace_existing added, unit-tests updated #2970 --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 43482a0c..8ddfa22c 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -366,7 +366,7 @@ namespace eosiosystem { eosio::transaction out; out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); out.delay_sec = refund_delay; - out.send( from, receiver ); + out.send( from, receiver, true ); const auto& fromv = _voters.get( from ); From 02eb09500e71c5d255cfe9cc2c4228e080b2093c Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sat, 12 May 2018 22:51:53 -0400 Subject: [PATCH 0238/1048] Fix eosio.system abi & skip sig checks - signature checks are skipped while replaying - abi of eosio.system contract was inconsistant, Fix #2999 - reduced console spam while syncing and replaying - add max usage of resources when querying account --- eosio.system.abi | 5 ++--- eosio.system.cpp | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 234a9776..d18f920f 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -54,9 +54,8 @@ "fields": [ {"name":"from", "type":"account_name"}, {"name":"to", "type":"account_name"}, - {"name":"net_weight", "type":"uint64"}, - {"name":"cpu_weight", "type":"uint64"}, - {"name":"ram_bytes", "type":"uint64"} + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, ] },{ "name": "user_resources", diff --git a/eosio.system.cpp b/eosio.system.cpp index efaaccc2..a24d0bf1 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -81,8 +81,8 @@ EOSIO_ABI( eosiosystem::system_contract, (delegatebw)(undelegatebw)(refund) (buyram)(buyrambytes)(sellram) // voting.cpp - (regproxy)(regproducer)(unregprod)(voteproducer) // producer_pay.cpp + (regproxy)(regproducer)(unregprod)(voteproducer) (claimrewards) // native.hpp //XXX From 3a0dc9ac7f3552bb04f46616817740668cb2019c Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 13 May 2018 11:21:23 -0400 Subject: [PATCH 0239/1048] fix tests by removing extra comma from abi --- eosio.system.abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index d18f920f..62c15beb 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -55,7 +55,7 @@ {"name":"from", "type":"account_name"}, {"name":"to", "type":"account_name"}, {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"} ] },{ "name": "user_resources", From 69720817210f72b869fcd98f10fdd791f5fd279d Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Sun, 13 May 2018 22:36:43 -0400 Subject: [PATCH 0240/1048] Producer Pay Algorithm #3014 - don't store balances in ram as asset - refactor producer pay algo to not iterate over all producers - perform one percentage-based calculation - partially fix unit tests - use higher precision time --- delegate_bandwidth.cpp | 10 +-- eosio.system.abi | 11 +-- eosio.system.hpp | 19 +++--- producer_pay.cpp | 150 +++++++++++++++-------------------------- voting.cpp | 21 +++--- 5 files changed, 87 insertions(+), 124 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 8ddfa22c..3206a06e 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -159,7 +159,7 @@ namespace eosiosystem { eosio_assert( bytes_out > 0, "must reserve a positive amount" ); _gstate.total_ram_bytes_reserved += uint64_t(bytes_out); - _gstate.total_ram_stake.amount += quant.amount; + _gstate.total_ram_stake += quant.amount; user_resources_table userres( _self, receiver ); auto res_itr = userres.find( receiver ); @@ -182,8 +182,9 @@ namespace eosiosystem { * refunds the purchase price to the account. In this way there is no profit to be made through buying * and selling ram. */ - void system_contract::sellram( account_name account, uint64_t bytes ) { + void system_contract::sellram( account_name account, int64_t bytes ) { require_auth( account ); + eosio_assert( bytes > 0, "cannot sell negative byte" ); user_resources_table userres( _self, account ); auto res_itr = userres.find( account ); @@ -198,10 +199,10 @@ namespace eosiosystem { }); _gstate.total_ram_bytes_reserved -= bytes; - _gstate.total_ram_stake.amount -= tokens_out.amount; + _gstate.total_ram_stake -= tokens_out.amount; //// this shouldn't happen, but just in case it does we should prevent it - eosio_assert( _gstate.total_ram_stake.amount >= 0, "error, attempt to unstake more tokens than previously staked" ); + eosio_assert( _gstate.total_ram_stake >= 0, "error, attempt to unstake more tokens than previously staked" ); userres.modify( res_itr, account, [&]( auto& res ) { res.ram_bytes -= bytes; @@ -284,7 +285,6 @@ namespace eosiosystem { } else { _voters.modify( from_voter, 0, [&]( auto& v ) { v.staked += total_stake; - print( " vote weight: ", v.last_vote_weight, "\n" ); }); } diff --git a/eosio.system.abi b/eosio.system.abi index 62c15beb..f3e0bb5c 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -123,13 +123,16 @@ "base": "eosio_parameters", "fields": [ {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"asset"}, + {"name":"total_ram_stake", "type":"uint64"}, {"name":"last_producer_schedule_update", "type":"time"}, {"name":"last_pervote_bucket_fill", "type":"uint64"}, - {"name":"pervote_bucket", "type":"asset"}, - {"name":"savings", "type":"asset"}, + {"name":"pervote_bucket", "type":"int64"}, + {"name":"perblock_bucket", "type":"int64"}, + {"name":"savings", "type":"int64"}, {"name":"last_producer_schedule_id", "type":"checksum160"}, - {"name":"total_activatied_stake", "type":"int64"} + {"name":"total_activatied_stake", "type":"int64"}, + {"name":"total_producer_vote_weight", "type":"float64"}, + {"name":"total_unpaid_blocks", "type":"uint32"} ] },{ "name": "producer_info", diff --git a/eosio.system.hpp b/eosio.system.hpp index 41a10d79..4530cffb 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -29,21 +29,24 @@ namespace eosiosystem { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } uint64_t total_ram_bytes_reserved = 0; - eosio::asset total_ram_stake; + int64_t total_ram_stake; block_timestamp last_producer_schedule_update = 0; uint64_t last_pervote_bucket_fill = 0; - eosio::asset pervote_bucket; - eosio::asset savings; + int64_t pervote_bucket; + int64_t perblock_bucket; + int64_t savings; checksum160 last_producer_schedule_id; int64_t total_activated_stake = 0; + double total_producer_vote_weight = 0; /// the sum of all producer votes + int32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update) (last_pervote_bucket_fill) - (pervote_bucket)(savings)(last_producer_schedule_id)(total_activated_stake) ) + (pervote_bucket)(perblock_bucket)(savings)(last_producer_schedule_id)(total_activated_stake)(total_producer_vote_weight)(total_unpaid_blocks) ) }; struct producer_info { @@ -171,7 +174,7 @@ namespace eosiosystem { * Reduces quota my bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. */ - void sellram( account_name receiver, uint64_t bytes ); + void sellram( account_name receiver, int64_t bytes ); /** * This action is called after the delegation-period to claim all pending @@ -195,12 +198,6 @@ namespace eosiosystem { void claimrewards( const account_name& owner ); private: - eosio::asset payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ); - - eosio::asset payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ); - - eosio::asset supply_growth( double rate, const eosio::asset& token_supply, time seconds ); - void update_elected_producers( block_timestamp timestamp ); // Implementation details: diff --git a/producer_pay.cpp b/producer_pay.cpp index 9022ca03..038f9764 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -6,24 +6,16 @@ namespace eosiosystem { const int64_t min_daily_tokens = 100; - const double continuous_rate = 0.04879; // 5% annual rate - const double perblock_rate = 0.0025; // 0.25% - const double standby_rate = 0.0075; // 0.75% - const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year - const uint32_t seconds_per_year = 52*7*24*3600; - const uint32_t blocks_per_day = 2 * 24 * 3600; - const uint32_t blocks_per_hour = 2 * 3600; - const uint64_t useconds_per_day = 24 * 3600 * uint64_t(1000000); - - eosio::asset system_contract::payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ) { - const int64_t payment = static_cast( (rate * double(token_supply.amount) * double(num_blocks)) / double(blocks_per_year) ); - return eosio::asset( payment, token_supply.symbol ); - } + const double continuous_rate = 0.04879; // 5% annual rate + const double perblock_rate = 0.0025; // 0.25% + const double standby_rate = 0.0075; // 0.75% + const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year + const uint32_t seconds_per_year = 52*7*24*3600; + const uint32_t blocks_per_day = 2 * 24 * 3600; + const uint32_t blocks_per_hour = 2 * 3600; + const uint64_t useconds_per_day = 24 * 3600 * uint64_t(1000000); + const uint64_t useconds_per_year = seconds_per_year*1000000ll; - eosio::asset system_contract::supply_growth( double rate, const eosio::asset& token_supply, time seconds ) { - const int64_t payment = static_cast( (rate * double(token_supply.amount) * double(seconds)) / double(seconds_per_year) ); - return eosio::asset( payment, token_supply.symbol ); - } void system_contract::onblock( block_timestamp timestamp, account_name producer ) { using namespace eosio; @@ -37,8 +29,14 @@ namespace eosiosystem { if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses _gstate.last_pervote_bucket_fill = current_time(); + + /** + * At startup the initial producer may not be one that is registered / elected + * and therefore there may be no producer object for them. + */ auto prod = _producers.find(producer); if ( prod != _producers.end() ) { + _gstate.total_unpaid_blocks++; _producers.modify( prod, 0, [&](auto& p ) { p.produced_blocks++; p.last_produced_block_time = timestamp; @@ -49,95 +47,59 @@ namespace eosiosystem { if( timestamp - _gstate.last_producer_schedule_update > 120 ) { update_elected_producers( timestamp ); } - - } - - eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) { - eosio::asset payment(0, S(4,EOS)); - const int64_t min_daily_amount = 100 * 10000; - if ( pervote_bucket.amount < min_daily_amount ) { - return payment; - } - - auto idx = _producers.template get_index(); - - double total_producer_votes = 0; - double running_payment_amount = 0; - bool to_be_payed = false; - for ( auto itr = idx.cbegin(); itr != idx.cend(); ++itr ) { - if ( !(itr->total_votes > 0) ) { - break; - } - if ( !itr->active() ) { - continue; - } - - if ( itr->owner == owner ) { - to_be_payed = true; - } - - total_producer_votes += itr->total_votes; - running_payment_amount = (itr->total_votes) * double(pervote_bucket.amount) / total_producer_votes; - if ( running_payment_amount < min_daily_amount ) { - if ( itr->owner == owner ) { - to_be_payed = false; - } - total_producer_votes -= itr->total_votes; - break; - } - } - - if ( to_be_payed ) { - payment.amount = static_cast( (double(pervote_bucket.amount) * owners_votes) / total_producer_votes ); - } - - return payment; } + using namespace eosio; void system_contract::claimrewards( const account_name& owner ) { - using namespace eosio; - require_auth(owner); - auto prod = _producers.find( owner ); - eosio_assert( prod != _producers.end(), "account name is not in producer list" ); - eosio_assert( prod->active(), "producer does not have an active key" ); - if( prod->last_claim_time > 0 ) { - eosio_assert(current_time() >= prod->last_claim_time + useconds_per_day, "already claimed rewards within a day"); - } + const auto& prod = _producers.get( owner ); + eosio_assert( prod.active(), "producer does not have an active key" ); - const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); - const uint32_t secs_since_last_fill = static_cast( (current_time() - _gstate.last_pervote_bucket_fill) / 1000000 ); + auto ct = current_time(); - const asset to_pervote_bucket = supply_growth( standby_rate, token_supply, secs_since_last_fill ); - const asset to_savings = supply_growth( continuous_rate - (perblock_rate + standby_rate), token_supply, secs_since_last_fill ); - const asset perblock_pay = payment_per_block( perblock_rate, token_supply, prod->produced_blocks ); - const asset issue_amount = to_pervote_bucket + to_savings + perblock_pay; - - const asset pervote_pay = payment_per_vote( owner, prod->total_votes, to_pervote_bucket + _gstate.pervote_bucket ); + eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" ); - if ( perblock_pay.amount + pervote_pay.amount == 0 ) { - _producers.modify( prod, 0, [&](auto& p) { - p.last_claim_time = current_time(); - }); - return; + const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); + const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill; + + if( usecs_since_last_fill > 0 ) { + auto new_tokens = static_cast( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); + + auto to_producers = new_tokens / 5; + auto to_savings = new_tokens - to_producers; + auto to_per_block_pay = to_producers / 4; + auto to_per_vote_pay = to_producers - to_per_block_pay; + + INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, + {N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); + + _gstate.pervote_bucket += to_per_vote_pay; + _gstate.perblock_bucket += to_per_block_pay; + _gstate.savings += to_savings; + + _gstate.last_pervote_bucket_fill = ct; } - - INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - {N(eosio), issue_amount, std::string("issue tokens for producer pay and savings")} ); - _gstate.pervote_bucket += ( to_pervote_bucket - pervote_pay ); - _gstate.last_pervote_bucket_fill = current_time(); - _gstate.savings += to_savings; - - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), owner, perblock_pay + pervote_pay, std::string("producer claiming rewards") } ); + int64_t producer_per_block_pay = (_gstate.perblock_bucket * prod.produced_blocks) / _gstate.total_unpaid_blocks; + int64_t producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); + int64_t total_pay = producer_per_block_pay + producer_per_vote_pay; - _producers.modify( prod, 0, [&](auto& p) { - p.last_claim_time = current_time(); - p.produced_blocks = 0; - }); + eosio_assert( total_pay > 100'0000, "insufficient pay to claim, require at least 100.0000 EOS" ); + + _gstate.pervote_bucket -= producer_per_vote_pay; + _gstate.perblock_bucket -= producer_per_block_pay; + _gstate.total_unpaid_blocks -= prod.produced_blocks; + _producers.modify( prod, 0, [&](auto& p) { + p.last_claim_time = ct; + p.produced_blocks = 0; + }); + + if( total_pay > 0 ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), owner, asset(total_pay), std::string("producer pay") } ); + } } } //namespace eosiosystem diff --git a/voting.cpp b/voting.cpp index 99f43ecb..2456900c 100644 --- a/voting.cpp +++ b/voting.cpp @@ -50,10 +50,10 @@ namespace eosiosystem { } } else { _producers.emplace( producer, [&]( producer_info& info ){ - info.owner = producer; - info.total_votes = 0; + info.owner = producer; + info.total_votes = 0; info.producer_key = producer_key; - info.url = url; + info.url = url; }); } } @@ -172,7 +172,7 @@ namespace eosiosystem { } boost::container::flat_map > producer_deltas; - if ( voter->last_vote_weight != 0 ) { + if( voter->last_vote_weight > 0 ) { if( voter->proxy ) { auto old_proxy = _voters.find( voter->proxy ); eosio_assert( old_proxy != _voters.end(), "old proxy not found" ); //data corruption @@ -213,9 +213,8 @@ namespace eosiosystem { if( pitr != _producers.end() ) { eosio_assert( pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); _producers.modify( pitr, 0, [&]( auto& p ) { - print( "orig total_votes: ", p.total_votes, " delta: ", pd.second.first, "\n" ); p.total_votes += pd.second.first; - print( "new total_votes: ", p.total_votes, "\n" ); + _gstate.total_producer_vote_weight += pd.second.first; //eosio_assert( p.total_votes >= 0, "something bad happened" ); }); } else { @@ -269,7 +268,8 @@ namespace eosiosystem { new_weight += voter.proxied_vote_weight; } - if ( new_weight != voter.last_vote_weight ) { +#warning come up with a better way to detect change, such as delta voter.staked and/or delta time + if( new_weight != voter.last_vote_weight ) { if ( voter.proxy ) { auto& proxy = _voters.get( voter.proxy, "proxy not found" ); //data corruption _voters.modify( proxy, 0, [&]( auto& p ) { @@ -278,12 +278,13 @@ namespace eosiosystem { ); propagate_weight_change( proxy ); } else { + auto delta = new_weight - voter.last_vote_weight; for ( auto acnt : voter.producers ) { auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption _producers.modify( pitr, 0, [&]( auto& p ) { - p.total_votes += new_weight - voter.last_vote_weight; - } - ); + p.total_votes += delta; + _gstate.total_producer_vote_weight += delta; + }); } } } From 1138425ff0b406a0654ae4b29b034a50acf4f83f Mon Sep 17 00:00:00 2001 From: Brian Johnson Date: Fri, 11 May 2018 07:19:07 -0500 Subject: [PATCH 0241/1048] Force account names to be exactly 12 chars and contain no dots. GH #2660 --- delegate_bandwidth.cpp | 13 ++++++++----- native.hpp | 7 +++---- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 8ddfa22c..d9c1580a 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -93,13 +93,16 @@ namespace eosiosystem { * an amount equal to the current new account creation fee. */ void native::newaccount( account_name creator, - account_name newact - /* no need to parse authorites - const authority& owner, - const authority& active, - const authority& recovery*/ ) { + account_name newact + /* no need to parse authorites + const authority& owner, + const authority& active*/ ) { + auto name_str = eosio::name{newact}.to_string(); eosio::print( eosio::name{creator}, " created ", eosio::name{newact}, "\n"); + eosio_assert( name_str.size() == 12, "account names must be 12 chars long" ); + eosio_assert( name_str.find_first_of('.') == std::string::npos, "account names cannot contain '.' character"); + user_resources_table userres( _self, newact); userres.emplace( newact, [&]( auto& res ) { diff --git a/native.hpp b/native.hpp index 18c89cdc..3a9bed79 100644 --- a/native.hpp +++ b/native.hpp @@ -83,10 +83,9 @@ namespace eosiosystem { */ void newaccount( account_name creator, account_name newact - /* no need to parse authorites - const authority& owner, - const authority& active, - const authority& recovery*/ ); + /* no need to parse authorites + const authority& owner, + const authority& active*/ ); void updateauth( /*account_name account, From 7e041a5e1f443971807fb5551015e73ea384c18d Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 14 May 2018 17:10:43 -0400 Subject: [PATCH 0242/1048] Fix for eos #2890 --- eosio.system.abi | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 62c15beb..d844c689 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -80,7 +80,7 @@ "base": "", "fields": [ {"name":"owner", "type":"account_name"}, - {"name":"request_time", "type":"time"}, + {"name":"request_time", "type":"time_point_sec"}, {"name":"amount", "type":"uint64"} ] },{ @@ -124,7 +124,7 @@ "fields": [ {"name":"total_ram_bytes_reserved", "type":"uint64"}, {"name":"total_ram_stake", "type":"asset"}, - {"name":"last_producer_schedule_update", "type":"time"}, + {"name":"last_producer_schedule_update", "type":"time_point_sec"}, {"name":"last_pervote_bucket_fill", "type":"uint64"}, {"name":"pervote_bucket", "type":"asset"}, {"name":"savings", "type":"asset"}, @@ -192,7 +192,7 @@ {"name":"proxied_vote_weight", "type":"float64"}, {"name":"is_proxy", "type":"bool"}, {"name":"deferred_trx_id", "type":"uint32"}, - {"name":"last_unstake_time", "type":"time"}, + {"name":"last_unstake_time", "type":"time_point_sec"}, {"name":"unstaking", "type":"asset"} ] },{ From 2f379d48832c73cbad3f93853d5e3a2d863c5e50 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 14 May 2018 19:25:22 -0400 Subject: [PATCH 0243/1048] Fixed abi issues, part of producer pay tests --- eosio.system.abi | 48 ++++++++++++++++++++++++------------------------ eosio.system.hpp | 8 ++++---- producer_pay.cpp | 2 +- 3 files changed, 29 insertions(+), 29 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index f3e0bb5c..40682d42 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -87,30 +87,30 @@ "name": "blockchain_parameters", "base": "", "fields": [ - {"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":"max_block_net_usage", "type":"uint64"}, + {"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": "uint64"}, - {"name":"target_block_cpu_usage_pct", "type": "uint32"}, - {"name":"max_transaction_cpu_usage", "type":"uint32"}, - {"name":"base_per_transaction_cpu_usage", "type":"uint32"}, - {"name":"base_per_action_cpu_usage", "type":"uint32"}, - {"name":"base_setcode_cpu_usage", "type":"uint32"}, - {"name":"per_signature_cpu_usage", "type":"uint32"}, - {"name":"cpu_usage_leeway", "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":"base_per_transaction_cpu_usage", "type":"uint32"}, + {"name":"base_per_action_cpu_usage", "type":"uint32"}, + {"name":"base_setcode_cpu_usage", "type":"uint32"}, + {"name":"per_signature_cpu_usage", "type":"uint32"}, + {"name":"cpu_usage_leeway", "type":"uint32"}, {"name":"context_free_discount_cpu_usage_num", "type":"uint32"}, {"name":"context_free_discount_cpu_usage_den", "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":"uint32"}, - {"name":"max_inline_action_depth", "type":"uint16"}, - {"name":"max_authority_depth", "type":"uint16"}, - {"name":"max_generated_transaction_count", "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":"uint32"}, + {"name":"max_inline_action_depth", "type":"uint16"}, + {"name":"max_authority_depth", "type":"uint16"}, + {"name":"max_generated_transaction_count", "type":"uint32"} ] },{ "name": "eosio_parameters", @@ -123,16 +123,16 @@ "base": "eosio_parameters", "fields": [ {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"uint64"}, + {"name":"total_ram_stake", "type":"int64"}, {"name":"last_producer_schedule_update", "type":"time"}, {"name":"last_pervote_bucket_fill", "type":"uint64"}, {"name":"pervote_bucket", "type":"int64"}, {"name":"perblock_bucket", "type":"int64"}, {"name":"savings", "type":"int64"}, - {"name":"last_producer_schedule_id", "type":"checksum160"}, - {"name":"total_activatied_stake", "type":"int64"}, - {"name":"total_producer_vote_weight", "type":"float64"}, {"name":"total_unpaid_blocks", "type":"uint32"} + {"name":"total_activated_stake", "type":"int64"}, + {"name":"last_producer_schedule_id", "type":"checksum160"}, + {"name":"total_producer_vote_weight", "type":"float64"} ] },{ "name": "producer_info", diff --git a/eosio.system.hpp b/eosio.system.hpp index 4530cffb..34ed8ca0 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -36,17 +36,17 @@ namespace eosiosystem { int64_t pervote_bucket; int64_t perblock_bucket; int64_t savings; - checksum160 last_producer_schedule_id; - + uint32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid int64_t total_activated_stake = 0; + checksum160 last_producer_schedule_id; double total_producer_vote_weight = 0; /// the sum of all producer votes - int32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid + // checksum160 last_producer_schedule_id; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update) (last_pervote_bucket_fill) - (pervote_bucket)(perblock_bucket)(savings)(last_producer_schedule_id)(total_activated_stake)(total_producer_vote_weight)(total_unpaid_blocks) ) + (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(last_producer_schedule_id)(total_producer_vote_weight) ) }; struct producer_info { diff --git a/producer_pay.cpp b/producer_pay.cpp index 038f9764..1a2dbd67 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -85,7 +85,7 @@ namespace eosiosystem { int64_t producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); int64_t total_pay = producer_per_block_pay + producer_per_vote_pay; - eosio_assert( total_pay > 100'0000, "insufficient pay to claim, require at least 100.0000 EOS" ); + eosio_assert( total_pay > 1000000 /* 100'0000 */, "insufficient pay to claim, require at least 100.0000 EOS" ); _gstate.pervote_bucket -= producer_per_vote_pay; _gstate.perblock_bucket -= producer_per_block_pay; From b9f3311ab0b81f84472de99c871fa4f95b75125d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 14 May 2018 22:50:46 -0400 Subject: [PATCH 0244/1048] Fixed producer_pay test, limited daily pay threshold to pervote --- producer_pay.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 1a2dbd67..aa338ee0 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -83,10 +83,11 @@ namespace eosiosystem { int64_t producer_per_block_pay = (_gstate.perblock_bucket * prod.produced_blocks) / _gstate.total_unpaid_blocks; int64_t producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); + if( producer_per_vote_pay < 100'0000 ) { + producer_per_vote_pay = 0; + } int64_t total_pay = producer_per_block_pay + producer_per_vote_pay; - eosio_assert( total_pay > 1000000 /* 100'0000 */, "insufficient pay to claim, require at least 100.0000 EOS" ); - _gstate.pervote_bucket -= producer_per_vote_pay; _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.produced_blocks; From 46d052d1cd082c5ef7ce0b5fdd387360df8178c7 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 15 May 2018 13:31:13 -0400 Subject: [PATCH 0245/1048] remove unneeded configuration parameters #2960 Also reduce default_max_transaction_cpu_usage to half of default_max_block_cpu_usage. --- eosio.system.abi | 7 ------- 1 file changed, 7 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index d844c689..4f847adf 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -97,13 +97,6 @@ {"name":"max_block_cpu_usage", "type": "uint64"}, {"name":"target_block_cpu_usage_pct", "type": "uint32"}, {"name":"max_transaction_cpu_usage", "type":"uint32"}, - {"name":"base_per_transaction_cpu_usage", "type":"uint32"}, - {"name":"base_per_action_cpu_usage", "type":"uint32"}, - {"name":"base_setcode_cpu_usage", "type":"uint32"}, - {"name":"per_signature_cpu_usage", "type":"uint32"}, - {"name":"cpu_usage_leeway", "type":"uint32"}, - {"name":"context_free_discount_cpu_usage_num", "type":"uint32"}, - {"name":"context_free_discount_cpu_usage_den", "type":"uint32"}, {"name":"max_transaction_lifetime", "type":"uint32"}, {"name":"deferred_trx_expiration_window", "type":"uint32"}, {"name":"max_transaction_delay", "type":"uint32"}, From 6be20f3dad453a9657214849ddaef0e02c0d2130 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 15 May 2018 15:39:08 -0400 Subject: [PATCH 0246/1048] Implement regproducer::location to Fix #3090 --- eosio.system.abi | 1 + eosio.system.hpp | 2 +- voting.cpp | 14 ++++++++------ 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index d844c689..bc57f417 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -152,6 +152,7 @@ {"name":"producer", "type":"account_name"}, {"name":"producer_key", "type":"public_key"}, {"name":"url", "type":"string"} + {"name":"location", "type":"uint16"} ] },{ "name": "unregprod", diff --git a/eosio.system.hpp b/eosio.system.hpp index 41a10d79..d622c9b7 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -181,7 +181,7 @@ namespace eosiosystem { // functions defined in voting.cpp - void regproducer( const account_name producer, const public_key& producer_key, const std::string& url ); + void regproducer( const account_name producer, const public_key& producer_key, const std::string& url, uint16_t location ); void unregprod( const account_name producer ); diff --git a/voting.cpp b/voting.cpp index 99f43ecb..274a8fc1 100644 --- a/voting.cpp +++ b/voting.cpp @@ -34,7 +34,7 @@ namespace eosiosystem { * @pre authority of producer to register * */ - void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url ) { //, const eosio_parameters& prefs ) { + void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { eosio_assert( url.size() < 512, "url too long" ); //eosio::print("produce_key: ", producer_key.size(), ", sizeof(public_key): ", sizeof(public_key), "\n"); require_auth( producer ); @@ -45,15 +45,17 @@ namespace eosiosystem { if( producer_key != prod->producer_key ) { _producers.modify( prod, producer, [&]( producer_info& info ){ info.producer_key = producer_key; - info.url = url; + info.url = url; + info.location = location; }); } } else { _producers.emplace( producer, [&]( producer_info& info ){ - info.owner = producer; - info.total_votes = 0; - info.producer_key = producer_key; - info.url = url; + info.owner = producer; + info.total_votes = 0; + info.producer_key = producer_key; + info.url = url; + info.location = location; }); } } From 182b86c3aa400cf5b13438896bcd28229c6c4641 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 15 May 2018 15:40:14 -0400 Subject: [PATCH 0247/1048] Fix abi for regproducer, added comma, Fix #3090 --- eosio.system.abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index bc57f417..18032d09 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -151,7 +151,7 @@ "fields": [ {"name":"producer", "type":"account_name"}, {"name":"producer_key", "type":"public_key"}, - {"name":"url", "type":"string"} + {"name":"url", "type":"string"}, {"name":"location", "type":"uint16"} ] },{ From 46cdf187c69d1050dbaa11fb7cda264f85094ec0 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 15 May 2018 15:46:29 -0400 Subject: [PATCH 0248/1048] make min_transaction_cpu_usage into a consensus parameter #2960 --- eosio.system.abi | 1 + 1 file changed, 1 insertion(+) diff --git a/eosio.system.abi b/eosio.system.abi index 4f847adf..983b1fc9 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -97,6 +97,7 @@ {"name":"max_block_cpu_usage", "type": "uint64"}, {"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"}, From 93e637fd0f1d09089d82724013d5786e4f655631 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 15 May 2018 17:16:11 -0400 Subject: [PATCH 0249/1048] Fixed producer pay tests, used longer names for producers and voters --- eosio.system.hpp | 9 ++++----- producer_pay.cpp | 2 +- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 34ed8ca0..912fa070 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -33,14 +33,13 @@ namespace eosiosystem { block_timestamp last_producer_schedule_update = 0; uint64_t last_pervote_bucket_fill = 0; - int64_t pervote_bucket; - int64_t perblock_bucket; - int64_t savings; + int64_t pervote_bucket = 0; + int64_t perblock_bucket = 0; + int64_t savings = 0; uint32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid int64_t total_activated_stake = 0; - checksum160 last_producer_schedule_id; + checksum160 last_producer_schedule_id; double total_producer_vote_weight = 0; /// the sum of all producer votes - // checksum160 last_producer_schedule_id; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) diff --git a/producer_pay.cpp b/producer_pay.cpp index aa338ee0..69e03734 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -86,7 +86,7 @@ namespace eosiosystem { if( producer_per_vote_pay < 100'0000 ) { producer_per_vote_pay = 0; } - int64_t total_pay = producer_per_block_pay + producer_per_vote_pay; + int64_t total_pay = producer_per_block_pay + producer_per_vote_pay; _gstate.pervote_bucket -= producer_per_vote_pay; _gstate.perblock_bucket -= producer_per_block_pay; From 574397dc01e71271dcb81f0586955f3e00be19b5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 15 May 2018 18:37:59 -0400 Subject: [PATCH 0250/1048] Fixed merge issues --- eosio.system.abi | 2 +- eosio.system.hpp | 10 ++++++---- producer_pay.cpp | 2 +- voting.cpp | 8 ++++---- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 4a99da66..b133e310 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -123,7 +123,7 @@ "base": "eosio_parameters", "fields": [ {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"asset"}, + {"name":"total_ram_stake", "type":"int64"}, {"name":"last_producer_schedule_update", "type":"time_point_sec"}, {"name":"last_pervote_bucket_fill", "type":"uint64"}, {"name":"pervote_bucket", "type":"int64"}, diff --git a/eosio.system.hpp b/eosio.system.hpp index fb5cb9c0..f232e091 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -17,6 +18,7 @@ namespace eosiosystem { using eosio::asset; using eosio::indexed_by; using eosio::const_mem_fun; + using eosio::block_timestamp; struct eosio_parameters : eosio::blockchain_parameters { uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; @@ -31,7 +33,7 @@ namespace eosiosystem { uint64_t total_ram_bytes_reserved = 0; int64_t total_ram_stake; - block_timestamp last_producer_schedule_update = 0; + block_timestamp last_producer_schedule_update; uint64_t last_pervote_bucket_fill = 0; int64_t pervote_bucket = 0; int64_t perblock_bucket = 0; @@ -56,8 +58,8 @@ namespace eosiosystem { uint32_t produced_blocks; uint64_t last_claim_time = 0; uint16_t location = 0; - block_timestamp time_became_active = 0; - block_timestamp last_produced_block_time = 0; + block_timestamp time_became_active; + block_timestamp last_produced_block_time; uint64_t primary_key()const { return owner; } double by_votes()const { return -total_votes; } @@ -127,7 +129,7 @@ namespace eosiosystem { ~system_contract(); // Actions: - void onblock( uint32_t timestamp_slot, account_name producer ); + void onblock( block_timestamp timestamp, account_name producer ); // const block_header& header ); /// only parse first 3 fields of block header // functions defined in delegate_bandwidth.cpp diff --git a/producer_pay.cpp b/producer_pay.cpp index 69e03734..094f5658 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -44,7 +44,7 @@ namespace eosiosystem { } /// only update block producers once every minute, block_timestamp is in half seconds - if( timestamp - _gstate.last_producer_schedule_update > 120 ) { + if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) { update_elected_producers( timestamp ); } } diff --git a/voting.cpp b/voting.cpp index c2600be4..ddb13c7e 100644 --- a/voting.cpp +++ b/voting.cpp @@ -81,15 +81,15 @@ namespace eosiosystem { for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) { if( !it->active() ) continue; - if ( it->time_became_active == 0 ) { + if ( it->time_became_active.slot == 0 ) { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); - } else if ( block_time > 2 * 21 * 12 + it->time_became_active && - block_time > it->last_produced_block_time + blocks_per_day ) { + } else if ( block_time.slot > 2 * 21 * 12 + it->time_became_active.slot && + block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) { _producers.modify( *it, 0, [&](auto& p) { p.producer_key = public_key(); - p.time_became_active = 0; + p.time_became_active.slot = 0; }); continue; From 8b0d99f8ae73d0e20a3740b10e01fa3d17b3e1f5 Mon Sep 17 00:00:00 2001 From: zorba80 <35532164+zorba80@users.noreply.github.com> Date: Tue, 15 May 2018 18:58:57 -0400 Subject: [PATCH 0251/1048] Added missing comma to eosio.system.abi --- eosio.system.abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index b133e310..173c546b 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -129,7 +129,7 @@ {"name":"pervote_bucket", "type":"int64"}, {"name":"perblock_bucket", "type":"int64"}, {"name":"savings", "type":"int64"}, - {"name":"total_unpaid_blocks", "type":"uint32"} + {"name":"total_unpaid_blocks", "type":"uint32"}, {"name":"total_activated_stake", "type":"int64"}, {"name":"last_producer_schedule_id", "type":"checksum160"}, {"name":"total_producer_vote_weight", "type":"float64"} From a356e591cdc28d5262704072d747b68552adc740 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 16 May 2018 08:31:57 -0400 Subject: [PATCH 0252/1048] Free RAM on undelegate bandwidth Fix #3107 - fix warnings in eosiolib - remove debug print statements from contracts - erase the delegate_bw object (didn't actually remove voter info object) - remove user balance object from token contract when balance goes to 0 --- delegate_bandwidth.cpp | 34 +++++++++++++++++----------------- voting.cpp | 8 +++++--- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index d9c1580a..1312593f 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -139,7 +139,7 @@ namespace eosiosystem { */ void system_contract::buyram( account_name payer, account_name receiver, asset quant ) { - print( "\n payer: ", eosio::name{payer}, " buys ram for ", eosio::name{receiver}, " with ", quant, "\n" ); + // print( "\n payer: ", eosio::name{payer}, " buys ram for ", eosio::name{receiver}, " with ", quant, "\n" ); require_auth( payer ); eosio_assert( quant.amount > 0, "must purchase a positive amount" ); @@ -148,7 +148,7 @@ namespace eosiosystem { { payer, N(eosio), quant, std::string("buy ram") } ); } - print( "free ram: ", _gstate.free_ram(), "\n"); + // print( "free ram: ", _gstate.free_ram(), "\n"); int64_t bytes_out; @@ -157,7 +157,7 @@ namespace eosiosystem { bytes_out = es.convert( quant, S(0,RAM) ).amount; }); - print( "ram bytes out: ", bytes_out, "\n" ); + // print( "ram bytes out: ", bytes_out, "\n" ); eosio_assert( bytes_out > 0, "must reserve a positive amount" ); @@ -187,17 +187,19 @@ namespace eosiosystem { */ void system_contract::sellram( account_name account, uint64_t bytes ) { require_auth( account ); + int64_t ibytes = static_cast(bytes); user_resources_table userres( _self, account ); auto res_itr = userres.find( account ); eosio_assert( res_itr != userres.end(), "no resource row" ); - eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); + eosio_assert( res_itr->ram_bytes >= ibytes, "insufficient quota" ); asset tokens_out; auto itr = _rammarket.find(S(4,RAMEOS)); _rammarket.modify( itr, 0, [&]( auto& es ) { - tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); - print( "out: ", tokens_out, "\n" ); + /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases + tokens_out = es.convert( asset(ibytes,S(0,RAM)), S(4,EOS) ); + // print( "out: ", tokens_out, "\n" ); }); _gstate.total_ram_bytes_reserved -= bytes; @@ -223,7 +225,7 @@ namespace eosiosystem { { require_auth( from ); - print( "from: ", eosio::name{from}, " to: ", eosio::name{receiver}, " net: ", stake_net_quantity, " cpu: ", stake_cpu_quantity ); + // print( "from: ", eosio::name{from}, " to: ", eosio::name{receiver}, " net: ", stake_net_quantity, " cpu: ", stake_cpu_quantity ); eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); @@ -252,7 +254,6 @@ namespace eosiosystem { }); } - print( "totals" ); user_resources_table totals_tbl( _self, receiver ); auto tot_itr = totals_tbl.find( receiver ); if( tot_itr == totals_tbl.end() ) { @@ -275,23 +276,18 @@ namespace eosiosystem { { source_stake_from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); } - print( "voters \n" ); auto from_voter = _voters.find(from); if( from_voter == _voters.end() ) { - print( " create voter \n" ); from_voter = _voters.emplace( from, [&]( auto& v ) { v.owner = from; v.staked = total_stake; - print( " vote weight: ", v.last_vote_weight, "\n" ); }); } else { _voters.modify( from_voter, 0, [&]( auto& v ) { v.staked += total_stake; - print( " vote weight: ", v.last_vote_weight, "\n" ); }); } - print( "voteproducer\n" ); if( from_voter->producers.size() || from_voter->proxy ) { voteproducer( from, from_voter->proxy, from_voter->producers ); } @@ -332,10 +328,14 @@ namespace eosiosystem { eosio_assert( total_refund > 0, "must unstake a positive amount" ); - del_tbl.modify( dbw, from, [&]( auto& dbo ){ - dbo.net_weight -= unstake_net_quantity; - dbo.cpu_weight -= unstake_cpu_quantity; - }); + if( dbw.net_weight == unstake_net_quantity && dbw.cpu_weight == unstake_cpu_quantity ) { + del_tbl.erase( dbw ); + } else { + del_tbl.modify( dbw, from, [&]( auto& dbo ){ + dbo.net_weight -= unstake_net_quantity; + dbo.cpu_weight -= unstake_cpu_quantity; + }); + } user_resources_table totals_tbl( _self, receiver ); diff --git a/voting.cpp b/voting.cpp index 274a8fc1..32b2f9d2 100644 --- a/voting.cpp +++ b/voting.cpp @@ -121,7 +121,8 @@ namespace eosiosystem { } double stake2vote( int64_t staked ) { - double weight = int64_t(now() / (seconds_per_day * 7)) / double( 52 ); + /// TODO subtract 2080 brings the large numbers closer to this decade + double weight = int64_t( (now() / (seconds_per_day * 7)) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } /** @@ -174,7 +175,7 @@ namespace eosiosystem { } boost::container::flat_map > producer_deltas; - if ( voter->last_vote_weight != 0 ) { + if ( voter->last_vote_weight > 0 ) { if( voter->proxy ) { auto old_proxy = _voters.find( voter->proxy ); eosio_assert( old_proxy != _voters.end(), "old proxy not found" ); //data corruption @@ -271,7 +272,8 @@ namespace eosiosystem { new_weight += voter.proxied_vote_weight; } - if ( new_weight != voter.last_vote_weight ) { + /// don't propagate small changes (1 ~= epsilon) + if ( fabs( new_weight - voter.last_vote_weight ) > 1 ) { if ( voter.proxy ) { auto& proxy = _voters.get( voter.proxy, "proxy not found" ); //data corruption _voters.modify( proxy, 0, [&]( auto& p ) { From 58b96399293ced39a1667eac1f3ac0c5291c8b81 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 16 May 2018 10:32:42 -0400 Subject: [PATCH 0253/1048] Fixed merge error --- delegate_bandwidth.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 7dcfa5c6..e7f405bc 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -187,18 +187,18 @@ namespace eosiosystem { */ void system_contract::sellram( account_name account, int64_t bytes ) { require_auth( account ); - int64_t ibytes = static_cast(bytes); + eosio_assert( bytes > 0, "cannot sell negative byte" ); user_resources_table userres( _self, account ); auto res_itr = userres.find( account ); eosio_assert( res_itr != userres.end(), "no resource row" ); - eosio_assert( res_itr->ram_bytes >= ibytes, "insufficient quota" ); + eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; auto itr = _rammarket.find(S(4,RAMEOS)); _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(ibytes,S(0,RAM)), S(4,EOS) ); + tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); // print( "out: ", tokens_out, "\n" ); }); From aaff5d324272d733677913b6342e288478e0fece Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 16 May 2018 11:16:29 -0400 Subject: [PATCH 0254/1048] Fixed abi mismatch --- eosio.system.abi | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 60c7879d..7db26217 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -87,6 +87,7 @@ "name": "blockchain_parameters", "base": "", "fields": [ + {"name":"max_block_net_usage", "type":"uint64"}, {"name":"target_block_net_usage_pct", "type":"uint32"}, {"name":"max_transaction_net_usage", "type":"uint32"}, @@ -97,13 +98,7 @@ {"name":"max_block_cpu_usage", "type":"uint32"}, {"name":"target_block_cpu_usage_pct", "type":"uint32"}, {"name":"max_transaction_cpu_usage", "type":"uint32"}, - {"name":"base_per_transaction_cpu_usage", "type":"uint32"}, - {"name":"base_per_action_cpu_usage", "type":"uint32"}, - {"name":"base_setcode_cpu_usage", "type":"uint32"}, - {"name":"per_signature_cpu_usage", "type":"uint32"}, - {"name":"cpu_usage_leeway", "type":"uint32"}, - {"name":"context_free_discount_cpu_usage_num", "type":"uint32"}, - {"name":"context_free_discount_cpu_usage_den", "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"}, From 910000d6186b0d1efe4f12481d5bbefbc0dda022 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 16 May 2018 11:51:38 -0400 Subject: [PATCH 0255/1048] setpriv action in system contract #1962 --- eosio.system.abi | 13 ++++++++++++- eosio.system.cpp | 8 +++++++- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 6957d6f3..a5b50818 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -196,7 +196,14 @@ "fields": [ {"name":"owner", "type":"account_name"} ] - } + },{ + "name": "setpriv", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"is_priv", "type":"int8"} + ] + } ], "actions": [ { @@ -247,6 +254,10 @@ "name": "claimrewards", "type": "claimrewards", "ricardian_contract": "" + },{ + "name": "setpriv", + "type": "setpriv", + "ricardian_contract": "" } ], "tables": [{ diff --git a/eosio.system.cpp b/eosio.system.cpp index a24d0bf1..7ca481ce 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -72,6 +72,11 @@ namespace eosiosystem { _global.set( _gstate, _self ); } + void system_contract::setpriv( account_name account, uint8_t ispriv ) { + require_auth( _self ); + set_privileged( account, ispriv ); + } + } /// eosio.system @@ -85,7 +90,8 @@ EOSIO_ABI( eosiosystem::system_contract, (regproxy)(regproducer)(unregprod)(voteproducer) (claimrewards) // native.hpp - //XXX (onblock) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) + //this file + (setpriv) ) From 181d8c7dd09cf684c4add28a438477c236478ac6 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 16 May 2018 11:58:00 -0400 Subject: [PATCH 0256/1048] Renamed produced_blocks to unpaid_blocks --- eosio.system.abi | 2 +- eosio.system.hpp | 6 +++--- producer_pay.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 7db26217..1f4da6e6 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -138,7 +138,7 @@ {"name":"total_votes", "type":"float64"}, {"name":"producer_key", "type":"public_key"}, {"name":"url", "type":"string"}, - {"name":"produced_blocks", "type":"uint32"}, + {"name":"unpaid_blocks", "type":"uint32"}, {"name":"last_claim_time", "type":"uint64"}, {"name":"location", "type":"uint16"}, {"name":"time_became_active", "type":"uint32"}, diff --git a/eosio.system.hpp b/eosio.system.hpp index f232e091..57db6c6e 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -31,7 +31,7 @@ namespace eosiosystem { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } uint64_t total_ram_bytes_reserved = 0; - int64_t total_ram_stake; + int64_t total_ram_stake = 0; block_timestamp last_producer_schedule_update; uint64_t last_pervote_bucket_fill = 0; @@ -55,7 +55,7 @@ namespace eosiosystem { double total_votes = 0; eosio::public_key producer_key; /// a packed public key object std::string url; - uint32_t produced_blocks; + uint32_t unpaid_blocks = 0; uint64_t last_claim_time = 0; uint16_t location = 0; block_timestamp time_became_active; @@ -67,7 +67,7 @@ namespace eosiosystem { // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(url) - (produced_blocks)(last_claim_time)(location) + (unpaid_blocks)(last_claim_time)(location) (time_became_active)(last_produced_block_time) ) }; diff --git a/producer_pay.cpp b/producer_pay.cpp index 094f5658..c69bf84d 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -38,7 +38,7 @@ namespace eosiosystem { if ( prod != _producers.end() ) { _gstate.total_unpaid_blocks++; _producers.modify( prod, 0, [&](auto& p ) { - p.produced_blocks++; + p.unpaid_blocks++; p.last_produced_block_time = timestamp; }); } @@ -81,7 +81,7 @@ namespace eosiosystem { _gstate.last_pervote_bucket_fill = ct; } - int64_t producer_per_block_pay = (_gstate.perblock_bucket * prod.produced_blocks) / _gstate.total_unpaid_blocks; + int64_t producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; int64_t producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); if( producer_per_vote_pay < 100'0000 ) { producer_per_vote_pay = 0; @@ -90,11 +90,11 @@ namespace eosiosystem { _gstate.pervote_bucket -= producer_per_vote_pay; _gstate.perblock_bucket -= producer_per_block_pay; - _gstate.total_unpaid_blocks -= prod.produced_blocks; + _gstate.total_unpaid_blocks -= prod.unpaid_blocks; _producers.modify( prod, 0, [&](auto& p) { p.last_claim_time = ct; - p.produced_blocks = 0; + p.unpaid_blocks = 0; }); if( total_pay > 0 ) { From 9a8477026a09ee000f3bb2c8e64fc7afb8a5a5d0 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 16 May 2018 13:59:09 -0400 Subject: [PATCH 0257/1048] setpriv action in system contract (missing file) #1962 --- eosio.system.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eosio.system.hpp b/eosio.system.hpp index d622c9b7..8bf9a87a 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -194,6 +194,8 @@ namespace eosiosystem { // functions defined in producer_pay.cpp void claimrewards( const account_name& owner ); + void setpriv( account_name account, uint8_t ispriv ); + private: eosio::asset payment_per_block( double rate, const eosio::asset& token_supply, uint32_t num_blocks ); From 97cb7958db31ae63d45dac2f52426e9fb81478f0 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 16 May 2018 14:37:16 -0400 Subject: [PATCH 0258/1048] allow eosio to create accounts with names shorter than 12 symbols #3136 --- delegate_bandwidth.cpp | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index e7f405bc..9e462b15 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -98,10 +98,9 @@ namespace eosiosystem { const authority& owner, const authority& active*/ ) { auto name_str = eosio::name{newact}.to_string(); - eosio::print( eosio::name{creator}, " created ", eosio::name{newact}, "\n"); - eosio_assert( name_str.size() == 12, "account names must be 12 chars long" ); - eosio_assert( name_str.find_first_of('.') == std::string::npos, "account names cannot contain '.' character"); + eosio_assert( name_str.size() == 12 || creator == N(eosio), "account names must be 12 chars long" ); + eosio_assert( name_str.find_first_of('.') == std::string::npos || creator == N(eosio), "account names cannot contain '.' character"); user_resources_table userres( _self, newact); @@ -123,7 +122,6 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMEOS)); auto tmp = *itr; auto eosout = tmp.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); - print( "eosout: ", eosout, " ", tmp.base.balance, " ", tmp.quote.balance, "\n" ); buyram( payer, receiver, eosout ); } @@ -139,7 +137,6 @@ namespace eosiosystem { */ void system_contract::buyram( account_name payer, account_name receiver, asset quant ) { - // print( "\n payer: ", eosio::name{payer}, " buys ram for ", eosio::name{receiver}, " with ", quant, "\n" ); require_auth( payer ); eosio_assert( quant.amount > 0, "must purchase a positive amount" ); @@ -148,7 +145,6 @@ namespace eosiosystem { { payer, N(eosio), quant, std::string("buy ram") } ); } - // print( "free ram: ", _gstate.free_ram(), "\n"); int64_t bytes_out; @@ -157,7 +153,6 @@ namespace eosiosystem { bytes_out = es.convert( quant, S(0,RAM) ).amount; }); - // print( "ram bytes out: ", bytes_out, "\n" ); eosio_assert( bytes_out > 0, "must reserve a positive amount" ); @@ -199,7 +194,6 @@ namespace eosiosystem { _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); - // print( "out: ", tokens_out, "\n" ); }); _gstate.total_ram_bytes_reserved -= bytes; @@ -225,7 +219,6 @@ namespace eosiosystem { { require_auth( from ); - // print( "from: ", eosio::name{from}, " to: ", eosio::name{receiver}, " net: ", stake_net_quantity, " cpu: ", stake_cpu_quantity ); eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); From bcbacb0d13fe73124d2eb79a9e7f32cd75187e15 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 16 May 2018 22:30:29 -0400 Subject: [PATCH 0259/1048] setabi treats abi as a blob of data; cleanup builtin abi types #3095 Also added a version and extensions field to abi_def. --- eosio.system.abi | 202 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 181 insertions(+), 21 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 6957d6f3..8e3828cb 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -1,6 +1,131 @@ { - "types": [], - "structs": [{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + },{ + "new_type_name": "transaction_id_type", + "type": "checksum256" + },{ + "new_type_name": "weight_type", + "type": "uint16" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name":"actor", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "key_weight", + "base": "", + "fields": [ + {"name":"key", "type":"public_key"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "permission_level_weight", + "base": "", + "fields": [ + {"name":"permission", "type":"permission_level"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "wait_weight", + "base": "", + "fields": [ + {"name":"wait_sec", "type":"uint32"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "authority", + "base": "", + "fields": [ + {"name":"threshold", "type":"uint32"}, + {"name":"keys", "type":"key_weight[]"}, + {"name":"accounts", "type":"permission_level_weight[]"}, + {"name":"waits", "type":"wait_weight[]"} + ] + },{ + "name": "newaccount", + "base": "", + "fields": [ + {"name":"creator", "type":"account_name"}, + {"name":"name", "type":"account_name"}, + {"name":"owner", "type":"authority"}, + {"name":"active", "type":"authority"} + ] + },{ + "name": "setcode", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"vmtype", "type":"uint8"}, + {"name":"vmversion", "type":"uint8"}, + {"name":"code", "type":"bytes"} + ] + },{ + "name": "setabi", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"abi", "type":"bytes"} + ] + },{ + "name": "updateauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"}, + {"name":"parent", "type":"permission_name"}, + {"name":"auth", "type":"authority"} + ] + },{ + "name": "deleteauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "linkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"}, + {"name":"requirement", "type":"permission_name"} + ] + },{ + "name": "unlinkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"} + ] + },{ + "name": "canceldelay", + "base": "", + "fields": [ + {"name":"canceling_auth", "type":"permission_level"}, + {"name":"trx_id", "type":"transaction_id_type"} + ] + },{ + "name": "onerror", + "base": "", + "fields": [ + {"name":"sender_id", "type":"uint128"}, + {"name":"sent_trx", "type":"bytes"} + ] + },{ "name": "buyrambytes", "base": "", "fields": [ @@ -197,59 +322,93 @@ {"name":"owner", "type":"account_name"} ] } - ], - "actions": [ - { + ], + "actions": [{ + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + },{ + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + },{ + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + },{ + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + },{ + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + },{ + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + },{ + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + },{ + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + },{ + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + },{ "name": "buyrambytes", "type": "buyrambytes", "ricardian_contract": "" - },{ + },{ "name": "buyram", "type": "buyram", "ricardian_contract": "" - },{ + },{ "name": "sellram", "type": "sellram", "ricardian_contract": "" - },{ + },{ "name": "delegatebw", "type": "delegatebw", "ricardian_contract": "" - },{ + },{ "name": "undelegatebw", "type": "undelegatebw", "ricardian_contract": "" - },{ + },{ "name": "refund", "type": "refund", "ricardian_contract": "" - },{ + },{ "name": "regproducer", "type": "regproducer", "ricardian_contract": "" - },{ + },{ "name": "setram", "type": "setram", "ricardian_contract": "" - },{ + },{ "name": "unregprod", "type": "unregprod", "ricardian_contract": "" - },{ + },{ "name": "regproxy", "type": "regproxy", "ricardian_contract": "" - },{ + },{ "name": "voteproducer", "type": "voteproducer", "ricardian_contract": "" - },{ + },{ "name": "claimrewards", "type": "claimrewards", "ricardian_contract": "" - } - ], - "tables": [{ + }], + "tables": [{ "name": "producers", "type": "producer_info", "index_type": "i64", @@ -292,6 +451,7 @@ "key_names" : ["owner"], "key_types" : ["uint64"] } - ], - "ricardian_clauses": [] + ], + "ricardian_clauses": [], + "abi_extensions": [] } From 4d0a46f11acb12407934ada8327681b70328cd84 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 17 May 2018 17:28:33 -0400 Subject: [PATCH 0260/1048] delegate bandwidth refacroting, allow to return pending refund to stake #3180 --- delegate_bandwidth.cpp | 273 +++++++++++++++++++++-------------------- eosio.system.hpp | 3 + 2 files changed, 144 insertions(+), 132 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 9e462b15..6cffa61d 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -213,80 +213,6 @@ namespace eosiosystem { } } - void system_contract::delegatebw( account_name from, account_name receiver, - asset stake_net_quantity, - asset stake_cpu_quantity, bool transfer ) - - { - require_auth( from ); - - eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); - eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); - - auto total_stake = stake_cpu_quantity.amount + stake_net_quantity.amount; - eosio_assert( total_stake > 0, "must stake a positive amount" ); - - account_name source_stake_from = from; - - if( transfer ) from = receiver; - - del_bandwidth_table del_tbl( _self, from); - auto itr = del_tbl.find( receiver ); - if( itr == del_tbl.end() ) { - del_tbl.emplace( from, [&]( auto& dbo ){ - dbo.from = from; - dbo.to = receiver; - dbo.net_weight = stake_net_quantity; - dbo.cpu_weight = stake_cpu_quantity; - }); - } - else { - del_tbl.modify( itr, 0, [&]( auto& dbo ){ - dbo.net_weight += stake_net_quantity; - dbo.cpu_weight += stake_cpu_quantity; - }); - } - - user_resources_table totals_tbl( _self, receiver ); - auto tot_itr = totals_tbl.find( receiver ); - if( tot_itr == totals_tbl.end() ) { - tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { - tot.owner = receiver; - tot.net_weight = stake_net_quantity; - tot.cpu_weight = stake_cpu_quantity; - }); - } else { - totals_tbl.modify( tot_itr, from == receiver ? from : 0, [&]( auto& tot ) { - tot.net_weight += stake_net_quantity; - tot.cpu_weight += stake_cpu_quantity; - }); - } - - set_resource_limits( tot_itr->owner, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - - if( N(eosio) != source_stake_from ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { source_stake_from, N(eosio), asset(total_stake), std::string("stake bandwidth") } ); - } - - auto from_voter = _voters.find(from); - if( from_voter == _voters.end() ) { - from_voter = _voters.emplace( from, [&]( auto& v ) { - v.owner = from; - v.staked = total_stake; - }); - } else { - _voters.modify( from_voter, 0, [&]( auto& v ) { - v.staked += total_stake; - }); - } - - if( from_voter->producers.size() || from_voter->proxy ) { - voteproducer( from, from_voter->proxy, from_voter->producers ); - } - } // delegatebw - - void validate_b1_vesting( int64_t stake ) { const int64_t seconds_per_year = 60*60*24*365; const int64_t base_time = 1527811200; /// 2018-06-01 @@ -296,79 +222,162 @@ namespace eosiosystem { eosio_assert( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } - void system_contract::undelegatebw( account_name from, account_name receiver, - asset unstake_net_quantity, asset unstake_cpu_quantity ) + void system_contract::changebw( account_name from, account_name receiver, + asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ) { - eosio_assert( unstake_cpu_quantity >= asset(), "must unstake a positive amount" ); - eosio_assert( unstake_net_quantity >= asset(), "must unstake a positive amount" ); - require_auth( from ); + eosio_assert( stake_net_quantity != asset(0) || stake_cpu_quantity != asset(0), "should stake non-zero amount" ); - del_bandwidth_table del_tbl( _self, from ); - const auto& dbw = del_tbl.get( receiver ); - eosio_assert( dbw.net_weight.amount >= unstake_net_quantity.amount, "insufficient staked net bandwidth" ); - eosio_assert( dbw.cpu_weight.amount >= unstake_cpu_quantity.amount, "insufficient staked cpu bandwidth" ); - - auto total_refund = unstake_cpu_quantity.amount + unstake_net_quantity.amount; + account_name source_stake_from = from; + if ( transfer ) { + from = receiver; + } - _voters.modify( _voters.get(from), 0, [&]( auto& v ) { - v.staked -= total_refund; - if( from == N(b1) ) { - validate_b1_vesting( v.staked ); + // update stake delegated from "from" to "receiver" + { + del_bandwidth_table del_tbl( _self, from); + auto itr = del_tbl.find( receiver ); + if( itr == del_tbl.end() ) { + itr = del_tbl.emplace( from, [&]( auto& dbo ){ + dbo.from = from; + dbo.to = receiver; + dbo.net_weight = stake_net_quantity; + dbo.cpu_weight = stake_cpu_quantity; + }); } - }); + else { + del_tbl.modify( itr, 0, [&]( auto& dbo ){ + dbo.net_weight += stake_net_quantity; + dbo.cpu_weight += stake_cpu_quantity; + }); + } + eosio_assert( asset(0) <= itr->net_weight, "insufficient staked net bandwidth" ); + eosio_assert( asset(0) <= itr->cpu_weight, "insufficient staked cpu bandwidth" ); + if ( itr->net_weight == asset(0) && itr->cpu_weight == asset(0) ) { + del_tbl.erase( itr ); + } + } // itr can be invalid, should go out of scope + + // update totals of "receiver" + { + user_resources_table totals_tbl( _self, receiver ); + auto tot_itr = totals_tbl.find( receiver ); + if( tot_itr == totals_tbl.end() ) { + tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { + tot.owner = receiver; + tot.net_weight = stake_net_quantity; + tot.cpu_weight = stake_cpu_quantity; + }); + } else { + totals_tbl.modify( tot_itr, from == receiver ? from : 0, [&]( auto& tot ) { + tot.net_weight += stake_net_quantity; + tot.cpu_weight += stake_cpu_quantity; + }); + } + eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); + eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); + set_resource_limits( receiver, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - eosio_assert( total_refund > 0, "must unstake a positive amount" ); + if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) ) { + totals_tbl.erase( tot_itr ); + } + } // tot_itr can be invalid, should go out of scope + + // transfer money or schedule a refund + asset total_update = stake_net_quantity + stake_cpu_quantity; + + if ( N(eosio) != source_stake_from ) { //for eosio transfer/refund doesn't make sense + refunds_table refunds_tbl( _self, from ); + auto req = refunds_tbl.find( from ); + + //create/update/delete refund + asset update_balance = total_update; + bool need_deferred_trx = false; + if ( req != refunds_tbl.end() ) { + refunds_tbl.modify( req, 0, [&]( refund_request& r ) { + r.amount -= update_balance; + if ( r.amount < asset(0) ){ + update_balance = -r.amount; + r.amount = asset(0); + } + r.request_time = now(); + }); + eosio_assert( asset(0) <= req->amount, "negative refund amount" ); //should never happen + + if ( req->amount == asset(0) ) { + refunds_tbl.erase( req ); + need_deferred_trx = false; + } else { + need_deferred_trx = true; + } + } else if ( update_balance < asset(0) ) { + refunds_tbl.emplace( from, [&]( refund_request& r ) { + r.owner = from; + r.amount = -total_update; + r.request_time = now(); + }); + need_deferred_trx = true; + } // else stake increases with no existing row in refunds_tbl -> nothing to do with refunds_tbl + + if ( asset(0) < update_balance ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { source_stake_from, N(eosio), asset(update_balance), std::string("stake bandwidth") } ); + } - if( dbw.net_weight == unstake_net_quantity && dbw.cpu_weight == unstake_cpu_quantity ) { - del_tbl.erase( dbw ); - } else { - del_tbl.modify( dbw, from, [&]( auto& dbo ){ - dbo.net_weight -= unstake_net_quantity; - dbo.cpu_weight -= unstake_cpu_quantity; - }); + if ( need_deferred_trx ) { + eosio::transaction out; + out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); + out.delay_sec = refund_delay; + out.send( from, receiver, true ); + } else { + //cancel_deferred( from ); + } } - user_resources_table totals_tbl( _self, receiver ); - - const auto& totals = totals_tbl.get( receiver ); - totals_tbl.modify( totals, 0, [&]( auto& tot ) { - tot.net_weight -= unstake_net_quantity; - tot.cpu_weight -= unstake_cpu_quantity; - }); - - set_resource_limits( receiver, totals.ram_bytes, totals.net_weight.amount, totals.cpu_weight.amount ); + // update voting power + { + auto from_voter = _voters.find(from); + if( from_voter == _voters.end() ) { + from_voter = _voters.emplace( from, [&]( auto& v ) { + v.owner = from; + v.staked = total_update.amount; + }); + } else { + _voters.modify( from_voter, 0, [&]( auto& v ) { + v.staked += total_update.amount; + }); + } + eosio_assert( 0 <= from_voter->staked, "stake for voting cannot be negative"); + if( from == N(b1) ) { + validate_b1_vesting( from_voter->staked ); + } - refunds_table refunds_tbl( _self, from ); - //create refund request - auto req = refunds_tbl.find( from ); - if ( req != refunds_tbl.end() ) { - refunds_tbl.modify( req, 0, [&]( refund_request& r ) { - r.amount += unstake_net_quantity + unstake_cpu_quantity; - r.request_time = now(); - }); - } else { - refunds_tbl.emplace( from, [&]( refund_request& r ) { - r.owner = from; - r.amount = unstake_net_quantity + unstake_cpu_quantity; - r.request_time = now(); - }); + if( from_voter->producers.size() || from_voter->proxy ) { + voteproducer( from, from_voter->proxy, from_voter->producers ); + } } + } - //create or replace deferred transaction - //refund act; - //act.owner = from; - eosio::transaction out; - out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); - out.delay_sec = refund_delay; - out.send( from, receiver, true ); + void system_contract::delegatebw( account_name from, account_name receiver, + asset stake_net_quantity, + asset stake_cpu_quantity, bool transfer ) + { + eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); + eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); + eosio_assert( stake_net_quantity + stake_cpu_quantity > asset(0), "must stake a positive amount" ); - const auto& fromv = _voters.get( from ); + changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); + } // delegatebw - if( fromv.producers.size() || fromv.proxy ) { - voteproducer( from, fromv.proxy, fromv.producers ); - } + void system_contract::undelegatebw( account_name from, account_name receiver, + asset unstake_net_quantity, asset unstake_cpu_quantity ) + { + eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); + eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); + eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); + + changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); } // undelegatebw diff --git a/eosio.system.hpp b/eosio.system.hpp index 5f3f4887..713b1c5e 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -134,6 +134,9 @@ namespace eosiosystem { // functions defined in delegate_bandwidth.cpp + void changebw( account_name from, account_name receiver, + asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + /** * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. * If transfer == true, then 'receiver' can unstake to their account From 86381eef73dcef07f7b1115421c3a9caa4a95604 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 17 May 2018 17:58:37 -0400 Subject: [PATCH 0261/1048] refund from net stake is not allowed to go to cpu stake and vice versa #3180 --- delegate_bandwidth.cpp | 81 +++++++++++++++++++++++++----------------- 1 file changed, 48 insertions(+), 33 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 6cffa61d..e94c8075 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -63,12 +63,13 @@ namespace eosiosystem { struct refund_request { account_name owner; time request_time; - eosio::asset amount; + eosio::asset net_amount; + eosio::asset cpu_amount; uint64_t primary_key()const { return owner; } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(amount) ) + EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(net_amount)(cpu_amount) ) }; /** @@ -223,10 +224,10 @@ namespace eosiosystem { } void system_contract::changebw( account_name from, account_name receiver, - asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ) + const asset stake_net_delta, const asset stake_cpu_delta, bool transfer ) { require_auth( from ); - eosio_assert( stake_net_quantity != asset(0) || stake_cpu_quantity != asset(0), "should stake non-zero amount" ); + eosio_assert( stake_net_delta != asset(0) || stake_cpu_delta != asset(0), "should stake non-zero amount" ); account_name source_stake_from = from; if ( transfer ) { @@ -241,14 +242,14 @@ namespace eosiosystem { itr = del_tbl.emplace( from, [&]( auto& dbo ){ dbo.from = from; dbo.to = receiver; - dbo.net_weight = stake_net_quantity; - dbo.cpu_weight = stake_cpu_quantity; + dbo.net_weight = stake_net_delta; + dbo.cpu_weight = stake_cpu_delta; }); } else { del_tbl.modify( itr, 0, [&]( auto& dbo ){ - dbo.net_weight += stake_net_quantity; - dbo.cpu_weight += stake_cpu_quantity; + dbo.net_weight += stake_net_delta; + dbo.cpu_weight += stake_cpu_delta; }); } eosio_assert( asset(0) <= itr->net_weight, "insufficient staked net bandwidth" ); @@ -265,13 +266,13 @@ namespace eosiosystem { if( tot_itr == totals_tbl.end() ) { tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { tot.owner = receiver; - tot.net_weight = stake_net_quantity; - tot.cpu_weight = stake_cpu_quantity; + tot.net_weight = stake_net_delta; + tot.cpu_weight = stake_cpu_delta; }); } else { totals_tbl.modify( tot_itr, from == receiver ? from : 0, [&]( auto& tot ) { - tot.net_weight += stake_net_quantity; - tot.cpu_weight += stake_cpu_quantity; + tot.net_weight += stake_net_delta; + tot.cpu_weight += stake_cpu_delta; }); } eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); @@ -284,46 +285,53 @@ namespace eosiosystem { } } // tot_itr can be invalid, should go out of scope - // transfer money or schedule a refund - asset total_update = stake_net_quantity + stake_cpu_quantity; - - if ( N(eosio) != source_stake_from ) { //for eosio transfer/refund doesn't make sense + // create refund or update from existing refund + if ( N(eosio) != source_stake_from ) { //for eosio both transfer and refund make no sense refunds_table refunds_tbl( _self, from ); auto req = refunds_tbl.find( from ); //create/update/delete refund - asset update_balance = total_update; + auto net_balance = stake_net_delta; + auto cpu_balance = stake_cpu_delta; bool need_deferred_trx = false; - if ( req != refunds_tbl.end() ) { + if ( req != refunds_tbl.end() ) { //need to update refund refunds_tbl.modify( req, 0, [&]( refund_request& r ) { - r.amount -= update_balance; - if ( r.amount < asset(0) ){ - update_balance = -r.amount; - r.amount = asset(0); + r.net_amount -= net_balance; + if ( r.net_amount < asset(0) ) { + net_balance = -r.net_amount; + r.net_amount = asset(0); + } + r.cpu_amount -= cpu_balance; + if ( r.cpu_amount < asset(0) ){ + cpu_balance = -r.cpu_amount; + r.cpu_amount = asset(0); } r.request_time = now(); }); - eosio_assert( asset(0) <= req->amount, "negative refund amount" ); //should never happen + eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen + eosio_assert( asset(0) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen - if ( req->amount == asset(0) ) { + if ( req->net_amount == asset(0) && req->cpu_amount == asset(0) ) { refunds_tbl.erase( req ); need_deferred_trx = false; } else { need_deferred_trx = true; } - } else if ( update_balance < asset(0) ) { + } else if ( net_balance < asset(0) && cpu_balance < asset(0) ) { //need to create refund refunds_tbl.emplace( from, [&]( refund_request& r ) { r.owner = from; - r.amount = -total_update; + if ( net_balance < asset(0) ) { + r.net_amount = -net_balance; + net_balance = asset(0); + } // else r.net_amount = 0 by default constructor + if ( cpu_balance < asset(0) ) { + r.cpu_amount = -cpu_balance; + cpu_balance = asset(0); + } // else r.cpu_amount = 0 by default constructor r.request_time = now(); }); need_deferred_trx = true; - } // else stake increases with no existing row in refunds_tbl -> nothing to do with refunds_tbl - - if ( asset(0) < update_balance ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { source_stake_from, N(eosio), asset(update_balance), std::string("stake bandwidth") } ); - } + } // else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl if ( need_deferred_trx ) { eosio::transaction out; @@ -333,10 +341,17 @@ namespace eosiosystem { } else { //cancel_deferred( from ); } + + auto transfer_amount = net_balance + cpu_balance; + if ( asset(0) < transfer_amount ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { source_stake_from, N(eosio), asset(transfer_amount), std::string("stake bandwidth") } ); + } } // update voting power { + asset total_update = stake_net_delta + stake_cpu_delta; auto from_voter = _voters.find(from); if( from_voter == _voters.end() ) { from_voter = _voters.emplace( from, [&]( auto& v ) { @@ -393,7 +408,7 @@ namespace eosiosystem { // consecutive missed blocks. INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), req->owner, req->amount, std::string("unstake") } ); + { N(eosio), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); refunds_tbl.erase( req ); } From c6939ab8d8e1557aa0d5373f65cd699d6dc23413 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 17 May 2018 18:08:42 -0400 Subject: [PATCH 0262/1048] system contract: changebw added to abi and dispatcher #3180 --- eosio.system.abi | 8 ++++++-- eosio.system.cpp | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index d1899899..8b3d30dc 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -24,7 +24,7 @@ {"name":"quant", "type":"asset"} ] },{ - "name": "delegatebw", + "name": "changebw", "base": "", "fields": [ {"name":"from", "type":"account_name"}, @@ -223,9 +223,13 @@ "name": "sellram", "type": "sellram", "ricardian_contract": "" + },{ + "name": "changebw", + "type": "changebw", + "ricardian_contract": "" },{ "name": "delegatebw", - "type": "delegatebw", + "type": "changebw", "ricardian_contract": "" },{ "name": "undelegatebw", diff --git a/eosio.system.cpp b/eosio.system.cpp index 7ca481ce..194c040d 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -83,7 +83,7 @@ namespace eosiosystem { EOSIO_ABI( eosiosystem::system_contract, (setram) // delegate_bandwith.cpp - (delegatebw)(undelegatebw)(refund) + (changebw)(delegatebw)(undelegatebw)(refund) (buyram)(buyrambytes)(sellram) // voting.cpp // producer_pay.cpp From f24e8d5c604f138eada748f439ae7fe136c445aa Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 17 May 2018 19:43:40 -0400 Subject: [PATCH 0263/1048] Producer pay divide-by-zero and min stake checks --- producer_pay.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index c69bf84d..04831bce 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -4,8 +4,8 @@ namespace eosiosystem { - const int64_t min_daily_tokens = 100; - + const int64_t min_daily_tokens = 100; + const int64_t min_activated_stake = 150'000'000'0000; const double continuous_rate = 0.04879; // 5% annual rate const double perblock_rate = 0.0025; // 0.25% const double standby_rate = 0.0075; // 0.75% @@ -23,7 +23,7 @@ namespace eosiosystem { require_auth(N(eosio)); /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < 150'000'000'0000 ) + if( _gstate.total_activated_stake < min_activated_stake ) return; if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses @@ -55,6 +55,8 @@ namespace eosiosystem { const auto& prod = _producers.get( owner ); eosio_assert( prod.active(), "producer does not have an active key" ); + + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "not enough has been staked for producers to claim rewards" ); auto ct = current_time(); @@ -81,8 +83,14 @@ namespace eosiosystem { _gstate.last_pervote_bucket_fill = ct; } - int64_t producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; - int64_t producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); + int64_t producer_per_block_pay = 0; + if( _gstate.total_unpaid_blocks > 0 ) { + producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; + } + int64_t producer_per_vote_pay = 0; + if( _gstate.total_producer_vote_weight > 0 ) { + producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); + } if( producer_per_vote_pay < 100'0000 ) { producer_per_vote_pay = 0; } From 794b77f76e2932cd4e1dbc9e418003c66888dd42 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Thu, 17 May 2018 21:06:32 -0400 Subject: [PATCH 0264/1048] Fix #3187 - effecient detection of names with '.' - also exempt the eosio account from this restriction --- delegate_bandwidth.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 9e462b15..3287c772 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -97,10 +97,14 @@ namespace eosiosystem { /* no need to parse authorites const authority& owner, const authority& active*/ ) { - auto name_str = eosio::name{newact}.to_string(); - eosio_assert( name_str.size() == 12 || creator == N(eosio), "account names must be 12 chars long" ); - eosio_assert( name_str.find_first_of('.') == std::string::npos || creator == N(eosio), "account names cannot contain '.' character"); + if( creator != _self ) { + auto tmp = newact; + for( uint32_t i = 0; i < 12; ++i ) { + if( tmp & 0x1f ) eosio_assert( false, "name may not contain '.'"); + tmp >>= 5; + } + } user_resources_table userres( _self, newact); From 464ee39b34350131dcedd8d52715469e2199cb51 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 18 May 2018 00:27:58 -0400 Subject: [PATCH 0265/1048] Implement Name Auction #3189 --- delegate_bandwidth.cpp | 38 ------------------- eosio.system.cpp | 86 ++++++++++++++++++++++++++++++++++++++++++ eosio.system.hpp | 21 ++++++++++- producer_pay.cpp | 13 +++++++ 4 files changed, 119 insertions(+), 39 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 3287c772..c4e6bdaa 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -80,44 +80,6 @@ namespace eosiosystem { typedef eosio::multi_index< N(refunds), refund_request> refunds_table; - /** - * Called after a new account is created. This code enforces resource-limits rules - * for new accounts as well as new account naming conventions. - * - * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 - * characters long without '.' until a future account auction process is implemented - * which prevents name squatting. - * - * 2. new accounts must stake a minimal number of tokens (as set in system parameters) - * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. - */ - void native::newaccount( account_name creator, - account_name newact - /* no need to parse authorites - const authority& owner, - const authority& active*/ ) { - - if( creator != _self ) { - auto tmp = newact; - for( uint32_t i = 0; i < 12; ++i ) { - if( tmp & 0x1f ) eosio_assert( false, "name may not contain '.'"); - tmp >>= 5; - } - } - - user_resources_table userres( _self, newact); - - userres.emplace( newact, [&]( auto& res ) { - res.owner = newact; - }); - - set_resource_limits( newact, - 0,// r->ram_bytes, - 0, 0 ); - // r->net_weight.amount, - // r->cpu_weight.amount ); - } /** * This action will buy an exact amount of ram and bill the payer the current market price. diff --git a/eosio.system.cpp b/eosio.system.cpp index 7ca481ce..668e164d 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -77,6 +77,91 @@ namespace eosiosystem { set_privileged( account, ispriv ); } + void system_contract::bidname( account_name bidder, account_name newname, asset bid ) { + require_auth( bidder ); + eosio_assert( eosio::name_suffix(newname) == newname, "you can only bid on top-level suffix" ); + eosio_assert( !is_account( newname ), "account already exists" ); + eosio_assert( bid.symbol == asset().symbol, "asset must be system token" ); + eosio_assert( bid.amount > 0, "insufficient bid" ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {bidder,N(active)}, + { bidder, N(eosio), bid, std::string("bid name ")+(name{newname}).to_string() } ); + + name_bid_table bids(_self,_self); + auto current = bids.find( newname ); + if( current != bids.end() ) { + bids.emplace( bidder, [&]( auto& b ) { + b.newname = newname; + b.high_bidder = bidder; + b.high_bid = bid.amount; + b.last_bid_time = current_time(); + }); + } else { + eosio_assert( current->high_bid > 0, "this auction has already closed" ); + eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); + eosio_assert( current->high_bidder != bidder, "account is already high bidder" ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(eosio.code)}, + { N(eosio), current->high_bidder, asset(current->high_bid), + std::string("refund bid on name ")+(name{newname}).to_string() } ); + + bids.modify( current, bidder, [&]( auto& b ) { + b.high_bidder = bidder; + b.high_bid = bid.amount; + b.last_bid_time = current_time(); + }); + } + } + + /** + * Called after a new account is created. This code enforces resource-limits rules + * for new accounts as well as new account naming conventions. + * + * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 + * characters long without '.' until a future account auction process is implemented + * which prevents name squatting. + * + * 2. new accounts must stake a minimal number of tokens (as set in system parameters) + * therefore, this method will execute an inline buyram from receiver for newacnt in + * an amount equal to the current new account creation fee. + */ + void native::newaccount( account_name creator, + account_name newact + /* no need to parse authorites + const authority& owner, + const authority& active*/ ) { + + if( creator != _self ) { + auto tmp = newact; + bool has_dot = false; + for( uint32_t i = 0; i < 13; ++i ) { + has_dot |= (tmp >> 59); + tmp <<= 5; + } + auto suffix = eosio::name_suffix(newact); + if( has_dot ) { + if( suffix == newact ) { + name_bid_table bids(_self,_self); + auto current = bids.find( newact ); + eosio_assert( current != bids.end(), "no active bid for name" ); + eosio_assert( current->high_bidder == creator, "only high bidder can claim" ); + eosio_assert( current->high_bid < 0, "auction for name is not closed yet" ); + bids.erase( current ); + } else { + eosio_assert( creator == suffix, "only suffix may create this account" ); + } + } + } + + user_resources_table userres( _self, newact); + + userres.emplace( newact, [&]( auto& res ) { + res.owner = newact; + }); + + set_resource_limits( newact, 0, 0, 0 ); + } + } /// eosio.system @@ -93,5 +178,6 @@ EOSIO_ABI( eosiosystem::system_contract, (onblock) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) //this file + (bidname) (setpriv) ) diff --git a/eosio.system.hpp b/eosio.system.hpp index 5f3f4887..42f8256c 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -27,6 +27,23 @@ namespace eosiosystem { EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_ram_size) ) }; + struct name_bid { + account_name newname; + account_name high_bidder; + int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed + uint64_t last_bid_time = 0; + + auto primary_key()const { return newname; } + uint64_t by_high_bid()const { return -high_bid; } + }; + + typedef eosio::multi_index< N(namebids), name_bid, + indexed_by > + > name_bid_table; + + + + struct eosio_global_state : eosio_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } @@ -42,12 +59,13 @@ namespace eosiosystem { int64_t total_activated_stake = 0; checksum160 last_producer_schedule_id; double total_producer_vote_weight = 0; /// the sum of all producer votes + block_timestamp last_name_close; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update) (last_pervote_bucket_fill) - (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(last_producer_schedule_id)(total_producer_vote_weight) ) + (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(last_producer_schedule_id)(total_producer_vote_weight)(last_name_close) ) }; struct producer_info { @@ -200,6 +218,7 @@ namespace eosiosystem { void setpriv( account_name account, uint8_t ispriv ); + void bidname( account_name bidder, account_name newname, asset bid ); private: void update_elected_producers( block_timestamp timestamp ); diff --git a/producer_pay.cpp b/producer_pay.cpp index 04831bce..bfcf4718 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -46,6 +46,19 @@ namespace eosiosystem { /// only update block producers once every minute, block_timestamp is in half seconds if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) { update_elected_producers( timestamp ); + + + if( (timestamp.slot - _gstate.last_name_close.slot) > (2*60*60*24ll)/*timeslots_per_day*/ ) { + name_bid_table bids(_self,_self); + auto idx = bids.get_index(); + auto highest = idx.begin(); + if( highest != idx.end() && highest->high_bid > 0 && highest->last_bid_time < (current_time() - useconds_per_day) ) { + _gstate.last_name_close = timestamp; + idx.modify( highest, 0, [&]( auto& b ){ + b.high_bid = -b.high_bid; + }); + } + } } } From 19f4b6d9868a0cce1ebfe3872d4a46bc9fd753ec Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Wed, 16 May 2018 06:10:53 -0300 Subject: [PATCH 0266/1048] Rename "EOS" symbol in eosio.system to "SYS" --- delegate_bandwidth.cpp | 10 +++++----- eosio.system.cpp | 8 ++++---- eosio.system.hpp | 2 +- producer_pay.cpp | 44 ++++++++++++++++++++++++++++++++++++++++++ voting.cpp | 2 +- 5 files changed, 55 insertions(+), 11 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 9e462b15..fb9e1adb 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -119,9 +119,9 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - auto itr = _rammarket.find(S(4,RAMEOS)); + auto itr = _rammarket.find(S(4,RAMSYS)); auto tmp = *itr; - auto eosout = tmp.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); + auto eosout = tmp.convert( asset(bytes,S(0,RAM)), S(4,SYS) ); buyram( payer, receiver, eosout ); } @@ -148,7 +148,7 @@ namespace eosiosystem { int64_t bytes_out; - auto itr = _rammarket.find(S(4,RAMEOS)); + auto itr = _rammarket.find(S(4,RAMSYS)); _rammarket.modify( itr, 0, [&]( auto& es ) { bytes_out = es.convert( quant, S(0,RAM) ).amount; }); @@ -190,10 +190,10 @@ namespace eosiosystem { eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; - auto itr = _rammarket.find(S(4,RAMEOS)); + auto itr = _rammarket.find(S(4,RAMSYS)); _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,EOS) ); + tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,SYS) ); }); _gstate.total_ram_bytes_reserved -= bytes; diff --git a/eosio.system.cpp b/eosio.system.cpp index 7ca481ce..b4eb1bcd 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -19,18 +19,18 @@ namespace eosiosystem { //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); - auto itr = _rammarket.find(S(4,RAMEOS)); + auto itr = _rammarket.find(S(4,RAMSYS)); if( itr == _rammarket.end() ) { auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; if( system_token_supply > 0 ) { itr = _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; - m.supply.symbol = S(4,RAMEOS); + m.supply.symbol = S(4,RAMSYS); m.base.balance.amount = int64_t(_gstate.free_ram()); m.base.balance.symbol = S(0,RAM); m.quote.balance.amount = system_token_supply / 1000; - m.quote.balance.symbol = S(4,EOS); + m.quote.balance.symbol = S(4,SYS); }); } } else { @@ -58,7 +58,7 @@ namespace eosiosystem { eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size); - auto itr = _rammarket.find(S(4,RAMEOS)); + auto itr = _rammarket.find(S(4,RAMSYS)); /** * Increase or decrease the amount of ram for sale based upon the change in max diff --git a/eosio.system.hpp b/eosio.system.hpp index 5f3f4887..1c085af9 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -113,7 +113,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr uint64_t system_token_symbol = S(4,EOS); + static constexpr uint64_t system_token_symbol = S(4,SYS); class system_contract : public native { private: diff --git a/producer_pay.cpp b/producer_pay.cpp index 04831bce..f7186d33 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -47,6 +47,50 @@ namespace eosiosystem { if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) { update_elected_producers( timestamp ); } + + } + + eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) { + eosio::asset payment(0, S(4,SYS)); + const int64_t min_daily_amount = 100 * 10000; + if ( pervote_bucket.amount < min_daily_amount ) { + return payment; + } + + auto idx = _producers.template get_index(); + + double total_producer_votes = 0; + double running_payment_amount = 0; + bool to_be_payed = false; + for ( auto itr = idx.cbegin(); itr != idx.cend(); ++itr ) { + if ( !(itr->total_votes > 0) ) { + break; + } + if ( !itr->active() ) { + continue; + } + + if ( itr->owner == owner ) { + to_be_payed = true; + } + + total_producer_votes += itr->total_votes; + running_payment_amount = (itr->total_votes) * double(pervote_bucket.amount) / total_producer_votes; + if ( running_payment_amount < min_daily_amount ) { + if ( itr->owner == owner ) { + to_be_payed = false; + } + total_producer_votes -= itr->total_votes; + break; + } + } + + if ( to_be_payed ) { + payment.amount = static_cast( (double(pervote_bucket.amount) * owners_votes) / total_producer_votes ); + } + + return payment; + } using namespace eosio; diff --git a/voting.cpp b/voting.cpp index 8eb98731..c2c5c4bd 100644 --- a/voting.cpp +++ b/voting.cpp @@ -131,7 +131,7 @@ namespace eosiosystem { * @pre if proxy is set then proxy account must exist and be registered as a proxy * @pre every listed producer or proxy must have been previously registered * @pre voter must authorize this action - * @pre voter must have previously staked some EOS for voting + * @pre voter must have previously staked some SYS for voting * @pre voter->staked must be up to date * * @post every producer previously voted for will have vote reduced by previous vote weight From 288f6fda957e0861cd621124891762c6b7d96b83 Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Wed, 16 May 2018 11:50:16 -0300 Subject: [PATCH 0267/1048] fix missing tests --- producer_pay.cpp | 44 -------------------------------------------- 1 file changed, 44 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index f7186d33..04831bce 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -47,50 +47,6 @@ namespace eosiosystem { if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) { update_elected_producers( timestamp ); } - - } - - eosio::asset system_contract::payment_per_vote( const account_name& owner, double owners_votes, const eosio::asset& pervote_bucket ) { - eosio::asset payment(0, S(4,SYS)); - const int64_t min_daily_amount = 100 * 10000; - if ( pervote_bucket.amount < min_daily_amount ) { - return payment; - } - - auto idx = _producers.template get_index(); - - double total_producer_votes = 0; - double running_payment_amount = 0; - bool to_be_payed = false; - for ( auto itr = idx.cbegin(); itr != idx.cend(); ++itr ) { - if ( !(itr->total_votes > 0) ) { - break; - } - if ( !itr->active() ) { - continue; - } - - if ( itr->owner == owner ) { - to_be_payed = true; - } - - total_producer_votes += itr->total_votes; - running_payment_amount = (itr->total_votes) * double(pervote_bucket.amount) / total_producer_votes; - if ( running_payment_amount < min_daily_amount ) { - if ( itr->owner == owner ) { - to_be_payed = false; - } - total_producer_votes -= itr->total_votes; - break; - } - } - - if ( to_be_payed ) { - payment.amount = static_cast( (double(pervote_bucket.amount) * owners_votes) / total_producer_votes ); - } - - return payment; - } using namespace eosio; From a86c7ba07ed3ce74e357c97a1e940e64af64dffb Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Fri, 18 May 2018 14:38:04 +0800 Subject: [PATCH 0268/1048] Adjust voting weight --- voting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 8eb98731..4b850c2d 100644 --- a/voting.cpp +++ b/voting.cpp @@ -122,7 +122,7 @@ namespace eosiosystem { double stake2vote( int64_t staked ) { /// TODO subtract 2080 brings the large numbers closer to this decade - double weight = int64_t( (now() / (seconds_per_day * 7)) ) / double( 52 ); + double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } /** From fddde42551de23cdc99c0206bece197089d96570 Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 18 May 2018 05:55:58 -0300 Subject: [PATCH 0269/1048] Add cmake configuration parameter to set the CORE symbol. (CORE_SYMBOL_NAME) --- delegate_bandwidth.cpp | 10 +++++----- eosio.system.cpp | 8 ++++---- eosio.system.hpp | 2 +- voting.cpp | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index fb9e1adb..32ebb6da 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -119,9 +119,9 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - auto itr = _rammarket.find(S(4,RAMSYS)); + auto itr = _rammarket.find(S(4,RAMCORE)); auto tmp = *itr; - auto eosout = tmp.convert( asset(bytes,S(0,RAM)), S(4,SYS) ); + auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); buyram( payer, receiver, eosout ); } @@ -148,7 +148,7 @@ namespace eosiosystem { int64_t bytes_out; - auto itr = _rammarket.find(S(4,RAMSYS)); + auto itr = _rammarket.find(S(4,RAMCORE)); _rammarket.modify( itr, 0, [&]( auto& es ) { bytes_out = es.convert( quant, S(0,RAM) ).amount; }); @@ -190,10 +190,10 @@ namespace eosiosystem { eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; - auto itr = _rammarket.find(S(4,RAMSYS)); + auto itr = _rammarket.find(S(4,RAMCORE)); _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(bytes,S(0,RAM)), S(4,SYS) ); + tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); }); _gstate.total_ram_bytes_reserved -= bytes; diff --git a/eosio.system.cpp b/eosio.system.cpp index b4eb1bcd..e81529a1 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -19,18 +19,18 @@ namespace eosiosystem { //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); - auto itr = _rammarket.find(S(4,RAMSYS)); + auto itr = _rammarket.find(S(4,RAMCORE)); if( itr == _rammarket.end() ) { auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; if( system_token_supply > 0 ) { itr = _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; - m.supply.symbol = S(4,RAMSYS); + m.supply.symbol = S(4,RAMCORE); m.base.balance.amount = int64_t(_gstate.free_ram()); m.base.balance.symbol = S(0,RAM); m.quote.balance.amount = system_token_supply / 1000; - m.quote.balance.symbol = S(4,SYS); + m.quote.balance.symbol = CORE_SYMBOL; }); } } else { @@ -58,7 +58,7 @@ namespace eosiosystem { eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size); - auto itr = _rammarket.find(S(4,RAMSYS)); + auto itr = _rammarket.find(S(4,RAMCORE)); /** * Increase or decrease the amount of ram for sale based upon the change in max diff --git a/eosio.system.hpp b/eosio.system.hpp index 1c085af9..f4ce6c1c 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -113,7 +113,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr uint64_t system_token_symbol = S(4,SYS); + static constexpr uint64_t system_token_symbol = CORE_SYMBOL; class system_contract : public native { private: diff --git a/voting.cpp b/voting.cpp index c2c5c4bd..8eb98731 100644 --- a/voting.cpp +++ b/voting.cpp @@ -131,7 +131,7 @@ namespace eosiosystem { * @pre if proxy is set then proxy account must exist and be registered as a proxy * @pre every listed producer or proxy must have been previously registered * @pre voter must authorize this action - * @pre voter must have previously staked some SYS for voting + * @pre voter must have previously staked some EOS for voting * @pre voter->staked must be up to date * * @post every producer previously voted for will have vote reduced by previous vote weight From fe7f09066bb28e4cd4d512925fdf367be2b3aa85 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 18 May 2018 11:16:35 -0400 Subject: [PATCH 0270/1048] cancel_deferred returns 0 (transaction not found) or 1 (canceled), don't reset refund timer when taking moner from refund to stake #3180 --- delegate_bandwidth.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index e94c8075..1b693245 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -296,6 +296,9 @@ namespace eosiosystem { bool need_deferred_trx = false; if ( req != refunds_tbl.end() ) { //need to update refund refunds_tbl.modify( req, 0, [&]( refund_request& r ) { + if ( net_balance <= asset(0) || cpu_balance <= asset(0) ) { + r.request_time = now(); + } r.net_amount -= net_balance; if ( r.net_amount < asset(0) ) { net_balance = -r.net_amount; @@ -306,7 +309,6 @@ namespace eosiosystem { cpu_balance = -r.cpu_amount; r.cpu_amount = asset(0); } - r.request_time = now(); }); eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen eosio_assert( asset(0) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen @@ -339,7 +341,7 @@ namespace eosiosystem { out.delay_sec = refund_delay; out.send( from, receiver, true ); } else { - //cancel_deferred( from ); + cancel_deferred( from ); } auto transfer_amount = net_balance + cpu_balance; From 364508233dc4924bb038f4eaccbddcdc46d4f134 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 18 May 2018 11:24:41 -0400 Subject: [PATCH 0271/1048] avoid some validation while increasing/decreasing voting power, but validate when voting #3158 --- delegate_bandwidth.cpp | 2 +- eosio.system.hpp | 2 ++ voting.cpp | 19 +++++++++++-------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 1b693245..3856bda0 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -371,7 +371,7 @@ namespace eosiosystem { } if( from_voter->producers.size() || from_voter->proxy ) { - voteproducer( from, from_voter->proxy, from_voter->producers ); + update_votes( from, from_voter->proxy, from_voter->producers, false ); } } } diff --git a/eosio.system.hpp b/eosio.system.hpp index 713b1c5e..3707b9db 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -211,6 +211,8 @@ namespace eosiosystem { //defined in voting.hpp static eosio_global_state get_default_parameters(); + void update_votes( const account_name voter, const account_name proxy, const std::vector& producers, bool voting ); + // defined in voting.cpp void propagate_weight_change( const voter_info& voter ); }; diff --git a/voting.cpp b/voting.cpp index 8eb98731..57658924 100644 --- a/voting.cpp +++ b/voting.cpp @@ -36,7 +36,6 @@ namespace eosiosystem { */ void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { eosio_assert( url.size() < 512, "url too long" ); - //eosio::print("produce_key: ", producer_key.size(), ", sizeof(public_key): ", sizeof(public_key), "\n"); require_auth( producer ); auto prod = _producers.find( producer ); @@ -142,6 +141,10 @@ namespace eosiosystem { * If voting for a proxy, the producer votes will not change until the proxy updates their own vote. */ void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector& producers ) { + update_votes( voter_name, proxy, producers, true ); + } + + void system_contract::update_votes( const account_name voter_name, const account_name proxy, const std::vector& producers, bool voting ) { require_auth( voter_name ); //validate input @@ -194,7 +197,8 @@ namespace eosiosystem { if( proxy ) { auto new_proxy = _voters.find( proxy ); - eosio_assert( new_proxy != _voters.end() && new_proxy->is_proxy, "invalid proxy specified" ); + eosio_assert( new_proxy != _voters.end(), "invalid proxy specified" ); //if ( !voting ) { data corruption } else { wrong vote } + eosio_assert( !voting || new_proxy->is_proxy, "proxy not found" ); if ( new_vote_weight >= 0 ) { _voters.modify( new_proxy, 0, [&]( auto& vp ) { vp.proxied_vote_weight += new_vote_weight; @@ -214,24 +218,24 @@ namespace eosiosystem { for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { - eosio_assert( pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); + eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); _producers.modify( pitr, 0, [&]( auto& p ) { p.total_votes += pd.second.first; + if ( p.total_votes < 0 ) { // floating point ariphmetics can give as small negative numbers + p.total_votes = 0; + } _gstate.total_producer_vote_weight += pd.second.first; //eosio_assert( p.total_votes >= 0, "something bad happened" ); }); } else { - eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); + eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } } _voters.modify( voter, 0, [&]( auto& av ) { - print( "last_vote_weight: ", av.last_vote_weight, "\n" ); - print( "new_vote_weight: ", new_vote_weight, "\n" ); av.last_vote_weight = new_vote_weight; av.producers = producers; av.proxy = proxy; - print( " vote weight: ", av.last_vote_weight, "\n" ); }); } @@ -253,7 +257,6 @@ namespace eosiosystem { eosio_assert( !isproxy || !pitr->proxy, "account that uses a proxy is not allowed to become a proxy" ); _voters.modify( pitr, 0, [&]( auto& p ) { p.is_proxy = isproxy; - print( " vote weight: ", p.last_vote_weight, "\n" ); }); propagate_weight_change( *pitr ); } else { From c42453fed96bd11db1a192e8a92a6fa0025a96dc Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 18 May 2018 12:02:52 -0400 Subject: [PATCH 0272/1048] producer pay: extra check added by Khaled's request --- producer_pay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 04831bce..c9857bae 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -65,7 +65,7 @@ namespace eosiosystem { const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill; - if( usecs_since_last_fill > 0 ) { + if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > 0 ) { auto new_tokens = static_cast( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); auto to_producers = new_tokens / 5; From 592cc8617bdf029e4d26ac8c89e3016e01882662 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 18 May 2018 13:09:02 -0400 Subject: [PATCH 0273/1048] changebw removed from abi and dispatcher #3180 --- eosio.system.abi | 16 +--------------- eosio.system.cpp | 2 +- eosio.system.hpp | 7 ++++--- 3 files changed, 6 insertions(+), 19 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index a2065508..684b027d 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -148,16 +148,6 @@ {"name":"receiver", "type":"account_name"}, {"name":"quant", "type":"asset"} ] - },{ - "name": "changebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"stake_net_quantity", "type":"asset"}, - {"name":"stake_cpu_quantity", "type":"asset"}, - {"name":"transfer", "type":"bool"} - ] },{ "name": "undelegatebw", "base": "", @@ -383,13 +373,9 @@ "name": "sellram", "type": "sellram", "ricardian_contract": "" - },{ - "name": "changebw", - "type": "changebw", - "ricardian_contract": "" },{ "name": "delegatebw", - "type": "changebw", + "type": "delegatebw", "ricardian_contract": "" },{ "name": "undelegatebw", diff --git a/eosio.system.cpp b/eosio.system.cpp index 59d2c66f..e81529a1 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -83,7 +83,7 @@ namespace eosiosystem { EOSIO_ABI( eosiosystem::system_contract, (setram) // delegate_bandwith.cpp - (changebw)(delegatebw)(undelegatebw)(refund) + (delegatebw)(undelegatebw)(refund) (buyram)(buyrambytes)(sellram) // voting.cpp // producer_pay.cpp diff --git a/eosio.system.hpp b/eosio.system.hpp index c48149f4..1e8c6fb9 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -134,9 +134,6 @@ namespace eosiosystem { // functions defined in delegate_bandwidth.cpp - void changebw( account_name from, account_name receiver, - asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); - /** * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. * If transfer == true, then 'receiver' can unstake to their account @@ -208,6 +205,10 @@ namespace eosiosystem { // Implementation details: + //defind in delegate_bandwidth.cpp + void changebw( account_name from, account_name receiver, + asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + //defined in voting.hpp static eosio_global_state get_default_parameters(); From cb6e7fc4901e4ffd4ab435a2f43d8255facb19f6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Fri, 18 May 2018 14:39:11 -0400 Subject: [PATCH 0274/1048] merge master, fix unit tests, and update system state abi --- eosio.system.abi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index 691217a4..b5f1223f 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -261,7 +261,8 @@ {"name":"total_unpaid_blocks", "type":"uint32"}, {"name":"total_activated_stake", "type":"int64"}, {"name":"last_producer_schedule_id", "type":"checksum160"}, - {"name":"total_producer_vote_weight", "type":"float64"} + {"name":"total_producer_vote_weight", "type":"float64"}, + {"name":"last_name_close", "type":"block_timestamp_type"} ] },{ "name": "producer_info", From 44cbeb9fd7199ddbc8f4ffb9e9f62d3f1aefe54b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 18 May 2018 14:53:13 -0400 Subject: [PATCH 0275/1048] restored delegatebw struct in system contract abi #3180 --- eosio.system.abi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index 684b027d..f0308be1 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -148,6 +148,16 @@ {"name":"receiver", "type":"account_name"}, {"name":"quant", "type":"asset"} ] + },{ + "name": "delegatebw", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"stake_net_quantity", "type":"asset"}, + {"name":"stake_cpu_quantity", "type":"asset"}, + {"name":"transfer", "type":"bool"} + ] },{ "name": "undelegatebw", "base": "", From 12c54367ffb067c726524e293da8249aac6c8b96 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Fri, 18 May 2018 14:15:21 -0500 Subject: [PATCH 0276/1048] Add bios actions/structs so get blocks with these structs provides pretty print output --- eosio.system.abi | 53 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index f0308be1..0e11106d 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -16,6 +16,7 @@ "new_type_name": "weight_type", "type": "uint16" }], + "____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.", "structs": [{ "name": "permission_level", "base": "", @@ -333,6 +334,40 @@ {"name":"account", "type":"account_name"}, {"name":"is_priv", "type":"int8"} ] + },{ + "name": "set_account_limits", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"ram_bytes", "type":"int64"}, + {"name":"net_weight", "type":"int64"}, + {"name":"cpu_weight", "type":"int64"} + ] + },{ + "name": "set_global_limits", + "base": "", + "fields": [ + {"name":"cpu_usec_per_period", "type":"int64"} + ] + },{ + "name": "producer_key", + "base": "", + "fields": [ + {"name":"producer_name", "type":"account_name"}, + {"name":"block_signing_key", "type":"public_key"} + ] + },{ + "name": "set_producers", + "base": "", + "fields": [ + {"name":"schedule", "type":"producer_key[]"} + ] + },{ + "name": "require_auth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"} + ] } ], "actions": [{ @@ -423,7 +458,23 @@ "name": "setpriv", "type": "setpriv", "ricardian_contract": "" - }], + },{ + "name": "setalimits", + "type": "set_account_limits", + "ricardian_contract": "" + },{ + "name": "setglimits", + "type": "set_global_limits", + "ricardian_contract": "" + },{ + "name": "setprods", + "type": "set_producers", + "ricardian_contract": "" + },{ + "name": "reqauth", + "type": "require_auth", + "ricardian_contract": "" + }], "tables": [{ "name": "producers", "type": "producer_info", From 6468f8d0a0e7e9e13199e6fb5f0cb18327d1439b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 18 May 2018 15:50:14 -0400 Subject: [PATCH 0277/1048] small bugfix: don't update requestim in case of zero change to refund #3180 --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 1b8a14da..d7c2b5b7 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -296,7 +296,7 @@ namespace eosiosystem { bool need_deferred_trx = false; if ( req != refunds_tbl.end() ) { //need to update refund refunds_tbl.modify( req, 0, [&]( refund_request& r ) { - if ( net_balance <= asset(0) || cpu_balance <= asset(0) ) { + if ( net_balance < asset(0) || cpu_balance < asset(0) ) { r.request_time = now(); } r.net_amount -= net_balance; From 6e082ead395f54a676cb2dd07359487cddbc80c6 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 18 May 2018 15:55:25 -0400 Subject: [PATCH 0278/1048] system contract bugfix: create refund record if either net or cpu refund requested #3180 --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index d7c2b5b7..0eb77a59 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -319,7 +319,7 @@ namespace eosiosystem { } else { need_deferred_trx = true; } - } else if ( net_balance < asset(0) && cpu_balance < asset(0) ) { //need to create refund + } else if ( net_balance < asset(0) || cpu_balance < asset(0) ) { //need to create refund refunds_tbl.emplace( from, [&]( refund_request& r ) { r.owner = from; if ( net_balance < asset(0) ) { From acfba4c74d2aaa96794d22c9e8695f3d5a1c3704 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Mon, 21 May 2018 07:42:11 -0400 Subject: [PATCH 0279/1048] fixing md formatting this should now display correctly on github --- eosio.system.voteproducer-rc.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/eosio.system.voteproducer-rc.md b/eosio.system.voteproducer-rc.md index 670cb99f..9b5f27ce 100644 --- a/eosio.system.voteproducer-rc.md +++ b/eosio.system.voteproducer-rc.md @@ -1,13 +1,18 @@ -#Ricardian Contract for VOTEPRODUCER +# Ricardian Contract for VOTEPRODUCER + This Ricardian contract for the system command VOTEPRODUCER is legally binding and can be used in the event of a dispute. Disputes shall be settled in this system's default arbitration forum. -VOTEPRODUCER (voter; array:producers) -Intent: cast a valid vote for up to 30 BP candidates +## VOTEPRODUCER (voter; array:producers) + +_Intent: cast a valid vote for up to 30 BP candidates_ + As an authorized party I {{ signer }} wish to vote on behalf of {{ voter }} in favor of the block producer candidates {{ array:producers }} with a voting weight equal to all tokens currently owned by {{ voter }} and staked for CPU or bandwidth. If I am not the beneficial owner of these shares I stipulate I have proof that I’ve been authorized to vote these shares by their beneficial owner(s). I stipulate I have not and will not accept anything of value in exchange for these votes, on penalty of confiscation of these tokens, and other penalties. -I acknowledge that using any system of automatic voting, re-voting, or vote refreshing, or allowing such a system to be used on my behalf or on behalf of another, is forbidden and doing so violates this contract. \ No newline at end of file +I acknowledge that using any system of automatic voting, re-voting, or vote refreshing, or allowing such a system to be used on my behalf or on behalf of another, is forbidden and doing so violates this contract. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From f4edcc4683a2d5330ccf3826dbdf5308188c6c54 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Mon, 21 May 2018 07:52:50 -0400 Subject: [PATCH 0280/1048] removed dup arb clause; reformat Removed the dual references to arbitration. Improved formatting (action is no longer UPPERCASE but is *emphasized* instead) --- eosio.system.voteproducer-rc.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.system.voteproducer-rc.md b/eosio.system.voteproducer-rc.md index 9b5f27ce..bc80e22f 100644 --- a/eosio.system.voteproducer-rc.md +++ b/eosio.system.voteproducer-rc.md @@ -1,6 +1,6 @@ -# Ricardian Contract for VOTEPRODUCER +# Ricardian Contract for *voteproducer* -This Ricardian contract for the system command VOTEPRODUCER is legally binding and can be used in the event of a dispute. Disputes shall be settled in this system's default arbitration forum. +This Ricardian contract for the system command *voteproducer* is legally binding and can be used in the event of a dispute. ## VOTEPRODUCER (voter; array:producers) From d4bb799e5d49fb386b7ce2ff5a2445cd47c18c81 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 21 May 2018 10:51:07 -0400 Subject: [PATCH 0281/1048] Prevent name auctions from closing until 14 days after min_stake_activated - #3209 --- eosio.system.abi | 1 + eosio.system.hpp | 4 +++- producer_pay.cpp | 31 +++++++++++++++++-------------- voting.cpp | 3 +++ 4 files changed, 24 insertions(+), 15 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index b5f1223f..6bdafa44 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -260,6 +260,7 @@ {"name":"savings", "type":"int64"}, {"name":"total_unpaid_blocks", "type":"uint32"}, {"name":"total_activated_stake", "type":"int64"}, + {"name":"thresh_activated_stake_time", "type":"uint64"}, {"name":"last_producer_schedule_id", "type":"checksum160"}, {"name":"total_producer_vote_weight", "type":"float64"}, {"name":"last_name_close", "type":"block_timestamp_type"} diff --git a/eosio.system.hpp b/eosio.system.hpp index 7174866a..d8e41025 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -57,6 +57,7 @@ namespace eosiosystem { int64_t savings = 0; uint32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid int64_t total_activated_stake = 0; + uint64_t thresh_activated_stake_time = 0; checksum160 last_producer_schedule_id; double total_producer_vote_weight = 0; /// the sum of all producer votes block_timestamp last_name_close; @@ -65,7 +66,8 @@ namespace eosiosystem { EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update) (last_pervote_bucket_fill) - (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(last_producer_schedule_id)(total_producer_vote_weight)(last_name_close) ) + (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(thresh_activated_stake_time) + (last_producer_schedule_id)(total_producer_vote_weight)(last_name_close) ) }; struct producer_info { diff --git a/producer_pay.cpp b/producer_pay.cpp index 96b9308f..f06cee95 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -4,17 +4,17 @@ namespace eosiosystem { - const int64_t min_daily_tokens = 100; - const int64_t min_activated_stake = 150'000'000'0000; - const double continuous_rate = 0.04879; // 5% annual rate - const double perblock_rate = 0.0025; // 0.25% - const double standby_rate = 0.0075; // 0.75% - const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year - const uint32_t seconds_per_year = 52*7*24*3600; - const uint32_t blocks_per_day = 2 * 24 * 3600; - const uint32_t blocks_per_hour = 2 * 3600; - const uint64_t useconds_per_day = 24 * 3600 * uint64_t(1000000); - const uint64_t useconds_per_year = seconds_per_year*1000000ll; + const int64_t min_pervote_daily_pay = 100'0000; + const int64_t min_activated_stake = 150'000'000'0000; + const double continuous_rate = 0.04879; // 5% annual rate + const double perblock_rate = 0.0025; // 0.25% + const double standby_rate = 0.0075; // 0.75% + const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year + const uint32_t seconds_per_year = 52*7*24*3600; + const uint32_t blocks_per_day = 2 * 24 * 3600; + const uint32_t blocks_per_hour = 2 * 3600; + const uint64_t useconds_per_day = 24 * 3600 * uint64_t(1000000); + const uint64_t useconds_per_year = seconds_per_year*1000000ll; void system_contract::onblock( block_timestamp timestamp, account_name producer ) { @@ -49,12 +49,15 @@ namespace eosiosystem { print( "maybe update bids \n" ); - if( (timestamp.slot - _gstate.last_name_close.slot) > (2*60*60*24ll)/*timeslots_per_day*/ ) { + if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { print( "update bids" ); name_bid_table bids(_self,_self); auto idx = bids.get_index(); auto highest = idx.begin(); - if( highest != idx.end() && highest->high_bid > 0 && highest->last_bid_time < (current_time() - useconds_per_day) ) { + if( highest != idx.end() && + highest->high_bid > 0 && + highest->last_bid_time < (current_time() - useconds_per_day) && + (current_time() - _gstate.thresh_activated_stake_time) > 14 * useconds_per_day ){ _gstate.last_name_close = timestamp; idx.modify( highest, 0, [&]( auto& b ){ b.high_bid = -b.high_bid; @@ -106,7 +109,7 @@ namespace eosiosystem { if( _gstate.total_producer_vote_weight > 0 ) { producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); } - if( producer_per_vote_pay < 100'0000 ) { + if( producer_per_vote_pay < min_pervote_daily_pay ) { producer_per_vote_pay = 0; } int64_t total_pay = producer_per_block_pay + producer_per_vote_pay; diff --git a/voting.cpp b/voting.cpp index 4b850c2d..feb40d55 100644 --- a/voting.cpp +++ b/voting.cpp @@ -167,6 +167,9 @@ namespace eosiosystem { */ if( voter->last_vote_weight <= 0.0 ) { _gstate.total_activated_stake += voter->staked; + if( _gstate.total_activated_stake >= min_activated_stake ) { + _gstate.thresh_activated_stake_time = current_time(); + } } auto new_vote_weight = stake2vote( voter->staked ); From 6d520133472a15fcb4f02e78b39bd4f8867f8a0c Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 21 May 2018 12:04:52 -0400 Subject: [PATCH 0282/1048] system contract: unit-test for taking stake from pednding refund #3213 bugfix #3180 --- delegate_bandwidth.cpp | 4 ++++ eosio.system.abi | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 0eb77a59..166f2183 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -303,11 +303,15 @@ namespace eosiosystem { if ( r.net_amount < asset(0) ) { net_balance = -r.net_amount; r.net_amount = asset(0); + } else { + net_balance = asset(0); } r.cpu_amount -= cpu_balance; if ( r.cpu_amount < asset(0) ){ cpu_balance = -r.cpu_amount; r.cpu_amount = asset(0); + } else { + cpu_balance = asset(0); } }); eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen diff --git a/eosio.system.abi b/eosio.system.abi index 0e11106d..d5b98c45 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -207,7 +207,8 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"request_time", "type":"time_point_sec"}, - {"name":"amount", "type":"uint64"} + {"name":"net_amount", "type":"asset"}, + {"name":"cpu_amount", "type":"asset"} ] },{ "name": "blockchain_parameters", From 91d3030669cd28f422419102c9252fa288dd39d0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 21 May 2018 19:44:03 -0400 Subject: [PATCH 0283/1048] Test multiple name auctions going in parallel - #3208 --- producer_pay.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index f06cee95..1aea6e72 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -55,12 +55,13 @@ namespace eosiosystem { auto idx = bids.get_index(); auto highest = idx.begin(); if( highest != idx.end() && - highest->high_bid > 0 && + highest->high_bid > 0 && highest->last_bid_time < (current_time() - useconds_per_day) && - (current_time() - _gstate.thresh_activated_stake_time) > 14 * useconds_per_day ){ - _gstate.last_name_close = timestamp; - idx.modify( highest, 0, [&]( auto& b ){ - b.high_bid = -b.high_bid; + _gstate.thresh_activated_stake_time > 0 && + (current_time() - _gstate.thresh_activated_stake_time) > 14 * useconds_per_day ) { + _gstate.last_name_close = timestamp; + idx.modify( highest, 0, [&]( auto& b ){ + b.high_bid = -b.high_bid; }); } } From bec48d6a9864d5aa09dbfc9bd03c010303190183 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 22 May 2018 16:52:54 -0400 Subject: [PATCH 0284/1048] Segregate EOSIO.SYSTEM funds #3291 - all ram trading fees sent from user to eosio.ramfee (also implement 1% fee Fix #3182) - all tokens received for ram sent to eosio.ram - all proceeds from selling ram sent from eosio.ram - all staked tokens sent to eosio.stake - all unstaked tokens sent from eosio.stake - fix build dependency issue with ram_tests --- delegate_bandwidth.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 181f3ca3..c6600dce 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -107,24 +107,32 @@ namespace eosiosystem { require_auth( payer ); eosio_assert( quant.amount > 0, "must purchase a positive amount" ); + auto fee = quant; + fee.amount /= 200; /// .5% fee + auto quant_after_fee = quant; + quant_after_fee.amount -= fee.amount; + if( payer != N(eosio) ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, - { payer, N(eosio), quant, std::string("buy ram") } ); + { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } ); } + if( fee.amount > 0 ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, + { payer, N(eosio.ramfee), fee, std::string("ram fee") } ); + } int64_t bytes_out; auto itr = _rammarket.find(S(4,RAMCORE)); _rammarket.modify( itr, 0, [&]( auto& es ) { - bytes_out = es.convert( quant, S(0,RAM) ).amount; + bytes_out = es.convert( quant_after_fee, S(0,RAM) ).amount; }); - eosio_assert( bytes_out > 0, "must reserve a positive amount" ); _gstate.total_ram_bytes_reserved += uint64_t(bytes_out); - _gstate.total_ram_stake += quant.amount; + _gstate.total_ram_stake += quant_after_fee.amount; user_resources_table userres( _self, receiver ); auto res_itr = userres.find( receiver ); @@ -176,7 +184,12 @@ namespace eosiosystem { if( N(eosio) != account ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), account, asset(tokens_out), std::string("sell ram") } ); + { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); + auto fee = tokens_out.amount / 200; + if( fee > 0 ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); + } } } @@ -317,7 +330,7 @@ namespace eosiosystem { auto transfer_amount = net_balance + cpu_balance; if ( asset(0) < transfer_amount ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { source_stake_from, N(eosio), asset(transfer_amount), std::string("stake bandwidth") } ); + { source_stake_from, N(eosio.stake), asset(transfer_amount), std::string("stake bandwidth") } ); } } @@ -380,7 +393,7 @@ namespace eosiosystem { // consecutive missed blocks. INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); + { N(eosio.stake), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); refunds_tbl.erase( req ); } From af263d12d95f26f185945e5813bbd0d67cb72a2b Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 22 May 2018 18:05:19 -0400 Subject: [PATCH 0285/1048] Segregate producer vote pay, producer block pay, and savings #3291 --- producer_pay.cpp | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 22bbdb51..79ded8c4 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -95,6 +95,15 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, {N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), N(eosio.saving), asset(to_savings), "unllocated inflation" } ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), N(eosio.bpay), asset(to_per_block_pay), "fund per-block bucket" } ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), N(eosio.vpay), asset(to_per_vote_pay), "fund per-vote bucket" } ); + _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; _gstate.savings += to_savings; @@ -113,8 +122,6 @@ namespace eosiosystem { if( producer_per_vote_pay < min_pervote_daily_pay ) { producer_per_vote_pay = 0; } - int64_t total_pay = producer_per_block_pay + producer_per_vote_pay; - _gstate.pervote_bucket -= producer_per_vote_pay; _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.unpaid_blocks; @@ -124,9 +131,13 @@ namespace eosiosystem { p.unpaid_blocks = 0; }); - if( total_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), owner, asset(total_pay), std::string("producer pay") } ); + if( producer_per_block_pay > 0 ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.bpay),N(active)}, + { N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } ); + } + if( producer_per_vote_pay > 0 ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.vpay),N(active)}, + { N(eosio.vpay), owner, asset(producer_per_vote_pay), std::string("producer vote pay") } ); } } From 1cff9c345615b5d0822f28eb733daa3c2f173de5 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 22 May 2018 21:54:50 -0400 Subject: [PATCH 0286/1048] system contract should only allow producers to increase ram #3302 --- eosio.system.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/eosio.system.cpp b/eosio.system.cpp index 3cb39b8c..6034468a 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -54,6 +54,7 @@ namespace eosiosystem { void system_contract::setram( uint64_t max_ram_size ) { require_auth( _self ); + eosio_assert( _gstate.max_ram_size < max_ram_size, "ram can only be increased" ); /// decreasing ram might result market maker issues eosio_assert( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" ); eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); From 757141231b89ccc29595f736b4a23c2ecd17a4eb Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 22 May 2018 22:29:01 -0400 Subject: [PATCH 0287/1048] Fix #3302 - eosio contract can only increase ram --- eosio.system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 6034468a..a54473bf 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -54,7 +54,7 @@ namespace eosiosystem { void system_contract::setram( uint64_t max_ram_size ) { require_auth( _self ); - eosio_assert( _gstate.max_ram_size < max_ram_size, "ram can only be increased" ); /// decreasing ram might result market maker issues + eosio_assert( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues eosio_assert( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" ); eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); From 9801410353eb4aeaaa41ed5731383947505aa2e4 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 22 May 2018 23:48:54 -0400 Subject: [PATCH 0288/1048] fix bug in staking to another account with transfer #3309 --- delegate_bandwidth.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 181f3ca3..157fbbe3 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -73,7 +73,7 @@ namespace eosiosystem { }; /** - * These tables are designed to be constructed in the scope of the relevant user, this + * These tables are designed to be constructed in the scope of the relevant user, this * facilitates simpler API for per-user queries */ typedef eosio::multi_index< N(userres), user_resources> user_resources_table; @@ -100,9 +100,9 @@ namespace eosiosystem { * storage of all database records associated with this action. * * RAM is a scarce resource whose supply is defined by global properties max_ram_size. RAM is - * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. + * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. */ - void system_contract::buyram( account_name payer, account_name receiver, asset quant ) + void system_contract::buyram( account_name payer, account_name receiver, asset quant ) { require_auth( payer ); eosio_assert( quant.amount > 0, "must purchase a positive amount" ); @@ -316,7 +316,7 @@ namespace eosiosystem { auto transfer_amount = net_balance + cpu_balance; if ( asset(0) < transfer_amount ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {source_stake_from, N(active)}, { source_stake_from, N(eosio), asset(transfer_amount), std::string("stake bandwidth") } ); } } From 8cb5c699dedd99472dab45f867cab5fd99e6734b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 23 May 2018 09:39:44 -0400 Subject: [PATCH 0289/1048] Authority, some system contract test fixes --- delegate_bandwidth.cpp | 4 ++-- producer_pay.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index c6600dce..c353b818 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -183,11 +183,11 @@ namespace eosiosystem { set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); if( N(eosio) != account ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.ram),N(active)}, { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); auto fee = tokens_out.amount / 200; if( fee > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); } } diff --git a/producer_pay.cpp b/producer_pay.cpp index 79ded8c4..65cefba2 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -96,7 +96,7 @@ namespace eosiosystem { {N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.saving), asset(to_savings), "unllocated inflation" } ); + { N(eosio), N(eosio.saving), asset(to_savings), "unallocated inflation" } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, { N(eosio), N(eosio.bpay), asset(to_per_block_pay), "fund per-block bucket" } ); From 9f847b9dab6fead895d97d1ecb7196b339715c08 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 23 May 2018 13:48:37 -0400 Subject: [PATCH 0290/1048] Fix #3315 - unable to create 12 char names (by non-eosio accounts) - added print(char) API - added unit test to validate create 12 --- eosio.system.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index a54473bf..1e491e44 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -134,11 +134,12 @@ namespace eosiosystem { const authority& active*/ ) { if( creator != _self ) { - auto tmp = newact; + auto tmp = newact >> 4; bool has_dot = false; - for( uint32_t i = 0; i < 13; ++i ) { - has_dot |= (tmp >> 59); - tmp <<= 5; + + for( uint32_t i = 0; i < 12; ++i ) { + has_dot |= !(tmp & 0x1f); + tmp >>= 5; } auto suffix = eosio::name_suffix(newact); if( has_dot ) { From 65ae0b166ceb42b16ce4fa88f376172964c4e8be Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 23 May 2018 15:12:43 -0400 Subject: [PATCH 0291/1048] Move builtin types to types.hpp so that account_name can be name --- delegate_bandwidth.cpp | 24 ++++++++++++------------ eosio.system.cpp | 12 ++++++------ eosio.system.hpp | 7 ++++--- native.hpp | 2 ++ producer_pay.cpp | 10 +++++----- 5 files changed, 29 insertions(+), 26 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 181f3ca3..9909d49a 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -28,8 +28,8 @@ namespace eosiosystem { using std::map; using std::pair; - static constexpr time refund_delay = 3*24*3600; - static constexpr time refund_expiration_time = 3600; + static constexpr uint32_t refund_delay = 3*24*3600; + static constexpr uint32_t refund_expiration_time = 3600; struct user_resources { account_name owner; @@ -62,7 +62,7 @@ namespace eosiosystem { struct refund_request { account_name owner; - time request_time; + uint32_t request_time; eosio::asset net_amount; eosio::asset cpu_amount; @@ -108,8 +108,8 @@ namespace eosiosystem { eosio_assert( quant.amount > 0, "must purchase a positive amount" ); if( payer != N(eosio) ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, - { payer, N(eosio), quant, std::string("buy ram") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {payer,NAME(active)}, + { payer, NAME(eosio), quant, std::string("buy ram") } ); } @@ -175,8 +175,8 @@ namespace eosiosystem { set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); if( N(eosio) != account ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), account, asset(tokens_out), std::string("sell ram") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, + { NAME(eosio), account, asset(tokens_out), std::string("sell ram") } ); } } @@ -307,7 +307,7 @@ namespace eosiosystem { if ( need_deferred_trx ) { eosio::transaction out; - out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); + out.actions.emplace_back( permission_level{ from, NAME(active) }, _self, NAME(refund), from ); out.delay_sec = refund_delay; out.send( from, receiver, true ); } else { @@ -316,8 +316,8 @@ namespace eosiosystem { auto transfer_amount = net_balance + cpu_balance; if ( asset(0) < transfer_amount ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { source_stake_from, N(eosio), asset(transfer_amount), std::string("stake bandwidth") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {from,NAME(active)}, + { source_stake_from, NAME(eosio), asset(transfer_amount), std::string("stake bandwidth") } ); } } @@ -379,8 +379,8 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, + { NAME(eosio), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); refunds_tbl.erase( req ); } diff --git a/eosio.system.cpp b/eosio.system.cpp index 3cb39b8c..17d41739 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -22,7 +22,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); if( itr == _rammarket.end() ) { - auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; + auto system_token_supply = eosio::token(NAME(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; if( system_token_supply > 0 ) { itr = _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; @@ -84,8 +84,8 @@ namespace eosiosystem { eosio_assert( bid.symbol == asset().symbol, "asset must be system token" ); eosio_assert( bid.amount > 0, "insufficient bid" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {bidder,N(active)}, - { bidder, N(eosio), bid, std::string("bid name ")+(name{newname}).to_string() } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {bidder,NAME(active)}, + { bidder, NAME(eosio), bid, std::string("bid name ")+(name{newname}).to_string() } ); name_bid_table bids(_self,_self); print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); @@ -102,8 +102,8 @@ namespace eosiosystem { eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); eosio_assert( current->high_bidder != bidder, "account is already high bidder" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), current->high_bidder, asset(current->high_bid), + INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, + { NAME(eosio), current->high_bidder, asset(current->high_bid), std::string("refund bid on name ")+(name{newname}).to_string() } ); bids.modify( current, bidder, [&]( auto& b ) { @@ -133,7 +133,7 @@ namespace eosiosystem { const authority& active*/ ) { if( creator != _self ) { - auto tmp = newact; + uint64_t tmp = newact; bool has_dot = false; for( uint32_t i = 0; i < 13; ++i ) { has_dot |= (tmp >> 59); diff --git a/eosio.system.hpp b/eosio.system.hpp index 70e0778f..9b8a133f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -15,6 +15,7 @@ namespace eosiosystem { + using eosio::account_name; using eosio::asset; using eosio::indexed_by; using eosio::const_mem_fun; @@ -92,8 +93,8 @@ namespace eosiosystem { }; struct voter_info { - account_name owner = 0; /// the voter - account_name proxy = 0; /// the proxy set by the voter, if any + account_name owner = {}; /// the voter + account_name proxy = {}; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set int64_t staked = 0; @@ -113,7 +114,7 @@ namespace eosiosystem { uint32_t deferred_trx_id = 0; /// the ID of the 3-day delay deferred transaction - time last_unstake_time = 0; /// the time when the deferred_trx_id was sent + uint32_t last_unstake_time = 0; /// the time when the deferred_trx_id was sent eosio::asset unstaking; /// the total unstaking (pending 3 day delay) uint64_t primary_key()const { return owner; } diff --git a/native.hpp b/native.hpp index 3a9bed79..3c0164a8 100644 --- a/native.hpp +++ b/native.hpp @@ -14,8 +14,10 @@ #include namespace eosiosystem { + using eosio::account_name; using eosio::permission_level; using eosio::public_key; + using eosio::weight_type; typedef std::vector bytes; diff --git a/producer_pay.cpp b/producer_pay.cpp index 22bbdb51..0a7e27ca 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -81,7 +81,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" ); - const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); + const asset token_supply = token( NAME(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill; if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > 0 ) { @@ -92,8 +92,8 @@ namespace eosiosystem { auto to_per_block_pay = to_producers / 4; auto to_per_vote_pay = to_producers - to_per_block_pay; - INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - {N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); + INLINE_ACTION_SENDER(eosio::token, issue)( NAME(eosio.token), {{NAME(eosio),NAME(active)}}, + {NAME(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; @@ -125,8 +125,8 @@ namespace eosiosystem { }); if( total_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), owner, asset(total_pay), std::string("producer pay") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, + { NAME(eosio), owner, asset(total_pay), std::string("producer pay") } ); } } From d279c3b913920ed97d5e7994c31f8237fc6b399d Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 23 May 2018 15:54:07 -0400 Subject: [PATCH 0292/1048] Revert "Move builtin types to types.hpp so that account_name can be name" This reverts commit 3b5e03dffb10f375c17abe6ea6e5c71738bfe786. --- delegate_bandwidth.cpp | 24 ++++++++++++------------ eosio.system.cpp | 12 ++++++------ eosio.system.hpp | 7 +++---- native.hpp | 2 -- producer_pay.cpp | 10 +++++----- 5 files changed, 26 insertions(+), 29 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 9909d49a..181f3ca3 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -28,8 +28,8 @@ namespace eosiosystem { using std::map; using std::pair; - static constexpr uint32_t refund_delay = 3*24*3600; - static constexpr uint32_t refund_expiration_time = 3600; + static constexpr time refund_delay = 3*24*3600; + static constexpr time refund_expiration_time = 3600; struct user_resources { account_name owner; @@ -62,7 +62,7 @@ namespace eosiosystem { struct refund_request { account_name owner; - uint32_t request_time; + time request_time; eosio::asset net_amount; eosio::asset cpu_amount; @@ -108,8 +108,8 @@ namespace eosiosystem { eosio_assert( quant.amount > 0, "must purchase a positive amount" ); if( payer != N(eosio) ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {payer,NAME(active)}, - { payer, NAME(eosio), quant, std::string("buy ram") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, + { payer, N(eosio), quant, std::string("buy ram") } ); } @@ -175,8 +175,8 @@ namespace eosiosystem { set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); if( N(eosio) != account ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, - { NAME(eosio), account, asset(tokens_out), std::string("sell ram") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), account, asset(tokens_out), std::string("sell ram") } ); } } @@ -307,7 +307,7 @@ namespace eosiosystem { if ( need_deferred_trx ) { eosio::transaction out; - out.actions.emplace_back( permission_level{ from, NAME(active) }, _self, NAME(refund), from ); + out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); out.delay_sec = refund_delay; out.send( from, receiver, true ); } else { @@ -316,8 +316,8 @@ namespace eosiosystem { auto transfer_amount = net_balance + cpu_balance; if ( asset(0) < transfer_amount ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {from,NAME(active)}, - { source_stake_from, NAME(eosio), asset(transfer_amount), std::string("stake bandwidth") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { source_stake_from, N(eosio), asset(transfer_amount), std::string("stake bandwidth") } ); } } @@ -379,8 +379,8 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, - { NAME(eosio), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); refunds_tbl.erase( req ); } diff --git a/eosio.system.cpp b/eosio.system.cpp index 17d41739..3cb39b8c 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -22,7 +22,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); if( itr == _rammarket.end() ) { - auto system_token_supply = eosio::token(NAME(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; + auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; if( system_token_supply > 0 ) { itr = _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; @@ -84,8 +84,8 @@ namespace eosiosystem { eosio_assert( bid.symbol == asset().symbol, "asset must be system token" ); eosio_assert( bid.amount > 0, "insufficient bid" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {bidder,NAME(active)}, - { bidder, NAME(eosio), bid, std::string("bid name ")+(name{newname}).to_string() } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {bidder,N(active)}, + { bidder, N(eosio), bid, std::string("bid name ")+(name{newname}).to_string() } ); name_bid_table bids(_self,_self); print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); @@ -102,8 +102,8 @@ namespace eosiosystem { eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); eosio_assert( current->high_bidder != bidder, "account is already high bidder" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, - { NAME(eosio), current->high_bidder, asset(current->high_bid), + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), current->high_bidder, asset(current->high_bid), std::string("refund bid on name ")+(name{newname}).to_string() } ); bids.modify( current, bidder, [&]( auto& b ) { @@ -133,7 +133,7 @@ namespace eosiosystem { const authority& active*/ ) { if( creator != _self ) { - uint64_t tmp = newact; + auto tmp = newact; bool has_dot = false; for( uint32_t i = 0; i < 13; ++i ) { has_dot |= (tmp >> 59); diff --git a/eosio.system.hpp b/eosio.system.hpp index 9b8a133f..70e0778f 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -15,7 +15,6 @@ namespace eosiosystem { - using eosio::account_name; using eosio::asset; using eosio::indexed_by; using eosio::const_mem_fun; @@ -93,8 +92,8 @@ namespace eosiosystem { }; struct voter_info { - account_name owner = {}; /// the voter - account_name proxy = {}; /// the proxy set by the voter, if any + account_name owner = 0; /// the voter + account_name proxy = 0; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set int64_t staked = 0; @@ -114,7 +113,7 @@ namespace eosiosystem { uint32_t deferred_trx_id = 0; /// the ID of the 3-day delay deferred transaction - uint32_t last_unstake_time = 0; /// the time when the deferred_trx_id was sent + time last_unstake_time = 0; /// the time when the deferred_trx_id was sent eosio::asset unstaking; /// the total unstaking (pending 3 day delay) uint64_t primary_key()const { return owner; } diff --git a/native.hpp b/native.hpp index 3c0164a8..3a9bed79 100644 --- a/native.hpp +++ b/native.hpp @@ -14,10 +14,8 @@ #include namespace eosiosystem { - using eosio::account_name; using eosio::permission_level; using eosio::public_key; - using eosio::weight_type; typedef std::vector bytes; diff --git a/producer_pay.cpp b/producer_pay.cpp index 0a7e27ca..22bbdb51 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -81,7 +81,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" ); - const asset token_supply = token( NAME(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); + const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill; if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > 0 ) { @@ -92,8 +92,8 @@ namespace eosiosystem { auto to_per_block_pay = to_producers / 4; auto to_per_vote_pay = to_producers - to_per_block_pay; - INLINE_ACTION_SENDER(eosio::token, issue)( NAME(eosio.token), {{NAME(eosio),NAME(active)}}, - {NAME(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); + INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, + {N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; @@ -125,8 +125,8 @@ namespace eosiosystem { }); if( total_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( NAME(eosio.token), {NAME(eosio),NAME(active)}, - { NAME(eosio), owner, asset(total_pay), std::string("producer pay") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + { N(eosio), owner, asset(total_pay), std::string("producer pay") } ); } } From 94c29eda9fcc8368b2632de49fed9471964854c7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 23 May 2018 15:57:57 -0400 Subject: [PATCH 0293/1048] System contract fixes --- delegate_bandwidth.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index c353b818..628d0b89 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -196,7 +196,7 @@ namespace eosiosystem { void validate_b1_vesting( int64_t stake ) { const int64_t seconds_per_year = 60*60*24*365; const int64_t base_time = 1527811200; /// 2018-06-01 - const int64_t max_claimable = 100'000'000'0000ll; + const int64_t max_claimable = 100'000'000'0000ll; // ' const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / (10*seconds_per_year) ); eosio_assert( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); @@ -208,6 +208,8 @@ namespace eosiosystem { require_auth( from ); eosio_assert( stake_net_delta != asset(0) || stake_cpu_delta != asset(0), "should stake non-zero amount" ); + print(from, " ", receiver, " ", stake_net_delta, " ", stake_cpu_delta); + account_name source_stake_from = from; if ( transfer ) { from = receiver; @@ -265,7 +267,7 @@ namespace eosiosystem { } // tot_itr can be invalid, should go out of scope // create refund or update from existing refund - if ( N(eosio) != source_stake_from ) { //for eosio both transfer and refund make no sense + if ( N(eosio.stake) != source_stake_from ) { //for eosio both transfer and refund make no sense refunds_table refunds_tbl( _self, from ); auto req = refunds_tbl.find( from ); @@ -392,7 +394,9 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, + print(req->net_amount, " ", req->cpu_amount); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.stake),N(active)}, { N(eosio.stake), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); refunds_tbl.erase( req ); From ba79eee775cc8181756bf26edda5e7840f78d6ba Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 23 May 2018 16:15:38 -0400 Subject: [PATCH 0294/1048] Tiny change --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 6080856f..e945b592 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -196,7 +196,7 @@ namespace eosiosystem { void validate_b1_vesting( int64_t stake ) { const int64_t seconds_per_year = 60*60*24*365; const int64_t base_time = 1527811200; /// 2018-06-01 - const int64_t max_claimable = 100'000'000'0000ll; // ' + const int64_t max_claimable = 100'000'000'0000ll; const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / (10*seconds_per_year) ); eosio_assert( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); From 8af02f97a1089e818abc2e4362d37f00462c69c1 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 23 May 2018 20:38:32 -0400 Subject: [PATCH 0295/1048] Fix #3344 producer-deactivated by increasing the timeout 100x to about 3-4 hours --- voting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 4ecc2ae3..822e9a38 100644 --- a/voting.cpp +++ b/voting.cpp @@ -84,7 +84,7 @@ namespace eosiosystem { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); - } else if ( block_time.slot > 2 * 21 * 12 + it->time_became_active.slot && + } else if ( block_time.slot > (2 * 21 * 12*100) + it->time_became_active.slot && block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) { _producers.modify( *it, 0, [&](auto& p) { p.producer_key = public_key(); From 3f1ec83ce17139c3bbf4d9c92f1814d0513240ee Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 23 May 2018 20:51:36 -0400 Subject: [PATCH 0296/1048] fix unit tests for producer-deactivation, #3344 --- producer_pay.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 65cefba2..c497cc15 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -47,10 +47,7 @@ namespace eosiosystem { if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) { update_elected_producers( timestamp ); - print( "maybe update bids \n" ); - if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { - print( "update bids" ); name_bid_table bids(_self,_self); auto idx = bids.get_index(); auto highest = idx.begin(); From c1bffb9144fe3d2213e98ef8855ea6af466d4e5b Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 23 May 2018 21:08:32 -0400 Subject: [PATCH 0297/1048] segregate auction proceeds, Fix #3352 --- eosio.system.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 1e491e44..667a2279 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -86,7 +86,7 @@ namespace eosiosystem { eosio_assert( bid.amount > 0, "insufficient bid" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {bidder,N(active)}, - { bidder, N(eosio), bid, std::string("bid name ")+(name{newname}).to_string() } ); + { bidder, N(eosio.names), bid, std::string("bid name ")+(name{newname}).to_string() } ); name_bid_table bids(_self,_self); print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); @@ -103,8 +103,8 @@ namespace eosiosystem { eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); eosio_assert( current->high_bidder != bidder, "account is already high bidder" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), current->high_bidder, asset(current->high_bid), + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.names),N(active)}, + { N(eosio.names), current->high_bidder, asset(current->high_bid), std::string("refund bid on name ")+(name{newname}).to_string() } ); bids.modify( current, bidder, [&]( auto& b ) { From 2a682b1a330e038c8add78759d2131e29b4340ce Mon Sep 17 00:00:00 2001 From: Greg Lee Date: Wed, 23 May 2018 22:31:45 -0400 Subject: [PATCH 0298/1048] Whitespace --- voting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 822e9a38..0c4d5616 100644 --- a/voting.cpp +++ b/voting.cpp @@ -84,7 +84,7 @@ namespace eosiosystem { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); - } else if ( block_time.slot > (2 * 21 * 12*100) + it->time_became_active.slot && + } else if ( block_time.slot > (2 * 21 * 12 * 100) + it->time_became_active.slot && block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) { _producers.modify( *it, 0, [&](auto& p) { p.producer_key = public_key(); From 7012d4bf31dfc9e7b41778d999996e3a6ce2f0af Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 23 May 2018 22:52:29 -0400 Subject: [PATCH 0299/1048] remove max_generated_transaction_count #3343 --- eosio.system.abi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 51371505..dcf903eb 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -239,8 +239,7 @@ {"name":"max_transaction_delay", "type":"uint32"}, {"name":"max_inline_action_size", "type":"uint32"}, {"name":"max_inline_action_depth", "type":"uint16"}, - {"name":"max_authority_depth", "type":"uint16"}, - {"name":"max_generated_transaction_count", "type":"uint32"} + {"name":"max_authority_depth", "type":"uint16"} ] },{ From 53cbbc15189359522dacf2805c8f09d2b77ce201 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 24 May 2018 10:44:46 -0400 Subject: [PATCH 0300/1048] initial drafts of Ricardian Contracts. These are initial drafts of the Ricardian contracts for each System contract action. This may include some private system actions that shouldn't have RCs. Many have the purpose listed as 'unknown' and the contract intention is blank -- these need to be added by someone who understands the current source code. --- eosio.system-bidname-rc.md | 19 +++++++++++++++ eosio.system-buyram-rc.md | 19 +++++++++++++++ eosio.system-buyrambytes-rc.md | 19 +++++++++++++++ eosio.system-canceldelay-rc.md | 19 +++++++++++++++ eosio.system-claimrewards-rc.md | 19 +++++++++++++++ eosio.system-delegatebw-rc.md | 24 +++++++++++++++++++ eosio.system-deleteauth-rc.md | 19 +++++++++++++++ eosio.system-linkauth-rc.md | 19 +++++++++++++++ eosio.system-newaccount-rc.md | 19 +++++++++++++++ eosio.system-onerror-rc.md | 19 +++++++++++++++ eosio.system-rc.md | 41 +++++++++++++++++++++++++++++++++ eosio.system-refund-rc.md | 20 ++++++++++++++++ eosio.system-regproducer-rc.md | 15 ++++++++++++ eosio.system-regproxy-rc.md | 19 +++++++++++++++ eosio.system-reqauth-rc.md | 19 +++++++++++++++ eosio.system-sellram-rc.md | 19 +++++++++++++++ eosio.system-setabi-rc.md | 19 +++++++++++++++ eosio.system-setalimits-rc.md | 20 ++++++++++++++++ eosio.system-setcode-rc.md | 19 +++++++++++++++ eosio.system-setglimits-rc.md | 19 +++++++++++++++ eosio.system-setpriv-rc.md | 19 +++++++++++++++ eosio.system-setprods-rc.md | 22 ++++++++++++++++++ eosio.system-setram-rc.md | 19 +++++++++++++++ eosio.system-undelegatebw-rc.md | 17 ++++++++++++++ eosio.system-unlinkauth-rc.md | 20 ++++++++++++++++ eosio.system-unregprod-rc.md | 19 +++++++++++++++ eosio.system-updateauth-rc.md | 19 +++++++++++++++ 27 files changed, 540 insertions(+) create mode 100644 eosio.system-bidname-rc.md create mode 100644 eosio.system-buyram-rc.md create mode 100644 eosio.system-buyrambytes-rc.md create mode 100644 eosio.system-canceldelay-rc.md create mode 100644 eosio.system-claimrewards-rc.md create mode 100644 eosio.system-delegatebw-rc.md create mode 100644 eosio.system-deleteauth-rc.md create mode 100644 eosio.system-linkauth-rc.md create mode 100644 eosio.system-newaccount-rc.md create mode 100644 eosio.system-onerror-rc.md create mode 100644 eosio.system-rc.md create mode 100644 eosio.system-refund-rc.md create mode 100644 eosio.system-regproducer-rc.md create mode 100644 eosio.system-regproxy-rc.md create mode 100644 eosio.system-reqauth-rc.md create mode 100644 eosio.system-sellram-rc.md create mode 100644 eosio.system-setabi-rc.md create mode 100644 eosio.system-setalimits-rc.md create mode 100644 eosio.system-setcode-rc.md create mode 100644 eosio.system-setglimits-rc.md create mode 100644 eosio.system-setpriv-rc.md create mode 100644 eosio.system-setprods-rc.md create mode 100644 eosio.system-setram-rc.md create mode 100644 eosio.system-undelegatebw-rc.md create mode 100644 eosio.system-unlinkauth-rc.md create mode 100644 eosio.system-unregprod-rc.md create mode 100644 eosio.system-updateauth-rc.md diff --git a/eosio.system-bidname-rc.md b/eosio.system-bidname-rc.md new file mode 100644 index 00000000..87b11b13 --- /dev/null +++ b/eosio.system-bidname-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ bidname }}` + +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 `{{ bidname }}` action places a bid on a premium account name, in the knowledge that the high bid will purchase the name. + +### Inputs and Input Types + +The `{{ bidname }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ bidname }}` | `{{ bidderVar }}`
`{{ newnameVar }}`
`{{ bidVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | + +As an authorized party I {{ signer }} wish to bid on behalf of {{ bidderVar }} the amount of {{ bidVar }} toward purchase of the account name {{ newnameVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-buyram-rc.md b/eosio.system-buyram-rc.md new file mode 100644 index 00000000..d6ff406d --- /dev/null +++ b/eosio.system-buyram-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ buyram }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ buyram }}` action... + +### Inputs and Input Types + +The `{{ buyram }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ buyram }}` | `{{ payerVar }}`
`{{ receiverVar }}`
`{{ quantVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | + +As an authorized party I {{ signer }} wish to buy {{ quantVar }} worth of RAM using the funds of {{ payerVar }} with the RAM to be owned by and be the property of {{ receiverVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-buyrambytes-rc.md b/eosio.system-buyrambytes-rc.md new file mode 100644 index 00000000..b37b59c2 --- /dev/null +++ b/eosio.system-buyrambytes-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ buyrambytes }}` + +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 `{{ buyrambytes }}` action... + +### Inputs and Input Types + +The `{{ buyrambytes }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ buyrambytes }}` | `{{ payerVar }}`
`{{ receiverVar }}`
`{{ bytesVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ uint32 }}` | + +As an authorized party I {{ signer }} wish to buy {{ bytesVar }} bytes of RAM at the current price using the funds of {{ payerVar }} with the RAM to be owned by and be the property of {{ receiverVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-canceldelay-rc.md b/eosio.system-canceldelay-rc.md new file mode 100644 index 00000000..db68ca85 --- /dev/null +++ b/eosio.system-canceldelay-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ canceldelay }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ canceldelay }}` action cancels an existing delayed transaction. + +### Inputs and Input Types + +The `{{ canceldelay }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ canceldelay }}` | `{{ canceling_authVar }}`
`{{ trx_idVar }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | + +As an authorized party I {{ signer }} wish to invoke the authority of {{ canceling_authVar }} to cancel the transaction with ID {{ trx_idVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-claimrewards-rc.md b/eosio.system-claimrewards-rc.md new file mode 100644 index 00000000..8470bcb2 --- /dev/null +++ b/eosio.system-claimrewards-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ claimrewards }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ claimrewards }}` action allows a block producer (active or standby) to claim the system rewards due them for producing blocks and receiving votes. + +### Input and Input Type + +The `{{ claimrewards }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ claimrewards }}` | `{{ ownerVar }}` | `{{ account_name }}` | + +As an authorized party I {{ signer }} wish to have the rewards earned by {{ ownerVar }} deposited into their (my) account. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-delegatebw-rc.md b/eosio.system-delegatebw-rc.md new file mode 100644 index 00000000..904d43db --- /dev/null +++ b/eosio.system-delegatebw-rc.md @@ -0,0 +1,24 @@ +# eosio.system delegatebw + +This Ricardian contract for the system action *delegatebw* is legally binding and can be used in the event of a dispute. + +## delegatebw + (account_name-from; + account_name-to; + asset-stake_net_quantity; + asset-stake_cpu_quantity; + bool:transfer) + +_Intent: stake tokens for bandwidth and/or CPU and optionally transfer ownership_ + +As an authorized party I {{ signer }} wish to stake {{ asset-stake_cpu_quantity }} for CPU and {{ asset-stake_net_quantity }} for bandwidth from the liquid tokens of {{ account_name-from }} for the use of delegatee {{ account_name-to }}. + + {{if bool:transfer }} + +It is {{ bool:transfer }} that I wish these tokens to become immediately owned by the delegatee. + + {{/if}} + +As signer I stipulate that, if I am not the beneficial owner of these tokens, I have proof that I’ve been authorized to take this action by their beneficial owner(s). + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-deleteauth-rc.md b/eosio.system-deleteauth-rc.md new file mode 100644 index 00000000..fc1db915 --- /dev/null +++ b/eosio.system-deleteauth-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ deleteauth }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ deleteauth }}` action... + +### Inputs and Input Types + +The `{{ deleteauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ deleteauth }}` | `{{ accountVar }}`
`{{ permissionVar }}` | `{{ account_name }}`
`{{ permission_name }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-linkauth-rc.md b/eosio.system-linkauth-rc.md new file mode 100644 index 00000000..9ba584cf --- /dev/null +++ b/eosio.system-linkauth-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ linkauth }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ linkauth }}` action... + +### Inputs and Input Types + +The `{{ linkauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ linkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}`
`{{ requirementVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-newaccount-rc.md b/eosio.system-newaccount-rc.md new file mode 100644 index 00000000..1392f41a --- /dev/null +++ b/eosio.system-newaccount-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ newaccount }}` + +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 `{{ newaccount }}` action creates a new account. + +### Inputs and Input Types + +The `{{ newaccount }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ newaccount }}` | `{{ creatorVar }}`
`{{ nameVar }}`
`{{ ownerVar }}`
`{{ activeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | + +As an authorized party I {{ signer }} wish to exercise the authority of {{ creatorVar }} to create a new account on this system named {{ nameVar }} such that the new account's owner public key shall be {{ ownerVar }} and the active public key shall be {{ activeVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-onerror-rc.md b/eosio.system-onerror-rc.md new file mode 100644 index 00000000..7b8755ec --- /dev/null +++ b/eosio.system-onerror-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ onerror }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ onerror }}` action... + +### Inputs and Input Types + +The `{{ onerror }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ onerror }}` | `{{ sender_idVar }}`
`{{ sent_trxVar }}` | `{{ uint128 }}`
`{{ bytes }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-rc.md b/eosio.system-rc.md new file mode 100644 index 00000000..8919cbae --- /dev/null +++ b/eosio.system-rc.md @@ -0,0 +1,41 @@ +# Smart Contract - `{{ eosio.system }}` + +This is an overview of the actions for the `{{ eosio.system }}` 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 `{{ eosio.system }}` contract... + +### Actions, Inputs and Input Types + +The table below contains the `actions`, `inputs` and `input types` for the `{{ eosio.system }}` contract. + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ newaccount }}` | `{{ creator }}`
`{{ name }}`
`{{ owner }}`
`{{ active }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | +| `{{ setcode }}` | `{{ account }}`
`{{ vmtype }}`
`{{ vmversion }}`
`{{ code }}` | `{{ account_name }}`
`{{ uint8 }}`
`{{ uint8 }}`
`{{ bytes }}` | +| `{{ setabi }}` | `{{ account }}`
`{{ abi }}` | `{{ account_name }}`
`{{ bytes }}` | +| `{{ updateauth }}` | `{{ account }}`
`{{ permission }}`
`{{ parent }}`
`{{ auth }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | +| `{{ deleteauth }}` | `{{ account }}`
`{{ permission }}` | `{{ account_name }}`
`{{ permission_name }}` | +| `{{ linkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}`
`{{ requirement }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | +| `{{ unlinkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | +| `{{ canceldelay }}` | `{{ canceling_auth }}`
`{{ trx_id }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | +| `{{ onerror }}` | `{{ sender_id }}`
`{{ sent_trx }}` | `{{ uint128 }}`
`{{ bytes }}` | +| `{{ buyrambytes }}` | `{{ payer }}`
`{{ receiver }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ uint32 }}` | +| `{{ buyram }}` | `{{ payer }}`
`{{ receiver }}`
`{{ quant }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | +| `{{ sellram }}` | `{{ account }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ uint64 }}` | +| `{{ delegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ stake_net_quantity }}`
`{{ stake_cpu_quantity }}`
`{{ transfer }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}`
`{{ bool }}` | +| `{{ undelegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ unstake_net_quantity }}`
`{{ unstake_cpu_quantity }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}` | +| `{{ refund }}` | `{{ owner }}` | `{{ account_name }}` | +| `{{ regproducer }}` | `{{ producer }}`
`{{ producer_key }}`
`{{ url }}`
`{{ location }}` | `{{ account_name }}`
`{{ public_key }}`
`{{ string }}`
`{{ uint16 }}` | +| `{{ setram }}` | `{{ max_ram_size }}` | `{{ uint64 }}` | +| `{{ bidname }}` | `{{ bidder }}`
`{{ newname }}`
`{{ bid }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | +| `{{ unregprod }}` | `{{ producer }}` | `{{ account_name }}` | +| `{{ regproxy }}` | `{{ proxy }}`
`{{ isproxy }}` | `{{ account_name }}`
`{{ bool }}` | +| `{{ voteproducer }}` | `{{ voter }}`
`{{ proxy }}`
`{{ producers }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ account_name[] }}` | +| `{{ claimrewards }}` | `{{ owner }}` | `{{ account_name }}` | +| `{{ setpriv }}` | `{{ account }}`
`{{ is_priv }}` | `{{ account_name }}`
`{{ int8 }}` | +| `{{ setalimits }}` | `{{ account }}`
`{{ ram_bytes }}`
`{{ net_weight }}`
`{{ cpu_weight }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | +| `{{ setglimits }}` | `{{ cpu_usec_per_period }}` | `{{ int64 }}` | +| `{{ setprods }}` | `{{ schedule }}` | `{{ producer_key[] }}` | +| `{{ reqauth }}` | `{{ from }}` | `{{ account_name }}` | \ No newline at end of file diff --git a/eosio.system-refund-rc.md b/eosio.system-refund-rc.md new file mode 100644 index 00000000..7e2af028 --- /dev/null +++ b/eosio.system-refund-rc.md @@ -0,0 +1,20 @@ +# Action - `{{ refund }}` + +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 intent of the `{{ refund }}` action is to return previously unstaked tokens to an account after the unstaking period has elapsed. + +### Input and Input Type + +The `{{ refund }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ refund }}` | `{{ ownerVar }}` | `{{ account_name }}` | + + +As an authorized party I {{ signer }} wish to have the unstaked tokens of {{ ownerVar }} returned. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-regproducer-rc.md b/eosio.system-regproducer-rc.md new file mode 100644 index 00000000..e7633f1e --- /dev/null +++ b/eosio.system-regproducer-rc.md @@ -0,0 +1,15 @@ +# eosio.system regproducer + +This Ricardian contract for the system action *regproducer* is legally binding and can be used in the event of a dispute. + +## regproducer + ( const account_name producer + , const public_key& producer_key + , const std::string& url + , uint16_t location ); + +_Intent: create a producer-config and producer-info object for 'producer'_ + +As an authorized party I {{ signer }} wish to register a producer candidate named {{ account_name }} and identified with {{ producer_key }} located at {{ url }} and located at {{ location }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-regproxy-rc.md b/eosio.system-regproxy-rc.md new file mode 100644 index 00000000..3c78aa69 --- /dev/null +++ b/eosio.system-regproxy-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ regproxy }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ regproxy }}` action... + +### Inputs and Input Types + +The `{{ regproxy }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ regproxy }}` | `{{ proxyVar }}`
`{{ isproxyVar }}` | `{{ account_name }}`
`{{ bool }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-reqauth-rc.md b/eosio.system-reqauth-rc.md new file mode 100644 index 00000000..c347e5b0 --- /dev/null +++ b/eosio.system-reqauth-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ reqauth }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ reqauth }}` action... + +### Input and Input Type + +The `{{ reqauth }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ reqauth }}` | `{{ fromVar }}` | `{{ account_name }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-sellram-rc.md b/eosio.system-sellram-rc.md new file mode 100644 index 00000000..b10dfb04 --- /dev/null +++ b/eosio.system-sellram-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ sellram }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ sellram }}` action... + +### Inputs and Input Types + +The `{{ sellram }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ sellram }}` | `{{ accountVar }}`
`{{ bytesVar }}` | `{{ account_name }}`
`{{ uint64 }}` | + +As an authorized party I {{ signer }} wish to sell {{ bytesVar }} of RAM from account {{ accountVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setabi-rc.md b/eosio.system-setabi-rc.md new file mode 100644 index 00000000..6167d2a8 --- /dev/null +++ b/eosio.system-setabi-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ setabi }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The intention of the `{{ setabi }}` action is to... + +### Inputs and Input Types + +The `{{ setabi }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setabi }}` | `{{ accountVar }}`
`{{ abiVar }}` | `{{ account_name }}`
`{{ bytes }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setalimits-rc.md b/eosio.system-setalimits-rc.md new file mode 100644 index 00000000..70b210ff --- /dev/null +++ b/eosio.system-setalimits-rc.md @@ -0,0 +1,20 @@ +# Action - `{{ setalimits }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ setalimits }}` action... + +### Inputs and Input Types + +The `{{ setalimits }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setalimits }}` | `{{ accountVar }}`
`{{ ram_bytesVar }}`
`{{ net_weightVar }}`
`{{ cpu_weightVar }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | + + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setcode-rc.md b/eosio.system-setcode-rc.md new file mode 100644 index 00000000..622c0eb9 --- /dev/null +++ b/eosio.system-setcode-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ setcode }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The intention of the `{{ setcode }}` action is to load a smart contract into memory and make it available for execution. + +### Inputs and Input Types + +The `{{ setcode }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setcode }}` | `{{ accountVar }}`
`{{ vmtypeVar }}`
`{{ vmversionVar }}`
`{{ codeVar }}` | `{{ account_name }}`
`{{ uint8 }}`
`{{ uint8 }}`
`{{ bytes }}` | + +As an authorized party I {{ signer }} wish to store in memory owned by {{ accountVar }} the code {{ codeVar }} which shall use VM Type {{ vmtypeVar }} version {{ vmversionVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setglimits-rc.md b/eosio.system-setglimits-rc.md new file mode 100644 index 00000000..fa8405a4 --- /dev/null +++ b/eosio.system-setglimits-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ setglimits }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The intention of the `{{ setglimits }}` action is to ... + +### Input and Input Type + +The `{{ setglimits }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setglimits }}` | `{{ cpu_usec_per_periodVar }}` | `{{ int64 }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setpriv-rc.md b/eosio.system-setpriv-rc.md new file mode 100644 index 00000000..9425fbed --- /dev/null +++ b/eosio.system-setpriv-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ setpriv }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The intention of the `{{ setpriv }}` action is to ... + +### Inputs and Input Types + +The `{{ setpriv }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setpriv }}` | `{{ accountVar }}`
`{{ is_privVar }}` | `{{ account_name }}`
`{{ int8 }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setprods-rc.md b/eosio.system-setprods-rc.md new file mode 100644 index 00000000..fd4f8d67 --- /dev/null +++ b/eosio.system-setprods-rc.md @@ -0,0 +1,22 @@ +# Action - `{{ setprods }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ setprods }}` action creates a new schedule of active producers, who will produce blocks in the order given. + +### Input and Input Type + +The `{{ setprods }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setprods }}` | `{{ scheduleVar }}` | `{{ producer_key[] }}` | + +THIS IS A SYSTEM COMMAND NOT AVAILABLE FOR DIRECT ACCESS BY USERS. + + +As an authorized party I {{ signer }} wish to set the rotation of producers to be {{ scheduleVar }}. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setram-rc.md b/eosio.system-setram-rc.md new file mode 100644 index 00000000..b911e264 --- /dev/null +++ b/eosio.system-setram-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ setram }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The intent of the `{{ setram }}` action is ... + +### Input and Input Type + +The `{{ setram }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setram }}` | `{{ max_ram_sizeVar }}` | `{{ uint64 }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-undelegatebw-rc.md b/eosio.system-undelegatebw-rc.md new file mode 100644 index 00000000..f0290732 --- /dev/null +++ b/eosio.system-undelegatebw-rc.md @@ -0,0 +1,17 @@ +# eosio.system undelegatebw + +This Ricardian contract for the system action *undelegatebw* is legally binding and can be used in the event of a dispute. + +## undelegatebw + (account_name-from; + account_name-to; + asset-unstake_net_quantity; + asset-unstake_cpu_quantity) + +_Intent: unstake tokens from bandwidth_ + +As an authorized party I {{ signer }} wish to unstake {{ asset-unstake_cpu_quantity }} from CPU and {{ asset-unstake_net_quantity }} from bandwidth from the tokens owned by {{ account_name-from }} previously delegated for the use of delegatee {{ account_name-to }}. + +If I as signer am not the beneficial owner of these tokens I stipulate I have proof that I’ve been authorized to take this action by their beneficial owner(s). + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-unlinkauth-rc.md b/eosio.system-unlinkauth-rc.md new file mode 100644 index 00000000..0e6034f8 --- /dev/null +++ b/eosio.system-unlinkauth-rc.md @@ -0,0 +1,20 @@ +# Action - `{{ unlinkauth }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ unlinkauth }}` action... + +### Inputs and Input Types + +The `{{ unlinkauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ unlinkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | + + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-unregprod-rc.md b/eosio.system-unregprod-rc.md new file mode 100644 index 00000000..22ae4ee1 --- /dev/null +++ b/eosio.system-unregprod-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ unregprod }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ unregprod }}` action... + +### Input and Input Type + +The `{{ unregprod }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ unregprod }}` | `{{ producerVar }}` | `{{ account_name }}` | + +As an authorized party I {{ signer }} wish to unregister the block producer candidate {{ producerVar }}, rendering that candidate no longer able to receive votes. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-updateauth-rc.md b/eosio.system-updateauth-rc.md new file mode 100644 index 00000000..fe5d639a --- /dev/null +++ b/eosio.system-updateauth-rc.md @@ -0,0 +1,19 @@ +# Action - `{{ updateauth }}` + +This Contract is legally binding and can be used in the event of a dispute. + +### Description + +The `{{ updateauth }}` action... + +### Inputs and Input Types + +The `{{ updateauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ updateauth }}` | `{{ accountVar }}`
`{{ permissionVar }}`
`{{ parentVar }}`
`{{ authVar }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From baecc67ea554ce992264d6bd51fd4c89aa4f0c7f Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 24 May 2018 14:52:42 -0400 Subject: [PATCH 0301/1048] action setparams added to system contract, unit-test of producers changing parameters using multi-sig #3390 --- eosio.system.abi | 10 ++++++++++ eosio.system.cpp | 8 ++++++++ eosio.system.hpp | 2 ++ 3 files changed, 20 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index dcf903eb..e559ad30 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -378,6 +378,12 @@ "fields": [ {"name":"from", "type":"account_name"} ] + },{ + "name": "setparams", + "base": "", + "fields": [ + {"name":"params", "type":"eosio_parameters"} + ] } ], "actions": [{ @@ -488,6 +494,10 @@ "name": "reqauth", "type": "require_auth", "ricardian_contract": "" + },{ + "name": "setparams", + "type": "setparams", + "ricardian_contract": "" }], "tables": [{ "name": "producers", diff --git a/eosio.system.cpp b/eosio.system.cpp index 667a2279..9bfa0d34 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -165,6 +165,13 @@ namespace eosiosystem { set_resource_limits( newact, 0, 0, 0 ); } + void system_contract::setparams( const eosio_parameters& params ) { + require_auth( N(eosio) ); + (eosiosystem::eosio_parameters&)(_gstate) = params; + eosio_assert( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); + set_blockchain_parameters( params ); + } + } /// eosio.system @@ -183,4 +190,5 @@ EOSIO_ABI( eosiosystem::system_contract, //this file (bidname) (setpriv) + (setparams) ) diff --git a/eosio.system.hpp b/eosio.system.hpp index 70e0778f..b2120247 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -215,6 +215,8 @@ namespace eosiosystem { void regproxy( const account_name proxy, bool isproxy ); + void setparams( const eosio_parameters& params ); + // functions defined in producer_pay.cpp void claimrewards( const account_name& owner ); From 8bb8d91c238e81e4caa0ecc78657b865685d85cb Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 24 May 2018 18:14:38 -0400 Subject: [PATCH 0302/1048] rename set_active_producers to set_proposed_producers --- voting.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/voting.cpp b/voting.cpp index 0c4d5616..9f014b03 100644 --- a/voting.cpp +++ b/voting.cpp @@ -34,7 +34,7 @@ namespace eosiosystem { * @pre authority of producer to register * */ - void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { + void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { eosio_assert( url.size() < 512, "url too long" ); require_auth( producer ); @@ -96,7 +96,7 @@ namespace eosiosystem { top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location})); } - + /// sort by producer name @@ -114,7 +114,7 @@ namespace eosiosystem { if( new_id != _gstate.last_producer_schedule_id ) { _gstate.last_producer_schedule_id = new_id; - set_active_producers( packed_schedule.data(), packed_schedule.size() ); + set_proposed_producers( packed_schedule.data(), packed_schedule.size() ); } _gstate.last_producer_schedule_update = block_time; } @@ -133,7 +133,7 @@ namespace eosiosystem { * @pre voter must have previously staked some EOS for voting * @pre voter->staked must be up to date * - * @post every producer previously voted for will have vote reduced by previous vote weight + * @post every producer previously voted for will have vote reduced by previous vote weight * @post every producer newly voted for will have vote increased by new vote amount * @post prior proxy will proxied_vote_weight decremented by previous vote weight * @post new proxy will proxied_vote_weight incremented by new vote weight @@ -245,7 +245,7 @@ namespace eosiosystem { /** * An account marked as a proxy can vote with the weight of other accounts which * have selected it as a proxy. Other accounts must refresh their voteproducer to - * update the proxy's weight. + * update the proxy's weight. * * @param isproxy - true if proxy wishes to vote on behalf of others, false otherwise * @pre proxy must have something staked (existing row in voters table) From a66219cd52ab274b3aa3f8ee85334329c4e5cc31 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 24 May 2018 18:55:13 -0400 Subject: [PATCH 0303/1048] Changes to producer deactivation - incomplete --- voting.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 0c4d5616..acd6028d 100644 --- a/voting.cpp +++ b/voting.cpp @@ -79,7 +79,7 @@ namespace eosiosystem { for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) { if( !it->active() ) continue; - +#if 0 if ( it->time_became_active.slot == 0 ) { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; @@ -93,7 +93,22 @@ namespace eosiosystem { continue; } +#else + if ( it->time_became_active.slot > 0 && + block_time.slot > (2 * 21 * 12 * 100) + it->time_became_active.slot && + block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) { + _producers.modify( *it, 0, [&](auto& p) { + p.producer_key = public_key(); + p.time_became_active.slot = 0; + }); + continue; + } else { + _producers.modify( *it, 0, [&](auto& p) { + p.time_became_active = block_time; + }); + } +#endif top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location})); } From 30afb2264142ca56e5969e892cfb09f14b5d33cb Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 25 May 2018 10:56:33 -0400 Subject: [PATCH 0304/1048] Change producer deactivation logic, fix unit tests --- voting.cpp | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/voting.cpp b/voting.cpp index acd6028d..cfa602c3 100644 --- a/voting.cpp +++ b/voting.cpp @@ -79,8 +79,14 @@ namespace eosiosystem { for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) { if( !it->active() ) continue; -#if 0 - if ( it->time_became_active.slot == 0 ) { + + /** + If it's the first time or it's been over a day since a producer was last voted in, + update his info. Otherwise, a producer gets a grace period of 7 hours after which + he gets deactivated if he hasn't produced in 24 hours. + */ + if ( it->time_became_active.slot == 0 || + block_time.slot > it->time_became_active.slot + blocks_per_day ) { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); @@ -91,24 +97,13 @@ namespace eosiosystem { p.time_became_active.slot = 0; }); - continue; - } -#else - if ( it->time_became_active.slot > 0 && - block_time.slot > (2 * 21 * 12 * 100) + it->time_became_active.slot && - block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) { - _producers.modify( *it, 0, [&](auto& p) { - p.producer_key = public_key(); - p.time_became_active.slot = 0; - }); - continue; } else { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); } -#endif + top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location})); } From 19ce461b4845e951c58382c3bcea4e49ed4b1f49 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 25 May 2018 10:59:48 -0400 Subject: [PATCH 0305/1048] buyram: don't charge fee to eosio account #3414 --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index e945b592..681f533a 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -117,7 +117,7 @@ namespace eosiosystem { { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } ); } - if( fee.amount > 0 ) { + if( payer != N(eosio) && fee.amount > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, { payer, N(eosio.ramfee), fee, std::string("ram fee") } ); } From c60a33e51687391080592ab49595c7b5c7328e6f Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 25 May 2018 15:06:57 -0400 Subject: [PATCH 0306/1048] system contract undelegatebw bugfix: don't delete row if ram_bytes != 0, small change in resource_limits to make debuging less confusing #3366 --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 681f533a..a292f855 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -259,7 +259,7 @@ namespace eosiosystem { set_resource_limits( receiver, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) ) { + if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); } } // tot_itr can be invalid, should go out of scope From 3763faa217ae9cd205552112a3bdb93f31d15a62 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 25 May 2018 16:53:47 -0400 Subject: [PATCH 0307/1048] system contract cleanup: remove special handling for eosio delegating/buying #3430 --- delegate_bandwidth.cpp | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index a292f855..a66cc181 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -112,12 +112,10 @@ namespace eosiosystem { auto quant_after_fee = quant; quant_after_fee.amount -= fee.amount; - if( payer != N(eosio) ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, - { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } ); - } + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, + { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } ); - if( payer != N(eosio) && fee.amount > 0 ) { + if( fee.amount > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, { payer, N(eosio.ramfee), fee, std::string("ram fee") } ); } @@ -182,14 +180,12 @@ namespace eosiosystem { }); set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); - if( N(eosio) != account ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.ram),N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.ram),N(active)}, { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); - auto fee = tokens_out.amount / 200; - if( fee > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, - { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); - } + auto fee = tokens_out.amount / 200; + if( fee > 0 ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, + { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); } } From cec00c20043b17f7564549ac60a8191ac2e8ad45 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 28 May 2018 18:40:02 -0400 Subject: [PATCH 0308/1048] Optimize update_elected_producers --- eosio.system.abi | 1 + eosio.system.hpp | 10 ++++++---- voting.cpp | 25 +++++++++++++++---------- 3 files changed, 22 insertions(+), 14 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index e559ad30..49044b11 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -273,6 +273,7 @@ {"name":"owner", "type":"account_name"}, {"name":"total_votes", "type":"float64"}, {"name":"producer_key", "type":"public_key"}, + {"name":"is_active", "type":"bool"}, {"name":"url", "type":"string"}, {"name":"unpaid_blocks", "type":"uint32"}, {"name":"last_claim_time", "type":"uint64"}, diff --git a/eosio.system.hpp b/eosio.system.hpp index b2120247..25420d07 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -74,6 +74,7 @@ namespace eosiosystem { account_name owner; double total_votes = 0; eosio::public_key producer_key; /// a packed public key object + bool is_active = true; std::string url; uint32_t unpaid_blocks = 0; uint64_t last_claim_time = 0; @@ -81,12 +82,13 @@ namespace eosiosystem { block_timestamp time_became_active; block_timestamp last_produced_block_time; - uint64_t primary_key()const { return owner; } - double by_votes()const { return -total_votes; } - bool active() const { return producer_key != public_key(); } + uint64_t primary_key()const { return owner; } + double by_votes()const { return is_active ? -total_votes : total_votes; } + bool active()const { return is_active; } + void deactivate() { producer_key = public_key(); is_active = false; } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(url) + EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url) (unpaid_blocks)(last_claim_time)(location) (time_became_active)(last_produced_block_time) ) }; diff --git a/voting.cpp b/voting.cpp index 10e51902..c7e0cdee 100644 --- a/voting.cpp +++ b/voting.cpp @@ -36,6 +36,7 @@ namespace eosiosystem { */ void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { eosio_assert( url.size() < 512, "url too long" ); + eosio_assert( producer_key != eosio::public_key(), "public key should not be the default value" ); require_auth( producer ); auto prod = _producers.find( producer ); @@ -44,6 +45,7 @@ namespace eosiosystem { if( producer_key != prod->producer_key ) { _producers.modify( prod, producer, [&]( producer_info& info ){ info.producer_key = producer_key; + info.is_active = true; info.url = url; info.location = location; }); @@ -53,6 +55,7 @@ namespace eosiosystem { info.owner = producer; info.total_votes = 0; info.producer_key = producer_key; + info.is_active = true; info.url = url; info.location = location; }); @@ -65,7 +68,7 @@ namespace eosiosystem { const auto& prod = _producers.get( producer, "producer not found" ); _producers.modify( prod, 0, [&]( producer_info& info ){ - info.producer_key = eosio::public_key(); + info.deactivate(); }); } @@ -77,8 +80,8 @@ namespace eosiosystem { std::vector< std::pair > top_producers; top_producers.reserve(21); - for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes; ++it ) { - if( !it->active() ) continue; + std::vector inactive_iters; + for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) { /** If it's the first time or it's been over a day since a producer was last voted in, @@ -92,11 +95,8 @@ namespace eosiosystem { }); } else if ( block_time.slot > (2 * 21 * 12 * 100) + it->time_became_active.slot && block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) { - _producers.modify( *it, 0, [&](auto& p) { - p.producer_key = public_key(); - p.time_became_active.slot = 0; - }); - + // save producers that will be deactivated + inactive_iters.push_back(it); continue; } else { _producers.modify( *it, 0, [&](auto& p) { @@ -107,7 +107,12 @@ namespace eosiosystem { top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location})); } - + for (const auto& it: inactive_iters) { + _producers.modify( *it, 0, [&](auto& p) { + p.deactivate(); + p.time_became_active.slot = 0; + }); + } /// sort by producer name std::sort( top_producers.begin(), top_producers.end() ); @@ -234,7 +239,7 @@ namespace eosiosystem { eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); _producers.modify( pitr, 0, [&]( auto& p ) { p.total_votes += pd.second.first; - if ( p.total_votes < 0 ) { // floating point ariphmetics can give as small negative numbers + if ( p.total_votes < 0 ) { // floating point arithmetics can give small negative numbers p.total_votes = 0; } _gstate.total_producer_vote_weight += pd.second.first; From dd1d3cc6f00fdc28b79983d57b3a6fe3fc26866b Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 29 May 2018 11:18:46 -0400 Subject: [PATCH 0309/1048] prevent unstaking until minimum activated stake #3547 --- delegate_bandwidth.cpp | 1 + eosio.system.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index a66cc181..06f234b4 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -372,6 +372,7 @@ namespace eosiosystem { eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "not enough has been staked for users to unstake" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); } // undelegatebw diff --git a/eosio.system.cpp b/eosio.system.cpp index 9bfa0d34..f6a13b5a 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -1,8 +1,8 @@ #include "eosio.system.hpp" #include -#include "delegate_bandwidth.cpp" #include "producer_pay.cpp" +#include "delegate_bandwidth.cpp" #include "voting.cpp" #include "exchange_state.cpp" @@ -104,7 +104,7 @@ namespace eosiosystem { eosio_assert( current->high_bidder != bidder, "account is already high bidder" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.names),N(active)}, - { N(eosio.names), current->high_bidder, asset(current->high_bid), + { N(eosio.names), current->high_bidder, asset(current->high_bid), std::string("refund bid on name ")+(name{newname}).to_string() } ); bids.modify( current, bidder, [&]( auto& b ) { @@ -125,7 +125,7 @@ namespace eosiosystem { * * 2. new accounts must stake a minimal number of tokens (as set in system parameters) * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. + * an amount equal to the current new account creation fee. */ void native::newaccount( account_name creator, account_name newact @@ -146,7 +146,7 @@ namespace eosiosystem { if( suffix == newact ) { name_bid_table bids(_self,_self); auto current = bids.find( newact ); - eosio_assert( current != bids.end(), "no active bid for name" ); + eosio_assert( current != bids.end(), "no active bid for name" ); eosio_assert( current->high_bidder == creator, "only high bidder can claim" ); eosio_assert( current->high_bid < 0, "auction for name is not closed yet" ); bids.erase( current ); @@ -173,7 +173,7 @@ namespace eosiosystem { } } /// eosio.system - + EOSIO_ABI( eosiosystem::system_contract, (setram) From 33f9e998fa198c82fbaffae411da5351a39037a3 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 29 May 2018 11:42:06 -0400 Subject: [PATCH 0310/1048] Added setram unit test --- eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index 25420d07..4d8383c4 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -83,7 +83,7 @@ namespace eosiosystem { block_timestamp last_produced_block_time; uint64_t primary_key()const { return owner; } - double by_votes()const { return is_active ? -total_votes : total_votes; } + double by_votes()const { return is_active ? -total_votes : total_votes; } bool active()const { return is_active; } void deactivate() { producer_key = public_key(); is_active = false; } From bf709edc3062ac7c243c4f3a705f51d0aa891d0f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 29 May 2018 13:42:05 -0400 Subject: [PATCH 0311/1048] Avoid producer deactivation corner case --- voting.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/voting.cpp b/voting.cpp index c7e0cdee..ecd8fd0f 100644 --- a/voting.cpp +++ b/voting.cpp @@ -89,7 +89,7 @@ namespace eosiosystem { he gets deactivated if he hasn't produced in 24 hours. */ if ( it->time_became_active.slot == 0 || - block_time.slot > it->time_became_active.slot + blocks_per_day ) { + block_time.slot > it->time_became_active.slot + 23 * blocks_per_hour ) { _producers.modify( *it, 0, [&](auto& p) { p.time_became_active = block_time; }); @@ -104,10 +104,10 @@ namespace eosiosystem { }); } - top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location})); + top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location}) ); } - for (const auto& it: inactive_iters) { + for ( const auto& it: inactive_iters ) { _producers.modify( *it, 0, [&](auto& p) { p.deactivate(); p.time_became_active.slot = 0; From 4d2019c17382f6653f7f020236b97a1ee19ca9f8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 29 May 2018 20:02:28 -0400 Subject: [PATCH 0312/1048] Prevent updating to producer schedule with fewer producers --- eosio.system.abi | 1 + eosio.system.hpp | 6 +++--- voting.cpp | 5 +++++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 49044b11..fb5e2a65 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -263,6 +263,7 @@ {"name":"total_activated_stake", "type":"int64"}, {"name":"thresh_activated_stake_time", "type":"uint64"}, {"name":"last_producer_schedule_id", "type":"checksum160"}, + {"name":"last_producer_schedule_size", "type":"uint16"}, {"name":"total_producer_vote_weight", "type":"float64"}, {"name":"last_name_close", "type":"block_timestamp_type"} ] diff --git a/eosio.system.hpp b/eosio.system.hpp index 4d8383c4..fdd57fec 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -59,15 +59,15 @@ namespace eosiosystem { int64_t total_activated_stake = 0; uint64_t thresh_activated_stake_time = 0; checksum160 last_producer_schedule_id; + uint16_t last_producer_schedule_size = 0; double total_producer_vote_weight = 0; /// the sum of all producer votes block_timestamp last_name_close; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) - (last_producer_schedule_update) - (last_pervote_bucket_fill) + (last_producer_schedule_update)(last_pervote_bucket_fill) (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(thresh_activated_stake_time) - (last_producer_schedule_id)(total_producer_vote_weight)(last_name_close) ) + (last_producer_schedule_id)(last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) }; struct producer_info { diff --git a/voting.cpp b/voting.cpp index ecd8fd0f..ae3f40d5 100644 --- a/voting.cpp +++ b/voting.cpp @@ -107,6 +107,10 @@ namespace eosiosystem { top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location}) ); } + if ( top_producers.size() < _gstate.last_producer_schedule_size ) { + return; + } + for ( const auto& it: inactive_iters ) { _producers.modify( *it, 0, [&](auto& p) { p.deactivate(); @@ -130,6 +134,7 @@ namespace eosiosystem { if( new_id != _gstate.last_producer_schedule_id ) { _gstate.last_producer_schedule_id = new_id; set_proposed_producers( packed_schedule.data(), packed_schedule.size() ); + _gstate.last_producer_schedule_size = top_producers.size(); } _gstate.last_producer_schedule_update = block_time; } From 6bad268a62110e6c5c712da1e52b3746b80e447c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 30 May 2018 11:56:26 -0400 Subject: [PATCH 0313/1048] Delete savings field from eosio_global_state --- eosio.system.abi | 1 - eosio.system.hpp | 3 +-- producer_pay.cpp | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index fb5e2a65..39c095a1 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -258,7 +258,6 @@ {"name":"last_pervote_bucket_fill", "type":"uint64"}, {"name":"pervote_bucket", "type":"int64"}, {"name":"perblock_bucket", "type":"int64"}, - {"name":"savings", "type":"int64"}, {"name":"total_unpaid_blocks", "type":"uint32"}, {"name":"total_activated_stake", "type":"int64"}, {"name":"thresh_activated_stake_time", "type":"uint64"}, diff --git a/eosio.system.hpp b/eosio.system.hpp index fdd57fec..2916d03a 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -54,7 +54,6 @@ namespace eosiosystem { uint64_t last_pervote_bucket_fill = 0; int64_t pervote_bucket = 0; int64_t perblock_bucket = 0; - int64_t savings = 0; uint32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid int64_t total_activated_stake = 0; uint64_t thresh_activated_stake_time = 0; @@ -66,7 +65,7 @@ namespace eosiosystem { // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update)(last_pervote_bucket_fill) - (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(thresh_activated_stake_time) + (pervote_bucket)(perblock_bucket)(total_unpaid_blocks)(total_activated_stake)(thresh_activated_stake_time) (last_producer_schedule_id)(last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) }; diff --git a/producer_pay.cpp b/producer_pay.cpp index c497cc15..c2fc7c96 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -103,7 +103,6 @@ namespace eosiosystem { _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; - _gstate.savings += to_savings; _gstate.last_pervote_bucket_fill = ct; } From 8f98c9ffbbf79fd9d4a3d6aec9ff9321c03bcaa0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 30 May 2018 13:09:16 -0400 Subject: [PATCH 0314/1048] Remove producer deactivation code and testing --- eosio.system.abi | 18 ++++++++---------- eosio.system.hpp | 5 +---- producer_pay.cpp | 1 - voting.cpp | 30 ------------------------------ 4 files changed, 9 insertions(+), 45 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 39c095a1..a0c9d5ca 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -270,16 +270,14 @@ "name": "producer_info", "base": "", "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"total_votes", "type":"float64"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"is_active", "type":"bool"}, - {"name":"url", "type":"string"}, - {"name":"unpaid_blocks", "type":"uint32"}, - {"name":"last_claim_time", "type":"uint64"}, - {"name":"location", "type":"uint16"}, - {"name":"time_became_active", "type":"uint32"}, - {"name":"last_produced_block_time", "type":"uint32"} + {"name":"owner", "type":"account_name"}, + {"name":"total_votes", "type":"float64"}, + {"name":"producer_key", "type":"public_key"}, + {"name":"is_active", "type":"bool"}, + {"name":"url", "type":"string"}, + {"name":"unpaid_blocks", "type":"uint32"}, + {"name":"last_claim_time", "type":"uint64"}, + {"name":"location", "type":"uint16"} ] },{ "name": "regproducer", diff --git a/eosio.system.hpp b/eosio.system.hpp index 2916d03a..6edfd135 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -78,8 +78,6 @@ namespace eosiosystem { uint32_t unpaid_blocks = 0; uint64_t last_claim_time = 0; uint16_t location = 0; - block_timestamp time_became_active; - block_timestamp last_produced_block_time; uint64_t primary_key()const { return owner; } double by_votes()const { return is_active ? -total_votes : total_votes; } @@ -88,8 +86,7 @@ namespace eosiosystem { // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url) - (unpaid_blocks)(last_claim_time)(location) - (time_became_active)(last_produced_block_time) ) + (unpaid_blocks)(last_claim_time)(location) ) }; struct voter_info { diff --git a/producer_pay.cpp b/producer_pay.cpp index c2fc7c96..f9d9bedb 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -39,7 +39,6 @@ namespace eosiosystem { _gstate.total_unpaid_blocks++; _producers.modify( prod, 0, [&](auto& p ) { p.unpaid_blocks++; - p.last_produced_block_time = timestamp; }); } diff --git a/voting.cpp b/voting.cpp index ae3f40d5..4fe7a5e0 100644 --- a/voting.cpp +++ b/voting.cpp @@ -80,30 +80,7 @@ namespace eosiosystem { std::vector< std::pair > top_producers; top_producers.reserve(21); - std::vector inactive_iters; for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) { - - /** - If it's the first time or it's been over a day since a producer was last voted in, - update his info. Otherwise, a producer gets a grace period of 7 hours after which - he gets deactivated if he hasn't produced in 24 hours. - */ - if ( it->time_became_active.slot == 0 || - block_time.slot > it->time_became_active.slot + 23 * blocks_per_hour ) { - _producers.modify( *it, 0, [&](auto& p) { - p.time_became_active = block_time; - }); - } else if ( block_time.slot > (2 * 21 * 12 * 100) + it->time_became_active.slot && - block_time.slot > it->last_produced_block_time.slot + blocks_per_day ) { - // save producers that will be deactivated - inactive_iters.push_back(it); - continue; - } else { - _producers.modify( *it, 0, [&](auto& p) { - p.time_became_active = block_time; - }); - } - top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location}) ); } @@ -111,13 +88,6 @@ namespace eosiosystem { return; } - for ( const auto& it: inactive_iters ) { - _producers.modify( *it, 0, [&](auto& p) { - p.deactivate(); - p.time_became_active.slot = 0; - }); - } - /// sort by producer name std::sort( top_producers.begin(), top_producers.end() ); From 33efd29607b66da81d7001a0ef0e470623f38c39 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 30 May 2018 13:26:17 -0400 Subject: [PATCH 0315/1048] Added rmvproducer system contract action --- eosio.system.abi | 6 ++++++ eosio.system.cpp | 8 ++++++++ eosio.system.hpp | 2 ++ 3 files changed, 16 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index a0c9d5ca..d036b7c7 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -343,6 +343,12 @@ {"name":"account", "type":"account_name"}, {"name":"is_priv", "type":"int8"} ] + },{ + "name": "rmvproducer", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"} + ] },{ "name": "set_account_limits", "base": "", diff --git a/eosio.system.cpp b/eosio.system.cpp index f6a13b5a..bc707de2 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -172,6 +172,14 @@ namespace eosiosystem { set_blockchain_parameters( params ); } + void system_contract::rmvproducer( account_name producer ) { + require_auth( _self ); + auto prod = _producers.get( producer ); + _producers.modify( prod, 0, [&](auto& p) { + p.deactivate(); + }); + } + } /// eosio.system diff --git a/eosio.system.hpp b/eosio.system.hpp index 6edfd135..fe34d301 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -220,6 +220,8 @@ namespace eosiosystem { void setpriv( account_name account, uint8_t ispriv ); + void rmvproducer( account_name producer ); + void bidname( account_name bidder, account_name newname, asset bid ); private: void update_elected_producers( block_timestamp timestamp ); From 0d0f70d03e75722b3154f54551bf7bac46f931bb Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 30 May 2018 15:56:26 -0400 Subject: [PATCH 0316/1048] update regproducer rc --- eosio.system-clause-constitution-rc.md | 58 ++++++++++++++++++++++ eosio.system-regproducer-rc.md | 66 ++++++++++++++++++++++---- eosio.system-unregprod-rc.md | 2 - 3 files changed, 115 insertions(+), 11 deletions(-) create mode 100644 eosio.system-clause-constitution-rc.md diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md new file mode 100644 index 00000000..76312fab --- /dev/null +++ b/eosio.system-clause-constitution-rc.md @@ -0,0 +1,58 @@ +This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. + +# Article I - Non Violence +Members shall not initiate violence or the threat of violence against another Member. + +# Article II - Perjury +Members shall be liable for losses caused by false or misleading attestiations and shall forfeit any profit gained thereby. + +# Article III - Rights +The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or community referendum. This Constitution creates no positive rights for or between any Members. + +# Article IV - Vote Buying +No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. + +# Article V - No Fiduciary +No Member nor SYS token holder shall have fiduciary responsibility to support the value of the SYS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of SYS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the SYS token supply. + +# Article VI - Restitution +Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. + +# Article VII - Open Source +Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via an free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. + +# Article VII - Language +Multi-lingual contracts must specify one prevailing language in case of dispute and the author is liable for losses due to their false, misleading, or ambiguous attested translations. + +# Article IX - Dispute Resolution +All disputes arising out of or in connection with this constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. + +# Article X - Choice of Law +Choice of law for disputes shall be, in order of precedence, this Constitution and the Maxims of Equity. + +# Article XI - Amending +This Constitution and its subordinate documents shall not be amended except by a vote of the Token Holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. + +# Article XII - Publishing +Members may only publish information to the Blockchain that is within their Right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. + +# Article XIII - Informed Consent +All service providers whom produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present the full Ricardian contract terms of this constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. + +# Article XIV - Severability +Severability If any part of this constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. + +# Article XV - Termination of Agreement +A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members by removing EXAMPLE from circulation. + +# Article XVI - Developer Liability +Members agree to hold software developers harmless for unintentional mistakes made in the expression of contractual intent, whether or not said mistakes were due to actual or perceived negligence. + +# Article XVII - Consideration +All rights and obligations under this Constitution are mutual and reciprocal and of equally significant value and cost to all parties. + +# Article XVIII - Acceptance +A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI and associated Ricardian contracts and said transaction is incorporated into the blockchain. + +# Article XIX - Counterparts +This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. diff --git a/eosio.system-regproducer-rc.md b/eosio.system-regproducer-rc.md index e7633f1e..0d0c26a2 100644 --- a/eosio.system-regproducer-rc.md +++ b/eosio.system-regproducer-rc.md @@ -1,15 +1,63 @@ # eosio.system regproducer -This Ricardian contract for the system action *regproducer* is legally binding and can be used in the event of a dispute. +I, {{producer}}, hereby nominate myself for consideration as an elected block producer. -## regproducer - ( const account_name producer - , const public_key& producer_key - , const std::string& url - , uint16_t location ); +If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby certify that I will keep this key secret and secure. -_Intent: create a producer-config and producer-info object for 'producer'_ +If {{producer}} is unable to perform obligations under this contract I will resign my position by setting by resubmitting this contract with +the null producer key. -As an authorized party I {{ signer }} wish to register a producer candidate named {{ account_name }} and identified with {{ producer_key }} located at {{ url }} and located at {{ location }}. +{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. +1. proposing a block at the time appointed by the block scheduling algorithm +2. pre-confirmation for block produced by a 3rd party when it is deemed valid +3. confirming a block for which {{producer}} has received 2/3+ pre-confirmation messages from other producers + +I hereby accept liability for any and all provable damages that result from: + +1. signing two different block proposals with the same timestamp with {{producer_key} +2. signing two different block proposals with the same block number with {{producer_key} +3. signing any block proposal which builds off of an objectively bad block +4. signing a pre-confirmation for an objectively invalid block according to deterministic blockchain rules +5. signing a confirmation for a block for which I do not possess pre-confirmation messages from 2/3+ other producers + +I hereby agree that double-signing for a timestamp or block number in concert with 2 or more other producers shall automatically be deemed malicious and subject to a fine equal to the past year of compensation received and imediate disqualification from being a producer. An exception may be made if {{producer}} can demonstrate that the double-signing occured due to a bug in the reference software; the burden of proof is on {{producer}}. + +I hereby agree not to interfer with the election process and to sign any blocks or confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. + +I hereby acknolwedge that 2/3+ other producers elected producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached. + +If {{producer}} qualifies to receive compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least 1 validating node validating with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. + +The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. + +I agree to process transactions on a FIFO best-effort and to honestly bill transactions for measured execution time. + +I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: + +1. the order in whcih transactions are included +2. the hash of the block that is produced + +I, {{producer}}, hereby agree to disclose and attest under penalty of purgery all ultimate beneficial owners of my company who own more than 1%. + +I, {{producer}}, hereby agree not to promise benefits to special interest groups in exchange for votes. + +I, {{producer}}, hereby agree to cooperate with other block producers. + +I, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract. + +I, {{producer}}, agree to set {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer. + +I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time. + +I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior producer. + +I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either CPU or network bandwidth metrics. + +I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by 2/3+ producers. + +## Constitution + +This agreement incorporates the current blockchain constitution: + +{{constitution}} diff --git a/eosio.system-unregprod-rc.md b/eosio.system-unregprod-rc.md index 22ae4ee1..1d21b022 100644 --- a/eosio.system-unregprod-rc.md +++ b/eosio.system-unregprod-rc.md @@ -1,7 +1,5 @@ # Action - `{{ unregprod }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ unregprod }}` action... From ab6681458022b80178edd34fcfee4752480e0542 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 30 May 2018 15:56:38 -0400 Subject: [PATCH 0317/1048] Merge branch 'constitution' of github.com:EOSIO/eos into constitution --- eosio.system-clause-constitution-rc.md | 30 +++++++++++++------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md index 76312fab..0f4057b0 100644 --- a/eosio.system-clause-constitution-rc.md +++ b/eosio.system-clause-constitution-rc.md @@ -1,15 +1,15 @@ This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. -# Article I - Non Violence +# Article I - No Initiation of Violence Members shall not initiate violence or the threat of violence against another Member. -# Article II - Perjury -Members shall be liable for losses caused by false or misleading attestiations and shall forfeit any profit gained thereby. +# Article II - No Perjury +Members shall be liable for losses caused by false or misleading attestations and shall forfeit any profit gained thereby. # Article III - Rights -The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or community referendum. This Constitution creates no positive rights for or between any Members. +The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or via community referendum. This Constitution creates no positive rights for or between any Members. -# Article IV - Vote Buying +# Article IV - No Vote Buying No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. # Article V - No Fiduciary @@ -19,31 +19,31 @@ No Member nor SYS token holder shall have fiduciary responsibility to support th Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. # Article VII - Open Source -Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via an free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. +Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via a free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. -# Article VII - Language -Multi-lingual contracts must specify one prevailing language in case of dispute and the author is liable for losses due to their false, misleading, or ambiguous attested translations. +# Article VIII - Language +Multi-lingual contracts must specify one prevailing language in case of dispute and the author of any translation shall be liable for losses due to their false, misleading, or ambiguous attested translations. # Article IX - Dispute Resolution -All disputes arising out of or in connection with this constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. +All disputes arising out of or in connection with this Constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. # Article X - Choice of Law Choice of law for disputes shall be, in order of precedence, this Constitution and the Maxims of Equity. # Article XI - Amending -This Constitution and its subordinate documents shall not be amended except by a vote of the Token Holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. +This Constitution and its subordinate documents shall not be amended except by a vote of the token holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. # Article XII - Publishing -Members may only publish information to the Blockchain that is within their Right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. +Members may only publish information to the Blockchain that is within their right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. # Article XIII - Informed Consent -All service providers whom produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present the full Ricardian contract terms of this constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. +All service providers who produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present to said other Members the full Ricardian contract terms of this Constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. # Article XIV - Severability -Severability If any part of this constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. +If any part of this Constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. # Article XV - Termination of Agreement -A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members by removing EXAMPLE from circulation. +A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members according to the system contract provisions then in effect for such redistribution. # Article XVI - Developer Liability Members agree to hold software developers harmless for unintentional mistakes made in the expression of contractual intent, whether or not said mistakes were due to actual or perceived negligence. @@ -52,7 +52,7 @@ Members agree to hold software developers harmless for unintentional mistakes ma All rights and obligations under this Constitution are mutual and reciprocal and of equally significant value and cost to all parties. # Article XVIII - Acceptance -A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI and associated Ricardian contracts and said transaction is incorporated into the blockchain. +A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI of said contract and said transaction is incorporated into the blockchain. # Article XIX - Counterparts This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. From e9628afdb31e5422b8aea7ba53158a7d68838129 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 30 May 2018 16:54:58 -0400 Subject: [PATCH 0318/1048] System contract rmvproducer testing --- eosio.system.abi | 4 ++++ eosio.system.cpp | 4 +++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index d036b7c7..220a7b1a 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -483,6 +483,10 @@ "name": "setpriv", "type": "setpriv", "ricardian_contract": "" + },{ + "name": "rmvproducer", + "type": "rmvproducer", + "ricardian_contract": "" },{ "name": "setalimits", "type": "set_account_limits", diff --git a/eosio.system.cpp b/eosio.system.cpp index bc707de2..0009e708 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -174,7 +174,8 @@ namespace eosiosystem { void system_contract::rmvproducer( account_name producer ) { require_auth( _self ); - auto prod = _producers.get( producer ); + auto prod = _producers.find( producer ); + eosio_assert( prod != _producers.end(), "producer not found" ); _producers.modify( prod, 0, [&](auto& p) { p.deactivate(); }); @@ -198,5 +199,6 @@ EOSIO_ABI( eosiosystem::system_contract, //this file (bidname) (setpriv) + (rmvproducer) (setparams) ) From f69ff90624ad49368b5cfcfd4e48b851abb001de Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 30 May 2018 17:11:43 -0400 Subject: [PATCH 0319/1048] removed unused totalband table from abi --- eosio.system.abi | 6 ------ 1 file changed, 6 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index fb5e2a65..4a3359fd 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -525,12 +525,6 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["uint64"] - },{ - "name": "totalband", - "type": "total_resources", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] },{ "name": "delband", "type": "delegated_bandwidth", From 28f01c237c3714e8699d02d9c4a1f06097712053 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 30 May 2018 17:35:02 -0400 Subject: [PATCH 0320/1048] fix setparams in system contract #3621 Also remove old recovery actions from dispatcher. --- eosio.system.abi | 11 +++-------- eosio.system.cpp | 35 +++++++++++++++-------------------- eosio.system.hpp | 21 +++++++-------------- native.hpp | 13 ++----------- 4 files changed, 27 insertions(+), 53 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 4a3359fd..8f882b93 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -242,16 +242,11 @@ {"name":"max_authority_depth", "type":"uint16"} ] - },{ - "name": "eosio_parameters", - "base": "blockchain_parameters", - "fields": [ - {"name":"max_ram_size", "type":"uint64"} - ] },{ "name": "eosio_global_state", - "base": "eosio_parameters", + "base": "blockchain_parameters", "fields": [ + {"name":"max_ram_size", "type":"uint64"}, {"name":"total_ram_bytes_reserved", "type":"uint64"}, {"name":"total_ram_stake", "type":"int64"}, {"name":"last_producer_schedule_update", "type":"time_point_sec"}, @@ -384,7 +379,7 @@ "name": "setparams", "base": "", "fields": [ - {"name":"params", "type":"eosio_parameters"} + {"name":"params", "type":"blockchain_parameters"} ] } ], diff --git a/eosio.system.cpp b/eosio.system.cpp index f6a13b5a..7e4ad9d7 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -73,6 +73,13 @@ namespace eosiosystem { _global.set( _gstate, _self ); } + void system_contract::setparams( const eosio::blockchain_parameters& params ) { + require_auth( N(eosio) ); + (eosio::blockchain_parameters&)(_gstate) = params; + eosio_assert( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); + set_blockchain_parameters( params ); + } + void system_contract::setpriv( account_name account, uint8_t ispriv ) { require_auth( _self ); set_privileged( account, ispriv ); @@ -165,30 +172,18 @@ namespace eosiosystem { set_resource_limits( newact, 0, 0, 0 ); } - void system_contract::setparams( const eosio_parameters& params ) { - require_auth( N(eosio) ); - (eosiosystem::eosio_parameters&)(_gstate) = params; - eosio_assert( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); - set_blockchain_parameters( params ); - } - } /// eosio.system EOSIO_ABI( eosiosystem::system_contract, - (setram) - // delegate_bandwith.cpp - (delegatebw)(undelegatebw)(refund) - (buyram)(buyrambytes)(sellram) + // native.hpp (newaccount definition is actually in eosio.system.cpp) + (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror) + // eosio.system.cpp + (setram)(setparams)(setpriv)(bidname) + // delegate_bandwidth.cpp + (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp + (regproducer)(unregprod)(voteproducer)(regproxy) // producer_pay.cpp - (regproxy)(regproducer)(unregprod)(voteproducer) - (claimrewards) - // native.hpp - (onblock) - (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(postrecovery)(passrecovery)(vetorecovery)(onerror)(canceldelay) - //this file - (bidname) - (setpriv) - (setparams) + (onblock)(claimrewards) ) diff --git a/eosio.system.hpp b/eosio.system.hpp index fdd57fec..5cd84d9d 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -20,13 +20,6 @@ namespace eosiosystem { using eosio::const_mem_fun; using eosio::block_timestamp; - struct eosio_parameters : eosio::blockchain_parameters { - uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE_DERIVED( eosio_parameters, eosio::blockchain_parameters, (max_ram_size) ) - }; - struct name_bid { account_name newname; account_name high_bidder; @@ -42,11 +35,10 @@ namespace eosiosystem { > name_bid_table; - - - struct eosio_global_state : eosio_parameters { + struct eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } + uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; uint64_t total_ram_bytes_reserved = 0; int64_t total_ram_stake = 0; @@ -64,7 +56,8 @@ namespace eosiosystem { block_timestamp last_name_close; // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) + EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio::blockchain_parameters, + (max_ram_size)(total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update)(last_pervote_bucket_fill) (pervote_bucket)(perblock_bucket)(savings)(total_unpaid_blocks)(total_activated_stake)(thresh_activated_stake_time) (last_producer_schedule_id)(last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) @@ -157,7 +150,7 @@ namespace eosiosystem { // functions defined in delegate_bandwidth.cpp /** - * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. + * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. * If transfer == true, then 'receiver' can unstake to their account * Else 'from' can unstake at any time. */ @@ -171,7 +164,7 @@ namespace eosiosystem { * left to delegate. * * This will cause an immediate reduction in net/cpu bandwidth of the - * receiver. + * receiver. * * A transaction is scheduled to send the tokens back to 'from' after * the staking period has passed. If existing transaction is scheduled, it @@ -217,7 +210,7 @@ namespace eosiosystem { void regproxy( const account_name proxy, bool isproxy ); - void setparams( const eosio_parameters& params ); + void setparams( const eosio::blockchain_parameters& params ); // functions defined in producer_pay.cpp void claimrewards( const account_name& owner ); diff --git a/native.hpp b/native.hpp index 3a9bed79..e6395807 100644 --- a/native.hpp +++ b/native.hpp @@ -79,7 +79,7 @@ namespace eosiosystem { * * 2. new accounts must stake a minimal number of tokens (as set in system parameters) * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. + * an amount equal to the current new account creation fee. */ void newaccount( account_name creator, account_name newact @@ -104,18 +104,9 @@ namespace eosiosystem { account_name code, action_name type*/ ) {} - void postrecovery( /*account_name account, - const authority& data, - const std::string& memo*/ ) {} - - void passrecovery( /*account_name account*/ ) {} - - void vetorecovery( /*account_name account*/ ) {} - - void onerror( /*const bytes&*/ ) {} - void canceldelay( /*permission_level canceling_auth, transaction_id_type trx_id*/ ) {} + void onerror( /*const bytes&*/ ) {} }; } From 88f009272bcb6572b5bf7c9048906a8b40d1a22b Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 30 May 2018 17:44:12 -0400 Subject: [PATCH 0321/1048] update some ricardian contracts --- eosio.system-buyrambytes-rc.md | 21 +++++++++------------ eosio.system-setcode-rc.md | 19 ++++++------------- eosio.system-setram-rc.md | 17 +++-------------- 3 files changed, 18 insertions(+), 39 deletions(-) diff --git a/eosio.system-buyrambytes-rc.md b/eosio.system-buyrambytes-rc.md index b37b59c2..63a60e83 100644 --- a/eosio.system-buyrambytes-rc.md +++ b/eosio.system-buyrambytes-rc.md @@ -1,19 +1,16 @@ # Action - `{{ buyrambytes }}` -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 `{{ buyrambytes }}` action... - -### Inputs and Input Types - -The `{{ buyrambytes }}` action requires the following `inputs` and `input types`: +This action will attempt to reserve about {{bytes}} bytes of RAM on behalf of {{receiver}}. -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ buyrambytes }}` | `{{ payerVar }}`
`{{ receiverVar }}`
`{{ bytesVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ uint32 }}` | +{{buyer}} authorizes this conrtact to transfer sufficient SYS tokens to buy the RAM based upon the current price as determined by the market maker algorithm. -As an authorized party I {{ signer }} wish to buy {{ bytesVar }} bytes of RAM at the current price using the funds of {{ payerVar }} with the RAM to be owned by and be the property of {{ receiverVar }}. +{{buyer}} accepts that a 0.5% fee will be charged on the SYS spent and that the actual RAM received may be slightly less than requested due to the approximations necessary to enable this service. +{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. +{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. +{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. +{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. +{{buyer}} acknowledges that RAM is non-transferrable. +{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-setcode-rc.md b/eosio.system-setcode-rc.md index 622c0eb9..5a0d7217 100644 --- a/eosio.system-setcode-rc.md +++ b/eosio.system-setcode-rc.md @@ -1,19 +1,12 @@ # Action - `{{ setcode }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description -The intention of the `{{ setcode }}` action is to load a smart contract into memory and make it available for execution. - -### Inputs and Input Types - -The `{{ setcode }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setcode }}` | `{{ accountVar }}`
`{{ vmtypeVar }}`
`{{ vmversionVar }}`
`{{ codeVar }}` | `{{ account_name }}`
`{{ uint8 }}`
`{{ uint8 }}`
`{{ bytes }}` | +This action updates the code that will run in response to delivered actions. It may be performed by the account upon which the code is being deployed. -As an authorized party I {{ signer }} wish to store in memory owned by {{ accountVar }} the code {{ codeVar }} which shall use VM Type {{ vmtypeVar }} version {{ vmversionVar }}. +By deploying this code you certify that: -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. +1. the code is not malicious +2. you are authorized to perform the actions automated by the code +3. the code is consistant with the ABI deployed and intent of the contract +4. updates to the code are consistant with the prior code's intent diff --git a/eosio.system-setram-rc.md b/eosio.system-setram-rc.md index b911e264..e9a3ce66 100644 --- a/eosio.system-setram-rc.md +++ b/eosio.system-setram-rc.md @@ -1,19 +1,8 @@ # Action - `{{ setram }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description -The intent of the `{{ setram }}` action is ... - -### Input and Input Type - -The `{{ setram }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setram }}` | `{{ max_ram_sizeVar }}` | `{{ uint64 }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN +This action sets the total RAM that may be allocated for use by accounts. It may only increase. -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. +Only the controller of this contract may update the RAM availablity. If the owner is a multi-sig collective, the +parties to the multi-sig each certify that off-the-shelf machines exist capable of supporting the available RAM. From 5820b0ac6e0cf2d0a76f2fe4900420f53235efac Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 18:06:36 -0400 Subject: [PATCH 0322/1048] update of regproducer RC typo fixes; language fixes; added definition of 'objectively [in]valid block'; deleted redundant vote-buying prohibition --- eosio.system-regproducer-rc.md | 39 +++++++++++++++++----------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/eosio.system-regproducer-rc.md b/eosio.system-regproducer-rc.md index 0d0c26a2..9857bc90 100644 --- a/eosio.system-regproducer-rc.md +++ b/eosio.system-regproducer-rc.md @@ -2,59 +2,58 @@ I, {{producer}}, hereby nominate myself for consideration as an elected block producer. -If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby certify that I will keep this key secret and secure. +If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. -If {{producer}} is unable to perform obligations under this contract I will resign my position by setting by resubmitting this contract with -the null producer key. +If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. + +I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. {{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: -1. proposing a block at the time appointed by the block scheduling algorithm -2. pre-confirmation for block produced by a 3rd party when it is deemed valid +1. proposing an objectively valid block at the time appointed by the block scheduling algorithm +2. pre-confirming a block produced by another producer in the schedule when I find said block objectively valid 3. confirming a block for which {{producer}} has received 2/3+ pre-confirmation messages from other producers -I hereby accept liability for any and all provable damages that result from: +I hereby accept liability for any and all provable damages that result from my: 1. signing two different block proposals with the same timestamp with {{producer_key} 2. signing two different block proposals with the same block number with {{producer_key} -3. signing any block proposal which builds off of an objectively bad block -4. signing a pre-confirmation for an objectively invalid block according to deterministic blockchain rules +3. signing any block proposal which builds off of an objectively invalid block +4. signing a pre-confirmation for an objectively invalid block 5. signing a confirmation for a block for which I do not possess pre-confirmation messages from 2/3+ other producers -I hereby agree that double-signing for a timestamp or block number in concert with 2 or more other producers shall automatically be deemed malicious and subject to a fine equal to the past year of compensation received and imediate disqualification from being a producer. An exception may be made if {{producer}} can demonstrate that the double-signing occured due to a bug in the reference software; the burden of proof is on {{producer}}. +I hereby agree that double-signing for a timestamp or block number in concert with 2 or more other producers shall automatically be deemed malicious and subject to a fine equal to the past year of compensation received and imediate disqualification from being a producer, and other damages. An exception may be made if {{producer}} can demonstrate that the double-signing occured due to a bug in the reference software; the burden of proof is on {{producer}}. -I hereby agree not to interfer with the election process and to sign any blocks or confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. +I hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. -I hereby acknolwedge that 2/3+ other producers elected producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached. +I hereby acknowledge that 2/3+ other elected producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among producers. -If {{producer}} qualifies to receive compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least 1 validating node validating with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. +If {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least 1 validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among producers, said method and reports to be made public. The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. -I agree to process transactions on a FIFO best-effort and to honestly bill transactions for measured execution time. +I agree to process transactions on a FIFO best-effort basis and to honestly bill transactions for measured execution time. I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: -1. the order in whcih transactions are included +1. the order in which transactions are included 2. the hash of the block that is produced -I, {{producer}}, hereby agree to disclose and attest under penalty of purgery all ultimate beneficial owners of my company who own more than 1%. - -I, {{producer}}, hereby agree not to promise benefits to special interest groups in exchange for votes. +I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my company who own more than 1%. -I, {{producer}}, hereby agree to cooperate with other block producers. +I, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain. I, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract. I, {{producer}}, agree to set {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer. -I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time. +I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among producers. I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior producer. I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either CPU or network bandwidth metrics. -I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by 2/3+ producers. +I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by 2/3+ producers, as shown in the system parameters. ## Constitution From 7865e4e61c2b07aa955950166154962c1de2df4b Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 30 May 2018 18:27:35 -0400 Subject: [PATCH 0323/1048] no need to check proposed produced schedule for uniqueness since set_proposed_producers will already do that --- eosio.system.abi | 1 - eosio.system.hpp | 9 ++++----- voting.cpp | 7 +------ 3 files changed, 5 insertions(+), 12 deletions(-) diff --git a/eosio.system.abi b/eosio.system.abi index 220a7b1a..16ffb18a 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -261,7 +261,6 @@ {"name":"total_unpaid_blocks", "type":"uint32"}, {"name":"total_activated_stake", "type":"int64"}, {"name":"thresh_activated_stake_time", "type":"uint64"}, - {"name":"last_producer_schedule_id", "type":"checksum160"}, {"name":"last_producer_schedule_size", "type":"uint16"}, {"name":"total_producer_vote_weight", "type":"float64"}, {"name":"last_name_close", "type":"block_timestamp_type"} diff --git a/eosio.system.hpp b/eosio.system.hpp index fe34d301..4fdb5056 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -57,7 +57,6 @@ namespace eosiosystem { uint32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid int64_t total_activated_stake = 0; uint64_t thresh_activated_stake_time = 0; - checksum160 last_producer_schedule_id; uint16_t last_producer_schedule_size = 0; double total_producer_vote_weight = 0; /// the sum of all producer votes block_timestamp last_name_close; @@ -66,7 +65,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio_parameters, (total_ram_bytes_reserved)(total_ram_stake) (last_producer_schedule_update)(last_pervote_bucket_fill) (pervote_bucket)(perblock_bucket)(total_unpaid_blocks)(total_activated_stake)(thresh_activated_stake_time) - (last_producer_schedule_id)(last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) + (last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) }; struct producer_info { @@ -153,7 +152,7 @@ namespace eosiosystem { // functions defined in delegate_bandwidth.cpp /** - * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. + * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. * If transfer == true, then 'receiver' can unstake to their account * Else 'from' can unstake at any time. */ @@ -167,7 +166,7 @@ namespace eosiosystem { * left to delegate. * * This will cause an immediate reduction in net/cpu bandwidth of the - * receiver. + * receiver. * * A transaction is scheduled to send the tokens back to 'from' after * the staking period has passed. If existing transaction is scheduled, it @@ -220,7 +219,7 @@ namespace eosiosystem { void setpriv( account_name account, uint8_t ispriv ); - void rmvproducer( account_name producer ); + void rmvproducer( account_name producer ); void bidname( account_name bidder, account_name newname, asset bid ); private: diff --git a/voting.cpp b/voting.cpp index 4fe7a5e0..a00e2054 100644 --- a/voting.cpp +++ b/voting.cpp @@ -98,15 +98,10 @@ namespace eosiosystem { producers.push_back(item.first); bytes packed_schedule = pack(producers); - checksum160 new_id; - sha1( packed_schedule.data(), packed_schedule.size(), &new_id ); - if( new_id != _gstate.last_producer_schedule_id ) { - _gstate.last_producer_schedule_id = new_id; - set_proposed_producers( packed_schedule.data(), packed_schedule.size() ); + if( set_proposed_producers( packed_schedule.data(), packed_schedule.size() ) >= 0 ) { _gstate.last_producer_schedule_size = top_producers.size(); } - _gstate.last_producer_schedule_update = block_time; } double stake2vote( int64_t staked ) { From e53c65d960face8d3e88546b1672305e3ddd864a Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Wed, 30 May 2018 18:19:33 -0500 Subject: [PATCH 0324/1048] Add rammarket table to abi --- eosio.system.abi | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index 8f882b93..61675eec 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -381,6 +381,21 @@ "fields": [ {"name":"params", "type":"blockchain_parameters"} ] + },{ + "name": "connector", + "base": "", + "fields": [ + {"name":"balance", "type":"asset"}, + {"name":"weight", "type":"float64"} + ] + },{ + "name": "exchange_state", + "base": "", + "fields": [ + {"name":"supply", "type":"asset"}, + {"name":"base", "type":"connector"}, + {"name":"quote", "type":"connector"} + ] } ], "actions": [{ @@ -526,6 +541,12 @@ "index_type": "i64", "key_names" : ["to"], "key_types" : ["uint64"] + },{ + "name": "rammarket", + "type": "exchange_state", + "index_type": "i64", + "key_names" : ["supply"], + "key_types" : ["uint64"] },{ "name": "refunds", "type": "refund_request", From 1bbb1b1fb7fdc31baf97dec731e10d3d22eb32c4 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:30:50 -0400 Subject: [PATCH 0325/1048] Update eosio.system-buyram-rc.md updated based on the pattern shown in buyrambytes --- eosio.system-buyram-rc.md | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/eosio.system-buyram-rc.md b/eosio.system-buyram-rc.md index d6ff406d..6d95fceb 100644 --- a/eosio.system-buyram-rc.md +++ b/eosio.system-buyram-rc.md @@ -1,19 +1,16 @@ # Action - `{{ buyram }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description -The `{{ buyram }}` action... - -### Inputs and Input Types - -The `{{ buyram }}` action requires the following `inputs` and `input types`: +This action will attempt to reserve about {{quant}} SYS tokens worth of RAM on behalf of {{receiver}}. -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ buyram }}` | `{{ payerVar }}`
`{{ receiverVar }}`
`{{ quantVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | +{{buyer}} authorizes this contract to transfer {{quant}} SYS tokens to buy RAM based upon the current price as determined by the market maker algorithm. -As an authorized party I {{ signer }} wish to buy {{ quantVar }} worth of RAM using the funds of {{ payerVar }} with the RAM to be owned by and be the property of {{ receiverVar }}. +{{buyer}} accepts that a 0.5% fee will be charged on the SYS spent and that the actual RAM received may be slightly less than expected due to the approximations necessary to enable this service. +{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. +{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. +{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. +{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. +{{buyer}} acknowledges that RAM is non-transferrable. +{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 79e0fcff838f8f01f998500b4f003a586551f15d Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:33:35 -0400 Subject: [PATCH 0326/1048] Update eosio.system-unregprod-rc.md remove deprecated arbitration clause --- eosio.system-unregprod-rc.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/eosio.system-unregprod-rc.md b/eosio.system-unregprod-rc.md index 1d21b022..de3dad69 100644 --- a/eosio.system-unregprod-rc.md +++ b/eosio.system-unregprod-rc.md @@ -2,7 +2,7 @@ ### Description -The `{{ unregprod }}` action... +The `{{ unregprod }}` action unregisters a previously registered block producer candidate. ### Input and Input Type @@ -13,5 +13,3 @@ The `{{ unregprod }}` action requires the following `input` and `input type`: | `{{ unregprod }}` | `{{ producerVar }}` | `{{ account_name }}` | As an authorized party I {{ signer }} wish to unregister the block producer candidate {{ producerVar }}, rendering that candidate no longer able to receive votes. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From d50d00f159b7da7b2a55bdd208324ea1eb28769f Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:35:12 -0400 Subject: [PATCH 0327/1048] Rename eosio.system.voteproducer-rc.md to eosio.system-voteproducer-rc.md renamed file to match others in naming convention --- ...o.system.voteproducer-rc.md => eosio.system-voteproducer-rc.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename eosio.system.voteproducer-rc.md => eosio.system-voteproducer-rc.md (100%) diff --git a/eosio.system.voteproducer-rc.md b/eosio.system-voteproducer-rc.md similarity index 100% rename from eosio.system.voteproducer-rc.md rename to eosio.system-voteproducer-rc.md From bb91cd4858abbc4b0d00b05e78e8c42b2fe9b285 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:36:44 -0400 Subject: [PATCH 0328/1048] Update eosio.system-bidname-rc.md removed deprecated arbitration clauses --- eosio.system-bidname-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-bidname-rc.md b/eosio.system-bidname-rc.md index 87b11b13..e71f2fa4 100644 --- a/eosio.system-bidname-rc.md +++ b/eosio.system-bidname-rc.md @@ -1,7 +1,5 @@ # Action - `{{ bidname }}` -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 `{{ bidname }}` action places a bid on a premium account name, in the knowledge that the high bid will purchase the name. @@ -15,5 +13,3 @@ The `{{ bidname }}` action requires the following `inputs` and `input types`: | `{{ bidname }}` | `{{ bidderVar }}`
`{{ newnameVar }}`
`{{ bidVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | As an authorized party I {{ signer }} wish to bid on behalf of {{ bidderVar }} the amount of {{ bidVar }} toward purchase of the account name {{ newnameVar }}. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 9f07287c43aa765fb6928ba835d10b9fada89cc4 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:37:08 -0400 Subject: [PATCH 0329/1048] Update eosio.system-canceldelay-rc.md removed deprecated arbitration clauses --- eosio.system-canceldelay-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-canceldelay-rc.md b/eosio.system-canceldelay-rc.md index db68ca85..8c7c0a38 100644 --- a/eosio.system-canceldelay-rc.md +++ b/eosio.system-canceldelay-rc.md @@ -1,7 +1,5 @@ # Action - `{{ canceldelay }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ canceldelay }}` action cancels an existing delayed transaction. @@ -15,5 +13,3 @@ The `{{ canceldelay }}` action requires the following `inputs` and `input types` | `{{ canceldelay }}` | `{{ canceling_authVar }}`
`{{ trx_idVar }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | As an authorized party I {{ signer }} wish to invoke the authority of {{ canceling_authVar }} to cancel the transaction with ID {{ trx_idVar }}. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 4a78d9fe9209e5ab71e1a117bbb5430058aff5ea Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:37:29 -0400 Subject: [PATCH 0330/1048] Update eosio.system-claimrewards-rc.md removed deprecated arbitration clauses --- eosio.system-claimrewards-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-claimrewards-rc.md b/eosio.system-claimrewards-rc.md index 8470bcb2..47362044 100644 --- a/eosio.system-claimrewards-rc.md +++ b/eosio.system-claimrewards-rc.md @@ -1,7 +1,5 @@ # Action - `{{ claimrewards }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ claimrewards }}` action allows a block producer (active or standby) to claim the system rewards due them for producing blocks and receiving votes. @@ -15,5 +13,3 @@ The `{{ claimrewards }}` action requires the following `input` and `input type`: | `{{ claimrewards }}` | `{{ ownerVar }}` | `{{ account_name }}` | As an authorized party I {{ signer }} wish to have the rewards earned by {{ ownerVar }} deposited into their (my) account. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From f0b7417da2a00259dc01537435bf2f9ec7e9feab Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:38:14 -0400 Subject: [PATCH 0331/1048] Update eosio.system-delegatebw-rc.md removed deprecated arbitration clauses --- eosio.system-delegatebw-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-delegatebw-rc.md b/eosio.system-delegatebw-rc.md index 904d43db..5db46687 100644 --- a/eosio.system-delegatebw-rc.md +++ b/eosio.system-delegatebw-rc.md @@ -1,7 +1,5 @@ # eosio.system delegatebw -This Ricardian contract for the system action *delegatebw* is legally binding and can be used in the event of a dispute. - ## delegatebw (account_name-from; account_name-to; @@ -20,5 +18,3 @@ It is {{ bool:transfer }} that I wish these tokens to become immediately owned b {{/if}} As signer I stipulate that, if I am not the beneficial owner of these tokens, I have proof that I’ve been authorized to take this action by their beneficial owner(s). - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 6b5559460200f1aa8c8b4d5d51a7d4cbd8522a00 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:38:33 -0400 Subject: [PATCH 0332/1048] Update eosio.system-deleteauth-rc.md removed deprecated arbitration clauses --- eosio.system-deleteauth-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-deleteauth-rc.md b/eosio.system-deleteauth-rc.md index fc1db915..c447bbe3 100644 --- a/eosio.system-deleteauth-rc.md +++ b/eosio.system-deleteauth-rc.md @@ -1,7 +1,5 @@ # Action - `{{ deleteauth }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ deleteauth }}` action... @@ -15,5 +13,3 @@ The `{{ deleteauth }}` action requires the following `inputs` and `input types`: | `{{ deleteauth }}` | `{{ accountVar }}`
`{{ permissionVar }}` | `{{ account_name }}`
`{{ permission_name }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From aefdf3eba22fd4da5b82fb827ee1a31ce6d59850 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:38:50 -0400 Subject: [PATCH 0333/1048] Update eosio.system-linkauth-rc.md removed deprecated arbitration clauses --- eosio.system-linkauth-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-linkauth-rc.md b/eosio.system-linkauth-rc.md index 9ba584cf..f3e4b726 100644 --- a/eosio.system-linkauth-rc.md +++ b/eosio.system-linkauth-rc.md @@ -1,7 +1,5 @@ # Action - `{{ linkauth }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ linkauth }}` action... @@ -15,5 +13,3 @@ The `{{ linkauth }}` action requires the following `inputs` and `input types`: | `{{ linkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}`
`{{ requirementVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 3005d8a2ca523fc131cba1dfd627f22c29373883 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:39:07 -0400 Subject: [PATCH 0334/1048] Update eosio.system-newaccount-rc.md removed deprecated arbitration clauses --- eosio.system-newaccount-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-newaccount-rc.md b/eosio.system-newaccount-rc.md index 1392f41a..70e9b473 100644 --- a/eosio.system-newaccount-rc.md +++ b/eosio.system-newaccount-rc.md @@ -1,7 +1,5 @@ # Action - `{{ newaccount }}` -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 `{{ newaccount }}` action creates a new account. @@ -15,5 +13,3 @@ The `{{ newaccount }}` action requires the following `inputs` and `input types`: | `{{ newaccount }}` | `{{ creatorVar }}`
`{{ nameVar }}`
`{{ ownerVar }}`
`{{ activeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | As an authorized party I {{ signer }} wish to exercise the authority of {{ creatorVar }} to create a new account on this system named {{ nameVar }} such that the new account's owner public key shall be {{ ownerVar }} and the active public key shall be {{ activeVar }}. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From bbbf63cb50862007fb50fbd530f7d7f97047d564 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:39:23 -0400 Subject: [PATCH 0335/1048] Update eosio.system-onerror-rc.md removed deprecated arbitration clauses --- eosio.system-onerror-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-onerror-rc.md b/eosio.system-onerror-rc.md index 7b8755ec..925abf77 100644 --- a/eosio.system-onerror-rc.md +++ b/eosio.system-onerror-rc.md @@ -1,7 +1,5 @@ # Action - `{{ onerror }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ onerror }}` action... @@ -15,5 +13,3 @@ The `{{ onerror }}` action requires the following `inputs` and `input types`: | `{{ onerror }}` | `{{ sender_idVar }}`
`{{ sent_trxVar }}` | `{{ uint128 }}`
`{{ bytes }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From d93f637b5e75a6b4ece07bdf5cad744712eba647 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:39:46 -0400 Subject: [PATCH 0336/1048] Update eosio.system-refund-rc.md removed deprecated arbitration clauses --- eosio.system-refund-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-refund-rc.md b/eosio.system-refund-rc.md index 7e2af028..04dac54a 100644 --- a/eosio.system-refund-rc.md +++ b/eosio.system-refund-rc.md @@ -1,7 +1,5 @@ # Action - `{{ refund }}` -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 intent of the `{{ refund }}` action is to return previously unstaked tokens to an account after the unstaking period has elapsed. @@ -16,5 +14,3 @@ The `{{ refund }}` action requires the following `input` and `input type`: As an authorized party I {{ signer }} wish to have the unstaked tokens of {{ ownerVar }} returned. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 340352b6dad6ebc1702cca918180a6882f7d832b Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:40:00 -0400 Subject: [PATCH 0337/1048] Update eosio.system-regproxy-rc.md removed deprecated arbitration clauses --- eosio.system-regproxy-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-regproxy-rc.md b/eosio.system-regproxy-rc.md index 3c78aa69..8e96159b 100644 --- a/eosio.system-regproxy-rc.md +++ b/eosio.system-regproxy-rc.md @@ -1,7 +1,5 @@ # Action - `{{ regproxy }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ regproxy }}` action... @@ -15,5 +13,3 @@ The `{{ regproxy }}` action requires the following `inputs` and `input types`: | `{{ regproxy }}` | `{{ proxyVar }}`
`{{ isproxyVar }}` | `{{ account_name }}`
`{{ bool }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 5369dba6335d6b9af3982b33f60436cbb6f445c6 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:40:15 -0400 Subject: [PATCH 0338/1048] Update eosio.system-reqauth-rc.md removed deprecated arbitration clauses --- eosio.system-reqauth-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-reqauth-rc.md b/eosio.system-reqauth-rc.md index c347e5b0..a95b8cb2 100644 --- a/eosio.system-reqauth-rc.md +++ b/eosio.system-reqauth-rc.md @@ -1,7 +1,5 @@ # Action - `{{ reqauth }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ reqauth }}` action... @@ -15,5 +13,3 @@ The `{{ reqauth }}` action requires the following `input` and `input type`: | `{{ reqauth }}` | `{{ fromVar }}` | `{{ account_name }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 9b56ae3768cba9b1d3a96325e9fa179613061776 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:40:52 -0400 Subject: [PATCH 0339/1048] Update eosio.system-sellram-rc.md removed deprecated arbitration clauses --- eosio.system-sellram-rc.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/eosio.system-sellram-rc.md b/eosio.system-sellram-rc.md index b10dfb04..ad4f616f 100644 --- a/eosio.system-sellram-rc.md +++ b/eosio.system-sellram-rc.md @@ -1,10 +1,8 @@ # Action - `{{ sellram }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description -The `{{ sellram }}` action... +The `{{ sellram }}` action sells unused RAM for SYS tokens. ### Inputs and Input Types @@ -15,5 +13,3 @@ The `{{ sellram }}` action requires the following `inputs` and `input types`: | `{{ sellram }}` | `{{ accountVar }}`
`{{ bytesVar }}` | `{{ account_name }}`
`{{ uint64 }}` | As an authorized party I {{ signer }} wish to sell {{ bytesVar }} of RAM from account {{ accountVar }}. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 7d6633b17caafc8e3e91a3ba727582c9f96d4d4c Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:41:12 -0400 Subject: [PATCH 0340/1048] Update eosio.system-setabi-rc.md removed deprecated arbitration clauses --- eosio.system-setabi-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-setabi-rc.md b/eosio.system-setabi-rc.md index 6167d2a8..21417856 100644 --- a/eosio.system-setabi-rc.md +++ b/eosio.system-setabi-rc.md @@ -1,7 +1,5 @@ # Action - `{{ setabi }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The intention of the `{{ setabi }}` action is to... @@ -15,5 +13,3 @@ The `{{ setabi }}` action requires the following `inputs` and `input types`: | `{{ setabi }}` | `{{ accountVar }}`
`{{ abiVar }}` | `{{ account_name }}`
`{{ bytes }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 3290df9fb197fb6cbc615578689db1e9c4145fad Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:41:29 -0400 Subject: [PATCH 0341/1048] Update eosio.system-setalimits-rc.md removed deprecated arbitration clauses --- eosio.system-setalimits-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-setalimits-rc.md b/eosio.system-setalimits-rc.md index 70b210ff..f03fbee1 100644 --- a/eosio.system-setalimits-rc.md +++ b/eosio.system-setalimits-rc.md @@ -1,7 +1,5 @@ # Action - `{{ setalimits }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ setalimits }}` action... @@ -16,5 +14,3 @@ The `{{ setalimits }}` action requires the following `inputs` and `input types`: As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 587d9210da11c36921f1b5a8e872b24cb0a94540 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:41:45 -0400 Subject: [PATCH 0342/1048] Update eosio.system-setglimits-rc.md removed deprecated arbitration clauses --- eosio.system-setglimits-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-setglimits-rc.md b/eosio.system-setglimits-rc.md index fa8405a4..0c168662 100644 --- a/eosio.system-setglimits-rc.md +++ b/eosio.system-setglimits-rc.md @@ -1,7 +1,5 @@ # Action - `{{ setglimits }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The intention of the `{{ setglimits }}` action is to ... @@ -15,5 +13,3 @@ The `{{ setglimits }}` action requires the following `input` and `input type`: | `{{ setglimits }}` | `{{ cpu_usec_per_periodVar }}` | `{{ int64 }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 6ee9e9164d0c086b707ee87d177fd18f4a2ac662 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:41:59 -0400 Subject: [PATCH 0343/1048] Update eosio.system-setpriv-rc.md removed deprecated arbitration clauses --- eosio.system-setpriv-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-setpriv-rc.md b/eosio.system-setpriv-rc.md index 9425fbed..0875c30d 100644 --- a/eosio.system-setpriv-rc.md +++ b/eosio.system-setpriv-rc.md @@ -1,7 +1,5 @@ # Action - `{{ setpriv }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The intention of the `{{ setpriv }}` action is to ... @@ -15,5 +13,3 @@ The `{{ setpriv }}` action requires the following `inputs` and `input types`: | `{{ setpriv }}` | `{{ accountVar }}`
`{{ is_privVar }}` | `{{ account_name }}`
`{{ int8 }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 039bad42ea14e5a9d14ab3c68719d321c13609c0 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:42:16 -0400 Subject: [PATCH 0344/1048] Update eosio.system-setprods-rc.md removed deprecated arbitration clauses --- eosio.system-setprods-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-setprods-rc.md b/eosio.system-setprods-rc.md index fd4f8d67..8b6ef8ca 100644 --- a/eosio.system-setprods-rc.md +++ b/eosio.system-setprods-rc.md @@ -1,7 +1,5 @@ # Action - `{{ setprods }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ setprods }}` action creates a new schedule of active producers, who will produce blocks in the order given. @@ -18,5 +16,3 @@ THIS IS A SYSTEM COMMAND NOT AVAILABLE FOR DIRECT ACCESS BY USERS. As an authorized party I {{ signer }} wish to set the rotation of producers to be {{ scheduleVar }}. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From bcb6f1230897e84f762f6fcc3b82f8d6e2331509 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:42:38 -0400 Subject: [PATCH 0345/1048] Update eosio.system-undelegatebw-rc.md removed deprecated arbitration clauses --- eosio.system-undelegatebw-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-undelegatebw-rc.md b/eosio.system-undelegatebw-rc.md index f0290732..e7a1fcf3 100644 --- a/eosio.system-undelegatebw-rc.md +++ b/eosio.system-undelegatebw-rc.md @@ -1,7 +1,5 @@ # eosio.system undelegatebw -This Ricardian contract for the system action *undelegatebw* is legally binding and can be used in the event of a dispute. - ## undelegatebw (account_name-from; account_name-to; @@ -13,5 +11,3 @@ _Intent: unstake tokens from bandwidth_ As an authorized party I {{ signer }} wish to unstake {{ asset-unstake_cpu_quantity }} from CPU and {{ asset-unstake_net_quantity }} from bandwidth from the tokens owned by {{ account_name-from }} previously delegated for the use of delegatee {{ account_name-to }}. If I as signer am not the beneficial owner of these tokens I stipulate I have proof that I’ve been authorized to take this action by their beneficial owner(s). - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 9251b842e85170704992d255c43a5d45d786ced4 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:42:55 -0400 Subject: [PATCH 0346/1048] Update eosio.system-unlinkauth-rc.md removed deprecated arbitration clauses --- eosio.system-unlinkauth-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-unlinkauth-rc.md b/eosio.system-unlinkauth-rc.md index 0e6034f8..b93928f8 100644 --- a/eosio.system-unlinkauth-rc.md +++ b/eosio.system-unlinkauth-rc.md @@ -1,7 +1,5 @@ # Action - `{{ unlinkauth }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ unlinkauth }}` action... @@ -16,5 +14,3 @@ The `{{ unlinkauth }}` action requires the following `inputs` and `input types`: As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 5843d2b136909fbdf91c3f79c9421e2fb49f45a0 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Wed, 30 May 2018 23:43:09 -0400 Subject: [PATCH 0347/1048] Update eosio.system-updateauth-rc.md removed deprecated arbitration clauses --- eosio.system-updateauth-rc.md | 4 ---- 1 file changed, 4 deletions(-) diff --git a/eosio.system-updateauth-rc.md b/eosio.system-updateauth-rc.md index fe5d639a..0e614458 100644 --- a/eosio.system-updateauth-rc.md +++ b/eosio.system-updateauth-rc.md @@ -1,7 +1,5 @@ # Action - `{{ updateauth }}` -This Contract is legally binding and can be used in the event of a dispute. - ### Description The `{{ updateauth }}` action... @@ -15,5 +13,3 @@ The `{{ updateauth }}` action requires the following `inputs` and `input types`: | `{{ updateauth }}` | `{{ accountVar }}`
`{{ permissionVar }}`
`{{ parentVar }}`
`{{ authVar }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | As an authorized party I {{ signer }} wish to UNKNOWN - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. From 786b50f6ef11b3dca8c8dd896e28f1a10b5e221b Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 09:57:15 -0400 Subject: [PATCH 0348/1048] Update eosio.system-buyram-rc.md --- eosio.system-buyram-rc.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/eosio.system-buyram-rc.md b/eosio.system-buyram-rc.md index 6d95fceb..98c775d7 100644 --- a/eosio.system-buyram-rc.md +++ b/eosio.system-buyram-rc.md @@ -2,11 +2,11 @@ ### Description -This action will attempt to reserve about {{quant}} SYS tokens worth of RAM on behalf of {{receiver}}. +This action will attempt to reserve about {{quant}} worth of RAM on behalf of {{receiver}}. -{{buyer}} authorizes this contract to transfer {{quant}} SYS tokens to buy RAM based upon the current price as determined by the market maker algorithm. +{{buyer}} authorizes this contract to transfer {{quant}} to buy RAM based upon the current price as determined by the market maker algorithm. -{{buyer}} accepts that a 0.5% fee will be charged on the SYS spent and that the actual RAM received may be slightly less than expected due to the approximations necessary to enable this service. +{{buyer}} accepts that a 0.5% fee will be charged on the amount spent and that the actual RAM received may be slightly less than expected due to the approximations necessary to enable this service. {{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. {{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. {{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. From b09147c76f207c8b105eddee50ce2938481cd4aa Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 09:59:06 -0400 Subject: [PATCH 0349/1048] Update eosio.system-sellram-rc.md removed 'SYS' --- eosio.system-sellram-rc.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system-sellram-rc.md b/eosio.system-sellram-rc.md index ad4f616f..316c7dec 100644 --- a/eosio.system-sellram-rc.md +++ b/eosio.system-sellram-rc.md @@ -2,7 +2,7 @@ ### Description -The `{{ sellram }}` action sells unused RAM for SYS tokens. +The `{{ sellram }}` action sells unused RAM for tokens. ### Inputs and Input Types From 85d8e3e3479742fe90d03bb06a4706f619016ec0 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:36:00 -0400 Subject: [PATCH 0350/1048] Create eosio.system-delband-rc.md --- eosio.system-delband-rc.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 eosio.system-delband-rc.md diff --git a/eosio.system-delband-rc.md b/eosio.system-delband-rc.md new file mode 100644 index 00000000..98c44af1 --- /dev/null +++ b/eosio.system-delband-rc.md @@ -0,0 +1,6 @@ +# Action - `{{ delband }}` + +### Description + +This action will ... + From babcf47d16f12f35ac775d7e357ae30da601d5d7 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:37:14 -0400 Subject: [PATCH 0351/1048] Create eosio.system-global-rc.md --- eosio.system-global-rc.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 eosio.system-global-rc.md diff --git a/eosio.system-global-rc.md b/eosio.system-global-rc.md new file mode 100644 index 00000000..e2ac60d2 --- /dev/null +++ b/eosio.system-global-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ global }}` + +### Description + +This action will ... From cf87f63d4857926a08e5ddf80bb948ea3f2193ed Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:37:38 -0400 Subject: [PATCH 0352/1048] Create eosio.system-producers-rc.md --- eosio.system-producers-rc.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 eosio.system-producers-rc.md diff --git a/eosio.system-producers-rc.md b/eosio.system-producers-rc.md new file mode 100644 index 00000000..fd0715d6 --- /dev/null +++ b/eosio.system-producers-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ producers }}` + +### Description + +This action will ... From 6f5698fa086bd648d426ad592ae1a34fb58d5e80 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:38:12 -0400 Subject: [PATCH 0353/1048] Create eosio.system-rammarket-rc.md --- eosio.system-rammarket-rc.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 eosio.system-rammarket-rc.md diff --git a/eosio.system-rammarket-rc.md b/eosio.system-rammarket-rc.md new file mode 100644 index 00000000..8f9566db --- /dev/null +++ b/eosio.system-rammarket-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ rammarket }}` + +### Description + +This action will ... From 1070c4f66c9dc7fc501d77e16482cb0ec2082346 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:38:34 -0400 Subject: [PATCH 0354/1048] Create eosio.system-refunds-rc.md --- eosio.system-refunds-rc.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 eosio.system-refunds-rc.md diff --git a/eosio.system-refunds-rc.md b/eosio.system-refunds-rc.md new file mode 100644 index 00000000..af134800 --- /dev/null +++ b/eosio.system-refunds-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ refunds }}` + +### Description + +This action will ... From f628c939bff611c4970ae262cca6c787c683b809 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:41:02 -0400 Subject: [PATCH 0355/1048] Create eosio.system-rmvproducer-rc.md --- eosio.system-rmvproducer-rc.md | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 eosio.system-rmvproducer-rc.md diff --git a/eosio.system-rmvproducer-rc.md b/eosio.system-rmvproducer-rc.md new file mode 100644 index 00000000..7d8d3037 --- /dev/null +++ b/eosio.system-rmvproducer-rc.md @@ -0,0 +1,7 @@ +# Action - `{{ rmvproducer }}` + +### Description + +This action will remove a producer from the schedule. Should be called by other scheduled producers only sparingly and for the purpose of maintaining chain integrity and network stability. + +Producers who call this without appropriate justification, such as a mutually agreed SLA or other objective criteria, can be liable for lost revenue and lost reputation suffered by the target of this call. From a0c156c9a3ea920b9ca053f44482745d8a7c88e1 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:41:37 -0400 Subject: [PATCH 0356/1048] Create eosio.system-setparams-rc.md --- eosio.system-setparams-rc.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 eosio.system-setparams-rc.md diff --git a/eosio.system-setparams-rc.md b/eosio.system-setparams-rc.md new file mode 100644 index 00000000..48f09b94 --- /dev/null +++ b/eosio.system-setparams-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ setparams }}` + +### Description + +This action will set system parameters. From e60bce59ec6c9bdc1d40fef8d921cc674a827fd2 Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:42:34 -0400 Subject: [PATCH 0357/1048] Create eosio.system-userres-rc.md --- eosio.system-userres-rc.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 eosio.system-userres-rc.md diff --git a/eosio.system-userres-rc.md b/eosio.system-userres-rc.md new file mode 100644 index 00000000..1c99be09 --- /dev/null +++ b/eosio.system-userres-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ userres }}` + +### Description + +This action will (something) user resources __... From 603a0ca6e65c6f30a0490cd1fe98fb32a8b792ee Mon Sep 17 00:00:00 2001 From: Thomas Cox Date: Thu, 31 May 2018 11:43:23 -0400 Subject: [PATCH 0358/1048] Create eosio.system-voters-rc.md --- eosio.system-voters-rc.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 eosio.system-voters-rc.md diff --git a/eosio.system-voters-rc.md b/eosio.system-voters-rc.md new file mode 100644 index 00000000..b680658d --- /dev/null +++ b/eosio.system-voters-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ voters }}` + +### Description + +This action will ... From 1ff7f1df5e1002220d7e6dce9b4cece08d6407f3 Mon Sep 17 00:00:00 2001 From: Andrianto Lie Date: Thu, 31 May 2018 13:57:58 -0400 Subject: [PATCH 0359/1048] Fix unable to delegatebw when the receiver has stakes --- voting.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/voting.cpp b/voting.cpp index a00e2054..8d31f244 100644 --- a/voting.cpp +++ b/voting.cpp @@ -126,12 +126,11 @@ namespace eosiosystem { * If voting for a proxy, the producer votes will not change until the proxy updates their own vote. */ void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector& producers ) { + require_auth( voter_name ); update_votes( voter_name, proxy, producers, true ); } void system_contract::update_votes( const account_name voter_name, const account_name proxy, const std::vector& producers, bool voting ) { - require_auth( voter_name ); - //validate input if ( proxy ) { eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" ); From 557ec169e3d414fcd15788135a2c3a028d178411 Mon Sep 17 00:00:00 2001 From: Greg Lee Date: Thu, 31 May 2018 14:49:54 -0400 Subject: [PATCH 0360/1048] Remove Ricardian contracts --- eosio.system-bidname-rc.md | 15 ------- eosio.system-buyram-rc.md | 16 ------- eosio.system-buyrambytes-rc.md | 16 ------- eosio.system-canceldelay-rc.md | 15 ------- eosio.system-claimrewards-rc.md | 15 ------- eosio.system-clause-constitution-rc.md | 58 ------------------------ eosio.system-delband-rc.md | 6 --- eosio.system-delegatebw-rc.md | 20 --------- eosio.system-deleteauth-rc.md | 15 ------- eosio.system-global-rc.md | 5 --- eosio.system-linkauth-rc.md | 15 ------- eosio.system-newaccount-rc.md | 15 ------- eosio.system-onerror-rc.md | 15 ------- eosio.system-producers-rc.md | 5 --- eosio.system-rammarket-rc.md | 5 --- eosio.system-rc.md | 41 ----------------- eosio.system-refund-rc.md | 16 ------- eosio.system-refunds-rc.md | 5 --- eosio.system-regproducer-rc.md | 62 -------------------------- eosio.system-regproxy-rc.md | 15 ------- eosio.system-reqauth-rc.md | 15 ------- eosio.system-rmvproducer-rc.md | 7 --- eosio.system-sellram-rc.md | 15 ------- eosio.system-setabi-rc.md | 15 ------- eosio.system-setalimits-rc.md | 16 ------- eosio.system-setcode-rc.md | 12 ----- eosio.system-setglimits-rc.md | 15 ------- eosio.system-setparams-rc.md | 5 --- eosio.system-setpriv-rc.md | 15 ------- eosio.system-setprods-rc.md | 18 -------- eosio.system-setram-rc.md | 8 ---- eosio.system-undelegatebw-rc.md | 13 ------ eosio.system-unlinkauth-rc.md | 16 ------- eosio.system-unregprod-rc.md | 15 ------- eosio.system-updateauth-rc.md | 15 ------- eosio.system-userres-rc.md | 5 --- eosio.system-voteproducer-rc.md | 18 -------- eosio.system-voters-rc.md | 5 --- 38 files changed, 603 deletions(-) delete mode 100644 eosio.system-bidname-rc.md delete mode 100644 eosio.system-buyram-rc.md delete mode 100644 eosio.system-buyrambytes-rc.md delete mode 100644 eosio.system-canceldelay-rc.md delete mode 100644 eosio.system-claimrewards-rc.md delete mode 100644 eosio.system-clause-constitution-rc.md delete mode 100644 eosio.system-delband-rc.md delete mode 100644 eosio.system-delegatebw-rc.md delete mode 100644 eosio.system-deleteauth-rc.md delete mode 100644 eosio.system-global-rc.md delete mode 100644 eosio.system-linkauth-rc.md delete mode 100644 eosio.system-newaccount-rc.md delete mode 100644 eosio.system-onerror-rc.md delete mode 100644 eosio.system-producers-rc.md delete mode 100644 eosio.system-rammarket-rc.md delete mode 100644 eosio.system-rc.md delete mode 100644 eosio.system-refund-rc.md delete mode 100644 eosio.system-refunds-rc.md delete mode 100644 eosio.system-regproducer-rc.md delete mode 100644 eosio.system-regproxy-rc.md delete mode 100644 eosio.system-reqauth-rc.md delete mode 100644 eosio.system-rmvproducer-rc.md delete mode 100644 eosio.system-sellram-rc.md delete mode 100644 eosio.system-setabi-rc.md delete mode 100644 eosio.system-setalimits-rc.md delete mode 100644 eosio.system-setcode-rc.md delete mode 100644 eosio.system-setglimits-rc.md delete mode 100644 eosio.system-setparams-rc.md delete mode 100644 eosio.system-setpriv-rc.md delete mode 100644 eosio.system-setprods-rc.md delete mode 100644 eosio.system-setram-rc.md delete mode 100644 eosio.system-undelegatebw-rc.md delete mode 100644 eosio.system-unlinkauth-rc.md delete mode 100644 eosio.system-unregprod-rc.md delete mode 100644 eosio.system-updateauth-rc.md delete mode 100644 eosio.system-userres-rc.md delete mode 100644 eosio.system-voteproducer-rc.md delete mode 100644 eosio.system-voters-rc.md diff --git a/eosio.system-bidname-rc.md b/eosio.system-bidname-rc.md deleted file mode 100644 index e71f2fa4..00000000 --- a/eosio.system-bidname-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ bidname }}` - -### Description - -The `{{ bidname }}` action places a bid on a premium account name, in the knowledge that the high bid will purchase the name. - -### Inputs and Input Types - -The `{{ bidname }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ bidname }}` | `{{ bidderVar }}`
`{{ newnameVar }}`
`{{ bidVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | - -As an authorized party I {{ signer }} wish to bid on behalf of {{ bidderVar }} the amount of {{ bidVar }} toward purchase of the account name {{ newnameVar }}. diff --git a/eosio.system-buyram-rc.md b/eosio.system-buyram-rc.md deleted file mode 100644 index 98c775d7..00000000 --- a/eosio.system-buyram-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ buyram }}` - -### Description - -This action will attempt to reserve about {{quant}} worth of RAM on behalf of {{receiver}}. - -{{buyer}} authorizes this contract to transfer {{quant}} to buy RAM based upon the current price as determined by the market maker algorithm. - -{{buyer}} accepts that a 0.5% fee will be charged on the amount spent and that the actual RAM received may be slightly less than expected due to the approximations necessary to enable this service. -{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. -{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. -{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. -{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. -{{buyer}} acknowledges that RAM is non-transferrable. -{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. - diff --git a/eosio.system-buyrambytes-rc.md b/eosio.system-buyrambytes-rc.md deleted file mode 100644 index 63a60e83..00000000 --- a/eosio.system-buyrambytes-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ buyrambytes }}` - -### Description - -This action will attempt to reserve about {{bytes}} bytes of RAM on behalf of {{receiver}}. - -{{buyer}} authorizes this conrtact to transfer sufficient SYS tokens to buy the RAM based upon the current price as determined by the market maker algorithm. - -{{buyer}} accepts that a 0.5% fee will be charged on the SYS spent and that the actual RAM received may be slightly less than requested due to the approximations necessary to enable this service. -{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. -{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. -{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. -{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. -{{buyer}} acknowledges that RAM is non-transferrable. -{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. - diff --git a/eosio.system-canceldelay-rc.md b/eosio.system-canceldelay-rc.md deleted file mode 100644 index 8c7c0a38..00000000 --- a/eosio.system-canceldelay-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ canceldelay }}` - -### Description - -The `{{ canceldelay }}` action cancels an existing delayed transaction. - -### Inputs and Input Types - -The `{{ canceldelay }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ canceldelay }}` | `{{ canceling_authVar }}`
`{{ trx_idVar }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | - -As an authorized party I {{ signer }} wish to invoke the authority of {{ canceling_authVar }} to cancel the transaction with ID {{ trx_idVar }}. diff --git a/eosio.system-claimrewards-rc.md b/eosio.system-claimrewards-rc.md deleted file mode 100644 index 47362044..00000000 --- a/eosio.system-claimrewards-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ claimrewards }}` - -### Description - -The `{{ claimrewards }}` action allows a block producer (active or standby) to claim the system rewards due them for producing blocks and receiving votes. - -### Input and Input Type - -The `{{ claimrewards }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ claimrewards }}` | `{{ ownerVar }}` | `{{ account_name }}` | - -As an authorized party I {{ signer }} wish to have the rewards earned by {{ ownerVar }} deposited into their (my) account. diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md deleted file mode 100644 index 0f4057b0..00000000 --- a/eosio.system-clause-constitution-rc.md +++ /dev/null @@ -1,58 +0,0 @@ -This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. - -# Article I - No Initiation of Violence -Members shall not initiate violence or the threat of violence against another Member. - -# Article II - No Perjury -Members shall be liable for losses caused by false or misleading attestations and shall forfeit any profit gained thereby. - -# Article III - Rights -The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or via community referendum. This Constitution creates no positive rights for or between any Members. - -# Article IV - No Vote Buying -No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. - -# Article V - No Fiduciary -No Member nor SYS token holder shall have fiduciary responsibility to support the value of the SYS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of SYS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the SYS token supply. - -# Article VI - Restitution -Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. - -# Article VII - Open Source -Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via a free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. - -# Article VIII - Language -Multi-lingual contracts must specify one prevailing language in case of dispute and the author of any translation shall be liable for losses due to their false, misleading, or ambiguous attested translations. - -# Article IX - Dispute Resolution -All disputes arising out of or in connection with this Constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. - -# Article X - Choice of Law -Choice of law for disputes shall be, in order of precedence, this Constitution and the Maxims of Equity. - -# Article XI - Amending -This Constitution and its subordinate documents shall not be amended except by a vote of the token holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. - -# Article XII - Publishing -Members may only publish information to the Blockchain that is within their right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. - -# Article XIII - Informed Consent -All service providers who produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present to said other Members the full Ricardian contract terms of this Constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. - -# Article XIV - Severability -If any part of this Constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. - -# Article XV - Termination of Agreement -A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members according to the system contract provisions then in effect for such redistribution. - -# Article XVI - Developer Liability -Members agree to hold software developers harmless for unintentional mistakes made in the expression of contractual intent, whether or not said mistakes were due to actual or perceived negligence. - -# Article XVII - Consideration -All rights and obligations under this Constitution are mutual and reciprocal and of equally significant value and cost to all parties. - -# Article XVIII - Acceptance -A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI of said contract and said transaction is incorporated into the blockchain. - -# Article XIX - Counterparts -This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. diff --git a/eosio.system-delband-rc.md b/eosio.system-delband-rc.md deleted file mode 100644 index 98c44af1..00000000 --- a/eosio.system-delband-rc.md +++ /dev/null @@ -1,6 +0,0 @@ -# Action - `{{ delband }}` - -### Description - -This action will ... - diff --git a/eosio.system-delegatebw-rc.md b/eosio.system-delegatebw-rc.md deleted file mode 100644 index 5db46687..00000000 --- a/eosio.system-delegatebw-rc.md +++ /dev/null @@ -1,20 +0,0 @@ -# eosio.system delegatebw - -## delegatebw - (account_name-from; - account_name-to; - asset-stake_net_quantity; - asset-stake_cpu_quantity; - bool:transfer) - -_Intent: stake tokens for bandwidth and/or CPU and optionally transfer ownership_ - -As an authorized party I {{ signer }} wish to stake {{ asset-stake_cpu_quantity }} for CPU and {{ asset-stake_net_quantity }} for bandwidth from the liquid tokens of {{ account_name-from }} for the use of delegatee {{ account_name-to }}. - - {{if bool:transfer }} - -It is {{ bool:transfer }} that I wish these tokens to become immediately owned by the delegatee. - - {{/if}} - -As signer I stipulate that, if I am not the beneficial owner of these tokens, I have proof that I’ve been authorized to take this action by their beneficial owner(s). diff --git a/eosio.system-deleteauth-rc.md b/eosio.system-deleteauth-rc.md deleted file mode 100644 index c447bbe3..00000000 --- a/eosio.system-deleteauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ deleteauth }}` - -### Description - -The `{{ deleteauth }}` action... - -### Inputs and Input Types - -The `{{ deleteauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ deleteauth }}` | `{{ accountVar }}`
`{{ permissionVar }}` | `{{ account_name }}`
`{{ permission_name }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-global-rc.md b/eosio.system-global-rc.md deleted file mode 100644 index e2ac60d2..00000000 --- a/eosio.system-global-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ global }}` - -### Description - -This action will ... diff --git a/eosio.system-linkauth-rc.md b/eosio.system-linkauth-rc.md deleted file mode 100644 index f3e4b726..00000000 --- a/eosio.system-linkauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ linkauth }}` - -### Description - -The `{{ linkauth }}` action... - -### Inputs and Input Types - -The `{{ linkauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ linkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}`
`{{ requirementVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-newaccount-rc.md b/eosio.system-newaccount-rc.md deleted file mode 100644 index 70e9b473..00000000 --- a/eosio.system-newaccount-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ newaccount }}` - -### Description - -The `{{ newaccount }}` action creates a new account. - -### Inputs and Input Types - -The `{{ newaccount }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ newaccount }}` | `{{ creatorVar }}`
`{{ nameVar }}`
`{{ ownerVar }}`
`{{ activeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | - -As an authorized party I {{ signer }} wish to exercise the authority of {{ creatorVar }} to create a new account on this system named {{ nameVar }} such that the new account's owner public key shall be {{ ownerVar }} and the active public key shall be {{ activeVar }}. diff --git a/eosio.system-onerror-rc.md b/eosio.system-onerror-rc.md deleted file mode 100644 index 925abf77..00000000 --- a/eosio.system-onerror-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ onerror }}` - -### Description - -The `{{ onerror }}` action... - -### Inputs and Input Types - -The `{{ onerror }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ onerror }}` | `{{ sender_idVar }}`
`{{ sent_trxVar }}` | `{{ uint128 }}`
`{{ bytes }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-producers-rc.md b/eosio.system-producers-rc.md deleted file mode 100644 index fd0715d6..00000000 --- a/eosio.system-producers-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ producers }}` - -### Description - -This action will ... diff --git a/eosio.system-rammarket-rc.md b/eosio.system-rammarket-rc.md deleted file mode 100644 index 8f9566db..00000000 --- a/eosio.system-rammarket-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ rammarket }}` - -### Description - -This action will ... diff --git a/eosio.system-rc.md b/eosio.system-rc.md deleted file mode 100644 index 8919cbae..00000000 --- a/eosio.system-rc.md +++ /dev/null @@ -1,41 +0,0 @@ -# Smart Contract - `{{ eosio.system }}` - -This is an overview of the actions for the `{{ eosio.system }}` 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 `{{ eosio.system }}` contract... - -### Actions, Inputs and Input Types - -The table below contains the `actions`, `inputs` and `input types` for the `{{ eosio.system }}` contract. - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ newaccount }}` | `{{ creator }}`
`{{ name }}`
`{{ owner }}`
`{{ active }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | -| `{{ setcode }}` | `{{ account }}`
`{{ vmtype }}`
`{{ vmversion }}`
`{{ code }}` | `{{ account_name }}`
`{{ uint8 }}`
`{{ uint8 }}`
`{{ bytes }}` | -| `{{ setabi }}` | `{{ account }}`
`{{ abi }}` | `{{ account_name }}`
`{{ bytes }}` | -| `{{ updateauth }}` | `{{ account }}`
`{{ permission }}`
`{{ parent }}`
`{{ auth }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | -| `{{ deleteauth }}` | `{{ account }}`
`{{ permission }}` | `{{ account_name }}`
`{{ permission_name }}` | -| `{{ linkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}`
`{{ requirement }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | -| `{{ unlinkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | -| `{{ canceldelay }}` | `{{ canceling_auth }}`
`{{ trx_id }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | -| `{{ onerror }}` | `{{ sender_id }}`
`{{ sent_trx }}` | `{{ uint128 }}`
`{{ bytes }}` | -| `{{ buyrambytes }}` | `{{ payer }}`
`{{ receiver }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ uint32 }}` | -| `{{ buyram }}` | `{{ payer }}`
`{{ receiver }}`
`{{ quant }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | -| `{{ sellram }}` | `{{ account }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ uint64 }}` | -| `{{ delegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ stake_net_quantity }}`
`{{ stake_cpu_quantity }}`
`{{ transfer }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}`
`{{ bool }}` | -| `{{ undelegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ unstake_net_quantity }}`
`{{ unstake_cpu_quantity }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}` | -| `{{ refund }}` | `{{ owner }}` | `{{ account_name }}` | -| `{{ regproducer }}` | `{{ producer }}`
`{{ producer_key }}`
`{{ url }}`
`{{ location }}` | `{{ account_name }}`
`{{ public_key }}`
`{{ string }}`
`{{ uint16 }}` | -| `{{ setram }}` | `{{ max_ram_size }}` | `{{ uint64 }}` | -| `{{ bidname }}` | `{{ bidder }}`
`{{ newname }}`
`{{ bid }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | -| `{{ unregprod }}` | `{{ producer }}` | `{{ account_name }}` | -| `{{ regproxy }}` | `{{ proxy }}`
`{{ isproxy }}` | `{{ account_name }}`
`{{ bool }}` | -| `{{ voteproducer }}` | `{{ voter }}`
`{{ proxy }}`
`{{ producers }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ account_name[] }}` | -| `{{ claimrewards }}` | `{{ owner }}` | `{{ account_name }}` | -| `{{ setpriv }}` | `{{ account }}`
`{{ is_priv }}` | `{{ account_name }}`
`{{ int8 }}` | -| `{{ setalimits }}` | `{{ account }}`
`{{ ram_bytes }}`
`{{ net_weight }}`
`{{ cpu_weight }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | -| `{{ setglimits }}` | `{{ cpu_usec_per_period }}` | `{{ int64 }}` | -| `{{ setprods }}` | `{{ schedule }}` | `{{ producer_key[] }}` | -| `{{ reqauth }}` | `{{ from }}` | `{{ account_name }}` | \ No newline at end of file diff --git a/eosio.system-refund-rc.md b/eosio.system-refund-rc.md deleted file mode 100644 index 04dac54a..00000000 --- a/eosio.system-refund-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ refund }}` - -### Description - -The intent of the `{{ refund }}` action is to return previously unstaked tokens to an account after the unstaking period has elapsed. - -### Input and Input Type - -The `{{ refund }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ refund }}` | `{{ ownerVar }}` | `{{ account_name }}` | - - -As an authorized party I {{ signer }} wish to have the unstaked tokens of {{ ownerVar }} returned. diff --git a/eosio.system-refunds-rc.md b/eosio.system-refunds-rc.md deleted file mode 100644 index af134800..00000000 --- a/eosio.system-refunds-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ refunds }}` - -### Description - -This action will ... diff --git a/eosio.system-regproducer-rc.md b/eosio.system-regproducer-rc.md deleted file mode 100644 index 9857bc90..00000000 --- a/eosio.system-regproducer-rc.md +++ /dev/null @@ -1,62 +0,0 @@ -# eosio.system regproducer - -I, {{producer}}, hereby nominate myself for consideration as an elected block producer. - -If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. - -If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. - -I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. - -{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: - -1. proposing an objectively valid block at the time appointed by the block scheduling algorithm -2. pre-confirming a block produced by another producer in the schedule when I find said block objectively valid -3. confirming a block for which {{producer}} has received 2/3+ pre-confirmation messages from other producers - -I hereby accept liability for any and all provable damages that result from my: - -1. signing two different block proposals with the same timestamp with {{producer_key} -2. signing two different block proposals with the same block number with {{producer_key} -3. signing any block proposal which builds off of an objectively invalid block -4. signing a pre-confirmation for an objectively invalid block -5. signing a confirmation for a block for which I do not possess pre-confirmation messages from 2/3+ other producers - -I hereby agree that double-signing for a timestamp or block number in concert with 2 or more other producers shall automatically be deemed malicious and subject to a fine equal to the past year of compensation received and imediate disqualification from being a producer, and other damages. An exception may be made if {{producer}} can demonstrate that the double-signing occured due to a bug in the reference software; the burden of proof is on {{producer}}. - -I hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. - -I hereby acknowledge that 2/3+ other elected producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among producers. - -If {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least 1 validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among producers, said method and reports to be made public. - -The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. - -I agree to process transactions on a FIFO best-effort basis and to honestly bill transactions for measured execution time. - -I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: - -1. the order in which transactions are included -2. the hash of the block that is produced - -I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my company who own more than 1%. - -I, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain. - -I, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract. - -I, {{producer}}, agree to set {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer. - -I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among producers. - -I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior producer. - -I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either CPU or network bandwidth metrics. - -I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by 2/3+ producers, as shown in the system parameters. - -## Constitution - -This agreement incorporates the current blockchain constitution: - -{{constitution}} diff --git a/eosio.system-regproxy-rc.md b/eosio.system-regproxy-rc.md deleted file mode 100644 index 8e96159b..00000000 --- a/eosio.system-regproxy-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ regproxy }}` - -### Description - -The `{{ regproxy }}` action... - -### Inputs and Input Types - -The `{{ regproxy }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ regproxy }}` | `{{ proxyVar }}`
`{{ isproxyVar }}` | `{{ account_name }}`
`{{ bool }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-reqauth-rc.md b/eosio.system-reqauth-rc.md deleted file mode 100644 index a95b8cb2..00000000 --- a/eosio.system-reqauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ reqauth }}` - -### Description - -The `{{ reqauth }}` action... - -### Input and Input Type - -The `{{ reqauth }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ reqauth }}` | `{{ fromVar }}` | `{{ account_name }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-rmvproducer-rc.md b/eosio.system-rmvproducer-rc.md deleted file mode 100644 index 7d8d3037..00000000 --- a/eosio.system-rmvproducer-rc.md +++ /dev/null @@ -1,7 +0,0 @@ -# Action - `{{ rmvproducer }}` - -### Description - -This action will remove a producer from the schedule. Should be called by other scheduled producers only sparingly and for the purpose of maintaining chain integrity and network stability. - -Producers who call this without appropriate justification, such as a mutually agreed SLA or other objective criteria, can be liable for lost revenue and lost reputation suffered by the target of this call. diff --git a/eosio.system-sellram-rc.md b/eosio.system-sellram-rc.md deleted file mode 100644 index 316c7dec..00000000 --- a/eosio.system-sellram-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ sellram }}` - -### Description - -The `{{ sellram }}` action sells unused RAM for tokens. - -### Inputs and Input Types - -The `{{ sellram }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ sellram }}` | `{{ accountVar }}`
`{{ bytesVar }}` | `{{ account_name }}`
`{{ uint64 }}` | - -As an authorized party I {{ signer }} wish to sell {{ bytesVar }} of RAM from account {{ accountVar }}. diff --git a/eosio.system-setabi-rc.md b/eosio.system-setabi-rc.md deleted file mode 100644 index 21417856..00000000 --- a/eosio.system-setabi-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ setabi }}` - -### Description - -The intention of the `{{ setabi }}` action is to... - -### Inputs and Input Types - -The `{{ setabi }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setabi }}` | `{{ accountVar }}`
`{{ abiVar }}` | `{{ account_name }}`
`{{ bytes }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setalimits-rc.md b/eosio.system-setalimits-rc.md deleted file mode 100644 index f03fbee1..00000000 --- a/eosio.system-setalimits-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ setalimits }}` - -### Description - -The `{{ setalimits }}` action... - -### Inputs and Input Types - -The `{{ setalimits }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setalimits }}` | `{{ accountVar }}`
`{{ ram_bytesVar }}`
`{{ net_weightVar }}`
`{{ cpu_weightVar }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | - - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setcode-rc.md b/eosio.system-setcode-rc.md deleted file mode 100644 index 5a0d7217..00000000 --- a/eosio.system-setcode-rc.md +++ /dev/null @@ -1,12 +0,0 @@ -# Action - `{{ setcode }}` - -### Description - -This action updates the code that will run in response to delivered actions. It may be performed by the account upon which the code is being deployed. - -By deploying this code you certify that: - -1. the code is not malicious -2. you are authorized to perform the actions automated by the code -3. the code is consistant with the ABI deployed and intent of the contract -4. updates to the code are consistant with the prior code's intent diff --git a/eosio.system-setglimits-rc.md b/eosio.system-setglimits-rc.md deleted file mode 100644 index 0c168662..00000000 --- a/eosio.system-setglimits-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ setglimits }}` - -### Description - -The intention of the `{{ setglimits }}` action is to ... - -### Input and Input Type - -The `{{ setglimits }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setglimits }}` | `{{ cpu_usec_per_periodVar }}` | `{{ int64 }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setparams-rc.md b/eosio.system-setparams-rc.md deleted file mode 100644 index 48f09b94..00000000 --- a/eosio.system-setparams-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ setparams }}` - -### Description - -This action will set system parameters. diff --git a/eosio.system-setpriv-rc.md b/eosio.system-setpriv-rc.md deleted file mode 100644 index 0875c30d..00000000 --- a/eosio.system-setpriv-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ setpriv }}` - -### Description - -The intention of the `{{ setpriv }}` action is to ... - -### Inputs and Input Types - -The `{{ setpriv }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setpriv }}` | `{{ accountVar }}`
`{{ is_privVar }}` | `{{ account_name }}`
`{{ int8 }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setprods-rc.md b/eosio.system-setprods-rc.md deleted file mode 100644 index 8b6ef8ca..00000000 --- a/eosio.system-setprods-rc.md +++ /dev/null @@ -1,18 +0,0 @@ -# Action - `{{ setprods }}` - -### Description - -The `{{ setprods }}` action creates a new schedule of active producers, who will produce blocks in the order given. - -### Input and Input Type - -The `{{ setprods }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setprods }}` | `{{ scheduleVar }}` | `{{ producer_key[] }}` | - -THIS IS A SYSTEM COMMAND NOT AVAILABLE FOR DIRECT ACCESS BY USERS. - - -As an authorized party I {{ signer }} wish to set the rotation of producers to be {{ scheduleVar }}. diff --git a/eosio.system-setram-rc.md b/eosio.system-setram-rc.md deleted file mode 100644 index e9a3ce66..00000000 --- a/eosio.system-setram-rc.md +++ /dev/null @@ -1,8 +0,0 @@ -# Action - `{{ setram }}` - -### Description - -This action sets the total RAM that may be allocated for use by accounts. It may only increase. - -Only the controller of this contract may update the RAM availablity. If the owner is a multi-sig collective, the -parties to the multi-sig each certify that off-the-shelf machines exist capable of supporting the available RAM. diff --git a/eosio.system-undelegatebw-rc.md b/eosio.system-undelegatebw-rc.md deleted file mode 100644 index e7a1fcf3..00000000 --- a/eosio.system-undelegatebw-rc.md +++ /dev/null @@ -1,13 +0,0 @@ -# eosio.system undelegatebw - -## undelegatebw - (account_name-from; - account_name-to; - asset-unstake_net_quantity; - asset-unstake_cpu_quantity) - -_Intent: unstake tokens from bandwidth_ - -As an authorized party I {{ signer }} wish to unstake {{ asset-unstake_cpu_quantity }} from CPU and {{ asset-unstake_net_quantity }} from bandwidth from the tokens owned by {{ account_name-from }} previously delegated for the use of delegatee {{ account_name-to }}. - -If I as signer am not the beneficial owner of these tokens I stipulate I have proof that I’ve been authorized to take this action by their beneficial owner(s). diff --git a/eosio.system-unlinkauth-rc.md b/eosio.system-unlinkauth-rc.md deleted file mode 100644 index b93928f8..00000000 --- a/eosio.system-unlinkauth-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ unlinkauth }}` - -### Description - -The `{{ unlinkauth }}` action... - -### Inputs and Input Types - -The `{{ unlinkauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ unlinkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | - - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-unregprod-rc.md b/eosio.system-unregprod-rc.md deleted file mode 100644 index de3dad69..00000000 --- a/eosio.system-unregprod-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ unregprod }}` - -### Description - -The `{{ unregprod }}` action unregisters a previously registered block producer candidate. - -### Input and Input Type - -The `{{ unregprod }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ unregprod }}` | `{{ producerVar }}` | `{{ account_name }}` | - -As an authorized party I {{ signer }} wish to unregister the block producer candidate {{ producerVar }}, rendering that candidate no longer able to receive votes. diff --git a/eosio.system-updateauth-rc.md b/eosio.system-updateauth-rc.md deleted file mode 100644 index 0e614458..00000000 --- a/eosio.system-updateauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ updateauth }}` - -### Description - -The `{{ updateauth }}` action... - -### Inputs and Input Types - -The `{{ updateauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ updateauth }}` | `{{ accountVar }}`
`{{ permissionVar }}`
`{{ parentVar }}`
`{{ authVar }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-userres-rc.md b/eosio.system-userres-rc.md deleted file mode 100644 index 1c99be09..00000000 --- a/eosio.system-userres-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ userres }}` - -### Description - -This action will (something) user resources __... diff --git a/eosio.system-voteproducer-rc.md b/eosio.system-voteproducer-rc.md deleted file mode 100644 index bc80e22f..00000000 --- a/eosio.system-voteproducer-rc.md +++ /dev/null @@ -1,18 +0,0 @@ -# Ricardian Contract for *voteproducer* - -This Ricardian contract for the system command *voteproducer* is legally binding and can be used in the event of a dispute. - - -## VOTEPRODUCER (voter; array:producers) - -_Intent: cast a valid vote for up to 30 BP candidates_ - -As an authorized party I {{ signer }} wish to vote on behalf of {{ voter }} in favor of the block producer candidates {{ array:producers }} with a voting weight equal to all tokens currently owned by {{ voter }} and staked for CPU or bandwidth. - -If I am not the beneficial owner of these shares I stipulate I have proof that I’ve been authorized to vote these shares by their beneficial owner(s). - -I stipulate I have not and will not accept anything of value in exchange for these votes, on penalty of confiscation of these tokens, and other penalties. - -I acknowledge that using any system of automatic voting, re-voting, or vote refreshing, or allowing such a system to be used on my behalf or on behalf of another, is forbidden and doing so violates this contract. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-voters-rc.md b/eosio.system-voters-rc.md deleted file mode 100644 index b680658d..00000000 --- a/eosio.system-voters-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ voters }}` - -### Description - -This action will ... From 28e9469d473c7d10fb15cac388d014b2d775bc57 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 31 May 2018 17:21:50 -0400 Subject: [PATCH 0361/1048] Fixed multiple warnings --- delegate_bandwidth.cpp | 3 +-- voting.cpp | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 06f234b4..f837f954 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -169,7 +169,7 @@ namespace eosiosystem { tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); }); - _gstate.total_ram_bytes_reserved -= bytes; + _gstate.total_ram_bytes_reserved -= static_cast(bytes); // bytes > 0 is asserted above _gstate.total_ram_stake -= tokens_out.amount; //// this shouldn't happen, but just in case it does we should prevent it @@ -190,7 +190,6 @@ namespace eosiosystem { } void validate_b1_vesting( int64_t stake ) { - const int64_t seconds_per_year = 60*60*24*365; const int64_t base_time = 1527811200; /// 2018-06-01 const int64_t max_claimable = 100'000'000'0000ll; const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / (10*seconds_per_year) ); diff --git a/voting.cpp b/voting.cpp index a00e2054..5ee572d8 100644 --- a/voting.cpp +++ b/voting.cpp @@ -100,7 +100,7 @@ namespace eosiosystem { bytes packed_schedule = pack(producers); if( set_proposed_producers( packed_schedule.data(), packed_schedule.size() ) >= 0 ) { - _gstate.last_producer_schedule_size = top_producers.size(); + _gstate.last_producer_schedule_size = static_cast( top_producers.size() ); } } From b6ddf4cfbe106825054b41c6d2ae94e706114d68 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 31 May 2018 18:51:09 -0400 Subject: [PATCH 0362/1048] better name bidding assert messages and cleanup eosio.system tests --- eosio.system.cpp | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/eosio.system.cpp b/eosio.system.cpp index 838c3ff1..d6cc50c1 100644 --- a/eosio.system.cpp +++ b/eosio.system.cpp @@ -117,7 +117,7 @@ namespace eosiosystem { } else { eosio_assert( current->high_bid > 0, "this auction has already closed" ); eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); - eosio_assert( current->high_bidder != bidder, "account is already high bidder" ); + eosio_assert( current->high_bidder != bidder, "account is already highest bidder" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.names),N(active)}, { N(eosio.names), current->high_bidder, asset(current->high_bid), @@ -135,13 +135,10 @@ namespace eosiosystem { * Called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. * - * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 - * characters long without '.' until a future account auction process is implemented - * which prevents name squatting. + * Account names containing '.' symbols must have a suffix equal to the name of the creator. + * This allows users who buy a premium name (shorter than 12 characters with no dots) to be the only ones + * who can create accounts with the creator's name as a suffix. * - * 2. new accounts must stake a minimal number of tokens (as set in system parameters) - * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. */ void native::newaccount( account_name creator, account_name newact @@ -157,13 +154,13 @@ namespace eosiosystem { has_dot |= !(tmp & 0x1f); tmp >>= 5; } - auto suffix = eosio::name_suffix(newact); - if( has_dot ) { + if( has_dot ) { // or is less than 12 characters + auto suffix = eosio::name_suffix(newact); if( suffix == newact ) { name_bid_table bids(_self,_self); auto current = bids.find( newact ); eosio_assert( current != bids.end(), "no active bid for name" ); - eosio_assert( current->high_bidder == creator, "only high bidder can claim" ); + eosio_assert( current->high_bidder == creator, "only highest bidder can claim" ); eosio_assert( current->high_bid < 0, "auction for name is not closed yet" ); bids.erase( current ); } else { From b32a2141ffe622b316030677b4ac3c33658a6a23 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 31 May 2018 18:54:34 -0400 Subject: [PATCH 0363/1048] Fixed multiple warnings - 4 --- eosio.system.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.system.hpp b/eosio.system.hpp index eab52665..9a495e57 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -26,8 +26,8 @@ namespace eosiosystem { int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed uint64_t last_bid_time = 0; - auto primary_key()const { return newname; } - uint64_t by_high_bid()const { return -high_bid; } + auto primary_key()const { return newname; } + uint64_t by_high_bid()const { return static_cast(-high_bid); } }; typedef eosio::multi_index< N(namebids), name_bid, From 8f9f8e81a79f3062d5a9325ba8f8e526af55eb9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9sar=20Rodr=C3=ADguez?= Date: Fri, 1 Jun 2018 01:26:55 +0200 Subject: [PATCH 0364/1048] Revert "Remove Ricardian contracts" --- eosio.system-bidname-rc.md | 15 +++++++ eosio.system-buyram-rc.md | 16 +++++++ eosio.system-buyrambytes-rc.md | 16 +++++++ eosio.system-canceldelay-rc.md | 15 +++++++ eosio.system-claimrewards-rc.md | 15 +++++++ eosio.system-clause-constitution-rc.md | 58 ++++++++++++++++++++++++ eosio.system-delband-rc.md | 6 +++ eosio.system-delegatebw-rc.md | 20 +++++++++ eosio.system-deleteauth-rc.md | 15 +++++++ eosio.system-global-rc.md | 5 +++ eosio.system-linkauth-rc.md | 15 +++++++ eosio.system-newaccount-rc.md | 15 +++++++ eosio.system-onerror-rc.md | 15 +++++++ eosio.system-producers-rc.md | 5 +++ eosio.system-rammarket-rc.md | 5 +++ eosio.system-rc.md | 41 +++++++++++++++++ eosio.system-refund-rc.md | 16 +++++++ eosio.system-refunds-rc.md | 5 +++ eosio.system-regproducer-rc.md | 62 ++++++++++++++++++++++++++ eosio.system-regproxy-rc.md | 15 +++++++ eosio.system-reqauth-rc.md | 15 +++++++ eosio.system-rmvproducer-rc.md | 7 +++ eosio.system-sellram-rc.md | 15 +++++++ eosio.system-setabi-rc.md | 15 +++++++ eosio.system-setalimits-rc.md | 16 +++++++ eosio.system-setcode-rc.md | 12 +++++ eosio.system-setglimits-rc.md | 15 +++++++ eosio.system-setparams-rc.md | 5 +++ eosio.system-setpriv-rc.md | 15 +++++++ eosio.system-setprods-rc.md | 18 ++++++++ eosio.system-setram-rc.md | 8 ++++ eosio.system-undelegatebw-rc.md | 13 ++++++ eosio.system-unlinkauth-rc.md | 16 +++++++ eosio.system-unregprod-rc.md | 15 +++++++ eosio.system-updateauth-rc.md | 15 +++++++ eosio.system-userres-rc.md | 5 +++ eosio.system-voteproducer-rc.md | 18 ++++++++ eosio.system-voters-rc.md | 5 +++ 38 files changed, 603 insertions(+) create mode 100644 eosio.system-bidname-rc.md create mode 100644 eosio.system-buyram-rc.md create mode 100644 eosio.system-buyrambytes-rc.md create mode 100644 eosio.system-canceldelay-rc.md create mode 100644 eosio.system-claimrewards-rc.md create mode 100644 eosio.system-clause-constitution-rc.md create mode 100644 eosio.system-delband-rc.md create mode 100644 eosio.system-delegatebw-rc.md create mode 100644 eosio.system-deleteauth-rc.md create mode 100644 eosio.system-global-rc.md create mode 100644 eosio.system-linkauth-rc.md create mode 100644 eosio.system-newaccount-rc.md create mode 100644 eosio.system-onerror-rc.md create mode 100644 eosio.system-producers-rc.md create mode 100644 eosio.system-rammarket-rc.md create mode 100644 eosio.system-rc.md create mode 100644 eosio.system-refund-rc.md create mode 100644 eosio.system-refunds-rc.md create mode 100644 eosio.system-regproducer-rc.md create mode 100644 eosio.system-regproxy-rc.md create mode 100644 eosio.system-reqauth-rc.md create mode 100644 eosio.system-rmvproducer-rc.md create mode 100644 eosio.system-sellram-rc.md create mode 100644 eosio.system-setabi-rc.md create mode 100644 eosio.system-setalimits-rc.md create mode 100644 eosio.system-setcode-rc.md create mode 100644 eosio.system-setglimits-rc.md create mode 100644 eosio.system-setparams-rc.md create mode 100644 eosio.system-setpriv-rc.md create mode 100644 eosio.system-setprods-rc.md create mode 100644 eosio.system-setram-rc.md create mode 100644 eosio.system-undelegatebw-rc.md create mode 100644 eosio.system-unlinkauth-rc.md create mode 100644 eosio.system-unregprod-rc.md create mode 100644 eosio.system-updateauth-rc.md create mode 100644 eosio.system-userres-rc.md create mode 100644 eosio.system-voteproducer-rc.md create mode 100644 eosio.system-voters-rc.md diff --git a/eosio.system-bidname-rc.md b/eosio.system-bidname-rc.md new file mode 100644 index 00000000..e71f2fa4 --- /dev/null +++ b/eosio.system-bidname-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ bidname }}` + +### Description + +The `{{ bidname }}` action places a bid on a premium account name, in the knowledge that the high bid will purchase the name. + +### Inputs and Input Types + +The `{{ bidname }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ bidname }}` | `{{ bidderVar }}`
`{{ newnameVar }}`
`{{ bidVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | + +As an authorized party I {{ signer }} wish to bid on behalf of {{ bidderVar }} the amount of {{ bidVar }} toward purchase of the account name {{ newnameVar }}. diff --git a/eosio.system-buyram-rc.md b/eosio.system-buyram-rc.md new file mode 100644 index 00000000..98c775d7 --- /dev/null +++ b/eosio.system-buyram-rc.md @@ -0,0 +1,16 @@ +# Action - `{{ buyram }}` + +### Description + +This action will attempt to reserve about {{quant}} worth of RAM on behalf of {{receiver}}. + +{{buyer}} authorizes this contract to transfer {{quant}} to buy RAM based upon the current price as determined by the market maker algorithm. + +{{buyer}} accepts that a 0.5% fee will be charged on the amount spent and that the actual RAM received may be slightly less than expected due to the approximations necessary to enable this service. +{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. +{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. +{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. +{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. +{{buyer}} acknowledges that RAM is non-transferrable. +{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. + diff --git a/eosio.system-buyrambytes-rc.md b/eosio.system-buyrambytes-rc.md new file mode 100644 index 00000000..63a60e83 --- /dev/null +++ b/eosio.system-buyrambytes-rc.md @@ -0,0 +1,16 @@ +# Action - `{{ buyrambytes }}` + +### Description + +This action will attempt to reserve about {{bytes}} bytes of RAM on behalf of {{receiver}}. + +{{buyer}} authorizes this conrtact to transfer sufficient SYS tokens to buy the RAM based upon the current price as determined by the market maker algorithm. + +{{buyer}} accepts that a 0.5% fee will be charged on the SYS spent and that the actual RAM received may be slightly less than requested due to the approximations necessary to enable this service. +{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. +{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. +{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. +{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. +{{buyer}} acknowledges that RAM is non-transferrable. +{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. + diff --git a/eosio.system-canceldelay-rc.md b/eosio.system-canceldelay-rc.md new file mode 100644 index 00000000..8c7c0a38 --- /dev/null +++ b/eosio.system-canceldelay-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ canceldelay }}` + +### Description + +The `{{ canceldelay }}` action cancels an existing delayed transaction. + +### Inputs and Input Types + +The `{{ canceldelay }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ canceldelay }}` | `{{ canceling_authVar }}`
`{{ trx_idVar }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | + +As an authorized party I {{ signer }} wish to invoke the authority of {{ canceling_authVar }} to cancel the transaction with ID {{ trx_idVar }}. diff --git a/eosio.system-claimrewards-rc.md b/eosio.system-claimrewards-rc.md new file mode 100644 index 00000000..47362044 --- /dev/null +++ b/eosio.system-claimrewards-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ claimrewards }}` + +### Description + +The `{{ claimrewards }}` action allows a block producer (active or standby) to claim the system rewards due them for producing blocks and receiving votes. + +### Input and Input Type + +The `{{ claimrewards }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ claimrewards }}` | `{{ ownerVar }}` | `{{ account_name }}` | + +As an authorized party I {{ signer }} wish to have the rewards earned by {{ ownerVar }} deposited into their (my) account. diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md new file mode 100644 index 00000000..0f4057b0 --- /dev/null +++ b/eosio.system-clause-constitution-rc.md @@ -0,0 +1,58 @@ +This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. + +# Article I - No Initiation of Violence +Members shall not initiate violence or the threat of violence against another Member. + +# Article II - No Perjury +Members shall be liable for losses caused by false or misleading attestations and shall forfeit any profit gained thereby. + +# Article III - Rights +The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or via community referendum. This Constitution creates no positive rights for or between any Members. + +# Article IV - No Vote Buying +No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. + +# Article V - No Fiduciary +No Member nor SYS token holder shall have fiduciary responsibility to support the value of the SYS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of SYS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the SYS token supply. + +# Article VI - Restitution +Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. + +# Article VII - Open Source +Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via a free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. + +# Article VIII - Language +Multi-lingual contracts must specify one prevailing language in case of dispute and the author of any translation shall be liable for losses due to their false, misleading, or ambiguous attested translations. + +# Article IX - Dispute Resolution +All disputes arising out of or in connection with this Constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. + +# Article X - Choice of Law +Choice of law for disputes shall be, in order of precedence, this Constitution and the Maxims of Equity. + +# Article XI - Amending +This Constitution and its subordinate documents shall not be amended except by a vote of the token holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. + +# Article XII - Publishing +Members may only publish information to the Blockchain that is within their right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. + +# Article XIII - Informed Consent +All service providers who produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present to said other Members the full Ricardian contract terms of this Constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. + +# Article XIV - Severability +If any part of this Constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. + +# Article XV - Termination of Agreement +A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members according to the system contract provisions then in effect for such redistribution. + +# Article XVI - Developer Liability +Members agree to hold software developers harmless for unintentional mistakes made in the expression of contractual intent, whether or not said mistakes were due to actual or perceived negligence. + +# Article XVII - Consideration +All rights and obligations under this Constitution are mutual and reciprocal and of equally significant value and cost to all parties. + +# Article XVIII - Acceptance +A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI of said contract and said transaction is incorporated into the blockchain. + +# Article XIX - Counterparts +This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. diff --git a/eosio.system-delband-rc.md b/eosio.system-delband-rc.md new file mode 100644 index 00000000..98c44af1 --- /dev/null +++ b/eosio.system-delband-rc.md @@ -0,0 +1,6 @@ +# Action - `{{ delband }}` + +### Description + +This action will ... + diff --git a/eosio.system-delegatebw-rc.md b/eosio.system-delegatebw-rc.md new file mode 100644 index 00000000..5db46687 --- /dev/null +++ b/eosio.system-delegatebw-rc.md @@ -0,0 +1,20 @@ +# eosio.system delegatebw + +## delegatebw + (account_name-from; + account_name-to; + asset-stake_net_quantity; + asset-stake_cpu_quantity; + bool:transfer) + +_Intent: stake tokens for bandwidth and/or CPU and optionally transfer ownership_ + +As an authorized party I {{ signer }} wish to stake {{ asset-stake_cpu_quantity }} for CPU and {{ asset-stake_net_quantity }} for bandwidth from the liquid tokens of {{ account_name-from }} for the use of delegatee {{ account_name-to }}. + + {{if bool:transfer }} + +It is {{ bool:transfer }} that I wish these tokens to become immediately owned by the delegatee. + + {{/if}} + +As signer I stipulate that, if I am not the beneficial owner of these tokens, I have proof that I’ve been authorized to take this action by their beneficial owner(s). diff --git a/eosio.system-deleteauth-rc.md b/eosio.system-deleteauth-rc.md new file mode 100644 index 00000000..c447bbe3 --- /dev/null +++ b/eosio.system-deleteauth-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ deleteauth }}` + +### Description + +The `{{ deleteauth }}` action... + +### Inputs and Input Types + +The `{{ deleteauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ deleteauth }}` | `{{ accountVar }}`
`{{ permissionVar }}` | `{{ account_name }}`
`{{ permission_name }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-global-rc.md b/eosio.system-global-rc.md new file mode 100644 index 00000000..e2ac60d2 --- /dev/null +++ b/eosio.system-global-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ global }}` + +### Description + +This action will ... diff --git a/eosio.system-linkauth-rc.md b/eosio.system-linkauth-rc.md new file mode 100644 index 00000000..f3e4b726 --- /dev/null +++ b/eosio.system-linkauth-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ linkauth }}` + +### Description + +The `{{ linkauth }}` action... + +### Inputs and Input Types + +The `{{ linkauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ linkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}`
`{{ requirementVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-newaccount-rc.md b/eosio.system-newaccount-rc.md new file mode 100644 index 00000000..70e9b473 --- /dev/null +++ b/eosio.system-newaccount-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ newaccount }}` + +### Description + +The `{{ newaccount }}` action creates a new account. + +### Inputs and Input Types + +The `{{ newaccount }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ newaccount }}` | `{{ creatorVar }}`
`{{ nameVar }}`
`{{ ownerVar }}`
`{{ activeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | + +As an authorized party I {{ signer }} wish to exercise the authority of {{ creatorVar }} to create a new account on this system named {{ nameVar }} such that the new account's owner public key shall be {{ ownerVar }} and the active public key shall be {{ activeVar }}. diff --git a/eosio.system-onerror-rc.md b/eosio.system-onerror-rc.md new file mode 100644 index 00000000..925abf77 --- /dev/null +++ b/eosio.system-onerror-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ onerror }}` + +### Description + +The `{{ onerror }}` action... + +### Inputs and Input Types + +The `{{ onerror }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ onerror }}` | `{{ sender_idVar }}`
`{{ sent_trxVar }}` | `{{ uint128 }}`
`{{ bytes }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-producers-rc.md b/eosio.system-producers-rc.md new file mode 100644 index 00000000..fd0715d6 --- /dev/null +++ b/eosio.system-producers-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ producers }}` + +### Description + +This action will ... diff --git a/eosio.system-rammarket-rc.md b/eosio.system-rammarket-rc.md new file mode 100644 index 00000000..8f9566db --- /dev/null +++ b/eosio.system-rammarket-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ rammarket }}` + +### Description + +This action will ... diff --git a/eosio.system-rc.md b/eosio.system-rc.md new file mode 100644 index 00000000..8919cbae --- /dev/null +++ b/eosio.system-rc.md @@ -0,0 +1,41 @@ +# Smart Contract - `{{ eosio.system }}` + +This is an overview of the actions for the `{{ eosio.system }}` 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 `{{ eosio.system }}` contract... + +### Actions, Inputs and Input Types + +The table below contains the `actions`, `inputs` and `input types` for the `{{ eosio.system }}` contract. + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ newaccount }}` | `{{ creator }}`
`{{ name }}`
`{{ owner }}`
`{{ active }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | +| `{{ setcode }}` | `{{ account }}`
`{{ vmtype }}`
`{{ vmversion }}`
`{{ code }}` | `{{ account_name }}`
`{{ uint8 }}`
`{{ uint8 }}`
`{{ bytes }}` | +| `{{ setabi }}` | `{{ account }}`
`{{ abi }}` | `{{ account_name }}`
`{{ bytes }}` | +| `{{ updateauth }}` | `{{ account }}`
`{{ permission }}`
`{{ parent }}`
`{{ auth }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | +| `{{ deleteauth }}` | `{{ account }}`
`{{ permission }}` | `{{ account_name }}`
`{{ permission_name }}` | +| `{{ linkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}`
`{{ requirement }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | +| `{{ unlinkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | +| `{{ canceldelay }}` | `{{ canceling_auth }}`
`{{ trx_id }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | +| `{{ onerror }}` | `{{ sender_id }}`
`{{ sent_trx }}` | `{{ uint128 }}`
`{{ bytes }}` | +| `{{ buyrambytes }}` | `{{ payer }}`
`{{ receiver }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ uint32 }}` | +| `{{ buyram }}` | `{{ payer }}`
`{{ receiver }}`
`{{ quant }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | +| `{{ sellram }}` | `{{ account }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ uint64 }}` | +| `{{ delegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ stake_net_quantity }}`
`{{ stake_cpu_quantity }}`
`{{ transfer }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}`
`{{ bool }}` | +| `{{ undelegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ unstake_net_quantity }}`
`{{ unstake_cpu_quantity }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}` | +| `{{ refund }}` | `{{ owner }}` | `{{ account_name }}` | +| `{{ regproducer }}` | `{{ producer }}`
`{{ producer_key }}`
`{{ url }}`
`{{ location }}` | `{{ account_name }}`
`{{ public_key }}`
`{{ string }}`
`{{ uint16 }}` | +| `{{ setram }}` | `{{ max_ram_size }}` | `{{ uint64 }}` | +| `{{ bidname }}` | `{{ bidder }}`
`{{ newname }}`
`{{ bid }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | +| `{{ unregprod }}` | `{{ producer }}` | `{{ account_name }}` | +| `{{ regproxy }}` | `{{ proxy }}`
`{{ isproxy }}` | `{{ account_name }}`
`{{ bool }}` | +| `{{ voteproducer }}` | `{{ voter }}`
`{{ proxy }}`
`{{ producers }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ account_name[] }}` | +| `{{ claimrewards }}` | `{{ owner }}` | `{{ account_name }}` | +| `{{ setpriv }}` | `{{ account }}`
`{{ is_priv }}` | `{{ account_name }}`
`{{ int8 }}` | +| `{{ setalimits }}` | `{{ account }}`
`{{ ram_bytes }}`
`{{ net_weight }}`
`{{ cpu_weight }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | +| `{{ setglimits }}` | `{{ cpu_usec_per_period }}` | `{{ int64 }}` | +| `{{ setprods }}` | `{{ schedule }}` | `{{ producer_key[] }}` | +| `{{ reqauth }}` | `{{ from }}` | `{{ account_name }}` | \ No newline at end of file diff --git a/eosio.system-refund-rc.md b/eosio.system-refund-rc.md new file mode 100644 index 00000000..04dac54a --- /dev/null +++ b/eosio.system-refund-rc.md @@ -0,0 +1,16 @@ +# Action - `{{ refund }}` + +### Description + +The intent of the `{{ refund }}` action is to return previously unstaked tokens to an account after the unstaking period has elapsed. + +### Input and Input Type + +The `{{ refund }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ refund }}` | `{{ ownerVar }}` | `{{ account_name }}` | + + +As an authorized party I {{ signer }} wish to have the unstaked tokens of {{ ownerVar }} returned. diff --git a/eosio.system-refunds-rc.md b/eosio.system-refunds-rc.md new file mode 100644 index 00000000..af134800 --- /dev/null +++ b/eosio.system-refunds-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ refunds }}` + +### Description + +This action will ... diff --git a/eosio.system-regproducer-rc.md b/eosio.system-regproducer-rc.md new file mode 100644 index 00000000..9857bc90 --- /dev/null +++ b/eosio.system-regproducer-rc.md @@ -0,0 +1,62 @@ +# eosio.system regproducer + +I, {{producer}}, hereby nominate myself for consideration as an elected block producer. + +If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. + +If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. + +I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. + +{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: + +1. proposing an objectively valid block at the time appointed by the block scheduling algorithm +2. pre-confirming a block produced by another producer in the schedule when I find said block objectively valid +3. confirming a block for which {{producer}} has received 2/3+ pre-confirmation messages from other producers + +I hereby accept liability for any and all provable damages that result from my: + +1. signing two different block proposals with the same timestamp with {{producer_key} +2. signing two different block proposals with the same block number with {{producer_key} +3. signing any block proposal which builds off of an objectively invalid block +4. signing a pre-confirmation for an objectively invalid block +5. signing a confirmation for a block for which I do not possess pre-confirmation messages from 2/3+ other producers + +I hereby agree that double-signing for a timestamp or block number in concert with 2 or more other producers shall automatically be deemed malicious and subject to a fine equal to the past year of compensation received and imediate disqualification from being a producer, and other damages. An exception may be made if {{producer}} can demonstrate that the double-signing occured due to a bug in the reference software; the burden of proof is on {{producer}}. + +I hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. + +I hereby acknowledge that 2/3+ other elected producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among producers. + +If {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least 1 validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among producers, said method and reports to be made public. + +The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. + +I agree to process transactions on a FIFO best-effort basis and to honestly bill transactions for measured execution time. + +I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: + +1. the order in which transactions are included +2. the hash of the block that is produced + +I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my company who own more than 1%. + +I, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain. + +I, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract. + +I, {{producer}}, agree to set {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer. + +I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among producers. + +I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior producer. + +I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either CPU or network bandwidth metrics. + +I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by 2/3+ producers, as shown in the system parameters. + +## Constitution + +This agreement incorporates the current blockchain constitution: + +{{constitution}} diff --git a/eosio.system-regproxy-rc.md b/eosio.system-regproxy-rc.md new file mode 100644 index 00000000..8e96159b --- /dev/null +++ b/eosio.system-regproxy-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ regproxy }}` + +### Description + +The `{{ regproxy }}` action... + +### Inputs and Input Types + +The `{{ regproxy }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ regproxy }}` | `{{ proxyVar }}`
`{{ isproxyVar }}` | `{{ account_name }}`
`{{ bool }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-reqauth-rc.md b/eosio.system-reqauth-rc.md new file mode 100644 index 00000000..a95b8cb2 --- /dev/null +++ b/eosio.system-reqauth-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ reqauth }}` + +### Description + +The `{{ reqauth }}` action... + +### Input and Input Type + +The `{{ reqauth }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ reqauth }}` | `{{ fromVar }}` | `{{ account_name }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-rmvproducer-rc.md b/eosio.system-rmvproducer-rc.md new file mode 100644 index 00000000..7d8d3037 --- /dev/null +++ b/eosio.system-rmvproducer-rc.md @@ -0,0 +1,7 @@ +# Action - `{{ rmvproducer }}` + +### Description + +This action will remove a producer from the schedule. Should be called by other scheduled producers only sparingly and for the purpose of maintaining chain integrity and network stability. + +Producers who call this without appropriate justification, such as a mutually agreed SLA or other objective criteria, can be liable for lost revenue and lost reputation suffered by the target of this call. diff --git a/eosio.system-sellram-rc.md b/eosio.system-sellram-rc.md new file mode 100644 index 00000000..316c7dec --- /dev/null +++ b/eosio.system-sellram-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ sellram }}` + +### Description + +The `{{ sellram }}` action sells unused RAM for tokens. + +### Inputs and Input Types + +The `{{ sellram }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ sellram }}` | `{{ accountVar }}`
`{{ bytesVar }}` | `{{ account_name }}`
`{{ uint64 }}` | + +As an authorized party I {{ signer }} wish to sell {{ bytesVar }} of RAM from account {{ accountVar }}. diff --git a/eosio.system-setabi-rc.md b/eosio.system-setabi-rc.md new file mode 100644 index 00000000..21417856 --- /dev/null +++ b/eosio.system-setabi-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ setabi }}` + +### Description + +The intention of the `{{ setabi }}` action is to... + +### Inputs and Input Types + +The `{{ setabi }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setabi }}` | `{{ accountVar }}`
`{{ abiVar }}` | `{{ account_name }}`
`{{ bytes }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setalimits-rc.md b/eosio.system-setalimits-rc.md new file mode 100644 index 00000000..f03fbee1 --- /dev/null +++ b/eosio.system-setalimits-rc.md @@ -0,0 +1,16 @@ +# Action - `{{ setalimits }}` + +### Description + +The `{{ setalimits }}` action... + +### Inputs and Input Types + +The `{{ setalimits }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setalimits }}` | `{{ accountVar }}`
`{{ ram_bytesVar }}`
`{{ net_weightVar }}`
`{{ cpu_weightVar }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | + + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setcode-rc.md b/eosio.system-setcode-rc.md new file mode 100644 index 00000000..5a0d7217 --- /dev/null +++ b/eosio.system-setcode-rc.md @@ -0,0 +1,12 @@ +# Action - `{{ setcode }}` + +### Description + +This action updates the code that will run in response to delivered actions. It may be performed by the account upon which the code is being deployed. + +By deploying this code you certify that: + +1. the code is not malicious +2. you are authorized to perform the actions automated by the code +3. the code is consistant with the ABI deployed and intent of the contract +4. updates to the code are consistant with the prior code's intent diff --git a/eosio.system-setglimits-rc.md b/eosio.system-setglimits-rc.md new file mode 100644 index 00000000..0c168662 --- /dev/null +++ b/eosio.system-setglimits-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ setglimits }}` + +### Description + +The intention of the `{{ setglimits }}` action is to ... + +### Input and Input Type + +The `{{ setglimits }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setglimits }}` | `{{ cpu_usec_per_periodVar }}` | `{{ int64 }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setparams-rc.md b/eosio.system-setparams-rc.md new file mode 100644 index 00000000..48f09b94 --- /dev/null +++ b/eosio.system-setparams-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ setparams }}` + +### Description + +This action will set system parameters. diff --git a/eosio.system-setpriv-rc.md b/eosio.system-setpriv-rc.md new file mode 100644 index 00000000..0875c30d --- /dev/null +++ b/eosio.system-setpriv-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ setpriv }}` + +### Description + +The intention of the `{{ setpriv }}` action is to ... + +### Inputs and Input Types + +The `{{ setpriv }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setpriv }}` | `{{ accountVar }}`
`{{ is_privVar }}` | `{{ account_name }}`
`{{ int8 }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setprods-rc.md b/eosio.system-setprods-rc.md new file mode 100644 index 00000000..8b6ef8ca --- /dev/null +++ b/eosio.system-setprods-rc.md @@ -0,0 +1,18 @@ +# Action - `{{ setprods }}` + +### Description + +The `{{ setprods }}` action creates a new schedule of active producers, who will produce blocks in the order given. + +### Input and Input Type + +The `{{ setprods }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ setprods }}` | `{{ scheduleVar }}` | `{{ producer_key[] }}` | + +THIS IS A SYSTEM COMMAND NOT AVAILABLE FOR DIRECT ACCESS BY USERS. + + +As an authorized party I {{ signer }} wish to set the rotation of producers to be {{ scheduleVar }}. diff --git a/eosio.system-setram-rc.md b/eosio.system-setram-rc.md new file mode 100644 index 00000000..e9a3ce66 --- /dev/null +++ b/eosio.system-setram-rc.md @@ -0,0 +1,8 @@ +# Action - `{{ setram }}` + +### Description + +This action sets the total RAM that may be allocated for use by accounts. It may only increase. + +Only the controller of this contract may update the RAM availablity. If the owner is a multi-sig collective, the +parties to the multi-sig each certify that off-the-shelf machines exist capable of supporting the available RAM. diff --git a/eosio.system-undelegatebw-rc.md b/eosio.system-undelegatebw-rc.md new file mode 100644 index 00000000..e7a1fcf3 --- /dev/null +++ b/eosio.system-undelegatebw-rc.md @@ -0,0 +1,13 @@ +# eosio.system undelegatebw + +## undelegatebw + (account_name-from; + account_name-to; + asset-unstake_net_quantity; + asset-unstake_cpu_quantity) + +_Intent: unstake tokens from bandwidth_ + +As an authorized party I {{ signer }} wish to unstake {{ asset-unstake_cpu_quantity }} from CPU and {{ asset-unstake_net_quantity }} from bandwidth from the tokens owned by {{ account_name-from }} previously delegated for the use of delegatee {{ account_name-to }}. + +If I as signer am not the beneficial owner of these tokens I stipulate I have proof that I’ve been authorized to take this action by their beneficial owner(s). diff --git a/eosio.system-unlinkauth-rc.md b/eosio.system-unlinkauth-rc.md new file mode 100644 index 00000000..b93928f8 --- /dev/null +++ b/eosio.system-unlinkauth-rc.md @@ -0,0 +1,16 @@ +# Action - `{{ unlinkauth }}` + +### Description + +The `{{ unlinkauth }}` action... + +### Inputs and Input Types + +The `{{ unlinkauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ unlinkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | + + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-unregprod-rc.md b/eosio.system-unregprod-rc.md new file mode 100644 index 00000000..de3dad69 --- /dev/null +++ b/eosio.system-unregprod-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ unregprod }}` + +### Description + +The `{{ unregprod }}` action unregisters a previously registered block producer candidate. + +### Input and Input Type + +The `{{ unregprod }}` action requires the following `input` and `input type`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ unregprod }}` | `{{ producerVar }}` | `{{ account_name }}` | + +As an authorized party I {{ signer }} wish to unregister the block producer candidate {{ producerVar }}, rendering that candidate no longer able to receive votes. diff --git a/eosio.system-updateauth-rc.md b/eosio.system-updateauth-rc.md new file mode 100644 index 00000000..0e614458 --- /dev/null +++ b/eosio.system-updateauth-rc.md @@ -0,0 +1,15 @@ +# Action - `{{ updateauth }}` + +### Description + +The `{{ updateauth }}` action... + +### Inputs and Input Types + +The `{{ updateauth }}` action requires the following `inputs` and `input types`: + +| Action | Input | Input Type | +|:--|:--|:--| +| `{{ updateauth }}` | `{{ accountVar }}`
`{{ permissionVar }}`
`{{ parentVar }}`
`{{ authVar }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | + +As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-userres-rc.md b/eosio.system-userres-rc.md new file mode 100644 index 00000000..1c99be09 --- /dev/null +++ b/eosio.system-userres-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ userres }}` + +### Description + +This action will (something) user resources __... diff --git a/eosio.system-voteproducer-rc.md b/eosio.system-voteproducer-rc.md new file mode 100644 index 00000000..bc80e22f --- /dev/null +++ b/eosio.system-voteproducer-rc.md @@ -0,0 +1,18 @@ +# Ricardian Contract for *voteproducer* + +This Ricardian contract for the system command *voteproducer* is legally binding and can be used in the event of a dispute. + + +## VOTEPRODUCER (voter; array:producers) + +_Intent: cast a valid vote for up to 30 BP candidates_ + +As an authorized party I {{ signer }} wish to vote on behalf of {{ voter }} in favor of the block producer candidates {{ array:producers }} with a voting weight equal to all tokens currently owned by {{ voter }} and staked for CPU or bandwidth. + +If I am not the beneficial owner of these shares I stipulate I have proof that I’ve been authorized to vote these shares by their beneficial owner(s). + +I stipulate I have not and will not accept anything of value in exchange for these votes, on penalty of confiscation of these tokens, and other penalties. + +I acknowledge that using any system of automatic voting, re-voting, or vote refreshing, or allowing such a system to be used on my behalf or on behalf of another, is forbidden and doing so violates this contract. + +All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-voters-rc.md b/eosio.system-voters-rc.md new file mode 100644 index 00000000..b680658d --- /dev/null +++ b/eosio.system-voters-rc.md @@ -0,0 +1,5 @@ +# Action - `{{ voters }}` + +### Description + +This action will ... From dafb9e4a42a51c2935d14471f1ed68c81d6664ca Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 1 Jun 2018 13:30:51 -0400 Subject: [PATCH 0365/1048] Changed large_offset_validator to use template parameter for type casting --- delegate_bandwidth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index f837f954..14b355f7 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -122,8 +122,8 @@ namespace eosiosystem { int64_t bytes_out; - auto itr = _rammarket.find(S(4,RAMCORE)); - _rammarket.modify( itr, 0, [&]( auto& es ) { + const auto& market = _rammarket.get(S(4,RAMCORE), "ram market does not exist"); + _rammarket.modify( market, 0, [&]( auto& es ) { bytes_out = es.convert( quant_after_fee, S(0,RAM) ).amount; }); From d01de67e859e5fc5a6d3ead3432a85142c41c62f Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 1 Jun 2018 13:39:00 -0400 Subject: [PATCH 0366/1048] Remove change --- delegate_bandwidth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 14b355f7..f837f954 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -122,8 +122,8 @@ namespace eosiosystem { int64_t bytes_out; - const auto& market = _rammarket.get(S(4,RAMCORE), "ram market does not exist"); - _rammarket.modify( market, 0, [&]( auto& es ) { + auto itr = _rammarket.find(S(4,RAMCORE)); + _rammarket.modify( itr, 0, [&]( auto& es ) { bytes_out = es.convert( quant_after_fee, S(0,RAM) ).amount; }); From d15050f6ce8aa660a829d5558b3a54f3ef0b2313 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 1 Jun 2018 13:43:19 -0400 Subject: [PATCH 0367/1048] Changed to better error message for buyram --- delegate_bandwidth.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index f837f954..14b355f7 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -122,8 +122,8 @@ namespace eosiosystem { int64_t bytes_out; - auto itr = _rammarket.find(S(4,RAMCORE)); - _rammarket.modify( itr, 0, [&]( auto& es ) { + const auto& market = _rammarket.get(S(4,RAMCORE), "ram market does not exist"); + _rammarket.modify( market, 0, [&]( auto& es ) { bytes_out = es.convert( quant_after_fee, S(0,RAM) ).amount; }); From c494d4423af6a8f4b336483d488b40be808cdba0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 1 Jun 2018 14:51:49 -0400 Subject: [PATCH 0368/1048] Fix issue #3740 --- eosio.system.abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system.abi b/eosio.system.abi index 0165bdb5..de5389ac 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -249,7 +249,7 @@ {"name":"max_ram_size", "type":"uint64"}, {"name":"total_ram_bytes_reserved", "type":"uint64"}, {"name":"total_ram_stake", "type":"int64"}, - {"name":"last_producer_schedule_update", "type":"time_point_sec"}, + {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, {"name":"last_pervote_bucket_fill", "type":"uint64"}, {"name":"pervote_bucket", "type":"int64"}, {"name":"perblock_bucket", "type":"int64"}, From bcb58601f0e1d4d431267dac1cbc1634dd777a7f Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 1 Jun 2018 17:08:12 -0400 Subject: [PATCH 0369/1048] Rename constitution.md to contracts/eosio.system/eosio.system-clause-constitution-rc.md --- eosio.system-clause-constitution-rc.md | 58 ++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 eosio.system-clause-constitution-rc.md diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md new file mode 100644 index 00000000..89e4644c --- /dev/null +++ b/eosio.system-clause-constitution-rc.md @@ -0,0 +1,58 @@ +This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. + +# Article I - No Initiation of Violence +Members shall not initiate violence or the threat of violence against another Member. + +# Article II - No Perjury +Members shall be liable for losses caused by false or misleading attestations and shall forfeit any profit gained thereby. + +# Article III - Rights +The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or via community referendum. This Constitution creates no positive rights for or between any Members. + +# Article IV - No Vote Buying +No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. + +# Article V - No Fiduciary +No Member nor SYS token holder shall have fiduciary responsibility to support the value of the SYS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of SYS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the SYS token supply. + +# Article VI - Restitution +Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. + +# Article VII - Open Source +Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via a free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. + +# Article VIII - Language +Multi-lingual contracts must specify one prevailing language in case of dispute and the author of any translation shall be liable for losses due to their false, misleading, or ambiguous attested translations. + +# Article IX - Dispute Resolution +All disputes arising out of or in connection with this Constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. + +# Article X - Choice of Law +Choice of law for disputes shall be, in order of precedence, this Constitution and the Maxims of Equity. + +# Article XI - Amending +This Constitution and its subordinate documents shall not be amended except by a vote of the token holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. + +# Article XII - Publishing +Members may only publish information to the Blockchain that is within their right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. + +# Article XIII - Informed Consent +All service providers who produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present to said other Members the full Ricardian contract terms of this Constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. + +# Article XIV - Severability +If any part of this Constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. + +# Article XV - Termination of Agreement +A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members according to the system contract provisions then in effect for such redistribution. + +# Article XVI - Developer Liability +Members agree to hold software developers harmless for unintentional mistakes made in the expression of contractual intent, whether or not said mistakes were due to actual or perceived negligence. + +# Article XVII - Consideration +All rights and obligations under this Constitution are mutual and reciprocal and of equally significant value and cost to all parties. + +# Article XVIII - Acceptance +A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI of said contract and said transaction is incorporated into the blockchain. + +# Article XIX - Counterparts +This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. From ad69bb6312b1ef8e23a74095f32d23b100757e22 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 1 Jun 2018 17:31:24 -0400 Subject: [PATCH 0370/1048] Update eosio.system-clause-constitution-rc.md --- eosio.system-clause-constitution-rc.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md index 89e4644c..a54f06c5 100644 --- a/eosio.system-clause-constitution-rc.md +++ b/eosio.system-clause-constitution-rc.md @@ -1,7 +1,7 @@ This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. # Article I - No Initiation of Violence -Members shall not initiate violence or the threat of violence against another Member. +Members shall not initiate violence or the threat of violence against another Member. Lawful prosecution of crimes with the goal of preserving life, liberty and property does not constitute initiation of violence. # Article II - No Perjury Members shall be liable for losses caused by false or misleading attestations and shall forfeit any profit gained thereby. @@ -13,12 +13,12 @@ The Members grant the right of contract and of private property to each other, t No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. # Article V - No Fiduciary -No Member nor SYS token holder shall have fiduciary responsibility to support the value of the SYS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of SYS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the SYS token supply. +No Member nor EOS token holder shall have fiduciary responsibility to support the value of the EOS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of EOS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the EOS token supply. # Article VI - Restitution Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. -# Article VII - Open Source +# Article VII - Open Source Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via a free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. # Article VIII - Language @@ -56,3 +56,6 @@ A contract is deemed accepted when a member signs a transaction which incorporat # Article XIX - Counterparts This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. + +# Article XX - Interim Constitution +This constitution is interim and is intended to remain in effect until a permanent constitution is written and ratified in a referendum. From de521db524b2f1d108b9086a2201eb88a4e836ed Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 1 Jun 2018 18:02:05 -0400 Subject: [PATCH 0371/1048] Create eosio.system-setram-rc.md --- eosio.system-setram-rc.md | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 eosio.system-setram-rc.md diff --git a/eosio.system-setram-rc.md b/eosio.system-setram-rc.md new file mode 100644 index 00000000..e9a3ce66 --- /dev/null +++ b/eosio.system-setram-rc.md @@ -0,0 +1,8 @@ +# Action - `{{ setram }}` + +### Description + +This action sets the total RAM that may be allocated for use by accounts. It may only increase. + +Only the controller of this contract may update the RAM availablity. If the owner is a multi-sig collective, the +parties to the multi-sig each certify that off-the-shelf machines exist capable of supporting the available RAM. From f5c0b76a5b730fe925169f3a9043a270962dafe6 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 1 Jun 2018 18:13:11 -0400 Subject: [PATCH 0372/1048] Rename contracts/eosio.system/eosio.system-clause-constitution-rc.md to governance/constitution.md --- eosio.system-clause-constitution-rc.md | 61 -------------------------- 1 file changed, 61 deletions(-) delete mode 100644 eosio.system-clause-constitution-rc.md diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md deleted file mode 100644 index a54f06c5..00000000 --- a/eosio.system-clause-constitution-rc.md +++ /dev/null @@ -1,61 +0,0 @@ -This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. - -# Article I - No Initiation of Violence -Members shall not initiate violence or the threat of violence against another Member. Lawful prosecution of crimes with the goal of preserving life, liberty and property does not constitute initiation of violence. - -# Article II - No Perjury -Members shall be liable for losses caused by false or misleading attestations and shall forfeit any profit gained thereby. - -# Article III - Rights -The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or via community referendum. This Constitution creates no positive rights for or between any Members. - -# Article IV - No Vote Buying -No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. - -# Article V - No Fiduciary -No Member nor EOS token holder shall have fiduciary responsibility to support the value of the EOS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of EOS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the EOS token supply. - -# Article VI - Restitution -Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. - -# Article VII - Open Source -Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via a free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. - -# Article VIII - Language -Multi-lingual contracts must specify one prevailing language in case of dispute and the author of any translation shall be liable for losses due to their false, misleading, or ambiguous attested translations. - -# Article IX - Dispute Resolution -All disputes arising out of or in connection with this Constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. - -# Article X - Choice of Law -Choice of law for disputes shall be, in order of precedence, this Constitution and the Maxims of Equity. - -# Article XI - Amending -This Constitution and its subordinate documents shall not be amended except by a vote of the token holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. - -# Article XII - Publishing -Members may only publish information to the Blockchain that is within their right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. - -# Article XIII - Informed Consent -All service providers who produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present to said other Members the full Ricardian contract terms of this Constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. - -# Article XIV - Severability -If any part of this Constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. - -# Article XV - Termination of Agreement -A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members according to the system contract provisions then in effect for such redistribution. - -# Article XVI - Developer Liability -Members agree to hold software developers harmless for unintentional mistakes made in the expression of contractual intent, whether or not said mistakes were due to actual or perceived negligence. - -# Article XVII - Consideration -All rights and obligations under this Constitution are mutual and reciprocal and of equally significant value and cost to all parties. - -# Article XVIII - Acceptance -A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI of said contract and said transaction is incorporated into the blockchain. - -# Article XIX - Counterparts -This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. - -# Article XX - Interim Constitution -This constitution is interim and is intended to remain in effect until a permanent constitution is written and ratified in a referendum. From 23ab92b668c6f05007074bf53e3ea2b36a0d90e4 Mon Sep 17 00:00:00 2001 From: Denis Date: Fri, 1 Jun 2018 21:07:36 -0400 Subject: [PATCH 0373/1048] Community Launch Update --- eosio.system-regproducer-rc.md | 41 +++++++++++++--------------------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/eosio.system-regproducer-rc.md b/eosio.system-regproducer-rc.md index 9857bc90..5412f8fc 100644 --- a/eosio.system-regproducer-rc.md +++ b/eosio.system-regproducer-rc.md @@ -1,26 +1,24 @@ # eosio.system regproducer -I, {{producer}}, hereby nominate myself for consideration as an elected block producer. +I, {{producer}}, hereby nominate myself for consideration as an elected block producer. -If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. +If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. -If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. +If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. {{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: - -1. proposing an objectively valid block at the time appointed by the block scheduling algorithm -2. pre-confirming a block produced by another producer in the schedule when I find said block objectively valid -3. confirming a block for which {{producer}} has received 2/3+ pre-confirmation messages from other producers +proposing an objectively valid block at the time appointed by the block scheduling algorithm +pre-confirming a block produced by another producer in the schedule when I find said block objectively valid +confirming a block for which {{producer}} has received 2/3+ pre-confirmation messages from other producers I hereby accept liability for any and all provable damages that result from my: - -1. signing two different block proposals with the same timestamp with {{producer_key} -2. signing two different block proposals with the same block number with {{producer_key} -3. signing any block proposal which builds off of an objectively invalid block -4. signing a pre-confirmation for an objectively invalid block -5. signing a confirmation for a block for which I do not possess pre-confirmation messages from 2/3+ other producers +signing two different block proposals with the same timestamp with {{producer_key} +signing two different block proposals with the same block number with {{producer_key} +signing any block proposal which builds off of an objectively invalid block +signing a pre-confirmation for an objectively invalid block +signing a confirmation for a block for which I do not possess pre-confirmation messages from 2/3+ other producers I hereby agree that double-signing for a timestamp or block number in concert with 2 or more other producers shall automatically be deemed malicious and subject to a fine equal to the past year of compensation received and imediate disqualification from being a producer, and other damages. An exception may be made if {{producer}} can demonstrate that the double-signing occured due to a bug in the reference software; the burden of proof is on {{producer}}. @@ -32,14 +30,13 @@ If {{producer}} qualifies for and chooses to collect compensation due to votes r The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. -I agree to process transactions on a FIFO best-effort basis and to honestly bill transactions for measured execution time. +I agree to process transactions on a FIFO best-effort basis and to honestly bill transactions for measured execution time. I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: +the order in which transactions are included +the hash of the block that is produced -1. the order in which transactions are included -2. the hash of the block that is produced - -I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my company who own more than 1%. +I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my company who own more than 10% and all direct shareholders. I, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain. @@ -51,12 +48,6 @@ I, {{producer}}, agree to maintain time synchronization within 10 ms of global a I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior producer. -I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either CPU or network bandwidth metrics. +I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either CPU or network bandwidth metrics. I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by 2/3+ producers, as shown in the system parameters. - -## Constitution - -This agreement incorporates the current blockchain constitution: - -{{constitution}} From 54a8bc694710b3d494b440820cbb3adc9761dca4 Mon Sep 17 00:00:00 2001 From: Kevin Heifner Date: Sat, 2 Jun 2018 13:44:04 -0500 Subject: [PATCH 0374/1048] Revert "FIX Pass string with whitespaces to cleos in cleos.sh" --- eosio.system-bidname-rc.md | 15 ------- eosio.system-buyram-rc.md | 16 ------- eosio.system-buyrambytes-rc.md | 16 ------- eosio.system-canceldelay-rc.md | 15 ------- eosio.system-claimrewards-rc.md | 15 ------- eosio.system-clause-constitution-rc.md | 58 -------------------------- eosio.system-delband-rc.md | 6 --- eosio.system-delegatebw-rc.md | 20 --------- eosio.system-deleteauth-rc.md | 15 ------- eosio.system-global-rc.md | 5 --- eosio.system-linkauth-rc.md | 15 ------- eosio.system-newaccount-rc.md | 15 ------- eosio.system-onerror-rc.md | 15 ------- eosio.system-producers-rc.md | 5 --- eosio.system-rammarket-rc.md | 5 --- eosio.system-rc.md | 41 ------------------ eosio.system-refund-rc.md | 16 ------- eosio.system-refunds-rc.md | 5 --- eosio.system-regproducer-rc.md | 53 ----------------------- eosio.system-regproxy-rc.md | 15 ------- eosio.system-reqauth-rc.md | 15 ------- eosio.system-rmvproducer-rc.md | 7 ---- eosio.system-sellram-rc.md | 15 ------- eosio.system-setabi-rc.md | 15 ------- eosio.system-setalimits-rc.md | 16 ------- eosio.system-setcode-rc.md | 12 ------ eosio.system-setglimits-rc.md | 15 ------- eosio.system-setparams-rc.md | 5 --- eosio.system-setpriv-rc.md | 15 ------- eosio.system-setprods-rc.md | 18 -------- eosio.system-setram-rc.md | 8 ---- eosio.system-undelegatebw-rc.md | 13 ------ eosio.system-unlinkauth-rc.md | 16 ------- eosio.system-unregprod-rc.md | 15 ------- eosio.system-updateauth-rc.md | 15 ------- eosio.system-userres-rc.md | 5 --- eosio.system-voteproducer-rc.md | 18 -------- eosio.system-voters-rc.md | 5 --- 38 files changed, 594 deletions(-) delete mode 100644 eosio.system-bidname-rc.md delete mode 100644 eosio.system-buyram-rc.md delete mode 100644 eosio.system-buyrambytes-rc.md delete mode 100644 eosio.system-canceldelay-rc.md delete mode 100644 eosio.system-claimrewards-rc.md delete mode 100644 eosio.system-clause-constitution-rc.md delete mode 100644 eosio.system-delband-rc.md delete mode 100644 eosio.system-delegatebw-rc.md delete mode 100644 eosio.system-deleteauth-rc.md delete mode 100644 eosio.system-global-rc.md delete mode 100644 eosio.system-linkauth-rc.md delete mode 100644 eosio.system-newaccount-rc.md delete mode 100644 eosio.system-onerror-rc.md delete mode 100644 eosio.system-producers-rc.md delete mode 100644 eosio.system-rammarket-rc.md delete mode 100644 eosio.system-rc.md delete mode 100644 eosio.system-refund-rc.md delete mode 100644 eosio.system-refunds-rc.md delete mode 100644 eosio.system-regproducer-rc.md delete mode 100644 eosio.system-regproxy-rc.md delete mode 100644 eosio.system-reqauth-rc.md delete mode 100644 eosio.system-rmvproducer-rc.md delete mode 100644 eosio.system-sellram-rc.md delete mode 100644 eosio.system-setabi-rc.md delete mode 100644 eosio.system-setalimits-rc.md delete mode 100644 eosio.system-setcode-rc.md delete mode 100644 eosio.system-setglimits-rc.md delete mode 100644 eosio.system-setparams-rc.md delete mode 100644 eosio.system-setpriv-rc.md delete mode 100644 eosio.system-setprods-rc.md delete mode 100644 eosio.system-setram-rc.md delete mode 100644 eosio.system-undelegatebw-rc.md delete mode 100644 eosio.system-unlinkauth-rc.md delete mode 100644 eosio.system-unregprod-rc.md delete mode 100644 eosio.system-updateauth-rc.md delete mode 100644 eosio.system-userres-rc.md delete mode 100644 eosio.system-voteproducer-rc.md delete mode 100644 eosio.system-voters-rc.md diff --git a/eosio.system-bidname-rc.md b/eosio.system-bidname-rc.md deleted file mode 100644 index e71f2fa4..00000000 --- a/eosio.system-bidname-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ bidname }}` - -### Description - -The `{{ bidname }}` action places a bid on a premium account name, in the knowledge that the high bid will purchase the name. - -### Inputs and Input Types - -The `{{ bidname }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ bidname }}` | `{{ bidderVar }}`
`{{ newnameVar }}`
`{{ bidVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | - -As an authorized party I {{ signer }} wish to bid on behalf of {{ bidderVar }} the amount of {{ bidVar }} toward purchase of the account name {{ newnameVar }}. diff --git a/eosio.system-buyram-rc.md b/eosio.system-buyram-rc.md deleted file mode 100644 index 98c775d7..00000000 --- a/eosio.system-buyram-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ buyram }}` - -### Description - -This action will attempt to reserve about {{quant}} worth of RAM on behalf of {{receiver}}. - -{{buyer}} authorizes this contract to transfer {{quant}} to buy RAM based upon the current price as determined by the market maker algorithm. - -{{buyer}} accepts that a 0.5% fee will be charged on the amount spent and that the actual RAM received may be slightly less than expected due to the approximations necessary to enable this service. -{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. -{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. -{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. -{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. -{{buyer}} acknowledges that RAM is non-transferrable. -{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. - diff --git a/eosio.system-buyrambytes-rc.md b/eosio.system-buyrambytes-rc.md deleted file mode 100644 index 63a60e83..00000000 --- a/eosio.system-buyrambytes-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ buyrambytes }}` - -### Description - -This action will attempt to reserve about {{bytes}} bytes of RAM on behalf of {{receiver}}. - -{{buyer}} authorizes this conrtact to transfer sufficient SYS tokens to buy the RAM based upon the current price as determined by the market maker algorithm. - -{{buyer}} accepts that a 0.5% fee will be charged on the SYS spent and that the actual RAM received may be slightly less than requested due to the approximations necessary to enable this service. -{{buyer}} accepts that a 0.5% fee will be charged if and when they sell the RAM received. -{{buyer}} accepts that rounding errors resulting from limits of computational precision may result in less RAM being allocated. -{{buyer}} acknowledges that the supply of RAM may be increased at any time up to the limits of off-the-shelf computer equipment and that this may result in RAM selling for less than purchase price. -{{buyer}} acknowledges that the price of RAM may increase or decrease over time according to supply and demand. -{{buyer}} acknowledges that RAM is non-transferrable. -{{buyer}} acknowledges RAM currently in use by their account cannot be sold until it is freed and that freeing RAM may be subject to terms of other contracts. - diff --git a/eosio.system-canceldelay-rc.md b/eosio.system-canceldelay-rc.md deleted file mode 100644 index 8c7c0a38..00000000 --- a/eosio.system-canceldelay-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ canceldelay }}` - -### Description - -The `{{ canceldelay }}` action cancels an existing delayed transaction. - -### Inputs and Input Types - -The `{{ canceldelay }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ canceldelay }}` | `{{ canceling_authVar }}`
`{{ trx_idVar }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | - -As an authorized party I {{ signer }} wish to invoke the authority of {{ canceling_authVar }} to cancel the transaction with ID {{ trx_idVar }}. diff --git a/eosio.system-claimrewards-rc.md b/eosio.system-claimrewards-rc.md deleted file mode 100644 index 47362044..00000000 --- a/eosio.system-claimrewards-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ claimrewards }}` - -### Description - -The `{{ claimrewards }}` action allows a block producer (active or standby) to claim the system rewards due them for producing blocks and receiving votes. - -### Input and Input Type - -The `{{ claimrewards }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ claimrewards }}` | `{{ ownerVar }}` | `{{ account_name }}` | - -As an authorized party I {{ signer }} wish to have the rewards earned by {{ ownerVar }} deposited into their (my) account. diff --git a/eosio.system-clause-constitution-rc.md b/eosio.system-clause-constitution-rc.md deleted file mode 100644 index 0f4057b0..00000000 --- a/eosio.system-clause-constitution-rc.md +++ /dev/null @@ -1,58 +0,0 @@ -This Constitution is a multi-party contract entered into by the Members by virtue of their use of this blockchain. - -# Article I - No Initiation of Violence -Members shall not initiate violence or the threat of violence against another Member. - -# Article II - No Perjury -Members shall be liable for losses caused by false or misleading attestations and shall forfeit any profit gained thereby. - -# Article III - Rights -The Members grant the right of contract and of private property to each other, therefore no property shall change hands except with the consent of the owner, by a valid Arbitrator’s order, or via community referendum. This Constitution creates no positive rights for or between any Members. - -# Article IV - No Vote Buying -No Member shall offer nor accept anything of value in exchange for a vote of any type, nor shall any Member unduly influence the vote of another. - -# Article V - No Fiduciary -No Member nor SYS token holder shall have fiduciary responsibility to support the value of the SYS token. The Members do not authorize anyone to hold assets, borrow, nor contract on behalf of SYS token holders collectively. This blockchain has no owners, managers or fiduciaries; therefore, no Member shall have beneficial interest in more than 10% of the SYS token supply. - -# Article VI - Restitution -Each Member agrees that penalties for breach of contract may include, but are not limited to, fines, loss of account, and other restitution. - -# Article VII - Open Source -Each Member who makes available a smart contract on this blockchain shall be a Developer. Each Developer shall offer their smart contracts via a free and open source license, and each smart contract shall be documented with a Ricardian Contract stating the intent of all parties and naming the Arbitration Forum that will resolve disputes arising from that contract. - -# Article VIII - Language -Multi-lingual contracts must specify one prevailing language in case of dispute and the author of any translation shall be liable for losses due to their false, misleading, or ambiguous attested translations. - -# Article IX - Dispute Resolution -All disputes arising out of or in connection with this Constitution shall be finally settled under the Rules of Arbitration of the International Chamber of Commerce by one or more arbitrators appointed in accordance with the said Rules. - -# Article X - Choice of Law -Choice of law for disputes shall be, in order of precedence, this Constitution and the Maxims of Equity. - -# Article XI - Amending -This Constitution and its subordinate documents shall not be amended except by a vote of the token holders with no less than 15% vote participation among tokens and no fewer than 10% more Yes than No votes, sustained for 30 continuous days within a 120 day period. - -# Article XII - Publishing -Members may only publish information to the Blockchain that is within their right to publish. Furthermore, Members voluntarily consent for all Members to permanently and irrevocably retain a copy, analyze, and distribute all broadcast transactions and derivative information. - -# Article XIII - Informed Consent -All service providers who produce tools to facilitate the construction and signing of transactions on behalf of other Members shall present to said other Members the full Ricardian contract terms of this Constitution and other referenced contracts. Service providers shall be liable for losses resulting from failure to disclose the full Ricardian contract terms to users. - -# Article XIV - Severability -If any part of this Constitution is declared unenforceable or invalid, the remainder will continue to be valid and enforceable. - -# Article XV - Termination of Agreement -A Member is automatically released from all revocable obligations under this Constitution 3 years after the last transaction signed by that Member is incorporated into the blockchain. After 3 years of inactivity an account may be put up for auction and the proceeds distributed to all Members according to the system contract provisions then in effect for such redistribution. - -# Article XVI - Developer Liability -Members agree to hold software developers harmless for unintentional mistakes made in the expression of contractual intent, whether or not said mistakes were due to actual or perceived negligence. - -# Article XVII - Consideration -All rights and obligations under this Constitution are mutual and reciprocal and of equally significant value and cost to all parties. - -# Article XVIII - Acceptance -A contract is deemed accepted when a member signs a transaction which incorporates a TAPOS proof of a block whose implied state incorporates an ABI of said contract and said transaction is incorporated into the blockchain. - -# Article XIX - Counterparts -This Constitution may be executed in any number of counterparts, each of which when executed and delivered shall constitute a duplicate original, but all counterparts together shall constitute a single agreement. diff --git a/eosio.system-delband-rc.md b/eosio.system-delband-rc.md deleted file mode 100644 index 98c44af1..00000000 --- a/eosio.system-delband-rc.md +++ /dev/null @@ -1,6 +0,0 @@ -# Action - `{{ delband }}` - -### Description - -This action will ... - diff --git a/eosio.system-delegatebw-rc.md b/eosio.system-delegatebw-rc.md deleted file mode 100644 index 5db46687..00000000 --- a/eosio.system-delegatebw-rc.md +++ /dev/null @@ -1,20 +0,0 @@ -# eosio.system delegatebw - -## delegatebw - (account_name-from; - account_name-to; - asset-stake_net_quantity; - asset-stake_cpu_quantity; - bool:transfer) - -_Intent: stake tokens for bandwidth and/or CPU and optionally transfer ownership_ - -As an authorized party I {{ signer }} wish to stake {{ asset-stake_cpu_quantity }} for CPU and {{ asset-stake_net_quantity }} for bandwidth from the liquid tokens of {{ account_name-from }} for the use of delegatee {{ account_name-to }}. - - {{if bool:transfer }} - -It is {{ bool:transfer }} that I wish these tokens to become immediately owned by the delegatee. - - {{/if}} - -As signer I stipulate that, if I am not the beneficial owner of these tokens, I have proof that I’ve been authorized to take this action by their beneficial owner(s). diff --git a/eosio.system-deleteauth-rc.md b/eosio.system-deleteauth-rc.md deleted file mode 100644 index c447bbe3..00000000 --- a/eosio.system-deleteauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ deleteauth }}` - -### Description - -The `{{ deleteauth }}` action... - -### Inputs and Input Types - -The `{{ deleteauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ deleteauth }}` | `{{ accountVar }}`
`{{ permissionVar }}` | `{{ account_name }}`
`{{ permission_name }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-global-rc.md b/eosio.system-global-rc.md deleted file mode 100644 index e2ac60d2..00000000 --- a/eosio.system-global-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ global }}` - -### Description - -This action will ... diff --git a/eosio.system-linkauth-rc.md b/eosio.system-linkauth-rc.md deleted file mode 100644 index f3e4b726..00000000 --- a/eosio.system-linkauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ linkauth }}` - -### Description - -The `{{ linkauth }}` action... - -### Inputs and Input Types - -The `{{ linkauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ linkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}`
`{{ requirementVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-newaccount-rc.md b/eosio.system-newaccount-rc.md deleted file mode 100644 index 70e9b473..00000000 --- a/eosio.system-newaccount-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ newaccount }}` - -### Description - -The `{{ newaccount }}` action creates a new account. - -### Inputs and Input Types - -The `{{ newaccount }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ newaccount }}` | `{{ creatorVar }}`
`{{ nameVar }}`
`{{ ownerVar }}`
`{{ activeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | - -As an authorized party I {{ signer }} wish to exercise the authority of {{ creatorVar }} to create a new account on this system named {{ nameVar }} such that the new account's owner public key shall be {{ ownerVar }} and the active public key shall be {{ activeVar }}. diff --git a/eosio.system-onerror-rc.md b/eosio.system-onerror-rc.md deleted file mode 100644 index 925abf77..00000000 --- a/eosio.system-onerror-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ onerror }}` - -### Description - -The `{{ onerror }}` action... - -### Inputs and Input Types - -The `{{ onerror }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ onerror }}` | `{{ sender_idVar }}`
`{{ sent_trxVar }}` | `{{ uint128 }}`
`{{ bytes }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-producers-rc.md b/eosio.system-producers-rc.md deleted file mode 100644 index fd0715d6..00000000 --- a/eosio.system-producers-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ producers }}` - -### Description - -This action will ... diff --git a/eosio.system-rammarket-rc.md b/eosio.system-rammarket-rc.md deleted file mode 100644 index 8f9566db..00000000 --- a/eosio.system-rammarket-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ rammarket }}` - -### Description - -This action will ... diff --git a/eosio.system-rc.md b/eosio.system-rc.md deleted file mode 100644 index 8919cbae..00000000 --- a/eosio.system-rc.md +++ /dev/null @@ -1,41 +0,0 @@ -# Smart Contract - `{{ eosio.system }}` - -This is an overview of the actions for the `{{ eosio.system }}` 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 `{{ eosio.system }}` contract... - -### Actions, Inputs and Input Types - -The table below contains the `actions`, `inputs` and `input types` for the `{{ eosio.system }}` contract. - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ newaccount }}` | `{{ creator }}`
`{{ name }}`
`{{ owner }}`
`{{ active }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ authority }}`
`{{ authority }}` | -| `{{ setcode }}` | `{{ account }}`
`{{ vmtype }}`
`{{ vmversion }}`
`{{ code }}` | `{{ account_name }}`
`{{ uint8 }}`
`{{ uint8 }}`
`{{ bytes }}` | -| `{{ setabi }}` | `{{ account }}`
`{{ abi }}` | `{{ account_name }}`
`{{ bytes }}` | -| `{{ updateauth }}` | `{{ account }}`
`{{ permission }}`
`{{ parent }}`
`{{ auth }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | -| `{{ deleteauth }}` | `{{ account }}`
`{{ permission }}` | `{{ account_name }}`
`{{ permission_name }}` | -| `{{ linkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}`
`{{ requirement }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}`
`{{ permission_name }}` | -| `{{ unlinkauth }}` | `{{ account }}`
`{{ code }}`
`{{ type }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | -| `{{ canceldelay }}` | `{{ canceling_auth }}`
`{{ trx_id }}` | `{{ permission_level }}`
`{{ transaction_id_type }}` | -| `{{ onerror }}` | `{{ sender_id }}`
`{{ sent_trx }}` | `{{ uint128 }}`
`{{ bytes }}` | -| `{{ buyrambytes }}` | `{{ payer }}`
`{{ receiver }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ uint32 }}` | -| `{{ buyram }}` | `{{ payer }}`
`{{ receiver }}`
`{{ quant }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | -| `{{ sellram }}` | `{{ account }}`
`{{ bytes }}` | `{{ account_name }}`
`{{ uint64 }}` | -| `{{ delegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ stake_net_quantity }}`
`{{ stake_cpu_quantity }}`
`{{ transfer }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}`
`{{ bool }}` | -| `{{ undelegatebw }}` | `{{ from }}`
`{{ receiver }}`
`{{ unstake_net_quantity }}`
`{{ unstake_cpu_quantity }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}`
`{{ asset }}` | -| `{{ refund }}` | `{{ owner }}` | `{{ account_name }}` | -| `{{ regproducer }}` | `{{ producer }}`
`{{ producer_key }}`
`{{ url }}`
`{{ location }}` | `{{ account_name }}`
`{{ public_key }}`
`{{ string }}`
`{{ uint16 }}` | -| `{{ setram }}` | `{{ max_ram_size }}` | `{{ uint64 }}` | -| `{{ bidname }}` | `{{ bidder }}`
`{{ newname }}`
`{{ bid }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ asset }}` | -| `{{ unregprod }}` | `{{ producer }}` | `{{ account_name }}` | -| `{{ regproxy }}` | `{{ proxy }}`
`{{ isproxy }}` | `{{ account_name }}`
`{{ bool }}` | -| `{{ voteproducer }}` | `{{ voter }}`
`{{ proxy }}`
`{{ producers }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ account_name[] }}` | -| `{{ claimrewards }}` | `{{ owner }}` | `{{ account_name }}` | -| `{{ setpriv }}` | `{{ account }}`
`{{ is_priv }}` | `{{ account_name }}`
`{{ int8 }}` | -| `{{ setalimits }}` | `{{ account }}`
`{{ ram_bytes }}`
`{{ net_weight }}`
`{{ cpu_weight }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | -| `{{ setglimits }}` | `{{ cpu_usec_per_period }}` | `{{ int64 }}` | -| `{{ setprods }}` | `{{ schedule }}` | `{{ producer_key[] }}` | -| `{{ reqauth }}` | `{{ from }}` | `{{ account_name }}` | \ No newline at end of file diff --git a/eosio.system-refund-rc.md b/eosio.system-refund-rc.md deleted file mode 100644 index 04dac54a..00000000 --- a/eosio.system-refund-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ refund }}` - -### Description - -The intent of the `{{ refund }}` action is to return previously unstaked tokens to an account after the unstaking period has elapsed. - -### Input and Input Type - -The `{{ refund }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ refund }}` | `{{ ownerVar }}` | `{{ account_name }}` | - - -As an authorized party I {{ signer }} wish to have the unstaked tokens of {{ ownerVar }} returned. diff --git a/eosio.system-refunds-rc.md b/eosio.system-refunds-rc.md deleted file mode 100644 index af134800..00000000 --- a/eosio.system-refunds-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ refunds }}` - -### Description - -This action will ... diff --git a/eosio.system-regproducer-rc.md b/eosio.system-regproducer-rc.md deleted file mode 100644 index 5412f8fc..00000000 --- a/eosio.system-regproducer-rc.md +++ /dev/null @@ -1,53 +0,0 @@ -# eosio.system regproducer - -I, {{producer}}, hereby nominate myself for consideration as an elected block producer. - -If {{producer}} is selected to produce blocks by the eosio contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. - -If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. - -I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. - -{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: -proposing an objectively valid block at the time appointed by the block scheduling algorithm -pre-confirming a block produced by another producer in the schedule when I find said block objectively valid -confirming a block for which {{producer}} has received 2/3+ pre-confirmation messages from other producers - -I hereby accept liability for any and all provable damages that result from my: -signing two different block proposals with the same timestamp with {{producer_key} -signing two different block proposals with the same block number with {{producer_key} -signing any block proposal which builds off of an objectively invalid block -signing a pre-confirmation for an objectively invalid block -signing a confirmation for a block for which I do not possess pre-confirmation messages from 2/3+ other producers - -I hereby agree that double-signing for a timestamp or block number in concert with 2 or more other producers shall automatically be deemed malicious and subject to a fine equal to the past year of compensation received and imediate disqualification from being a producer, and other damages. An exception may be made if {{producer}} can demonstrate that the double-signing occured due to a bug in the reference software; the burden of proof is on {{producer}}. - -I hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. - -I hereby acknowledge that 2/3+ other elected producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among producers. - -If {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least 1 validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among producers, said method and reports to be made public. - -The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. - -I agree to process transactions on a FIFO best-effort basis and to honestly bill transactions for measured execution time. - -I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: -the order in which transactions are included -the hash of the block that is produced - -I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my company who own more than 10% and all direct shareholders. - -I, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain. - -I, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract. - -I, {{producer}}, agree to set {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer. - -I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among producers. - -I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior producer. - -I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either CPU or network bandwidth metrics. - -I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by 2/3+ producers, as shown in the system parameters. diff --git a/eosio.system-regproxy-rc.md b/eosio.system-regproxy-rc.md deleted file mode 100644 index 8e96159b..00000000 --- a/eosio.system-regproxy-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ regproxy }}` - -### Description - -The `{{ regproxy }}` action... - -### Inputs and Input Types - -The `{{ regproxy }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ regproxy }}` | `{{ proxyVar }}`
`{{ isproxyVar }}` | `{{ account_name }}`
`{{ bool }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-reqauth-rc.md b/eosio.system-reqauth-rc.md deleted file mode 100644 index a95b8cb2..00000000 --- a/eosio.system-reqauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ reqauth }}` - -### Description - -The `{{ reqauth }}` action... - -### Input and Input Type - -The `{{ reqauth }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ reqauth }}` | `{{ fromVar }}` | `{{ account_name }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-rmvproducer-rc.md b/eosio.system-rmvproducer-rc.md deleted file mode 100644 index 7d8d3037..00000000 --- a/eosio.system-rmvproducer-rc.md +++ /dev/null @@ -1,7 +0,0 @@ -# Action - `{{ rmvproducer }}` - -### Description - -This action will remove a producer from the schedule. Should be called by other scheduled producers only sparingly and for the purpose of maintaining chain integrity and network stability. - -Producers who call this without appropriate justification, such as a mutually agreed SLA or other objective criteria, can be liable for lost revenue and lost reputation suffered by the target of this call. diff --git a/eosio.system-sellram-rc.md b/eosio.system-sellram-rc.md deleted file mode 100644 index 316c7dec..00000000 --- a/eosio.system-sellram-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ sellram }}` - -### Description - -The `{{ sellram }}` action sells unused RAM for tokens. - -### Inputs and Input Types - -The `{{ sellram }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ sellram }}` | `{{ accountVar }}`
`{{ bytesVar }}` | `{{ account_name }}`
`{{ uint64 }}` | - -As an authorized party I {{ signer }} wish to sell {{ bytesVar }} of RAM from account {{ accountVar }}. diff --git a/eosio.system-setabi-rc.md b/eosio.system-setabi-rc.md deleted file mode 100644 index 21417856..00000000 --- a/eosio.system-setabi-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ setabi }}` - -### Description - -The intention of the `{{ setabi }}` action is to... - -### Inputs and Input Types - -The `{{ setabi }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setabi }}` | `{{ accountVar }}`
`{{ abiVar }}` | `{{ account_name }}`
`{{ bytes }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setalimits-rc.md b/eosio.system-setalimits-rc.md deleted file mode 100644 index f03fbee1..00000000 --- a/eosio.system-setalimits-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ setalimits }}` - -### Description - -The `{{ setalimits }}` action... - -### Inputs and Input Types - -The `{{ setalimits }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setalimits }}` | `{{ accountVar }}`
`{{ ram_bytesVar }}`
`{{ net_weightVar }}`
`{{ cpu_weightVar }}` | `{{ account_name }}`
`{{ int64 }}`
`{{ int64 }}`
`{{ int64 }}` | - - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setcode-rc.md b/eosio.system-setcode-rc.md deleted file mode 100644 index 5a0d7217..00000000 --- a/eosio.system-setcode-rc.md +++ /dev/null @@ -1,12 +0,0 @@ -# Action - `{{ setcode }}` - -### Description - -This action updates the code that will run in response to delivered actions. It may be performed by the account upon which the code is being deployed. - -By deploying this code you certify that: - -1. the code is not malicious -2. you are authorized to perform the actions automated by the code -3. the code is consistant with the ABI deployed and intent of the contract -4. updates to the code are consistant with the prior code's intent diff --git a/eosio.system-setglimits-rc.md b/eosio.system-setglimits-rc.md deleted file mode 100644 index 0c168662..00000000 --- a/eosio.system-setglimits-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ setglimits }}` - -### Description - -The intention of the `{{ setglimits }}` action is to ... - -### Input and Input Type - -The `{{ setglimits }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setglimits }}` | `{{ cpu_usec_per_periodVar }}` | `{{ int64 }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setparams-rc.md b/eosio.system-setparams-rc.md deleted file mode 100644 index 48f09b94..00000000 --- a/eosio.system-setparams-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ setparams }}` - -### Description - -This action will set system parameters. diff --git a/eosio.system-setpriv-rc.md b/eosio.system-setpriv-rc.md deleted file mode 100644 index 0875c30d..00000000 --- a/eosio.system-setpriv-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ setpriv }}` - -### Description - -The intention of the `{{ setpriv }}` action is to ... - -### Inputs and Input Types - -The `{{ setpriv }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setpriv }}` | `{{ accountVar }}`
`{{ is_privVar }}` | `{{ account_name }}`
`{{ int8 }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-setprods-rc.md b/eosio.system-setprods-rc.md deleted file mode 100644 index 8b6ef8ca..00000000 --- a/eosio.system-setprods-rc.md +++ /dev/null @@ -1,18 +0,0 @@ -# Action - `{{ setprods }}` - -### Description - -The `{{ setprods }}` action creates a new schedule of active producers, who will produce blocks in the order given. - -### Input and Input Type - -The `{{ setprods }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ setprods }}` | `{{ scheduleVar }}` | `{{ producer_key[] }}` | - -THIS IS A SYSTEM COMMAND NOT AVAILABLE FOR DIRECT ACCESS BY USERS. - - -As an authorized party I {{ signer }} wish to set the rotation of producers to be {{ scheduleVar }}. diff --git a/eosio.system-setram-rc.md b/eosio.system-setram-rc.md deleted file mode 100644 index e9a3ce66..00000000 --- a/eosio.system-setram-rc.md +++ /dev/null @@ -1,8 +0,0 @@ -# Action - `{{ setram }}` - -### Description - -This action sets the total RAM that may be allocated for use by accounts. It may only increase. - -Only the controller of this contract may update the RAM availablity. If the owner is a multi-sig collective, the -parties to the multi-sig each certify that off-the-shelf machines exist capable of supporting the available RAM. diff --git a/eosio.system-undelegatebw-rc.md b/eosio.system-undelegatebw-rc.md deleted file mode 100644 index e7a1fcf3..00000000 --- a/eosio.system-undelegatebw-rc.md +++ /dev/null @@ -1,13 +0,0 @@ -# eosio.system undelegatebw - -## undelegatebw - (account_name-from; - account_name-to; - asset-unstake_net_quantity; - asset-unstake_cpu_quantity) - -_Intent: unstake tokens from bandwidth_ - -As an authorized party I {{ signer }} wish to unstake {{ asset-unstake_cpu_quantity }} from CPU and {{ asset-unstake_net_quantity }} from bandwidth from the tokens owned by {{ account_name-from }} previously delegated for the use of delegatee {{ account_name-to }}. - -If I as signer am not the beneficial owner of these tokens I stipulate I have proof that I’ve been authorized to take this action by their beneficial owner(s). diff --git a/eosio.system-unlinkauth-rc.md b/eosio.system-unlinkauth-rc.md deleted file mode 100644 index b93928f8..00000000 --- a/eosio.system-unlinkauth-rc.md +++ /dev/null @@ -1,16 +0,0 @@ -# Action - `{{ unlinkauth }}` - -### Description - -The `{{ unlinkauth }}` action... - -### Inputs and Input Types - -The `{{ unlinkauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ unlinkauth }}` | `{{ accountVar }}`
`{{ codeVar }}`
`{{ typeVar }}` | `{{ account_name }}`
`{{ account_name }}`
`{{ action_name }}` | - - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-unregprod-rc.md b/eosio.system-unregprod-rc.md deleted file mode 100644 index de3dad69..00000000 --- a/eosio.system-unregprod-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ unregprod }}` - -### Description - -The `{{ unregprod }}` action unregisters a previously registered block producer candidate. - -### Input and Input Type - -The `{{ unregprod }}` action requires the following `input` and `input type`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ unregprod }}` | `{{ producerVar }}` | `{{ account_name }}` | - -As an authorized party I {{ signer }} wish to unregister the block producer candidate {{ producerVar }}, rendering that candidate no longer able to receive votes. diff --git a/eosio.system-updateauth-rc.md b/eosio.system-updateauth-rc.md deleted file mode 100644 index 0e614458..00000000 --- a/eosio.system-updateauth-rc.md +++ /dev/null @@ -1,15 +0,0 @@ -# Action - `{{ updateauth }}` - -### Description - -The `{{ updateauth }}` action... - -### Inputs and Input Types - -The `{{ updateauth }}` action requires the following `inputs` and `input types`: - -| Action | Input | Input Type | -|:--|:--|:--| -| `{{ updateauth }}` | `{{ accountVar }}`
`{{ permissionVar }}`
`{{ parentVar }}`
`{{ authVar }}` | `{{ account_name }}`
`{{ permission_name }}`
`{{ permission_name }}`
`{{ authority }}` | - -As an authorized party I {{ signer }} wish to UNKNOWN diff --git a/eosio.system-userres-rc.md b/eosio.system-userres-rc.md deleted file mode 100644 index 1c99be09..00000000 --- a/eosio.system-userres-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ userres }}` - -### Description - -This action will (something) user resources __... diff --git a/eosio.system-voteproducer-rc.md b/eosio.system-voteproducer-rc.md deleted file mode 100644 index bc80e22f..00000000 --- a/eosio.system-voteproducer-rc.md +++ /dev/null @@ -1,18 +0,0 @@ -# Ricardian Contract for *voteproducer* - -This Ricardian contract for the system command *voteproducer* is legally binding and can be used in the event of a dispute. - - -## VOTEPRODUCER (voter; array:producers) - -_Intent: cast a valid vote for up to 30 BP candidates_ - -As an authorized party I {{ signer }} wish to vote on behalf of {{ voter }} in favor of the block producer candidates {{ array:producers }} with a voting weight equal to all tokens currently owned by {{ voter }} and staked for CPU or bandwidth. - -If I am not the beneficial owner of these shares I stipulate I have proof that I’ve been authorized to vote these shares by their beneficial owner(s). - -I stipulate I have not and will not accept anything of value in exchange for these votes, on penalty of confiscation of these tokens, and other penalties. - -I acknowledge that using any system of automatic voting, re-voting, or vote refreshing, or allowing such a system to be used on my behalf or on behalf of another, is forbidden and doing so violates this contract. - -All disputes arising from this contract shall be resolved in the EOS Core Arbitration Forum. diff --git a/eosio.system-voters-rc.md b/eosio.system-voters-rc.md deleted file mode 100644 index b680658d..00000000 --- a/eosio.system-voters-rc.md +++ /dev/null @@ -1,5 +0,0 @@ -# Action - `{{ voters }}` - -### Description - -This action will ... From b9aa7d4f331649877bcd0bc0e1401a748b5ddb4b Mon Sep 17 00:00:00 2001 From: Kayan Date: Mon, 4 Jun 2018 15:33:14 +0800 Subject: [PATCH 0375/1048] add cleos command for name bidding --- eosio.system.abi | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/eosio.system.abi b/eosio.system.abi index de5389ac..ab1059d7 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -398,6 +398,15 @@ {"name":"base", "type":"connector"}, {"name":"quote", "type":"connector"} ] + }, { + "name": "namebid_info", + "base": "", + "fields": [ + {"name":"newname", "type":"account_name"}, + {"name":"high_bidder", "type":"account_name"}, + {"name":"high_bid", "type":"int64"}, + {"name":"last_bid_time", "type":"uint64"} + ] } ], "actions": [{ @@ -559,6 +568,12 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["uint64"] + },{ + "name": "namebids", + "type": "namebid_info", + "index_type": "i64", + "key_names" : ["newname"], + "key_types" : ["account_name"] } ], "ricardian_clauses": [], From fabff5d121cdc40193fb22d61a48558256738234 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 4 Jun 2018 10:14:47 -0400 Subject: [PATCH 0376/1048] system contract bugfix: regproducer should always modify parameters (removed check if key is different) #3783 --- voting.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/voting.cpp b/voting.cpp index 1ca89775..31bf7059 100644 --- a/voting.cpp +++ b/voting.cpp @@ -42,14 +42,12 @@ namespace eosiosystem { auto prod = _producers.find( producer ); if ( prod != _producers.end() ) { - if( producer_key != prod->producer_key ) { - _producers.modify( prod, producer, [&]( producer_info& info ){ - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; - }); - } + _producers.modify( prod, producer, [&]( producer_info& info ){ + info.producer_key = producer_key; + info.is_active = true; + info.url = url; + info.location = location; + }); } else { _producers.emplace( producer, [&]( producer_info& info ){ info.owner = producer; From 26a002717f1ce5c508ab4ea674dfdcd4d43f7173 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 7 Jun 2018 18:02:50 -0400 Subject: [PATCH 0377/1048] more clear message when unstaking is forbidden due to 15% rule #3931 --- delegate_bandwidth.cpp | 2 +- producer_pay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 14b355f7..4f33344e 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -371,7 +371,7 @@ namespace eosiosystem { eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "not enough has been staked for users to unstake" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% participated in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); } // undelegatebw diff --git a/producer_pay.cpp b/producer_pay.cpp index f9d9bedb..b4e170c8 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -71,7 +71,7 @@ namespace eosiosystem { const auto& prod = _producers.get( owner ); eosio_assert( prod.active(), "producer does not have an active key" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "not enough has been staked for producers to claim rewards" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% participated in voting)" ); auto ct = current_time(); From 4f6f195b689529466baaf547a199ade3b0b0d7d9 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 7 Jun 2018 18:03:58 -0400 Subject: [PATCH 0378/1048] more clear message when unstaking is forbidden due to 15% rule #3931 --- delegate_bandwidth.cpp | 2 +- producer_pay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 4f33344e..633ab17a 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -371,7 +371,7 @@ namespace eosiosystem { eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% participated in voting)" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% of token volume participated in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); } // undelegatebw diff --git a/producer_pay.cpp b/producer_pay.cpp index b4e170c8..d6ba6e71 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -71,7 +71,7 @@ namespace eosiosystem { const auto& prod = _producers.get( owner ); eosio_assert( prod.active(), "producer does not have an active key" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% participated in voting)" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% of token volume participated in voting)" ); auto ct = current_time(); From 48e8aa2c6734285e5e49b11a54e37cce8f54c213 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 7 Jun 2018 18:08:58 -0400 Subject: [PATCH 0379/1048] more clear message when unstaking is forbidden due to 15% rule #3931 --- delegate_bandwidth.cpp | 2 +- producer_pay.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 633ab17a..8648d340 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -371,7 +371,7 @@ namespace eosiosystem { eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% of token volume participated in voting)" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activated yet (less than 15% of all tokens have participated in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); } // undelegatebw diff --git a/producer_pay.cpp b/producer_pay.cpp index d6ba6e71..1da31339 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -71,7 +71,7 @@ namespace eosiosystem { const auto& prod = _producers.get( owner ); eosio_assert( prod.active(), "producer does not have an active key" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activate yet (less than 15% of token volume participated in voting)" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activated yet (less than 15% of all tokens participated in voting)" ); auto ct = current_time(); From 064d506a78af1de6cefb81cc58497c4f336e44c2 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 7 Jun 2018 18:09:39 -0400 Subject: [PATCH 0380/1048] more clear message when unstaking is forbidden due to 15% rule #3931 --- producer_pay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/producer_pay.cpp b/producer_pay.cpp index 1da31339..1c118f83 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -71,7 +71,7 @@ namespace eosiosystem { const auto& prod = _producers.get( owner ); eosio_assert( prod.active(), "producer does not have an active key" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activated yet (less than 15% of all tokens participated in voting)" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activated yet (less than 15% of all tokens have participated in voting)" ); auto ct = current_time(); From 0b67a52e3749128ec91fcbc38cc41769359669fb Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 7 Jun 2018 19:42:21 -0400 Subject: [PATCH 0381/1048] fix 15% percent error message and associated tests #3932 --- delegate_bandwidth.cpp | 3 ++- producer_pay.cpp | 13 +++++++------ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index 8648d340..c235d5c8 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -371,7 +371,8 @@ namespace eosiosystem { eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activated yet (less than 15% of all tokens have participated in voting)" ); + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, + "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); } // undelegatebw diff --git a/producer_pay.cpp b/producer_pay.cpp index 1c118f83..1d0af68d 100644 --- a/producer_pay.cpp +++ b/producer_pay.cpp @@ -41,11 +41,11 @@ namespace eosiosystem { p.unpaid_blocks++; }); } - + /// only update block producers once every minute, block_timestamp is in half seconds if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) { update_elected_producers( timestamp ); - + if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { name_bid_table bids(_self,_self); auto idx = bids.get_index(); @@ -70,8 +70,9 @@ namespace eosiosystem { const auto& prod = _producers.get( owner ); eosio_assert( prod.active(), "producer does not have an active key" ); - - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "the chain has not been activated yet (less than 15% of all tokens have participated in voting)" ); + + eosio_assert( _gstate.total_activated_stake >= min_activated_stake, + "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" ); auto ct = current_time(); @@ -111,7 +112,7 @@ namespace eosiosystem { producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; } int64_t producer_per_vote_pay = 0; - if( _gstate.total_producer_vote_weight > 0 ) { + if( _gstate.total_producer_vote_weight > 0 ) { producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); } if( producer_per_vote_pay < min_pervote_daily_pay ) { @@ -125,7 +126,7 @@ namespace eosiosystem { p.last_claim_time = ct; p.unpaid_blocks = 0; }); - + if( producer_per_block_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.bpay),N(active)}, { N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } ); From 8234e267ea9809fc16c24a8eb8af3b4059f2fc7d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 14 Jun 2018 15:22:18 -0400 Subject: [PATCH 0382/1048] Additional check in name bidding --- voting.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/voting.cpp b/voting.cpp index 31bf7059..166f1707 100644 --- a/voting.cpp +++ b/voting.cpp @@ -152,7 +152,7 @@ namespace eosiosystem { */ if( voter->last_vote_weight <= 0.0 ) { _gstate.total_activated_stake += voter->staked; - if( _gstate.total_activated_stake >= min_activated_stake ) { + if( _gstate.total_activated_stake >= min_activated_stake && _gstate.thresh_activated_stake_time == 0 ) { _gstate.thresh_activated_stake_time = current_time(); } } From ecf66ced502d513fd6f009ddc9b0ef02646c99b0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 14 Jun 2018 17:51:50 -0400 Subject: [PATCH 0383/1048] Fix issue #4051 --- delegate_bandwidth.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index c235d5c8..dbe0e991 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -108,7 +108,7 @@ namespace eosiosystem { eosio_assert( quant.amount > 0, "must purchase a positive amount" ); auto fee = quant; - fee.amount /= 200; /// .5% fee + fee.amount = ( fee.amount + 199 ) / 200; /// .5% fee auto quant_after_fee = quant; quant_after_fee.amount -= fee.amount; From fa18978cb47873739c76a7a1f0df95cfd5d64bb9 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 15 Jun 2018 10:40:36 -0400 Subject: [PATCH 0384/1048] remove unused (but reserved) fields in eosiosystem::voter_info from ABI; add clarifying comments to system_contract::buyram fee logic --- delegate_bandwidth.cpp | 7 ++++++- eosio.system.abi | 5 +---- eosio.system.hpp | 8 ++++---- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/delegate_bandwidth.cpp b/delegate_bandwidth.cpp index dbe0e991..712a6cc9 100644 --- a/delegate_bandwidth.cpp +++ b/delegate_bandwidth.cpp @@ -108,9 +108,14 @@ namespace eosiosystem { eosio_assert( quant.amount > 0, "must purchase a positive amount" ); auto fee = quant; - fee.amount = ( fee.amount + 199 ) / 200; /// .5% fee + fee.amount = ( fee.amount + 199 ) / 200; /// .5% fee (round up) + // fee.amount cannot be 0 since that is only possible if quant.amount is 0 which is not allowed by the assert above. + // If quant.amount == 1, then fee.amount == 1, + // otherwise if quant.amount > 1, then 0 < fee.amount < quant.amount. auto quant_after_fee = quant; quant_after_fee.amount -= fee.amount; + // quant_after_fee.amount should be > 0 if quant.amount > 1. + // If quant.amount == 1, then quant_after_fee.amount == 0 and the next inline transfer will fail causing the buyram action to fail. INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } ); diff --git a/eosio.system.abi b/eosio.system.abi index ab1059d7..87937c78 100644 --- a/eosio.system.abi +++ b/eosio.system.abi @@ -319,10 +319,7 @@ {"name":"staked", "type":"int64"}, {"name":"last_vote_weight", "type":"float64"}, {"name":"proxied_vote_weight", "type":"float64"}, - {"name":"is_proxy", "type":"bool"}, - {"name":"deferred_trx_id", "type":"uint32"}, - {"name":"last_unstake_time", "type":"time_point_sec"}, - {"name":"unstaking", "type":"asset"} + {"name":"is_proxy", "type":"bool"} ] },{ "name": "claimrewards", diff --git a/eosio.system.hpp b/eosio.system.hpp index 9a495e57..a33238a1 100644 --- a/eosio.system.hpp +++ b/eosio.system.hpp @@ -102,14 +102,14 @@ namespace eosiosystem { bool is_proxy = 0; /// whether the voter is a proxy for others - uint32_t deferred_trx_id = 0; /// the ID of the 3-day delay deferred transaction - time last_unstake_time = 0; /// the time when the deferred_trx_id was sent - eosio::asset unstaking; /// the total unstaking (pending 3 day delay) + uint32_t reserved1 = 0; + time reserved2 = 0; + eosio::asset reserved3; uint64_t primary_key()const { return owner; } // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(deferred_trx_id)(last_unstake_time)(unstaking) ) + EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(reserved1)(reserved2)(reserved3) ) }; typedef eosio::multi_index< N(voters), voter_info> voters_table; From 51b568daf2b47bd089b060fb61ad2e280940ab0a Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 19 Jun 2018 09:30:49 -0400 Subject: [PATCH 0385/1048] Initial commit --- .gitignore | 32 ++++++++++++++++++++++++++++++++ LICENSE | 21 +++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..259148fa --- /dev/null +++ b/.gitignore @@ -0,0 +1,32 @@ +# Prerequisites +*.d + +# Compiled Object files +*.slo +*.lo +*.o +*.obj + +# Precompiled Headers +*.gch +*.pch + +# Compiled Dynamic libraries +*.so +*.dylib +*.dll + +# Fortran module files +*.mod +*.smod + +# Compiled Static libraries +*.lai +*.la +*.a +*.lib + +# Executables +*.exe +*.out +*.app diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..bf31410b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 EOSIO + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. From 4bb00e7adea09b99c2e2fe70ddc9921bdb689338 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 22 Jun 2018 15:20:38 -0400 Subject: [PATCH 0386/1048] Added build script and dependencies --- .gitmodules | 6 +++++ CMakeLists.txt | 24 ----------------- eosio.system.abi => abi/eosio.system.abi | 0 build.sh | 34 ++++++++++++++++++++++++ deps/eosio.exchange | 1 + deps/eosio.token | 1 + src/eosio.system.cpp | 7 ++++- src/exchange_state.cpp | 2 +- src/voting.cpp | 2 +- 9 files changed, 50 insertions(+), 27 deletions(-) create mode 100644 .gitmodules delete mode 100644 CMakeLists.txt rename eosio.system.abi => abi/eosio.system.abi (100%) create mode 100755 build.sh create mode 160000 deps/eosio.exchange create mode 160000 deps/eosio.token diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..e281cede --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "deps/eosio.token"] + path = deps/eosio.token + url = https://github.com/eosio/eosio.token +[submodule "deps/eosio.exchange"] + path = deps/eosio.exchange + url = git@github.com:eosio/eosio.exchange diff --git a/CMakeLists.txt b/CMakeLists.txt deleted file mode 100644 index b79182ab..00000000 --- a/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(eosio_token VERSION 1.0.0) - -# if no wasm root is given use default path -if(WASM_ROOT STREQUAL "" OR NOT WASM_ROOT) - set(WASM_ROOT ${CMAKE_INSTALL_PREFIX}) -endif() - -list(APPEND CMAKE_MODULE_PATH ${WASM_ROOT}/lib/cmake) -include(EosioWasmToolchain) - -add_executable(eosio.system - ${CMAKE_SOURCE_DIR}/src/eosio.system.cpp - ${CMAKE_SOURCE_DIR}/src/producer_pay.cpp - ${CMAKE_SOURCE_DIR}/src/delegate_bandwidth.cpp - ${CMAKE_SOURCE_DIR}/src/voting.cpp - ${CMAKE_SOURCE_DIR}/src/exchange_state.cpp) - -target_include_directories(eosio.system - PUBLIC - ${STANDARD_INCLUDES} - ${CMAKE_SOURCE_DIR}/include) -target_link_libraries(eosio.system PRIVATE ${STANDARD_LIBS}) -#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosiosdk/include) diff --git a/eosio.system.abi b/abi/eosio.system.abi similarity index 100% rename from eosio.system.abi rename to abi/eosio.system.abi diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..07caccad --- /dev/null +++ b/build.sh @@ -0,0 +1,34 @@ +#! /bin/bash + +CONTRACT_NAME="eosio.system" +unamestr=`uname` + +if [[ "${unamestr}" == 'Darwin' ]]; then + PREFIX=/usr/local +else + PREFIX=/opt +fi + +mkdir -p bin/${CONTRACT_NAME} +### BUILD THE CONTRACT +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -Ideps/eosio.token/include -Ideps/eosio.exchange/include " +LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " +LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" +S2W="${PREFIX}/bin/eosio-s2wasm " +W2W="${PREFIX}/bin/eosio-wast2wasm " +${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp +${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LLC} -o ${CONTRACT_NAME}.s linked.bc +${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s +${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n +cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi + +if [[ "$1" == 'noinstall' ]]; then + rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s + exit 0 +fi + +### INSTALL THE HEADERS +cp -r include/* /usr/local/include + +rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/deps/eosio.exchange b/deps/eosio.exchange new file mode 160000 index 00000000..788ecb31 --- /dev/null +++ b/deps/eosio.exchange @@ -0,0 +1 @@ +Subproject commit 788ecb31eb31ec85434c7eff5ed23da27d48bf67 diff --git a/deps/eosio.token b/deps/eosio.token new file mode 160000 index 00000000..abbfe787 --- /dev/null +++ b/deps/eosio.token @@ -0,0 +1 @@ +Subproject commit abbfe7872e42523e77325b0ae018664b8b212d9c diff --git a/src/eosio.system.cpp b/src/eosio.system.cpp index b5aed6ae..fe560725 100644 --- a/src/eosio.system.cpp +++ b/src/eosio.system.cpp @@ -1,7 +1,12 @@ #include -#include #include +#include "producer_pay.cpp" +#include "delegate_bandwidth.cpp" +#include "voting.cpp" +#include "exchange_state.cpp" + + namespace eosiosystem { system_contract::system_contract( account_name s ) diff --git a/src/exchange_state.cpp b/src/exchange_state.cpp index b621bdef..b50d2aa0 100644 --- a/src/exchange_state.cpp +++ b/src/exchange_state.cpp @@ -1,4 +1,4 @@ -#include +#include namespace eosiosystem { asset exchange_state::convert_to_exchange( connector& c, asset in ) { diff --git a/src/voting.cpp b/src/voting.cpp index 166f1707..a625dcc6 100644 --- a/src/voting.cpp +++ b/src/voting.cpp @@ -2,7 +2,7 @@ * @file * @copyright defined in eos/LICENSE.txt */ -#include "eosio.system.hpp" +#include #include #include From 063ddf714cd6aa79bf516c40438e79690f5715c2 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Sat, 23 Jun 2018 18:51:40 -0400 Subject: [PATCH 0387/1048] Fixed build.sh and started on unit test support, a lot of undefined references --- build.sh | 9 +- tests/CMakeLists.txt | 119 ++ tests/eosio.system_tester.hpp | 578 ++++++++ tests/eosio.system_tests.cpp | 2479 +++++++++++++++++++++++++++++++++ 4 files changed, 3181 insertions(+), 4 deletions(-) create mode 100644 tests/CMakeLists.txt create mode 100644 tests/eosio.system_tester.hpp create mode 100644 tests/eosio.system_tests.cpp diff --git a/build.sh b/build.sh index 07caccad..14750842 100755 --- a/build.sh +++ b/build.sh @@ -6,16 +6,17 @@ unamestr=`uname` if [[ "${unamestr}" == 'Darwin' ]]; then PREFIX=/usr/local else - PREFIX=/opt + PREFIX=~/opt + BOOST=~/opt/boost/include fi mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -Ideps/eosio.token/include -Ideps/eosio.exchange/include " +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -Ideps/eosio.token/include -Ideps/eosio.exchange/include -I${BOOST}" LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${PREFIX}/bin/eosio-s2wasm " -W2W="${PREFIX}/bin/eosio-wast2wasm " +S2W="/usr/local/bin/eosio-s2wasm " +W2W="/usr/local/bin/eosio-wast2wasm " ${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp ${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc ${LLC} -o ${CONTRACT_NAME}.s linked.bc diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 00000000..68799b09 --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,119 @@ +#file(GLOB COMMON_SOURCES "common/*.cpp") + +find_package( Gperftools QUIET ) +if( GPERFTOOLS_FOUND ) + message( STATUS "Found gperftools; compiling tests with TCMalloc") + list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc ) +endif() + +find_package(LLVM 4.0 REQUIRED CONFIG) + +link_directories(${LLVM_LIBRARY_DIR}) + +set( CMAKE_CXX_STANDARD 14 ) + +find_package(Boost 1.67 REQUIRED) +#add_subdirectory(contracts) + +file(GLOB UNIT_TESTS "*.cpp") + +find_library(libtester eosio_testing /usr/local/lib) +find_library(libchain eosio_chain /usr/local/lib) +find_library(libfc fc /usr/local/lib) +find_library(libwasm WASM /usr/local/lib) +find_library(libwast WAST /usr/local/lib) +find_library(libir IR /usr/local/lib) +find_library(libruntime Runtime /usr/local/lib) +find_library(libsoftfloat softfloat /usr/local/lib) + +add_executable( unit_test ${UNIT_TESTS} ) +target_link_libraries( unit_test ${LLVM} ${libchain} ${libtester} ${libfc} ${libir} ${libwast} ${libwasm} ${libruntime} ${libsoftfloat} ${PLATFORM_SPECIFIC_LIBS} + LLVMX86Disassembler + LLVMX86AsmParser + LLVMX86AsmPrinter + LLVMX86CodeGen + + LLVMSelectionDAG + + LLVMAsmPrinter + LLVMMCParser + LLVMX86Info + + LLVMOrcJIT + LLVMExecutionEngine + + LLVMCodeGen + LLVMScalarOpts + LLVMTransformUtils + + LLVMipo + LLVMAnalysis + LLVMTarget + LLVMMC + + LLVMCore + LLVMSupport + ) + +target_include_directories( unit_test PUBLIC + ${Boost_INCLUDE_DIRS} + /usr/local/include + /usr/local/include/eosio/wasm-jit/Include + /usr/local/include/eosio/softfloat/include + ${CMAKE_CURRENT_BINARY_DIR}/include ) + #add_dependencies(unit_test asserter test_api test_api_mem test_api_db test_ram_limit test_api_multi_index exchange eosio.token proxy identity identity_test stltest infinite eosio.system eosio.token eosio.bios test.inline multi_index_test noop dice eosio.msig payloadless tic_tac_toe deferred_test) + +#Manually run unit_test for all supported runtimes +#To run unit_test with all log from blockchain displayed, put --verbose after --, i.e. unit_test -- --verbose +add_test(NAME unit_test_binaryen COMMAND unit_test + --report_level=detailed --color_output -- --binaryen) +add_test(NAME unit_test_wavm COMMAND unit_test + --report_level=detailed --color_output --catch_system_errors=no -- --wavm) + +if(ENABLE_COVERAGE_TESTING) + + set(Coverage_NAME ${PROJECT_NAME}_ut_coverage) + + if(NOT LCOV_PATH) + message(FATAL_ERROR "lcov not found! Aborting...") + endif() # NOT LCOV_PATH + + if(NOT LLVMCOV_PATH) + message(FATAL_ERROR "llvm-cov not found! Aborting...") + endif() # NOT LCOV_PATH + + if(NOT GENHTML_PATH) + message(FATAL_ERROR "genhtml not found! Aborting...") + endif() # NOT GENHTML_PATH + + # no spaces allowed within tests list + set(ctest_tests 'unit_test_binaryen|unit_test_wavm') + set(ctest_exclude_tests '') + + # Setup target + add_custom_target(${Coverage_NAME} + + # Cleanup lcov + COMMAND ${LCOV_PATH} --directory . --zerocounters + + # Run tests + COMMAND ./tools/ctestwrapper.sh -R ${ctest_tests} -E ${ctest_exclude_tests} + + COMMAND ${LCOV_PATH} --directory . --capture --gcov-tool ./tools/llvm-gcov.sh --output-file ${Coverage_NAME}.info + + COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/fc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info + + COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info + + COMMAND if [ "$CI" != "true" ]\; then ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.info ${Coverage_NAME}_filtered.info ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info.cleaned\; fi + + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + COMMENT "Resetting code coverage counters to zero. Processing code coverage counters and generating report. Report published in ./${Coverage_NAME}" + ) + + # Show info where to find the report + add_custom_command(TARGET ${Coverage_NAME} POST_BUILD + COMMAND ; + COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." + ) +endif() diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp new file mode 100644 index 00000000..526370b7 --- /dev/null +++ b/tests/eosio.system_tester.hpp @@ -0,0 +1,578 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include +#include + +#include +#include + +using namespace eosio::chain; +using namespace eosio::testing; +using namespace fc; + +using mvo = fc::mutable_variant_object; + +#ifndef TESTER +#ifdef NON_VALIDATING_TEST +#define TESTER tester +#else +#define TESTER validating_tester +#endif +#endif + +namespace eosio_system { + +std::vector read_wasm( const char* fn ) { + std::ifstream wasm_file(fn, std::ios::binary); + wasm_file.seekg(0, std::ios::end); + std::vector wasm; + wasm.resize(wasm_file.tellg()); + wasm_file.seekg(0, std::ios::beg); + wasm_file.read((char*)wasm.data(), wasm.size()); + wasm_file.close(); + return wasm; +} +std::vector read_abi( const char* fn ) { + std::ifstream abi_file(fn); + abi_file.seekg(0, std::ios::end); + std::vector abi; + abi.resize(abi_file.tellg()+1); + abi_file.seekg(0, std::ios::beg); + abi_file.read(abi.data(), abi.size()); + abi[abi.size()-1] = '\0'; + abi_file.close(); + return abi; +} + + +class eosio_system_tester : public TESTER { +public: + + eosio_system_tester() + : eosio_system_tester([](TESTER& ) {}){} + + template + eosio_system_tester(Lambda setup) { + setup(*this); + + 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) }); + + + produce_blocks( 100 ); + + //const auto eosio_token = read_wasm("../deps/eosio.token/bin/eosio.token/eosio.token.wasm"); + //const auto eosio_token_abi = read_abi("../deps/eosio.token/bin/eosio.token/eosio.token.abi"); + set_code( N(eosio.token), read_wasm("../deps/eosio.token/bin/eosio.token/eosio.token.wasm") ); + set_abi( N(eosio.token), read_abi("../deps/eosio.token/bin/eosio.token/eosio.token.abi").data() ); + { + const auto& accnt = control->db().get( N(eosio.token) ); + abi_def abi; + BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); + token_abi_ser.set_abi(abi); + } + + create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); + issue(config::system_account_name, core_from_string("1000000000.0000")); + BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance( "eosio" ) ); + + set_code( config::system_account_name, read_wasm("../bin/eosio.system/eosio.system.wasm") ); + set_abi( config::system_account_name, read_abi("../bin/eosio.system/eosio.system.abi").data() ); + + { + const auto& accnt = control->db().get( config::system_account_name ); + abi_def abi; + BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); + abi_ser.set_abi(abi); + } + + produce_blocks(); + + create_account_with_resources( N(alice1111111), config::system_account_name, core_from_string("1.0000"), false ); + create_account_with_resources( N(bob111111111), config::system_account_name, core_from_string("0.4500"), false ); + create_account_with_resources( N(carol1111111), config::system_account_name, core_from_string("1.0000"), false ); + + BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + } + + + void create_accounts_with_resources( vector accounts, account_name creator = config::system_account_name ) { + for( auto a : accounts ) { + create_account_with_resources( a, creator ); + } + } + + transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, uint32_t ram_bytes = 8000 ) { + signed_transaction trx; + set_transaction_headers(trx); + + authority owner_auth; + owner_auth = authority( get_public_key( a, "owner" ) ); + + trx.actions.emplace_back( vector{{creator,config::active_name}}, + newaccount{ + .creator = creator, + .name = a, + .owner = owner_auth, + .active = authority( get_public_key( a, "active" ) ) + }); + + trx.actions.emplace_back( get_action( config::system_account_name, N(buyrambytes), vector{{creator,config::active_name}}, + mvo() + ("payer", creator) + ("receiver", a) + ("bytes", ram_bytes) ) + ); + trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, + mvo() + ("from", creator) + ("receiver", a) + ("stake_net_quantity", core_from_string("10.0000") ) + ("stake_cpu_quantity", core_from_string("10.0000") ) + ("transfer", 0 ) + ) + ); + + set_transaction_headers(trx); + trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); + return push_transaction( trx ); + } + + transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, + asset net = core_from_string("10.0000"), asset cpu = core_from_string("10.0000") ) { + signed_transaction trx; + set_transaction_headers(trx); + + authority owner_auth; + if (multisig) { + // multisig between account's owner key and creators active permission + owner_auth = authority(2, {key_weight{get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}}); + } else { + owner_auth = authority( get_public_key( a, "owner" ) ); + } + + trx.actions.emplace_back( vector{{creator,config::active_name}}, + newaccount{ + .creator = creator, + .name = a, + .owner = owner_auth, + .active = authority( get_public_key( a, "active" ) ) + }); + + trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{{creator,config::active_name}}, + mvo() + ("payer", creator) + ("receiver", a) + ("quant", ramfunds) ) + ); + + trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, + mvo() + ("from", creator) + ("receiver", a) + ("stake_net_quantity", net ) + ("stake_cpu_quantity", cpu ) + ("transfer", 0 ) + ) + ); + + set_transaction_headers(trx); + trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); + return push_transaction( trx ); + } + + transaction_trace_ptr setup_producer_accounts( const std::vector& accounts ) { + account_name creator(config::system_account_name); + signed_transaction trx; + set_transaction_headers(trx); + asset cpu = core_from_string("80.0000"); + asset net = core_from_string("80.0000"); + asset ram = core_from_string("1.0000"); + + for (const auto& a: accounts) { + authority owner_auth( get_public_key( a, "owner" ) ); + trx.actions.emplace_back( vector{{creator,config::active_name}}, + newaccount{ + .creator = creator, + .name = a, + .owner = owner_auth, + .active = authority( get_public_key( a, "active" ) ) + }); + + trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{ {creator, config::active_name} }, + mvo() + ("payer", creator) + ("receiver", a) + ("quant", ram) ) + ); + + trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{ {creator, config::active_name} }, + mvo() + ("from", creator) + ("receiver", a) + ("stake_net_quantity", net) + ("stake_cpu_quantity", cpu ) + ("transfer", 0 ) + ) + ); + } + + set_transaction_headers(trx); + trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); + return push_transaction( trx ); + } + + action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { + return push_action( payer, N(buyram), mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); + } + action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { + return push_action( payer, N(buyrambytes), mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); + } + + action_result sellram( const account_name& account, uint64_t numbytes ) { + return push_action( account, N(sellram), mvo()( "account", account)("bytes",numbytes) ); + } + + action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { + string action_type_name = abi_ser.get_action_type(name); + + action act; + act.account = config::system_account_name; + act.name = name; + act.data = abi_ser.variant_to_binary( action_type_name, data ); + + return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + } + + action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { + return push_action( name(from), N(delegatebw), mvo() + ("from", from) + ("receiver", to) + ("stake_net_quantity", net) + ("stake_cpu_quantity", cpu) + ("transfer", 0 ) + ); + } + + action_result stake( const account_name& acnt, const asset& net, const asset& cpu ) { + return stake( acnt, acnt, net, cpu ); + } + + action_result stake_with_transfer( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { + return push_action( name(from), N(delegatebw), mvo() + ("from", from) + ("receiver", to) + ("stake_net_quantity", net) + ("stake_cpu_quantity", cpu) + ("transfer", true ) + ); + } + + action_result stake_with_transfer( const account_name& acnt, const asset& net, const asset& cpu ) { + return stake_with_transfer( acnt, acnt, net, cpu ); + } + + action_result unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { + return push_action( name(from), N(undelegatebw), mvo() + ("from", from) + ("receiver", to) + ("unstake_net_quantity", net) + ("unstake_cpu_quantity", cpu) + ); + } + + action_result unstake( const account_name& acnt, const asset& net, const asset& cpu ) { + return unstake( acnt, acnt, net, cpu ); + } + + action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { + return push_action( name(bidder), N(bidname), mvo() + ("bidder", bidder) + ("newname", newname) + ("bid", bid) + ); + } + + static fc::variant_object producer_parameters_example( int n ) { + return mutable_variant_object() + ("max_block_net_usage", 10000000 + n ) + ("target_block_net_usage_pct", 10 + n ) + ("max_transaction_net_usage", 1000000 + n ) + ("base_per_transaction_net_usage", 100 + n) + ("net_usage_leeway", 500 + n ) + ("context_free_discount_net_usage_num", 1 + n ) + ("context_free_discount_net_usage_den", 100 + n ) + ("max_block_cpu_usage", 10000000 + n ) + ("target_block_cpu_usage_pct", 10 + n ) + ("max_transaction_cpu_usage", 1000000 + n ) + ("min_transaction_cpu_usage", 100 + n ) + ("max_transaction_lifetime", 3600 + n) + ("deferred_trx_expiration_window", 600 + n) + ("max_transaction_delay", 10*86400+n) + ("max_inline_action_size", 4096 + n) + ("max_inline_action_depth", 4 + n) + ("max_authority_depth", 6 + n) + ("max_ram_size", (n % 10 + 1) * 1024 * 1024) + ("ram_reserve_ratio", 100 + n); + } + + action_result regproducer( const account_name& acnt, int params_fixture = 1 ) { + action_result r = push_action( acnt, N(regproducer), mvo() + ("producer", acnt ) + ("producer_key", get_public_key( acnt, "active" ) ) + ("url", "" ) + ("location", 0 ) + ); + BOOST_REQUIRE_EQUAL( success(), r); + return r; + } + + action_result vote( const account_name& voter, const std::vector& producers, const account_name& proxy = name(0) ) { + return push_action(voter, N(voteproducer), mvo() + ("voter", voter) + ("proxy", proxy) + ("producers", producers)); + } + + uint32_t last_block_time() const { + return time_point_sec( control->head_block_time() ).sec_since_epoch(); + } + + asset get_balance( const account_name& act ) { + vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYMBOL).to_symbol_code().value ); + return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data)["balance"].as(); + } + + fc::variant get_total_stake( const account_name& act ) { + vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data ); + } + + fc::variant get_voter_info( const account_name& act ) { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data ); + } + + fc::variant get_producer_info( const account_name& act ) { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); + return abi_ser.binary_to_variant( "producer_info", data ); + } + + void create_currency( name contract, name manager, asset maxsupply ) { + auto act = mutable_variant_object() + ("issuer", manager ) + ("maximum_supply", maxsupply ); + + base_tester::push_action(contract, N(create), contract, act ); + } + + void issue( name to, const asset& amount, name manager = config::system_account_name ) { + base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() + ("to", to ) + ("quantity", amount ) + ("memo", "") + ); + } + void transfer( name from, name to, const asset& amount, name manager = config::system_account_name ) { + base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() + ("from", from) + ("to", to ) + ("quantity", amount) + ("memo", "") + ); + } + + double stake2votes( asset stake ) { + auto now = control->pending_block_time().time_since_epoch().count() / 1000000; + return stake.get_amount() * pow(2, int64_t((now - (config::block_timestamp_epoch / 1000)) / (86400 * 7))/ double(52) ); // 52 week periods (i.e. ~years) + } + + double stake2votes( const string& s ) { + return stake2votes( core_from_string(s) ); + } + + fc::variant get_stats( const string& symbolname ) { + auto symb = eosio::chain::symbol::from_string(symbolname); + auto symbol_code = symb.to_symbol_code().value; + vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data ); + } + + asset get_token_supply() { + return get_stats("4," CORE_SYMBOL_NAME)["supply"].as(); + } + + fc::variant get_global_state() { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); + if (data.empty()) std::cout << "\nData is empty\n" << std::endl; + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); + + } + + fc::variant get_refund_request( name account ) { + vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); + } +#if 0 + abi_serializer initialize_multisig() { + abi_serializer msig_abi_ser; + { + create_account_with_resources( N(eosio.msig), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), buyram( "eosio", "eosio.msig", core_from_string("5000.0000") ) ); + produce_block(); + + auto trace = base_tester::push_action(config::system_account_name, N(setpriv), + config::system_account_name, mutable_variant_object() + ("account", "eosio.msig") + ("is_priv", 1) + ); + + set_code( N(eosio.msig), eosio_msig_wast ); + set_abi( N(eosio.msig), eosio_msig_abi ); + + produce_blocks(); + const auto& accnt = control->db().get( N(eosio.msig) ); + abi_def msig_abi; + BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); + msig_abi_ser.set_abi(msig_abi); + } + return msig_abi_ser; + } +#endif + //helper function + + vector active_and_vote_producers() { + //stake more than 15% of total EOS supply to activate chain + transfer( "eosio", "alice1111111", core_from_string("650000000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("300000000.0000"), core_from_string("300000000.0000") ) ); + + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + const std::string root("defproducer"); + for ( char c = 'a'; c < 'a'+21; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + setup_producer_accounts(producer_names); + for (const auto& p: producer_names) { + + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + } + } + produce_blocks( 250); + + auto trace_auth = TESTER::push_action(config::system_account_name, updateauth::get_name(), config::system_account_name, mvo() + ("account", name(config::system_account_name).to_string()) + ("permission", name(config::active_name).to_string()) + ("parent", name(config::owner_name).to_string()) + ("auth", authority(1, {key_weight{get_public_key( config::system_account_name, "active" ), 1}}, { + permission_level_weight{{config::system_account_name, config::eosio_code_name}, 1}, + permission_level_weight{{config::producers_account_name, config::active_name}, 1} + } + )) + ); + BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace_auth->receipt->status); + + //vote for producers + { + transfer( config::system_account_name, "alice1111111", core_from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake( "alice1111111", core_from_string("30000000.0000"), core_from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(success(), buyram( "alice1111111", "alice1111111", core_from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(success(), push_action(N(alice1111111), N(voteproducer), mvo() + ("voter", "alice1111111") + ("proxy", name(0).to_string()) + ("producers", vector(producer_names.begin(), producer_names.begin()+21)) + ) + ); + } + produce_blocks( 250 ); + + auto producer_keys = control->head_block_state()->active_schedule.producers; + BOOST_REQUIRE_EQUAL( 21, producer_keys.size() ); + BOOST_REQUIRE_EQUAL( name("defproducera"), producer_keys[0].producer_name ); + + return producer_names; + } + + void cross_15_percent_threshold() { + setup_producer_accounts({N(producer1111)}); + regproducer(N(producer1111)); + { + signed_transaction trx; + set_transaction_headers(trx); + + trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), + vector{{config::system_account_name, config::active_name}}, + mvo() + ("from", name{config::system_account_name}) + ("receiver", "producer1111") + ("stake_net_quantity", core_from_string("150000000.0000") ) + ("stake_cpu_quantity", core_from_string("0.0000") ) + ("transfer", 1 ) + ) + ); + trx.actions.emplace_back( get_action( config::system_account_name, N(voteproducer), + vector{{N(producer1111), config::active_name}}, + mvo() + ("voter", "producer1111") + ("proxy", name(0).to_string()) + ("producers", vector(1, N(producer1111))) + ) + ); + trx.actions.emplace_back( get_action( config::system_account_name, N(undelegatebw), + vector{{N(producer1111), config::active_name}}, + mvo() + ("from", "producer1111") + ("receiver", "producer1111") + ("unstake_net_quantity", core_from_string("150000000.0000") ) + ("unstake_cpu_quantity", core_from_string("0.0000") ) + ) + ); + + set_transaction_headers(trx); + trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); + trx.sign( get_private_key( N(producer1111), "active" ), control->get_chain_id() ); + push_transaction( trx ); + } + } + + abi_serializer abi_ser; + abi_serializer token_abi_ser; +}; + +inline fc::mutable_variant_object voter( account_name acct ) { + return mutable_variant_object() + ("owner", acct) + ("proxy", name(0).to_string()) + ("producers", variants() ) + ("staked", int64_t(0)) + //("last_vote_weight", double(0)) + ("proxied_vote_weight", double(0)) + ("is_proxy", 0) + ; +} + +inline fc::mutable_variant_object voter( account_name acct, const asset& vote_stake ) { + return voter( acct )( "staked", vote_stake.get_amount() ); +} + +inline fc::mutable_variant_object voter( account_name acct, int64_t vote_stake ) { + return voter( acct )( "staked", vote_stake ); +} + +inline fc::mutable_variant_object proxy( account_name acct ) { + return voter( acct )( "is_proxy", 1 ); +} + +inline uint64_t M( const string& eos_str ) { + return core_from_string( eos_str ).get_amount(); +} + +} diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp new file mode 100644 index 00000000..0ea2b89a --- /dev/null +++ b/tests/eosio.system_tests.cpp @@ -0,0 +1,2479 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "eosio.system_tester.hpp" + +using namespace eosio_system; + +BOOST_AUTO_TEST_SUITE(eosio_system_tests) + +BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { + + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + auto total = get_total_stake( "alice1111111" ); + auto init_bytes = total["ram_bytes"].as_uint64(); + + const asset initial_ram_balance = get_balance(N(eosio.ram)); + const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("800.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( initial_ram_balance + core_from_string("199.0000"), get_balance(N(eosio.ram)) ); + BOOST_REQUIRE_EQUAL( initial_ramfee_balance + core_from_string("1.0000"), get_balance(N(eosio.ramfee)) ); + + total = get_total_stake( "alice1111111" ); + auto bytes = total["ram_bytes"].as_uint64(); + auto bought_bytes = bytes - init_bytes; + wdump((init_bytes)(bought_bytes)(bytes) ); + + BOOST_REQUIRE_EQUAL( true, 0 < bought_bytes ); + + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); + BOOST_REQUIRE_EQUAL( core_from_string("998.0050"), get_balance( "alice1111111" ) ); + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); + + transfer( "eosio", "alice1111111", core_from_string("100000000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( core_from_string("100000998.0050"), get_balance( "alice1111111" ) ); + // alice buys ram for 10000000.0000, 0.5% = 50000.0000 go to ramfee + // after fee 9950000.0000 go to bought bytes + // when selling back bought bytes, pay 0.5% fee and get back 99.5% of 9950000.0000 = 9900250.0000 + // expected account after that is 90000998.0050 + 9900250.0000 = 99901248.0050 with a difference + // of order 0.0001 due to rounding errors + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("90000998.0050"), get_balance( "alice1111111" ) ); + + total = get_total_stake( "alice1111111" ); + bytes = total["ram_bytes"].as_uint64(); + bought_bytes = bytes - init_bytes; + wdump((init_bytes)(bought_bytes)(bytes) ); + + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); + total = get_total_stake( "alice1111111" ); + + bytes = total["ram_bytes"].as_uint64(); + bought_bytes = bytes - init_bytes; + wdump((init_bytes)(bought_bytes)(bytes) ); + + BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); + BOOST_REQUIRE_EQUAL( core_from_string("99901248.0044"), get_balance( "alice1111111" ) ); + + + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("30.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99900688.0044"), get_balance( "alice1111111" ) ); + + auto newtotal = get_total_stake( "alice1111111" ); + + auto newbytes = newtotal["ram_bytes"].as_uint64(); + bought_bytes = newbytes - bytes; + wdump((newbytes)(bytes)(bought_bytes) ); + + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99901242.4183"), get_balance( "alice1111111" ) ); + + + newtotal = get_total_stake( "alice1111111" ); + auto startbytes = newtotal["ram_bytes"].as_uint64(); + + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("300000.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("49301242.4183"), get_balance( "alice1111111" ) ); + + auto finaltotal = get_total_stake( "alice1111111" ); + auto endbytes = finaltotal["ram_bytes"].as_uint64(); + + bought_bytes = endbytes - startbytes; + wdump((startbytes)(endbytes)(bought_bytes) ); + + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); + + BOOST_REQUIRE_EQUAL( core_from_string("99396507.4147"), get_balance( "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( stake_unstake, eosio_system_tester ) try { + cross_15_percent_threshold(); + + produce_blocks( 10 ); + produce_block( fc::hours(3*24) ); + + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + auto total = get_total_stake("alice1111111"); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + + const auto init_eosio_stake_balance = get_balance( N(eosio.stake) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_from_string("300.0000"), get_balance( N(eosio.stake) ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + produce_block( fc::hours(3*24-1) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_from_string("300.0000"), get_balance( N(eosio.stake) ) ); + //after 3 days funds should be released + produce_block( fc::hours(1) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( init_eosio_stake_balance, get_balance( N(eosio.stake) ) ); + + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + total = get_total_stake("bob111111111"); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000").get_amount(), total["net_weight"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000").get_amount(), total["cpu_weight"].as().get_amount() ); + + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000")), get_voter_info( "alice1111111" ) ); + + auto bytes = total["ram_bytes"].as_uint64(); + BOOST_REQUIRE_EQUAL( true, 0 < bytes ); + + //unstake from bob111111111 + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + total = get_total_stake("bob111111111"); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); + produce_block( fc::hours(3*24-1) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + //after 3 days funds should be released + produce_block( fc::hours(1) ); + produce_blocks(1); + + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("0.0000") ), get_voter_info( "alice1111111" ) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "eosio", core_from_string("1000.0000"), config::system_account_name ); + issue( "eosio.stake", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + + //eosio stakes for alice with transfer flag + + transfer( "eosio", "bob111111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + //check that alice has both bandwidth and voting power + auto total = get_total_stake("alice1111111"); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000")), get_voter_info( "alice1111111" ) ); + + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + + //alice stakes for herself + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + //now alice's stake should be equal to transfered from eosio + own stake + total = get_total_stake("alice1111111"); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("410.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("600.0000")), get_voter_info( "alice1111111" ) ); + + //alice can unstake everything (including what was transfered) + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("400.0000"), core_from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + edump((get_balance( "eosio.stake" ))); + + produce_block( fc::hours(3*24-1) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + //after 3 days funds should be released + + produce_block( fc::hours(1) ); + produce_blocks(1); + + BOOST_REQUIRE_EQUAL( core_from_string("1300.0000"), get_balance( "alice1111111" ) ); + + //stake should be equal to what was staked in constructor, votring power should be 0 + total = get_total_stake("alice1111111"); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("0.0000")), get_voter_info( "alice1111111" ) ); + + // Now alice stakes to bob with transfer flag + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("100.0000") ) ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("2000.0000"), core_from_string("1000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("10.0000"), core_from_string("10.0000") ) ); + + BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), + push_action( N(alice1111111), N(delegatebw), mvo() + ("from", "alice1111111") + ("receiver", "bob111111111") + ("stake_net_quantity", core_from_string("10.0000")) + ("stake_cpu_quantity", core_from_string("10.0000")) + ("transfer", 0 ) + ,false + ) + ); + + BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), + push_action(N(alice1111111), N(undelegatebw), mvo() + ("from", "alice1111111") + ("receiver", "bob111111111") + ("unstake_net_quantity", core_from_string("200.0000")) + ("unstake_cpu_quantity", core_from_string("100.0000")) + ("transfer", 0 ) + ,false + ) + ); + //REQUIRE_MATCHING_OBJECT( , get_voter_info( "alice1111111" ) ); +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), + stake( "alice1111111", core_from_string("-0.0001"), core_from_string("0.0000") ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), + stake( "alice1111111", core_from_string("0.0000"), core_from_string("-0.0001") ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), + stake( "alice1111111", core_from_string("00.0000"), core_from_string("00.0000") ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), + stake( "alice1111111", core_from_string("0.0000"), core_from_string("00.0000") ) + + ); + + BOOST_REQUIRE_EQUAL( true, get_voter_info( "alice1111111" ).is_null() ); +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0001"), core_from_string("100.0001") ) ); + + auto total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0001"), total["net_weight"].as()); + auto vinfo = get_voter_info("alice1111111" ); + wdump((vinfo)); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0002") ), get_voter_info( "alice1111111" ) ); + + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), + unstake( "alice1111111", "bob111111111", core_from_string("-1.0000"), core_from_string("0.0000") ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), + unstake( "alice1111111", "bob111111111", core_from_string("0.0000"), core_from_string("-1.0000") ) + ); + + //unstake all zeros + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), + unstake( "alice1111111", "bob111111111", core_from_string("0.0000"), core_from_string("0.0000") ) + + ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( unstake_more_than_at_stake, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + auto total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //trying to unstake more net bandwith than at stake + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), + unstake( "alice1111111", core_from_string("200.0001"), core_from_string("0.0000") ) + ); + + //trying to unstake more cpu bandwith than at stake + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), + unstake( "alice1111111", core_from_string("0.0000"), core_from_string("100.0001") ) + + ); + + //check that nothing has changed + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + + BOOST_REQUIRE_EQUAL( success(), stake ( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + auto total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + //all voting power goes to alice1111111 + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + //but not to bob111111111 + BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); + + //bob111111111 should not be able to unstake what was staked by alice1111111 + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), + unstake( "bob111111111", core_from_string("0.0000"), core_from_string("10.0000") ) + + ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), + unstake( "bob111111111", core_from_string("10.0000"), core_from_string("0.0000") ) + ); + + issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", "bob111111111", core_from_string("20.0000"), core_from_string("10.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("970.0000"), get_balance( "carol1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("30.0000") ), get_voter_info( "carol1111111" ) ); + + //alice1111111 should not be able to unstake money staked by carol1111111 + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), + unstake( "alice1111111", "bob111111111", core_from_string("2001.0000"), core_from_string("1.0000") ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), + unstake( "alice1111111", "bob111111111", core_from_string("1.0000"), core_from_string("101.0000") ) + + ); + + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["cpu_weight"].as()); + //balance should not change after unsuccessfull attempts to unstake + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + //voting power too + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("30.0000") ), get_voter_info( "carol1111111" ) ); + BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( stake_unstake_separate, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + + //everything at once + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("10.0000"), core_from_string("20.0000") ) ); + auto total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); + + //cpu + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("100.0000"), core_from_string("0.0000") ) ); + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); + + //net + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("0.0000"), core_from_string("200.0000") ) ); + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["cpu_weight"].as()); + + //unstake cpu + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("100.0000"), core_from_string("0.0000") ) ); + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["cpu_weight"].as()); + + //unstake net + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("0.0000"), core_from_string("200.0000") ) ); + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( adding_stake_partial_unstake, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + + auto total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("450.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("550.0000"), get_balance( "alice1111111" ) ); + + //unstake a share + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("150.0000"), core_from_string("75.0000") ) ); + + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("85.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("225.0000") ), get_voter_info( "alice1111111" ) ); + + //unstake more + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("150.0000") ), get_voter_info( "alice1111111" ) ); + + //combined amount should be available only in 3 days + produce_block( fc::days(2) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("550.0000"), get_balance( "alice1111111" ) ); + produce_block( fc::days(1) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("850.0000"), get_balance( "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + auto total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //unstake a share + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("150.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + auto refund = get_refund_request( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string( "50.0000"), refund["cpu_amount"].as() ); + //XXX auto request_time = refund["request_time"].as_int64(); + + //stake less than pending refund, entire amount should be traken from refund + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("85.0000"), total["cpu_weight"].as()); + refund = get_refund_request( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("50.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("25.0000"), refund["cpu_amount"].as() ); + //request time should stay the same + //BOOST_REQUIRE_EQUAL( request_time, refund["request_time"].as_int64() ); + //balance shoud stay the same + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //stake exactly pending refund amount + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + //pending refund should be removed + refund = get_refund_request( "alice1111111" ); + BOOST_TEST_REQUIRE( refund.is_null() ); + //balance shoud stay the same + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //create pending refund again + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + refund = get_refund_request( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); + + //stake more than pending refund + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("300.0000"), core_from_string("200.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); + refund = get_refund_request( "alice1111111" ); + BOOST_TEST_REQUIRE( refund.is_null() ); + //200 EOS should be taken from alice's account + BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + + +// Tests for voting +BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try { + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + + //fc::variant params = producer_parameters_example(1); + auto key = fc::crypto::public_key( std::string("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ); + BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", key ) + ("url", "http://block.one") + ("location", 1) + ) + ); + + auto info = get_producer_info( "alice1111111" ); + BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); + BOOST_REQUIRE_EQUAL( 0, info["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( "http://block.one", info["url"].as_string() ); + + //change parameters one by one to check for things like #3783 + //fc::variant params2 = producer_parameters_example(2); + BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", key ) + ("url", "http://block.two") + ("location", 1) + ) + ); + info = get_producer_info( "alice1111111" ); + BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); + BOOST_REQUIRE_EQUAL( key, fc::crypto::public_key(info["producer_key"].as_string()) ); + BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); + BOOST_REQUIRE_EQUAL( 1, info["location"].as_int64() ); + + auto key2 = fc::crypto::public_key( std::string("EOS5jnmSKrzdBHE9n8hw58y7yxFWBC8SNiG7m8S1crJH3KvAnf9o6") ); + BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", key2 ) + ("url", "http://block.two") + ("location", 2) + ) + ); + info = get_producer_info( "alice1111111" ); + BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); + BOOST_REQUIRE_EQUAL( key2, fc::crypto::public_key(info["producer_key"].as_string()) ); + BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); + BOOST_REQUIRE_EQUAL( 2, info["location"].as_int64() ); + + //unregister producer + BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(unregprod), mvo() + ("producer", "alice1111111") + ) + ); + info = get_producer_info( "alice1111111" ); + //key should be empty + BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(info["producer_key"].as_string()) ); + //everything else should stay the same + BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); + BOOST_REQUIRE_EQUAL( 0, info["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); + + //unregister bob111111111 who is not a producer + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer not found" ), + push_action( N(bob111111111), N(unregprod), mvo() + ("producer", "bob111111111") + ) + ); + +} FC_LOG_AND_RETHROW() + + +#if 0 +BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + fc::variant params = producer_parameters_example(1); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + auto prod = get_producer_info( "alice1111111" ); + BOOST_REQUIRE_EQUAL( "alice1111111", prod["owner"].as_string() ); + BOOST_REQUIRE_EQUAL( 0, prod["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); + + issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); + issue( "carol1111111", core_from_string("3000.0000"), config::system_account_name ); + + //bob111111111 makes stake + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("11.0000"), core_from_string("0.1111") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("1988.8889"), get_balance( "bob111111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("11.1111") ), get_voter_info( "bob111111111" ) ); + + //bob111111111 votes for alice1111111 + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(alice1111111) } ) ); + + //check that producer parameters stay the same after voting + prod = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("11.1111")) == prod["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( "alice1111111", prod["owner"].as_string() ); + BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); + + //carol1111111 makes stake + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("22.0000"), core_from_string("0.2222") ) ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("22.2222") ), get_voter_info( "carol1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("2977.7778"), get_balance( "carol1111111" ) ); + //carol1111111 votes for alice1111111 + BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); + + //new stake votes be added to alice1111111's total_votes + prod = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("33.3333")) == prod["total_votes"].as_double() ); + + //bob111111111 increases his stake + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("33.0000"), core_from_string("0.3333") ) ); + //alice1111111 stake with transfer to bob111111111 + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_from_string("22.0000"), core_from_string("0.2222") ) ); + //should increase alice1111111's total_votes + prod = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("88.8888")) == prod["total_votes"].as_double() ); + + //carol1111111 unstakes part of the stake + BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_from_string("2.0000"), core_from_string("0.0002")/*"2.0000 EOS", "0.0002 EOS"*/ ) ); + + //should decrease alice1111111's total_votes + prod = get_producer_info( "alice1111111" ); + wdump((prod)); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("86.8886")) == prod["total_votes"].as_double() ); + + //bob111111111 revokes his vote + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector() ) ); + + //should decrease alice1111111's total_votes + prod = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.2220")) == prod["total_votes"].as_double() ); + //but eos should still be at stake + BOOST_REQUIRE_EQUAL( core_from_string("1955.5556"), get_balance( "bob111111111" ) ); + + //carol1111111 unstakes rest of eos + BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_from_string("20.0000"), core_from_string("0.2220") ) ); + //should decrease alice1111111's total_votes to zero + prod = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( 0.0 == prod["total_votes"].as_double() ); + + //carol1111111 should receive funds in 3 days + produce_block( fc::days(3) ); + produce_block(); + BOOST_REQUIRE_EQUAL( core_from_string("3000.0000"), get_balance( "carol1111111" ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { + issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("13.0000"), core_from_string("0.5791") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("13.5791") ), get_voter_info( "bob111111111" ) ); + + //bob111111111 should not be able to vote for alice1111111 who is not a producer + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer is not registered" ), + vote( N(bob111111111), { N(alice1111111) } ) ); + + //alice1111111 registers as a producer + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + fc::variant params = producer_parameters_example(1); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url", "") + ("location", 0) + ) + ); + //and then unregisters + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(unregprod), mvo() + ("producer", "alice1111111") + ) + ); + //key should be empty + auto prod = get_producer_info( "alice1111111" ); + BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(prod["producer_key"].as_string()) ); + + //bob111111111 should not be able to vote for alice1111111 who is an unregistered producer + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer is not currently registered" ), + vote( N(bob111111111), { N(alice1111111) } ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try { + issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("13.0000"), core_from_string("0.5791") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("13.5791") ), get_voter_info( "bob111111111" ) ); + + //bob111111111 should not be able to vote for alice1111111 who is not a producer + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "attempt to vote for too many producers" ), + vote( N(bob111111111), vector(31, N(alice1111111)) ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try { + issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("50.0000"), core_from_string("50.0000") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("100.0000") ), get_voter_info( "bob111111111" ) ); + + //alice1111111 becomes a producer + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + fc::variant params = producer_parameters_example(1); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key(N(alice1111111), "active") ) + ("url", "") + ("location", 0) + ) + ); + + //bob111111111 should not be able to vote for alice1111111 who is not a producer + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer votes must be unique and sorted" ), + vote( N(bob111111111), vector(30, N(alice1111111)) ) ); + + auto prod = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( 0 == prod["total_votes"].as_double() ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + fc::variant params = producer_parameters_example(1); + vector key = fc::raw::pack( get_public_key( N(alice1111111), "active" ) ); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url", "") + ("location", 0) + ) + ); + + //bob111111111 makes stake + issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("13.0000"), core_from_string("0.5791") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("13.5791") ), get_voter_info( "bob111111111" ) ); + + //bob111111111 votes for alice1111111 + BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), { N(alice1111111) } ) ); + + auto prod = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")) == prod["total_votes"].as_double() ); + + //unregister producer + BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(unregprod), mvo() + ("producer", "alice1111111") + ) + ); + prod = get_producer_info( "alice1111111" ); + //key should be empty + BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(prod["producer_key"].as_string()) ); + //check parameters just in case + //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); + //votes should stay the same + BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")), prod["total_votes"].as_double() ); + + //regtister the same producer again + params = producer_parameters_example(2); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url", "") + ("location", 0) + ) + ); + prod = get_producer_info( "alice1111111" ); + //votes should stay the same + BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")), prod["total_votes"].as_double() ); + + //change parameters + params = producer_parameters_example(3); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url","") + ("location", 0) + ) + ); + prod = get_producer_info( "alice1111111" ); + //votes should stay the same + BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")), prod["total_votes"].as_double() ); + //check parameters just in case + //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( vote_for_two_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { + //alice1111111 becomes a producer + fc::variant params = producer_parameters_example(1); + auto key = get_public_key( N(alice1111111), "active" ); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url","") + ("location", 0) + ) + ); + //bob111111111 becomes a producer + params = producer_parameters_example(2); + key = get_public_key( N(bob111111111), "active" ); + BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproducer), mvo() + ("producer", "bob111111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url","") + ("location", 0) + ) + ); + + //carol1111111 votes for alice1111111 and bob111111111 + issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("15.0005"), core_from_string("5.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111), N(bob111111111) } ) ); + + auto alice_info = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == alice_info["total_votes"].as_double() ); + auto bob_info = get_producer_info( "bob111111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == bob_info["total_votes"].as_double() ); + + //carol1111111 votes for alice1111111 (but revokes vote for bob111111111) + BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); + + alice_info = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == alice_info["total_votes"].as_double() ); + bob_info = get_producer_info( "bob111111111" ); + BOOST_TEST_REQUIRE( 0 == bob_info["total_votes"].as_double() ); + + //alice1111111 votes for herself and bob111111111 + issue( "alice1111111", core_from_string("2.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("1.0000"), core_from_string("1.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(alice1111111), N(bob111111111) } ) ); + + alice_info = get_producer_info( "alice1111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("22.0005")) == alice_info["total_votes"].as_double() ); + + bob_info = get_producer_info( "bob111111111" ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("2.0000")) == bob_info["total_votes"].as_double() ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tester ) try { + //register proxy by first action for this user ever + BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", true ) + ) + ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + + //unregister proxy + BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", false) + ) + ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111" ), get_voter_info( "alice1111111" ) ); + + //stake and then register as a proxy + issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("200.0002"), core_from_string("100.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() + ("proxy", "bob111111111") + ("isproxy", true) + ) + ); + REQUIRE_MATCHING_OBJECT( proxy( "bob111111111" )( "staked", 3000003 ), get_voter_info( "bob111111111" ) ); + //unrgister and check that stake is still in place + BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() + ("proxy", "bob111111111") + ("isproxy", false) + ) + ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("300.0003") ), get_voter_info( "bob111111111" ) ); + + //register as a proxy and then stake + BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() + ("proxy", "carol1111111") + ("isproxy", true) + ) + ); + issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("246.0002"), core_from_string("531.0001") ) ); + //check that both proxy flag and stake a correct + REQUIRE_MATCHING_OBJECT( proxy( "carol1111111" )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); + + //unregister + BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() + ("proxy", "carol1111111") + ("isproxy", false) + ) + ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("777.0003") ), get_voter_info( "carol1111111" ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( proxy_stake_unstake_keeps_proxy_flag, eosio_system_tester ) try { + cross_15_percent_threshold(); + + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", true) + ) + ); + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + + //stake + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + //check that account is still a proxy + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); + + //stake more + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("30.0000"), core_from_string("20.0000") ) ); + //check that account is still a proxy + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); + + //unstake more + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("65.0000"), core_from_string("35.0000") ) ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); + + //unstake the rest + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("65.0000"), core_from_string("35.0000") ) ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 0 ), get_voter_info( "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { + cross_15_percent_threshold(); + + create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + + //register as a proxy + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", true) + ) + ); + + //accumulate proxied votes + issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), vector(), N(alice1111111) ) ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); + + //vote for producers + BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //vote for another producers + BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer3) } ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //unregister proxy + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", false) + ) + ); + //REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //register proxy again + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", true) + ) + ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //stake increase by proxy itself affects producers + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("30.0001"), core_from_string("20.0001") ) ); + BOOST_REQUIRE_EQUAL( stake2votes(core_from_string("200.0005")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( stake2votes(core_from_string("200.0005")), get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //stake decrease by proxy itself affects producers + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("10.0001"), core_from_string("10.0001") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("180.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("180.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { + + const double continuous_rate = 4.879 / 100.; + const double usecs_per_year = 52 * 7 * 24 * 3600 * 1000000ll; + const double secs_per_year = 52 * 7 * 24 * 3600; + + + const asset large_asset = core_from_string("80.0000"); + create_account_with_resources( N(defproducera), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(defproducerb), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(defproducerc), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + + create_account_with_resources( N(producvotera), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvoterb), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + + BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); + auto prod = get_producer_info( N(defproducera) ); + BOOST_REQUIRE_EQUAL("defproducera", prod["owner"].as_string()); + BOOST_REQUIRE_EQUAL(0, prod["total_votes"].as_double()); + + transfer( config::system_account_name, "producvotera", core_from_string("400000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_from_string("100000000.0000"), core_from_string("100000000.0000"))); + BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera) })); + + // defproducera is the only active producer + // produce enough blocks so new schedule kicks in and defproducera produces some blocks + { + produce_blocks(50); + + const auto initial_global_state = get_global_state(); + const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); + const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); + const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); + + prod = get_producer_info("defproducera"); + const uint32_t unpaid_blocks = prod["unpaid_blocks"].as(); + BOOST_REQUIRE(1 < unpaid_blocks); + BOOST_REQUIRE_EQUAL(0, prod["last_claim_time"].as()); + + BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); + + const asset initial_supply = get_token_supply(); + const asset initial_balance = get_balance(N(defproducera)); + + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + + const auto global_state = get_global_state(); + const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t pervote_bucket = global_state["pervote_bucket"].as(); + const int64_t perblock_bucket = global_state["perblock_bucket"].as(); + const int64_t savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); + + prod = get_producer_info("defproducera"); + BOOST_REQUIRE_EQUAL(1, prod["unpaid_blocks"].as()); + BOOST_REQUIRE_EQUAL(1, tot_unpaid_blocks); + const asset supply = get_token_supply(); + const asset balance = get_balance(N(defproducera)); + + BOOST_REQUIRE_EQUAL(claim_time, prod["last_claim_time"].as()); + + auto usecs_between_fills = claim_time - initial_claim_time; + int32_t secs_between_fills = usecs_between_fills/1000000; + + BOOST_REQUIRE_EQUAL(0, initial_savings); + BOOST_REQUIRE_EQUAL(0, initial_perblock_bucket); + BOOST_REQUIRE_EQUAL(0, initial_pervote_bucket); + + BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * continuous_rate ) / secs_per_year ), + supply.get_amount() - initial_supply.get_amount()); + BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (4. * continuous_rate/ 5.) / secs_per_year ) ), + savings - initial_savings); + BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ), + balance.get_amount() - initial_balance.get_amount()); + + int64_t from_perblock_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ; + int64_t from_pervote_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.75 * continuous_rate/ 5.) / secs_per_year ) ; + + + if (from_pervote_bucket >= 100 * 10000) { + BOOST_REQUIRE_EQUAL(from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount()); + BOOST_REQUIRE_EQUAL(0, pervote_bucket); + } else { + BOOST_REQUIRE_EQUAL(from_perblock_bucket, balance.get_amount() - initial_balance.get_amount()); + BOOST_REQUIRE_EQUAL(from_pervote_bucket, pervote_bucket); + } + } + + { + BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), + push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + } + + // defproducera waits for 23 hours and 55 minutes, can't claim rewards yet + { + produce_block(fc::seconds(23 * 3600 + 55 * 60)); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), + push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + } + + // wait 5 more minutes, defproducera can now claim rewards again + { + produce_block(fc::seconds(5 * 60)); + + const auto initial_global_state = get_global_state(); + const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); + const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); + const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); + const double initial_tot_vote_weight = initial_global_state["total_producer_vote_weight"].as(); + + prod = get_producer_info("defproducera"); + const uint32_t unpaid_blocks = prod["unpaid_blocks"].as(); + BOOST_REQUIRE(1 < unpaid_blocks); + BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); + BOOST_REQUIRE(0 < prod["total_votes"].as()); + BOOST_TEST(initial_tot_vote_weight, prod["total_votes"].as()); + BOOST_REQUIRE(0 < prod["last_claim_time"].as()); + + BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); + + const asset initial_supply = get_token_supply(); + const asset initial_balance = get_balance(N(defproducera)); + + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + + const auto global_state = get_global_state(); + const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t pervote_bucket = global_state["pervote_bucket"].as(); + const int64_t perblock_bucket = global_state["perblock_bucket"].as(); + const int64_t savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); + + prod = get_producer_info("defproducera"); + BOOST_REQUIRE_EQUAL(1, prod["unpaid_blocks"].as()); + BOOST_REQUIRE_EQUAL(1, tot_unpaid_blocks); + const asset supply = get_token_supply(); + const asset balance = get_balance(N(defproducera)); + + BOOST_REQUIRE_EQUAL(claim_time, prod["last_claim_time"].as()); + auto usecs_between_fills = claim_time - initial_claim_time; + + BOOST_REQUIRE_EQUAL(int64_t( ( double(initial_supply.get_amount()) * double(usecs_between_fills) * continuous_rate / usecs_per_year ) ), + supply.get_amount() - initial_supply.get_amount()); + BOOST_REQUIRE_EQUAL( (supply.get_amount() - initial_supply.get_amount()) - (supply.get_amount() - initial_supply.get_amount()) / 5, + savings - initial_savings); + + int64_t to_producer = int64_t( (double(initial_supply.get_amount()) * double(usecs_between_fills) * continuous_rate) / usecs_per_year ) / 5; + int64_t to_perblock_bucket = to_producer / 4; + int64_t to_pervote_bucket = to_producer - to_perblock_bucket; + + if (to_pervote_bucket + initial_pervote_bucket >= 100 * 10000) { + BOOST_REQUIRE_EQUAL(to_perblock_bucket + to_pervote_bucket + initial_pervote_bucket, balance.get_amount() - initial_balance.get_amount()); + BOOST_REQUIRE_EQUAL(0, pervote_bucket); + } else { + BOOST_REQUIRE_EQUAL(to_perblock_bucket, balance.get_amount() - initial_balance.get_amount()); + BOOST_REQUIRE_EQUAL(to_pervote_bucket + initial_pervote_bucket, pervote_bucket); + } + } + + // defproducerb tries to claim rewards but he's not on the list + { + BOOST_REQUIRE_EQUAL(wasm_assert_msg("unable to find key"), + push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); + } + + // test stability over a year + { + regproducer(N(defproducerb)); + regproducer(N(defproducerc)); + const asset initial_supply = get_token_supply(); + const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); + for (uint32_t i = 0; i < 7 * 52; ++i) { + produce_block(fc::seconds(8 * 3600)); + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerc), N(claimrewards), mvo()("owner", "defproducerc"))); + produce_block(fc::seconds(8 * 3600)); + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); + produce_block(fc::seconds(8 * 3600)); + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + } + const asset supply = get_token_supply(); + const int64_t savings = get_balance(N(eosio.saving)).get_amount(); + // Amount issued per year is very close to the 5% inflation target. Small difference (500 tokens out of 50'000'000 issued) + // is due to compounding every 8 hours in this test as opposed to theoretical continuous compounding + BOOST_REQUIRE(500 * 10000 > int64_t(double(initial_supply.get_amount()) * double(0.05)) - (supply.get_amount() - initial_supply.get_amount())); + BOOST_REQUIRE(500 * 10000 > int64_t(double(initial_supply.get_amount()) * double(0.04)) - (savings - initial_savings)); + } +} FC_LOG_AND_RETHROW() + + + +BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { + + auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; + + const int64_t secs_per_year = 52 * 7 * 24 * 3600; + const double usecs_per_year = secs_per_year * 1000000; + const double cont_rate = 4.879/100.; + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; + for (const auto& v: voters) { + create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + } + + // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + { + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'z'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + } + { + const std::string root("abcproducer"); + for ( char c = 'a'; c <= 'n'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + } + setup_producer_accounts(producer_names); + for (const auto& p: producer_names) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + produce_blocks(1); + ilog( "------ get pro----------" ); + wdump((p)); + BOOST_TEST(0 == get_producer_info(p)["total_votes"].as()); + } + } + + // producvotera votes for defproducera ... defproducerj + // producvoterb votes for defproducera ... defproduceru + // producvoterc votes for defproducera ... defproducerz + // producvoterd votes for abcproducera ... abcproducern + { + BOOST_REQUIRE_EQUAL(success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); + BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); + BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.begin()+26))); + BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end()))); + } + + { + auto proda = get_producer_info( N(defproducera) ); + auto prodj = get_producer_info( N(defproducerj) ); + auto prodk = get_producer_info( N(defproducerk) ); + auto produ = get_producer_info( N(defproduceru) ); + auto prodv = get_producer_info( N(defproducerv) ); + auto prodz = get_producer_info( N(defproducerz) ); + + BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); + BOOST_REQUIRE (0 == proda["last_claim_time"].as() && 0 == prodz["last_claim_time"].as()); + + // check vote ratios + BOOST_REQUIRE ( 0 < proda["total_votes"].as() && 0 < prodz["total_votes"].as() ); + BOOST_TEST( proda["total_votes"].as() == prodj["total_votes"].as() ); + BOOST_TEST( prodk["total_votes"].as() == produ["total_votes"].as() ); + BOOST_TEST( prodv["total_votes"].as() == prodz["total_votes"].as() ); + BOOST_TEST( 2 * proda["total_votes"].as() == 3 * produ["total_votes"].as() ); + BOOST_TEST( proda["total_votes"].as() == 3 * prodz["total_votes"].as() ); + } + + // give a chance for everyone to produce blocks + { + produce_blocks(23 * 12 + 20); + bool all_21_produced = true; + for (uint32_t i = 0; i < 21; ++i) { + if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + all_21_produced = false; + } + } + bool rest_didnt_produce = true; + for (uint32_t i = 21; i < producer_names.size(); ++i) { + if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + rest_didnt_produce = false; + } + } + BOOST_REQUIRE(all_21_produced && rest_didnt_produce); + } + + std::vector vote_shares(producer_names.size()); + { + double total_votes = 0; + for (uint32_t i = 0; i < producer_names.size(); ++i) { + vote_shares[i] = get_producer_info(producer_names[i])["total_votes"].as(); + total_votes += vote_shares[i]; + } + BOOST_TEST(total_votes == get_global_state()["total_producer_vote_weight"].as()); + std::for_each(vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; }); + + BOOST_TEST(double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0))); + BOOST_TEST(double(3./71.) == vote_shares.front()); + BOOST_TEST(double(1./71.) == vote_shares.back()); + } + + { + const uint32_t prod_index = 2; + const auto prod_name = producer_names[prod_index]; + + const auto initial_global_state = get_global_state(); + const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); + const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); + const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); + const asset initial_supply = get_token_supply(); + const asset initial_bpay_balance = get_balance(N(eosio.bpay)); + const asset initial_vpay_balance = get_balance(N(eosio.vpay)); + const asset initial_balance = get_balance(prod_name); + const uint32_t initial_unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); + + BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + + const auto global_state = get_global_state(); + const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t pervote_bucket = global_state["pervote_bucket"].as(); + const int64_t perblock_bucket = global_state["perblock_bucket"].as(); + const int64_t savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); + const asset supply = get_token_supply(); + const asset bpay_balance = get_balance(N(eosio.bpay)); + const asset vpay_balance = get_balance(N(eosio.vpay)); + const asset balance = get_balance(prod_name); + const uint32_t unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); + + const uint64_t usecs_between_fills = claim_time - initial_claim_time; + const int32_t secs_between_fills = static_cast(usecs_between_fills / 1000000); + + const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; + BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); + + BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth) - int64_t(expected_supply_growth)/5, savings - initial_savings ); + + const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ); + const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ); + + const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; + const int64_t from_pervote_bucket = int64_t( vote_shares[prod_index] * expected_pervote_bucket); + + BOOST_REQUIRE( 1 >= abs(int32_t(initial_tot_unpaid_blocks - tot_unpaid_blocks) - int32_t(initial_unpaid_blocks - unpaid_blocks)) ); + + if (from_pervote_bucket >= 100 * 10000) { + BOOST_REQUIRE( within_one( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ) ); + BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ) ); + } else { + BOOST_REQUIRE( within_one( from_perblock_bucket, balance.get_amount() - initial_balance.get_amount() ) ); + BOOST_REQUIRE( within_one( expected_pervote_bucket, pervote_bucket ) ); + BOOST_REQUIRE( within_one( expected_pervote_bucket, vpay_balance.get_amount() ) ); + BOOST_REQUIRE( within_one( perblock_bucket, bpay_balance.get_amount() ) ); + } + + produce_blocks(5); + + BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + } + + { + const uint32_t prod_index = 23; + const auto prod_name = producer_names[prod_index]; + BOOST_REQUIRE_EQUAL(success(), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + BOOST_REQUIRE_EQUAL(0, get_balance(prod_name).get_amount()); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + } + + // Wait for 23 hours. By now, pervote_bucket has grown enough + // that a producer's share is more than 100 tokens. + produce_block(fc::seconds(23 * 3600)); + + { + const uint32_t prod_index = 15; + const auto prod_name = producer_names[prod_index]; + + const auto initial_global_state = get_global_state(); + const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); + const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); + const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); + const asset initial_supply = get_token_supply(); + const asset initial_bpay_balance = get_balance(N(eosio.bpay)); + const asset initial_vpay_balance = get_balance(N(eosio.vpay)); + const asset initial_balance = get_balance(prod_name); + const uint32_t initial_unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); + + BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + + const auto global_state = get_global_state(); + const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t pervote_bucket = global_state["pervote_bucket"].as(); + const int64_t perblock_bucket = global_state["perblock_bucket"].as(); + const int64_t savings = get_balance(N(eosio.saving)).get_amount(); + const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); + const asset supply = get_token_supply(); + const asset bpay_balance = get_balance(N(eosio.bpay)); + const asset vpay_balance = get_balance(N(eosio.vpay)); + const asset balance = get_balance(prod_name); + const uint32_t unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); + + const uint64_t usecs_between_fills = claim_time - initial_claim_time; + + const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; + BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); + BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth) - int64_t(expected_supply_growth)/5, savings - initial_savings ); + + const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) + + initial_perblock_bucket; + const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) + + initial_pervote_bucket; + const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; + const int64_t from_pervote_bucket = int64_t( vote_shares[prod_index] * expected_pervote_bucket); + + BOOST_REQUIRE( 1 >= abs(int32_t(initial_tot_unpaid_blocks - tot_unpaid_blocks) - int32_t(initial_unpaid_blocks - unpaid_blocks)) ); + if (from_pervote_bucket >= 100 * 10000) { + BOOST_REQUIRE( within_one( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ) ); + BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ) ); + BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, vpay_balance.get_amount() ) ); + BOOST_REQUIRE( within_one( expected_perblock_bucket - from_perblock_bucket, perblock_bucket ) ); + BOOST_REQUIRE( within_one( expected_perblock_bucket - from_perblock_bucket, bpay_balance.get_amount() ) ); + } else { + BOOST_REQUIRE( within_one( from_perblock_bucket, balance.get_amount() - initial_balance.get_amount() ) ); + BOOST_REQUIRE( within_one( expected_pervote_bucket, pervote_bucket ) ); + } + + produce_blocks(5); + + BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + } + + { + const uint32_t prod_index = 24; + const auto prod_name = producer_names[prod_index]; + BOOST_REQUIRE_EQUAL(success(), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + BOOST_REQUIRE(100 * 10000 <= get_balance(prod_name).get_amount()); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); + } + + { + const uint32_t rmv_index = 5; + account_name prod_name = producer_names[rmv_index]; + + auto info = get_producer_info(prod_name); + BOOST_REQUIRE( info["is_active"].as() ); + BOOST_REQUIRE( fc::crypto::public_key() != fc::crypto::public_key(info["producer_key"].as_string()) ); + + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), + push_action(prod_name, N(rmvproducer), mvo()("producer", prod_name))); + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), + push_action(producer_names[rmv_index + 2], N(rmvproducer), mvo()("producer", prod_name) ) ); + BOOST_REQUIRE_EQUAL( success(), + push_action(config::system_account_name, N(rmvproducer), mvo()("producer", prod_name) ) ); + { + bool rest_didnt_produce = true; + for (uint32_t i = 21; i < producer_names.size(); ++i) { + if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + rest_didnt_produce = false; + } + } + BOOST_REQUIRE(rest_didnt_produce); + } + + produce_blocks(3 * 21 * 12); + info = get_producer_info(prod_name); + const uint32_t init_unpaid_blocks = info["unpaid_blocks"].as(); + BOOST_REQUIRE( !info["is_active"].as() ); + BOOST_REQUIRE( fc::crypto::public_key() == fc::crypto::public_key(info["producer_key"].as_string()) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("producer does not have an active key"), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); + produce_blocks(3 * 21 * 12); + BOOST_REQUIRE_EQUAL( init_unpaid_blocks, get_producer_info(prod_name)["unpaid_blocks"].as() ); + { + bool prod_was_replaced = false; + for (uint32_t i = 21; i < producer_names.size(); ++i) { + if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + prod_was_replaced = true; + } + } + BOOST_REQUIRE(prod_was_replaced); + } + } + + { + BOOST_REQUIRE_EQUAL( wasm_assert_msg("producer not found"), + push_action( config::system_account_name, N(rmvproducer), mvo()("producer", "nonexistingp") ) ); + } + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { + //install multisig contract + abi_serializer msig_abi_ser = initialize_multisig(); + auto producer_names = active_and_vote_producers(); + + //helper function + auto push_action_msig = [&]( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) -> action_result { + string action_type_name = msig_abi_ser.get_action_type(name); + + action act; + act.account = N(eosio.msig); + act.name = name; + act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + + return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + }; + // test begins + vector prod_perms; + for ( auto& x : producer_names ) { + prod_perms.push_back( { name(x), config::active_name } ); + } + //prepare system contract with different hash (contract differs in one byte) + string eosio_system_wast2 = eosio_system_wast; + string msg = "producer votes must be unique and sorted"; + auto pos = eosio_system_wast2.find(msg); + BOOST_REQUIRE( pos != std::string::npos ); + msg[0] = 'P'; + eosio_system_wast2.replace( pos, msg.size(), msg ); + + transaction trx; + { + auto code = wast_to_wasm( eosio_system_wast2 ); + variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", 0) + ("actions", fc::variants({ + fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("name", "setcode") + ("authorization", vector{ { config::system_account_name, config::active_name } }) + ("data", fc::mutable_variant_object() ("account", name(config::system_account_name)) + ("vmtype", 0) + ("vmversion", "0") + ("code", bytes( code.begin(), code.end() )) + ) + }) + ); + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + } + + BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() + ("proposer", "alice1111111") + ("proposal_name", "upgrade1") + ("trx", trx) + ("requested", prod_perms) + ) + ); + + // get 15 approvals + for ( size_t i = 0; i < 14; ++i ) { + BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[i]), N(approve), mvo() + ("proposer", "alice1111111") + ("proposal_name", "upgrade1") + ("level", permission_level{ name(producer_names[i]), config::active_name }) + ) + ); + } + + //should fail + BOOST_REQUIRE_EQUAL(wasm_assert_msg("transaction authorization failed"), + push_action_msig( N(alice1111111), N(exec), mvo() + ("proposer", "alice1111111") + ("proposal_name", "upgrade1") + ("executer", "alice1111111") + ) + ); + + // one more approval + BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[14]), N(approve), mvo() + ("proposer", "alice1111111") + ("proposal_name", "upgrade1") + ("level", permission_level{ name(producer_names[14]), config::active_name }) + ) + ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() + ("proposer", "alice1111111") + ("proposal_name", "upgrade1") + ("executer", "alice1111111") + ) + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); + + produce_blocks( 250 ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { + + const asset large_asset = core_from_string("80.0000"); + create_account_with_resources( N(producvotera), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvoterb), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvoterc), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + producer_names.reserve('z' - 'a' + 1); + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'z'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + setup_producer_accounts(producer_names); + + for (auto a:producer_names) + regproducer(a); + + BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.front() )["total_votes"].as()); + BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.back() )["total_votes"].as()); + + + transfer(config::system_account_name, "producvotera", core_from_string("200000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_from_string("70000000.0000"), core_from_string("70000000.0000") )); + BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); + BOOST_CHECK_EQUAL( wasm_assert_msg("not enough has been staked for users to unstake"), unstake( "producvotera", core_from_string("50.0000"), core_from_string("50.0000") ) ); + + // give a chance for everyone to produce blocks + { + produce_blocks(21 * 12); + bool all_21_produced = true; + for (uint32_t i = 0; i < 21; ++i) { + if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + all_21_produced= false; + } + } + bool rest_didnt_produce = true; + for (uint32_t i = 21; i < producer_names.size(); ++i) { + if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + rest_didnt_produce = false; + } + } + BOOST_REQUIRE_EQUAL(false, all_21_produced); + BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); + } + + { + BOOST_CHECK_EQUAL(0, get_global_state()["total_unpaid_blocks"].as()); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("not enough has been staked for producers to claim rewards"), + push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); + BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.front()).get_amount()); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("not enough has been staked for producers to claim rewards"), + push_action(producer_names.back(), N(claimrewards), mvo()("owner", producer_names.back()))); + BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.back()).get_amount()); + } + + // stake across 15% boundary + transfer(config::system_account_name, "producvoterb", core_from_string("100000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvoterb", core_from_string("4000000.0000"), core_from_string("4000000.0000"))); + transfer(config::system_account_name, "producvoterc", core_from_string("100000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvoterc", core_from_string("2000000.0000"), core_from_string("2000000.0000"))); + + BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); + BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterc), vector(producer_names.begin(), producer_names.end()))); + + // give a chance for everyone to produce blocks + { + produce_blocks(21 * 12); + bool all_21_produced = true; + for (uint32_t i = 0; i < 21; ++i) { + if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + all_21_produced= false; + } + } + bool rest_didnt_produce = true; + for (uint32_t i = 21; i < producer_names.size(); ++i) { + if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + rest_didnt_produce = false; + } + } + BOOST_REQUIRE_EQUAL(true, all_21_produced); + BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); + BOOST_REQUIRE_EQUAL(success(), + push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); + BOOST_REQUIRE(0 < get_balance(producer_names.front()).get_amount()); + } + + BOOST_CHECK_EQUAL( success(), unstake( "producvotera", core_from_string("50.0000"), core_from_string("50.0000") ) ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+6) ) try { + cross_15_percent_threshold(); + + create_accounts_with_resources( { N(donald111111), N(defproducer1), N(defproducer2), N(defproducer3) } ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + + //alice1111111 becomes a producer + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", true) + ) + ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + + //alice1111111 makes stake and votes + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("30.0001"), core_from_string("20.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + BOOST_REQUIRE_EQUAL( success(), push_action( N(donald111111), N(regproxy), mvo() + ("proxy", "donald111111") + ("isproxy", true) + ) + ); + REQUIRE_MATCHING_OBJECT( proxy( "donald111111" ), get_voter_info( "donald111111" ) ); + + //bob111111111 chooses alice1111111 as a proxy + issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //carol1111111 chooses alice1111111 as a proxy + issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("30.0001"), core_from_string("20.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("250.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("250.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //proxied voter carol1111111 increases stake + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("50.0000"), core_from_string("70.0000") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("320.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("370.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("370.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //proxied voter bob111111111 decreases stake + BOOST_REQUIRE_EQUAL( success(), unstake( "bob111111111", core_from_string("50.0001"), core_from_string("50.0001") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("220.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("270.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("270.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //proxied voter carol1111111 chooses another proxy + BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "donald111111" ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0001")), get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("170.0002")), get_voter_info( "donald111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); + + //bob111111111 switches to direct voting and votes for one of the same producers, but not for another one + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); + BOOST_TEST_REQUIRE( 0.0 == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( 0.0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) try { + //alice1111111 becomes a proxy + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", true) + ) + ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + + //carol1111111 becomes a producer + BOOST_REQUIRE_EQUAL( success(), regproducer( "carol1111111", 1) ); + + //bob111111111 chooses alice1111111 as a proxy + + issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot vote for producers and proxy at same time"), + vote( N(bob111111111), { N(carol1111111) }, "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( select_invalid_proxy, eosio_system_tester ) try { + //accumulate proxied votes + issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + + //selecting account not registered as a proxy + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), + vote( N(bob111111111), vector(), "alice1111111" ) ); + + //selecting not existing account as a proxy + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), + vote( N(bob111111111), vector(), "notexist" ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_system_tester ) try { + //alice1111111 becomes a proxy + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", 1) + ) + ); + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("5.0000"), core_from_string("5.0000") ) ); + edump((get_voter_info("alice1111111"))); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + + //bob111111111 stakes and selects alice1111111 as a proxy + issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes( core_from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + + //double regestering should fail without affecting total votes and stake + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), + push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", 1) + ) + ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + + //uregister + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", 0) + ) + ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + + //double unregistering should not affect proxied_votes and stake + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), + push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", 0) + ) + ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( proxy_cannot_use_another_proxy, eosio_system_tester ) try { + //alice1111111 becomes a proxy + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() + ("proxy", "alice1111111") + ("isproxy", 1) + ) + ); + + //bob111111111 becomes a proxy + BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() + ("proxy", "bob111111111") + ("isproxy", 1) + ) + ); + + //proxy should not be able to use a proxy + issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account registered as a proxy is not allowed to use a proxy" ), + vote( N(bob111111111), vector(), "alice1111111" ) ); + + //voter that uses a proxy should not be allowed to become a proxy + issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account that uses a proxy is not allowed to become a proxy" ), + push_action( N(carol1111111), N(regproxy), mvo() + ("proxy", "carol1111111") + ("isproxy", 1) + ) + ); + + //proxy should not be able to use itself as a proxy + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "cannot proxy to self" ), + vote( N(bob111111111), vector(), "bob111111111" ) ); + +} FC_LOG_AND_RETHROW() + +fc::mutable_variant_object config_to_variant( const eosio::chain::chain_config& config ) { + return mutable_variant_object() + ( "max_block_net_usage", config.max_block_net_usage ) + ( "target_block_net_usage_pct", config.target_block_net_usage_pct ) + ( "max_transaction_net_usage", config.max_transaction_net_usage ) + ( "base_per_transaction_net_usage", config.base_per_transaction_net_usage ) + ( "context_free_discount_net_usage_num", config.context_free_discount_net_usage_num ) + ( "context_free_discount_net_usage_den", config.context_free_discount_net_usage_den ) + ( "max_block_cpu_usage", config.max_block_cpu_usage ) + ( "target_block_cpu_usage_pct", config.target_block_cpu_usage_pct ) + ( "max_transaction_cpu_usage", config.max_transaction_cpu_usage ) + ( "min_transaction_cpu_usage", config.min_transaction_cpu_usage ) + ( "max_transaction_lifetime", config.max_transaction_lifetime ) + ( "deferred_trx_expiration_window", config.deferred_trx_expiration_window ) + ( "max_transaction_delay", config.max_transaction_delay ) + ( "max_inline_action_size", config.max_inline_action_size ) + ( "max_inline_action_depth", config.max_inline_action_depth ) + ( "max_authority_depth", config.max_authority_depth ); +} + +BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_tester ) try { + create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + + //stake more than 15% of total EOS supply to activate chain + transfer( "eosio", "alice1111111", core_from_string("600000000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("300000000.0000"), core_from_string("300000000.0000") ) ); + //vote for producers + BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1) } ) ); + produce_blocks(250); + auto producer_keys = control->head_block_state()->active_schedule.producers; + BOOST_REQUIRE_EQUAL( 1, producer_keys.size() ); + BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); + + //auto config = config_to_variant( control->get_global_properties().configuration ); + //auto prod1_config = testing::filter_fields( config, producer_parameters_example( 1 ) ); + //REQUIRE_EQUAL_OBJECTS(prod1_config, config); + + // elect 2 producers + issue( "bob111111111", core_from_string("80000.0000"), config::system_account_name ); + ilog("stake"); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("40000.0000"), core_from_string("40000.0000") ) ); + ilog("start vote"); + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); + ilog("."); + produce_blocks(250); + producer_keys = control->head_block_state()->active_schedule.producers; + BOOST_REQUIRE_EQUAL( 2, producer_keys.size() ); + BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); + BOOST_REQUIRE_EQUAL( name("defproducer2"), producer_keys[1].producer_name ); + //config = config_to_variant( control->get_global_properties().configuration ); + //auto prod2_config = testing::filter_fields( config, producer_parameters_example( 2 ) ); + //REQUIRE_EQUAL_OBJECTS(prod2_config, config); + + // elect 3 producers + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2), N(defproducer3) } ) ); + produce_blocks(250); + producer_keys = control->head_block_state()->active_schedule.producers; + BOOST_REQUIRE_EQUAL( 3, producer_keys.size() ); + BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); + BOOST_REQUIRE_EQUAL( name("defproducer2"), producer_keys[1].producer_name ); + BOOST_REQUIRE_EQUAL( name("defproducer3"), producer_keys[2].producer_name ); + //config = config_to_variant( control->get_global_properties().configuration ); + //REQUIRE_EQUAL_OBJECTS(prod2_config, config); + + // try to go back to 2 producers and fail + BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer3) } ) ); + produce_blocks(250); + producer_keys = control->head_block_state()->active_schedule.producers; + BOOST_REQUIRE_EQUAL( 3, producer_keys.size() ); + + // The test below is invalid now, producer schedule is not updated if there are + // fewer producers in the new schedule + /* + BOOST_REQUIRE_EQUAL( 2, producer_keys.size() ); + BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); + BOOST_REQUIRE_EQUAL( name("defproducer3"), producer_keys[1].producer_name ); + //config = config_to_variant( control->get_global_properties().configuration ); + //auto prod3_config = testing::filter_fields( config, producer_parameters_example( 3 ) ); + //REQUIRE_EQUAL_OBJECTS(prod3_config, config); + */ + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { + create_accounts_with_resources( { N(dan), N(sam) } ); + transfer( config::system_account_name, "dan", core_from_string( "10000.0000" ) ); + transfer( config::system_account_name, "sam", core_from_string( "10000.0000" ) ); + stake_with_transfer( config::system_account_name, "sam", core_from_string( "80000000.0000" ), core_from_string( "80000000.0000" ) ); + + regproducer( config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), vote( N(sam), { config::system_account_name } ) ); + // wait 14 days after min required amount has been staked + produce_block( fc::days(14) ); + produce_block(); + + BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(fail) }, N(dan) ), // dan shouldn't be able to create fail + eosio_assert_message_exception, eosio_assert_message_is( "no active bid for name" ) ); + bidname( "dan", "nofail", core_from_string( "1.0000" ) ); + BOOST_REQUIRE_EQUAL( "assertion failure with message: must increase bid by 10%", bidname( "sam", "nofail", core_from_string( "1.0000" ) )); // didn't increase bid by 10% + BOOST_REQUIRE_EQUAL( success(), bidname( "sam", "nofail", core_from_string( "2.0000" ) )); // didn't increase bid by 10% + produce_block( fc::days(1) ); + produce_block(); + + BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(nofail) }, N(dan) ), // dan shoudn't be able to do this, sam won + eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); + //wlog( "verify sam can create nofail" ); + create_accounts_with_resources( { N(nofail) }, N(sam) ); // sam should be able to do this, he won the bid + //wlog( "verify nofail can create test.nofail" ); + transfer( "eosio", "nofail", core_from_string( "1000.0000" ) ); + create_accounts_with_resources( { N(test.nofail) }, N(nofail) ); // only nofail can create test.nofail + //wlog( "verify dan cannot create test.fail" ); + BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(test.fail) }, N(dan) ), // dan shouldn't be able to do this + eosio_assert_message_exception, eosio_assert_message_is( "only suffix may create this account" ) ); + + create_accounts_with_resources( { N(goodgoodgood) }, N(dan) ); /// 12 char names should succeed +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { + + const std::string not_closed_message("auction for name is not closed yet"); + + std::vector accounts = { N(alice), N(bob), N(carl), N(david), N(eve) }; + create_accounts_with_resources( accounts ); + for ( const auto& a: accounts ) { + transfer( config::system_account_name, a, core_from_string( "10000.0000" ) ); + BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance(a) ); + } + create_accounts_with_resources( { N(producer) } ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(producer) ) ); + + produce_block(); + // stake but but not enough to go live + stake_with_transfer( config::system_account_name, "bob", core_from_string( "35000000.0000" ), core_from_string( "35000000.0000" ) ); + stake_with_transfer( config::system_account_name, "carl", core_from_string( "35000000.0000" ), core_from_string( "35000000.0000" ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(bob), { N(producer) } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(carl), { N(producer) } ) ); + + // start bids + bidname( "bob", "prefa", core_from_string("1.0003") ); + BOOST_REQUIRE_EQUAL( core_from_string( "9998.9997" ), get_balance("bob") ); + bidname( "bob", "prefb", core_from_string("1.0000") ); + bidname( "bob", "prefc", core_from_string("1.0000") ); + BOOST_REQUIRE_EQUAL( core_from_string( "9996.9997" ), get_balance("bob") ); + + bidname( "carl", "prefd", core_from_string("1.0000") ); + bidname( "carl", "prefe", core_from_string("1.0000") ); + BOOST_REQUIRE_EQUAL( core_from_string( "9998.0000" ), get_balance("carl") ); + + BOOST_REQUIRE_EQUAL( error("assertion failure with message: account is already highest bidder"), + bidname( "bob", "prefb", core_from_string("1.1001") ) ); + BOOST_REQUIRE_EQUAL( error("assertion failure with message: must increase bid by 10%"), + bidname( "alice", "prefb", core_from_string("1.0999") ) ); + BOOST_REQUIRE_EQUAL( core_from_string( "9996.9997" ), get_balance("bob") ); + BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance("alice") ); + + // alice outbids bob on prefb + { + const asset initial_names_balance = get_balance(N(eosio.names)); + BOOST_REQUIRE_EQUAL( success(), + bidname( "alice", "prefb", core_from_string("1.1001") ) ); + BOOST_REQUIRE_EQUAL( core_from_string( "9997.9997" ), get_balance("bob") ); + BOOST_REQUIRE_EQUAL( core_from_string( "9998.8999" ), get_balance("alice") ); + BOOST_REQUIRE_EQUAL( initial_names_balance + core_from_string("0.1001"), get_balance(N(eosio.names)) ); + } + + // david outbids carl on prefd + { + BOOST_REQUIRE_EQUAL( core_from_string( "9998.0000" ), get_balance("carl") ); + BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance("david") ); + BOOST_REQUIRE_EQUAL( success(), + bidname( "david", "prefd", core_from_string("1.9900") ) ); + BOOST_REQUIRE_EQUAL( core_from_string( "9999.0000" ), get_balance("carl") ); + BOOST_REQUIRE_EQUAL( core_from_string( "9998.0100" ), get_balance("david") ); + } + + // eve outbids carl on prefe + { + BOOST_REQUIRE_EQUAL( success(), + bidname( "eve", "prefe", core_from_string("1.7200") ) ); + } + + produce_block( fc::days(14) ); + produce_block(); + + // highest bid is from david for prefd but no bids can be closed yet + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefd), N(david) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + + // stake enough to go above the 15% threshold + stake_with_transfer( config::system_account_name, "alice", core_from_string( "10000000.0000" ), core_from_string( "10000000.0000" ) ); + BOOST_REQUIRE_EQUAL(0, get_producer_info("producer")["unpaid_blocks"].as()); + BOOST_REQUIRE_EQUAL( success(), vote( N(alice), { N(producer) } ) ); + + // need to wait for 14 days after going live + produce_blocks(10); + produce_block( fc::days(2) ); + produce_blocks( 10 ); + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefd), N(david) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + // it's been 14 days, auction for prefd has been closed + produce_block( fc::days(12) ); + create_account_with_resources( N(prefd), N(david) ); + produce_blocks(2); + produce_block( fc::hours(23) ); + // auctions for prefa, prefb, prefc, prefe haven't been closed + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefa), N(bob) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(alice) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefc), N(bob) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefe), N(eve) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + // attemp to create account with no bid + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefg), N(alice) ), + fc::exception, fc_assert_exception_message_is( "no active bid for name" ) ); + // changing highest bid pushes auction closing time by 24 hours + BOOST_REQUIRE_EQUAL( success(), + bidname( "eve", "prefb", core_from_string("2.1880") ) ); + + produce_block( fc::hours(22) ); + produce_blocks(2); + + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(eve) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + // but changing a bid that is not the highest does not push closing time + BOOST_REQUIRE_EQUAL( success(), + bidname( "carl", "prefe", core_from_string("2.0980") ) ); + produce_block( fc::hours(2) ); + produce_blocks(2); + // bid for prefb has closed, only highest bidder can claim + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(alice) ), + eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(carl) ), + eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); + create_account_with_resources( N(prefb), N(eve) ); + + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefe), N(carl) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + produce_block(); + produce_block( fc::hours(24) ); + // by now bid for prefe has closed + create_account_with_resources( N(prefe), N(carl) ); + // prefe can now create *.prefe + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(xyz.prefe), N(carl) ), + fc::exception, fc_assert_exception_message_is("only suffix may create this account") ); + transfer( config::system_account_name, N(prefe), core_from_string("10000.0000") ); + create_account_with_resources( N(xyz.prefe), N(prefe) ); + + // other auctions haven't closed + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefa), N(bob) ), + fc::exception, fc_assert_exception_message_is( not_closed_message ) ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; + for (const auto& v: voters) { + create_account_with_resources(v, config::system_account_name, core_from_string("1.0000"), false, net, cpu); + } + + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'z'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + setup_producer_accounts(producer_names); + for (const auto& p: producer_names) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + produce_blocks(1); + ilog( "------ get pro----------" ); + wdump((p)); + BOOST_TEST(0 == get_producer_info(p)["total_votes"].as()); + } + } + + for (const auto& v: voters) { + transfer( config::system_account_name, v, core_from_string("200000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + } + + { + BOOST_REQUIRE_EQUAL(success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+20))); + BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); + BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.end()))); + } + + // give a chance for everyone to produce blocks + { + produce_blocks(23 * 12 + 20); + bool all_21_produced = true; + for (uint32_t i = 0; i < 21; ++i) { + if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + all_21_produced = false; + } + } + bool rest_didnt_produce = true; + for (uint32_t i = 21; i < producer_names.size(); ++i) { + if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { + rest_didnt_produce = false; + } + } + BOOST_REQUIRE(all_21_produced && rest_didnt_produce); + } + + { + produce_block(fc::hours(7)); + const uint32_t voted_out_index = 20; + const uint32_t new_prod_index = 23; + BOOST_REQUIRE_EQUAL(success(), stake("producvoterd", core_from_string("40000000.0000"), core_from_string("40000000.0000"))); + BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), { producer_names[new_prod_index] })); + BOOST_REQUIRE_EQUAL(0, get_producer_info(producer_names[new_prod_index])["unpaid_blocks"].as()); + produce_blocks(4 * 12 * 21); + BOOST_REQUIRE(0 < get_producer_info(producer_names[new_prod_index])["unpaid_blocks"].as()); + const uint32_t initial_unpaid_blocks = get_producer_info(producer_names[voted_out_index])["unpaid_blocks"].as(); + produce_blocks(2 * 12 * 21); + BOOST_REQUIRE_EQUAL(initial_unpaid_blocks, get_producer_info(producer_names[voted_out_index])["unpaid_blocks"].as()); + produce_block(fc::hours(24)); + BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), { producer_names[voted_out_index] })); + produce_blocks(2 * 12 * 21); + BOOST_REQUIRE(fc::crypto::public_key() != fc::crypto::public_key(get_producer_info(producer_names[voted_out_index])["producer_key"].as_string())); + BOOST_REQUIRE_EQUAL(success(), push_action(producer_names[voted_out_index], N(claimrewards), mvo()("owner", producer_names[voted_out_index]))); + } + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { + //install multisig contract + abi_serializer msig_abi_ser = initialize_multisig(); + auto producer_names = active_and_vote_producers(); + + //helper function + auto push_action_msig = [&]( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) -> action_result { + string action_type_name = msig_abi_ser.get_action_type(name); + + action act; + act.account = N(eosio.msig); + act.name = name; + act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + + return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + }; + + // test begins + vector prod_perms; + for ( auto& x : producer_names ) { + prod_perms.push_back( { name(x), config::active_name } ); + } + + eosio::chain::chain_config params; + params = control->get_global_properties().configuration; + //change some values + params.max_block_net_usage += 10; + params.max_transaction_lifetime += 1; + + transaction trx; + { + variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", 0) + ("actions", fc::variants({ + fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("name", "setparams") + ("authorization", vector{ { config::system_account_name, config::active_name } }) + ("data", fc::mutable_variant_object() + ("params", params) + ) + }) + ); + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + } + + BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() + ("proposer", "alice1111111") + ("proposal_name", "setparams1") + ("trx", trx) + ("requested", prod_perms) + ) + ); + + // get 16 approvals + for ( size_t i = 0; i < 15; ++i ) { + BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[i]), N(approve), mvo() + ("proposer", "alice1111111") + ("proposal_name", "setparams1") + ("level", permission_level{ name(producer_names[i]), config::active_name }) + ) + ); + } + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() + ("proposer", "alice1111111") + ("proposal_name", "setparams1") + ("executer", "alice1111111") + ) + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); + + produce_blocks( 250 ); + + // make sure that changed parameters were applied + auto active_params = control->get_global_properties().configuration; + BOOST_REQUIRE_EQUAL( params.max_block_net_usage, active_params.max_block_net_usage ); + BOOST_REQUIRE_EQUAL( params.max_transaction_lifetime, active_params.max_transaction_lifetime ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { + + const asset net = core_from_string("8.0000"); + const asset cpu = core_from_string("8.0000"); + std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + for (const auto& a: accounts) { + create_account_with_resources(a, config::system_account_name, core_from_string("1.0000"), false, net, cpu); + } + + { + const auto name_a = accounts[0]; + transfer( config::system_account_name, name_a, core_from_string("1000.0000") ); + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance(name_a) ); + const uint64_t init_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64(); + BOOST_REQUIRE_EQUAL( success(), buyram( name_a, name_a, core_from_string("300.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance(name_a) ); + const uint64_t bought_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64() - init_bytes_a; + + // after buying and selling balance should be 700 + 300 * 0.995 * 0.995 = 997.0075 + BOOST_REQUIRE_EQUAL( success(), sellram(name_a, bought_bytes_a ) ); + BOOST_REQUIRE_EQUAL( core_from_string("997.0075"), get_balance(name_a) ); + } + + { + const auto name_b = accounts[1]; + transfer( config::system_account_name, name_b, core_from_string("1000.0000") ); + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance(name_b) ); + const uint64_t init_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64(); + // name_b buys ram at current price + BOOST_REQUIRE_EQUAL( success(), buyram( name_b, name_b, core_from_string("300.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance(name_b) ); + const uint64_t bought_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64() - init_bytes_b; + + // increase max_ram_size, ram bought by name_b loses part of its value + BOOST_REQUIRE_EQUAL( wasm_assert_msg("ram may only be increased"), + push_action(config::system_account_name, N(setram), mvo()("max_ram_size", 64ll*1024 * 1024 * 1024)) ); + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), + push_action(name_b, N(setram), mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); + BOOST_REQUIRE_EQUAL( success(), + push_action(config::system_account_name, N(setram), mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); + + BOOST_REQUIRE_EQUAL( success(), sellram(name_b, bought_bytes_b ) ); + BOOST_REQUIRE( core_from_string("900.0000") < get_balance(name_b) ); + BOOST_REQUIRE( core_from_string("950.0000") > get_balance(name_b) ); + } + +} FC_LOG_AND_RETHROW() +#endif +BOOST_AUTO_TEST_SUITE_END() + +void translate_fc_exception(const fc::exception &e) { + std::cerr << "\033[33m" << e.to_detail_string() << "\033[0m" << std::endl; + BOOST_TEST_FAIL("Caught Unexpected Exception"); +} + +boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { + // Turn off blockchain logging if no --verbose parameter is not added + // To have verbose enabled, call "tests/chain_test -- --verbose" + bool is_verbose = false; + std::string verbose_arg = "--verbose"; + for (int i = 0; i < argc; i++) { + if (verbose_arg == argv[i]) { + is_verbose = true; + break; + } + } + if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + + // Register fc::exception translator + boost::unit_test::unit_test_monitor.register_exception_translator(&translate_fc_exception); + + std::srand(time(NULL)); + std::cout << "Random number generator seeded to " << time(NULL) << std::endl; + return nullptr; +} From a95fe7b1f7dcc129c2cd0b85839b3bc4d97d8da4 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 25 Jun 2018 18:16:57 -0400 Subject: [PATCH 0388/1048] Changes added to build scripts and now building tests --- build.sh | 30 +++ deps/eosio.exchange | 2 +- deps/eosio.token | 2 +- src/delegate_bandwidth.cpp | 27 +- src/eosio.system.cpp | 4 + tests/CMakeLists.txt | 46 ++-- ..._tester.hpp => eosio.system_tester.hpp.in} | 31 +-- tests/eosio.system_tests.cpp | 234 ++++++++++++++---- 8 files changed, 274 insertions(+), 102 deletions(-) rename tests/{eosio.system_tester.hpp => eosio.system_tester.hpp.in} (95%) diff --git a/build.sh b/build.sh index 14750842..87ec8d81 100755 --- a/build.sh +++ b/build.sh @@ -5,9 +5,11 @@ unamestr=`uname` if [[ "${unamestr}" == 'Darwin' ]]; then PREFIX=/usr/local + OPENSSL=/usr/local/opt/openssl else PREFIX=~/opt BOOST=~/opt/boost/include + OPENSSL=/usr/include/openssl fi mkdir -p bin/${CONTRACT_NAME} @@ -17,6 +19,17 @@ LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" S2W="/usr/local/bin/eosio-s2wasm " W2W="/usr/local/bin/eosio-wast2wasm " + +deps=( "eosio.token" ) # "eosio.exchange" ) + +for dep in "${deps[@]}"; do + echo "building ${dep}" + pushd ./deps/${dep} &> /dev/null + ./build.sh notests + popd &> /dev/null +done + +echo "building eosio.system" ${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp ${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc ${LLC} -o ${CONTRACT_NAME}.s linked.bc @@ -24,6 +37,22 @@ ${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s ${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi +if [[ "$1" == 'notests' ]]; then + rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s + exit 0 +fi + +contract_dir=`pwd` +pushd tests &> /dev/null +mkdir build +pushd build &> /dev/null +cmake -DCONTRACT_DIR="${contract_dir}" -DEOSIO_INSTALL_PREFIX="/usr/local" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="/usr/local" ../ +make -j8 +popd &> /dev/null +popd &> /dev/null +cp tests/build/unit_test bin/ +rm -r tests/build + if [[ "$1" == 'noinstall' ]]; then rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s exit 0 @@ -31,5 +60,6 @@ fi ### INSTALL THE HEADERS cp -r include/* /usr/local/include +cp build/unit_tests bin/ rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/deps/eosio.exchange b/deps/eosio.exchange index 788ecb31..abef55f3 160000 --- a/deps/eosio.exchange +++ b/deps/eosio.exchange @@ -1 +1 @@ -Subproject commit 788ecb31eb31ec85434c7eff5ed23da27d48bf67 +Subproject commit abef55f39ea50f950d27bded0e81629c01f7cafd diff --git a/deps/eosio.token b/deps/eosio.token index abbfe787..6ef029d9 160000 --- a/deps/eosio.token +++ b/deps/eosio.token @@ -1 +1 @@ -Subproject commit abbfe7872e42523e77325b0ae018664b8b212d9c +Subproject commit 6ef029d9fc0309033ee6a433834abc19af9f0b75 diff --git a/src/delegate_bandwidth.cpp b/src/delegate_bandwidth.cpp index fe296fef..d19be4c6 100644 --- a/src/delegate_bandwidth.cpp +++ b/src/delegate_bandwidth.cpp @@ -152,11 +152,11 @@ namespace eosiosystem { set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } - - /** - * While buying ram uses the current market price according to the bancor-algorithm, selling ram only - * refunds the purchase price to the account. In this way there is no profit to be made through buying - * and selling ram. + /** + * The system contract now buys and sells RAM allocations at prevailing market prices. + * This may result in traders buying RAM today in anticipation of potential shortages + * tomorrow. Overall this will result in the market balancing the supply and demand + * for RAM over time. */ void system_contract::sellram( account_name account, int64_t bytes ) { require_auth( account ); @@ -207,6 +207,9 @@ namespace eosiosystem { { require_auth( from ); eosio_assert( stake_net_delta != asset(0) || stake_cpu_delta != asset(0), "should stake non-zero amount" ); + eosio_assert( std::abs( (stake_net_delta + stake_cpu_delta).amount ) + >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), + "net and cpu deltas cannot be opposite signs" ); account_name source_stake_from = from; if ( transfer ) { @@ -273,8 +276,14 @@ namespace eosiosystem { auto net_balance = stake_net_delta; auto cpu_balance = stake_cpu_delta; bool need_deferred_trx = false; - if ( req != refunds_tbl.end() ) { //need to update refund - refunds_tbl.modify( req, 0, [&]( refund_request& r ) { + // net and cpu are same sign by assertions in delegatebw and undelegatebw + // redundant assertion also at start of changebw to protect against misuse of changebw + bool is_undelegating = (net_balance.amount + cpu_balance.amount ) < 0; + bool is_delegating_to_self = (!transfer && from == receiver); + + if( is_delegating_to_self || is_undelegating ) { + if ( req != refunds_tbl.end() ) { //need to update refund + refunds_tbl.modify( req, 0, [&]( refund_request& r ) { if ( net_balance < asset(0) || cpu_balance < asset(0) ) { r.request_time = now(); } @@ -293,6 +302,7 @@ namespace eosiosystem { cpu_balance = asset(0); } }); + eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen eosio_assert( asset(0) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen @@ -317,6 +327,7 @@ namespace eosiosystem { }); need_deferred_trx = true; } // else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl + } if ( need_deferred_trx ) { eosio::transaction out; @@ -366,7 +377,7 @@ namespace eosiosystem { eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); eosio_assert( stake_net_quantity + stake_cpu_quantity > asset(0), "must stake a positive amount" ); - + eosio_assert( !transfer || from != receiver, "cannot use transfer flag if delegating to self" ); changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); } // delegatebw diff --git a/src/eosio.system.cpp b/src/eosio.system.cpp index fe560725..a38a4a4f 100644 --- a/src/eosio.system.cpp +++ b/src/eosio.system.cpp @@ -97,6 +97,10 @@ namespace eosiosystem { void system_contract::bidname( account_name bidder, account_name newname, asset bid ) { require_auth( bidder ); eosio_assert( eosio::name_suffix(newname) == newname, "you can only bid on top-level suffix" ); + + eosio_assert( newname != 0, "the empty name is not a valid account name to bid on" ); + eosio_assert( (newname & 0xFull) == 0, "13 character names are not valid account names to bid on" ); + eosio_assert( (newname & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); eosio_assert( !is_account( newname ), "account already exists" ); eosio_assert( bid.symbol == asset().symbol, "asset must be system token" ); eosio_assert( bid.amount > 0, "insufficient bid" ); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 68799b09..9da6ba85 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,23 +11,30 @@ find_package(LLVM 4.0 REQUIRED CONFIG) link_directories(${LLVM_LIBRARY_DIR}) set( CMAKE_CXX_STANDARD 14 ) - -find_package(Boost 1.67 REQUIRED) -#add_subdirectory(contracts) +configure_file(${CMAKE_SOURCE_DIR}/eosio.system_tester.hpp.in ${CMAKE_SOURCE_DIR}/eosio.system_tester.hpp) +find_package(Boost 1.67 REQUIRED COMPONENTS date_time filesystem system chrono iostreams date_time) file(GLOB UNIT_TESTS "*.cpp") -find_library(libtester eosio_testing /usr/local/lib) -find_library(libchain eosio_chain /usr/local/lib) -find_library(libfc fc /usr/local/lib) -find_library(libwasm WASM /usr/local/lib) -find_library(libwast WAST /usr/local/lib) -find_library(libir IR /usr/local/lib) -find_library(libruntime Runtime /usr/local/lib) -find_library(libsoftfloat softfloat /usr/local/lib) +find_library(libtester eosio_testing ) +find_library(libchain eosio_chain ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libfc fc ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libbinaryen binaryen ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libwasm WASM ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libwast WAST ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libir IR ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libplatform Platform ${EOSIO_INSTALL_PREFIX}/lib) +find_library(liblogging Logging ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libruntime Runtime ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libsoftfloat softfloat ${EOSIO_INSTALL_PREFIX}/lib) +find_library(liboscrypto crypto ${OPENSSL_INSTALL_LIB}) +find_library(libosssl ssl ${OPENSSL_INSTALL_LIB}) +find_library(libchainbase chainbase ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libbuiltins builtins ${EOSIO_INSTALL_PREFIX}/lib) +find_library(libsecp256k1 secp256k1 ${SECP256K1_INSTALL_LIB}) add_executable( unit_test ${UNIT_TESTS} ) -target_link_libraries( unit_test ${LLVM} ${libchain} ${libtester} ${libfc} ${libir} ${libwast} ${libwasm} ${libruntime} ${libsoftfloat} ${PLATFORM_SPECIFIC_LIBS} +target_link_libraries( unit_test ${LLVM} ${libchain} ${libtester} ${libfc} ${libir} ${libplatform} ${libbinaryen} ${libwast} ${libwasm} ${libruntime} ${libsoftfloat} ${liboscrypto} ${libosssl} ${liblogging} ${libchainbase} ${libbuiltins} ${libsecp256k1} ${PLATFORM_SPECIFIC_LIBS} LLVMX86Disassembler LLVMX86AsmParser LLVMX86AsmPrinter @@ -35,6 +42,7 @@ target_link_libraries( unit_test ${LLVM} ${libchain} ${libtester} ${libfc} ${lib LLVMSelectionDAG + LLVMDebugInfoDWARF LLVMAsmPrinter LLVMMCParser LLVMX86Info @@ -50,18 +58,22 @@ target_link_libraries( unit_test ${LLVM} ${libchain} ${libtester} ${libfc} ${lib LLVMAnalysis LLVMTarget LLVMMC - LLVMCore LLVMSupport + ${Boost_FILESYSTEM_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${Boost_CHRONO_LIBRARY} + ${Boost_IOSTREAMS_LIBRARY} + ${Boost_DATE_TIME_LIBRARY} ) target_include_directories( unit_test PUBLIC ${Boost_INCLUDE_DIRS} - /usr/local/include - /usr/local/include/eosio/wasm-jit/Include - /usr/local/include/eosio/softfloat/include + ${OPENSSL_INSTALL_PREFIX}/include + ${EOSIO_INSTALL_PREFIX}/include + ${EOSIO_INSTALL_PREFIX}/include/eosio/wasm-jit/Include + ${EOSIO_INSTALL_PREFIX}/include/eosio/softfloat/include ${CMAKE_CURRENT_BINARY_DIR}/include ) - #add_dependencies(unit_test asserter test_api test_api_mem test_api_db test_ram_limit test_api_multi_index exchange eosio.token proxy identity identity_test stltest infinite eosio.system eosio.token eosio.bios test.inline multi_index_test noop dice eosio.msig payloadless tic_tac_toe deferred_test) #Manually run unit_test for all supported runtimes #To run unit_test with all log from blockchain displayed, put --verbose after --, i.e. unit_test -- --verbose diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp.in similarity index 95% rename from tests/eosio.system_tester.hpp rename to tests/eosio.system_tester.hpp.in index 526370b7..a12e9068 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp.in @@ -26,29 +26,6 @@ using mvo = fc::mutable_variant_object; namespace eosio_system { -std::vector read_wasm( const char* fn ) { - std::ifstream wasm_file(fn, std::ios::binary); - wasm_file.seekg(0, std::ios::end); - std::vector wasm; - wasm.resize(wasm_file.tellg()); - wasm_file.seekg(0, std::ios::beg); - wasm_file.read((char*)wasm.data(), wasm.size()); - wasm_file.close(); - return wasm; -} -std::vector read_abi( const char* fn ) { - std::ifstream abi_file(fn); - abi_file.seekg(0, std::ios::end); - std::vector abi; - abi.resize(abi_file.tellg()+1); - abi_file.seekg(0, std::ios::beg); - abi_file.read(abi.data(), abi.size()); - abi[abi.size()-1] = '\0'; - abi_file.close(); - return abi; -} - - class eosio_system_tester : public TESTER { public: @@ -69,8 +46,8 @@ class eosio_system_tester : public TESTER { //const auto eosio_token = read_wasm("../deps/eosio.token/bin/eosio.token/eosio.token.wasm"); //const auto eosio_token_abi = read_abi("../deps/eosio.token/bin/eosio.token/eosio.token.abi"); - set_code( N(eosio.token), read_wasm("../deps/eosio.token/bin/eosio.token/eosio.token.wasm") ); - set_abi( N(eosio.token), read_abi("../deps/eosio.token/bin/eosio.token/eosio.token.abi").data() ); + set_code( N(eosio.token), read_wasm("${CONTRACT_DIR}/deps/eosio.token/bin/eosio.token/eosio.token.wasm") ); + set_abi( N(eosio.token), read_abi("${CONTRACT_DIR}/deps/eosio.token/bin/eosio.token/eosio.token.abi").data() ); { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; @@ -82,8 +59,8 @@ class eosio_system_tester : public TESTER { issue(config::system_account_name, core_from_string("1000000000.0000")); BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance( "eosio" ) ); - set_code( config::system_account_name, read_wasm("../bin/eosio.system/eosio.system.wasm") ); - set_abi( config::system_account_name, read_abi("../bin/eosio.system/eosio.system.abi").data() ); + set_code( config::system_account_name, read_wasm("${CONTRACT_DIR}/bin/eosio.system/eosio.system.wasm") ); + set_abi( config::system_account_name, read_abi("${CONTRACT_DIR}/bin/eosio.system/eosio.system.abi").data() ); { const auto& accnt = control->db().get( config::system_account_name ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0ea2b89a..a808afa6 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -8,7 +8,6 @@ #include #include #include - #include #include "eosio.system_tester.hpp" @@ -42,19 +41,19 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, 0 < bought_bytes ); BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("998.0050"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("998.0049"), get_balance( "alice1111111" ) ); total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); transfer( "eosio", "alice1111111", core_from_string("100000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( core_from_string("100000998.0050"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("100000998.0049"), get_balance( "alice1111111" ) ); // alice buys ram for 10000000.0000, 0.5% = 50000.0000 go to ramfee // after fee 9950000.0000 go to bought bytes // when selling back bought bytes, pay 0.5% fee and get back 99.5% of 9950000.0000 = 9900250.0000 - // expected account after that is 90000998.0050 + 9900250.0000 = 99901248.0050 with a difference + // expected account after that is 90000998.0049 + 9900250.0000 = 99901248.0049 with a difference // of order 0.0001 due to rounding errors BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("90000998.0050"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("90000998.0049"), get_balance( "alice1111111" ) ); total = get_total_stake( "alice1111111" ); bytes = total["ram_bytes"].as_uint64(); @@ -69,8 +68,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { wdump((init_bytes)(bought_bytes)(bytes) ); BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - BOOST_REQUIRE_EQUAL( core_from_string("99901248.0044"), get_balance( "alice1111111" ) ); - + BOOST_REQUIRE_EQUAL( core_from_string("99901248.0041"), get_balance( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); @@ -81,7 +79,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99900688.0044"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99900688.0041"), get_balance( "alice1111111" ) ); auto newtotal = get_total_stake( "alice1111111" ); @@ -90,7 +88,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { wdump((newbytes)(bytes)(bought_bytes) ); BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99901242.4183"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99901242.4179"), get_balance( "alice1111111" ) ); newtotal = get_total_stake( "alice1111111" ); @@ -105,7 +103,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("300000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("49301242.4183"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("49301242.4179"), get_balance( "alice1111111" ) ); auto finaltotal = get_total_stake( "alice1111111" ); auto endbytes = finaltotal["ram_bytes"].as_uint64(); @@ -115,7 +113,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99396507.4147"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99396507.4142"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() @@ -218,7 +216,72 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("400.0000"), core_from_string("200.0000") ) ); BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); - edump((get_balance( "eosio.stake" ))); + produce_block( fc::hours(3*24-1) ); + produce_blocks(1); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + //after 3 days funds should be released + + produce_block( fc::hours(1) ); + produce_blocks(1); + + BOOST_REQUIRE_EQUAL( core_from_string("1300.0000"), get_balance( "alice1111111" ) ); + + //stake should be equal to what was staked in constructor, voting power should be 0 + total = get_total_stake("alice1111111"); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("0.0000")), get_voter_info( "alice1111111" ) ); + + // Now alice stakes to bob with transfer flag + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("100.0000") ) ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try { + cross_15_percent_threshold(); + + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot use transfer flag if delegating to self"), + stake_with_transfer( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) + ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "eosio", core_from_string("1000.0000"), config::system_account_name ); + issue( "eosio.stake", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + + //eosio stakes for alice with transfer flag + + transfer( "eosio", "bob111111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + //check that alice has both bandwidth and voting power + auto total = get_total_stake("alice1111111"); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000")), get_voter_info( "alice1111111" ) ); + + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + + //alice stakes for herself + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + //now alice's stake should be equal to transfered from eosio + own stake + total = get_total_stake("alice1111111"); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("410.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("600.0000")), get_voter_info( "alice1111111" ) ); + + //alice can unstake everything (including what was transfered) + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("400.0000"), core_from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); produce_block( fc::hours(3*24-1) ); produce_blocks(1); @@ -230,7 +293,7 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try BOOST_REQUIRE_EQUAL( core_from_string("1300.0000"), get_balance( "alice1111111" ) ); - //stake should be equal to what was staked in constructor, votring power should be 0 + //stake should be equal to what was staked in constructor, voting power should be 0 total = get_total_stake("alice1111111"); BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); @@ -498,30 +561,47 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { cross_15_percent_threshold(); issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); - auto total = get_total_stake( "bob111111111" ); + auto total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("50.0000") ) ); - //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); + + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("400.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("600.0000"), get_balance( "alice1111111" ) ); + + //unstake a share + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("150.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("250.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("600.0000"), get_balance( "alice1111111" ) ); auto refund = get_refund_request( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_from_string( "50.0000"), refund["cpu_amount"].as() ); //XXX auto request_time = refund["request_time"].as_int64(); - //stake less than pending refund, entire amount should be traken from refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); - total = get_total_stake( "bob111111111" ); + //alice delegates to bob, should pull from liquid balance not refund + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("50.0000") ) ); + total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("350.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + refund = get_refund_request( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string( "50.0000"), refund["cpu_amount"].as() ); + + //stake less than pending refund, entire amount should be taken from refund + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_from_string("85.0000"), total["cpu_weight"].as()); refund = get_refund_request( "alice1111111" ); @@ -529,42 +609,77 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("25.0000"), refund["cpu_amount"].as() ); //request time should stay the same //BOOST_REQUIRE_EQUAL( request_time, refund["request_time"].as_int64() ); - //balance shoud stay the same - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + //balance should stay the same + BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); //stake exactly pending refund amount - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); - total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); //pending refund should be removed refund = get_refund_request( "alice1111111" ); BOOST_TEST_REQUIRE( refund.is_null() ); - //balance shoud stay the same - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + //balance should stay the same + BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); //create pending refund again - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); - total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); refund = get_refund_request( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); //stake more than pending refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("300.0000"), core_from_string("200.0000") ) ); - total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("300.0000"), core_from_string("200.0000") ) ); + total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("700.0000") ), get_voter_info( "alice1111111" ) ); refund = get_refund_request( "alice1111111" ); BOOST_TEST_REQUIRE( refund.is_null() ); - //200 EOS should be taken from alice's account - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + //200 core tokens should be taken from alice's account + BOOST_REQUIRE_EQUAL( core_from_string("300.0000"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tester ) try { + cross_15_percent_threshold(); + + issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + auto total = get_total_stake( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //unstake + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + auto refund = get_refund_request( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); + //auto orig_request_time = refund["request_time"].as_int64(); + + //stake to another user + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + total = get_total_stake( "bob111111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + //stake should be taken from alices' balance, and refund request should stay the same + BOOST_REQUIRE_EQUAL( core_from_string("400.0000"), get_balance( "alice1111111" ) ); + refund = get_refund_request( "alice1111111" ); + BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); + //BOOST_REQUIRE_EQUAL( orig_request_time, refund["request_time"].as_int64() ); + +} FC_LOG_AND_RETHROW() // Tests for voting BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try { @@ -637,7 +752,6 @@ BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try } FC_LOG_AND_RETHROW() -#if 0 BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { cross_15_percent_threshold(); @@ -1564,7 +1678,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_REQUIRE(prod_was_replaced); } } - + { BOOST_REQUIRE_EQUAL( wasm_assert_msg("producer not found"), push_action( config::system_account_name, N(rmvproducer), mvo()("producer", "nonexistingp") ) ); @@ -1572,6 +1686,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni } FC_LOG_AND_RETHROW() +#if 0 BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { //install multisig contract abi_serializer msig_abi_ser = initialize_multisig(); @@ -1677,7 +1792,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) produce_blocks( 250 ); } FC_LOG_AND_RETHROW() - +#endif BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { @@ -1705,7 +1820,8 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { transfer(config::system_account_name, "producvotera", core_from_string("200000000.0000"), config::system_account_name); BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_from_string("70000000.0000"), core_from_string("70000000.0000") )); BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); - BOOST_CHECK_EQUAL( wasm_assert_msg("not enough has been staked for users to unstake"), unstake( "producvotera", core_from_string("50.0000"), core_from_string("50.0000") ) ); + BOOST_CHECK_EQUAL( wasm_assert_msg( "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ), + unstake( "producvotera", core_from_string("50.0000"), core_from_string("50.0000") ) ); // give a chance for everyone to produce blocks { @@ -1727,11 +1843,12 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { } { + const char* claimrewards_activation_error_message = "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)"; BOOST_CHECK_EQUAL(0, get_global_state()["total_unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("not enough has been staked for producers to claim rewards"), + BOOST_REQUIRE_EQUAL(wasm_assert_msg( claimrewards_activation_error_message ), push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.front()).get_amount()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("not enough has been staked for producers to claim rewards"), + BOOST_REQUIRE_EQUAL(wasm_assert_msg( claimrewards_activation_error_message ), push_action(producer_names.back(), N(claimrewards), mvo()("owner", producer_names.back()))); BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.back()).get_amount()); } @@ -2067,11 +2184,14 @@ BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { transfer( config::system_account_name, "dan", core_from_string( "10000.0000" ) ); transfer( config::system_account_name, "sam", core_from_string( "10000.0000" ) ); stake_with_transfer( config::system_account_name, "sam", core_from_string( "80000000.0000" ), core_from_string( "80000000.0000" ) ); + stake_with_transfer( config::system_account_name, "dan", core_from_string( "80000000.0000" ), core_from_string( "80000000.0000" ) ); regproducer( config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), vote( N(sam), { config::system_account_name } ) ); // wait 14 days after min required amount has been staked - produce_block( fc::days(14) ); + produce_block( fc::days(7) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(dan), { config::system_account_name } ) ); + produce_block( fc::days(7) ); produce_block(); BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(fail) }, N(dan) ), // dan shouldn't be able to create fail @@ -2096,6 +2216,23 @@ BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { create_accounts_with_resources( { N(goodgoodgood) }, N(dan) ); /// 12 char names should succeed } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( bid_invalid_names, eosio_system_tester ) try { + create_accounts_with_resources( { N(dan) } ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "you can only bid on top-level suffix" ), + bidname( "dan", "abcdefg.12345", core_from_string( "1.0000" ) ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "the empty name is not a valid account name to bid on" ), + bidname( "dan", "", core_from_string( "1.0000" ) ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "13 character names are not valid account names to bid on" ), + bidname( "dan", "abcdefgh12345", core_from_string( "1.0000" ) ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "accounts with 12 character names and no dots can be created without bidding required" ), + bidname( "dan", "abcdefg12345", core_from_string( "1.0000" ) ) ); + +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { const std::string not_closed_message("auction for name is not closed yet"); @@ -2311,6 +2448,7 @@ BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +#if 0 BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { //install multisig contract abi_serializer msig_abi_ser = initialize_multisig(); @@ -2401,6 +2539,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( params.max_transaction_lifetime, active_params.max_transaction_lifetime ); } FC_LOG_AND_RETHROW() +#endif BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { @@ -2420,9 +2559,9 @@ BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance(name_a) ); const uint64_t bought_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64() - init_bytes_a; - // after buying and selling balance should be 700 + 300 * 0.995 * 0.995 = 997.0075 + // after buying and selling balance should be 700 + 300 * 0.995 * 0.995 = 997.0075 (actually 997.0074 due to rounding fees up) BOOST_REQUIRE_EQUAL( success(), sellram(name_a, bought_bytes_a ) ); - BOOST_REQUIRE_EQUAL( core_from_string("997.0075"), get_balance(name_a) ); + BOOST_REQUIRE_EQUAL( core_from_string("997.0074"), get_balance(name_a) ); } { @@ -2449,7 +2588,6 @@ BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { } } FC_LOG_AND_RETHROW() -#endif BOOST_AUTO_TEST_SUITE_END() void translate_fc_exception(const fc::exception &e) { @@ -2471,7 +2609,7 @@ boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); // Register fc::exception translator - boost::unit_test::unit_test_monitor.register_exception_translator(&translate_fc_exception); + boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); std::srand(time(NULL)); std::cout << "Random number generator seeded to " << time(NULL) << std::endl; From 7f354317c1d0e4d7d5d6840ba98d61ecf8ffbc3c Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 25 Jun 2018 18:20:52 -0400 Subject: [PATCH 0389/1048] Update .gitmodules --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index e281cede..fab757f5 100644 --- a/.gitmodules +++ b/.gitmodules @@ -3,4 +3,4 @@ url = https://github.com/eosio/eosio.token [submodule "deps/eosio.exchange"] path = deps/eosio.exchange - url = git@github.com:eosio/eosio.exchange + url = https://github.com/eosio/eosio.exchange From 55d4e71a3df07d9b6784a6e6c0321572ca4eada4 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 25 Jun 2018 19:30:47 -0400 Subject: [PATCH 0390/1048] fixed some missing changes from latest commit --- .gitmodules | 3 --- build.sh | 5 ++--- deps/eosio.exchange | 1 - src/delegate_bandwidth.cpp | 41 +++++++++++++++++++++++--------------- src/exchange_state.cpp | 2 +- 5 files changed, 28 insertions(+), 24 deletions(-) delete mode 160000 deps/eosio.exchange diff --git a/.gitmodules b/.gitmodules index e281cede..78239599 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "deps/eosio.token"] path = deps/eosio.token url = https://github.com/eosio/eosio.token -[submodule "deps/eosio.exchange"] - path = deps/eosio.exchange - url = git@github.com:eosio/eosio.exchange diff --git a/build.sh b/build.sh index 87ec8d81..a8ee3175 100755 --- a/build.sh +++ b/build.sh @@ -14,16 +14,15 @@ fi mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -Ideps/eosio.token/include -Ideps/eosio.exchange/include -I${BOOST}" +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -Ideps/eosio.token/include -I${BOOST}" LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" S2W="/usr/local/bin/eosio-s2wasm " W2W="/usr/local/bin/eosio-wast2wasm " -deps=( "eosio.token" ) # "eosio.exchange" ) +deps=( "eosio.token" ) for dep in "${deps[@]}"; do - echo "building ${dep}" pushd ./deps/${dep} &> /dev/null ./build.sh notests popd &> /dev/null diff --git a/deps/eosio.exchange b/deps/eosio.exchange deleted file mode 160000 index abef55f3..00000000 --- a/deps/eosio.exchange +++ /dev/null @@ -1 +0,0 @@ -Subproject commit abef55f39ea50f950d27bded0e81629c01f7cafd diff --git a/src/delegate_bandwidth.cpp b/src/delegate_bandwidth.cpp index d19be4c6..9678c28e 100644 --- a/src/delegate_bandwidth.cpp +++ b/src/delegate_bandwidth.cpp @@ -152,6 +152,7 @@ namespace eosiosystem { set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } + /** * The system contract now buys and sells RAM allocations at prevailing market prices. * This may result in traders buying RAM today in anticipation of potential shortages @@ -173,6 +174,8 @@ namespace eosiosystem { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); }); + + eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); _gstate.total_ram_bytes_reserved -= static_cast(bytes); // bytes > 0 is asserted above _gstate.total_ram_stake -= tokens_out.amount; @@ -187,7 +190,10 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.ram),N(active)}, { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); - auto fee = tokens_out.amount / 200; + + auto fee = ( tokens_out.amount + 199 ) / 200; /// .5% fee (round up) + // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount + if( fee > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); @@ -276,6 +282,8 @@ namespace eosiosystem { auto net_balance = stake_net_delta; auto cpu_balance = stake_cpu_delta; bool need_deferred_trx = false; + + // net and cpu are same sign by assertions in delegatebw and undelegatebw // redundant assertion also at start of changebw to protect against misuse of changebw bool is_undelegating = (net_balance.amount + cpu_balance.amount ) < 0; @@ -303,17 +311,17 @@ namespace eosiosystem { } }); - eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen - eosio_assert( asset(0) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen - - if ( req->net_amount == asset(0) && req->cpu_amount == asset(0) ) { - refunds_tbl.erase( req ); - need_deferred_trx = false; - } else { - need_deferred_trx = true; - } - } else if ( net_balance < asset(0) || cpu_balance < asset(0) ) { //need to create refund - refunds_tbl.emplace( from, [&]( refund_request& r ) { + eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen + eosio_assert( asset(0) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen + + if ( req->net_amount == asset(0) && req->cpu_amount == asset(0) ) { + refunds_tbl.erase( req ); + need_deferred_trx = false; + } else { + need_deferred_trx = true; + } + } else if ( net_balance < asset(0) || cpu_balance < asset(0) ) { //need to create refund + refunds_tbl.emplace( from, [&]( refund_request& r ) { r.owner = from; if ( net_balance < asset(0) ) { r.net_amount = -net_balance; @@ -325,15 +333,16 @@ namespace eosiosystem { } // else r.cpu_amount = 0 by default constructor r.request_time = now(); }); - need_deferred_trx = true; - } // else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl - } + need_deferred_trx = true; + } // else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl + } /// end if is_delegating_to_self || is_undelegating if ( need_deferred_trx ) { eosio::transaction out; out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); out.delay_sec = refund_delay; - out.send( from, receiver, true ); + cancel_deferred( from ); // TODO: Remove this line when replacing deferred trxs is fixed + out.send( from, from, true ); } else { cancel_deferred( from ); } diff --git a/src/exchange_state.cpp b/src/exchange_state.cpp index b50d2aa0..621d3e71 100644 --- a/src/exchange_state.cpp +++ b/src/exchange_state.cpp @@ -1,4 +1,4 @@ -#include +#include namespace eosiosystem { asset exchange_state::convert_to_exchange( connector& c, asset in ) { From f2494991fe55733d6d7ddf5f7d5cea8826be93ca Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 29 Jun 2018 17:38:49 -0400 Subject: [PATCH 0391/1048] previous commits to these repos are from https://github.com/eosio/eos commit #7eb1b84 --- .gitmodules | 3 - build.sh | 59 +- deps/eosio.token | 1 - eosio.msig/README.md | 113 + eosio.msig/abi/eosio.msig.abi | 152 + eosio.msig/build.sh | 22 + eosio.msig/include/eosio.msig/eosio.msig.hpp | 36 + eosio.msig/src/eosio.msig.cpp | 137 + eosio.sudo/README.md | 16 + eosio.sudo/abi/eosio.sudo.abi | 73 + eosio.sudo/build.sh | 22 + eosio.sudo/include/eosio.sudo/eosio.sudo.hpp | 15 + eosio.sudo/src/eosio.sudo.cpp | 37 + README.md => eosio.system/README.md | 0 {abi => eosio.system/abi}/eosio.system.abi | 0 eosio.system/build.sh | 21 + .../include}/eosio.system/eosio.system.hpp | 0 .../include}/eosio.system/exchange_state.hpp | 0 .../include}/eosio.system/native.hpp | 0 .../src}/delegate_bandwidth.cpp | 0 {src => eosio.system/src}/eosio.system.cpp | 0 {src => eosio.system/src}/exchange_state.cpp | 0 {src => eosio.system/src}/producer_pay.cpp | 0 {src => eosio.system/src}/voting.cpp | 0 eosio.token/README.md | 7 + eosio.token/abi/eosio.token.abi | 78 + eosio.token/build.sh | 31 + .../include/eosio.token/eosio.token.hpp | 83 + eosio.token/src/eosio.token.cpp | 120 + tests/CMakeLists.txt | 7 +- tests/contracts.hpp.in | 25 + tests/eosio.msig_tests.cpp | 628 + tests/eosio.sudo_tests.cpp | 360 + ..._tester.hpp.in => eosio.system_tester.hpp} | 23 +- tests/eosio.system_tests.cpp | 6 +- tests/eosio.token_tests.cpp | 266 + tests/test_contracts/exchange.wasm | Bin 0 -> 72187 bytes tests/test_contracts/exchange.wast | 47435 ++++++++++++++ tests/test_contracts/test_api.wasm | Bin 0 -> 89736 bytes tests/test_contracts/test_api.wast | 53138 ++++++++++++++++ 40 files changed, 102847 insertions(+), 67 deletions(-) delete mode 160000 deps/eosio.token create mode 100644 eosio.msig/README.md create mode 100644 eosio.msig/abi/eosio.msig.abi create mode 100755 eosio.msig/build.sh create mode 100644 eosio.msig/include/eosio.msig/eosio.msig.hpp create mode 100644 eosio.msig/src/eosio.msig.cpp create mode 100644 eosio.sudo/README.md create mode 100644 eosio.sudo/abi/eosio.sudo.abi create mode 100755 eosio.sudo/build.sh create mode 100644 eosio.sudo/include/eosio.sudo/eosio.sudo.hpp create mode 100644 eosio.sudo/src/eosio.sudo.cpp rename README.md => eosio.system/README.md (100%) rename {abi => eosio.system/abi}/eosio.system.abi (100%) create mode 100755 eosio.system/build.sh rename {include => eosio.system/include}/eosio.system/eosio.system.hpp (100%) rename {include => eosio.system/include}/eosio.system/exchange_state.hpp (100%) rename {include => eosio.system/include}/eosio.system/native.hpp (100%) rename {src => eosio.system/src}/delegate_bandwidth.cpp (100%) rename {src => eosio.system/src}/eosio.system.cpp (100%) rename {src => eosio.system/src}/exchange_state.cpp (100%) rename {src => eosio.system/src}/producer_pay.cpp (100%) rename {src => eosio.system/src}/voting.cpp (100%) create mode 100644 eosio.token/README.md create mode 100644 eosio.token/abi/eosio.token.abi create mode 100755 eosio.token/build.sh create mode 100644 eosio.token/include/eosio.token/eosio.token.hpp create mode 100644 eosio.token/src/eosio.token.cpp create mode 100644 tests/contracts.hpp.in create mode 100644 tests/eosio.msig_tests.cpp create mode 100644 tests/eosio.sudo_tests.cpp rename tests/{eosio.system_tester.hpp.in => eosio.system_tester.hpp} (96%) create mode 100644 tests/eosio.token_tests.cpp create mode 100644 tests/test_contracts/exchange.wasm create mode 100644 tests/test_contracts/exchange.wast create mode 100644 tests/test_contracts/test_api.wasm create mode 100644 tests/test_contracts/test_api.wast diff --git a/.gitmodules b/.gitmodules index 78239599..e69de29b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +0,0 @@ -[submodule "deps/eosio.token"] - path = deps/eosio.token - url = https://github.com/eosio/eosio.token diff --git a/build.sh b/build.sh index a8ee3175..72fa222d 100755 --- a/build.sh +++ b/build.sh @@ -1,8 +1,11 @@ #! /bin/bash -CONTRACT_NAME="eosio.system" -unamestr=`uname` +contracts=( "eosio.token" + "eosio.system" + "eosio.msig" + "eosio.sudo" ) +unamestr=`uname` if [[ "${unamestr}" == 'Darwin' ]]; then PREFIX=/usr/local OPENSSL=/usr/local/opt/openssl @@ -12,53 +15,25 @@ else OPENSSL=/usr/include/openssl fi -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -Ideps/eosio.token/include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="/usr/local/bin/eosio-s2wasm " -W2W="/usr/local/bin/eosio-wast2wasm " - -deps=( "eosio.token" ) +### Build all the contracts -for dep in "${deps[@]}"; do - pushd ./deps/${dep} &> /dev/null - ./build.sh notests +for contract in "${contracts[@]}"; do + pushd ${contract} &> /dev/null + echo "Building ${contract}..." + CONTRACT_NAME="${contract}" + ./build.sh ${PREFIX} popd &> /dev/null done -echo "building eosio.system" -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi - -if [[ "$1" == 'notests' ]]; then - rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s - exit 0 -fi -contract_dir=`pwd` +### Build the unit tests +root_dir=`pwd` pushd tests &> /dev/null -mkdir build +mkdir -p build pushd build &> /dev/null -cmake -DCONTRACT_DIR="${contract_dir}" -DEOSIO_INSTALL_PREFIX="/usr/local" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="/usr/local" ../ +cmake -DROOT_DIR="${root_dir}" -DEOSIO_INSTALL_PREFIX="${PREFIX}" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="${PREFIX}" ../ make -j8 +cp unit_test ../../ popd &> /dev/null +rm -r build popd &> /dev/null -cp tests/build/unit_test bin/ -rm -r tests/build - -if [[ "$1" == 'noinstall' ]]; then - rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s - exit 0 -fi - -### INSTALL THE HEADERS -cp -r include/* /usr/local/include -cp build/unit_tests bin/ - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/deps/eosio.token b/deps/eosio.token deleted file mode 160000 index 6ef029d9..00000000 --- a/deps/eosio.token +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 6ef029d9fc0309033ee6a433834abc19af9f0b75 diff --git a/eosio.msig/README.md b/eosio.msig/README.md new file mode 100644 index 00000000..1d727913 --- /dev/null +++ b/eosio.msig/README.md @@ -0,0 +1,113 @@ +eosio.msig +-------- + +Actions: +The naming convention is codeaccount::actionname followed by a list of paramters. + +Create a proposal +## eosio.msig::propose proposer proposal_name requested trx + - **proposer** account proposing a transaction + - **proposal_name** name of the proposal (should be unique for proposer) + - **requested** permission levels expected to approve the proposal + - **trx** proposed transaction + + Storage changes are billed to 'proposer' + +Approve a proposal +## eosio.msig::approve proposer proposal_name level + - **proposer** account proposing a transaction + - **proposal_name** name of the proposal + - **level** permission level approving the transaction + + Storage changes are billed to 'proposer' + +Revoke an approval of transaction +## eosio.msig::unapprove proposer proposal_name level + - **proposer** account proposing a transaction + - **proposal_name** name of the proposal + - **level** permission level revoking approval from the transaction + + Storage changes are billed to 'proposer' + +Cancel a proposal +## eosio.msig::cancel proposer proposal_name canceler + - **proposer** account proposing a transaction + - **proposal_name** name of the proposal + - **canceler** account canceling the transaction (only proposer can cancel not expired transaction) + +Execute a proposal +## eosio.msig::exec proposer proposal_name executer + - **proposer** account proposing a transaction + - **proposal_name** name of the proposal + - **executer** account executing the transaction + + +Cleos usage example. + +Prerequisites: + - eosio.token contract installed to eosio.token accountm, eosio.msig contract installed on eosio.msig account which is a priviliged account. + - account 'treasury' is the issuer of EOS token. + - account 'tester' exists. + - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. + +One user creates a proposal: +```` +$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 EOS", "memo": ""}' -p tester +executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles +# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... +```` + +Another user reviews the transaction: +```` +$ cleos multisig review tester test -p treasury +{ + "proposal_name": "test", + "requested_approvals": [{ + "actor": "treasury", + "permission": "active" + } + ], + "provided_approvals": [], + "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", + "transaction": { + "expiration": "2018-05-01T00:00:00", + "region": 0, + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_kcpu_usage": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "issue", + "authorization": [{ + "actor": "treasury", + "permission": "active" + } + ], + "data": { + "to": "tester", + "quantity": "1000.0000 EOS", + "memo": "" + }, + "hex_data": "000000005c95b1ca809698000000000004454f530000000000" + } + ] + } +} +```` + +And then approves it: +```` +$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury +executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles +# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} +```` + +First user initiates execution: +```` +$ cleos multisig exec tester test -p tester +executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles +# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} +```` diff --git a/eosio.msig/abi/eosio.msig.abi b/eosio.msig/abi/eosio.msig.abi new file mode 100644 index 00000000..9fcf8a95 --- /dev/null +++ b/eosio.msig/abi/eosio.msig.abi @@ -0,0 +1,152 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name": "actor", "type": "account_name"}, + {"name": "permission", "type": "permission_name"} + ] + },{ + "name": "action", + "base": "", + "fields": [ + {"name": "account", "type": "account_name"}, + {"name": "name", "type": "action_name"}, + {"name": "authorization", "type": "permission_level[]"}, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction_header", + "base": "", + "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": "extension", + "base": "", + "fields": [ + {"name": "type", "type" : "uint16" }, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction", + "base": "transaction_header", + "fields": [ + {"name": "context_free_actions", "type": "action[]"}, + {"name": "actions", "type": "action[]"}, + {"name": "transaction_extensions", "type": "extension[]"} + ] + },{ + "name": "propose", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"requested", "type":"permission_level[]"}, + {"name":"trx", "type":"transaction"} + ] + },{ + "name": "approve", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"level", "type":"permission_level"} + ] + },{ + "name": "unapprove", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"level", "type":"permission_level"} + ] + },{ + "name": "cancel", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"canceler", "type":"account_name"} + ] + },{ + "name": "exec", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"executer", "type":"account_name"} + ] + },{ + "name": "proposal", + "base": "", + "fields": [ + {"name": "proposal_name", "type": "name"}, + {"name": "packed_transaction", "type": "bytes"} + ] + },{ + "name": "approvals_info", + "base": "", + "fields": [ + {"name": "proposal_name", "type": "name"}, + {"name": "requested_approvals", "type": "permission_level[]"}, + {"name": "provided_approvals", "type": "permission_level[]"} + ] + } + ], + "actions": [{ + "name": "propose", + "type": "propose", + "ricardian_contract": "" + },{ + "name": "approve", + "type": "approve", + "ricardian_contract": "" + },{ + "name": "unapprove", + "type": "unapprove", + "ricardian_contract": "" + }, { + "name": "cancel", + "type": "cancel", + "ricardian_contract": "" + }, { + "name": "exec", + "type": "exec", + "ricardian_contract": "" + } + + ], + "tables": [{ + "name": "proposal", + "type": "proposal", + "index_type": "i64", + "key_names" : ["proposal_name"], + "key_types" : ["name"] + },{ + "name": "approvals", + "type": "approvals_info", + "index_type": "i64", + "key_names" : ["proposal_name"], + "key_types" : ["name"] + } + ], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/eosio.msig/build.sh b/eosio.msig/build.sh new file mode 100755 index 00000000..bce26d68 --- /dev/null +++ b/eosio.msig/build.sh @@ -0,0 +1,22 @@ +#! /bin/bash + +CONTRACT_NAME="eosio.msig" +PREFIX=$1 + +mkdir -p bin/${CONTRACT_NAME} +### BUILD THE CONTRACT +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I./include -I${BOOST}" +LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " +LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" +S2W="/usr/local/bin/eosio-s2wasm " +W2W="/usr/local/bin/eosio-wast2wasm " + +${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp +${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LLC} -o ${CONTRACT_NAME}.s linked.bc +${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s +${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n +cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi +cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast + +rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp new file mode 100644 index 00000000..48ce2e3d --- /dev/null +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -0,0 +1,36 @@ +#pragma once +#include +#include + +namespace eosio { + + class multisig : public contract { + public: + multisig( account_name self ):contract(self){} + + void propose(); + void approve( account_name proposer, name proposal_name, permission_level level ); + void unapprove( account_name proposer, name proposal_name, permission_level level ); + void cancel( account_name proposer, name proposal_name, account_name canceler ); + void exec( account_name proposer, name proposal_name, account_name executer ); + + private: + struct proposal { + name proposal_name; + vector packed_transaction; + + auto primary_key()const { return proposal_name.value; } + }; + typedef eosio::multi_index proposals; + + struct approvals_info { + name proposal_name; + vector requested_approvals; + vector provided_approvals; + + auto primary_key()const { return proposal_name.value; } + }; + typedef eosio::multi_index approvals; + }; + +} /// namespace eosio diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp new file mode 100644 index 00000000..9d04a1a9 --- /dev/null +++ b/eosio.msig/src/eosio.msig.cpp @@ -0,0 +1,137 @@ +#include +#include +#include + +namespace eosio { + +/* +propose function manually parses input data (instead of taking parsed arguments from dispatcher) +because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big + +If we use dispatcher the function signature should be: + +void multisig::propose( account_name proposer, + name proposal_name, + vector requested, + transaction trx) +*/ + +void multisig::propose() { + constexpr size_t max_stack_buffer_size = 512; + size_t size = action_data_size(); + char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); + read_action_data( buffer, size ); + + account_name proposer; + name proposal_name; + vector requested; + transaction_header trx_header; + + datastream ds( buffer, size ); + ds >> proposer >> proposal_name >> requested; + + size_t trx_pos = ds.tellp(); + ds >> trx_header; + + require_auth( proposer ); + eosio_assert( trx_header.expiration >= eosio::time_point_sec(now()), "transaction expired" ); + //eosio_assert( trx_header.actions.size() > 0, "transaction must have at least one action" ); + + proposals proptable( _self, proposer ); + eosio_assert( proptable.find( proposal_name ) == proptable.end(), "proposal with the same name exists" ); + + bytes packed_requested = pack(requested); + auto res = ::check_transaction_authorization( buffer+trx_pos, size-trx_pos, + (const char*)0, 0, + packed_requested.data(), packed_requested.size() + ); + eosio_assert( res > 0, "transaction authorization failed" ); + + proptable.emplace( proposer, [&]( auto& prop ) { + prop.proposal_name = proposal_name; + prop.packed_transaction = bytes( buffer+trx_pos, buffer+size ); + }); + + approvals apptable( _self, proposer ); + apptable.emplace( proposer, [&]( auto& a ) { + a.proposal_name = proposal_name; + a.requested_approvals = std::move(requested); + }); +} + +void multisig::approve( account_name proposer, name proposal_name, permission_level level ) { + require_auth( level ); + + approvals apptable( _self, proposer ); + auto& apps = apptable.get( proposal_name, "proposal not found" ); + + auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level ); + eosio_assert( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" ); + + apptable.modify( apps, proposer, [&]( auto& a ) { + a.provided_approvals.push_back( level ); + a.requested_approvals.erase( itr ); + }); +} + +void multisig::unapprove( account_name proposer, name proposal_name, permission_level level ) { + require_auth( level ); + + approvals apptable( _self, proposer ); + auto& apps = apptable.get( proposal_name, "proposal not found" ); + auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); + eosio_assert( itr != apps.provided_approvals.end(), "no approval previously granted" ); + + apptable.modify( apps, proposer, [&]( auto& a ) { + a.requested_approvals.push_back(level); + a.provided_approvals.erase(itr); + }); +} + +void multisig::cancel( account_name proposer, name proposal_name, account_name canceler ) { + require_auth( canceler ); + + proposals proptable( _self, proposer ); + auto& prop = proptable.get( proposal_name, "proposal not found" ); + + if( canceler != proposer ) { + eosio_assert( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(now()), "cannot cancel until expiration" ); + } + + approvals apptable( _self, proposer ); + auto& apps = apptable.get( proposal_name, "proposal not found" ); + + proptable.erase(prop); + apptable.erase(apps); +} + +void multisig::exec( account_name proposer, name proposal_name, account_name executer ) { + require_auth( executer ); + + proposals proptable( _self, proposer ); + auto& prop = proptable.get( proposal_name, "proposal not found" ); + + approvals apptable( _self, proposer ); + auto& apps = apptable.get( proposal_name, "proposal not found" ); + + transaction_header trx_header; + datastream ds( prop.packed_transaction.data(), prop.packed_transaction.size() ); + ds >> trx_header; + eosio_assert( trx_header.expiration >= eosio::time_point_sec(now()), "transaction expired" ); + + bytes packed_provided_approvals = pack(apps.provided_approvals); + auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), + (const char*)0, 0, + packed_provided_approvals.data(), packed_provided_approvals.size() + ); + eosio_assert( res > 0, "transaction authorization failed" ); + + send_deferred( (uint128_t(proposer) << 64) | proposal_name, executer, prop.packed_transaction.data(), prop.packed_transaction.size() ); + + proptable.erase(prop); + apptable.erase(apps); +} + +} /// namespace eosio + +EOSIO_ABI( eosio::multisig, (propose)(approve)(unapprove)(cancel)(exec) ) diff --git a/eosio.sudo/README.md b/eosio.sudo/README.md new file mode 100644 index 00000000..9c6873ca --- /dev/null +++ b/eosio.sudo/README.md @@ -0,0 +1,16 @@ +eosio.sudo +-------- + +Actions: +The naming convention is codeaccount::actionname followed by a list of parameters. + +Execute a transaction while bypassing regular authorization checks (requires authorization of eosio.sudo which needs to be a privileged account) +## eosio.sudo::exec executer trx + - **executer** account executing the transaction + - **trx** transaction to execute + + Deferred transaction RAM usage is billed to 'executer' + +Cleos usage example. + +TODO: Fill in cleos usage example. diff --git a/eosio.sudo/abi/eosio.sudo.abi b/eosio.sudo/abi/eosio.sudo.abi new file mode 100644 index 00000000..6f74921b --- /dev/null +++ b/eosio.sudo/abi/eosio.sudo.abi @@ -0,0 +1,73 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name": "actor", "type": "account_name"}, + {"name": "permission", "type": "permission_name"} + ] + },{ + "name": "action", + "base": "", + "fields": [ + {"name": "account", "type": "account_name"}, + {"name": "name", "type": "action_name"}, + {"name": "authorization", "type": "permission_level[]"}, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction_header", + "base": "", + "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": "extension", + "base": "", + "fields": [ + {"name": "type", "type" : "uint16" }, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction", + "base": "transaction_header", + "fields": [ + {"name": "context_free_actions", "type": "action[]"}, + {"name": "actions", "type": "action[]"}, + {"name": "transaction_extensions", "type": "extension[]"} + ] + },{ + "name": "exec", + "base": "", + "fields": [ + {"name":"executer", "type":"account_name"}, + {"name":"trx", "type":"transaction"} + ] + } + ], + "actions": [{ + "name": "exec", + "type": "exec", + "ricardian_contract": "" + } + ], + "tables": [], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/eosio.sudo/build.sh b/eosio.sudo/build.sh new file mode 100755 index 00000000..c93e09c0 --- /dev/null +++ b/eosio.sudo/build.sh @@ -0,0 +1,22 @@ +#! /bin/bash + +CONTRACT_NAME="eosio.sudo" +PREFIX=$1 + +mkdir -p bin/${CONTRACT_NAME} +### BUILD THE CONTRACT +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I./include -I${BOOST}" +LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " +LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" +S2W="/usr/local/bin/eosio-s2wasm " +W2W="/usr/local/bin/eosio-wast2wasm " + +${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp +${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LLC} -o ${CONTRACT_NAME}.s linked.bc +${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s +${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n +cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi +cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast + +rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp new file mode 100644 index 00000000..a9656212 --- /dev/null +++ b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace eosio { + + class sudo : public contract { + public: + sudo( account_name self ):contract(self){} + + void exec(); + + }; + +} /// namespace eosio diff --git a/eosio.sudo/src/eosio.sudo.cpp b/eosio.sudo/src/eosio.sudo.cpp new file mode 100644 index 00000000..10e50193 --- /dev/null +++ b/eosio.sudo/src/eosio.sudo.cpp @@ -0,0 +1,37 @@ +#include +#include + +namespace eosio { + +/* +exec function manually parses input data (instead of taking parsed arguments from dispatcher) +because parsing data in the dispatcher uses too much CPU if the included transaction is very big + +If we use dispatcher the function signature should be: + +void sudo::exec( account_name executer, + transaction trx ) +*/ + +void sudo::exec() { + require_auth( _self ); + + constexpr size_t max_stack_buffer_size = 512; + size_t size = action_data_size(); + char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); + read_action_data( buffer, size ); + + account_name executer; + + datastream ds( buffer, size ); + ds >> executer; + + require_auth( executer ); + + size_t trx_pos = ds.tellp(); + send_deferred( (uint128_t(executer) << 64) | current_time(), executer, buffer+trx_pos, size ); +} + +} /// namespace eosio + +EOSIO_ABI( eosio::sudo, (exec) ) diff --git a/README.md b/eosio.system/README.md similarity index 100% rename from README.md rename to eosio.system/README.md diff --git a/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi similarity index 100% rename from abi/eosio.system.abi rename to eosio.system/abi/eosio.system.abi diff --git a/eosio.system/build.sh b/eosio.system/build.sh new file mode 100755 index 00000000..7cfc9971 --- /dev/null +++ b/eosio.system/build.sh @@ -0,0 +1,21 @@ +#! /bin/bash + +CONTRACT_NAME="eosio.system" +PREFIX=$1 +mkdir -p bin/${CONTRACT_NAME} +### BUILD THE CONTRACT +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I../eosio.token/include -I${BOOST}" +LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " +LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" +S2W="/usr/local/bin/eosio-s2wasm " +W2W="/usr/local/bin/eosio-wast2wasm " + +${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp +${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LLC} -o ${CONTRACT_NAME}.s linked.bc +${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s +${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n +cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi +cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast + +rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp similarity index 100% rename from include/eosio.system/eosio.system.hpp rename to eosio.system/include/eosio.system/eosio.system.hpp diff --git a/include/eosio.system/exchange_state.hpp b/eosio.system/include/eosio.system/exchange_state.hpp similarity index 100% rename from include/eosio.system/exchange_state.hpp rename to eosio.system/include/eosio.system/exchange_state.hpp diff --git a/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp similarity index 100% rename from include/eosio.system/native.hpp rename to eosio.system/include/eosio.system/native.hpp diff --git a/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp similarity index 100% rename from src/delegate_bandwidth.cpp rename to eosio.system/src/delegate_bandwidth.cpp diff --git a/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp similarity index 100% rename from src/eosio.system.cpp rename to eosio.system/src/eosio.system.cpp diff --git a/src/exchange_state.cpp b/eosio.system/src/exchange_state.cpp similarity index 100% rename from src/exchange_state.cpp rename to eosio.system/src/exchange_state.cpp diff --git a/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp similarity index 100% rename from src/producer_pay.cpp rename to eosio.system/src/producer_pay.cpp diff --git a/src/voting.cpp b/eosio.system/src/voting.cpp similarity index 100% rename from src/voting.cpp rename to eosio.system/src/voting.cpp diff --git a/eosio.token/README.md b/eosio.token/README.md new file mode 100644 index 00000000..b482fc40 --- /dev/null +++ b/eosio.token/README.md @@ -0,0 +1,7 @@ +eosio.token +----------- + +This eosio contract allows users to create, issue, and manage tokens on +eosio based blockchains. + + diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi new file mode 100644 index 00000000..d769deb3 --- /dev/null +++ b/eosio.token/abi/eosio.token.abi @@ -0,0 +1,78 @@ +{ + "version": "eosio::abi/1.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":"asset"}, + {"name":"memo", "type":"string"} + ] + },{ + "name": "create", + "base": "", + "fields": [ + {"name":"issuer", "type":"account_name"}, + {"name":"maximum_supply", "type":"asset"} + ] + },{ + "name": "issue", + "base": "", + "fields": [ + {"name":"to", "type":"account_name"}, + {"name":"quantity", "type":"asset"}, + {"name":"memo", "type":"string"} + ] + },{ + "name": "account", + "base": "", + "fields": [ + {"name":"balance", "type":"asset"} + ] + },{ + "name": "currency_stats", + "base": "", + "fields": [ + {"name":"supply", "type":"asset"}, + {"name":"max_supply", "type":"asset"}, + {"name":"issuer", "type":"account_name"} + ] + } + ], + "actions": [{ + "name": "transfer", + "type": "transfer", + "ricardian_contract": "" + },{ + "name": "issue", + "type": "issue", + "ricardian_contract": "" + }, { + "name": "create", + "type": "create", + "ricardian_contract": "" + } + + ], + "tables": [{ + "name": "accounts", + "type": "account", + "index_type": "i64", + "key_names" : ["currency"], + "key_types" : ["uint64"] + },{ + "name": "stat", + "type": "currency_stats", + "index_type": "i64", + "key_names" : ["currency"], + "key_types" : ["uint64"] + } + ], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/eosio.token/build.sh b/eosio.token/build.sh new file mode 100755 index 00000000..fed39289 --- /dev/null +++ b/eosio.token/build.sh @@ -0,0 +1,31 @@ +#! /bin/bash + +CONTRACT_NAME="eosio.token" +unamestr=`uname` + +if [[ "${unamestr}" == 'Darwin' ]]; then + PREFIX=/usr/local + OPENSSL=/usr/local/opt/openssl +else + PREFIX=~/opt + BOOST=~/opt/boost/include + OPENSSL=/usr/include/openssl +fi + +mkdir -p bin/${CONTRACT_NAME} +### BUILD THE CONTRACT +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I${BOOST}" +LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " +LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" +S2W="/usr/local/bin/eosio-s2wasm " +W2W="/usr/local/bin/eosio-wast2wasm " + +${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp +${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LLC} -o ${CONTRACT_NAME}.s linked.bc +${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s +${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n +cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi +cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast + +rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp new file mode 100644 index 00000000..15875134 --- /dev/null +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -0,0 +1,83 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ +#pragma once + +#include +#include + +#include + +namespace eosiosystem { + class system_contract; +} + +namespace eosio { + + using std::string; + + class token : public contract { + public: + token( account_name self ):contract(self){} + + void create( account_name issuer, + asset maximum_supply); + + void issue( account_name to, asset quantity, string memo ); + + void transfer( account_name from, + account_name to, + asset quantity, + string memo ); + + + inline asset get_supply( symbol_name sym )const; + + inline asset get_balance( account_name owner, symbol_name sym )const; + + private: + struct account { + asset balance; + + uint64_t primary_key()const { return balance.symbol.name(); } + }; + + struct currency_stats { + asset supply; + asset max_supply; + account_name issuer; + + uint64_t primary_key()const { return supply.symbol.name(); } + }; + + typedef eosio::multi_index accounts; + typedef eosio::multi_index stats; + + void sub_balance( account_name owner, asset value ); + void add_balance( account_name owner, asset value, account_name ram_payer ); + + public: + struct transfer_args { + account_name from; + account_name to; + asset quantity; + string memo; + }; + }; + + asset token::get_supply( symbol_name sym )const + { + stats statstable( _self, sym ); + const auto& st = statstable.get( sym ); + return st.supply; + } + + asset token::get_balance( account_name owner, symbol_name sym )const + { + accounts accountstable( _self, owner ); + const auto& ac = accountstable.get( sym ); + return ac.balance; + } + +} /// namespace eosio diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp new file mode 100644 index 00000000..d85c2362 --- /dev/null +++ b/eosio.token/src/eosio.token.cpp @@ -0,0 +1,120 @@ +/** + * @file + * @copyright defined in eos/LICENSE.txt + */ + +#include + +namespace eosio { + +void token::create( account_name issuer, + asset maximum_supply ) +{ + require_auth( _self ); + + auto sym = maximum_supply.symbol; + eosio_assert( sym.is_valid(), "invalid symbol name" ); + eosio_assert( maximum_supply.is_valid(), "invalid supply"); + eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); + + stats statstable( _self, sym.name() ); + auto existing = statstable.find( sym.name() ); + eosio_assert( existing == statstable.end(), "token with symbol already exists" ); + + statstable.emplace( _self, [&]( auto& s ) { + s.supply.symbol = maximum_supply.symbol; + s.max_supply = maximum_supply; + s.issuer = issuer; + }); +} + + +void token::issue( account_name to, asset quantity, string memo ) +{ + auto sym = quantity.symbol; + eosio_assert( sym.is_valid(), "invalid symbol name" ); + eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); + + auto sym_name = sym.name(); + stats statstable( _self, sym_name ); + auto existing = statstable.find( sym_name ); + eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); + const auto& st = *existing; + + require_auth( st.issuer ); + eosio_assert( quantity.is_valid(), "invalid quantity" ); + eosio_assert( quantity.amount > 0, "must issue positive quantity" ); + + eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); + eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); + + statstable.modify( st, 0, [&]( auto& s ) { + s.supply += quantity; + }); + + add_balance( st.issuer, quantity, st.issuer ); + + if( to != st.issuer ) { + SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); + } +} + +void token::transfer( account_name from, + account_name to, + asset quantity, + string memo ) +{ + eosio_assert( from != to, "cannot transfer to self" ); + require_auth( from ); + eosio_assert( is_account( to ), "to account does not exist"); + auto sym = quantity.symbol.name(); + stats statstable( _self, sym ); + const auto& st = statstable.get( sym ); + + require_recipient( from ); + require_recipient( to ); + + eosio_assert( quantity.is_valid(), "invalid quantity" ); + eosio_assert( quantity.amount > 0, "must transfer positive quantity" ); + eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); + eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); + + + sub_balance( from, quantity ); + add_balance( to, quantity, from ); +} + +void token::sub_balance( account_name owner, asset value ) { + accounts from_acnts( _self, owner ); + + const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" ); + eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); + + + if( from.balance.amount == value.amount ) { + from_acnts.erase( from ); + } else { + from_acnts.modify( from, owner, [&]( auto& a ) { + a.balance -= value; + }); + } +} + +void token::add_balance( account_name owner, asset value, account_name ram_payer ) +{ + accounts to_acnts( _self, owner ); + auto to = to_acnts.find( value.symbol.name() ); + if( to == to_acnts.end() ) { + to_acnts.emplace( ram_payer, [&]( auto& a ){ + a.balance = value; + }); + } else { + to_acnts.modify( to, 0, [&]( auto& a ) { + a.balance += value; + }); + } +} + +} /// namespace eosio + +EOSIO_ABI( eosio::token, (create)(issue)(transfer) ) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9da6ba85..06efce9f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -11,7 +11,8 @@ find_package(LLVM 4.0 REQUIRED CONFIG) link_directories(${LLVM_LIBRARY_DIR}) set( CMAKE_CXX_STANDARD 14 ) -configure_file(${CMAKE_SOURCE_DIR}/eosio.system_tester.hpp.in ${CMAKE_SOURCE_DIR}/eosio.system_tester.hpp) + +configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_SOURCE_DIR}/contracts.hpp) find_package(Boost 1.67 REQUIRED COMPONENTS date_time filesystem system chrono iostreams date_time) file(GLOB UNIT_TESTS "*.cpp") @@ -27,8 +28,8 @@ find_library(libplatform Platform ${EOSIO_INSTALL_PREFIX}/lib) find_library(liblogging Logging ${EOSIO_INSTALL_PREFIX}/lib) find_library(libruntime Runtime ${EOSIO_INSTALL_PREFIX}/lib) find_library(libsoftfloat softfloat ${EOSIO_INSTALL_PREFIX}/lib) -find_library(liboscrypto crypto ${OPENSSL_INSTALL_LIB}) -find_library(libosssl ssl ${OPENSSL_INSTALL_LIB}) +find_library(liboscrypto crypto ${OPENSSL_INSTALL_PREFIX}/lib) +find_library(libosssl ssl ${OPENSSL_INSTALL_PREFIX}/lib) find_library(libchainbase chainbase ${EOSIO_INSTALL_PREFIX}/lib) find_library(libbuiltins builtins ${EOSIO_INSTALL_PREFIX}/lib) find_library(libsecp256k1 secp256k1 ${SECP256K1_INSTALL_LIB}) diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in new file mode 100644 index 00000000..1d91f506 --- /dev/null +++ b/tests/contracts.hpp.in @@ -0,0 +1,25 @@ +#pragma once +#include + +namespace eosio { namespace testing { + +struct contracts { + static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.abi"); } + static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wasm"); } + static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wast"); } + static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi"); } + + struct util { + static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } + static std::vector exchange_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/exchange.wasm"); } + }; +}; +}} //ns eosio::testing diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp new file mode 100644 index 00000000..ce01cc85 --- /dev/null +++ b/tests/eosio.msig_tests.cpp @@ -0,0 +1,628 @@ +#include +#include +#include +#include + +#include + +#include +#include "contracts.hpp" + +using namespace eosio::testing; +using namespace eosio; +using namespace eosio::chain; +using namespace eosio::testing; +using namespace fc; + +using mvo = fc::mutable_variant_object; + +class eosio_msig_tester : public tester { +public: + + eosio_msig_tester() { + create_accounts( { N(eosio.msig), N(eosio.stake), N(eosio.ram), N(eosio.ramfee), N(alice), N(bob), N(carol) } ); + produce_block(); + + auto trace = base_tester::push_action(config::system_account_name, N(setpriv), + config::system_account_name, mutable_variant_object() + ("account", "eosio.msig") + ("is_priv", 1) + ); + + set_code( N(eosio.msig), contracts::msig_wasm() ); + set_abi( N(eosio.msig), contracts::msig_abi().data() ); + + produce_blocks(); + const auto& accnt = control->db().get( N(eosio.msig) ); + abi_def abi; + BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); + abi_ser.set_abi(abi); + } + + transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, + asset net = core_from_string("10.0000"), asset cpu = core_from_string("10.0000") ) { + signed_transaction trx; + set_transaction_headers(trx); + + authority owner_auth; + if (multisig) { + // multisig between account's owner key and creators active permission + owner_auth = authority(2, {key_weight{get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}}); + } else { + owner_auth = authority( get_public_key( a, "owner" ) ); + } + + trx.actions.emplace_back( vector{{creator,config::active_name}}, + newaccount{ + .creator = creator, + .name = a, + .owner = owner_auth, + .active = authority( get_public_key( a, "active" ) ) + }); + + trx.actions.emplace_back( get_action( N(eosio), N(buyram), vector{{creator,config::active_name}}, + mvo() + ("payer", creator) + ("receiver", a) + ("quant", ramfunds) ) + ); + + trx.actions.emplace_back( get_action( N(eosio), N(delegatebw), vector{{creator,config::active_name}}, + mvo() + ("from", creator) + ("receiver", a) + ("stake_net_quantity", net ) + ("stake_cpu_quantity", cpu ) + ("transfer", 0 ) + ) + ); + + set_transaction_headers(trx); + trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); + return push_transaction( trx ); + } + void create_currency( name contract, name manager, asset maxsupply ) { + auto act = mutable_variant_object() + ("issuer", manager ) + ("maximum_supply", maxsupply ); + + base_tester::push_action(contract, N(create), contract, act ); + } + void issue( name to, const asset& amount, name manager = config::system_account_name ) { + base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() + ("to", to ) + ("quantity", amount ) + ("memo", "") + ); + } + void transfer( name from, name to, const string& amount, name manager = config::system_account_name ) { + base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() + ("from", from) + ("to", to ) + ("quantity", asset::from_string(amount) ) + ("memo", "") + ); + } + asset get_balance( const account_name& act ) { + //return get_currency_balance( config::system_account_name, symbol(CORE_SYMBOL), act ); + //temporary code. current get_currency_balancy uses table name N(accounts) from currency.h + //generic_currency table name is N(account). + const auto& db = control->db(); + const auto* tbl = db.find(boost::make_tuple(N(eosio.token), act, N(accounts))); + share_type result = 0; + + // the balance is implied to be 0 if either the table or row does not exist + if (tbl) { + const auto *obj = db.find(boost::make_tuple(tbl->id, symbol(CORE_SYMBOL).to_symbol_code())); + if (obj) { + // balance is the first field in the serialization + fc::datastream ds(obj->value.data(), obj->value.size()); + fc::raw::unpack(ds, result); + } + } + return asset( result, symbol(CORE_SYMBOL) ); + } + + transaction_trace_ptr push_action( const account_name& signer, const action_name& name, const variant_object& data, bool auth = true ) { + vector accounts; + if( auth ) + accounts.push_back( signer ); + auto trace = base_tester::push_action( N(eosio.msig), name, accounts, data ); + produce_block(); + BOOST_REQUIRE_EQUAL( true, chain_has_transaction(trace->id) ); + return trace; + + /* + string action_type_name = abi_ser.get_action_type(name); + + action act; + act.account = N(eosio.msig); + act.name = name; + act.data = abi_ser.variant_to_binary( action_type_name, data ); + //std::cout << "test:\n" << fc::to_hex(act.data.data(), act.data.size()) << " size = " << act.data.size() << std::endl; + + return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : 0 ); + */ + } + + transaction reqauth( account_name from, const vector& auths ); + + abi_serializer abi_ser; +}; + +transaction eosio_msig_tester::reqauth( account_name from, const vector& auths ) { + fc::variants v; + for ( auto& level : auths ) { + v.push_back(fc::mutable_variant_object() + ("actor", level.actor) + ("permission", level.permission) + ); + } + variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", 0) + ("actions", fc::variants({ + fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("name", "reqauth") + ("authorization", v) + ("data", fc::mutable_variant_object() ("from", from) ) + }) + ); + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + return trx; +} + +BOOST_AUTO_TEST_SUITE(eosio_msig_tests) + +BOOST_FIXTURE_TEST_CASE( propose_approve_execute, eosio_msig_tester ) try { + auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}} ); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + //fail to execute before approval + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + + //approve and execute + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( propose_approve_unapprove, eosio_msig_tester ) try { + auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}} ); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + push_action( N(alice), N(unapprove), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }) + ); + + //approve by alice + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + //fail because approval by bob is missing + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + + //approve by bob and execute + push_action( N(bob), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(bob), config::active_name }) + ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + //try with not enough requested auth + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "third") + ("trx", trx) + ("requested", vector{ { N(alice), config::active_name } } ) + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( big_transaction, eosio_msig_tester ) try { + vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name } }; + auto wasm = contracts::util::exchange_wasm(); + + variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", 0) + ("actions", fc::variants({ + fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("name", "setcode") + ("authorization", perm) + ("data", fc::mutable_variant_object() + ("account", "alice") + ("vmtype", 0) + ("vmversion", 0) + ("code", bytes( wasm.begin(), wasm.end() )) + ) + }) + ); + + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", perm) + ); + + //approve by alice + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + //approve by bob and execute + push_action( N(bob), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(bob), config::active_name }) + ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); +} FC_LOG_AND_RETHROW() + + + +BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) try { + + // required to set up the link between (eosio active) and (eosio.prods active) + // + // eosio active + // | + // eosio.prods active (2/3 threshold) + // / | \ <--- implicitly updated in onblock action + // alice active bob active carol active + + set_authority(N(eosio), "active", authority(1, + vector{{get_private_key("eosio", "active").get_public_key(), 1}}, + vector{{{N(eosio.prods), config::active_name}, 1}}), "owner", + { { N(eosio), "active" } }, { get_private_key( N(eosio), "active" ) }); + + set_producers( {N(alice),N(bob),N(carol)} ); + produce_blocks(50); + + create_accounts( { N(eosio.token) } ); + set_code( N(eosio.token), contracts::token_wasm() ); + set_abi( N(eosio.token), contracts::token_abi().data() ); + + create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); + issue(config::system_account_name, core_from_string("1000000000.0000")); + BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), + get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + + set_code( config::system_account_name, contracts::system_wasm() ); + set_abi( config::system_account_name, contracts::system_abi().data() ); + + produce_blocks(); + + create_account_with_resources( N(alice1111111), N(eosio), core_from_string("1.0000"), false ); + create_account_with_resources( N(bob111111111), N(eosio), core_from_string("0.4500"), false ); + create_account_with_resources( N(carol1111111), N(eosio), core_from_string("1.0000"), false ); + + BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), + get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + + vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, + {N(carol), config::active_name} }; + + vector action_perm = {{N(eosio), config::active_name}}; + + auto wasm = contracts::util::test_api_wasm(); + + variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", 0) + ("actions", fc::variants({ + fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("name", "setcode") + ("authorization", action_perm) + ("data", fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("vmtype", 0) + ("vmversion", 0) + ("code", bytes( wasm.begin(), wasm.end() )) + ) + }) + ); + + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + + // propose action + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", perm) + ); + + //approve by alice + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + //approve by bob + push_action( N(bob), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(bob), config::active_name }) + ); + //approve by carol + push_action( N(carol), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(carol), config::active_name }) + ); + // execute by alice to replace the eosio system contract + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); + + // can't create account because system contract was replace by the test_api contract + + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_from_string("1.0000"), false ), + eosio_assert_message_exception, eosio_assert_message_is("Unknown Test") + + ); +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ) try { + + // set up the link between (eosio active) and (eosio.prods active) + set_authority(N(eosio), "active", authority(1, + vector{{get_private_key("eosio", "active").get_public_key(), 1}}, + vector{{{N(eosio.prods), config::active_name}, 1}}), "owner", + { { N(eosio), "active" } }, { get_private_key( N(eosio), "active" ) }); + + create_accounts( { N(apple) } ); + set_producers( {N(alice),N(bob),N(carol), N(apple)} ); + produce_blocks(50); + + create_accounts( { N(eosio.token) } ); + set_code( N(eosio.token), contracts::token_wasm() ); + set_abi( N(eosio.token), contracts::token_abi().data() ); + + create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); + issue(config::system_account_name, core_from_string("1000000000.0000")); + BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance( "eosio" ) ); + + set_code( config::system_account_name, contracts::system_wasm() ); + set_abi( config::system_account_name, contracts::system_abi().data() ); + + produce_blocks(); + + create_account_with_resources( N(alice1111111), N(eosio), core_from_string("1.0000"), false ); + create_account_with_resources( N(bob111111111), N(eosio), core_from_string("0.4500"), false ); + create_account_with_resources( N(carol1111111), N(eosio), core_from_string("1.0000"), false ); + + BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), + get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + + vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, + {N(carol), config::active_name}, {N(apple), config::active_name}}; + + vector action_perm = {{N(eosio), config::active_name}}; + + auto wasm = contracts::util::test_api_wasm(); + + variant pretty_trx = fc::mutable_variant_object() + ("expiration", "2020-01-01T00:30") + ("ref_block_num", 2) + ("ref_block_prefix", 3) + ("max_net_usage_words", 0) + ("max_cpu_usage_ms", 0) + ("delay_sec", 0) + ("actions", fc::variants({ + fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("name", "setcode") + ("authorization", action_perm) + ("data", fc::mutable_variant_object() + ("account", name(config::system_account_name)) + ("vmtype", 0) + ("vmversion", 0) + ("code", bytes( wasm.begin(), wasm.end() )) + ) + }) + ); + + transaction trx; + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + + // propose action + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", perm) + ); + + //approve by alice + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + //approve by bob + push_action( N(bob), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(bob), config::active_name }) + ); + + // not enough approvers + BOOST_REQUIRE_EXCEPTION( + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, eosio_assert_message_is("transaction authorization failed") + ); + + //approve by apple + push_action( N(apple), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(apple), config::active_name }) + ); + // execute by alice to replace the eosio system contract + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + + // execute by another producer different from proposer + push_action( N(apple), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "apple") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); + + // can't create account because system contract was replace by the test_api contract + + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_from_string("1.0000"), false ), + eosio_assert_message_exception, eosio_assert_message_is("Unknown Test") + + ); +} FC_LOG_AND_RETHROW() + + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.sudo_tests.cpp b/tests/eosio.sudo_tests.cpp new file mode 100644 index 00000000..607b2677 --- /dev/null +++ b/tests/eosio.sudo_tests.cpp @@ -0,0 +1,360 @@ +#include +#include +#include + +#include + +#include + +#include "contracts.hpp" + +using namespace eosio::testing; +using namespace eosio; +using namespace eosio::chain; +using namespace eosio::testing; +using namespace fc; + +using mvo = fc::mutable_variant_object; + +class eosio_sudo_tester : public tester { +public: + + eosio_sudo_tester() { + create_accounts( { N(eosio.msig), N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(alice), N(bob), N(carol) } ); + produce_block(); + + + base_tester::push_action(config::system_account_name, N(setpriv), + config::system_account_name, mutable_variant_object() + ("account", "eosio.msig") + ("is_priv", 1) + ); + + set_code( N(eosio.msig), contracts::msig_wasm() ); + set_abi( N(eosio.msig), contracts::msig_abi().data() ); + + produce_blocks(); + + signed_transaction trx; + set_transaction_headers(trx); + authority auth( 1, {}, {{{config::system_account_name, config::active_name}, 1}} ); + trx.actions.emplace_back( vector{{config::system_account_name, config::active_name}}, + newaccount{ + .creator = config::system_account_name, + .name = N(eosio.sudo), + .owner = auth, + .active = auth, + }); + + set_transaction_headers(trx); + trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); + push_transaction( trx ); + + base_tester::push_action(config::system_account_name, N(setpriv), + config::system_account_name, mutable_variant_object() + ("account", "eosio.sudo") + ("is_priv", 1) + ); + + auto system_private_key = get_private_key( config::system_account_name, "active" ); + set_code( N(eosio.sudo), contracts::sudo_wasm(), &system_private_key ); + set_abi( N(eosio.sudo), contracts::sudo_abi().data(), &system_private_key ); + + produce_blocks(); + + set_authority( config::system_account_name, config::active_name, + authority( 1, {{get_public_key( config::system_account_name, "active" ), 1}}, + {{{config::producers_account_name, config::active_name}, 1}} ), + config::owner_name, + { { config::system_account_name, config::owner_name } }, + { get_private_key( config::system_account_name, "active" ) } + ); + + set_producers( {N(prod1), N(prod2), N(prod3), N(prod4), N(prod5)} ); + + produce_blocks(); + + const auto& accnt = control->db().get( N(eosio.sudo) ); + abi_def abi; + BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); + abi_ser.set_abi(abi); + + while( control->pending_block_state()->header.producer.to_string() == "eosio" ) { + produce_block(); + } + } + + void propose( name proposer, name proposal_name, vector requested_permissions, const transaction& trx ) { + push_action( N(eosio.msig), N(propose), proposer, mvo() + ("proposer", proposer) + ("proposal_name", proposal_name) + ("requested", requested_permissions) + ("trx", trx) + ); + } + + void approve( name proposer, name proposal_name, name approver ) { + push_action( N(eosio.msig), N(approve), approver, mvo() + ("proposer", proposer) + ("proposal_name", proposal_name) + ("level", permission_level{approver, config::active_name} ) + ); + } + + void unapprove( name proposer, name proposal_name, name unapprover ) { + push_action( N(eosio.msig), N(unapprove), unapprover, mvo() + ("proposer", proposer) + ("proposal_name", proposal_name) + ("level", permission_level{unapprover, config::active_name}) + ); + } + + transaction sudo_exec( account_name executer, const transaction& trx, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); + + transaction reqauth( account_name from, const vector& auths, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); + + abi_serializer abi_ser; +}; + +transaction eosio_sudo_tester::sudo_exec( account_name executer, const transaction& trx, uint32_t expiration ) { + fc::variants v; + v.push_back( fc::mutable_variant_object() + ("actor", executer) + ("permission", name{config::active_name}) + ); + v.push_back( fc::mutable_variant_object() + ("actor", "eosio.sudo") + ("permission", name{config::active_name}) + ); + auto act_obj = fc::mutable_variant_object() + ("account", "eosio.sudo") + ("name", "exec") + ("authorization", v) + ("data", fc::mutable_variant_object()("executer", executer)("trx", trx) ); + transaction trx2; + set_transaction_headers(trx2, expiration); + action act; + abi_serializer::from_variant( act_obj, act, get_resolver() ); + trx2.actions.push_back( std::move(act) ); + return trx2; +} + +transaction eosio_sudo_tester::reqauth( account_name from, const vector& auths, uint32_t expiration ) { + fc::variants v; + for ( auto& level : auths ) { + v.push_back(fc::mutable_variant_object() + ("actor", level.actor) + ("permission", level.permission) + ); + } + auto act_obj = fc::mutable_variant_object() + ("account", name{config::system_account_name}) + ("name", "reqauth") + ("authorization", v) + ("data", fc::mutable_variant_object() ("from", from) ); + transaction trx; + set_transaction_headers(trx, expiration); + action act; + abi_serializer::from_variant( act_obj, act, get_resolver() ); + trx.actions.push_back( std::move(act) ); + return trx; +} + +BOOST_AUTO_TEST_SUITE(eosio_sudo_tests) + +BOOST_FIXTURE_TEST_CASE( sudo_exec_direct, eosio_sudo_tester ) try { + auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + + { + signed_transaction sudo_trx( sudo_exec( N(alice), trx ), {}, {} ); + /* + set_transaction_headers( sudo_trx ); + sudo_trx.actions.emplace_back( get_action( N(eosio.sudo), N(exec), + {{N(alice), config::active_name}, {N(eosio.sudo), config::active_name}}, + mvo() + ("executer", "alice") + ("trx", trx) + ) ); + */ + sudo_trx.sign( get_private_key( N(alice), "active" ), control->get_chain_id() ); + for( const auto& actor : {"prod1", "prod2", "prod3", "prod4"} ) { + sudo_trx.sign( get_private_key( actor, "active" ), control->get_chain_id() ); + } + push_transaction( sudo_trx ); + } + + produce_block(); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( "eosio", name{trace->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( "reqauth", name{trace->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( sudo_with_msig, eosio_sudo_tester ) try { + auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); + auto sudo_trx = sudo_exec( N(alice), trx ); + + propose( N(carol), N(first), + { {N(alice), N(active)}, + {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, + sudo_trx ); + + approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the sudo::exec action + + // More than 2/3 of block producers approve + approve( N(carol), N(first), N(prod1) ); + approve( N(carol), N(first), N(prod2) ); + approve( N(carol), N(first), N(prod3) ); + approve( N(carol), N(first), N(prod4) ); + + vector traces; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { + if (t->scheduled) { + traces.push_back( t ); + } + } ); + + // Now the proposal should be ready to execute + push_action( N(eosio.msig), N(exec), N(alice), mvo() + ("proposer", "carol") + ("proposal_name", "first") + ("executer", "alice") + ); + + produce_block(); + + BOOST_REQUIRE_EQUAL( 2, traces.size() ); + + BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); + BOOST_REQUIRE_EQUAL( "eosio.sudo", name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); + + BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); + BOOST_REQUIRE_EQUAL( "eosio", name{traces[1]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( "reqauth", name{traces[1]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( sudo_with_msig_unapprove, eosio_sudo_tester ) try { + auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); + auto sudo_trx = sudo_exec( N(alice), trx ); + + propose( N(carol), N(first), + { {N(alice), N(active)}, + {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, + sudo_trx ); + + approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the sudo::exec action + + // 3 of the 4 needed producers approve + approve( N(carol), N(first), N(prod1) ); + approve( N(carol), N(first), N(prod2) ); + approve( N(carol), N(first), N(prod3) ); + + // first producer takes back approval + unapprove( N(carol), N(first), N(prod1) ); + + // fourth producer approves but the total number of approving producers is still 3 which is less than two-thirds of producers + approve( N(carol), N(first), N(prod4) ); + + produce_block(); + + // The proposal should not have sufficient approvals to pass the authorization checks of eosio.sudo::exec. + BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() + ("proposer", "carol") + ("proposal_name", "first") + ("executer", "alice") + ), eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( sudo_with_msig_producers_change, eosio_sudo_tester ) try { + create_accounts( { N(newprod1) } ); + + auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); + auto sudo_trx = sudo_exec( N(alice), trx, 36000 ); + + propose( N(carol), N(first), + { {N(alice), N(active)}, + {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, + sudo_trx ); + + approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the sudo::exec action + + // 2 of the 4 needed producers approve + approve( N(carol), N(first), N(prod1) ); + approve( N(carol), N(first), N(prod2) ); + + produce_block(); + + set_producers( {N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(newprod1)} ); // With 6 producers, the 2/3+1 threshold becomes 5 + + while( control->pending_block_state()->active_schedule.producers.size() != 6 ) { + produce_block(); + } + + // Now two more block producers approve which would have been sufficient under the old schedule but not the new one. + approve( N(carol), N(first), N(prod3) ); + approve( N(carol), N(first), N(prod4) ); + + produce_block(); + + // The proposal has four of the five requested approvals but they are not sufficient to satisfy the authorization checks of eosio.sudo::exec. + BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() + ("proposer", "carol") + ("proposal_name", "first") + ("executer", "alice") + ), eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + + // Unfortunately the new producer cannot approve because they were not in the original requested approvals. + BOOST_REQUIRE_EXCEPTION( approve( N(carol), N(first), N(newprod1) ), + eosio_assert_message_exception, + eosio_assert_message_is("approval is not on the list of requested approvals") + ); + + // But prod5 still can provide the fifth approval necessary to satisfy the 2/3+1 threshold of the new producer set + approve( N(carol), N(first), N(prod5) ); + + vector traces; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { + if (t->scheduled) { + traces.push_back( t ); + } + } ); + + // Now the proposal should be ready to execute + push_action( N(eosio.msig), N(exec), N(alice), mvo() + ("proposer", "carol") + ("proposal_name", "first") + ("executer", "alice") + ); + + produce_block(); + + BOOST_REQUIRE_EQUAL( 2, traces.size() ); + + BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); + BOOST_REQUIRE_EQUAL( "eosio.sudo", name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); + + BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); + BOOST_REQUIRE_EQUAL( "eosio", name{traces[1]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( "reqauth", name{traces[1]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); + +} FC_LOG_AND_RETHROW() + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.system_tester.hpp.in b/tests/eosio.system_tester.hpp similarity index 96% rename from tests/eosio.system_tester.hpp.in rename to tests/eosio.system_tester.hpp index a12e9068..ff90f8d3 100644 --- a/tests/eosio.system_tester.hpp.in +++ b/tests/eosio.system_tester.hpp @@ -6,6 +6,7 @@ #include #include +#include "contracts.hpp" #include #include @@ -43,11 +44,8 @@ class eosio_system_tester : public TESTER { produce_blocks( 100 ); - - //const auto eosio_token = read_wasm("../deps/eosio.token/bin/eosio.token/eosio.token.wasm"); - //const auto eosio_token_abi = read_abi("../deps/eosio.token/bin/eosio.token/eosio.token.abi"); - set_code( N(eosio.token), read_wasm("${CONTRACT_DIR}/deps/eosio.token/bin/eosio.token/eosio.token.wasm") ); - set_abi( N(eosio.token), read_abi("${CONTRACT_DIR}/deps/eosio.token/bin/eosio.token/eosio.token.abi").data() ); + set_code( N(eosio.token), contracts::token_wasm()); + set_abi( N(eosio.token), contracts::token_abi().data() ); { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; @@ -58,9 +56,8 @@ class eosio_system_tester : public TESTER { create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); issue(config::system_account_name, core_from_string("1000000000.0000")); BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance( "eosio" ) ); - - set_code( config::system_account_name, read_wasm("${CONTRACT_DIR}/bin/eosio.system/eosio.system.wasm") ); - set_abi( config::system_account_name, read_abi("${CONTRACT_DIR}/bin/eosio.system/eosio.system.abi").data() ); + set_code( config::system_account_name, contracts::system_wasm() ); + set_abi( config::system_account_name, contracts::system_abi().data() ); { const auto& accnt = control->db().get( config::system_account_name ); @@ -396,7 +393,7 @@ class eosio_system_tester : public TESTER { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); } -#if 0 + abi_serializer initialize_multisig() { abi_serializer msig_abi_ser; { @@ -409,9 +406,9 @@ class eosio_system_tester : public TESTER { ("account", "eosio.msig") ("is_priv", 1) ); - - set_code( N(eosio.msig), eosio_msig_wast ); - set_abi( N(eosio.msig), eosio_msig_abi ); + + set_code( N(eosio.msig), contracts::msig_wasm() ); + set_abi( N(eosio.msig), contracts::msig_abi().data() ); produce_blocks(); const auto& accnt = control->db().get( N(eosio.msig) ); @@ -421,7 +418,7 @@ class eosio_system_tester : public TESTER { } return msig_abi_ser; } -#endif + //helper function vector active_and_vote_producers() { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index a808afa6..03351a5e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1686,7 +1686,6 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni } FC_LOG_AND_RETHROW() -#if 0 BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { //install multisig contract abi_serializer msig_abi_ser = initialize_multisig(); @@ -1709,7 +1708,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) prod_perms.push_back( { name(x), config::active_name } ); } //prepare system contract with different hash (contract differs in one byte) - string eosio_system_wast2 = eosio_system_wast; + string eosio_system_wast2 = contracts::system_wast(); string msg = "producer votes must be unique and sorted"; auto pos = eosio_system_wast2.find(msg); BOOST_REQUIRE( pos != std::string::npos ); @@ -1792,7 +1791,6 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) produce_blocks( 250 ); } FC_LOG_AND_RETHROW() -#endif BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { @@ -2448,7 +2446,6 @@ BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -#if 0 BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { //install multisig contract abi_serializer msig_abi_ser = initialize_multisig(); @@ -2539,7 +2536,6 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( params.max_transaction_lifetime, active_params.max_transaction_lifetime ); } FC_LOG_AND_RETHROW() -#endif BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp new file mode 100644 index 00000000..1c85d7fe --- /dev/null +++ b/tests/eosio.token_tests.cpp @@ -0,0 +1,266 @@ +#include +#include +#include +#include "eosio.system_tester.hpp" + +#include + +#include + +using namespace eosio::testing; +using namespace eosio; +using namespace eosio::chain; +using namespace eosio::testing; +using namespace fc; +using namespace std; + +using mvo = fc::mutable_variant_object; + +class eosio_token_tester : public tester { +public: + + eosio_token_tester() { + produce_blocks( 2 ); + + create_accounts( { N(alice), N(bob), N(carol), N(eosio.token) } ); + produce_blocks( 2 ); + + set_code( N(eosio.token), contracts::token_wasm() ); + set_abi( N(eosio.token), contracts::token_abi().data() ); + + produce_blocks(); + + const auto& accnt = control->db().get( N(eosio.token) ); + abi_def abi; + BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); + abi_ser.set_abi(abi); + } + + action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) { + string action_type_name = abi_ser.get_action_type(name); + + action act; + act.account = N(eosio.token); + act.name = name; + act.data = abi_ser.variant_to_binary( action_type_name, data ); + + return base_tester::push_action( std::move(act), uint64_t(signer)); + } + + fc::variant get_stats( const string& symbolname ) + { + auto symb = eosio::chain::symbol::from_string(symbolname); + auto symbol_code = symb.to_symbol_code().value; + vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data ); + } + + fc::variant get_account( account_name acc, const string& symbolname) + { + auto symb = eosio::chain::symbol::from_string(symbolname); + auto symbol_code = symb.to_symbol_code().value; + vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data ); + } + + action_result create( account_name issuer, + asset maximum_supply ) { + + return push_action( N(eosio.token), N(create), mvo() + ( "issuer", issuer) + ( "maximum_supply", maximum_supply) + ); + } + + action_result issue( account_name issuer, account_name to, asset quantity, string memo ) { + return push_action( issuer, N(issue), mvo() + ( "to", to) + ( "quantity", quantity) + ( "memo", memo) + ); + } + + action_result transfer( account_name from, + account_name to, + asset quantity, + string memo ) { + return push_action( from, N(transfer), mvo() + ( "from", from) + ( "to", to) + ( "quantity", quantity) + ( "memo", memo) + ); + } + + abi_serializer abi_ser; +}; + +BOOST_AUTO_TEST_SUITE(eosio_token_tests) + +BOOST_FIXTURE_TEST_CASE( create_tests, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("1000.000 TKN")); + auto stats = get_stats("3,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "0.000 TKN") + ("max_supply", "1000.000 TKN") + ("issuer", "alice") + ); + produce_blocks(1); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( create_negative_max_supply, eosio_token_tester ) try { + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "max-supply must be positive" ), + create( N(alice), asset::from_string("-1000.000 TKN")) + ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( symbol_already_exists, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("100 TKN")); + auto stats = get_stats("0,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "0 TKN") + ("max_supply", "100 TKN") + ("issuer", "alice") + ); + produce_blocks(1); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "token with symbol already exists" ), + create( N(alice), asset::from_string("100 TKN")) + ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("4611686018427387903 TKN")); + auto stats = get_stats("0,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "0 TKN") + ("max_supply", "4611686018427387903 TKN") + ("issuer", "alice") + ); + produce_blocks(1); + + asset max(10, symbol(SY(0, NKT))); + share_type amount = 4611686018427387904; + static_assert(sizeof(share_type) <= sizeof(asset), "asset changed so test is no longer valid"); + static_assert(std::is_trivially_copyable::value, "asset is not trivially copyable"); + memcpy(&max, &amount, sizeof(share_type)); // hack in an invalid amount + + BOOST_CHECK_EXCEPTION( create( N(alice), max) , asset_type_exception, [](const asset_type_exception& e) { + return expect_assert_message(e, "magnitude of asset amount must be less than 2^62"); + }); + + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("1.000000000000000000 TKN")); + auto stats = get_stats("18,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "0.000000000000000000 TKN") + ("max_supply", "1.000000000000000000 TKN") + ("issuer", "alice") + ); + produce_blocks(1); + + asset max(10, symbol(SY(0, NKT))); + //1.0000000000000000000 => 0x8ac7230489e80000L + share_type amount = 0x8ac7230489e80000L; + static_assert(sizeof(share_type) <= sizeof(asset), "asset changed so test is no longer valid"); + static_assert(std::is_trivially_copyable::value, "asset is not trivially copyable"); + memcpy(&max, &amount, sizeof(share_type)); // hack in an invalid amount + + BOOST_CHECK_EXCEPTION( create( N(alice), max) , asset_type_exception, [](const asset_type_exception& e) { + return expect_assert_message(e, "magnitude of asset amount must be less than 2^62"); + }); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("1000.000 TKN")); + produce_blocks(1); + + issue( N(alice), N(alice), asset::from_string("500.000 TKN"), "hola" ); + + auto stats = get_stats("3,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "500.000 TKN") + ("max_supply", "1000.000 TKN") + ("issuer", "alice") + ); + + auto alice_balance = get_account(N(alice), "3,TKN"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "500.000 TKN") + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "quantity exceeds available supply" ), + issue( N(alice), N(alice), asset::from_string("500.001 TKN"), "hola" ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must issue positive quantity" ), + issue( N(alice), N(alice), asset::from_string("-1.000 TKN"), "hola" ) + ); + + BOOST_REQUIRE_EQUAL( success(), + issue( N(alice), N(alice), asset::from_string("1.000 TKN"), "hola" ) + ); + + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("1000 CERO")); + produce_blocks(1); + + issue( N(alice), N(alice), asset::from_string("1000 CERO"), "hola" ); + + auto stats = get_stats("0,CERO"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "1000 CERO") + ("max_supply", "1000 CERO") + ("issuer", "alice") + ); + + auto alice_balance = get_account(N(alice), "0,CERO"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "1000 CERO") + ); + + transfer( N(alice), N(bob), asset::from_string("300 CERO"), "hola" ); + + alice_balance = get_account(N(alice), "0,CERO"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "700 CERO") + ("frozen", 0) + ("whitelist", 1) + ); + + auto bob_balance = get_account(N(bob), "0,CERO"); + REQUIRE_MATCHING_OBJECT( bob_balance, mvo() + ("balance", "300 CERO") + ("frozen", 0) + ("whitelist", 1) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "overdrawn balance" ), + transfer( N(alice), N(bob), asset::from_string("701 CERO"), "hola" ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must transfer positive quantity" ), + transfer( N(alice), N(bob), asset::from_string("-1000 CERO"), "hola" ) + ); + + +} FC_LOG_AND_RETHROW() + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_contracts/exchange.wasm b/tests/test_contracts/exchange.wasm new file mode 100644 index 0000000000000000000000000000000000000000..8880a905c9e52813621b3745938a95c588d0d0c5 GIT binary patch literal 72187 zcmeFa3z%KkQRllK=hf$&?%uMVu?*Sg5TKRV(2`|IHX+vTNPgzwXJRr8k}S0&wPZUp1_bxzALicBzRU^^)GYLh1xxH56B?A4{I< zzNu>r+vlaTd2^&k$Bu=^=p}!mW5>f|(H~XPczpkn>W+sGOil$AJtsSMPVG6cf7`Ad zQ#-aD+Vg|s!7@wUd3bVieE-z8$?=`zdyb4x22~}u^W>>LkB+;f)~<)QJ+f#2u5EiZ ztPdK>)FkEI<5QL}poHZl?Adj6!+MwT;N+f1cT7GW4C>p`;@iFh?-`$b_`u=)yMkeT z87#i+A3r)33@L56NShpg^uUqvpsm!QBK6SJfywdUn*OYZ4>Gv%AXMrSvX%{%eby+{ zjHOspYTh+sY1UAiG;6|=TB=alTmzQYR9budz@a?{w(U4{XdE!tmDF@e<45;Qxjr{` z?>Mw=$Kk2n!BTy%Jv#pA&V!E!2Cq60+CR1Hkzk2^vbQ}!Qoii(eL3VSv}}jA?Q;#f zIu83{$>jKsUE6x5+JUn@IsVw;J(J_EBi6uRZ_>J;rbd_KX&}R%gL^;=*M95JxaNKT zzCHWLY4ue2W8u)y(6aXO<;#awG*=GQm#jze>7+TS;RI1^@uvV+aVG!1TYS|kE zw=iWnyA6<9ThWpoU3(|QX)@~TphYlb1kN1}FAG-1W z1MdmGZFJka-gcAC@!EAcv^2Y0@4NeL_itOf;o$h>qk9g475lgC8$U9>Z)@m!o~9=*zXzvJ#j>)q(9U9dyy>G0wg4OPl*QuXAm#b+Fnt_4vVYP5rjD z^Lx8B*m%n#)vR6H3%rGA;ns^iu;}YVe`#xd&Mfudp?zNa=;3`+d*B7T#*g0lmdDqQ zuD^NXP3t$@yza)EHr#mA`b`@)t~30&$#?4@98&Af*1OcVQ7Z=)Km0g_*Kb^R^M;#l zylLZ&H?6(-<{NKZzkYP<+irUJz=1~r(5^+<5X`bB`dejhZq^>Ihq^GNW{ z{fiV^yU8P$if=mvmW&^w76G7lSO&he8*bdR{-&Ep*Kb_EZX*ELu-?FTlVb4S3-DW>GS6Oo@_Bt+~@@ahx>~G^ZpyR1^0b$QFz|yk*BESe|CW0fBUxJ{%>6b zrt1&wI5G~6K2R>an{sZxao4y}$imD!c<0)p&Z5Ys_w1S4y=!vEdlo6P?c3&;SqJwL zU5#$L31+`*d~2}%J1&=N)8T`D?t;nJUoImnh-fd*eCSQ{GjH69KsPmh)Vh0F4B?f0nvn4tBIr2}Aj|U$Q2L{6+3tF{Lgi}Yi zJ^s$-zx|u|$HI1y25Fe3$+O|sR^Q7|`6UZ(Z#5B#$7WA_@AR`ReOVLRpGNX6t)Gs< z_{lU(!!>c^Q(I6~`FHWwG$u>8_Nla%Mm!z+)HB7WnKT-SRz2t5H-BjJGs!dI(`P<> zu3NP_j%|z^X_S}SNJC+^YJxgC6`m4%s?qDJJ_Tt_*{frh{J&d|6_1yK2eKqtlGer= zCp)z)=!DVcXmh+dtv#Eqn#xq*y%X7&E?xSA@a{prS;lT{>{9stvEaVJKshN|ro^-# zPISYpe#cP=}!qy?R*l}6e5fQEy#vN29tza7QllW3<;3MNTDntQX0%0p5k zAJ)CusgNYWt5b6TtbfX2lGdN-1z-U>2T1|21Mu>!4uGmAWdf=>;Gds4bFN!|LSW-t z0yz0;&{B}rdtg~F0Js<|>l&qpWqlD?)&)7LDq-255(6Y)8I`aMds93t!xpgVh2;;o zs#U@Ac=%*=JOiIcqDpo?+}j=65D7g_hlU>l=_&VE=W&xqnlKx+r>X-$TVv?|&p^^G z5DhFy+f-oqrx(NOc3Qn}FmzK_)6-Bk6Hb7dj3All4g&bDVW&%PD7`V!Z7Lm%Fz^SR zHpND*l+VixSuMj*+TIw?P_ceT$@pA2q4~{5CahHQ9qFJ;bp)YGn?9kTAzCZx(3<$U zkjHkTl~!D*+o|R;@YV8crd^^=Zp;ibqt@cp< zz+7U^>96i%cy@`|6w8$`wp)t#=}g5%*7R)fjQJl{Ovo5cxU6irlgxI@QX7 zX-SYgCrCzO-d9ovw4smU1dgsn1_cfo2N0zz#ZkH_Bv6A&b}t@{+A4)_NFmw6|O5n*qqP-EMU(ydPN9 zvzLMi;P6tIEV~v)a6XuL1M6Iz!k|G}F~-e2$FLHXDOlnrr6(-0ugof{%v_*GsiL|7 zyU^lZ6}zCSazW}(iRl}Z5|r$Mg|STW3lij3b2wE`qmA($3=E}-9ic}%*2tcBaH*ScQxu;DVqJ)gf zy(S*j{E=ZzJYr7*Gam(d^(n0<--*~lmNoG`bl4WgcMgU^{Xnx@&(24h-85*uE)0*8 zSFjWQj!YyYhSGr;WHQpx+T1!>k1MRjm0~Tv5bW)?RRPN;!cWQq-2i=q%*K|D?&~%u zI->FBR%&ZzqmOo)X{$59%nk4w9_d!eG|{cGHg@Zz)qrRkKG3bLX4R>uz<+f|gnfJ> zt?o^$ymp(C#;6ijcpH^gco34O;XBCcKisaqYjPTCTT`aqv9@c<#*Vv3K-F!I83nYn z7ojbiG}x+e(S|chfe|4wz;4sQIztyx!r&}~c$5gl}Mo|@us-;z-P}B0YN1_oR(iX9V zHrniU%8xkR0^#&j7g(zFqC@j(eQ&3xUh&1CbT1N26a2Mq4lo@6eInbf#sMT_?KCws z8(uXn>QcpYd0E=LExRDO6$Jw-u@b7c#mM*_o1T8|r~c)SJpIu>U_z2gcOVPyP=k!} z`o8iEA&oXfqgj|;h^S8eFd%=o#_fjZvb6bWQ~QR9$<#!Sw7S-uAO z*4xtvPn*znJ`$=IBAWrGn@X4#k&{}ZTQ`t-U_+GZhXHhHKs7PeRbAkIodKc+kn?G7 zffPXF?Etx{?lkxzV?u?rl4>NHt{M0wA0qPgZ?TO+%5M{^!6&{k5_HX%d{vI?|mgxei> z;Ff?|(t!sYa_CzYk_MvsvUH`9Rz#nb>~kOc-0N=}tnwu7OlldA@l;mb->D0?Lbz|3 zM#%=P*2nFe&-?h@t2=cVfH-!OuBs;gbLVOp32ArpoBcb|-!3tUkE8oQ1$c_9^CqeX zKmZ}$3sf|k4(y%;rfj&C(B~7CSnw6Mlio49w>!{jFbPbrSX#g&3dD7By;a=^VDK^8 zt3^)4C#tKtxlF^`7+bBQ#$gT>z{}ocPIZC|{Za*1l1e)@VNEENC#k|6Uwb4A4`rvS z$r8(4%bu#-N$y(mb77}KR`rUyhbOXwkL~SNgdvQ%LWb(KDe&G9z0Uol`hnoJaF5Vz zEt{^qRg;l?JY?n#v*~7IBzj$^0@jLpP^N|6HAg+HlWsAp?9J+TXXoe>K&)g9E%a0l z2eH@{AJ8?WVixFK4_SAc6jA~aUFL`ec3y)pI7fZ8?86*?O~6QQ9&h|pMS)e|N` z^)L<*nvkX-v_RrZ!~J0aY_JfC&=}7u7V5m9BeY6MXqBAMDq^xgQ$(P3t=9Uv3X~Q- zSqBp&`Un%!z1`u?5V?kxCDi;^x-rwnu(Y@c$5{nKzY4ChRS>voVxyFdm98NLS1aR-RBo~;s*GO#Y}D>Z5ze4yJ{Z48_NYME?{Wb1purN-)R z+ZcK%hF&+MVIdKQ4ccn?E~EgYOM~iAI;dU`X)#Qk0H~FBC_xn!+_Wy3Z3D@(B9y1M zW4E4sRw#L~!u0!rcAKB*3}%f^n{LzT3C1uuRzKMtH2aFyDlY{HAh!Nws}Al>+hjEU zKp}_LZK1W+KY^H3kJe2?>mhM(Nyb2iDbfO8zbm_-e!z|$8uHQ5utK(avK9fQQ(vjH;UbJbX$ENA@v2_<2!JQkSikeHMmwH%-A%vv3ODQctVm zXj?U3LIMa9=3v^33^T?jg5>EC(LrQmf+^GiZxC64Gid9MO0+D9h%jZ4(J0z#L_h;> zt0p>C*L63?U5BqGOfa9ux8N8O;Ul-qgs`$Swz{*UqV=P~4fj5!_o?#zpxzIb@32Rv zM5|01nb@P1LbV$+^~0(=h79Y-R~h$&I0i!tm>T#gC{6doaJ$IK0o4K)_ce56E-M6I zcrn5>DJrzTG;d-LHP!UFrqtF?RVwk5wSICR087>pAsND7(N%OYei z3=`DoLsyu@6!8O@m~JJ-@z zif4-K2O;~xg6t`jq?Kb`vLfK*R6i|h!#+xlNMLhVKpPeiF((XQ0(RFH3us@S1w>?Y zEFkhMAnIWOD8ctEQ0&_lwh2_ zZBUd28f!7=Hhh)`NQIrhYp{}51k99G7k<(*`AT?;z+nmCZ%p%;(y>%as1xl=piS!% z>IOvM`qm@VwG36Tz2Am}6oHSfLk|o_*h#+J%Gw%US(!&TB>e`R6NRKz34dC)Su2nZ z(>Pg&b&ihP&`_ETMuLLIRMv zqXMIcEUV8-zQaHQSymxS8Re&7nwNsdCT|IbZE?_Y6!=9I(MaMDYp|Jez(d!)t_fda zH=0<#XjD9xl~ioYPjAcWNmp!8)#q!rRgXPG(xb1NT(0g#vSKT_^4zklERdU}R0fCG z_&-2xIG|z(`K>st9e3Q?=}@9CX;E&`HXQCodtrb4G0JXEAd8Fg!49v;2vM9O6G@Dr zK3@H2=`Nr}69oWdjeNEKm$e?OOC!@>a&dv#v4tP~BNDKI3k*W$hLn`FA)q%T2s*x7 zSRM^o#Rd!H1;?dc7VpLsq^Hso(IuiDbXa`WO50OhUkp(}X(6QbMy=B+kz z)nU);t*zQqn+UEtuQL!el2T518me2col-4vRyqJ=L2LANK(nKFrvN!Baq8PlT&QnO zY@fwgCEZP86XlT-JgqdwBsUqMAb*HZA_%1+!&`7?HY*LsR`13Qfvx0V3*sEK1|t{U zz=JM@k9BKPpGd1GsHv9Kr9sD8{fHxv>a*QglN7^#p*~rG7zkOcv6zHSjyR=b!DVEq zfFG0u(-2KA&Y0rJ1Z%-SkKIU?blDf_2dKRe7&%NtXqt_$~}CMcW|q|axg0`^0zE?z z_bdQCzzaDg7pV$glOKZ2xX7-t03D|dEn@iyIs?KVncnICfOye>2AH>FJlQC*sZME* zvDygFgjObNk_4i;1}Q2nQ9lfoFCt&S>MXRTJ0cXctOKTswpjYpSmqO?dF!|>W!PJ> zv132iYAfWnRB&5a5FDh?Xk7r{p-ht`w=SXnV_8Te>wx;)|DPigx1512nm1?-y+nN+ zq>?mxyE(m(%J?!Q)xE;aeS49&BYx?SyaH?s9@PnGWDiYH@}Yc=8`&>WRcB~*gGs%gT2H{Fw>`e|!cqLDc&<$y%_5rJ#TKCk6 zQm!`!$fkEXFp-To8OFRdjDO0o0d5qiDq{fe1*%$3qchOcr1t!iPlbt|wIltE0PpiHsjDbq?yhXK#2R*KtT+qUNW}SDa z7kNSAVG6+=bgEx5bV|ZREODIB8tDvR3vmf@Eqfhn zx=7a`rq>>zIj<@QEmdb@S6RejBgh>0w4C)}rjcaM>pW}A#fXAOuonUK3ESalT5)?x zMJsOpZo3JR9E@oEVrfL~f>t=1>vD8%Td^%2hwu@oss$tIW&E9b`eVo1VtUJfVBWZT7=Lu)MsPe&A-iO?m-Dj$&d%89N#g-ASG)^@I};*;g$bLHc&>QQ^2 zR_Cnhe1STvW6=rc8yLvb!nqy<*^6bt&zFxE%EvGCRrivryGV7uV=tFAO~=L9PLz)) zi${&{l#D;8V|wGpH4_&dIa_4RK3+baD;_1bJg4HnN^$xC_@d-yo@TLKn5r1uo}HI| z%yuU8=-qvS)(0w)w#(9hNdOaNQtd`#CqDWoA66&W^OvWtte;F~CuHHkt`Tj9io<6Y zcGeBa*bRIAdHPdiJ4GkQmX$l}_NBn(AcPL296Ns=>(~e#1NT#YMqh3Hla`$QwTX@3 z5cOtu{Gv8jpV0N?3h=P!jU#6yq^j+BFIpQm8P83o0nJ?yl)C}xtS15rXH3Opsfo1 zX|M-4J$>=xzy1gR5ThIpDz)tRTclXB`E$$VYjMb8{6-@Azb?&7*jxYS@(##-1Kf73 zd;?nWPV)sYmW$zPgWxTJ3)g|~@jLuqB&BDIKM~DB?|zs6i{aOHoBxfrmd)Abr+0HV z^#5CktD6)i_!2W$TGm)XG?Qj7hLhVf@xLamHc`YxshhCA~y^CE9Q>9>xC9r zm%Ab}x9@jFRuo<&lO*5EkDU0vxAhD0H#exIFop=Oh*PhI4QjmP= zhrl^c%gtX>1hN1)flT52{v|(>bUKxJ(Mj&SBWv64<|s zZ|-oo&5o0#jhmhK-GJ10NU3!uinX2C=a|zJjWtDEa?|!BclxH^M+X>kr}T=!pZ%f~ z18u@#U8r|sxv#TL#&@~Lxgr&>%nZmCVpZ3?DhIIpbpQdb4Q2$@KCEi4N{xxk$i5p} zns)24ixz4ORf3&TWK@9^846-Tb$X2U5AcalJ^bnGVKu2FTlzAyb1yy7b{fQjoZM;} z5Z%(QzhLwq9gJ!PBVxPN_>gfWW^j5yKE}4dNFBO^jj-bw?UbPZ*~X;Kll1k*wvM$8 zmq=riortV5jopF4(10)XUjGTV1lk7YYEAKC?i-!hwP+1Q9=gceg07wM&}KphixRsQ zooY-aR4=H+f^HpKrfqVXwwP9P=mKd9qmp>YQfM>IKz4dTR!?=)j9_~4SPp{p4J}}b35sCUQ&%x=2gEyn@Rt>-c zwNsH(X|0A;Xv*5X1_}*^FB_SLZ#r@Vh---53UH8XcYc;b-YwZI)%$`T{MLw|>cGjC znIWt>#HeB#^0qfYSqi$jS<`iM?lFCe8sQ^#xE5I?P`d+3tnYM7Jj6PMgNy46pw3<8 z8_bAyZEeEx25c7k8(>PEsaQo*bF~0`TaqCgg`K^kX(8ubLQX-0KYep&NGS*=HS*~g z3U=FMpl7ODFO)jGTb4)jRk@2l%ZBKBO<2))n-_VL0l9AwH~$3`dB}n(Yw*)xzVN%Z zr|Wr2WEzvdf3j5yJ-I+Ntr4~4HZoyS>Gj=L4KRo;Z|3uPpb{+Gr9c=mHJ;V z$E2!OL`*?WfpP5I%Wbt<5WLiLOZS}cS&;dWnDYItkbIUvV7_-dy2g*$~rl~ zPI{igIj?>g zo}zk+<0(w)8_sfMGJcGa(*%J+G12Ns9o84@z8RSiawm&m0cW2 zR^fOMCU488n|fsRPgdHGKXfT8TvsdVrhGxI@-kbPmy%XKa;F08m9#tnt@E^Lur>&iYqRqp6wWl>n~EK!XS?`64U;R-Ss3Mv-I=l1 zkSiKXe1=6nue$ta*_T!QBBe(z|9SNCpEnhsdwVUA$OBgpc_PH~Ou~#E*5v`&ovswL zDhw=XRUo##ApVY`^d?cBs+D1GE;N%Rt^d%j)ou3(<93fS zFXoigmiTWQ+C!4%TGTE%;+XQL}4* zUpAxnr6$nZmQf9jL5>Vdv*&PvgNu++KTAC6y7UIFvZV8qAE;RB_o<$XXlc}W<#vYB zrMzKyafe3FM!XMgjL-2aE-LmSSxzM55*+h!3F%Ve>ES4NRNXV~tCVx*I=EDiXL;Ps zM?CwK#r{&O%g#;?Rl1$JhRZ~AWn;Ey!yv3U1IfRr;`3Dea+qq!HUu}umqOQjHVG*- zxA#hz+xwRhJ?|kixT$Z{e9;7I>-|eSZswyl8f&gbmsLGq6Q7E@Lw<_R+Z3&dXQFP~ zI_0B%{edvU>0GwEFTlQbR>E~rg`e1j|z-9LRQBoNjO(R;w+D=_{NH0kQh;& zwijnb&x0-6=44dtltw1(7YHm(SiM!23kpZ1JxIQ$MD-x)MUGtawcGaaA&lb{0!Nin zN8N3yK{sw+2AbNUuA&?a_EFol+QUeaH;X<+uF5QipE=FXS3eU2i;Z7)4-qE2i!~$?6Emhy zd{=hn7ulDsDxWk{E8y6~6N*0|wTa-BL!WvE*##YNMw%(@3m8K24beJC^n@sWu93q+a>`FQRbB0A`!jLlQ1Hc9ZXR%b{Nk$ApVP)+{?ErN~BecDo%0 z8x{|_eQ#AIQbB2^E$_d(pc$-3%%Ev!1{*}o=q-uzEvW>{9Nl?B!FqX5dDmL?1WdS% zr3u!-4lF<7sqo7|TBedM=`cK%qd-oA8A`SoPi^47uqZb*dmK9;*yFZvxJIT-8X5~8 z%r0utRI7S9MYC2(9rw44oU&8w8^ zmK~LnCNS4zk(#D zMJVmGXlW3Vn7dHyroDka`IBR4!;;jJrZ!P1<$tI});h(K8q83fL*>7&plTaZ*y@Nz5)8e4bXk-Ik;I1-6dYh}^?)*h>nB1&#gL6Cokjb4aa`NjS zkIl)w*#+T=nP%O(cdR?0bZ6%j&21?}17ODGBF&U~Lm*d}@|pmtMiSm8POYeIOj%rJ|rBL?ZlQ@%^^n>txLiaoy>Jd;>`H!P+0@hM|Pfv@qd9na~#mJ z>yC5Uti_%+dq~@YZFA?i&oPH{VF6hr;e76bBC(h|z>LBPtlycPXD*FJ>h!J{gO>WH zU+RTQ-S#6`o|_MI97GMiiQDdWg*xtn4NN^tm<$Qf`N3Ig)n! zxe$H7hxK!8SOEmJ^w?gO^XxK2X9YkDv4cQm0IZ8)vBedP{`UgExamj_e(+i?J6{Z$GiCO|TA-s|T`f5Z%f`9` z2Z6vftctu3HLUq={{522RV?2O<0^80RYjV(zte~`{hrn~Q3zav^Kf8}B;jC4+C41rpIQ75{0 ze7w?Q_nU?fC=d$*l8J#3Th2r-aa9BtX}EvEJ0L;hxg6y~9@3HK7=db$gM1Ag3TpHo zhYiR>eF+jqpTY`st;c$|j_nOnr6i9-It=+1kI_emGH47&_9Fw{YF>$>=pB6Al(wHR!{CpPjWLZph%Ob<( zv}NLt1b~4AP^YaMf`>9^VCMYyb~`-N(n_orG~anOmgeU+PZOTfHnkuMYjrB8akO^| zL)Nau!dopglcTQqLK7*e-X=1zi6o~ca+90L^$SlVwHa{S81k-aA$Q{{?;(+CE=DyQK3D zk>NT6pjRWiIMgB1iek|^)G~++jMar+b)i?SAH8as&`TjoDJA#c9KDF7Z|GI)MK4a< z*K+hi9BT=^;0_+WNFhYEh0GFq4KV2D3By^?tKrd0XWu24_Yk%v$x*DNYfCaV;i+3; za?lEhYMFu(3N7wveHDl6sW6osbtb%)^rkR|m^z#h!Lb3gt*#P`UQRd)dw_bMdR(#> zT9$*Xi(+RfG%Onrwa6)&A|T!auH@^AlC)~4;nVgF!3d`E@Q6nL*lHl03I?@L00FD+ zIsiJX6RWDl*zr9zJiHNdBI}nKu9qKUBImd94ask|bwqhd(Oi zK0M&!Y*`n*Lv{HP$8#%{{SFxM6=bp^>~0!5_X}Q$ zHO(eg$|6#c)47Y%M|4@bL43Ns2)J6!V#VFn@fqUo5^FN85Q~q1KN!(!qG|=jge?#p zE&%jwbhzXGs@|3-O)vg?c)$(@x@|@)A^%tWztjilWm`niQiz_%zJ-quZq;akV}|nL ztOM4P9kJJV&|m2#8#(H67Ro>&pRdRkem?7V29neT)=&MIA^_{5PXeP384kBvzY%_8 zn)z}mH=Rg+pfwxWB@}%T<8Y^u!U9#{-OQ@YoG8w&qWzd#rR@%Yn)r|>-53QYs~rA> z%>XMdk&m&xLPIR0j)s7uU3^esab|a{L&OhCUPlF0@Cs_wl*G&jFVG^v55V`lKEh1( z*9R8VjV^U77&vuN#z~gne)j z`$`RrTrk13k$gXHH-GfAf?X795cq*=z6tq$DsJVUxu~tUQYl z1m6?1DheKooHm7qnFkLQ3srxET;YIT92VD$2%A=GHYtQpr5d|65ugR$qX;_MiN zIx*Cy_T`jpb=Q5}3OE5B+JMU_h*sxfSv`2>E=_VbY*j4FCG;yW}aO5T6 zs8<5k;j>%<9+13@1nkgD3Kl7vb$GCxQQ7oR}Ss!74Bc?r0wxymQQD-cahcn~Zj;;%2@#(qRt3M@9mx*$gm6WrhH^o!V zidMQJn-#6dUa3u*3%t0Vj$E#%qtYY9%MF zCq#S!sn5yiAj(~dhr>j=at#&89fAb82Ar+|K~h4S$WdX#i+b-$!KFH+~Qf@uxA>Rv9Zo8~yJ@7js-@nre1MaJy2<>QORqp?)2w8Z7`LA<0~L@k=ZGiO<9iL#=@X7qC{neo|yo!#;(&c$xOMsm$D-z6RXmftje4kco`cIkflRZxJ_z*Rn zrMs@vRx8hx#F+?;h!t6rRMejqzxYd_#FLlz0e*#m#6)c##Nk%9-3%~HhNYcp*TmBCk9LKVMH2h|dwN-}`X zg(X`S2Fn-uwSWxdTHzwBt)vn$-x8#}_d%48D{}A(m~zERsE@}NZKHCftT(=YsxDn= za0J5kqOUyURS5EG&`R-;r>nkc>N^`L^fn8d1Mf?QM0PM1x=iGcoa}Ip$>JPc&3v*l zyPz*NtNB-|doJROoQcIK9XIM$?m<*%3g8LRJF|;0B|ytp<4fkywG#0{D*_ec#xfg< z4e9*RN{?md1w^(kJROVaOovXb&!(4X*@Rc6KBaBhpH^u>goPje=@$NFG^d4s zg%8*L7qRQt&bz*d|X52`7F<8OVAs{av_Te63DYtC9pmGfw5V!zk0wvwGgmJ1Y$qN z9>gZujcgvM<+C^9K|OL=NE`PMhp~ET15OK!gyxNV!Ccr=#g@xu4r9F!A8^gffT=biRVW#Ndw5Cl< zv?himAviJYaqchY$mu_luZ#`mQzc&@Pa6T)jr2H=EMiX%j?pv5h-m@&M@8cxZG0y->@pb zBnz9vsXUqVqE2%xlqE$z=#6gUo^F-tvwa6VNL&zuvF4MKk;jhX>@XHSh|27A=1xe{ zcR zU{P19QjU|Sp_XaIwM@a|$%^dUH9D68mwin(t4I36Nf5Lp+Hd`Zvu2ehhV$6roiPTS zbDQZ3{h)n86Lac{BDx860L(zW^f)rYle@m&T{8JtL z!!MQ<8ExnV?3Q*rI#-tRV@DIzdtJ1bF)pY=n zxDHg*0S%81pqb3;0FDaQfxI@mj4@>kNF6ZmV~dwzwNKA$kC3fjc6+Y2%eD7nGs*0BUbL0-JYxMa_ya**WL%eg7#c(i?oN0=s6$BbWS*sA_%FB{V68l z3PdS;n^Ux$N95vROhpCr0-25~NX!LYQm#XiGAwH8u^Qd-@`aDy24d?E@)otDsM#f*D!V%8TR?y2hbHX z?ustGN6c-s8#`fCh2)WSeo0;|zrtIs!60F}$-8|K-Sp@g;(BMuWlzgrN)d@2$y(N7 zHOtwN-9zElTSn>mp>5E)&8JwmO>v)w*rBma;A#w0aGg;^&>X77CvZU3W#=P?1i8bi z(9~V~3Rk1|)S&y7S7ml=yOM`?X0a6f1E7K)F!uYu^t(}qjw-;D*>s{sY&wx_I#I7p zr#}UYy=*!d&~vX422`ean~pY<0I>+^Qt|=r?;}seYWuX3a|Z zBE`I$^LuEuuj5X0!^c@Kfw{I50kF1wZIeyaf_W)#w$a9t$#eo`twDD0gce%YwwB3c zFH4iMg6?i@07p{or&u-7=G5I0rIpR5$i*i3-HKW1^SfsiLt>%R-EavFpf@~`uFJEH z2w6cHfEG1w1BIdJa`3J;cIMtfT*C#MVXCCCOjipt6gUUB5Lf4(?ymZ~8moP`5LYE% z_1{8VUHBGa?MNU3(3_q(!z{yyx$za?mAA1QUVZhf>;ev$=IrhZ;1x4o;#ETvTuCN$ zbsY$&@JP(B{gn8HRb5BV`|+!cm89LZ0>3cx3cuJt6qVskrP`P#6J_XGfnS8}67SHC z9)BEi;cmN%In7IHv$5)tDZkFR()!D=?{sI%#*r-sP6X7-^9t)hU=cZNHNco|r*Omr zwe^(mP8RP95K-<*^7)1!xg~gQ`CVF2_F8|npnYG`_kBt4cUBF_(beo4w`v&iiqDrz zM^r8yRiG*k_h%fkC^(!y%qm)8qZqA%{nI>xti8|ij+^7zmuF>iUn#ebO%P{8KC4+> zSjK5o2xiKMttXr~xc!zO(HC}Wi*myYmb1CiDl}}RIKBYa$+s)N8B@S*FMXrL6!_0! ztPnxvK0MTDq8X?ljUzN{;km0*B_@P9-OR6EZlN{OtBKCAVdbR7zW5}RVw>Z9>!&+y zc*Em!y0h=SbXUuuyYhSJ#H3Pc5~fNdwc{-;+$@LCq`y9!C9>yuM;ezDDK{oj!UVouw`eEdsC{o1^o}6TTAmlqVH8$w%`HKD zv2yLplzaUx!Qf)$1}{_Y4YveCi2cg*Rc zU))hhN$*tEBkmNsmpnA)iaUt#5_eQm6la&I=i(0de?&t2DIye`JYMr+O07@asm&L6 zY72`yH81Yu^|)&lX6+zYEjfUd5gAT<(_X4L=x+Z8zv=BSPisNxr$=f+MM7!os0dJO*8wX9_52#b#kQ|o>?)b1G%)Ab+suciM+b=Wx>yuk1v*w zpVwni-33+m64lv;BBLp5dbup~Kg!2x_Arq&d~Z$?AU`|BeY3tJrz=HAW{Qm2&y*cPXOG7k}A(bgK+_8MDx3X>arC}V=PGFuUyEY}Zr%jT**XJ%bYK_cJFy;s) z+Pp_%SayD?{64tJygX1>&)q%Y1-N_O;|t^V0ef(kcH6$h?ZeJt4bURfj=v{a6@Sy5 zTQ@`xh;f`>%25;@sH1F7OiYR7pM12;iz9E68IwycJU*J@7~2&s0YRLP2scgh_rR6% z9`Eka9El#XjY>F_Luc*THphg@Bf>!3VKx<@Akh$SV|<4nTJE1g3E+}lC}9!`NKE(Q zFd>#^KTHO+=N}3Z1x&D6mN3DHm&1gz1x)CJ!GuFjMyn1aq#8&_?S}~Q=Qsp!5K)H3 zAtH*!HNYs>xdy-!?cOr;HU%x5Yk*;hJ^oV77Sz&Qa-NeMioa?Q%)L&dSM{2DQH;x! z4uu6-CN8GlyTuEWqa%QMIrC+7yGKasOny(I$OIKO}=(9^0+AT!SWHN=WEgkPwW007Gk${G1#*B zxgw)meO*Uje0g!LT^piV)$kc=pc`;ftz1N_WMdw^w|C{TSGRJ#0_(QRj+jTse=YQ- ze{)g2)nm;W#17lOCuiHF_HcZLQoI$#Ua(@g+xT(?&sGj-$$reshAE28*7l_pl^R|& zy+%e+%@U)UL^3FG`78pCkn(cp8u%_O?O?9%5a$s-HnfNcIwY-ls8@Dl*5{s+WoeQ}o;Sk_c)^cCqN?spa%n zVOZ?!A3CE2W0Rd!XFdGCc}GShp?^)_x@eEjsh@0>16Mr>YJ~f%-KVES$K3SOz;FDb zK9kk%5L=?SZ|B+bS%DYR59##ays16Y;2A z{v2PYud!p}P4el)Gs~a?8FlHYiX!*BqV8QSpNsVoFId7EFgEBzV_v0rMHG~+k4~)N zgVxqz@eRd;vQLWRGOG7t6&^Mk(f<9gdH3}Md>YP9!8>{)K5^#7YB?Fw0&}~YAEx@C zd%MTIJ;V=l`GWE=w{+9qnG$=~l=zWaFqaqN{Cz|8nVx5cWrHUOA36X9hY=cP6G9C!b_0;r<3URm=gbd*Dn0`p zb2ORgro4b^JZgKNss!Rh(Vp}L1f({=uf?Mcr5F3J3BXLRgMb$yC#mJ{u5(7?30rk)=Rhy6dVdl_kDP3Ky8iwpA6?=mSdw3z9FdaIc zkmIy=riAFMWsWOAm=qSB2~-gKG|@ynwD>(G1OYc^LTYy~7P!QVOYqPJqjqL&dYePZ zL+HGq%?tvA4qT%jObTm2D)BoFM9QnZ2*XQ&^I4Q;!fNNxp}2?65||NfQnLn7@FYuS zI4-$hO*SxHg1Cuoe02v-w!}1qB{u|&#reoXKddCW6c^esW`>run+_FB?x4N+){gpN z<+_p)6qU`EfHA}VS5R}MQ0*E*^0J#Sk6rB7ad-08Je`SCe8@x(@_!u>6RVuZi$dv)aX^5}^aLhyGyAq+!=M2lkxLlCzOyV{l#$6)AU?eal}5OvQAEOS`iPQ-H4mO3&4v`)qz zFJdOoyylFjE8DP)M3oMDsCT^?7CL6ohZn2)k~ryF>(v5a+Uf}0@jG6Z8=b~7b*6HO>h;@ zc)g_tUmWKB83#F`Mo3w)ld^P^3EILTa7B?4so< zcZw>UOP`9qLMKSKiOVKE_85lo9_~1iyQCZqIeI6BqzeS)Wk}G1^$M@oHfWlcAp^G2 zVL{?aVhFcEi2@Ay3NOQ|^Wcpu@jdXSFNllArT7DAmmcSu_%^0Yys0ok{bmSp|)>s=3ehlKPh$ zf>pMw#x97G`%t>74w^B z0_0|UgPc^>N3xQV+uX+FJ%uf!@HoyrW7&;8U5(-%=bX~oWO{RhYILqrN0Ap(?EK`L zGWd74ZDV24aKn8tJGBau8-QYU;`b{vE`gBV0QB-)<5KiZ{;!2jEoom&6}WO6h6A~$Yl>;YV%ebHo7u*vQw zu;0SISQ82mpx{Io(wF)0%d{_2cVS7UprlM3pZ;%pV7n!izj<-4y55jfDYwdNZ$)SV7>ljyCRylh$Op&qB6@+#5npEh?gi zSk5kS@)-CHLCXG89%K!XfwnjW;v#{}gj+jyoWSa*b?!%Gy~JAOBR!^8341*lc2o&} z9$Q^jV(}VPiS1IKS0~#tQm0M?Qq(vm#dcf?JSVxUt%Zmu85%J35Qa`anmy9V&k^?5 zYsFUZHRhPriE{x$06Gow5cif9TLC+*1=|f_E0sMeTnyB4dMJ&=SXE0TPn1cCdfPFb z30t)5#IC<&6=>xivUB7RF93gtP#BYZEAT_ZM14>rmvLE8vpJ%GRS4l*D9sX4 z2AHQJ#UqMA*%m%6$y)oSuLa~S3AY?^Y~m!%k9MCW09rCCI3g9ZVCVZRnO7e>X+!iz zfT0LeI>uyDYlC8|>;yKudcGRonMKK>t~@yL#tqSR6jdlj`Rw5&XXOx;kMS^)-{<5j z;GGUMixZR_V6n=sFIwjq4q0p#T|eqn<5VXBSr}q*AxCV5x7O$qhd%9yCEeKGm27N8 z)5^ZU5lcZq5OLCUQ_7J>)Cq6W&8l}+@O#)|wo;3U$fSB_eF zT)sb#!V)WCN#@dA)7Wj)2>+4~P2E7Z5DunZ-Ow0JDe#*OLcS*~&a>^Aaa$0xYC{Q= zrSvgFtmpq?c(}w95CU?+)fu-<7a?}mvNNp~y-=UY_6B`+Dv5BU?_k%d)#f3f`Z(We zZK%ka?40`mt)1sd=c#buXKP;b52!fN`Xq&zytF*gT7xS&RW!;Ev_^uqmzSd)+C91p z^0n7pOd0Ue19gCl6+#W>2e_o%hztD6-_^0i@_fjJ#ZD&rGj(%LChpeB#AW%BMxD?q zP9}ckXHhVO0DV{!>(@8HS(N{~8utfXoguEHcCg1-rHD0ERkT&T)MFO8{6A>KqODdG zYbx%KH5FT|sTej$DTt?tHAU2SEOH=xZ>%Z#p60QpEwV9ZiuVGWrnP z(0GQOU=zBkSW{IOYs!cZcN2*Y1K?mX9fJRQf?xb#I*|K5gp%5fVZa^4F|@>_A;t1h z<-aM%{w`hm_rLp-|MCxaa%|qcUV8qMANx-aJUAHg>QuU)`TZX`e(xYw2=_kovw!;5 z`v$c^P9Oe3-iKs+n?YEGmp=86fAY_NGbpOKU=8>he&@%2^9pbzCi zufVAK%=(7yR0jriBuZgw!ell2JOfzRXWN}Bjge`r-WXoJ$VPN5VFpB<($`mhK*ivD8B0;f+$%mW?u~k6kEVme_?{H;#zXZvLLxsDL0Yt;P zR5klb9cfL_IZwdGMu+uQ7XbqT(sbTO>nn1#`%eI~b=aU50v4dAtGF4t`+-0U;He%c z+JGmic~-(3Z>Pg(Gr8Oe%LX^^+DBLea)(xY^3g>vNgz>d?y%y^wdoGqWkoW02)<%& zX5_<)VlmZ=oE_(Z+}o`M&bi=?v$C$`mB7idNNJicGMj^n)9*<*@f(v6UDKuvwvR4ue1mnqS z_V7$xM+IU%RVO8Umkh;JpH)r+N)a83)9RS@;?1;9ESE*Nic^t#xk`VE4vfQ9!jh{< z7wt)bXBs=S6ibO=a*aiDEZK;d@5ZQxUoMdVPBac^Lw=7Fn<3{ z22af^8=9bU4mw@FE!b=_+)~d99L?3DI*G-G3?b)N!2nRMZQcoG@Aq-c{ni22xo{SQ zY5E9$fcGp;OHHRrs3UHhtf-b&6tzL~r7s|yYtTC6c1tZ@zRx3swA_k~PedT?6e27u zDFhuM)+M1ZF^`82CZ3NAH$q|IDX_3EPkb4c`&lu#a2ZxycdXd`fOQ2c&e2fonATM` z_4u0n(_T*Oror8dOb{?!&`em8i0=|1e67W>XLye#k^OYd8FyI`EZ;DPy7$;C99gu*JYeer2DCtt~pIM2D-@@k7| zbYGaJyncOgrbOYhxQixB5|Ad_8yS&}wresauJFS`28+?)$UmjTCq zjkEXGLCM%iSCXzrQn#hY5;|0?E_0TrrG=bO+*bwEjq(V{QT=_9} z@*`4H&i=LOWpS5GeoX!mGNv|qH2?M^VH4&I#1+#ExisNN4qP(X@FaVU5+t#u_M{Le zud^orts{E+45e;}u18SRz9pHHe;m?HdQ5Vq^$VdHKZ+s5ml=W=fqRC~F9Ih&9(K^+ z)H95M`cdc+CuAl($$F(u$4JY1dYztJL=xxRI%1zRitEV?A5w&p>gzoSK}mDNq#s?fpzjDEU2)zigpksqA5C;SxlsDLcr74S?+0<`@MN) zR(dk)cCitWgi}qkQ!exWMmmU$6dHO5V=uilQN8lBuBfeM$(I2?rk=1-Eo4^0Zed~#x=ocw4AUZB7Wl6a@3~rVB-$(Qpt}CKqZBF=^pP*f> z?0FNTe1rpOze)G%jM1t5`YPG32I9@)KJGu}$F8qx$>J6ETf9QEc!|m>)g)&gT|M*` zudvtRg{&Lq7BB54&AYxzVD88ihQ$l@Wr6Ff{0%oYuwqQ@HSwrM2Y-Oa0wRrVAo;OS zm-jd}!_Y^f5gEsU6psh(<^m0n+<%QB-W)#=R-GZfCDX7rl{z7FFOg3GHUog_VA*V$ zY1pp6QMMKfU|Q`E;gTs8k+zf%j@6b%EnfWL{}mWkcuOE_(NhHa^6Y96gUko}_{xW( zxmV%j2j;aE`}I0o?^QSR>#=SubdH@5WuTxid(DLF@fBpfcEPNm3f?Xs3;O~?$^XYi zhLT6uD~E+@%nu6%%2vJC4o~vhv7b>=u@&?N0wmj&g>-_439;?^G99iiJs^tf%f#d{ zro&P4>&sx33twLrh`rSN*-PEni|gUtfl1<*zRb zR6?xFG%LGMtXMH+7ocT{k8=MKGa-eB-HXJ_J4oZ_6|OI1;76!N*O%4djliJZdwm%j z9Qx{D!~HmDO;~8*lrTLDXjsRD+H-vww~9&e72i{QJyt`7e+zVd8GX_9W&CXChkouR z?*;TJf$^%ZFJr{IzAWguzRdb#4e+Pr=MUIUAFUvAsC6J(e!L_9sO!thkC_1K)ScEZ z$6>A5yifDcivlenDaa#u&x7NkEoi2K-&Ko#96=7G?qF(e|;Wz0Rk}hHX z{DLY3HYSPRZ{3`I-=9ZqHrC6&9r!pVy;_PGYNy=+6~~)_vvzy$%w~xqWE9%1GC(x+ z+%s2rQ_+=Bbc!oFyY;D0q_q>&M1%&N6K8YcNKP0vB2{Z-70l-R;Cjd$zEv|%by4q~ zVsb1tMxm4DA{vY2NG7?L>XXD4N8xTuhdkWdrGdlt-=3XQcUcwW55bJ`O`&FRy0mA2 z0kXILNn|lueLx*D_w3kwy%m|L)I=DsDJhW*t1Rq(jddGYOqW+-3Y)4q+(@y=Kja2g z^Jvx5oPS7*su2D{kieBFud(;W z`a)0H0*_>^M8awPaOInLE|Vo|jPU%`M|;TveTuz`==qObUhnyj1+LIomd&Hte35Vj z>tf&dX91w~qY)O35AGW zl|}Y%`)`X2lv92p#f@^gWLA>4OlA=KA~B&C6E!fig%JkiSY#OH>FKJXSCQ+&QRvtju3;sVqS8&$|U;;Hadx6t*~0 zn!>;Com8JT(I@<$^Ululn49Xq-u<(~bFy)<*yCV?@Gl<=IUORplOCF!w@ZDEqT% z!7@&GvqAR>Z{Xg7-8Wfpes-{Sq3mL08wx34+!aBCI-m2rXbi*0k7( z_?Y9>Vw;cT7H(IwCm++zQBliG82Uy<)$B{*V;Igl+T6A!SbLC7Z38j@Y5C#Z^fGJR zX==P#S5!-dTC_LKPJ&fe$>g-3g=Ubzj>6!erA{O>g=&^n#iD_^Vt1=HcblTz;ayj) zJXSc_VN}q9Bl~Kon9A!5_ubChl9Br*)GfDk+CB!Gh_WLnwWb7fX6L1DKefV-L+g4GGLI1}8z7{R0^sSH>C=Gu5WDaf1x#Gm!44PG zK_^;eb+bE#5L>hhib6B8@X@ls`zuL9F{8Nq9G9Bq6I(OtxXz`KHY8UqoIBan-v3yGVa{D#F-O+ zxed3VyK;5=P!|dUpxZHfDP#RMkwc^W2EK&(`|UE(0h1YEALxou50@xAeiv99b(WHo z+W%RFT9v~Wj5Ys_Y}t|SK=#zpiEQ~DgJGsyi2eolgYNAvReJc?-VAenx^yb7-L|^3 z6hk8|qt019H7n4_e!>dWj&zs$0!!1{RNAltMR$DfWtp`>O&!1o>y7+uzUhOPfbsMsN$yc zsp;9D=20ELbm{p^@!f-!yt?E5ArKtti{XpH-EwXF-Rgq>zWL2(y30RpC|l3&CSZVB z%)jJni?@8_aB%XCU)cEMmhbzkm;aB~?*Caqm)bPww0VY!05@D?v3Z7B3}%Su#8m-wAv{bkrl+Gx8op*~f|qnc zEk55(&OA*Hf+(efPd|O;=`-E-8Hz4Hqbkp+R`=hQzkJ))yGEY;?OV@m8ULey^AmS{ z;CFAGIkP3qzUAk(PyJgxzV$mkbnk-?eol{lYq)lMVlj@7o0^wCL#h=g(|;(Ee$_PoLTHrT4vIoC=0z{II^=I!pI&lPrsjC&@RyxjyN%3>73)!V% z=y&fCT$QwOW9%zp{w*&E0UaO7jvso=5c=uPa^@G(mk8(Q4(BR>7@aFIOQ$s1& z^QX7`<<0;7OJho7o^RfFw!P!~Q!oi!G?v1sj3^kU5aImK{MzK6jgP$P%$EPO_y79M z?9;#UYoPn}fBfzL`@}nz2=jm9)4#T2->*ONJdbZOO!-Y=N>?=Hdlk&ih#dQ8eyf}{kkDJ<#+?n`y8Yy3wCS;5oLH;n;f0H5`*nqt1Y6NgP(_mPTNu z*egq2EG`;r&D=YI0}p$dN7(aQeQhY`H2(HYu{fI5lAG24xVXU!(X?g2}3Rg?|)tw zb|SZKcK;z=Pd5b8oF**3C)l2hG^y6bG`#hM^u0s7XWw zimKx=R6)@wJB9=yG||p4dqx4nIDUv>T>9I;dCvp{{M7qS95pIYnxVYqRwdNvD#6s- zYQl8C1u^quVe9{_gl$ua9Ri?U&1T&}s4(fUBxkd~j$@*N@d>zQC?&o;8b!1>4by0K zq4rSjGZ_ch2c;0{Y*Bk3D1vpQ6AG=An4RFYOPEhOLS=lE-a{i+yT;@kflQwwdS??O zE16CIMcYaT71C419pQ-4r~-9MteFoKaaESNEX$za6%K+RLGtq&Bfy;71=d8en~r0jL@4JZymH+p_b2tUE138yyLVa|}e~Fii6< z8XaWfEMze{j3}V~m_Y^J0@ec_APLwgGKdBX5bJLrWQA2_Fa|?@0O|@(*ig`pZ8GJv zkEKw`G6Ze>dRUafCru?<&8NxikEr*-n zw$%#psmi4GfQhIq@L!9%Y>hf7OV)1vP&I6zS_>UC$Y^s0b$oOi*d>e2*==UyxYay_ zGIrfQx{dbmqk+e7;42)?Il8MP>6c(JS#qQs-5PWo8V`Jb@8*ERn_5n84d9KwTDgPE z&sh5N*=-aRY*Wn@bEmZi@Q9~74I@S;&YpTXzO!3fjW}d2v2@i|?@jBl^SsxC0X>Zo zQSzRmzE8=hrJll>gx`LtLrr%}1fC)CWgvWoVD7r#p!*edU)#}iKPBOImQM$fnqUsL zfV}h^ZyITDzUN?_$i@&$`%-`bMfJA92=K_;TPW$m7$^W6wJ>d%MabyUAv=amg;l|( z2)T(bno6Ii2PuN=GY|pCCY8nbj`E3n3HcrM3b>@%z%eSw?F>XPwb=Eo=yvRSCaUbB zr^`Pe0a$4WR%Fxvj~o~@Fg?PeVpMDhL7kOB5!i|yrN(=(!;o$-wqx8@_hqeW zVeXD2BW`_pwluwfmg&Ihe!d-fmMv2V|=^w8svK73$bx_`%` z<9xXY_2#Tid?6{*0;{f_fbLT$K zJ$Gyawn8Oif+t6Q#_ z-8;QnJXm{`Nq(YNlN~w6iDBq?G8~I* zH5Q|RLWZ>Kj^7t3xG~HD@6hfjL{9N}wbjhG9BqX7 z?erBxA+6A1;$Qm#9EKm)dU08y?}uT~52fe9VXg5sN)jc#o?|%**t7!I9#m( zXq)ZQK|CHR;W?2fV{5=>cj+4$$I2VVEE*+U14aY&krNLDYSmLAt2H3RspT%Ub5Vc{ zpte=mbAu7~CRJ*c_t<#0HLKER|Az}W9B~TMDt&be7JBneR802hyG*qa{6tVJ_UMOF z{GsyTZ&q0D>R62A9qlox(c{ddc2SPkf-_#n56pN@>r^u*^zy7umqNXFqF6)C2Od-u zzl#PE&)0%aE^xArXNu>ScrNP&huEqMu4Bf-#)Rn155yXYeK5c-TjrHk1b+Yw=L=v!?0UVq2eR{6d z_oU+*YO`GFctW~vsSO~x+^3f%AEliW@LeFEKBOk3bc`DapFgC=dZPsI^dWt|(S|*g zH4^f7xF%hU3Y6YN26rY0bfs}%h)0Zq#05A)r{71iB*TM~Y#|N~^MH+;w$g>*2oI==K?0!QWpzL`w6Y(eckwzoq^DUDIbP;KPUOe1njcav-^Z!NVQG|M z%w)5VZ5`5ORIIG0p#g>VU~)v~xz8R#36-T7#Abd%$Lxq++}_9;82QQ_glu|5J3?c2 zc|=tqetM%{R!2;bd4KgBovg_*RieOUDxDrvEwjt7^J8k3#nFync2<8(FOeP*`0f}* zFlpm@jRxRo;i8FnU|SZCe#Y^nK`%1JOy@U=gQhalEG)WXP*s%Z+|L_y{}s+G@Z_#b z8`R1ZlOf$!ZY;62YS3A}RU+|xd)lNr+E9UzEpC}vv$zHTFYMU7S!ggM-owCIlTF&B znz5-kAreM{gul3zdy|>IIpsV7M z!t9SnL1`FTNr<6{dCOU!wW-RUY2ux?X-}KcZ;LjONxx(3g|rPQ*BJ=QHnq(b=!%E` z*zmOmScgvYWUW1kgKOn$dmU=}Y6S7jM-4WpTy&_lu~9_7?9fxKKxoFxZj`qSPfzJW z$FE0^%xJ#cxARkatR=GXv`r>GrOToWhOqRtv7n^YDP4U~VIXosQ5g0ERq1*V9 zSxC>$=nKP42;1aA#}OnL(K(~xh=&P|JfvrIl{fy!;#o@AKqfuGzm?Dt&L7c5MhzT7FAP2aEoBB+KB8wlkaG1H3Yd*s1gGa4s`%<%W*``wL&7i% zntH4+?ub(>XK--n=iGy(+n`M1L4eyS_u%TBs`@yO{mBK@bC>vidO>^Urq6G)3%b-v z(ehg}l3ws%xA|-J);#}t3s|pL@7>!?|NQ0ee}8=g%cWJw{`}yNzaWd>#L#aZm)v@X ye0cb#P \00") + (data (i32.const 2160) "unable to fill\00") + (data (i32.const 2176) "sold\00") + (data (i32.const 2192) "received\00") + (data (i32.const 2224) "unable to find key\00") + (data (i32.const 2256) "can only transfer to white listed accounts\00") + (data (i32.const 2304) "receiver requires whitelist by issuer\00") + (data (i32.const 2352) ".\00") + (data (i32.const 2368) " \00") + (data (i32.const 2384) "invalid borrow delta\00") + (data (i32.const 2416) "invalid collateral delta\00") + (data (i32.const 2448) "no effect\00") + (data (i32.const 2464) "invalid args\00") + (data (i32.const 2480) "invalid asset for market\00") + (data (i32.const 2512) "borrowed\00") + (data (i32.const 2528) "collateral\00") + (data (i32.const 2544) "invalid cover amount\00") + (data (i32.const 2576) "cover amount must be positive\00") + (data (i32.const 2608) "invalid initial supply\00") + (data (i32.const 2640) "initial supply must be positive\00") + (data (i32.const 2672) "invalid base deposit\00") + (data (i32.const 2704) "base deposit must be positive\00") + (data (i32.const 2736) "invalid quote deposit\00") + (data (i32.const 2768) "quote deposit must be positive\00") + (data (i32.const 2800) "must exchange between two different currencies\00") + (data (i32.const 2848) "base: \00") + (data (i32.const 2864) "quote: \00") + (data (i32.const 2880) "marketid: \00") + (data (i32.const 2896) " \n \00") + (data (i32.const 2912) "market already exists\00") + (data (i32.const 2944) "initial exchange tokens\00") + (data (i32.const 2976) "new exchange issue\00") + (data (i32.const 3008) "new exchange deposit\00") + (data (i32.const 3040) "token with symbol already exists\00") + (data (i32.const 3088) "must lend a positive amount\00") + (data (i32.const 3120) "must unlend a positive amount\00") + (data (i32.const 3152) "invalid quantity in transfer\00") + (data (i32.const 3184) "zero quantity is disallowed in transfer\00") + (data (i32.const 3232) "withdrew tokens without withdraw in memo\00") + (data (i32.const 3280) "received tokens without deposit in memo\00") + (data (i32.const 3328) "must transfer positive quantity\00") + (data (i32.const 3360) "overdrawn balance\00") + (data (i32.const 3392) "account is frozen by issuer\00") + (data (i32.const 3424) "all transfers are frozen by issuer\00") + (data (i32.const 3472) "account is not white listed\00") + (data (i32.const 3504) "issuer may not recall token\00") + (data (i32.const 3536) "insufficient authority\00") + (data (i32.const 3568) "issue\n\00") + (data (i32.const 3584) "transfer\n\00") + (data (i32.const 3600) "create\n\00") + (data (i32.const 3616) "must issue positive quantity\00") + (data (i32.const 3664) "\00\00\00\00\00\00\f0?\00\00\00\00\00\00\f8?") + (data (i32.const 3680) "\00\00\00\00\00\00\00\00\06\d0\cfC\eb\fdL>") + (data (i32.const 3696) "\00\00\00\00\00\00\00\00\00\00\00@\03\b8\e2?") + (data (i32.const 12112) "malloc_from_freed was designed to only be called after _heap was completely allocated\00") + (export "memory" (memory $0)) + (export "_ZeqRK11checksum256S1_" (func $_ZeqRK11checksum256S1_)) + (export "_ZeqRK11checksum160S1_" (func $_ZeqRK11checksum160S1_)) + (export "_ZneRK11checksum160S1_" (func $_ZneRK11checksum160S1_)) + (export "now" (func $now)) + (export "_ZN5eosio12require_authERKNS_16permission_levelE" (func $_ZN5eosio12require_authERKNS_16permission_levelE)) + (export "_ZN5eosio14exchange_state19convert_to_exchangeERNS0_9connectorENS_14extended_assetE" (func $_ZN5eosio14exchange_state19convert_to_exchangeERNS0_9connectorENS_14extended_assetE)) + (export "_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE" (func $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE)) + (export "_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE" (func $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE)) + (export "_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE" (func $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE)) + (export "_ZNK5eosio14exchange_state20requires_margin_callEv" (func $_ZNK5eosio14exchange_state20requires_margin_callEv)) + (export "_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE" (func $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE)) + (export "_ZN5eosio12market_stateC2EyNS_11symbol_typeERNS_17exchange_accountsE" (func $_ZN5eosio12market_stateC2EyNS_11symbol_typeERNS_17exchange_accountsE)) + (export "_ZN5eosio12market_state11margin_callENS_15extended_symbolE" (func $_ZN5eosio12market_state11margin_callENS_15extended_symbolE)) + (export "_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE" (func $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE)) + (export "_ZNK5eosio12market_state13initial_stateEv" (func $_ZNK5eosio12market_state13initial_stateEv)) + (export "_ZN5eosio12market_state4lendEyRKNS_14extended_assetE" (func $_ZN5eosio12market_state4lendEyRKNS_14extended_assetE)) + (export "_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd" (func $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd)) + (export "_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE" (func $_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE)) + (export "_ZN5eosio12market_state12cover_marginEyRKNS_14extended_assetE" (func $_ZN5eosio12market_state12cover_marginEyRKNS_14extended_assetE)) + (export "_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE" (func $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE)) + (export "_ZN5eosio12market_state13update_marginEyRKNS_14extended_assetES3_" (func $_ZN5eosio12market_state13update_marginEyRKNS_14extended_assetES3_)) + (export "_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_" (func $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_)) + (export "_ZN5eosio12market_state4saveEv" (func $_ZN5eosio12market_state4saveEv)) + (export "_ZN5eosio8exchange7depositEyNS_14extended_assetE" (func $_ZN5eosio8exchange7depositEyNS_14extended_assetE)) + (export "_ZN5eosio8exchange8withdrawEyNS_14extended_assetE" (func $_ZN5eosio8exchange8withdrawEyNS_14extended_assetE)) + (export "_ZN5eosio8exchange2onERKNS0_5tradeE" (func $_ZN5eosio8exchange2onERKNS0_5tradeE)) + (export "_ZN5eosio8exchange2onERKNS0_8upmarginE" (func $_ZN5eosio8exchange2onERKNS0_8upmarginE)) + (export "_ZN5eosio8exchange2onERKNS0_11covermarginE" (func $_ZN5eosio8exchange2onERKNS0_11covermarginE)) + (export "_ZN5eosio8exchange7createxEyNS_5assetEmNS_14extended_assetES2_" (func $_ZN5eosio8exchange7createxEyNS_5assetEmNS_14extended_assetES2_)) + (export "_ZN5eosio8exchange4lendEyNS_11symbol_typeENS_14extended_assetE" (func $_ZN5eosio8exchange4lendEyNS_11symbol_typeENS_14extended_assetE)) + (export "_ZN5eosio8exchange6unlendEyNS_11symbol_typeEdNS_15extended_symbolE" (func $_ZN5eosio8exchange6unlendEyNS_11symbol_typeEdNS_15extended_symbolE)) + (export "_ZN5eosio8exchange2onERKNS_8currency8transferEy" (func $_ZN5eosio8exchange2onERKNS_8currency8transferEy)) + (export "_ZN5eosio8exchange5applyEyy" (func $_ZN5eosio8exchange5applyEyy)) + (export "apply" (func $apply)) + (export "pow" (func $pow)) + (export "sqrt" (func $sqrt)) + (export "fabs" (func $fabs)) + (export "scalbn" (func $scalbn)) + (export "memcmp" (func $memcmp)) + (export "strlen" (func $strlen)) + (export "malloc" (func $malloc)) + (export "free" (func $free)) + (func $_ZeqRK11checksum256S1_ (param $0 i32) (param $1 i32) (result i32) + (i32.eqz + (call $memcmp + (get_local $0) + (get_local $1) + (i32.const 32) + ) + ) + ) + (func $_ZeqRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) + (i32.eqz + (call $memcmp + (get_local $0) + (get_local $1) + (i32.const 32) + ) + ) + ) + (func $_ZneRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) + (i32.ne + (call $memcmp + (get_local $0) + (get_local $1) + (i32.const 32) + ) + (i32.const 0) + ) + ) + (func $now (result i32) + (i32.wrap/i64 + (i64.div_u + (call $current_time) + (i64.const 1000000) + ) + ) + ) + (func $_ZN5eosio12require_authERKNS_16permission_levelE (param $0 i32) + (call $require_auth2 + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (func $_ZN5eosio14exchange_state19convert_to_exchangeERNS0_9connectorENS_14extended_assetE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (i64.store offset=8 + (get_local $1) + (i64.add + (tee_local $5 + (i64.trunc_s/f64 + (f64.neg + (f64.mul + (f64.convert_s/i64 + (i64.load offset=8 + (get_local $1) + ) + ) + (f64.sub + (f64.const 1) + (call $pow + (f64.add + (f64.div + (f64.convert_s/i64 + (tee_local $6 + (i64.load + (get_local $3) + ) + ) + ) + (f64.convert_s/i64 + (i64.add + (get_local $6) + (i64.load + (get_local $2) + ) + ) + ) + ) + (f64.const 1) + ) + (f64.div + (f64.convert_u/i32 + (i32.load offset=24 + (get_local $2) + ) + ) + (f64.const 1e3) + ) + ) + ) + ) + ) + ) + ) + (i64.load offset=8 + (get_local $1) + ) + ) + ) + (i64.store + (get_local $2) + (i64.add + (get_local $6) + (i64.load + (get_local $2) + ) + ) + ) + (set_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (set_local $6 + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i64.store + (get_local $0) + (get_local $5) + ) + (i64.store offset=8 + (get_local $0) + (get_local $6) + ) + (call $eosio_assert + (i64.lt_u + (i64.add + (get_local $5) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775807) + ) + (i32.const 16) + ) + (set_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (set_local $1 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $6) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $2 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $2 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $2) + (i32.const 80) + ) + (i64.store offset=16 + (get_local $0) + (get_local $4) + ) + ) + (func $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i64) + (local $5 f64) + (local $6 i64) + (local $7 i64) + (call $eosio_assert + (i64.eq + (i64.load offset=16 + (get_local $3) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (i32.const 112) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $3) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i32.const 144) + ) + (set_local $6 + (i64.load + (get_local $2) + ) + ) + (set_local $5 + (call $pow + (f64.add + (f64.div + (f64.convert_s/i64 + (tee_local $7 + (i64.load + (get_local $3) + ) + ) + ) + (f64.convert_s/i64 + (i64.sub + (i64.load offset=8 + (get_local $1) + ) + (get_local $7) + ) + ) + ) + (f64.const 1) + ) + (f64.div + (f64.const 1e3) + (f64.convert_u/i32 + (i32.load offset=24 + (get_local $2) + ) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $1) + (i64.sub + (i64.load offset=8 + (get_local $1) + ) + (get_local $7) + ) + ) + (i64.store + (get_local $2) + (i64.sub + (i64.load + (get_local $2) + ) + (tee_local $7 + (i64.trunc_s/f64 + (f64.mul + (f64.convert_s/i64 + (get_local $6) + ) + (f64.add + (get_local $5) + (f64.const -1) + ) + ) + ) + ) + ) + ) + (set_local $4 + (i64.load offset=16 + (get_local $2) + ) + ) + (set_local $6 + (i64.load offset=8 + (get_local $2) + ) + ) + (i64.store + (get_local $0) + (get_local $7) + ) + (i64.store offset=8 + (get_local $0) + (get_local $6) + ) + (call $eosio_assert + (i64.lt_u + (i64.add + (get_local $7) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775807) + ) + (i32.const 16) + ) + (set_local $7 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $7) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $1 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 80) + ) + (i64.store offset=16 + (get_local $0) + (get_local $4) + ) + ) + (func $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 f64) + (local $10 i32) + (local $11 i32) + (local $12 i64) + (local $13 i32) + (local $14 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $14 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 208) + ) + ) + ) + (set_local $8 + (i64.load + (i32.add + (get_local $1) + (i32.const 152) + ) + ) + ) + (set_local $7 + (i64.load + (i32.add + (get_local $1) + (i32.const 144) + ) + ) + ) + (set_local $6 + (i64.load + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + ) + (set_local $5 + (i64.load + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + ) + (set_local $12 + (i64.load offset=16 + (get_local $2) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (br_if $label$8 + (i64.ne + (tee_local $4 + (i64.load offset=8 + (get_local $2) + ) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + (br_if $label$8 + (i64.ne + (get_local $12) + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + ) + (br_if $label$7 + (i64.ne + (tee_local $12 + (i64.load + (get_local $3) + ) + ) + (get_local $5) + ) + ) + (br_if $label$7 + (i64.ne + (i64.load offset=8 + (get_local $3) + ) + (get_local $6) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 160) + ) + (i32.const 16) + ) + (tee_local $5 + (i64.load + (tee_local $13 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 160) + ) + (i32.const 8) + ) + (tee_local $4 + (i64.load + (tee_local $10 + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + ) + ) + (set_local $12 + (i64.load + (get_local $2) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 48) + ) + (i32.const 16) + ) + (get_local $5) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 48) + ) + (i32.const 8) + ) + (get_local $4) + ) + (i64.store offset=160 + (get_local $14) + (get_local $12) + ) + (i64.store offset=48 + (get_local $14) + (get_local $12) + ) + (call $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE + (i32.add + (get_local $14) + (i32.const 184) + ) + (get_local $1) + (i32.add + (get_local $1) + (i32.const 40) + ) + (i32.add + (get_local $14) + (i32.const 48) + ) + ) + (i64.store + (get_local $13) + (i64.load + (i32.add + (i32.add + (get_local $14) + (i32.const 184) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (get_local $10) + (i64.load + (i32.add + (i32.add + (get_local $14) + (i32.const 184) + ) + (i32.const 8) + ) + ) + ) + (i64.store + (get_local $2) + (i64.load offset=184 + (get_local $14) + ) + ) + (br $label$0) + ) + (br_if $label$6 + (i64.ne + (get_local $4) + (get_local $5) + ) + ) + (br_if $label$6 + (i64.ne + (get_local $12) + (get_local $6) + ) + ) + (set_local $5 + (i64.load offset=8 + (get_local $1) + ) + ) + (set_local $9 + (call $pow + (f64.add + (f64.div + (f64.convert_s/i64 + (tee_local $12 + (i64.load + (get_local $2) + ) + ) + ) + (f64.convert_s/i64 + (i64.add + (i64.load + (tee_local $13 + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + ) + (get_local $12) + ) + ) + ) + (f64.const 1) + ) + (f64.div + (f64.convert_u/i32 + (i32.load + (i32.add + (get_local $1) + (i32.const 64) + ) + ) + ) + (f64.const 1e3) + ) + ) + ) + (i64.store + (get_local $13) + (i64.add + (get_local $12) + (i64.load + (get_local $13) + ) + ) + ) + (i64.store offset=8 + (get_local $1) + (i64.add + (tee_local $5 + (i64.trunc_s/f64 + (f64.neg + (f64.mul + (f64.convert_s/i64 + (get_local $5) + ) + (f64.sub + (f64.const 1) + (get_local $9) + ) + ) + ) + ) + ) + (i64.load offset=8 + (get_local $1) + ) + ) + ) + (set_local $6 + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (set_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i64.lt_u + (i64.add + (get_local $5) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775807) + ) + (i32.const 16) + ) + (set_local $12 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (set_local $13 + (i32.const 0) + ) + (loop $label$9 + (br_if $label$5 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $12) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$10 + (br_if $label$10 + (i64.ne + (i64.and + (tee_local $12 + (i64.shr_u + (get_local $12) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$11 + (br_if $label$5 + (i64.ne + (i64.and + (tee_local $12 + (i64.shr_u + (get_local $12) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$11 + (i32.lt_s + (tee_local $13 + (i32.add + (get_local $13) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $10 + (i32.const 1) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $13 + (i32.add + (get_local $13) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$4) + ) + ) + (block $label$12 + (br_if $label$12 + (i64.ne + (get_local $12) + (get_local $7) + ) + ) + (br_if $label$12 + (i64.ne + (i64.load offset=8 + (get_local $3) + ) + (get_local $8) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 136) + ) + (i32.const 16) + ) + (tee_local $5 + (i64.load + (tee_local $13 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 136) + ) + (i32.const 8) + ) + (tee_local $4 + (i64.load + (tee_local $10 + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + ) + ) + (set_local $12 + (i64.load + (get_local $2) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 72) + ) + (i32.const 16) + ) + (get_local $5) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 72) + ) + (i32.const 8) + ) + (get_local $4) + ) + (i64.store offset=136 + (get_local $14) + (get_local $12) + ) + (i64.store offset=72 + (get_local $14) + (get_local $12) + ) + (call $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE + (i32.add + (get_local $14) + (i32.const 184) + ) + (get_local $1) + (i32.add + (get_local $1) + (i32.const 136) + ) + (i32.add + (get_local $14) + (i32.const 72) + ) + ) + (i64.store + (get_local $13) + (i64.load + (i32.add + (i32.add + (get_local $14) + (i32.const 184) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (get_local $10) + (i64.load + (i32.add + (i32.add + (get_local $14) + (i32.const 184) + ) + (i32.const 8) + ) + ) + ) + (i64.store + (get_local $2) + (i64.load offset=184 + (get_local $14) + ) + ) + (br $label$0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 192) + ) + (br $label$0) + ) + (br_if $label$3 + (i64.ne + (get_local $4) + (get_local $7) + ) + ) + (br_if $label$3 + (i64.ne + (get_local $12) + (get_local $8) + ) + ) + (set_local $5 + (i64.load offset=8 + (get_local $1) + ) + ) + (set_local $9 + (call $pow + (f64.add + (f64.div + (f64.convert_s/i64 + (tee_local $12 + (i64.load + (get_local $2) + ) + ) + ) + (f64.convert_s/i64 + (i64.add + (i64.load + (tee_local $13 + (i32.add + (get_local $1) + (i32.const 136) + ) + ) + ) + (get_local $12) + ) + ) + ) + (f64.const 1) + ) + (f64.div + (f64.convert_u/i32 + (i32.load + (i32.add + (get_local $1) + (i32.const 160) + ) + ) + ) + (f64.const 1e3) + ) + ) + ) + (i64.store + (get_local $13) + (i64.add + (get_local $12) + (i64.load + (get_local $13) + ) + ) + ) + (i64.store offset=8 + (get_local $1) + (i64.add + (tee_local $5 + (i64.trunc_s/f64 + (f64.neg + (f64.mul + (f64.convert_s/i64 + (get_local $5) + ) + (f64.sub + (f64.const 1) + (get_local $9) + ) + ) + ) + ) + ) + (i64.load offset=8 + (get_local $1) + ) + ) + ) + (set_local $6 + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (set_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i64.lt_u + (i64.add + (get_local $5) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775807) + ) + (i32.const 16) + ) + (set_local $12 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (set_local $13 + (i32.const 0) + ) + (loop $label$13 + (br_if $label$2 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $12) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$14 + (br_if $label$14 + (i64.ne + (i64.and + (tee_local $12 + (i64.shr_u + (get_local $12) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$15 + (br_if $label$2 + (i64.ne + (i64.and + (tee_local $12 + (i64.shr_u + (get_local $12) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$15 + (i32.lt_s + (tee_local $13 + (i32.add + (get_local $13) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $10 + (i32.const 1) + ) + (br_if $label$13 + (i32.lt_s + (tee_local $13 + (i32.add + (get_local $13) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$1) + ) + ) + (set_local $10 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $10) + (i32.const 80) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 8) + ) + (get_local $4) + ) + (i64.store + (get_local $2) + (get_local $5) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (get_local $6) + ) + (br $label$0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 176) + ) + (br $label$0) + ) + (set_local $10 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $10) + (i32.const 80) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 8) + ) + (get_local $4) + ) + (i64.store + (get_local $2) + (get_local $5) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (get_local $6) + ) + ) + (block $label$16 + (block $label$17 + (br_if $label$17 + (i64.ne + (i64.load + (get_local $3) + ) + (i64.load + (tee_local $13 + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + ) + ) + (br_if $label$17 + (i64.ne + (i64.load offset=8 + (get_local $3) + ) + (i64.load + (tee_local $10 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + ) + ) + (i64.store + (get_local $0) + (i64.load + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.load + (get_local $10) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (br $label$16) + ) + (i64.store + (tee_local $10 + (i32.add + (i32.add + (get_local $14) + (i32.const 112) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + (i64.store + (tee_local $11 + (i32.add + (i32.add + (get_local $14) + (i32.const 112) + ) + (i32.const 8) + ) + ) + (i64.load + (get_local $13) + ) + ) + (i64.store offset=112 + (get_local $14) + (i64.load + (get_local $2) + ) + ) + (i64.store + (tee_local $13 + (i32.add + (i32.add + (get_local $14) + (i32.const 96) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + (i64.store offset=96 + (get_local $14) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 24) + ) + (i32.const 16) + ) + (i64.load + (get_local $10) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 24) + ) + (i32.const 8) + ) + (i64.load + (get_local $11) + ) + ) + (i64.store offset=24 + (get_local $14) + (i64.load offset=112 + (get_local $14) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $14) + (i32.const 8) + ) + (i32.const 8) + ) + (i64.load + (get_local $13) + ) + ) + (i64.store offset=8 + (get_local $14) + (i64.load offset=96 + (get_local $14) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (get_local $0) + (get_local $1) + (i32.add + (get_local $14) + (i32.const 24) + ) + (i32.add + (get_local $14) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $14) + (i32.const 208) + ) + ) + ) + (func $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE (param $0 i32) (param $1 i32) (result i32) + (local $2 i64) + (local $3 f64) + (local $4 i64) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 336) + ) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i64.lt_s + (tee_local $5 + (i64.load + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + ) + (i64.const 1) + ) + ) + (drop + (call $memcpy + (i32.add + (get_local $7) + (i32.const 104) + ) + (get_local $0) + (i32.const 232) + ) + ) + (set_local $3 + (f64.load + (i32.add + (get_local $1) + (i32.const 80) + ) + ) + ) + (i64.store offset=64 + (get_local $7) + (tee_local $4 + (i64.load offset=8 + (get_local $1) + ) + ) + ) + (i64.store offset=56 + (get_local $7) + (tee_local $5 + (i64.trunc_s/f64 + (f64.mul + (get_local $3) + (f64.convert_s/i64 + (get_local $5) + ) + ) + ) + ) + ) + (set_local $2 + (i64.load offset=16 + (get_local $1) + ) + ) + (call $eosio_assert + (i64.lt_u + (i64.add + (get_local $5) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775807) + ) + (i32.const 16) + ) + (set_local $5 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$2 + (block $label$3 + (loop $label$4 + (br_if $label$3 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $5) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$5 + (br_if $label$5 + (i64.ne + (i64.and + (tee_local $5 + (i64.shr_u + (get_local $5) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$6 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $5 + (i64.shr_u + (get_local $5) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$6 + (i32.lt_s + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $6 + (i32.const 1) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$2) + ) + ) + (set_local $6 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 80) + ) + (i64.store offset=72 + (get_local $7) + (get_local $2) + ) + (set_local $5 + (i64.load + (i32.add + (get_local $1) + (i32.const 64) + ) + ) + ) + (set_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 72) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 56) + ) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 32) + ) + (i32.load offset=72 + (get_local $7) + ) + ) + (i64.store offset=48 + (get_local $7) + (get_local $4) + ) + (i32.store + (i32.add + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 56) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 8) + ) + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 56) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=40 + (get_local $7) + (get_local $5) + ) + (i32.store offset=20 + (get_local $7) + (i32.load offset=60 + (get_local $7) + ) + ) + (i32.store offset=16 + (get_local $7) + (i32.load offset=56 + (get_local $7) + ) + ) + (i64.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i64.load offset=48 + (get_local $7) + ) + ) + (i64.store + (get_local $7) + (i64.load offset=40 + (get_local $7) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $7) + (i32.const 80) + ) + (i32.add + (get_local $7) + (i32.const 104) + ) + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $7) + ) + (set_local $0 + (i32.const 1) + ) + (br_if $label$0 + (i64.le_s + (i64.load offset=80 + (get_local $7) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + ) + ) + ) + (set_local $0 + (i32.const 0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 336) + ) + ) + (get_local $0) + ) + (func $_ZNK5eosio14exchange_state20requires_margin_callEv (param $0 i32) (result i32) + (local $1 i32) + (set_local $1 + (i32.const 1) + ) + (block $label$0 + (br_if $label$0 + (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE + (get_local $0) + (i32.add + (get_local $0) + (i32.const 40) + ) + ) + ) + (set_local $1 + (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE + (get_local $0) + (i32.add + (get_local $0) + (i32.const 136) + ) + ) + ) + ) + (get_local $1) + ) + (func $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i64) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $12 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 96) + ) + ) + ) + (i64.store offset=16 + (get_local $12) + (get_local $1) + ) + (set_local $4 + (i32.add + (tee_local $11 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $10 + (i32.mul + (i32.load + (i32.add + (get_local $0) + (i32.const 12) + ) + ) + (i32.const 48) + ) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $10) + ) + ) + (set_local $10 + (i32.div_s + (get_local $10) + (i32.const 48) + ) + ) + (set_local $9 + (get_local $11) + ) + (loop $label$1 + (set_local $9 + (select + (tee_local $7 + (i32.add + (tee_local $6 + (i32.add + (get_local $9) + (i32.mul + (tee_local $5 + (i32.shr_u + (get_local $10) + (i32.const 1) + ) + ) + (i32.const 48) + ) + ) + ) + (i32.const 48) + ) + ) + (get_local $9) + (tee_local $6 + (i64.lt_u + (i64.load + (get_local $6) + ) + (get_local $1) + ) + ) + ) + ) + (set_local $11 + (select + (get_local $7) + (get_local $11) + (get_local $6) + ) + ) + (br_if $label$1 + (tee_local $10 + (select + (i32.sub + (i32.add + (get_local $10) + (i32.const -1) + ) + (get_local $5) + ) + (get_local $5) + (get_local $6) + ) + ) + ) + ) + ) + (block $label$2 + (br_if $label$2 + (i32.eq + (get_local $11) + (get_local $4) + ) + ) + (set_local $11 + (select + (get_local $4) + (get_local $11) + (i64.gt_u + (i64.load + (get_local $11) + ) + (get_local $1) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.ne + (get_local $11) + (get_local $4) + ) + ) + (set_local $8 + (i64.load + (get_local $0) + ) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 64) + ) + (get_local $1) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 72) + ) + (i64.const -1) + ) + (i64.store + (tee_local $10 + (i32.add + (get_local $12) + (i32.const 80) + ) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 88) + ) + (i32.const 0) + ) + (i64.store offset=56 + (get_local $12) + (get_local $8) + ) + (i64.store offset=48 + (get_local $12) + (get_local $1) + ) + (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS1_9select1stIyEENSt3__14lessIyEENS0_13new_allocatorIS8_EEE13insert_uniqueEOS8_ + (i32.add + (get_local $12) + (i32.const 40) + ) + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.add + (get_local $12) + (i32.const 48) + ) + ) + (block $label$4 + (br_if $label$4 + (i32.eqz + (tee_local $5 + (i32.load + (get_local $10) + ) + ) + ) + ) + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.eq + (tee_local $10 + (i32.load + (tee_local $6 + (i32.add + (get_local $12) + (i32.const 84) + ) + ) + ) + ) + (get_local $5) + ) + ) + (loop $label$7 + (set_local $9 + (i32.load + (tee_local $10 + (i32.add + (get_local $10) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $10) + (i32.const 0) + ) + (block $label$8 + (br_if $label$8 + (i32.eqz + (get_local $9) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (i32.load + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $9) + ) + ) + ) + (call $_ZdlPv + (get_local $9) + ) + ) + (br_if $label$7 + (i32.ne + (get_local $5) + (get_local $10) + ) + ) + ) + (set_local $10 + (i32.load + (i32.add + (get_local $12) + (i32.const 80) + ) + ) + ) + (br $label$5) + ) + (set_local $10 + (get_local $5) + ) + ) + (i32.store + (get_local $6) + (get_local $5) + ) + (call $_ZdlPv + (get_local $10) + ) + ) + (set_local $11 + (i32.load offset=40 + (get_local $12) + ) + ) + (set_local $1 + (i64.load offset=16 + (get_local $12) + ) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eq + (tee_local $5 + (i32.load + (i32.add + (get_local $11) + (i32.const 36) + ) + ) + ) + (tee_local $7 + (i32.load + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + ) + ) + ) + (set_local $10 + (i32.add + (get_local $5) + (i32.const -24) + ) + ) + (set_local $6 + (i32.sub + (i32.const 0) + (get_local $7) + ) + ) + (loop $label$11 + (br_if $label$10 + (i64.eq + (i64.load + (i32.load + (get_local $10) + ) + ) + (get_local $1) + ) + ) + (set_local $5 + (get_local $10) + ) + (set_local $10 + (tee_local $9 + (i32.add + (get_local $10) + (i32.const -24) + ) + ) + ) + (br_if $label$11 + (i32.ne + (i32.add + (get_local $9) + (get_local $6) + ) + (i32.const -24) + ) + ) + ) + ) + (set_local $10 + (i32.add + (get_local $11) + (i32.const 8) + ) + ) + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (br_if $label$15 + (i32.eq + (get_local $5) + (get_local $7) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=20 + (tee_local $9 + (i32.load + (i32.add + (get_local $5) + (i32.const -24) + ) + ) + ) + ) + (get_local $10) + ) + (i32.const 224) + ) + (br_if $label$14 + (get_local $9) + ) + (br $label$13) + ) + (br_if $label$13 + (i32.lt_s + (tee_local $9 + (call $db_find_i64 + (i64.load + (i32.add + (get_local $11) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $11) + (i32.const 16) + ) + ) + (i64.const 6290548272952901632) + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=20 + (tee_local $9 + (call $_ZNK5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE31load_object_by_primary_iteratorEl + (get_local $10) + (get_local $9) + ) + ) + ) + (get_local $10) + ) + (i32.const 224) + ) + ) + (i32.store offset=48 + (get_local $12) + (get_local $2) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 352) + ) + (call $_ZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE6modifyIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_1EEvRKS1_yOT_ + (get_local $10) + (get_local $9) + (i32.add + (get_local $12) + (i32.const 48) + ) + ) + (br $label$12) + ) + (set_local $1 + (i64.load offset=16 + (get_local $12) + ) + ) + (i32.store offset=12 + (get_local $12) + (get_local $2) + ) + (i32.store offset=8 + (get_local $12) + (i32.add + (get_local $12) + (i32.const 16) + ) + ) + (i64.store offset=40 + (get_local $12) + (get_local $1) + ) + (call $eosio_assert + (i64.eq + (i64.load + (i32.add + (get_local $11) + (i32.const 8) + ) + ) + (call $current_receiver) + ) + (i32.const 288) + ) + (i32.store offset=48 + (get_local $12) + (get_local $10) + ) + (i32.store offset=52 + (get_local $12) + (i32.add + (get_local $12) + (i32.const 8) + ) + ) + (i32.store offset=56 + (get_local $12) + (i32.add + (get_local $12) + (i32.const 40) + ) + ) + (i32.store offset=16 + (tee_local $9 + (call $_Znwj + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i64.store offset=8 align=4 + (get_local $9) + (i64.const 0) + ) + (i32.store offset=20 + (get_local $9) + (get_local $10) + ) + (call $_ZZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE7emplaceIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_0EENS2_14const_iteratorEyOT_ENKUlRSH_E_clINS2_4itemEEEDaSJ_ + (i32.add + (get_local $12) + (i32.const 48) + ) + (get_local $9) + ) + (i32.store offset=32 + (get_local $12) + (get_local $9) + ) + (i64.store offset=48 + (get_local $12) + (tee_local $1 + (i64.load + (get_local $9) + ) + ) + ) + (i32.store offset=28 + (get_local $12) + (tee_local $5 + (i32.load offset=24 + (get_local $9) + ) + ) + ) + (block $label$16 + (block $label$17 + (br_if $label$17 + (i32.ge_u + (tee_local $10 + (i32.load + (tee_local $6 + (i32.add + (get_local $11) + (i32.const 36) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $11) + (i32.const 40) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $10) + (get_local $1) + ) + (i32.store offset=16 + (get_local $10) + (get_local $5) + ) + (i32.store offset=32 + (get_local $12) + (i32.const 0) + ) + (i32.store + (get_local $10) + (get_local $9) + ) + (i32.store + (get_local $6) + (i32.add + (get_local $10) + (i32.const 24) + ) + ) + (br $label$16) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy6290548272952901632ENS1_9exaccountEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $11) + (i32.const 32) + ) + (i32.add + (get_local $12) + (i32.const 32) + ) + (i32.add + (get_local $12) + (i32.const 48) + ) + (i32.add + (get_local $12) + (i32.const 28) + ) + ) + ) + (set_local $10 + (i32.load offset=32 + (get_local $12) + ) + ) + (i32.store offset=32 + (get_local $12) + (i32.const 0) + ) + (br_if $label$12 + (i32.eqz + (get_local $10) + ) + ) + (block $label$18 + (br_if $label$18 + (i32.eqz + (i32.load + (i32.add + (get_local $10) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $10) + ) + ) + ) + (call $_ZdlPv + (get_local $10) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $12) + (i32.const 96) + ) + ) + ) + (func $_ZN5boost9container3dtl9flat_treeINS1_4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS1_9select1stIyEENSt3__14lessIyEENS0_13new_allocatorIS8_EEE13insert_uniqueEOS8_ (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i64) + (local $10 i32) + (i32.store8 offset=4 + (get_local $0) + (i32.const 0) + ) + (i32.store + (get_local $0) + (i32.const 0) + ) + (set_local $5 + (i64.load + (get_local $2) + ) + ) + (set_local $6 + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $7 + (i32.div_s + (i32.mul + (tee_local $4 + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.const 48) + ) + (i32.const 48) + ) + ) + ) + ) + (loop $label$1 + (block $label$2 + (br_if $label$2 + (i64.ge_u + (i64.load + (tee_local $8 + (i32.add + (get_local $6) + (i32.mul + (tee_local $10 + (i32.shr_u + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 48) + ) + ) + ) + ) + (get_local $5) + ) + ) + (set_local $6 + (i32.add + (get_local $8) + (i32.const 48) + ) + ) + (set_local $10 + (i32.sub + (i32.add + (get_local $7) + (i32.const -1) + ) + (get_local $10) + ) + ) + ) + (br_if $label$1 + (tee_local $7 + (get_local $10) + ) + ) + ) + ) + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.eq + (get_local $6) + (i32.add + (get_local $3) + (i32.mul + (get_local $4) + (i32.const 48) + ) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $0) + (i32.const 4) + ) + (i64.lt_u + (get_local $5) + (tee_local $9 + (i64.load + (get_local $6) + ) + ) + ) + ) + (br_if $label$5 + (i64.lt_u + (get_local $5) + (get_local $9) + ) + ) + (br $label$4) + ) + (i32.store8 + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.const 1) + ) + ) + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (br_if $label$10 + (i32.ne + (i32.load offset=8 + (get_local $1) + ) + (get_local $4) + ) + ) + (br_if $label$3 + (i32.eq + (get_local $4) + (i32.const 89478485) + ) + ) + (br_if $label$9 + (i32.gt_u + (get_local $4) + (i32.const 536870911) + ) + ) + (set_local $7 + (i32.div_u + (i32.shl + (get_local $4) + (i32.const 3) + ) + (i32.const 5) + ) + ) + (br $label$8) + ) + (call $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_expand_forwardINS2_17insert_move_proxyISA_PS8_EEEEvSE_jT_ + (get_local $1) + (get_local $6) + (i32.const 1) + (get_local $2) + ) + (br $label$7) + ) + (set_local $7 + (select + (i32.const -1) + (i32.shl + (get_local $4) + (i32.const 3) + ) + (i32.gt_u + (get_local $4) + (i32.const -1610612737) + ) + ) + ) + ) + (br_if $label$3 + (i32.ge_u + (tee_local $7 + (select + (tee_local $10 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (tee_local $7 + (select + (get_local $7) + (i32.const 89478485) + (i32.lt_u + (get_local $7) + (i32.const 89478485) + ) + ) + ) + (i32.gt_u + (get_local $10) + (get_local $7) + ) + ) + ) + (i32.const 89478486) + ) + ) + (call $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_new_allocationINS2_17insert_move_proxyISA_PS8_EEEEvSE_jSE_jT_ + (get_local $1) + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 48) + ) + ) + (get_local $7) + (get_local $6) + (i32.const 1) + (get_local $2) + ) + ) + (set_local $6 + (i32.add + (i32.load + (get_local $1) + ) + (i32.mul + (i32.div_s + (i32.sub + (get_local $6) + (get_local $3) + ) + (i32.const 48) + ) + (i32.const 48) + ) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + (return) + ) + (call $abort) + (unreachable) + ) + (func $_ZNK5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (set_local $8 + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $9) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $2 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $2) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i32.eq + (i32.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $4 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $4) + (get_local $3) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + (set_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i32.xor + (i32.shr_u + (tee_local $6 + (call $db_get_i64 + (get_local $1) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 31) + ) + (i32.const 1) + ) + (i32.const 656) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.lt_u + (get_local $6) + (i32.const 513) + ) + ) + (set_local $4 + (call $malloc + (get_local $6) + ) + ) + (br $label$4) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (get_local $9) + (i32.and + (i32.add + (get_local $6) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $db_get_i64 + (get_local $1) + (get_local $4) + (get_local $6) + ) + ) + (i32.store offset=36 + (get_local $8) + (get_local $4) + ) + (i32.store offset=32 + (get_local $8) + (get_local $4) + ) + (i32.store offset=40 + (get_local $8) + (tee_local $7 + (i32.add + (get_local $4) + (get_local $6) + ) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.le_u + (get_local $6) + (i32.const 512) + ) + ) + (call $free + (get_local $4) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $8) + (i32.const 40) + ) + ) + ) + (set_local $4 + (i32.load offset=36 + (get_local $8) + ) + ) + ) + (i32.store offset=16 + (tee_local $6 + (call $_Znwj + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i64.store offset=8 align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store offset=20 + (get_local $6) + (get_local $0) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (get_local $7) + (get_local $4) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $6) + (get_local $4) + (i32.const 8) + ) + ) + (i32.store offset=36 + (get_local $8) + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEENS_15extended_symbolExEERT_S7_RN5boost9container8flat_mapIT0_T1_NSt3__14lessISB_EENS9_13new_allocatorINSD_4pairISB_SC_EEEEEE + (i32.add + (get_local $8) + (i32.const 32) + ) + (i32.add + (get_local $6) + (i32.const 8) + ) + ) + ) + (i32.store offset=24 + (get_local $6) + (get_local $1) + ) + (i32.store offset=24 + (get_local $8) + (get_local $6) + ) + (i64.store offset=16 + (get_local $8) + (tee_local $5 + (i64.load + (get_local $6) + ) + ) + ) + (i32.store offset=12 + (get_local $8) + (tee_local $7 + (i32.load offset=24 + (get_local $6) + ) + ) + ) + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ge_u + (tee_local $4 + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $4) + (get_local $5) + ) + (i32.store offset=16 + (get_local $4) + (get_local $7) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $4) + (get_local $6) + ) + (i32.store + (get_local $1) + (i32.add + (get_local $4) + (i32.const 24) + ) + ) + (br $label$7) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy6290548272952901632ENS1_9exaccountEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 12) + ) + ) + ) + (set_local $4 + (i32.load offset=24 + (get_local $8) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $4) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (i32.load + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $4) + ) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 48) + ) + ) + (get_local $6) + ) + (func $_ZZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE7emplaceIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_0EENS2_14const_iteratorEyOT_ENKUlRSH_E_clINS2_4itemEEEDaSJ_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i64) + (local $14 i32) + (local $15 i32) + (set_local $14 + (tee_local $15 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $15) + ) + (i64.store + (get_local $1) + (i64.load + (i32.load + (tee_local $3 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + ) + ) + (set_local $6 + (i32.add + (tee_local $11 + (i32.load offset=8 + (get_local $1) + ) + ) + (tee_local $10 + (i32.mul + (i32.load + (i32.add + (get_local $1) + (i32.const 12) + ) + ) + (i32.const 24) + ) + ) + ) + ) + (set_local $2 + (i32.load + (get_local $0) + ) + ) + (set_local $5 + (i64.load offset=16 + (tee_local $12 + (i32.load offset=4 + (get_local $3) + ) + ) + ) + ) + (set_local $13 + (i64.load offset=8 + (get_local $12) + ) + ) + (set_local $4 + (i64.load + (get_local $12) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $10) + ) + ) + (set_local $12 + (i32.div_s + (get_local $10) + (i32.const 24) + ) + ) + (set_local $10 + (get_local $11) + ) + (loop $label$1 + (set_local $10 + (select + (tee_local $9 + (i32.add + (tee_local $8 + (i32.add + (get_local $10) + (i32.mul + (tee_local $7 + (i32.shr_u + (get_local $12) + (i32.const 1) + ) + ) + (i32.const 24) + ) + ) + ) + (i32.const 24) + ) + ) + (get_local $10) + (tee_local $8 + (i64.lt_u + (i64.load + (get_local $8) + ) + (get_local $13) + ) + ) + ) + ) + (set_local $11 + (select + (get_local $9) + (get_local $11) + (get_local $8) + ) + ) + (br_if $label$1 + (tee_local $12 + (select + (i32.sub + (i32.add + (get_local $12) + (i32.const -1) + ) + (get_local $7) + ) + (get_local $7) + (get_local $8) + ) + ) + ) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $11) + (get_local $6) + ) + ) + (br_if $label$2 + (i64.ge_u + (get_local $13) + (i64.load + (get_local $11) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $14) + (get_local $5) + ) + (i64.store + (get_local $14) + (get_local $13) + ) + (i64.store offset=16 + (get_local $14) + (i64.const 0) + ) + (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueENS0_12vec_iteratorIPS6_Lb1EEEOS6_ + (i32.add + (get_local $14) + (i32.const 24) + ) + (get_local $7) + (get_local $11) + (get_local $14) + ) + (set_local $11 + (i32.load offset=24 + (get_local $14) + ) + ) + ) + (i64.store offset=16 + (get_local $11) + (get_local $4) + ) + (call $eosio_assert + (i32.xor + (i32.wrap/i64 + (i64.shr_u + (i64.load + (i32.load + (i32.add + (get_local $3) + (i32.const 4) + ) + ) + ) + (i64.const 63) + ) + ) + (i32.const 1) + ) + (i32.const 624) + ) + (set_local $13 + (i64.extend_u/i32 + (tee_local $10 + (i32.load + (i32.add + (get_local $1) + (i32.const 12) + ) + ) + ) + ) + ) + (set_local $12 + (i32.const 8) + ) + (loop $label$4 + (set_local $12 + (i32.add + (get_local $12) + (i32.const 1) + ) + ) + (br_if $label$4 + (i64.ne + (tee_local $13 + (i64.shr_u + (get_local $13) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (get_local $10) + ) + ) + (set_local $12 + (i32.add + (i32.sub + (tee_local $10 + (i32.mul + (get_local $10) + (i32.const 24) + ) + ) + (i32.rem_u + (i32.add + (get_local $10) + (i32.const -24) + ) + (i32.const 24) + ) + ) + (get_local $12) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.lt_u + (get_local $12) + (i32.const 513) + ) + ) + (set_local $10 + (call $malloc + (get_local $12) + ) + ) + (br $label$6) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (get_local $15) + (i32.and + (i32.add + (get_local $12) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (i32.store + (get_local $14) + (get_local $10) + ) + (i32.store offset=8 + (get_local $14) + (i32.add + (get_local $10) + (get_local $12) + ) + ) + (call $eosio_assert + (i32.gt_s + (get_local $12) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (get_local $10) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $14) + (i32.add + (get_local $10) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEENS_15extended_symbolExEERT_S6_RKN5boost9container8flat_mapIT0_T1_NSt3__14lessISA_EENS8_13new_allocatorINSC_4pairISA_SB_EEEEEE + (get_local $14) + (get_local $7) + ) + ) + (i32.store offset=24 + (get_local $1) + (call $db_store_i64 + (i64.load offset=8 + (get_local $2) + ) + (i64.const 6290548272952901632) + (i64.load + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $13 + (i64.load + (get_local $1) + ) + ) + (get_local $10) + (get_local $12) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.lt_u + (get_local $12) + (i32.const 513) + ) + ) + (call $free + (get_local $10) + ) + ) + (block $label$9 + (br_if $label$9 + (i64.lt_u + (get_local $13) + (i64.load offset=16 + (get_local $2) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (select + (i64.const -2) + (i64.add + (get_local $13) + (i64.const 1) + ) + (i64.gt_u + (get_local $13) + (i64.const -3) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $14) + (i32.const 32) + ) + ) + ) + (func $_ZNSt3__16vectorIN5eosio11multi_indexILy6290548272952901632ENS1_9exaccountEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.add + (tee_local $4 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 24) + ) + ) + (i32.const 1) + ) + ) + (i32.const 178956971) + ) + ) + (set_local $7 + (i32.const 178956970) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $6 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $6) + ) + (i32.const 24) + ) + ) + (i32.const 89478484) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $5) + (tee_local $7 + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $5) + ) + ) + ) + ) + ) + ) + (set_local $6 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $5 + (i32.load + (get_local $1) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $6) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + (get_local $5) + ) + (i64.store offset=8 + (get_local $1) + (i64.load + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $1) + (i32.load + (get_local $3) + ) + ) + (set_local $4 + (i32.add + (get_local $6) + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (loop $label$6 + (set_local $3 + (i32.load + (tee_local $2 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -24) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -8) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -12) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -16) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const -24) + ) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$6 + (i32.ne + (get_local $7) + (get_local $2) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $6 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $5) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $6) + ) + ) + (loop $label$8 + (set_local $1 + (i32.load + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $1) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (i32.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $1) + ) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $6) + (get_local $7) + ) + ) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $_ZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE6modifyIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_1EEvRKS1_yOT_ (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i64) + (local $13 i32) + (local $14 i32) + (set_local $13 + (tee_local $14 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $14) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=20 + (get_local $1) + ) + (get_local $0) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $0) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (set_local $6 + (i32.add + (tee_local $11 + (i32.load offset=8 + (get_local $1) + ) + ) + (tee_local $10 + (i32.mul + (i32.load + (i32.add + (get_local $1) + (i32.const 12) + ) + ) + (i32.const 24) + ) + ) + ) + ) + (set_local $3 + (i64.load + (get_local $1) + ) + ) + (set_local $5 + (i64.load offset=16 + (tee_local $2 + (i32.load + (get_local $2) + ) + ) + ) + ) + (set_local $12 + (i64.load offset=8 + (get_local $2) + ) + ) + (set_local $4 + (i64.load + (get_local $2) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $10) + ) + ) + (set_local $2 + (i32.div_s + (get_local $10) + (i32.const 24) + ) + ) + (set_local $10 + (get_local $11) + ) + (loop $label$1 + (set_local $10 + (select + (tee_local $9 + (i32.add + (tee_local $8 + (i32.add + (get_local $10) + (i32.mul + (tee_local $7 + (i32.shr_u + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 24) + ) + ) + ) + (i32.const 24) + ) + ) + (get_local $10) + (tee_local $8 + (i64.lt_u + (i64.load + (get_local $8) + ) + (get_local $12) + ) + ) + ) + ) + (set_local $11 + (select + (get_local $9) + (get_local $11) + (get_local $8) + ) + ) + (br_if $label$1 + (tee_local $2 + (select + (i32.sub + (i32.add + (get_local $2) + (i32.const -1) + ) + (get_local $7) + ) + (get_local $7) + (get_local $8) + ) + ) + ) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $11) + (get_local $6) + ) + ) + (br_if $label$2 + (i64.ge_u + (get_local $12) + (i64.load + (get_local $11) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $13) + (get_local $5) + ) + (i64.store + (get_local $13) + (get_local $12) + ) + (i64.store offset=16 + (get_local $13) + (i64.const 0) + ) + (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueENS0_12vec_iteratorIPS6_Lb1EEEOS6_ + (i32.add + (get_local $13) + (i32.const 24) + ) + (get_local $7) + (get_local $11) + (get_local $13) + ) + (set_local $11 + (i32.load offset=24 + (get_local $13) + ) + ) + ) + (i64.store offset=16 + (get_local $11) + (tee_local $12 + (i64.add + (i64.load offset=16 + (get_local $11) + ) + (get_local $4) + ) + ) + ) + (call $eosio_assert + (i32.xor + (i32.wrap/i64 + (i64.shr_u + (get_local $12) + (i64.const 63) + ) + ) + (i32.const 1) + ) + (i32.const 512) + ) + (call $eosio_assert + (i64.eq + (get_local $3) + (i64.load + (get_local $1) + ) + ) + (i32.const 544) + ) + (set_local $12 + (i64.extend_u/i32 + (tee_local $10 + (i32.load + (i32.add + (get_local $1) + (i32.const 12) + ) + ) + ) + ) + ) + (set_local $2 + (i32.const 8) + ) + (loop $label$4 + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (br_if $label$4 + (i64.ne + (tee_local $12 + (i64.shr_u + (get_local $12) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (get_local $10) + ) + ) + (set_local $2 + (i32.add + (i32.sub + (tee_local $10 + (i32.mul + (get_local $10) + (i32.const 24) + ) + ) + (i32.rem_u + (i32.add + (get_local $10) + (i32.const -24) + ) + (i32.const 24) + ) + ) + (get_local $2) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.lt_u + (get_local $2) + (i32.const 513) + ) + ) + (set_local $10 + (call $malloc + (get_local $2) + ) + ) + (br $label$6) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (get_local $14) + (i32.and + (i32.add + (get_local $2) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (i32.store + (get_local $13) + (get_local $10) + ) + (i32.store offset=8 + (get_local $13) + (i32.add + (get_local $10) + (get_local $2) + ) + ) + (call $eosio_assert + (i32.gt_s + (get_local $2) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (get_local $10) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $13) + (i32.add + (get_local $10) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEENS_15extended_symbolExEERT_S6_RKN5boost9container8flat_mapIT0_T1_NSt3__14lessISA_EENS8_13new_allocatorINSC_4pairISA_SB_EEEEEE + (get_local $13) + (get_local $7) + ) + ) + (call $db_update_i64 + (i32.load offset=24 + (get_local $1) + ) + (i64.const 0) + (get_local $10) + (get_local $2) + ) + (block $label$8 + (br_if $label$8 + (i32.lt_u + (get_local $2) + (i32.const 513) + ) + ) + (call $free + (get_local $10) + ) + ) + (block $label$9 + (br_if $label$9 + (i64.lt_u + (get_local $3) + (i64.load offset=16 + (get_local $0) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (select + (i64.const -2) + (i64.add + (get_local $3) + (i64.const 1) + ) + (i64.gt_u + (get_local $3) + (i64.const -3) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $13) + (i32.const 32) + ) + ) + ) + (func $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueENS0_12vec_iteratorIPS6_Lb1EEEOS6_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i64) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $13 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.eq + (tee_local $6 + (i32.add + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + (i32.mul + (tee_local $5 + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.const 24) + ) + ) + ) + (get_local $2) + ) + ) + (br_if $label$7 + (i64.ge_u + (tee_local $7 + (i64.load + (get_local $3) + ) + ) + (i64.load + (get_local $2) + ) + ) + ) + ) + (br_if $label$4 + (i32.eq + (get_local $4) + (get_local $2) + ) + ) + (br_if $label$4 + (i64.lt_u + (tee_local $8 + (i64.load + (tee_local $12 + (i32.add + (get_local $2) + (i32.const -24) + ) + ) + ) + ) + (tee_local $7 + (i64.load + (get_local $3) + ) + ) + ) + ) + (br_if $label$3 + (i64.ge_u + (get_local $7) + (get_local $8) + ) + ) + (set_local $2 + (get_local $4) + ) + (br_if $label$6 + (tee_local $11 + (i32.div_s + (i32.sub + (get_local $12) + (get_local $4) + ) + (i32.const 24) + ) + ) + ) + (br $label$5) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (tee_local $11 + (i32.div_s + (i32.sub + (get_local $6) + (get_local $2) + ) + (i32.const 24) + ) + ) + ) + ) + (loop $label$10 + (block $label$11 + (br_if $label$11 + (i64.ge_u + (i64.load + (tee_local $9 + (i32.add + (get_local $2) + (i32.mul + (tee_local $10 + (i32.shr_u + (get_local $11) + (i32.const 1) + ) + ) + (i32.const 24) + ) + ) + ) + ) + (get_local $7) + ) + ) + (set_local $2 + (i32.add + (get_local $9) + (i32.const 24) + ) + ) + (set_local $10 + (i32.sub + (i32.add + (get_local $11) + (i32.const -1) + ) + (get_local $10) + ) + ) + ) + (br_if $label$10 + (tee_local $11 + (get_local $10) + ) + ) + ) + ) + (br_if $label$4 + (i32.eq + (get_local $2) + (get_local $6) + ) + ) + (set_local $12 + (get_local $2) + ) + (br_if $label$4 + (i64.lt_u + (get_local $7) + (i64.load + (get_local $2) + ) + ) + ) + (br $label$3) + ) + (loop $label$12 + (block $label$13 + (br_if $label$13 + (i64.ge_u + (i64.load + (tee_local $9 + (i32.add + (get_local $2) + (i32.mul + (tee_local $10 + (i32.shr_u + (get_local $11) + (i32.const 1) + ) + ) + (i32.const 24) + ) + ) + ) + ) + (get_local $7) + ) + ) + (set_local $2 + (i32.add + (get_local $9) + (i32.const 24) + ) + ) + (set_local $10 + (i32.sub + (i32.add + (get_local $11) + (i32.const -1) + ) + (get_local $10) + ) + ) + ) + (br_if $label$12 + (tee_local $11 + (get_local $10) + ) + ) + ) + ) + (br_if $label$4 + (i32.eq + (get_local $2) + (get_local $12) + ) + ) + (set_local $12 + (get_local $2) + ) + (br_if $label$3 + (i64.ge_u + (get_local $7) + (i64.load + (get_local $2) + ) + ) + ) + ) + (i32.store offset=8 + (get_local $13) + (get_local $2) + ) + (block $label$14 + (br_if $label$14 + (i32.ne + (i32.load offset=8 + (get_local $1) + ) + (get_local $5) + ) + ) + (call $_ZN5boost9container6vectorINS0_3dtl4pairIN5eosio15extended_symbolExEENS0_13new_allocatorIS6_EEvE37priv_forward_range_insert_no_capacityINS2_17insert_move_proxyIS8_PS6_EEEENS0_12vec_iteratorISC_Lb0EEERKSC_jT_NS_11move_detail17integral_constantIjLj1EEE + (get_local $0) + (get_local $1) + (i32.add + (get_local $13) + (i32.const 8) + ) + (i32.const 1) + (get_local $3) + ) + (br $label$0) + ) + (set_local $9 + (i32.div_s + (i32.sub + (get_local $2) + (get_local $4) + ) + (i32.const 24) + ) + ) + (br_if $label$2 + (i32.eq + (get_local $6) + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $6) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + ) + (i64.store + (get_local $6) + (i64.load + (tee_local $11 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + ) + (i64.store offset=16 + (i32.add + (get_local $4) + (i32.mul + (get_local $5) + (i32.const 24) + ) + ) + (i64.load + (i32.add + (get_local $6) + (i32.const -8) + ) + ) + ) + (i32.store + (tee_local $10 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (get_local $10) + ) + (i32.const 1) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eq + (get_local $11) + (get_local $2) + ) + ) + (loop $label$16 + (i64.store + (i32.add + (get_local $11) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $11) + (i32.const -16) + ) + ) + ) + (i64.store + (get_local $11) + (i64.load + (tee_local $10 + (i32.add + (get_local $11) + (i32.const -24) + ) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $11) + (i32.const -8) + ) + ) + ) + (set_local $11 + (get_local $10) + ) + (br_if $label$16 + (i32.ne + (get_local $2) + (get_local $10) + ) + ) + ) + ) + (i64.store + (get_local $2) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + (i64.store offset=16 + (get_local $2) + (i64.load offset=16 + (get_local $3) + ) + ) + (br $label$1) + ) + (i32.store + (get_local $0) + (i32.add + (get_local $4) + (i32.mul + (i32.div_s + (i32.sub + (get_local $12) + (get_local $4) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + (br $label$0) + ) + (i64.store + (get_local $2) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + (i64.store offset=16 + (i32.add + (get_local $4) + (i32.mul + (get_local $5) + (i32.const 24) + ) + ) + (i64.load offset=16 + (get_local $3) + ) + ) + (i32.store + (tee_local $11 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (i32.store + (get_local $0) + (i32.add + (i32.load + (get_local $1) + ) + (i32.mul + (get_local $9) + (i32.const 24) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $13) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEENS_15extended_symbolExEERT_S6_RKN5boost9container8flat_mapIT0_T1_NSt3__14lessISA_EENS8_13new_allocatorINSC_4pairISA_SB_EEEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $5 + (i64.load32_u offset=4 + (get_local $1) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $7 + (i32.wrap/i64 + (get_local $5) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $2 + (i64.ne + (tee_local $5 + (i64.shr_u + (get_local $5) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $7) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $3) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $2) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $4 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (set_local $3 + (i32.add + (tee_local $7 + (i32.load + (get_local $1) + ) + ) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$2 + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $6) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (get_local $7) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $6) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $6) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + ) + (br_if $label$2 + (i32.ne + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 24) + ) + ) + (get_local $3) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5boost9container6vectorINS0_3dtl4pairIN5eosio15extended_symbolExEENS0_13new_allocatorIS6_EEvE37priv_forward_range_insert_no_capacityINS2_17insert_move_proxyIS8_PS6_EEEENS0_12vec_iteratorISC_Lb0EEERKSC_jT_NS_11move_detail17integral_constantIjLj1EEE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (set_local $6 + (i32.div_s + (i32.sub + (tee_local $5 + (i32.load + (get_local $2) + ) + ) + (i32.load + (get_local $1) + ) + ) + (i32.const 24) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.lt_u + (i32.sub + (i32.const 178956970) + (tee_local $2 + (i32.load offset=8 + (get_local $1) + ) + ) + ) + (i32.add + (i32.sub + (get_local $3) + (get_local $2) + ) + (tee_local $10 + (i32.load offset=4 + (get_local $1) + ) + ) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.gt_u + (get_local $2) + (i32.const 536870911) + ) + ) + (set_local $2 + (i32.div_u + (i32.shl + (get_local $2) + (i32.const 3) + ) + (i32.const 5) + ) + ) + (br $label$1) + ) + (set_local $2 + (select + (i32.const -1) + (i32.shl + (get_local $2) + (i32.const 3) + ) + (i32.gt_u + (get_local $2) + (i32.const -1610612737) + ) + ) + ) + ) + (br_if $label$0 + (i32.ge_u + (tee_local $7 + (select + (tee_local $10 + (i32.add + (get_local $10) + (get_local $3) + ) + ) + (tee_local $2 + (select + (get_local $2) + (i32.const 178956970) + (i32.lt_u + (get_local $2) + (i32.const 178956970) + ) + ) + ) + (i32.gt_u + (get_local $10) + (get_local $2) + ) + ) + ) + (i32.const 178956971) + ) + ) + (set_local $2 + (tee_local $9 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eq + (tee_local $8 + (i32.load + (get_local $1) + ) + ) + (get_local $5) + ) + ) + (set_local $2 + (get_local $9) + ) + (br_if $label$3 + (i32.eqz + (get_local $8) + ) + ) + (set_local $10 + (get_local $8) + ) + (set_local $2 + (get_local $9) + ) + (loop $label$4 + (i64.store + (get_local $2) + (i64.load + (get_local $10) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const 8) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const 16) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 24) + ) + ) + (br_if $label$4 + (i32.ne + (tee_local $10 + (i32.add + (get_local $10) + (i32.const 24) + ) + ) + (get_local $5) + ) + ) + ) + ) + (i64.store + (get_local $2) + (i64.load + (get_local $4) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + ) + (i64.store offset=16 + (get_local $2) + (i64.load offset=16 + (get_local $4) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.mul + (get_local $3) + (i32.const 24) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (get_local $8) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.eq + (tee_local $10 + (i32.add + (get_local $8) + (i32.mul + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (i32.const 24) + ) + ) + ) + (get_local $5) + ) + ) + (loop $label$7 + (i64.store + (get_local $2) + (i64.load + (get_local $5) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 24) + ) + ) + (br_if $label$7 + (i32.ne + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 24) + ) + ) + (get_local $10) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load + (get_local $1) + ) + ) + ) + (i32.store + (get_local $1) + (get_local $9) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 8) + ) + (get_local $7) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.div_s + (i32.sub + (get_local $2) + (get_local $9) + ) + (i32.const 24) + ) + ) + (i32.store + (get_local $0) + (i32.add + (get_local $9) + (i32.mul + (get_local $6) + (i32.const 24) + ) + ) + ) + (return) + ) + (call $abort) + (unreachable) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEENS_15extended_symbolExEERT_S7_RN5boost9container8flat_mapIT0_T1_NSt3__14lessISB_EENS9_13new_allocatorINSD_4pairISB_SC_EEEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=4 + (get_local $1) + (i32.const 0) + ) + (set_local $8 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $5 + (i64.const 0) + ) + (set_local $7 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $8) + (i32.load + (get_local $7) + ) + ) + (i32.const 704) + ) + (set_local $3 + (i32.load8_u + (tee_local $8 + (i32.load + (get_local $2) + ) + ) + ) + ) + (i32.store + (get_local $2) + (tee_local $8 + (i32.add + (get_local $8) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $3) + (i32.const 127) + ) + (tee_local $6 + (i32.and + (get_local $6) + (i32.const 255) + ) + ) + ) + ) + (get_local $5) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $3) + (i32.const 7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $3 + (i32.wrap/i64 + (get_local $5) + ) + ) + ) + ) + (set_local $7 + (i32.add + (get_local $3) + (i32.const -1) + ) + ) + (set_local $6 + (i32.add + (i32.add + (get_local $9) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (set_local $4 + (i32.add + (get_local $9) + (i32.const 56) + ) + ) + (loop $label$2 + (i64.store + (get_local $6) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $9) + (i64.const 0) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $8) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $9) + (i32.const 16) + ) + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $3) + (tee_local $8 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $8) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $6) + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $3) + (tee_local $8 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $8) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $9) + (i32.const 8) + ) + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $3) + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 40) + ) + (i32.const 8) + ) + (i64.load + (get_local $6) + ) + ) + (i64.store offset=40 + (get_local $9) + (i64.load offset=16 + (get_local $9) + ) + ) + (i64.store + (get_local $4) + (i64.load offset=8 + (get_local $9) + ) + ) + (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueEOS6_ + (i32.add + (get_local $9) + (i32.const 32) + ) + (get_local $1) + (i32.add + (get_local $9) + (i32.const 40) + ) + ) + (br_if $label$1 + (i32.eqz + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const -1) + ) + ) + (set_local $8 + (i32.load + (get_local $3) + ) + ) + (br $label$2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 64) + ) + ) + (get_local $0) + ) + (func $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueEOS6_ (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i64) + (local $10 i32) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store8 offset=4 + (get_local $0) + (i32.const 0) + ) + (i32.store + (get_local $0) + (i32.const 0) + ) + (set_local $5 + (i64.load + (get_local $2) + ) + ) + (set_local $6 + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $7 + (i32.div_s + (i32.mul + (tee_local $4 + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.const 24) + ) + (i32.const 24) + ) + ) + ) + ) + (loop $label$1 + (block $label$2 + (br_if $label$2 + (i64.ge_u + (i64.load + (tee_local $8 + (i32.add + (get_local $6) + (i32.mul + (tee_local $10 + (i32.shr_u + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 24) + ) + ) + ) + ) + (get_local $5) + ) + ) + (set_local $6 + (i32.add + (get_local $8) + (i32.const 24) + ) + ) + (set_local $10 + (i32.sub + (i32.add + (get_local $7) + (i32.const -1) + ) + (get_local $10) + ) + ) + ) + (br_if $label$1 + (tee_local $7 + (get_local $10) + ) + ) + ) + ) + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.eqz + (tee_local $7 + (i32.ne + (get_local $6) + (tee_local $10 + (i32.add + (get_local $3) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + ) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $0) + (i32.const 4) + ) + (i64.lt_u + (get_local $5) + (tee_local $9 + (i64.load + (get_local $6) + ) + ) + ) + ) + (br_if $label$5 + (i64.lt_u + (get_local $5) + (get_local $9) + ) + ) + (br $label$4) + ) + (i32.store8 + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.const 1) + ) + ) + (i32.store offset=8 + (get_local $11) + (get_local $6) + ) + (block $label$7 + (br_if $label$7 + (i32.ne + (i32.load offset=8 + (get_local $1) + ) + (get_local $4) + ) + ) + (call $_ZN5boost9container6vectorINS0_3dtl4pairIN5eosio15extended_symbolExEENS0_13new_allocatorIS6_EEvE37priv_forward_range_insert_no_capacityINS2_17insert_move_proxyIS8_PS6_EEEENS0_12vec_iteratorISC_Lb0EEERKSC_jT_NS_11move_detail17integral_constantIjLj1EEE + (get_local $11) + (get_local $1) + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.const 1) + (get_local $2) + ) + (set_local $6 + (i32.load + (get_local $11) + ) + ) + (br $label$3) + ) + (set_local $8 + (i32.div_s + (i32.sub + (get_local $6) + (get_local $3) + ) + (i32.const 24) + ) + ) + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $7) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const -16) + ) + ) + ) + (i64.store + (get_local $10) + (i64.load + (tee_local $7 + (i32.add + (get_local $10) + (i32.const -24) + ) + ) + ) + ) + (i64.store offset=16 + (i32.add + (get_local $3) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const -8) + ) + ) + ) + (i32.store + (tee_local $10 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (get_local $10) + ) + (i32.const 1) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eq + (get_local $7) + (get_local $6) + ) + ) + (loop $label$11 + (i64.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -16) + ) + ) + ) + (i64.store + (get_local $7) + (i64.load + (tee_local $10 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i64.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -8) + ) + ) + ) + (set_local $7 + (get_local $10) + ) + (br_if $label$11 + (i32.ne + (get_local $6) + (get_local $10) + ) + ) + ) + ) + (i64.store + (get_local $6) + (i64.load + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $6) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i64.store offset=16 + (get_local $6) + (i64.load offset=16 + (get_local $2) + ) + ) + (br $label$8) + ) + (i64.store + (get_local $6) + (i64.load + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $6) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i64.store offset=16 + (i32.add + (get_local $3) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + (i64.load offset=16 + (get_local $2) + ) + ) + (i32.store + (tee_local $7 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (get_local $7) + ) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i32.add + (i32.load + (get_local $1) + ) + (i32.mul + (get_local $8) + (i32.const 24) + ) + ) + ) + ) + (i32.store + (get_local $11) + (get_local $6) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 16) + ) + ) + ) + (func $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_new_allocationINS2_17insert_move_proxyISA_PS8_EEEEvSE_jSE_jT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (set_local $11 + (get_local $1) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $10 + (i32.load + (get_local $0) + ) + ) + (get_local $3) + ) + ) + (set_local $11 + (get_local $1) + ) + (br_if $label$0 + (i32.eqz + (get_local $10) + ) + ) + (set_local $6 + (get_local $10) + ) + (set_local $11 + (get_local $1) + ) + (loop $label$1 + (i64.store + (get_local $11) + (i64.load + (get_local $6) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $6) + (i32.const 24) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $6) + (i32.const 8) + ) + ) + ) + (i32.store + (tee_local $12 + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $9 + (i32.add + (get_local $11) + (i32.const 36) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $7 + (i32.add + (get_local $11) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $12) + (i32.load + (tee_local $8 + (i32.add + (get_local $6) + (i32.const 32) + ) + ) + ) + ) + (i32.store + (get_local $9) + (i32.load + (i32.add + (get_local $6) + (i32.const 36) + ) + ) + ) + (i32.store + (get_local $7) + (i32.load + (tee_local $12 + (i32.add + (get_local $6) + (i32.const 40) + ) + ) + ) + ) + (i32.store + (get_local $12) + (i32.const 0) + ) + (i64.store align=4 + (get_local $8) + (i64.const 0) + ) + (set_local $11 + (i32.add + (get_local $11) + (i32.const 48) + ) + ) + (br_if $label$1 + (i32.ne + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 48) + ) + ) + (get_local $3) + ) + ) + ) + ) + (i64.store + (get_local $11) + (i64.load + (get_local $5) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 24) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $11) + (i64.load offset=8 + (get_local $5) + ) + ) + (i32.store + (tee_local $6 + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $12 + (i32.add + (get_local $11) + (i32.const 36) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $9 + (i32.add + (get_local $11) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $6) + (i32.load + (tee_local $7 + (i32.add + (get_local $5) + (i32.const 32) + ) + ) + ) + ) + (i32.store + (get_local $12) + (i32.load + (i32.add + (get_local $5) + (i32.const 36) + ) + ) + ) + (i32.store + (get_local $9) + (i32.load + (tee_local $6 + (i32.add + (get_local $5) + (i32.const 40) + ) + ) + ) + ) + (i32.store + (get_local $6) + (i32.const 0) + ) + (i64.store align=4 + (get_local $7) + (i64.const 0) + ) + (set_local $12 + (i32.add + (get_local $11) + (i32.mul + (get_local $4) + (i32.const 48) + ) + ) + ) + (block $label$2 + (br_if $label$2 + (i32.eqz + (get_local $10) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eq + (tee_local $8 + (i32.add + (get_local $10) + (i32.mul + (tee_local $9 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.const 48) + ) + ) + ) + (get_local $3) + ) + ) + (loop $label$4 + (i64.store + (get_local $12) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 24) + ) + ) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + (i32.store + (tee_local $11 + (i32.add + (get_local $12) + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $6 + (i32.add + (get_local $12) + (i32.const 36) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $9 + (i32.add + (get_local $12) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $11) + (i32.load + (tee_local $7 + (i32.add + (get_local $3) + (i32.const 32) + ) + ) + ) + ) + (i32.store + (get_local $6) + (i32.load + (i32.add + (get_local $3) + (i32.const 36) + ) + ) + ) + (i32.store + (get_local $9) + (i32.load + (tee_local $11 + (i32.add + (get_local $3) + (i32.const 40) + ) + ) + ) + ) + (i32.store + (get_local $11) + (i32.const 0) + ) + (i64.store align=4 + (get_local $7) + (i64.const 0) + ) + (set_local $12 + (i32.add + (get_local $12) + (i32.const 48) + ) + ) + (br_if $label$4 + (i32.ne + (tee_local $3 + (i32.add + (get_local $3) + (i32.const 48) + ) + ) + (get_local $8) + ) + ) + ) + (set_local $9 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (get_local $9) + ) + ) + (loop $label$6 + (set_local $9 + (i32.add + (get_local $9) + (i32.const -1) + ) + ) + (block $label$7 + (br_if $label$7 + (i32.eqz + (tee_local $3 + (i32.load + (tee_local $7 + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + ) + ) + ) + ) + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.eq + (tee_local $11 + (i32.load + (tee_local $8 + (i32.add + (get_local $10) + (i32.const 36) + ) + ) + ) + ) + (get_local $3) + ) + ) + (loop $label$10 + (set_local $6 + (i32.load + (tee_local $11 + (i32.add + (get_local $11) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $11) + (i32.const 0) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $6) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (i32.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $6) + ) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + (br_if $label$10 + (i32.ne + (get_local $3) + (get_local $11) + ) + ) + ) + (set_local $11 + (i32.load + (get_local $7) + ) + ) + (br $label$8) + ) + (set_local $11 + (get_local $3) + ) + ) + (i32.store + (get_local $8) + (get_local $3) + ) + (call $_ZdlPv + (get_local $11) + ) + ) + (set_local $10 + (i32.add + (get_local $10) + (i32.const 48) + ) + ) + (br_if $label$6 + (get_local $9) + ) + ) + ) + (call $_ZdlPv + (i32.load + (get_local $0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store offset=8 + (get_local $0) + (get_local $2) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.div_s + (i32.sub + (get_local $12) + (get_local $1) + ) + (i32.const 48) + ) + ) + ) + (func $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_expand_forwardINS2_17insert_move_proxyISA_PS8_EEEEvSE_jT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (local $14 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $2) + ) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $13 + (i32.sub + (tee_local $11 + (i32.add + (tee_local $4 + (i32.load + (get_local $0) + ) + ) + (i32.mul + (tee_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 48) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + (br_if $label$9 + (i32.ge_u + (i32.div_s + (get_local $13) + (i32.const 48) + ) + (get_local $2) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eq + (get_local $11) + (get_local $1) + ) + ) + (set_local $9 + (i32.sub + (i32.sub + (i32.const 0) + (get_local $4) + ) + (i32.mul + (get_local $6) + (i32.const 48) + ) + ) + ) + (set_local $10 + (i32.mul + (get_local $2) + (i32.const 48) + ) + ) + (set_local $13 + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (loop $label$12 + (i64.store + (i32.add + (tee_local $8 + (i32.add + (get_local $13) + (get_local $10) + ) + ) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $13) + (i32.const -40) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -28) + ) + (i32.load + (i32.add + (get_local $13) + (i32.const -28) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -32) + ) + (i32.load + (i32.add + (get_local $13) + (i32.const -32) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -16) + ) + (i64.load + (i32.add + (get_local $13) + (i32.const -16) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -24) + ) + (i64.load + (i32.add + (get_local $13) + (i32.const -24) + ) + ) + ) + (i32.store + (tee_local $7 + (i32.add + (get_local $8) + (i32.const -8) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $12 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $7) + (i32.load + (tee_local $14 + (i32.add + (get_local $13) + (i32.const -8) + ) + ) + ) + ) + (i32.store + (get_local $12) + (i32.load + (tee_local $7 + (i32.add + (get_local $13) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.load + (get_local $13) + ) + ) + (i32.store + (get_local $14) + (i32.const 0) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (i32.store + (get_local $13) + (i32.const 0) + ) + (br_if $label$12 + (i32.ne + (i32.add + (tee_local $13 + (i32.add + (get_local $13) + (i32.const 48) + ) + ) + (get_local $9) + ) + (i32.const 40) + ) + ) + ) + ) + (i64.store + (get_local $1) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (get_local $1) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 24) + ) + ) + ) + (i64.store + (i32.add + (get_local $1) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $1) + (i64.load offset=8 + (get_local $3) + ) + ) + (set_local $12 + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + (br_if $label$8 + (i32.eqz + (tee_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + ) + ) + (br_if $label$6 + (i32.eq + (tee_local $13 + (i32.load + (tee_local $9 + (i32.add + (get_local $1) + (i32.const 36) + ) + ) + ) + ) + (get_local $7) + ) + ) + (loop $label$13 + (set_local $8 + (i32.load + (tee_local $13 + (i32.add + (get_local $13) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $13) + (i32.const 0) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (get_local $8) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (i32.load + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $8) + ) + ) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$13 + (i32.ne + (get_local $7) + (get_local $13) + ) + ) + ) + (set_local $13 + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + (br $label$5) + ) + (i64.store + (get_local $11) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 24) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $11) + (i64.load offset=8 + (get_local $3) + ) + ) + (i32.store + (tee_local $13 + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $8 + (i32.add + (get_local $11) + (i32.const 36) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $7 + (i32.add + (get_local $11) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $13) + (i32.load + (tee_local $11 + (i32.add + (get_local $3) + (i32.const 32) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.load + (i32.add + (get_local $3) + (i32.const 36) + ) + ) + ) + (i32.store + (get_local $7) + (i32.load + (tee_local $13 + (i32.add + (get_local $3) + (i32.const 40) + ) + ) + ) + ) + (i32.store + (get_local $13) + (i32.const 0) + ) + (i64.store align=4 + (get_local $11) + (i64.const 0) + ) + (i32.store + (tee_local $13 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (get_local $13) + ) + (get_local $2) + ) + ) + (return) + ) + (set_local $6 + (i32.add + (i32.add + (get_local $4) + (tee_local $13 + (i32.mul + (i32.sub + (i32.const 0) + (get_local $2) + ) + (i32.const 48) + ) + ) + ) + (tee_local $8 + (i32.mul + (get_local $6) + (i32.const 48) + ) + ) + ) + ) + (set_local $5 + (i32.mul + (get_local $2) + (i32.const 48) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (get_local $8) + ) + ) + (set_local $12 + (i32.add + (get_local $11) + (get_local $13) + ) + ) + (set_local $7 + (i32.const 0) + ) + (loop $label$16 + (i64.store + (tee_local $13 + (i32.add + (get_local $4) + (get_local $7) + ) + ) + (i64.load + (tee_local $8 + (i32.add + (get_local $6) + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $13) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $8) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $13) + (i32.const 8) + ) + (i32.load + (i32.add + (get_local $8) + (i32.const 8) + ) + ) + ) + (i64.store + (i32.add + (get_local $13) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $8) + (i32.const 24) + ) + ) + ) + (i64.store + (i32.add + (get_local $13) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + (i32.store + (tee_local $14 + (i32.add + (get_local $13) + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $9 + (i32.add + (get_local $13) + (i32.const 36) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $13 + (i32.add + (get_local $13) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $14) + (i32.load + (tee_local $10 + (i32.add + (get_local $8) + (i32.const 32) + ) + ) + ) + ) + (i32.store + (get_local $9) + (i32.load + (tee_local $14 + (i32.add + (get_local $8) + (i32.const 36) + ) + ) + ) + ) + (i32.store + (get_local $13) + (i32.load + (tee_local $8 + (i32.add + (get_local $8) + (i32.const 40) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $10) + (i32.const 0) + ) + (i32.store + (get_local $14) + (i32.const 0) + ) + (br_if $label$16 + (i32.ne + (get_local $5) + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 48) + ) + ) + ) + ) + ) + (i32.store + (tee_local $13 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (get_local $13) + ) + (get_local $2) + ) + ) + (block $label$17 + (br_if $label$17 + (i32.eq + (get_local $12) + (get_local $1) + ) + ) + (loop $label$18 + (i64.store + (tee_local $5 + (i32.add + (get_local $11) + (i32.const -48) + ) + ) + (i64.load + (tee_local $10 + (i32.add + (get_local $12) + (i32.const -48) + ) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const -24) + ) + (i64.load + (i32.add + (get_local $12) + (i32.const -24) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const -32) + ) + (i64.load + (i32.add + (get_local $12) + (i32.const -32) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $12) + (i32.const -40) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $12) + (i32.const -16) + ) + ) + (block $label$19 + (block $label$20 + (block $label$21 + (block $label$22 + (br_if $label$22 + (i32.eqz + (tee_local $7 + (i32.load + (tee_local $9 + (i32.add + (get_local $11) + (i32.const -16) + ) + ) + ) + ) + ) + ) + (br_if $label$21 + (i32.eq + (tee_local $13 + (i32.load + (tee_local $14 + (i32.add + (get_local $11) + (i32.const -12) + ) + ) + ) + ) + (get_local $7) + ) + ) + (loop $label$23 + (set_local $8 + (i32.load + (tee_local $13 + (i32.add + (get_local $13) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $13) + (i32.const 0) + ) + (block $label$24 + (br_if $label$24 + (i32.eqz + (get_local $8) + ) + ) + (block $label$25 + (br_if $label$25 + (i32.eqz + (i32.load + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $8) + ) + ) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$23 + (i32.ne + (get_local $7) + (get_local $13) + ) + ) + ) + (set_local $13 + (i32.load + (get_local $9) + ) + ) + (br $label$20) + ) + (set_local $8 + (i32.add + (get_local $11) + (i32.const -8) + ) + ) + (set_local $14 + (i32.add + (get_local $11) + (i32.const -12) + ) + ) + (br $label$19) + ) + (set_local $13 + (get_local $7) + ) + ) + (i32.store + (get_local $14) + (get_local $7) + ) + (call $_ZdlPv + (get_local $13) + ) + (i32.store + (get_local $14) + (i32.const 0) + ) + (i32.store + (tee_local $8 + (i32.add + (get_local $11) + (i32.const -8) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $9) + (i32.const 0) + ) + ) + (i32.store + (get_local $9) + (i32.load + (get_local $6) + ) + ) + (i32.store + (get_local $14) + (i32.load + (tee_local $13 + (i32.add + (get_local $12) + (i32.const -12) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.load + (i32.add + (get_local $12) + (i32.const -8) + ) + ) + ) + (i32.store + (get_local $6) + (i32.const 0) + ) + (i64.store align=4 + (get_local $13) + (i64.const 0) + ) + (set_local $11 + (get_local $5) + ) + (set_local $12 + (get_local $10) + ) + (br_if $label$18 + (i32.ne + (get_local $10) + (get_local $1) + ) + ) + ) + ) + (i64.store + (get_local $1) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (get_local $1) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 24) + ) + ) + ) + (i64.store + (i32.add + (get_local $1) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $1) + (i64.load offset=8 + (get_local $3) + ) + ) + (br_if $label$7 + (i32.eqz + (tee_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + ) + ) + (br_if $label$3 + (i32.eq + (tee_local $13 + (i32.load + (tee_local $11 + (i32.add + (get_local $1) + (i32.const 36) + ) + ) + ) + ) + (get_local $7) + ) + ) + (loop $label$26 + (set_local $8 + (i32.load + (tee_local $13 + (i32.add + (get_local $13) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $13) + (i32.const 0) + ) + (block $label$27 + (br_if $label$27 + (i32.eqz + (get_local $8) + ) + ) + (block $label$28 + (br_if $label$28 + (i32.eqz + (i32.load + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=8 + (get_local $8) + ) + ) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$26 + (i32.ne + (get_local $7) + (get_local $13) + ) + ) + ) + (set_local $13 + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + (br $label$2) + ) + (set_local $13 + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (set_local $9 + (i32.add + (get_local $1) + (i32.const 36) + ) + ) + (br $label$4) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (set_local $11 + (i32.add + (get_local $1) + (i32.const 36) + ) + ) + (br $label$1) + ) + (set_local $13 + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 36) + ) + (get_local $7) + ) + (call $_ZdlPv + (get_local $13) + ) + (i32.store + (tee_local $13 + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $1) + (i32.const 32) + ) + (i64.const 0) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.load + (tee_local $8 + (i32.add + (get_local $3) + (i32.const 32) + ) + ) + ) + ) + (i32.store + (get_local $9) + (i32.load + (tee_local $14 + (i32.add + (get_local $3) + (i32.const 36) + ) + ) + ) + ) + (i32.store + (get_local $13) + (i32.load + (tee_local $7 + (i32.add + (get_local $3) + (i32.const 40) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (i64.store align=4 + (get_local $8) + (i64.const 0) + ) + (i64.store + (get_local $11) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (tee_local $13 + (i32.add + (get_local $4) + (i32.mul + (get_local $6) + (i32.const 48) + ) + ) + ) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $12) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $13) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $12) + (i32.const 8) + ) + ) + ) + (i64.store offset=8 + (get_local $13) + (i64.load + (get_local $12) + ) + ) + (i32.store + (tee_local $11 + (i32.add + (get_local $13) + (i32.const 32) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $12 + (i32.add + (get_local $13) + (i32.const 36) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $13 + (i32.add + (get_local $13) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $11) + (i32.load + (get_local $8) + ) + ) + (i32.store + (get_local $12) + (i32.load + (get_local $14) + ) + ) + (i32.store + (get_local $13) + (i32.load + (get_local $7) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (i64.store align=4 + (get_local $8) + (i64.const 0) + ) + (i32.store + (tee_local $13 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (i32.add + (i32.load + (get_local $13) + ) + (get_local $2) + ) + ) + (return) + ) + (set_local $13 + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 36) + ) + (get_local $7) + ) + (call $_ZdlPv + (get_local $13) + ) + (i32.store + (tee_local $7 + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $1) + (i32.const 32) + ) + (i64.const 0) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.load + (tee_local $13 + (i32.add + (get_local $3) + (i32.const 32) + ) + ) + ) + ) + (i32.store + (get_local $11) + (i32.load + (i32.add + (get_local $3) + (i32.const 36) + ) + ) + ) + (i32.store + (get_local $7) + (i32.load + (tee_local $8 + (i32.add + (get_local $3) + (i32.const 40) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i64.store align=4 + (get_local $13) + (i64.const 0) + ) + ) + ) + (func $_ZN5eosio12market_stateC2EyNS_11symbol_typeERNS_17exchange_accountsE (param $0 i32) (param $1 i64) (param $2 i64) (param $3 i32) (result i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (i64.store + (get_local $0) + (i64.shr_u + (get_local $2) + (i64.const 8) + ) + ) + (set_local $4 + (call $_ZN5eosio14exchange_stateC2Ev + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (i64.store offset=240 + (get_local $0) + (get_local $1) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 256) + ) + (i64.const -1) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 264) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 272) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 248) + ) + (tee_local $2 + (i64.load + (get_local $0) + ) + ) + ) + (i64.store offset=280 + (get_local $0) + (get_local $1) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 288) + ) + (tee_local $6 + (i64.or + (tee_local $5 + (i64.shl + (get_local $2) + (i64.const 4) + ) + ) + (i64.const 1) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 296) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 304) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 308) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 312) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $0) + (i32.const 316) + ) + (i32.const 0) + ) + (i64.store offset=320 + (get_local $0) + (get_local $1) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 328) + ) + (tee_local $5 + (i64.or + (get_local $5) + (i64.const 2) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 336) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 344) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 348) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 352) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $0) + (i32.const 356) + ) + (i32.const 0) + ) + (i64.store offset=360 + (get_local $0) + (get_local $1) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 368) + ) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 376) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 384) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 388) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 392) + ) + (i32.const 0) + ) + (i64.store offset=400 + (get_local $0) + (get_local $1) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 408) + ) + (get_local $5) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 416) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 424) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 428) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 432) + ) + (i32.const 0) + ) + (i32.store offset=440 + (get_local $0) + (get_local $3) + ) + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy + (i32.add + (get_local $0) + (i32.const 444) + ) + (i32.add + (get_local $0) + (i32.const 240) + ) + (get_local $2) + ) + (call $eosio_assert + (i32.ne + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 448) + ) + ) + ) + (i32.const 0) + ) + (i32.const 720) + ) + (drop + (call $memcpy + (get_local $4) + (i32.load + (get_local $3) + ) + (i32.const 232) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio14exchange_stateC2Ev (param $0 i32) (result i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store offset=40 + (get_local $0) + (i64.const 0) + ) + (i32.store offset=32 + (get_local $0) + (i32.const 0) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 48) + ) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$5 + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 64) + ) + (i32.const 500) + ) + (drop + (call $_ZN5eosio12margin_stateC2Ev + (i32.add + (get_local $0) + (i32.const 72) + ) + ) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 144) + ) + ) + (i64.const 1398362884) + ) + (i64.store offset=136 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$10 + (block $label$11 + (loop $label$12 + (br_if $label$11 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$13 + (br_if $label$13 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$14 + (br_if $label$11 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$14 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$12 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$10) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 160) + ) + (i32.const 500) + ) + (drop + (call $_ZN5eosio12margin_stateC2Ev + (i32.add + (get_local $0) + (i32.const 168) + ) + ) + ) + (get_local $0) + ) + (func $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy (param $0 i32) (param $1 i32) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + ) + (tee_local $3 + (i32.load offset=24 + (get_local $1) + ) + ) + ) + ) + (set_local $4 + (i32.sub + (i32.const 0) + (get_local $3) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i64.eq + (i64.shr_u + (i64.load + (i32.add + (i32.load + (get_local $6) + ) + (i32.const 16) + ) + ) + (i64.const 8) + ) + (get_local $2) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $5 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $5) + (get_local $4) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (br_if $label$2 + (i32.eq + (get_local $7) + (get_local $3) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=232 + (tee_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (get_local $1) + ) + (i32.const 224) + ) + (i32.store offset=4 + (get_local $0) + (get_local $6) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (return) + ) + (block $label$3 + (br_if $label$3 + (i32.le_s + (tee_local $6 + (call $db_find_i64 + (i64.load + (get_local $1) + ) + (i64.load offset=8 + (get_local $1) + ) + (i64.const -7949128877345865728) + (get_local $2) + ) + ) + (i32.const -1) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=232 + (tee_local $6 + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE31load_object_by_primary_iteratorEl + (get_local $1) + (get_local $6) + ) + ) + ) + (get_local $1) + ) + (i32.const 224) + ) + (i32.store offset=4 + (get_local $0) + (get_local $6) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (return) + ) + (i32.store offset=4 + (get_local $0) + (i32.const 0) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + ) + (func $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (set_local $8 + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $9) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $2 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $2) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i32.eq + (i32.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $4 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $4) + (get_local $3) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + (set_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i32.xor + (i32.shr_u + (tee_local $6 + (call $db_get_i64 + (get_local $1) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 31) + ) + (i32.const 1) + ) + (i32.const 656) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.lt_u + (get_local $6) + (i32.const 513) + ) + ) + (set_local $4 + (call $malloc + (get_local $6) + ) + ) + (br $label$4) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (get_local $9) + (i32.and + (i32.add + (get_local $6) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $db_get_i64 + (get_local $1) + (get_local $4) + (get_local $6) + ) + ) + (i32.store offset=36 + (get_local $8) + (get_local $4) + ) + (i32.store offset=32 + (get_local $8) + (get_local $4) + ) + (i32.store offset=40 + (get_local $8) + (i32.add + (get_local $4) + (get_local $6) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.lt_u + (get_local $6) + (i32.const 513) + ) + ) + (call $free + (get_local $4) + ) + ) + (set_local $4 + (call $_ZN5eosio14exchange_stateC2Ev + (tee_local $6 + (call $_Znwj + (i32.const 248) + ) + ) + ) + ) + (i32.store offset=232 + (get_local $6) + (get_local $0) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_stateE + (i32.add + (get_local $8) + (i32.const 32) + ) + (get_local $4) + ) + ) + (i32.store offset=236 + (get_local $6) + (get_local $1) + ) + (i32.store offset=24 + (get_local $8) + (get_local $6) + ) + (i64.store offset=16 + (get_local $8) + (tee_local $5 + (i64.shr_u + (i64.load offset=16 + (get_local $6) + ) + (i64.const 8) + ) + ) + ) + (i32.store offset=12 + (get_local $8) + (tee_local $7 + (i32.load offset=236 + (get_local $6) + ) + ) + ) + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ge_u + (tee_local $4 + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $4) + (get_local $5) + ) + (i32.store offset=16 + (get_local $4) + (get_local $7) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $4) + (get_local $6) + ) + (i32.store + (get_local $1) + (i32.add + (get_local $4) + (i32.const 24) + ) + ) + (br $label$7) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497615196363685888ENS1_14exchange_stateEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 12) + ) + ) + ) + (set_local $4 + (i32.load offset=24 + (get_local $8) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $4) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 48) + ) + ) + (get_local $6) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_stateE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 3) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_state9connectorE + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_state9connectorE + (get_local $0) + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (i32.add + (get_local $1) + (i32.const 136) + ) + ) + ) + (func $_ZNSt3__16vectorIN5eosio11multi_indexILy10497615196363685888ENS1_14exchange_stateEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.add + (tee_local $4 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 24) + ) + ) + (i32.const 1) + ) + ) + (i32.const 178956971) + ) + ) + (set_local $7 + (i32.const 178956970) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $6 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $6) + ) + (i32.const 24) + ) + ) + (i32.const 89478484) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $5) + (tee_local $7 + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $5) + ) + ) + ) + ) + ) + ) + (set_local $6 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $5 + (i32.load + (get_local $1) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $6) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + (get_local $5) + ) + (i64.store offset=8 + (get_local $1) + (i64.load + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $1) + (i32.load + (get_local $3) + ) + ) + (set_local $4 + (i32.add + (get_local $6) + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (loop $label$6 + (set_local $3 + (i32.load + (tee_local $2 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -24) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -8) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -12) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -16) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const -24) + ) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$6 + (i32.ne + (get_local $7) + (get_local $2) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $6 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $5) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $6) + ) + ) + (loop $label$8 + (set_local $1 + (i32.load + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $6) + (get_local $7) + ) + ) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_state9connectorE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 3) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 40) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 48) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 56) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 64) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 72) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 80) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 88) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio12margin_stateC2Ev (param $0 i32) (result i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (i64.store offset=8 + (get_local $0) + (i64.const 1398362884) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load offset=8 + (get_local $0) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + (i64.const 1398362884) + ) + (i64.store offset=24 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$5 + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store offset=56 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=48 + (get_local $0) + (i64.const 9218868437227405311) + ) + (get_local $0) + ) + (func $_ZN5eosio12market_state11margin_callENS_15extended_symbolE (param $0 i32) (param $1 i32) + (block $label$0 + (br_if $label$0 + (i64.ne + (i64.load + (get_local $1) + ) + (i64.load + (i32.add + (get_local $0) + (i32.const 56) + ) + ) + ) + ) + (br_if $label$0 + (i64.ne + (i64.load offset=8 + (get_local $1) + ) + (i64.load + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + ) + (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE + (get_local $0) + (i32.add + (get_local $0) + (i32.const 48) + ) + (i32.add + (get_local $0) + (i32.const 280) + ) + ) + (return) + ) + (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE + (get_local $0) + (i32.add + (get_local $0) + (i32.const 144) + ) + (i32.add + (get_local $0) + (i32.const 320) + ) + ) + ) + (func $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 f64) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 288) + ) + ) + ) + (i32.store offset=272 + (get_local $9) + (get_local $2) + ) + (i64.store offset=240 + (get_local $9) + (i64.const 0) + ) + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE11lower_boundERKy + (i32.add + (get_local $9) + (i32.const 264) + ) + (i32.add + (get_local $9) + (i32.const 272) + ) + (i32.add + (get_local $9) + (i32.const 240) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $2 + (i32.load offset=268 + (get_local $9) + ) + ) + ) + ) + (i64.store + (tee_local $3 + (i32.add + (i32.add + (get_local $9) + (i32.const 216) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 48) + ) + ) + ) + (i64.store + (tee_local $4 + (i32.add + (i32.add + (get_local $9) + (i32.const 216) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 40) + ) + ) + ) + (i64.store offset=216 + (get_local $9) + (i64.load offset=32 + (get_local $2) + ) + ) + (set_local $7 + (i64.load + (i32.add + (get_local $2) + (i32.const 24) + ) + ) + ) + (i64.store offset=200 + (get_local $9) + (i64.load + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + (i64.store offset=208 + (get_local $9) + (get_local $7) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 80) + ) + (i32.const 16) + ) + (i64.load + (get_local $3) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 80) + ) + (i32.const 8) + ) + (i64.load + (get_local $4) + ) + ) + (i64.store offset=80 + (get_local $9) + (i64.load offset=216 + (get_local $9) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 64) + ) + (i32.const 8) + ) + (i64.load offset=208 + (get_local $9) + ) + ) + (i64.store offset=64 + (get_local $9) + (i64.load offset=200 + (get_local $9) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $9) + (i32.const 240) + ) + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (i32.add + (get_local $9) + (i32.const 80) + ) + (i32.add + (get_local $9) + (i32.const 64) + ) + ) + (call $eosio_assert + (i64.ge_s + (tee_local $7 + (i64.load offset=240 + (get_local $9) + ) + ) + (i64.load offset=8 + (i32.load offset=268 + (get_local $9) + ) + ) + ) + (i32.const 736) + ) + (call $eosio_assert + (i64.eq + (tee_local $5 + (i64.load offset=256 + (get_local $9) + ) + ) + (i64.load + (i32.add + (tee_local $2 + (i32.load offset=268 + (get_local $9) + ) + ) + (i32.const 24) + ) + ) + ) + (i32.const 800) + ) + (call $eosio_assert + (i64.eq + (i64.load + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + (tee_local $6 + (i64.load offset=248 + (get_local $9) + ) + ) + ) + (i32.const 816) + ) + (call $eosio_assert + (i64.gt_s + (tee_local $7 + (i64.sub + (get_local $7) + (i64.load offset=8 + (get_local $2) + ) + ) + ) + (i64.const -4611686018427387904) + ) + (i32.const 864) + ) + (call $eosio_assert + (i64.lt_s + (get_local $7) + (i64.const 4611686018427387904) + ) + (i32.const 896) + ) + (i64.store offset=160 + (get_local $9) + (get_local $6) + ) + (i64.store offset=152 + (get_local $9) + (get_local $7) + ) + (i64.store offset=168 + (get_local $9) + (get_local $5) + ) + (i64.store offset=136 + (get_local $9) + (i64.load + (i32.add + (tee_local $2 + (i32.load offset=268 + (get_local $9) + ) + ) + (i32.const 40) + ) + ) + ) + (i64.store offset=144 + (get_local $9) + (i64.load + (i32.add + (get_local $2) + (i32.const 48) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $9) + (i32.const 40) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (i32.add + (get_local $9) + (i32.const 152) + ) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $9) + (i32.const 40) + ) + (i32.const 16) + ) + (i32.load offset=168 + (get_local $9) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 40) + ) + (i32.const 8) + ) + (i64.load offset=160 + (get_local $9) + ) + ) + (i64.store offset=40 + (get_local $9) + (i64.load offset=152 + (get_local $9) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 24) + ) + (i32.const 8) + ) + (i64.load offset=144 + (get_local $9) + ) + ) + (i64.store offset=24 + (get_local $9) + (i64.load offset=136 + (get_local $9) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $9) + (i32.const 176) + ) + (get_local $3) + (i32.add + (get_local $9) + (i32.const 40) + ) + (i32.add + (get_local $9) + (i32.const 24) + ) + ) + (set_local $7 + (i64.load + (i32.load offset=268 + (get_local $9) + ) + ) + ) + (i64.store + (tee_local $2 + (i32.add + (i32.add + (get_local $9) + (i32.const 112) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $9) + (i32.const 176) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (tee_local $3 + (i32.add + (i32.add + (get_local $9) + (i32.const 112) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $9) + (i32.const 176) + ) + (i32.const 8) + ) + ) + ) + (i32.store offset=112 + (get_local $9) + (i32.load offset=176 + (get_local $9) + ) + ) + (i32.store offset=116 + (get_local $9) + (i32.load offset=180 + (get_local $9) + ) + ) + (set_local $0 + (i32.load offset=440 + (get_local $0) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 16) + ) + (i64.load + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 8) + ) + (i64.load + (get_local $3) + ) + ) + (i64.store + (get_local $9) + (i64.load offset=112 + (get_local $9) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $0) + (get_local $7) + (get_local $9) + (get_local $9) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + (i64.sub + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (i32.load offset=268 + (get_local $9) + ) + ) + ) + ) + (i64.store offset=280 + (get_local $9) + (tee_local $7 + (i64.load offset=264 + (get_local $9) + ) + ) + ) + (call $eosio_assert + (i32.ne + (tee_local $2 + (i32.wrap/i64 + (i64.shr_u + (get_local $7) + (i64.const 32) + ) + ) + ) + (i32.const 0) + ) + (i32.const 928) + ) + (drop + (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE14const_iteratorppEv + (i32.add + (get_local $9) + (i32.const 280) + ) + ) + ) + (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ + (i32.load offset=272 + (get_local $9) + ) + (get_local $2) + ) + (i64.store offset=280 + (get_local $9) + (i64.const 0) + ) + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE11lower_boundERKy + (i32.add + (get_local $9) + (i32.const 104) + ) + (i32.add + (get_local $9) + (i32.const 272) + ) + (i32.add + (get_local $9) + (i32.const 280) + ) + ) + (i64.store offset=264 + (get_local $9) + (tee_local $7 + (i64.load offset=104 + (get_local $9) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.eqz + (tee_local $2 + (i32.wrap/i64 + (i64.shr_u + (get_local $7) + (i64.const 32) + ) + ) + ) + ) + ) + (set_local $8 + (f64.load offset=56 + (get_local $2) + ) + ) + (br $label$1) + ) + (set_local $8 + (f64.const 18446744073709551615) + ) + ) + (f64.store + (i32.add + (get_local $1) + (i32.const 80) + ) + (get_local $8) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 288) + ) + ) + ) + (func $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE11lower_boundERKy (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $10) + (i64.const 0) + ) + (i64.store + (get_local $10) + (i64.load + (get_local $2) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.lt_s + (tee_local $3 + (call $db_idx64_lowerbound + (i64.load + (tee_local $8 + (i32.load + (get_local $1) + ) + ) + ) + (i64.load offset=8 + (get_local $8) + ) + (i64.const -7949197150146002944) + (get_local $10) + (i32.add + (get_local $10) + (i32.const 8) + ) + ) + ) + (i32.const 0) + ) + ) + (set_local $5 + (i64.load offset=8 + (get_local $10) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $9 + (i32.load + (i32.add + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + (i32.const 28) + ) + ) + ) + (tee_local $6 + (i32.load offset=24 + (get_local $4) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $9) + (i32.const -24) + ) + ) + (set_local $7 + (i32.sub + (i32.const 0) + (get_local $6) + ) + ) + (loop $label$2 + (br_if $label$1 + (i64.eq + (i64.load + (i32.load + (get_local $2) + ) + ) + (get_local $5) + ) + ) + (set_local $9 + (get_local $2) + ) + (set_local $2 + (tee_local $8 + (i32.add + (get_local $2) + (i32.const -24) + ) + ) + ) + (br_if $label$2 + (i32.ne + (i32.add + (get_local $8) + (get_local $7) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.eq + (get_local $9) + (get_local $6) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $2 + (i32.load + (i32.add + (get_local $9) + (i32.const -24) + ) + ) + ) + ) + (get_local $4) + ) + (i32.const 224) + ) + (br $label$3) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $2 + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $4) + (call $db_find_i64 + (i64.load + (get_local $4) + ) + (i64.load offset=8 + (get_local $4) + ) + (i64.const -7949197150146002944) + (get_local $5) + ) + ) + ) + ) + (get_local $4) + ) + (i32.const 224) + ) + ) + (i32.store + (i32.add + (get_local $2) + (i32.const 72) + ) + (get_local $3) + ) + ) + (i32.store offset=4 + (get_local $0) + (get_local $2) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE14const_iteratorppEv (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=4 + (get_local $0) + ) + (i32.const 0) + ) + (i32.const 1152) + ) + (block $label$0 + (br_if $label$0 + (i32.ne + (tee_local $7 + (i32.load offset=72 + (tee_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + ) + (i32.const -1) + ) + ) + (set_local $7 + (call $db_idx64_find_primary + (i64.load + (tee_local $7 + (i32.load + (i32.load + (get_local $0) + ) + ) + ) + ) + (i64.load offset=8 + (get_local $7) + ) + (i64.const -7949197150146002944) + (i32.add + (get_local $9) + (i32.const 8) + ) + (i64.load + (get_local $6) + ) + ) + ) + (i32.store offset=72 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (get_local $7) + ) + ) + (i64.store offset=8 + (get_local $9) + (i64.const 0) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.le_s + (tee_local $1 + (call $db_idx64_next + (get_local $7) + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + ) + (i32.const -1) + ) + ) + (set_local $3 + (i64.load offset=8 + (get_local $9) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $8 + (i32.load + (i32.add + (tee_local $2 + (i32.load + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 28) + ) + ) + ) + (tee_local $4 + (i32.load offset=24 + (get_local $2) + ) + ) + ) + ) + (set_local $7 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + (set_local $5 + (i32.sub + (i32.const 0) + (get_local $4) + ) + ) + (loop $label$6 + (br_if $label$5 + (i64.eq + (i64.load + (i32.load + (get_local $7) + ) + ) + (get_local $3) + ) + ) + (set_local $8 + (get_local $7) + ) + (set_local $7 + (tee_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + (br_if $label$6 + (i32.ne + (i32.add + (get_local $6) + (get_local $5) + ) + (i32.const -24) + ) + ) + ) + ) + (br_if $label$3 + (i32.eq + (get_local $8) + (get_local $4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $7 + (i32.load + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + (br $label$2) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.const 0) + ) + (br $label$1) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $7 + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $2) + (call $db_find_i64 + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (get_local $3) + ) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $7) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 72) + ) + (get_local $1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ (param $0 i32) (param $1 i32) + (local $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (get_local $1) + ) + (get_local $0) + ) + (i32.const 976) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $0) + ) + (call $current_receiver) + ) + (i32.const 1024) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (tee_local $3 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $2 + (i64.load + (get_local $1) + ) + ) + (set_local $6 + (i32.sub + (i32.const 0) + (get_local $3) + ) + ) + (set_local $8 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i64.eq + (i64.load + (i32.load + (get_local $8) + ) + ) + (get_local $2) + ) + ) + (set_local $7 + (get_local $8) + ) + (set_local $8 + (tee_local $4 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $4) + (get_local $6) + ) + (i32.const -24) + ) + ) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $7) + (get_local $3) + ) + (i32.const 1088) + ) + (set_local $8 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (tee_local $4 + (i32.load + (get_local $5) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $4) + ) + ) + (set_local $7 + (get_local $8) + ) + (loop $label$4 + (set_local $6 + (i32.load + (tee_local $8 + (i32.add + (get_local $7) + (i32.const 24) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (set_local $4 + (i32.load + (get_local $7) + ) + ) + (i32.store + (get_local $7) + (get_local $6) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (get_local $4) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + ) + (i64.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + ) + (set_local $7 + (get_local $8) + ) + (br_if $label$4 + (i32.ne + (i32.add + (get_local $8) + (get_local $3) + ) + (i32.const -24) + ) + ) + ) + (br_if $label$2 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (get_local $8) + ) + ) + ) + (loop $label$6 + (set_local $4 + (i32.load + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (block $label$7 + (br_if $label$7 + (i32.eqz + (get_local $4) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (br_if $label$6 + (i32.ne + (get_local $8) + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 28) + ) + (get_local $8) + ) + (call $db_remove_i64 + (i32.load offset=68 + (get_local $1) + ) + ) + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.gt_s + (tee_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 72) + ) + ) + ) + (i32.const -1) + ) + ) + (br_if $label$8 + (i32.lt_s + (tee_local $7 + (call $db_idx64_find_primary + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + (i64.const -7949197150146002944) + (i32.add + (get_local $9) + (i32.const 8) + ) + (i64.load + (get_local $1) + ) + ) + ) + (i32.const 0) + ) + ) + ) + (call $db_idx64_remove + (get_local $7) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + ) + (func $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store offset=44 + (tee_local $8 + (get_local $9) + ) + (get_local $1) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $2 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $2) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i32.eq + (i32.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $4 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $4) + (get_local $3) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + (set_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i32.xor + (i32.shr_u + (tee_local $6 + (call $db_get_i64 + (get_local $1) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 31) + ) + (i32.const 1) + ) + (i32.const 656) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.lt_u + (get_local $6) + (i32.const 513) + ) + ) + (set_local $4 + (call $malloc + (get_local $6) + ) + ) + (br $label$4) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (get_local $9) + (i32.and + (i32.add + (get_local $6) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $db_get_i64 + (get_local $1) + (get_local $4) + (get_local $6) + ) + ) + (i32.store offset=36 + (get_local $8) + (get_local $4) + ) + (i32.store offset=32 + (get_local $8) + (get_local $4) + ) + (i32.store offset=40 + (get_local $8) + (i32.add + (get_local $4) + (get_local $6) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.lt_u + (get_local $6) + (i32.const 513) + ) + ) + (call $free + (get_local $4) + ) + ) + (i32.store offset=8 + (get_local $8) + (get_local $0) + ) + (i32.store offset=12 + (get_local $8) + (i32.add + (get_local $8) + (i32.const 32) + ) + ) + (i32.store offset=16 + (get_local $8) + (i32.add + (get_local $8) + (i32.const 44) + ) + ) + (drop + (call $_ZN5eosio15margin_positionC2Ev + (tee_local $6 + (call $_Znwj + (i32.const 80) + ) + ) + ) + ) + (i32.store offset=64 + (get_local $6) + (get_local $0) + ) + (call $_ZZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorElENKUlRT_E_clINS8_4itemEEEDaSA_ + (i32.add + (get_local $8) + (i32.const 8) + ) + (get_local $6) + ) + (i32.store offset=24 + (get_local $8) + (get_local $6) + ) + (i64.store offset=8 + (get_local $8) + (tee_local $5 + (i64.load + (get_local $6) + ) + ) + ) + (i32.store offset=4 + (get_local $8) + (tee_local $7 + (i32.load offset=68 + (get_local $6) + ) + ) + ) + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ge_u + (tee_local $4 + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $4) + (get_local $5) + ) + (i32.store offset=16 + (get_local $4) + (get_local $7) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $4) + (get_local $6) + ) + (i32.store + (get_local $1) + (i32.add + (get_local $4) + (i32.const 24) + ) + ) + (br $label$7) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497546923563548672ENS1_15margin_positionEJNS1_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS3_yXadL_ZNKS3_8get_callEvEEEEEEEE8item_ptrENS_9allocatorISB_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINSA_4itemENS_14default_deleteISH_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.add + (get_local $8) + (i32.const 4) + ) + ) + ) + (set_local $4 + (i32.load offset=24 + (get_local $8) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $4) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 48) + ) + ) + (get_local $6) + ) + (func $_ZN5eosio15margin_positionC2Ev (param $0 i32) (result i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 40) + ) + ) + (i64.const 1398362884) + ) + (i64.store offset=32 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$5 + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store offset=56 + (get_local $0) + (i64.const 0) + ) + (get_local $0) + ) + (func $_ZZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorElENKUlRT_E_clINS8_4itemEEEDaSA_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $3 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $3 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $3 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $3 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $3 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 40) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $3 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 48) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $3 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 56) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $2 + (i32.load + (i32.load offset=8 + (get_local $0) + ) + ) + ) + (i32.store offset=72 + (get_local $1) + (i32.const -1) + ) + (i32.store offset=68 + (get_local $1) + (get_local $2) + ) + ) + (func $_ZNSt3__16vectorIN5eosio11multi_indexILy10497546923563548672ENS1_15margin_positionEJNS1_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS3_yXadL_ZNKS3_8get_callEvEEEEEEEE8item_ptrENS_9allocatorISB_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINSA_4itemENS_14default_deleteISH_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.add + (tee_local $4 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 24) + ) + ) + (i32.const 1) + ) + ) + (i32.const 178956971) + ) + ) + (set_local $7 + (i32.const 178956970) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $6 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $6) + ) + (i32.const 24) + ) + ) + (i32.const 89478484) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $5) + (tee_local $7 + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $5) + ) + ) + ) + ) + ) + ) + (set_local $6 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $5 + (i32.load + (get_local $1) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $6) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + (get_local $5) + ) + (i64.store offset=8 + (get_local $1) + (i64.load + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $1) + (i32.load + (get_local $3) + ) + ) + (set_local $4 + (i32.add + (get_local $6) + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (loop $label$6 + (set_local $3 + (i32.load + (tee_local $2 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -24) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -8) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -12) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -16) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const -24) + ) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$6 + (i32.ne + (get_local $7) + (get_local $2) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $6 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $5) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $6) + ) + ) + (loop $label$8 + (set_local $1 + (i32.load + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $6) + (get_local $7) + ) + ) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $_ZNK5eosio12market_state13initial_stateEv (param $0 i32) (result i32) + (i32.load + (i32.add + (get_local $0) + (i32.const 448) + ) + ) + ) + (func $_ZN5eosio12market_state4lendEyRKNS_14extended_assetE (param $0 i32) (param $1 i64) (param $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i32) + (local $6 i64) + (local $7 f64) + (local $8 f64) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i64.store offset=32 + (get_local $9) + (tee_local $3 + (i64.load offset=8 + (get_local $2) + ) + ) + ) + (set_local $5 + (i32.load offset=440 + (get_local $0) + ) + ) + (set_local $4 + (i64.load offset=16 + (get_local $2) + ) + ) + (set_local $6 + (i64.load + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 8) + ) + (get_local $3) + ) + (i64.store offset=24 + (get_local $9) + (tee_local $6 + (i64.sub + (i64.const 0) + (get_local $6) + ) + ) + ) + (i64.store offset=40 + (get_local $9) + (get_local $4) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 16) + ) + (get_local $4) + ) + (i64.store + (get_local $9) + (get_local $6) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $5) + (get_local $1) + (get_local $9) + (get_local $9) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.ne + (get_local $3) + (i64.load + (i32.add + (get_local $0) + (i32.const 56) + ) + ) + ) + ) + (br_if $label$5 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + ) + (set_local $4 + (i64.load + (get_local $2) + ) + ) + (br_if $label$4 + (i64.lt_s + (tee_local $3 + (i64.load + (i32.add + (get_local $0) + (i32.const 80) + ) + ) + ) + (i64.const 1) + ) + ) + (set_local $8 + (f64.add + (tee_local $8 + (f64.load + (i32.add + (get_local $0) + (i32.const 136) + ) + ) + ) + (f64.div + (f64.mul + (get_local $8) + (tee_local $7 + (f64.convert_s/i64 + (get_local $4) + ) + ) + ) + (f64.convert_s/i64 + (get_local $3) + ) + ) + ) + ) + (br $label$3) + ) + (block $label$6 + (br_if $label$6 + (i64.ne + (get_local $3) + (i64.load + (i32.add + (get_local $0) + (i32.const 152) + ) + ) + ) + ) + (br_if $label$6 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $0) + (i32.const 160) + ) + ) + ) + ) + (set_local $4 + (i64.load + (get_local $2) + ) + ) + (br_if $label$2 + (i64.lt_s + (tee_local $3 + (i64.load + (i32.add + (get_local $0) + (i32.const 176) + ) + ) + ) + (i64.const 1) + ) + ) + (set_local $8 + (f64.add + (tee_local $8 + (f64.load + (i32.add + (get_local $0) + (i32.const 232) + ) + ) + ) + (f64.div + (f64.mul + (get_local $8) + (tee_local $7 + (f64.convert_s/i64 + (get_local $4) + ) + ) + ) + (f64.convert_s/i64 + (get_local $3) + ) + ) + ) + ) + (br $label$1) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1184) + ) + (br $label$0) + ) + (set_local $8 + (f64.add + (tee_local $7 + (f64.convert_s/i64 + (get_local $4) + ) + ) + (f64.load + (i32.add + (get_local $0) + (i32.const 136) + ) + ) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 80) + ) + (i64.add + (get_local $3) + (get_local $4) + ) + ) + (f64.store + (i32.add + (get_local $0) + (i32.const 136) + ) + (get_local $8) + ) + (call $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd + (get_local $9) + (get_local $1) + (i32.add + (get_local $0) + (i32.const 360) + ) + (get_local $7) + ) + (br $label$0) + ) + (set_local $8 + (f64.add + (tee_local $7 + (f64.convert_s/i64 + (get_local $4) + ) + ) + (f64.load + (i32.add + (get_local $0) + (i32.const 232) + ) + ) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 176) + ) + (i64.add + (get_local $3) + (get_local $4) + ) + ) + (f64.store + (i32.add + (get_local $0) + (i32.const 232) + ) + (get_local $8) + ) + (call $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd + (get_local $9) + (get_local $1) + (i32.add + (get_local $0) + (i32.const 400) + ) + (get_local $7) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + ) + (func $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd (param $0 i32) (param $1 i64) (param $2 i32) (param $3 f64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $9 + (i32.load + (i32.add + (get_local $2) + (i32.const 28) + ) + ) + ) + (tee_local $4 + (i32.load offset=24 + (get_local $2) + ) + ) + ) + ) + (set_local $8 + (i32.add + (get_local $9) + (i32.const -24) + ) + ) + (set_local $5 + (i32.sub + (i32.const 0) + (get_local $4) + ) + ) + (loop $label$1 + (br_if $label$0 + (i64.eq + (i64.load + (i32.load + (get_local $8) + ) + ) + (get_local $1) + ) + ) + (set_local $9 + (get_local $8) + ) + (set_local $8 + (tee_local $6 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $6) + (get_local $5) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (get_local $9) + (get_local $4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=16 + (tee_local $8 + (i32.load + (i32.add + (get_local $9) + (i32.const -24) + ) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + (br_if $label$4 + (get_local $8) + ) + (br $label$3) + ) + (br_if $label$3 + (i32.lt_s + (tee_local $8 + (call $db_find_i64 + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -8282898168966807552) + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=16 + (tee_local $8 + (call $_ZNK5eosio11multi_indexILy10163845904742744064ENS_13loan_positionEJEE31load_object_by_primary_iteratorEl + (get_local $2) + (get_local $8) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 352) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=16 + (get_local $8) + ) + (get_local $2) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $2) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (f64.store offset=8 + (get_local $8) + (tee_local $3 + (f64.add + (f64.load offset=8 + (get_local $8) + ) + (get_local $3) + ) + ) + ) + (set_local $1 + (i64.load + (get_local $8) + ) + ) + (call $eosio_assert + (f64.ge + (get_local $3) + (f64.const 0) + ) + (i32.const 1216) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (i64.load + (get_local $8) + ) + ) + (i32.const 544) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $10) + (i32.const 16) + ) + (get_local $8) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.or + (i32.add + (get_local $10) + (i32.const 16) + ) + (i32.const 8) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $db_update_i64 + (i32.load offset=20 + (get_local $8) + ) + (i64.const 0) + (i32.add + (get_local $10) + (i32.const 16) + ) + (i32.const 16) + ) + (br_if $label$2 + (i64.lt_u + (get_local $1) + (i64.load offset=16 + (get_local $2) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (select + (i64.const -2) + (i64.add + (get_local $1) + (i64.const 1) + ) + (i64.gt_u + (get_local $1) + (i64.const -3) + ) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $2) + ) + (call $current_receiver) + ) + (i32.const 288) + ) + (i32.store offset=16 + (tee_local $8 + (call $_Znwj + (i32.const 32) + ) + ) + (get_local $2) + ) + (f64.store offset=8 + (get_local $8) + (get_local $3) + ) + (i64.store + (get_local $8) + (get_local $1) + ) + (call $eosio_assert + (f64.ge + (get_local $3) + (f64.const 0) + ) + (i32.const 1216) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $10) + (i32.const 16) + ) + (get_local $8) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.or + (i32.add + (get_local $10) + (i32.const 16) + ) + (i32.const 8) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=20 + (get_local $8) + (tee_local $9 + (call $db_store_i64 + (i64.load offset=8 + (get_local $2) + ) + (i64.const -8282898168966807552) + (get_local $1) + (tee_local $7 + (i64.load + (get_local $8) + ) + ) + (i32.add + (get_local $10) + (i32.const 16) + ) + (i32.const 16) + ) + ) + ) + (block $label$6 + (br_if $label$6 + (i64.lt_u + (get_local $7) + (i64.load offset=16 + (get_local $2) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (select + (i64.const -2) + (i64.add + (get_local $7) + (i64.const 1) + ) + (i64.gt_u + (get_local $7) + (i64.const -3) + ) + ) + ) + ) + (i32.store offset=8 + (get_local $10) + (get_local $8) + ) + (i64.store offset=16 + (get_local $10) + (tee_local $1 + (i64.load + (get_local $8) + ) + ) + ) + (i32.store offset=4 + (get_local $10) + (get_local $9) + ) + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ge_u + (tee_local $6 + (i32.load + (tee_local $5 + (i32.add + (get_local $2) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $6) + (get_local $1) + ) + (i32.store offset=16 + (get_local $6) + (get_local $9) + ) + (i32.store offset=8 + (get_local $10) + (i32.const 0) + ) + (i32.store + (get_local $6) + (get_local $8) + ) + (i32.store + (get_local $5) + (i32.add + (get_local $6) + (i32.const 24) + ) + ) + (br $label$7) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10163845904742744064ENS1_13loan_positionEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $2) + (i32.const 24) + ) + (i32.add + (get_local $10) + (i32.const 8) + ) + (i32.add + (get_local $10) + (i32.const 16) + ) + (i32.add + (get_local $10) + (i32.const 4) + ) + ) + ) + (set_local $8 + (i32.load offset=8 + (get_local $10) + ) + ) + (i32.store offset=8 + (get_local $10) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $8) + ) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + ) + (func $_ZNK5eosio11multi_indexILy10163845904742744064ENS_13loan_positionEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (set_local $8 + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $9) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $2 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $2) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i32.eq + (i32.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $4 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $4) + (get_local $3) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + (set_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i32.xor + (i32.shr_u + (tee_local $4 + (call $db_get_i64 + (get_local $1) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 31) + ) + (i32.const 1) + ) + (i32.const 656) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.le_u + (get_local $4) + (i32.const 512) + ) + ) + (drop + (call $db_get_i64 + (get_local $1) + (tee_local $7 + (call $malloc + (get_local $4) + ) + ) + (get_local $4) + ) + ) + (call $free + (get_local $7) + ) + (br $label$4) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (get_local $9) + (i32.and + (i32.add + (get_local $4) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + (drop + (call $db_get_i64 + (get_local $1) + (get_local $7) + (get_local $4) + ) + ) + ) + (i32.store offset=16 + (tee_local $6 + (call $_Znwj + (i32.const 32) + ) + ) + (get_local $0) + ) + (call $eosio_assert + (i32.gt_u + (get_local $4) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $6) + (get_local $7) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (i32.and + (get_local $4) + (i32.const -8) + ) + (i32.const 8) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $6) + (i32.const 8) + ) + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=20 + (get_local $6) + (get_local $1) + ) + (i32.store offset=24 + (get_local $8) + (get_local $6) + ) + (i64.store offset=16 + (get_local $8) + (tee_local $5 + (i64.load + (get_local $6) + ) + ) + ) + (i32.store offset=12 + (get_local $8) + (tee_local $7 + (i32.load offset=20 + (get_local $6) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.ge_u + (tee_local $4 + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $4) + (get_local $5) + ) + (i32.store offset=16 + (get_local $4) + (get_local $7) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $4) + (get_local $6) + ) + (i32.store + (get_local $1) + (i32.add + (get_local $4) + (i32.const 24) + ) + ) + (br $label$6) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10163845904742744064ENS1_13loan_positionEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 12) + ) + ) + ) + (set_local $4 + (i32.load offset=24 + (get_local $8) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $4) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 32) + ) + ) + (get_local $6) + ) + (func $_ZNSt3__16vectorIN5eosio11multi_indexILy10163845904742744064ENS1_13loan_positionEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.add + (tee_local $4 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 24) + ) + ) + (i32.const 1) + ) + ) + (i32.const 178956971) + ) + ) + (set_local $7 + (i32.const 178956970) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $6 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $6) + ) + (i32.const 24) + ) + ) + (i32.const 89478484) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $5) + (tee_local $7 + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $5) + ) + ) + ) + ) + ) + ) + (set_local $6 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $5 + (i32.load + (get_local $1) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $6) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + (get_local $5) + ) + (i64.store offset=8 + (get_local $1) + (i64.load + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $1) + (i32.load + (get_local $3) + ) + ) + (set_local $4 + (i32.add + (get_local $6) + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (loop $label$6 + (set_local $3 + (i32.load + (tee_local $2 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -24) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -8) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -12) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -16) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const -24) + ) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$6 + (i32.ne + (get_local $7) + (get_local $2) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $6 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $5) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $6) + ) + ) + (loop $label$8 + (set_local $1 + (i32.load + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $6) + (get_local $7) + ) + ) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE (param $0 i32) (param $1 i64) (param $2 f64) (param $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i32) + (local $7 f64) + (local $8 f64) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (call $eosio_assert + (f64.gt + (get_local $2) + (f64.const 0) + ) + (i32.const 1232) + ) + (call $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd + (get_local $9) + (get_local $1) + (i32.add + (get_local $0) + (i32.const 360) + ) + (f64.neg + (get_local $2) + ) + ) + (call $prints + (i32.const 1264) + ) + (call $_ZNK5eosio11symbol_type5printEb + (get_local $3) + (i32.const 1) + ) + (call $prints + (i32.const 1280) + ) + (call $printn + (i64.load offset=8 + (get_local $3) + ) + ) + (set_local $5 + (i64.load offset=8 + (get_local $3) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i64.ne + (tee_local $4 + (i64.load + (get_local $3) + ) + ) + (i64.load + (i32.add + (get_local $0) + (i32.const 56) + ) + ) + ) + ) + (br_if $label$1 + (i64.ne + (get_local $5) + (i64.load + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + ) + (i64.store + (tee_local $6 + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $0) + (i32.const 120) + ) + ) + ) + (i64.store offset=96 + (get_local $9) + (i64.load + (i32.add + (get_local $0) + (i32.const 112) + ) + ) + ) + (call $prints + (i32.const 1296) + ) + (call $printdf + (get_local $2) + ) + (call $prints + (i32.const 1312) + ) + (call $printdf + (f64.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 136) + ) + ) + ) + ) + (call $prints + (i32.const 1344) + ) + (f64.store + (get_local $3) + (tee_local $8 + (f64.sub + (tee_local $7 + (f64.load + (get_local $3) + ) + ) + (get_local $2) + ) + ) + ) + (i64.store + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 80) + ) + ) + (i64.sub + (tee_local $5 + (i64.load + (get_local $3) + ) + ) + (tee_local $5 + (i64.trunc_s/f64 + (f64.div + (f64.mul + (f64.convert_s/i64 + (get_local $5) + ) + (get_local $2) + ) + (get_local $7) + ) + ) + ) + ) + ) + (call $eosio_assert + (f64.ge + (get_local $8) + (f64.const 0) + ) + (i32.const 1216) + ) + (call $eosio_assert + (i32.xor + (i32.wrap/i64 + (i64.shr_u + (i64.load + (get_local $3) + ) + (i64.const 63) + ) + ) + (i32.const 1) + ) + (i32.const 1216) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 92) + ) + (i32.load + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (tee_local $3 + (i32.add + (i32.add + (get_local $9) + (i32.const 72) + ) + (i32.const 16) + ) + ) + (i32.load + (get_local $6) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $9) + (i32.const 72) + ) + (i32.const 12) + ) + (i32.load offset=100 + (get_local $9) + ) + ) + (i64.store offset=72 + (get_local $9) + (get_local $5) + ) + (i32.store offset=80 + (get_local $9) + (i32.load offset=96 + (get_local $9) + ) + ) + (set_local $0 + (i32.load offset=440 + (get_local $0) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 8) + ) + (i64.load offset=80 + (get_local $9) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 16) + ) + (i64.load + (get_local $3) + ) + ) + (i64.store + (get_local $9) + (i64.load offset=72 + (get_local $9) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $0) + (get_local $1) + (get_local $9) + (get_local $9) + ) + (br $label$0) + ) + (block $label$2 + (br_if $label$2 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $0) + (i32.const 152) + ) + ) + ) + ) + (br_if $label$2 + (i64.ne + (get_local $5) + (i64.load + (i32.add + (get_local $0) + (i32.const 160) + ) + ) + ) + ) + (i64.store + (tee_local $6 + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $0) + (i32.const 216) + ) + ) + ) + (i64.store offset=96 + (get_local $9) + (i64.load + (i32.add + (get_local $0) + (i32.const 208) + ) + ) + ) + (call $prints + (i32.const 1296) + ) + (call $printdf + (get_local $2) + ) + (call $prints + (i32.const 1312) + ) + (call $printdf + (f64.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 232) + ) + ) + ) + ) + (call $prints + (i32.const 1344) + ) + (f64.store + (get_local $3) + (tee_local $8 + (f64.sub + (tee_local $7 + (f64.load + (get_local $3) + ) + ) + (get_local $2) + ) + ) + ) + (i64.store + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 176) + ) + ) + (i64.sub + (tee_local $5 + (i64.load + (get_local $3) + ) + ) + (tee_local $5 + (i64.trunc_s/f64 + (f64.div + (f64.mul + (f64.convert_s/i64 + (get_local $5) + ) + (get_local $2) + ) + (get_local $7) + ) + ) + ) + ) + ) + (call $eosio_assert + (f64.ge + (get_local $8) + (f64.const 0) + ) + (i32.const 1216) + ) + (call $eosio_assert + (i32.xor + (i32.wrap/i64 + (i64.shr_u + (i64.load + (get_local $3) + ) + (i64.const 63) + ) + ) + (i32.const 1) + ) + (i32.const 1216) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 68) + ) + (i32.load + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (tee_local $3 + (i32.add + (i32.add + (get_local $9) + (i32.const 48) + ) + (i32.const 16) + ) + ) + (i32.load + (get_local $6) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $9) + (i32.const 48) + ) + (i32.const 12) + ) + (i32.load offset=100 + (get_local $9) + ) + ) + (i64.store offset=48 + (get_local $9) + (get_local $5) + ) + (i32.store offset=56 + (get_local $9) + (i32.load offset=96 + (get_local $9) + ) + ) + (set_local $0 + (i32.load offset=440 + (get_local $0) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 24) + ) + (i32.const 8) + ) + (i64.load offset=56 + (get_local $9) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 24) + ) + (i32.const 16) + ) + (i64.load + (get_local $3) + ) + ) + (i64.store offset=24 + (get_local $9) + (i64.load offset=48 + (get_local $9) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $0) + (get_local $1) + (i32.add + (get_local $9) + (i32.const 24) + ) + (get_local $9) + ) + (br $label$0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1184) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 112) + ) + ) + ) + (func $_ZNK5eosio11symbol_type5printEb (param $0 i32) (param $1 i32) + (local $2 i64) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (call $printui + (i64.load8_u + (get_local $0) + ) + ) + (call $prints + (i32.const 1360) + ) + ) + (i32.store8 offset=15 + (get_local $3) + (tee_local $0 + (i32.wrap/i64 + (i64.shr_u + (tee_local $2 + (i64.load + (get_local $0) + ) + ) + (i64.const 8) + ) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 255) + ) + ) + ) + (call $prints_l + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + (i32.store8 offset=15 + (get_local $3) + (tee_local $0 + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 16) + ) + ) + ) + ) + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 255) + ) + ) + ) + (call $prints_l + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + (i32.store8 offset=15 + (get_local $3) + (tee_local $0 + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 24) + ) + ) + ) + ) + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 255) + ) + ) + ) + (call $prints_l + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + (i32.store8 offset=15 + (get_local $3) + (tee_local $0 + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 32) + ) + ) + ) + ) + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 255) + ) + ) + ) + (call $prints_l + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + (i32.store8 offset=15 + (get_local $3) + (tee_local $0 + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 40) + ) + ) + ) + ) + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 255) + ) + ) + ) + (call $prints_l + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + (i32.store8 offset=15 + (get_local $3) + (tee_local $0 + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 48) + ) + ) + ) + ) + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 255) + ) + ) + ) + (call $prints_l + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + (i32.store8 offset=15 + (get_local $3) + (tee_local $0 + (i32.wrap/i64 + (i64.shr_u + (get_local $2) + (i64.const 56) + ) + ) + ) + ) + (br_if $label$1 + (i32.eqz + (get_local $0) + ) + ) + (call $prints_l + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosio12market_state12cover_marginEyRKNS_14extended_assetE (param $0 i32) (param $1 i64) (param $2 i32) + (local $3 i64) + (local $4 i64) + (set_local $4 + (i64.load offset=16 + (get_local $2) + ) + ) + (block $label$0 + (br_if $label$0 + (i64.ne + (tee_local $3 + (i64.load offset=8 + (get_local $2) + ) + ) + (i64.load + (i32.add + (get_local $0) + (i32.const 56) + ) + ) + ) + ) + (br_if $label$0 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + ) + (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE + (get_local $0) + (get_local $1) + (i32.add + (get_local $0) + (i32.const 280) + ) + (i32.add + (get_local $0) + (i32.const 48) + ) + (get_local $2) + ) + (return) + ) + (block $label$1 + (br_if $label$1 + (i64.ne + (get_local $3) + (i64.load + (i32.add + (get_local $0) + (i32.const 152) + ) + ) + ) + ) + (br_if $label$1 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $0) + (i32.const 160) + ) + ) + ) + ) + (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE + (get_local $0) + (get_local $1) + (i32.add + (get_local $0) + (i32.const 320) + ) + (i32.add + (get_local $0) + (i32.const 144) + ) + (get_local $2) + ) + (return) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1376) + ) + ) + (func $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i64) + (local $13 i64) + (local $14 i64) + (local $15 f64) + (local $16 i32) + (local $17 i32) + (local $18 f64) + (local $19 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $19 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 704) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $17 + (i32.load + (i32.add + (get_local $2) + (i32.const 28) + ) + ) + ) + (tee_local $10 + (i32.load offset=24 + (get_local $2) + ) + ) + ) + ) + (set_local $16 + (i32.add + (get_local $17) + (i32.const -24) + ) + ) + (set_local $5 + (i32.sub + (i32.const 0) + (get_local $10) + ) + ) + (loop $label$1 + (br_if $label$0 + (i64.eq + (i64.load + (i32.load + (get_local $16) + ) + ) + (get_local $1) + ) + ) + (set_local $17 + (get_local $16) + ) + (set_local $16 + (tee_local $6 + (i32.add + (get_local $16) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $6) + (get_local $5) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $17) + (get_local $10) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $16 + (i32.load + (i32.add + (get_local $17) + (i32.const -24) + ) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + (br $label$2) + ) + (set_local $16 + (i32.const 0) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $6 + (call $db_find_i64 + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $16 + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $2) + (get_local $6) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + ) + (call $eosio_assert + (tee_local $7 + (i32.ne + (get_local $16) + (i32.const 0) + ) + ) + (i32.const 1408) + ) + (call $eosio_assert + (i64.ge_s + (i64.load offset=8 + (get_local $16) + ) + (i64.load + (get_local $4) + ) + ) + (i32.const 1440) + ) + (drop + (call $memcpy + (i32.add + (get_local $19) + (i32.const 360) + ) + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (i32.const 232) + ) + ) + (i64.store + (tee_local $8 + (i32.add + (i32.add + (get_local $19) + (i32.const 312) + ) + (i32.const 16) + ) + ) + (i64.load + (tee_local $17 + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + ) + (i64.store + (tee_local $9 + (i32.add + (i32.add + (get_local $19) + (i32.const 312) + ) + (i32.const 8) + ) + ) + (i64.load + (tee_local $5 + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + ) + ) + (i64.store offset=312 + (get_local $19) + (i64.load + (get_local $4) + ) + ) + (set_local $14 + (i64.load + (tee_local $10 + (i32.add + (get_local $16) + (i32.const 48) + ) + ) + ) + ) + (i64.store offset=296 + (get_local $19) + (i64.load + (tee_local $11 + (i32.add + (get_local $16) + (i32.const 40) + ) + ) + ) + ) + (i64.store offset=304 + (get_local $19) + (get_local $14) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 120) + ) + (i32.const 16) + ) + (i64.load + (get_local $8) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 120) + ) + (i32.const 8) + ) + (i64.load + (get_local $9) + ) + ) + (i64.store offset=120 + (get_local $19) + (i64.load offset=312 + (get_local $19) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 104) + ) + (i32.const 8) + ) + (i64.load offset=304 + (get_local $19) + ) + ) + (i64.store offset=104 + (get_local $19) + (i64.load offset=296 + (get_local $19) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $19) + (i32.const 336) + ) + (i32.add + (get_local $19) + (i32.const 360) + ) + (i32.add + (get_local $19) + (i32.const 120) + ) + (i32.add + (get_local $19) + (i32.const 104) + ) + ) + (i64.store + (tee_local $8 + (i32.add + (i32.add + (get_local $19) + (i32.const 248) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $19) + (i32.const 336) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (tee_local $9 + (i32.add + (i32.add + (get_local $19) + (i32.const 248) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $19) + (i32.const 336) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=248 + (get_local $19) + (i64.load offset=336 + (get_local $19) + ) + ) + (set_local $14 + (i64.load + (get_local $17) + ) + ) + (i64.store offset=232 + (get_local $19) + (i64.load + (get_local $5) + ) + ) + (i64.store offset=240 + (get_local $19) + (get_local $14) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 80) + ) + (i32.const 16) + ) + (i64.load + (get_local $8) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 80) + ) + (i32.const 8) + ) + (i64.load + (get_local $9) + ) + ) + (i64.store offset=80 + (get_local $19) + (i64.load offset=248 + (get_local $19) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 64) + ) + (i32.const 8) + ) + (i64.load offset=240 + (get_local $19) + ) + ) + (i64.store offset=64 + (get_local $19) + (i64.load offset=232 + (get_local $19) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $19) + (i32.const 272) + ) + (get_local $6) + (i32.add + (get_local $19) + (i32.const 80) + ) + (i32.add + (get_local $19) + (i32.const 64) + ) + ) + (call $eosio_assert + (i64.ge_s + (tee_local $14 + (i64.load offset=272 + (get_local $19) + ) + ) + (i64.load + (get_local $4) + ) + ) + (i32.const 1488) + ) + (call $eosio_assert + (i64.eq + (tee_local $12 + (i64.load offset=288 + (get_local $19) + ) + ) + (i64.load + (get_local $17) + ) + ) + (i32.const 800) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $5) + ) + (tee_local $13 + (i64.load offset=280 + (get_local $19) + ) + ) + ) + (i32.const 816) + ) + (call $eosio_assert + (i64.gt_s + (tee_local $14 + (i64.sub + (get_local $14) + (i64.load + (get_local $4) + ) + ) + ) + (i64.const -4611686018427387904) + ) + (i32.const 864) + ) + (call $eosio_assert + (i64.lt_s + (get_local $14) + (i64.const 4611686018427387904) + ) + (i32.const 896) + ) + (i64.store offset=192 + (get_local $19) + (get_local $13) + ) + (i64.store offset=184 + (get_local $19) + (get_local $14) + ) + (i64.store offset=200 + (get_local $19) + (get_local $12) + ) + (i64.store offset=176 + (get_local $19) + (i64.load + (get_local $10) + ) + ) + (i64.store offset=168 + (get_local $19) + (i64.load + (get_local $11) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 40) + ) + (i32.const 8) + ) + (i64.load offset=192 + (get_local $19) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $19) + (i32.const 40) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (i32.add + (get_local $19) + (i32.const 184) + ) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $19) + (i32.const 40) + ) + (i32.const 16) + ) + (i32.load offset=200 + (get_local $19) + ) + ) + (i64.store offset=40 + (get_local $19) + (i64.load offset=184 + (get_local $19) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $19) + (i32.const 24) + ) + (i32.const 8) + ) + (i64.load offset=176 + (get_local $19) + ) + ) + (i64.store offset=24 + (get_local $19) + (i64.load offset=168 + (get_local $19) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $19) + (i32.const 208) + ) + (get_local $6) + (i32.add + (get_local $19) + (i32.const 40) + ) + (i32.add + (get_local $19) + (i32.const 24) + ) + ) + (i64.store offset=336 + (get_local $19) + (tee_local $14 + (i64.sub + (i64.load offset=336 + (get_local $19) + ) + (i64.load offset=208 + (get_local $19) + ) + ) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.ne + (i64.load offset=8 + (get_local $16) + ) + (i64.load + (get_local $4) + ) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $10) + ) + (i64.load offset=352 + (get_local $19) + ) + ) + (i32.const 800) + ) + (set_local $13 + (i64.load offset=32 + (get_local $16) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=344 + (get_local $19) + ) + (tee_local $12 + (i64.load + (get_local $11) + ) + ) + ) + (i32.const 816) + ) + (call $eosio_assert + (i64.gt_s + (tee_local $14 + (i64.sub + (get_local $13) + (get_local $14) + ) + ) + (i64.const -4611686018427387904) + ) + (i32.const 864) + ) + (call $eosio_assert + (i64.lt_s + (get_local $14) + (i64.const 4611686018427387904) + ) + (i32.const 896) + ) + (set_local $13 + (i64.load + (get_local $10) + ) + ) + (call $eosio_assert + (get_local $7) + (i32.const 928) + ) + (call $eosio_assert + (get_local $7) + (i32.const 1152) + ) + (block $label$6 + (br_if $label$6 + (i32.lt_s + (tee_local $6 + (call $db_next_i64 + (i32.load offset=68 + (get_local $16) + ) + (i32.add + (get_local $19) + (i32.const 592) + ) + ) + ) + (i32.const 0) + ) + ) + (drop + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $2) + (get_local $6) + ) + ) + ) + (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ + (get_local $2) + (get_local $16) + ) + (set_local $16 + (i32.const 0) + ) + (block $label$7 + (br_if $label$7 + (i32.lt_s + (tee_local $6 + (call $db_lowerbound_i64 + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (i64.const 0) + ) + ) + (i32.const 0) + ) + ) + (set_local $16 + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $2) + (get_local $6) + ) + ) + ) + (i64.store offset=152 + (get_local $19) + (get_local $12) + ) + (set_local $6 + (i32.load offset=440 + (get_local $0) + ) + ) + (i64.store + (i32.add + (get_local $19) + (i32.const 8) + ) + (get_local $12) + ) + (i64.store offset=160 + (get_local $19) + (get_local $13) + ) + (i64.store + (i32.add + (get_local $19) + (i32.const 16) + ) + (get_local $13) + ) + (i64.store offset=144 + (get_local $19) + (get_local $14) + ) + (i64.store + (get_local $19) + (get_local $14) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $6) + (get_local $1) + (get_local $19) + (get_local $19) + ) + (br $label$4) + ) + (call $eosio_assert + (get_local $7) + (i32.const 352) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (get_local $16) + ) + (get_local $2) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $2) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (i64.store offset=32 + (get_local $16) + (tee_local $14 + (i64.sub + (i64.load offset=32 + (get_local $16) + ) + (get_local $14) + ) + ) + ) + (i64.store offset=680 + (get_local $19) + (i64.trunc_u/f64 + (f64.mul + (f64.load + (tee_local $6 + (i32.add + (get_local $16) + (i32.const 56) + ) + ) + ) + (f64.const 1e6) + ) + ) + ) + (set_local $1 + (i64.load + (get_local $16) + ) + ) + (i64.store offset=8 + (get_local $16) + (tee_local $12 + (i64.sub + (i64.load offset=8 + (get_local $16) + ) + (i64.load + (get_local $4) + ) + ) + ) + ) + (f64.store + (get_local $6) + (f64.div + (f64.convert_s/i64 + (get_local $12) + ) + (f64.convert_s/i64 + (get_local $14) + ) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 544) + ) + (i32.store offset=672 + (get_local $19) + (i32.add + (i32.add + (get_local $19) + (i32.const 592) + ) + (i32.const 64) + ) + ) + (i32.store offset=668 + (get_local $19) + (i32.add + (get_local $19) + (i32.const 592) + ) + ) + (i32.store offset=664 + (get_local $19) + (i32.add + (get_local $19) + (i32.const 592) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE + (i32.add + (get_local $19) + (i32.const 664) + ) + (get_local $16) + ) + ) + (call $db_update_i64 + (i32.load offset=68 + (get_local $16) + ) + (i64.const 0) + (i32.add + (get_local $19) + (i32.const 592) + ) + (i32.const 64) + ) + (block $label$8 + (br_if $label$8 + (i64.lt_u + (get_local $1) + (i64.load offset=16 + (get_local $2) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (select + (i64.const -2) + (i64.add + (get_local $1) + (i64.const 1) + ) + (i64.gt_u + (get_local $1) + (i64.const -3) + ) + ) + ) + ) + (i64.store offset=696 + (get_local $19) + (i64.trunc_u/f64 + (f64.mul + (f64.load + (get_local $6) + ) + (f64.const 1e6) + ) + ) + ) + (br_if $label$4 + (i32.eqz + (call $memcmp + (i32.add + (get_local $19) + (i32.const 680) + ) + (i32.add + (get_local $19) + (i32.const 696) + ) + (i32.const 8) + ) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.gt_s + (tee_local $6 + (i32.load + (tee_local $17 + (i32.add + (get_local $16) + (i32.const 72) + ) + ) + ) + ) + (i32.const -1) + ) + ) + (i32.store + (get_local $17) + (tee_local $6 + (call $db_idx64_find_primary + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (i32.add + (get_local $19) + (i32.const 688) + ) + (get_local $1) + ) + ) + ) + ) + (call $db_idx64_update + (get_local $6) + (i64.const 0) + (i32.add + (get_local $19) + (i32.const 696) + ) + ) + ) + (i64.store + (tee_local $6 + (i32.add + (get_local $3) + (i32.const 56) + ) + ) + (i64.sub + (i64.load + (get_local $6) + ) + (i64.load + (get_local $4) + ) + ) + ) + (block $label$10 + (block $label$11 + (block $label$12 + (br_if $label$12 + (i32.eqz + (get_local $16) + ) + ) + (br_if $label$11 + (i32.eqz + (i32.or + (f64.ge + (tee_local $18 + (f64.load offset=56 + (get_local $16) + ) + ) + (tee_local $15 + (f64.load + (tee_local $16 + (i32.add + (get_local $3) + (i32.const 80) + ) + ) + ) + ) + ) + (i32.or + (f64.ne + (get_local $18) + (get_local $18) + ) + (f64.ne + (get_local $15) + (get_local $15) + ) + ) + ) + ) + ) + (br $label$10) + ) + (set_local $16 + (i32.add + (get_local $3) + (i32.const 80) + ) + ) + (set_local $18 + (f64.const 1797693134862315708145274e284) + ) + ) + (f64.store + (get_local $16) + (get_local $18) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $19) + (i32.const 704) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 40) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 48) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 56) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio12market_state13update_marginEyRKNS_14extended_assetES3_ (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) + (local $4 i64) + (local $5 i64) + (set_local $5 + (i64.load offset=16 + (get_local $2) + ) + ) + (block $label$0 + (br_if $label$0 + (i64.ne + (tee_local $4 + (i64.load offset=8 + (get_local $2) + ) + ) + (i64.load + (i32.add + (get_local $0) + (i32.const 56) + ) + ) + ) + ) + (br_if $label$0 + (i64.ne + (get_local $5) + (i64.load + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + ) + (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ + (get_local $0) + (get_local $1) + (i32.add + (get_local $0) + (i32.const 280) + ) + (i32.add + (get_local $0) + (i32.const 48) + ) + (get_local $2) + (get_local $3) + ) + (return) + ) + (block $label$1 + (br_if $label$1 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $0) + (i32.const 152) + ) + ) + ) + ) + (br_if $label$1 + (i64.ne + (get_local $5) + (i64.load + (i32.add + (get_local $0) + (i32.const 160) + ) + ) + ) + ) + (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ + (get_local $0) + (get_local $1) + (i32.add + (get_local $0) + (i32.const 320) + ) + (i32.add + (get_local $0) + (i32.const 144) + ) + (get_local $2) + (get_local $3) + ) + (return) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1376) + ) + ) + (func $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i64) + (local $10 f64) + (local $11 i64) + (local $12 f64) + (local $13 i32) + (local $14 i32) + (local $15 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $15 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $14 + (i32.load + (i32.add + (get_local $2) + (i32.const 28) + ) + ) + ) + (tee_local $6 + (i32.load offset=24 + (get_local $2) + ) + ) + ) + ) + (set_local $13 + (i32.add + (get_local $14) + (i32.const -24) + ) + ) + (set_local $7 + (i32.sub + (i32.const 0) + (get_local $6) + ) + ) + (loop $label$1 + (br_if $label$0 + (i64.eq + (i64.load + (i32.load + (get_local $13) + ) + ) + (get_local $1) + ) + ) + (set_local $14 + (get_local $13) + ) + (set_local $13 + (tee_local $8 + (i32.add + (get_local $13) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $8) + (get_local $7) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.eq + (get_local $14) + (get_local $6) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $8 + (i32.load + (i32.add + (get_local $14) + (i32.const -24) + ) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + (br_if $label$7 + (get_local $8) + ) + (br $label$6) + ) + (br_if $label$6 + (i32.lt_s + (tee_local $13 + (call $db_find_i64 + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (tee_local $8 + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $2) + (get_local $13) + ) + ) + ) + (get_local $2) + ) + (i32.const 224) + ) + ) + (br_if $label$5 + (i64.ne + (i64.load offset=8 + (get_local $8) + ) + (i64.sub + (i64.const 0) + (i64.load + (get_local $4) + ) + ) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=32 + (get_local $8) + ) + (i64.sub + (i64.const 0) + (i64.load + (get_local $5) + ) + ) + ) + (i32.const 1584) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 928) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1152) + ) + (set_local $13 + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.lt_s + (tee_local $14 + (call $db_next_i64 + (i32.load offset=68 + (get_local $8) + ) + (get_local $15) + ) + ) + (i32.const 0) + ) + ) + (drop + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $2) + (get_local $14) + ) + ) + ) + (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ + (get_local $2) + (get_local $8) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $8 + (call $db_lowerbound_i64 + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (i64.const 0) + ) + ) + (i32.const 0) + ) + ) + (set_local $13 + (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl + (get_local $2) + (get_local $8) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i64.gt_s + (i64.load + (get_local $4) + ) + (i64.const 0) + ) + (i32.const 1520) + ) + (call $eosio_assert + (i64.gt_s + (i64.load + (get_local $5) + ) + (i64.const 0) + ) + (i32.const 1552) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $2) + ) + (call $current_receiver) + ) + (i32.const 288) + ) + (set_local $8 + (call $_ZN5eosio15margin_positionC2Ev + (tee_local $13 + (call $_Znwj + (i32.const 80) + ) + ) + ) + ) + (i32.store offset=64 + (get_local $13) + (get_local $2) + ) + (i64.store + (get_local $13) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $13) + (i32.const 28) + ) + (i32.load + (i32.add + (get_local $4) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (get_local $13) + (i32.const 24) + ) + (i32.load + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $13) + (i32.const 20) + ) + (i32.load + (i32.add + (get_local $4) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $13) + (i32.const 16) + ) + (i32.load + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + ) + (i32.store + (i32.add + (get_local $13) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $4) + (i32.const 4) + ) + ) + ) + (i32.store offset=8 + (get_local $13) + (i32.load + (get_local $4) + ) + ) + (i64.store + (i32.add + (get_local $13) + (i32.const 48) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $13) + (i32.const 40) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i64.store offset=32 + (get_local $13) + (i64.load + (get_local $5) + ) + ) + (f64.store offset=56 + (get_local $13) + (f64.div + (f64.convert_s/i64 + (i64.load offset=8 + (get_local $13) + ) + ) + (f64.convert_s/i64 + (i64.load offset=32 + (get_local $13) + ) + ) + ) + ) + (i32.store offset=80 + (get_local $15) + (i32.add + (get_local $15) + (i32.const 64) + ) + ) + (i32.store offset=76 + (get_local $15) + (get_local $15) + ) + (i32.store offset=72 + (get_local $15) + (get_local $15) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE + (i32.add + (get_local $15) + (i32.const 72) + ) + (get_local $8) + ) + ) + (i32.store offset=68 + (get_local $13) + (call $db_store_i64 + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (get_local $1) + (tee_local $9 + (i64.load + (get_local $13) + ) + ) + (get_local $15) + (i32.const 64) + ) + ) + (block $label$10 + (br_if $label$10 + (i64.lt_u + (get_local $9) + (i64.load offset=16 + (get_local $2) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (select + (i64.const -2) + (i64.add + (get_local $9) + (i64.const 1) + ) + (i64.gt_u + (get_local $9) + (i64.const -3) + ) + ) + ) + ) + (set_local $9 + (i64.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (set_local $11 + (i64.load + (get_local $13) + ) + ) + (i64.store offset=104 + (get_local $15) + (i64.trunc_u/f64 + (f64.mul + (f64.load + (i32.add + (get_local $13) + (i32.const 56) + ) + ) + (f64.const 1e6) + ) + ) + ) + (i32.store offset=72 + (get_local $13) + (call $db_idx64_store + (get_local $9) + (i64.const -7949197150146002944) + (get_local $1) + (get_local $11) + (i32.add + (get_local $15) + (i32.const 104) + ) + ) + ) + (i32.store offset=72 + (get_local $15) + (get_local $13) + ) + (i64.store + (get_local $15) + (tee_local $1 + (i64.load + (get_local $13) + ) + ) + ) + (i32.store offset=104 + (get_local $15) + (tee_local $14 + (i32.load + (i32.add + (get_local $13) + (i32.const 68) + ) + ) + ) + ) + (br_if $label$4 + (i32.ge_u + (tee_local $8 + (i32.load + (i32.add + (get_local $2) + (i32.const 28) + ) + ) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $8) + (get_local $1) + ) + (i32.store offset=16 + (get_local $8) + (get_local $14) + ) + (i32.store offset=72 + (get_local $15) + (i32.const 0) + ) + (i32.store + (get_local $8) + (get_local $13) + ) + (i32.store + (i32.add + (get_local $2) + (i32.const 28) + ) + (i32.add + (get_local $8) + (i32.const 24) + ) + ) + (br $label$3) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 352) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=64 + (get_local $8) + ) + (get_local $2) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $2) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (i64.store offset=88 + (get_local $15) + (i64.trunc_u/f64 + (f64.mul + (f64.load + (tee_local $13 + (i32.add + (get_local $8) + (i32.const 56) + ) + ) + ) + (f64.const 1e6) + ) + ) + ) + (set_local $1 + (i64.load + (get_local $8) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $4) + ) + (i64.load + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + (i32.const 1632) + ) + (i64.store offset=8 + (get_local $8) + (tee_local $9 + (i64.add + (i64.load offset=8 + (get_local $8) + ) + (i64.load + (get_local $4) + ) + ) + ) + ) + (call $eosio_assert + (i64.gt_s + (get_local $9) + (i64.const -4611686018427387904) + ) + (i32.const 1680) + ) + (call $eosio_assert + (i64.lt_s + (i64.load offset=8 + (get_local $8) + ) + (i64.const 4611686018427387904) + ) + (i32.const 1712) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $5) + ) + (i64.load + (i32.add + (get_local $8) + (i32.const 40) + ) + ) + ) + (i32.const 1632) + ) + (i64.store offset=32 + (get_local $8) + (tee_local $9 + (i64.add + (i64.load offset=32 + (get_local $8) + ) + (i64.load + (get_local $5) + ) + ) + ) + ) + (call $eosio_assert + (i64.gt_s + (get_local $9) + (i64.const -4611686018427387904) + ) + (i32.const 1680) + ) + (call $eosio_assert + (i64.lt_s + (i64.load offset=32 + (get_local $8) + ) + (i64.const 4611686018427387904) + ) + (i32.const 1712) + ) + (f64.store + (get_local $13) + (f64.div + (f64.convert_s/i64 + (i64.load offset=8 + (get_local $8) + ) + ) + (f64.convert_s/i64 + (i64.load offset=32 + (get_local $8) + ) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (i64.load + (get_local $8) + ) + ) + (i32.const 544) + ) + (i32.store offset=80 + (get_local $15) + (i32.add + (get_local $15) + (i32.const 64) + ) + ) + (i32.store offset=76 + (get_local $15) + (get_local $15) + ) + (i32.store offset=72 + (get_local $15) + (get_local $15) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE + (i32.add + (get_local $15) + (i32.const 72) + ) + (get_local $8) + ) + ) + (call $db_update_i64 + (i32.load offset=68 + (get_local $8) + ) + (i64.const 0) + (get_local $15) + (i32.const 64) + ) + (block $label$11 + (br_if $label$11 + (i64.lt_u + (get_local $1) + (i64.load offset=16 + (get_local $2) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (select + (i64.const -2) + (i64.add + (get_local $1) + (i64.const 1) + ) + (i64.gt_u + (get_local $1) + (i64.const -3) + ) + ) + ) + ) + (i64.store offset=104 + (get_local $15) + (i64.trunc_u/f64 + (f64.mul + (f64.load + (get_local $13) + ) + (f64.const 1e6) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (call $memcmp + (i32.add + (get_local $15) + (i32.const 88) + ) + (i32.add + (get_local $15) + (i32.const 104) + ) + (i32.const 8) + ) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.gt_s + (tee_local $13 + (i32.load + (tee_local $14 + (i32.add + (get_local $8) + (i32.const 72) + ) + ) + ) + ) + (i32.const -1) + ) + ) + (i32.store + (get_local $14) + (tee_local $13 + (call $db_idx64_find_primary + (i64.load + (get_local $2) + ) + (i64.load offset=8 + (get_local $2) + ) + (i64.const -7949197150146002944) + (i32.add + (get_local $15) + (i32.const 96) + ) + (get_local $1) + ) + ) + ) + ) + (call $db_idx64_update + (get_local $13) + (i64.const 0) + (i32.add + (get_local $15) + (i32.const 104) + ) + ) + ) + (set_local $13 + (get_local $8) + ) + (br $label$2) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497546923563548672ENS1_15margin_positionEJNS1_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS3_yXadL_ZNKS3_8get_callEvEEEEEEEE8item_ptrENS_9allocatorISB_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINSA_4itemENS_14default_deleteISH_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $2) + (i32.const 24) + ) + (i32.add + (get_local $15) + (i32.const 72) + ) + (get_local $15) + (i32.add + (get_local $15) + (i32.const 104) + ) + ) + ) + (set_local $8 + (i32.load offset=72 + (get_local $15) + ) + ) + (i32.store offset=72 + (get_local $15) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $8) + ) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $4) + ) + (i64.load + (i32.add + (get_local $3) + (i32.const 64) + ) + ) + ) + (i32.const 1632) + ) + (i64.store + (tee_local $8 + (i32.add + (get_local $3) + (i32.const 56) + ) + ) + (tee_local $1 + (i64.add + (i64.load + (get_local $8) + ) + (i64.load + (get_local $4) + ) + ) + ) + ) + (call $eosio_assert + (i64.gt_s + (get_local $1) + (i64.const -4611686018427387904) + ) + (i32.const 1680) + ) + (call $eosio_assert + (i64.lt_s + (i64.load + (get_local $8) + ) + (i64.const 4611686018427387904) + ) + (i32.const 1712) + ) + (call $eosio_assert + (i64.le_s + (i64.load + (get_local $8) + ) + (i64.load offset=32 + (get_local $3) + ) + ) + (i32.const 1744) + ) + (block $label$14 + (block $label$15 + (br_if $label$15 + (i32.eqz + (get_local $13) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.or + (f64.ge + (tee_local $10 + (f64.load offset=56 + (get_local $13) + ) + ) + (tee_local $12 + (f64.load + (tee_local $13 + (i32.add + (get_local $3) + (i32.const 80) + ) + ) + ) + ) + ) + (i32.or + (f64.ne + (get_local $10) + (get_local $10) + ) + (f64.ne + (get_local $12) + (get_local $12) + ) + ) + ) + ) + (f64.store + (get_local $13) + (get_local $10) + ) + ) + (call $eosio_assert + (i32.xor + (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $3) + ) + (i32.const 1) + ) + (i32.const 1792) + ) + (br $label$14) + ) + (i64.store + (i32.add + (get_local $3) + (i32.const 80) + ) + (i64.const 9218868437227405311) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $15) + (i32.const 112) + ) + ) + ) + (func $_ZN5eosio12market_state4saveEv (param $0 i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 240) + ) + ) + ) + (call $eosio_assert + (i32.ne + (tee_local $2 + (i32.load + (i32.add + (get_local $0) + (i32.const 448) + ) + ) + ) + (i32.const 0) + ) + (i32.const 352) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=232 + (get_local $2) + ) + (i32.add + (get_local $0) + (i32.const 240) + ) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=240 + (get_local $0) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (set_local $1 + (i64.load + (tee_local $3 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + ) + (drop + (call $memcpy + (get_local $2) + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.const 232) + ) + ) + (call $eosio_assert + (i64.eq + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.shr_u + (i64.load + (get_local $3) + ) + (i64.const 8) + ) + ) + (i32.const 544) + ) + (i32.store offset=232 + (get_local $4) + (i32.add + (get_local $4) + (i32.const 220) + ) + ) + (i32.store offset=228 + (get_local $4) + (get_local $4) + ) + (i32.store offset=224 + (get_local $4) + (get_local $4) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_stateE + (i32.add + (get_local $4) + (i32.const 224) + ) + (get_local $2) + ) + ) + (call $db_update_i64 + (i32.load offset=236 + (get_local $2) + ) + (i64.const 0) + (get_local $4) + (i32.const 220) + ) + (block $label$0 + (br_if $label$0 + (i64.lt_u + (get_local $1) + (i64.load + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 256) + ) + ) + ) + ) + ) + (i64.store + (get_local $0) + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $4) + (i32.const 240) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_stateE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 3) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_state9connectorE + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_state9connectorE + (get_local $0) + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (i32.add + (get_local $1) + (i32.const 136) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_state9connectorE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 3) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 40) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 48) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 56) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 64) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 72) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 80) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 88) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio8exchange7depositEyNS_14extended_assetE (type $FUNCSIG$viji) (param $0 i32) (param $1 i64) (param $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 128) + ) + ) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (i64.load + (get_local $2) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $8 + (i64.shr_u + (i64.load offset=8 + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $6 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $8) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $4 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $4 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $4) + (i32.const 1840) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 16) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 8) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i32.store offset=108 + (get_local $11) + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (i32.store offset=104 + (get_local $11) + (i32.load + (get_local $2) + ) + ) + (set_local $3 + (i64.load + (get_local $0) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=88 + (get_local $11) + (i64.const 0) + ) + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.ge_u + (tee_local $6 + (call $strlen + (i32.const 1872) + ) + ) + (i32.const -16) + ) + ) + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.ge_u + (get_local $6) + (i32.const 11) + ) + ) + (i32.store8 offset=88 + (get_local $11) + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (set_local $4 + (i32.or + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.const 1) + ) + ) + (br_if $label$8 + (get_local $6) + ) + (br $label$7) + ) + (set_local $4 + (call $_Znwj + (tee_local $5 + (i32.and + (i32.add + (get_local $6) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=88 + (get_local $11) + (i32.or + (get_local $5) + (i32.const 1) + ) + ) + (i32.store offset=96 + (get_local $11) + (get_local $4) + ) + (i32.store offset=92 + (get_local $11) + (get_local $6) + ) + ) + (drop + (call $memcpy + (get_local $4) + (i32.const 1872) + (get_local $6) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $4) + (get_local $6) + ) + (i32.const 0) + ) + (set_local $8 + (i64.const 0) + ) + (set_local $7 + (i64.const 59) + ) + (set_local $6 + (i32.const 1888) + ) + (set_local $9 + (i64.const 0) + ) + (loop $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (br_if $label$15 + (i64.gt_u + (get_local $8) + (i64.const 5) + ) + ) + (br_if $label$14 + (i32.gt_u + (i32.and + (i32.add + (tee_local $4 + (i32.load8_s + (get_local $6) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 165) + ) + ) + (br $label$13) + ) + (set_local $10 + (i64.const 0) + ) + (br_if $label$12 + (i64.le_u + (get_local $8) + (i64.const 11) + ) + ) + (br $label$11) + ) + (set_local $4 + (select + (i32.add + (get_local $4) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $4) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $10 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $4) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $10 + (i64.shl + (i64.and + (get_local $10) + (i64.const 31) + ) + (i64.and + (get_local $7) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (set_local $8 + (i64.add + (get_local $8) + (i64.const 1) + ) + ) + (set_local $9 + (i64.or + (get_local $10) + (get_local $9) + ) + ) + (br_if $label$10 + (i64.ne + (tee_local $7 + (i64.add + (get_local $7) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=24 + (get_local $11) + (i64.load offset=104 + (get_local $11) + ) + ) + (call $_ZN5eosio8currency15inline_transferEyyNS_14extended_assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy + (get_local $1) + (get_local $3) + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.add + (get_local $11) + (i32.const 88) + ) + (get_local $9) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (i32.and + (i32.load8_u offset=88 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=96 + (get_local $11) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i64.store offset=64 + (get_local $11) + (i64.load + (get_local $2) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 48) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=48 + (get_local $11) + (i64.const 0) + ) + (br_if $label$5 + (i32.ge_u + (tee_local $6 + (call $strlen + (i32.const 1872) + ) + ) + (i32.const -16) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (block $label$17 + (block $label$18 + (block $label$19 + (br_if $label$19 + (i32.ge_u + (get_local $6) + (i32.const 11) + ) + ) + (i32.store8 offset=48 + (get_local $11) + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (set_local $4 + (i32.or + (i32.add + (get_local $11) + (i32.const 48) + ) + (i32.const 1) + ) + ) + (br_if $label$18 + (get_local $6) + ) + (br $label$17) + ) + (set_local $4 + (call $_Znwj + (tee_local $0 + (i32.and + (i32.add + (get_local $6) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=48 + (get_local $11) + (i32.or + (get_local $0) + (i32.const 1) + ) + ) + (i32.store offset=56 + (get_local $11) + (get_local $4) + ) + (i32.store offset=52 + (get_local $11) + (get_local $6) + ) + ) + (drop + (call $memcpy + (get_local $4) + (i32.const 1872) + (get_local $6) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $4) + (get_local $6) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 8) + ) + ) + ) + (i64.store + (get_local $11) + (i64.load offset=64 + (get_local $11) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $2) + (get_local $1) + (get_local $11) + (get_local $6) + ) + (block $label$20 + (br_if $label$20 + (i32.eqz + (i32.and + (i32.load8_u offset=48 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=56 + (get_local $11) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 128) + ) + ) + (return) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $11) + (i32.const 88) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $11) + (i32.const 48) + ) + ) + (unreachable) + ) + (func $_ZN5eosio8currency15inline_transferEyyNS_14extended_assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy (param $0 i64) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i64) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i64) + (local $12 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $12 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (set_local $5 + (i64.load offset=16 + (get_local $2) + ) + ) + (set_local $9 + (i64.const 0) + ) + (set_local $8 + (i64.const 59) + ) + (set_local $7 + (i32.const 1904) + ) + (set_local $10 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $9) + (i64.const 7) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $6 + (i32.load8_s + (get_local $7) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $11 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $9) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $6 + (select + (i32.add + (get_local $6) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $6) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $11 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $6) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $11 + (i64.shl + (i64.and + (get_local $11) + (i64.const 31) + ) + (i64.and + (get_local $8) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (set_local $9 + (i64.add + (get_local $9) + (i64.const 1) + ) + ) + (set_local $10 + (i64.or + (get_local $11) + (get_local $10) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $8 + (i64.add + (get_local $8) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 28) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 24) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (i64.store offset=16 + (get_local $12) + (get_local $1) + ) + (i64.store offset=8 + (get_local $12) + (get_local $0) + ) + (i32.store offset=24 + (get_local $12) + (i32.load + (get_local $2) + ) + ) + (drop + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 32) + ) + (get_local $3) + ) + ) + (i64.store offset=64 + (get_local $12) + (get_local $10) + ) + (i64.store offset=56 + (get_local $12) + (get_local $5) + ) + (i64.store + (tee_local $7 + (call $_Znwj + (i32.const 16) + ) + ) + (get_local $0) + ) + (i64.store offset=8 + (get_local $7) + (get_local $4) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 32) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 24) + ) + (tee_local $6 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 20) + ) + (get_local $6) + ) + (i32.store offset=72 + (get_local $12) + (get_local $7) + ) + (i32.store offset=84 + (get_local $12) + (i32.const 0) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 36) + ) + (i32.const 0) + ) + (set_local $7 + (i32.add + (tee_local $6 + (select + (i32.load + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 36) + ) + ) + (i32.shr_u + (tee_local $7 + (i32.load8_u offset=40 + (get_local $12) + ) + ) + (i32.const 1) + ) + (i32.and + (get_local $7) + (i32.const 1) + ) + ) + ) + (i32.const 32) + ) + ) + (set_local $9 + (i64.extend_u/i32 + (get_local $6) + ) + ) + (set_local $6 + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 28) + ) + ) + (loop $label$6 + (set_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $9 + (i64.shr_u + (get_local $9) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.eqz + (get_local $7) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $6) + (get_local $7) + ) + (set_local $6 + (i32.load + (i32.add + (get_local $12) + (i32.const 88) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $12) + (i32.const 84) + ) + ) + ) + (br $label$7) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $7 + (i32.const 0) + ) + ) + (i32.store offset=100 + (get_local $12) + (get_local $7) + ) + (i32.store offset=96 + (get_local $12) + (get_local $7) + ) + (i32.store offset=104 + (get_local $12) + (get_local $6) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency8transferE + (i32.add + (get_local $12) + (i32.const 96) + ) + (i32.add + (get_local $12) + (i32.const 8) + ) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (i32.and + (i32.load8_u + (i32.add + (get_local $12) + (i32.const 40) + ) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $12) + (i32.const 48) + ) + ) + ) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.add + (get_local $12) + (i32.const 56) + ) + ) + (call $send_inline + (tee_local $7 + (i32.load offset=8 + (get_local $12) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $12) + ) + (get_local $7) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $7 + (i32.load offset=8 + (get_local $12) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $12) + (get_local $7) + ) + (call $_ZdlPv + (get_local $7) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (tee_local $7 + (i32.load offset=84 + (get_local $12) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 88) + ) + (get_local $7) + ) + (call $_ZdlPv + (get_local $7) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $7 + (i32.load offset=72 + (get_local $12) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 76) + ) + (get_local $7) + ) + (call $_ZdlPv + (get_local $7) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $12) + (i32.const 112) + ) + ) + ) + (func $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (i32.sub + (tee_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (get_local $1) + ) + ) + (br_if $label$2 + (i32.le_s + (tee_local $4 + (i32.add + (tee_local $3 + (i32.sub + (get_local $6) + (tee_local $5 + (i32.load + (get_local $0) + ) + ) + ) + ) + (get_local $1) + ) + ) + (i32.const -1) + ) + ) + (set_local $6 + (i32.const 2147483647) + ) + (block $label$5 + (br_if $label$5 + (i32.gt_u + (tee_local $2 + (i32.sub + (get_local $2) + (get_local $5) + ) + ) + (i32.const 1073741822) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $6 + (select + (get_local $4) + (tee_local $6 + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $6) + (get_local $4) + ) + ) + ) + ) + ) + ) + (set_local $2 + (call $_Znwj + (get_local $6) + ) + ) + (br $label$1) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$6 + (i32.store8 + (get_local $6) + (i32.const 0) + ) + (i32.store + (get_local $0) + (tee_local $6 + (i32.add + (i32.load + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$6 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + (br $label$0) + ) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $2 + (i32.const 0) + ) + (br $label$1) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $4 + (i32.add + (get_local $2) + (get_local $6) + ) + ) + (set_local $6 + (tee_local $5 + (i32.add + (get_local $2) + (get_local $3) + ) + ) + ) + (loop $label$7 + (i32.store8 + (get_local $6) + (i32.const 0) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$7 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + ) + (set_local $5 + (i32.sub + (get_local $5) + (tee_local $2 + (i32.sub + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $1 + (i32.load + (get_local $0) + ) + ) + ) + ) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.lt_s + (get_local $2) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $1) + (get_local $2) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $5) + ) + (i32.store + (get_local $3) + (get_local $6) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + (return) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency8transferE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE + (get_local $0) + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + (func $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=8 + (get_local $0) + (i32.const 0) + ) + (i64.store align=4 + (get_local $0) + (i64.const 0) + ) + (set_local $5 + (i32.const 16) + ) + (set_local $2 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + (set_local $6 + (i64.extend_u/i32 + (i32.shr_s + (tee_local $4 + (i32.sub + (tee_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + ) + (tee_local $3 + (i32.load offset=16 + (get_local $1) + ) + ) + ) + ) + (i32.const 4) + ) + ) + ) + (loop $label$0 + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $3) + (get_local $7) + ) + ) + (set_local $5 + (i32.add + (i32.and + (get_local $4) + (i32.const -16) + ) + (get_local $5) + ) + ) + ) + (set_local $5 + (i32.sub + (i32.sub + (tee_local $7 + (i32.load offset=28 + (get_local $1) + ) + ) + (get_local $5) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + (set_local $6 + (i64.extend_u/i32 + (i32.sub + (get_local $3) + (get_local $7) + ) + ) + ) + (loop $label$2 + (set_local $5 + (i32.add + (get_local $5) + (i32.const -1) + ) + ) + (br_if $label$2 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (set_local $7 + (i32.const 0) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.eqz + (get_local $5) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $0) + (i32.sub + (i32.const 0) + (get_local $5) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $5 + (i32.load + (get_local $0) + ) + ) + (br $label$3) + ) + (set_local $5 + (i32.const 0) + ) + ) + (i32.store + (get_local $8) + (get_local $5) + ) + (i32.store offset=8 + (get_local $8) + (get_local $7) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $7) + (get_local $5) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $1) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $7) + (tee_local $0 + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (get_local $0) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $8) + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE + (call $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE + (get_local $8) + (get_local $2) + ) + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $4 + (i64.extend_u/i32 + (i32.shr_s + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + (i32.const 4) + ) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$0 + (set_local $3 + (i32.wrap/i64 + (get_local $4) + ) + ) + (i32.store8 offset=15 + (get_local $7) + (i32.or + (i32.shl + (tee_local $6 + (i64.ne + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $3) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $5) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $6) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $6 + (i32.load + (get_local $1) + ) + ) + (tee_local $1 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$2 + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $5) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $3) + ) + (get_local $6) + (i32.const 8) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $5) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $3) + ) + (i32.add + (get_local $6) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (br_if $label$2 + (i32.ne + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $7 + (i64.extend_u/i32 + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $2 + (i32.wrap/i64 + (get_local $7) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $3 + (i64.ne + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $2) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $5) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $5) + (tee_local $6 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $3) + ) + ) + (call $eosio_assert + (i32.ge_s + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $6) + ) + (tee_local $5 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + ) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (get_local $2) + (get_local $5) + ) + ) + (i32.store + (get_local $6) + (i32.add + (i32.load + (get_local $6) + ) + (get_local $5) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $7 + (i64.extend_u/i32 + (select + (i32.load offset=4 + (get_local $1) + ) + (i32.shr_u + (tee_local $5 + (i32.load8_u + (get_local $1) + ) + ) + (i32.const 1) + ) + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $2 + (i32.wrap/i64 + (get_local $7) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $3 + (i64.ne + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $2) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (get_local $5) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $5) + (tee_local $6 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $3) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $5 + (select + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (i32.shr_u + (tee_local $5 + (i32.load8_u + (get_local $1) + ) + ) + (i32.const 1) + ) + (tee_local $2 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (set_local $3 + (i32.load offset=8 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.ge_s + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $6) + ) + (get_local $5) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (select + (get_local $3) + (i32.add + (get_local $1) + (i32.const 1) + ) + (get_local $2) + ) + (get_local $5) + ) + ) + (i32.store + (get_local $6) + (i32.add + (i32.load + (get_local $6) + ) + (get_local $5) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio8exchange8withdrawEyNS_14extended_assetE (type $FUNCSIG$viji) (param $0 i32) (param $1 i64) (param $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (call $require_auth + (get_local $1) + ) + (set_local $9 + (i64.load offset=8 + (get_local $2) + ) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (tee_local $6 + (i64.load + (get_local $2) + ) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $7 + (i64.shr_u + (get_local $9) + (i64.const 8) + ) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $7) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $4 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $4 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $4) + (i32.const 1840) + ) + (call $eosio_assert + (i32.xor + (i32.wrap/i64 + (i64.shr_u + (get_local $6) + (i64.const 63) + ) + ) + (i32.const 1) + ) + (i32.const 1920) + ) + (i64.store offset=96 + (get_local $10) + (get_local $9) + ) + (set_local $7 + (i64.load offset=16 + (get_local $2) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.const 8) + ) + (get_local $9) + ) + (i64.store offset=104 + (get_local $10) + (get_local $7) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.const 16) + ) + (get_local $7) + ) + (i64.store offset=88 + (get_local $10) + (tee_local $7 + (i64.sub + (i64.const 0) + (get_local $6) + ) + ) + ) + (i64.store offset=24 + (get_local $10) + (get_local $7) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (i32.add + (get_local $0) + (i32.const 16) + ) + (get_local $1) + (i32.add + (get_local $10) + (i32.const 24) + ) + (get_local $5) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 16) + ) + (i32.load offset=16 + (get_local $2) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 8) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i32.store offset=68 + (get_local $10) + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (i32.store offset=64 + (get_local $10) + (i32.load + (get_local $2) + ) + ) + (set_local $3 + (i64.load + (get_local $0) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 48) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=48 + (get_local $10) + (i64.const 0) + ) + (block $label$5 + (br_if $label$5 + (i32.ge_u + (tee_local $5 + (call $strlen + (i32.const 1968) + ) + ) + (i32.const -16) + ) + ) + (block $label$6 + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ge_u + (get_local $5) + (i32.const 11) + ) + ) + (i32.store8 offset=48 + (get_local $10) + (i32.shl + (get_local $5) + (i32.const 1) + ) + ) + (set_local $2 + (i32.or + (i32.add + (get_local $10) + (i32.const 48) + ) + (i32.const 1) + ) + ) + (br_if $label$7 + (get_local $5) + ) + (br $label$6) + ) + (set_local $2 + (call $_Znwj + (tee_local $4 + (i32.and + (i32.add + (get_local $5) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=48 + (get_local $10) + (i32.or + (get_local $4) + (i32.const 1) + ) + ) + (i32.store offset=56 + (get_local $10) + (get_local $2) + ) + (i32.store offset=52 + (get_local $10) + (get_local $5) + ) + ) + (drop + (call $memcpy + (get_local $2) + (i32.const 1968) + (get_local $5) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $2) + (get_local $5) + ) + (i32.const 0) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 1888) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$9 + (block $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (br_if $label$14 + (i64.gt_u + (get_local $7) + (i64.const 5) + ) + ) + (br_if $label$13 + (i32.gt_u + (i32.and + (i32.add + (tee_local $2 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 165) + ) + ) + (br $label$12) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$11 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$10) + ) + (set_local $2 + (select + (i32.add + (get_local $2) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $2) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$9 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 8) + ) + ) + ) + (i64.store + (get_local $10) + (i64.load offset=64 + (get_local $10) + ) + ) + (call $_ZN5eosio8currency15inline_transferEyyNS_14extended_assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy + (get_local $3) + (get_local $1) + (get_local $10) + (i32.add + (get_local $10) + (i32.const 48) + ) + (get_local $8) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (i32.and + (i32.load8_u offset=48 + (get_local $10) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=56 + (get_local $10) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 112) + ) + ) + (return) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $10) + (i32.const 48) + ) + ) + (unreachable) + ) + (func $_ZN5eosio8exchange2onERKNS0_5tradeE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i64) + (local $14 i64) + (local $15 i64) + (local $16 i64) + (local $17 i32) + (local $18 i32) + (local $19 i32) + (local $20 i32) + (local $21 i32) + (local $22 i32) + (local $23 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $23 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 1008) + ) + ) + ) + (call $require_auth + (i64.load + (get_local $1) + ) + ) + (set_local $3 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + (set_local $21 + (i32.const 0) + ) + (set_local $22 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (i64.load offset=16 + (get_local $1) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $4 + (i64.shr_u + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (i64.const 8) + ) + ) + (set_local $20 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $4) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $20 + (i32.add + (get_local $20) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $22 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $20 + (i32.add + (get_local $20) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $22 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $22) + (i32.const 1984) + ) + (call $eosio_assert + (i64.gt_s + (i64.load + (get_local $3) + ) + (i64.const 0) + ) + (i32.const 2016) + ) + (block $label$5 + (br_if $label$5 + (i64.gt_u + (i64.add + (i64.load offset=40 + (get_local $1) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $4 + (i64.shr_u + (i64.load + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + (i64.const 8) + ) + ) + (set_local $20 + (i32.const 0) + ) + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $4) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $20 + (i32.add + (get_local $20) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $21 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $20 + (i32.add + (get_local $20) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $21 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $21) + (i32.const 2048) + ) + (call $eosio_assert + (i32.xor + (i32.wrap/i64 + (i64.shr_u + (i64.load + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (i64.const 63) + ) + ) + (i32.const 1) + ) + (i32.const 2080) + ) + (call $eosio_assert + (i32.or + (i64.ne + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (tee_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + ) + ) + (i64.ne + (i64.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + (tee_local $5 + (i64.load + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + ) + ) + ) + (i32.const 192) + ) + (i64.store offset=552 + (get_local $23) + (i64.shr_u + (i64.load offset=8 + (get_local $1) + ) + (i64.const 8) + ) + ) + (set_local $13 + (i64.load + (get_local $0) + ) + ) + (set_local $20 + (call $_ZN5eosio14exchange_stateC2Ev + (i32.add + (i32.add + (get_local $23) + (i32.const 552) + ) + (i32.const 8) + ) + ) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 808) + ) + (i64.const -1) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 816) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 824) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 800) + ) + (tee_local $14 + (i64.load offset=552 + (get_local $23) + ) + ) + ) + (i64.store offset=792 + (get_local $23) + (get_local $13) + ) + (i64.store offset=832 + (get_local $23) + (get_local $13) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 840) + ) + (tee_local $16 + (i64.or + (tee_local $15 + (i64.shl + (get_local $14) + (i64.const 4) + ) + ) + (i64.const 1) + ) + ) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 848) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 856) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 860) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 864) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $23) + (i32.const 868) + ) + (i32.const 0) + ) + (i64.store offset=872 + (get_local $23) + (get_local $13) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 880) + ) + (tee_local $15 + (i64.or + (get_local $15) + (i64.const 2) + ) + ) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 888) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 896) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 900) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 904) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $23) + (i32.const 908) + ) + (i32.const 0) + ) + (i64.store offset=912 + (get_local $23) + (get_local $13) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 920) + ) + (get_local $16) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 928) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 936) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 940) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 944) + ) + (i32.const 0) + ) + (i64.store offset=952 + (get_local $23) + (get_local $13) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 960) + ) + (get_local $15) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 968) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 976) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 980) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 984) + ) + (i32.const 0) + ) + (i32.store offset=992 + (get_local $23) + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy + (i32.add + (get_local $23) + (i32.const 996) + ) + (i32.add + (get_local $23) + (i32.const 792) + ) + (get_local $14) + ) + (call $eosio_assert + (i32.ne + (i32.load + (tee_local $21 + (i32.add + (get_local $23) + (i32.const 1000) + ) + ) + ) + (i32.const 0) + ) + (i32.const 720) + ) + (drop + (call $memcpy + (i32.add + (get_local $23) + (i32.const 320) + ) + (tee_local $2 + (call $memcpy + (get_local $20) + (i32.load + (get_local $21) + ) + (i32.const 232) + ) + ) + (i32.const 232) + ) + ) + (i64.store + (tee_local $20 + (i32.add + (i32.add + (get_local $23) + (i32.const 272) + ) + (i32.const 16) + ) + ) + (i64.load + (tee_local $17 + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + ) + (i64.store + (tee_local $21 + (i32.add + (i32.add + (get_local $23) + (i32.const 272) + ) + (i32.const 8) + ) + ) + (i64.load + (tee_local $18 + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + ) + (i64.store offset=272 + (get_local $23) + (i64.load + (get_local $3) + ) + ) + (i64.store offset=256 + (get_local $23) + (get_local $4) + ) + (i64.store offset=264 + (get_local $23) + (get_local $5) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 104) + ) + (i32.const 8) + ) + (i64.load + (get_local $21) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 104) + ) + (i32.const 16) + ) + (i64.load + (get_local $20) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 88) + ) + (i32.const 8) + ) + (i64.load offset=264 + (get_local $23) + ) + ) + (i64.store offset=104 + (get_local $23) + (i64.load offset=272 + (get_local $23) + ) + ) + (i64.store offset=88 + (get_local $23) + (i64.load offset=256 + (get_local $23) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $23) + (i32.const 296) + ) + (i32.add + (get_local $23) + (i32.const 320) + ) + (i32.add + (get_local $23) + (i32.const 104) + ) + (i32.add + (get_local $23) + (i32.const 88) + ) + ) + (set_local $12 + (i32.add + (get_local $23) + (i32.const 456) + ) + ) + (set_local $11 + (i32.add + (get_local $23) + (i32.const 872) + ) + ) + (set_local $10 + (i32.add + (get_local $23) + (i32.const 696) + ) + ) + (set_local $9 + (i32.add + (get_local $23) + (i32.const 832) + ) + ) + (set_local $8 + (i32.add + (i32.add + (get_local $23) + (i32.const 552) + ) + (i32.const 48) + ) + ) + (set_local $7 + (i32.add + (i32.add + (get_local $23) + (i32.const 320) + ) + (i32.const 40) + ) + ) + (set_local $19 + (i32.add + (get_local $23) + (i32.const 616) + ) + ) + (block $label$10 + (loop $label$11 + (block $label$12 + (br_if $label$12 + (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE + (i32.add + (get_local $23) + (i32.const 320) + ) + (get_local $7) + ) + ) + (br_if $label$10 + (i32.eqz + (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE + (i32.add + (get_local $23) + (i32.const 320) + ) + (get_local $12) + ) + ) + ) + ) + (block $label$13 + (block $label$14 + (br_if $label$14 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 552) + ) + (i32.const 56) + ) + ) + ) + ) + (br_if $label$14 + (i64.ne + (get_local $5) + (i64.load + (get_local $19) + ) + ) + ) + (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE + (i32.add + (get_local $23) + (i32.const 552) + ) + (get_local $8) + (get_local $9) + ) + (br $label$13) + ) + (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE + (i32.add + (get_local $23) + (i32.const 552) + ) + (get_local $10) + (get_local $11) + ) + ) + (drop + (call $memcpy + (i32.add + (get_local $23) + (i32.const 320) + ) + (get_local $2) + (i32.const 232) + ) + ) + (i64.store + (tee_local $20 + (i32.add + (i32.add + (get_local $23) + (i32.const 232) + ) + (i32.const 16) + ) + ) + (i64.load + (get_local $17) + ) + ) + (i64.store + (tee_local $21 + (i32.add + (i32.add + (get_local $23) + (i32.const 232) + ) + (i32.const 8) + ) + ) + (i64.load + (get_local $18) + ) + ) + (i64.store offset=232 + (get_local $23) + (i64.load + (get_local $3) + ) + ) + (i64.store offset=216 + (get_local $23) + (get_local $4) + ) + (i64.store + (tee_local $22 + (i32.add + (i32.add + (get_local $23) + (i32.const 216) + ) + (i32.const 8) + ) + ) + (get_local $5) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 16) + ) + (i32.const 8) + ) + (i64.load + (get_local $21) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 16) + ) + (i32.const 16) + ) + (i64.load + (get_local $20) + ) + ) + (i64.store + (i32.add + (get_local $23) + (i32.const 8) + ) + (i64.load + (get_local $22) + ) + ) + (i64.store offset=16 + (get_local $23) + (i64.load offset=232 + (get_local $23) + ) + ) + (i64.store + (get_local $23) + (i64.load offset=216 + (get_local $23) + ) + ) + (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.add + (get_local $23) + (i32.const 320) + ) + (i32.add + (get_local $23) + (i32.const 16) + ) + (get_local $23) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 296) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 296) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=296 + (get_local $23) + (i64.load offset=128 + (get_local $23) + ) + ) + (br $label$11) + ) + ) + (drop + (call $memcpy + (get_local $2) + (i32.add + (get_local $23) + (i32.const 320) + ) + (i32.const 232) + ) + ) + (call $printn + (i64.load + (get_local $1) + ) + ) + (call $prints + (i32.const 2128) + ) + (call $_ZNK5eosio5asset5printEv + (get_local $3) + ) + (call $prints + (i32.const 1280) + ) + (call $printn + (i64.load + (tee_local $20 + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + ) + (call $prints + (i32.const 2144) + ) + (call $_ZNK5eosio5asset5printEv + (i32.add + (get_local $23) + (i32.const 296) + ) + ) + (call $prints + (i32.const 1280) + ) + (call $printn + (i64.load offset=312 + (get_local $23) + ) + ) + (call $prints + (i32.const 1344) + ) + (block $label$15 + (br_if $label$15 + (i64.eqz + (tee_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + ) + ) + ) + (call $eosio_assert + (i64.le_s + (get_local $4) + (i64.load offset=296 + (get_local $23) + ) + ) + (i32.const 2160) + ) + ) + (i64.store offset=200 + (get_local $23) + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (i64.store offset=192 + (get_local $23) + (i64.sub + (i64.const 0) + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + (set_local $4 + (i64.load + (get_local $1) + ) + ) + (i64.store offset=208 + (get_local $23) + (i64.load + (get_local $20) + ) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 136) + ) + (i32.const 0) + ) + (i64.store offset=128 + (get_local $23) + (i64.const 0) + ) + (block $label$16 + (block $label$17 + (block $label$18 + (br_if $label$18 + (i32.ge_u + (tee_local $20 + (call $strlen + (i32.const 2176) + ) + ) + (i32.const -16) + ) + ) + (block $label$19 + (block $label$20 + (block $label$21 + (br_if $label$21 + (i32.ge_u + (get_local $20) + (i32.const 11) + ) + ) + (i32.store8 offset=128 + (get_local $23) + (i32.shl + (get_local $20) + (i32.const 1) + ) + ) + (set_local $21 + (i32.or + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.const 1) + ) + ) + (br_if $label$20 + (get_local $20) + ) + (br $label$19) + ) + (set_local $21 + (call $_Znwj + (tee_local $22 + (i32.and + (i32.add + (get_local $20) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=128 + (get_local $23) + (i32.or + (get_local $22) + (i32.const 1) + ) + ) + (i32.store offset=136 + (get_local $23) + (get_local $21) + ) + (i32.store offset=132 + (get_local $23) + (get_local $20) + ) + ) + (drop + (call $memcpy + (get_local $21) + (i32.const 2176) + (get_local $20) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $21) + (get_local $20) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 64) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 192) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 64) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 192) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=64 + (get_local $23) + (i64.load offset=192 + (get_local $23) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $6) + (get_local $4) + (i32.add + (get_local $23) + (i32.const 64) + ) + (get_local $23) + ) + (block $label$22 + (br_if $label$22 + (i32.eqz + (i32.and + (i32.load8_u offset=128 + (get_local $23) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=136 + (get_local $23) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $23) + (i32.const 168) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (i32.add + (get_local $23) + (i32.const 296) + ) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $23) + (i32.const 168) + ) + (i32.const 16) + ) + (i32.load + (i32.add + (i32.add + (get_local $23) + (i32.const 296) + ) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $23) + (i32.const 168) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $23) + (i32.const 296) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $23) + (i32.const 168) + ) + (i32.const 8) + ) + (i32.load + (i32.add + (i32.add + (get_local $23) + (i32.const 296) + ) + (i32.const 8) + ) + ) + ) + (i32.store offset=172 + (get_local $23) + (i32.load offset=300 + (get_local $23) + ) + ) + (i32.store offset=168 + (get_local $23) + (i32.load offset=296 + (get_local $23) + ) + ) + (set_local $4 + (i64.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=128 + (get_local $23) + (i64.const 0) + ) + (br_if $label$17 + (i32.ge_u + (tee_local $20 + (call $strlen + (i32.const 2192) + ) + ) + (i32.const -16) + ) + ) + (block $label$23 + (block $label$24 + (block $label$25 + (br_if $label$25 + (i32.ge_u + (get_local $20) + (i32.const 11) + ) + ) + (i32.store8 offset=128 + (get_local $23) + (i32.shl + (get_local $20) + (i32.const 1) + ) + ) + (set_local $21 + (i32.or + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.const 1) + ) + ) + (br_if $label$24 + (get_local $20) + ) + (br $label$23) + ) + (set_local $21 + (call $_Znwj + (tee_local $22 + (i32.and + (i32.add + (get_local $20) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=128 + (get_local $23) + (i32.or + (get_local $22) + (i32.const 1) + ) + ) + (i32.store offset=136 + (get_local $23) + (get_local $21) + ) + (i32.store offset=132 + (get_local $23) + (get_local $20) + ) + ) + (drop + (call $memcpy + (get_local $21) + (i32.const 2192) + (get_local $20) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $21) + (get_local $20) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 40) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 168) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 40) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 168) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=40 + (get_local $23) + (i64.load offset=168 + (get_local $23) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $6) + (get_local $4) + (i32.add + (get_local $23) + (i32.const 40) + ) + (get_local $23) + ) + (block $label$26 + (br_if $label$26 + (i32.eqz + (i32.and + (i32.load8_u offset=128 + (get_local $23) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=136 + (get_local $23) + ) + ) + ) + (block $label$27 + (br_if $label$27 + (i64.eq + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 552) + ) + (i32.const 16) + ) + ) + (i64.load offset=8 + (tee_local $20 + (i32.load + (i32.add + (get_local $23) + (i32.const 1000) + ) + ) + ) + ) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load + (i32.add + (get_local $23) + (i32.const 584) + ) + ) + (i64.load + (i32.add + (get_local $20) + (i32.const 24) + ) + ) + ) + (i32.const 800) + ) + (set_local $4 + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 552) + ) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load + (i32.add + (get_local $20) + (i32.const 16) + ) + ) + (tee_local $5 + (i64.load + (i32.add + (i32.add + (get_local $23) + (i32.const 552) + ) + (i32.const 24) + ) + ) + ) + ) + (i32.const 816) + ) + (call $eosio_assert + (i64.gt_s + (tee_local $4 + (i64.sub + (get_local $4) + (i64.load + (i32.add + (get_local $20) + (i32.const 8) + ) + ) + ) + ) + (i64.const -4611686018427387904) + ) + (i32.const 864) + ) + (call $eosio_assert + (i64.lt_s + (get_local $4) + (i64.const 4611686018427387904) + ) + (i32.const 896) + ) + (i64.store + (i32.add + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.const 16) + ) + (get_local $5) + ) + (i64.store align=4 + (i32.add + (get_local $23) + (i32.const 156) + ) + (i64.const 0) + ) + (i64.store offset=136 + (get_local $23) + (get_local $4) + ) + (i32.store offset=152 + (get_local $23) + (i32.const 0) + ) + (i64.store offset=128 + (get_local $23) + (i64.load + (get_local $0) + ) + ) + (set_local $21 + (i32.add + (i32.add + (get_local $23) + (i32.const 128) + ) + (i32.const 24) + ) + ) + (br_if $label$16 + (i32.ge_u + (tee_local $20 + (call $strlen + (i32.const 2208) + ) + ) + (i32.const -16) + ) + ) + (set_local $22 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (block $label$28 + (block $label$29 + (block $label$30 + (br_if $label$30 + (i32.ge_u + (get_local $20) + (i32.const 11) + ) + ) + (i32.store8 + (i32.add + (get_local $23) + (i32.const 152) + ) + (i32.shl + (get_local $20) + (i32.const 1) + ) + ) + (set_local $21 + (i32.add + (get_local $21) + (i32.const 1) + ) + ) + (br_if $label$29 + (get_local $20) + ) + (br $label$28) + ) + (set_local $21 + (call $_Znwj + (tee_local $3 + (i32.and + (i32.add + (get_local $20) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 152) + ) + (i32.or + (get_local $3) + (i32.const 1) + ) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 160) + ) + (get_local $21) + ) + (i32.store + (i32.add + (get_local $23) + (i32.const 156) + ) + (get_local $20) + ) + ) + (drop + (call $memcpy + (get_local $21) + (i32.const 2208) + (get_local $20) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $21) + (get_local $20) + ) + (i32.const 0) + ) + (call $_ZN5eosio8currency14issue_currencyERKNS0_5issueE + (get_local $22) + (i32.add + (get_local $23) + (i32.const 128) + ) + ) + (br_if $label$27 + (i32.eqz + (i32.and + (i32.load8_u + (i32.add + (get_local $23) + (i32.const 152) + ) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $23) + (i32.const 160) + ) + ) + ) + ) + (call $_ZN5eosio12market_state4saveEv + (i32.add + (get_local $23) + (i32.const 552) + ) + ) + (drop + (call $_ZN5eosio12market_stateD2Ev + (i32.add + (get_local $23) + (i32.const 552) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $23) + (i32.const 1008) + ) + ) + (return) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $23) + (i32.const 128) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $23) + (i32.const 128) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $21) + ) + (unreachable) + ) + (func $_ZNK5eosio5asset5printEv (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i32) + (set_local $10 + (tee_local $2 + (i32.load offset=4 + (i32.const 0) + ) + ) + ) + (set_local $7 + (i64.const 1) + ) + (block $label$0 + (br_if $label$0 + (tee_local $5 + (i64.eqz + (tee_local $8 + (i64.load8_u offset=8 + (get_local $0) + ) + ) + ) + ) + ) + (set_local $9 + (i64.add + (get_local $8) + (i64.const 1) + ) + ) + (set_local $7 + (i64.const 1) + ) + (loop $label$1 + (set_local $7 + (i64.mul + (get_local $7) + (i64.const 10) + ) + ) + (br_if $label$1 + (i64.gt_s + (tee_local $9 + (i64.add + (get_local $9) + (i64.const -1) + ) + ) + (i64.const 1) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $2) + (i32.and + (i32.add + (i32.wrap/i64 + (i64.add + (get_local $8) + (i64.const 1) + ) + ) + (i32.const 15) + ) + (i32.const 1008) + ) + ) + ) + ) + (i32.store8 + (tee_local $6 + (i32.add + (get_local $2) + (tee_local $3 + (i32.wrap/i64 + (get_local $8) + ) + ) + ) + ) + (i32.const 0) + ) + (set_local $4 + (i64.load + (get_local $0) + ) + ) + (block $label$2 + (br_if $label$2 + (get_local $5) + ) + (set_local $8 + (i64.add + (get_local $8) + (i64.const 1) + ) + ) + (set_local $9 + (i64.rem_s + (get_local $4) + (get_local $7) + ) + ) + (set_local $0 + (i32.add + (get_local $6) + (i32.const -1) + ) + ) + (loop $label$3 + (i64.store8 + (get_local $0) + (i64.add + (i64.rem_s + (get_local $9) + (i64.const 10) + ) + (i64.const 48) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const -1) + ) + ) + (set_local $9 + (i64.div_s + (get_local $9) + (i64.const 10) + ) + ) + (br_if $label$3 + (i64.gt_s + (tee_local $8 + (i64.add + (get_local $8) + (i64.const -1) + ) + ) + (i64.const 1) + ) + ) + ) + ) + (call $printi + (i64.div_s + (get_local $4) + (get_local $7) + ) + ) + (call $prints + (i32.const 2352) + ) + (call $prints_l + (get_local $2) + (get_local $3) + ) + (call $prints + (i32.const 2368) + ) + (call $_ZNK5eosio11symbol_type5printEb + (get_local $1) + (i32.const 0) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $10) + ) + ) + (func $_ZN5eosio8currency14issue_currencyERKNS0_5issueE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 80) + ) + ) + ) + (set_local $6 + (i64.load + (tee_local $3 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 72) + ) + (i32.const 0) + ) + (i64.store offset=56 + (get_local $7) + (i64.const -1) + ) + (i64.store offset=64 + (get_local $7) + (i64.const 0) + ) + (i64.store offset=40 + (get_local $7) + (i64.load + (get_local $0) + ) + ) + (i64.store offset=48 + (get_local $7) + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + ) + (set_local $2 + (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc + (i32.add + (get_local $7) + (i32.const 40) + ) + (get_local $6) + (i32.const 2224) + ) + ) + (i32.store offset=32 + (get_local $7) + (get_local $1) + ) + (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_14issue_currencyERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ + (i32.add + (get_local $7) + (i32.const 40) + ) + (get_local $2) + (i64.const 0) + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + (i32.store + (tee_local $4 + (i32.add + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 12) + ) + ) + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + ) + (i32.store + (tee_local $5 + (i32.add + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.load + (get_local $3) + ) + ) + (i32.store offset=20 + (get_local $7) + (i32.load + (i32.add + (get_local $1) + (i32.const 12) + ) + ) + ) + (i32.store offset=16 + (get_local $7) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i64.load offset=32 + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 12) + ) + (i32.load + (get_local $4) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.load + (get_local $5) + ) + ) + (i32.store offset=4 + (get_local $7) + (i32.load offset=20 + (get_local $7) + ) + ) + (i32.store + (get_local $7) + (i32.load offset=16 + (get_local $7) + ) + ) + (call $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy + (get_local $0) + (get_local $6) + (get_local $7) + (get_local $2) + (get_local $6) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $0 + (i32.load offset=64 + (get_local $7) + ) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.eq + (tee_local $1 + (i32.load + (tee_local $3 + (i32.add + (get_local $7) + (i32.const 68) + ) + ) + ) + ) + (get_local $0) + ) + ) + (loop $label$3 + (set_local $2 + (i32.load + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (block $label$4 + (br_if $label$4 + (i32.eqz + (get_local $2) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$3 + (i32.ne + (get_local $0) + (get_local $1) + ) + ) + ) + (set_local $1 + (i32.load + (i32.add + (get_local $7) + (i32.const 64) + ) + ) + ) + (br $label$1) + ) + (set_local $1 + (get_local $0) + ) + ) + (i32.store + (get_local $3) + (get_local $0) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 80) + ) + ) + ) + (func $_ZN5eosio12market_stateD2Ev (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 424) + ) + ) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.eq + (tee_local $4 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 428) + ) + ) + ) + ) + (get_local $1) + ) + ) + (loop $label$3 + (set_local $2 + (i32.load + (tee_local $4 + (i32.add + (get_local $4) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (block $label$4 + (br_if $label$4 + (i32.eqz + (get_local $2) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$3 + (i32.ne + (get_local $1) + (get_local $4) + ) + ) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $0) + (i32.const 424) + ) + ) + ) + (br $label$1) + ) + (set_local $4 + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (get_local $1) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 384) + ) + ) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.eq + (tee_local $4 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 388) + ) + ) + ) + ) + (get_local $1) + ) + ) + (loop $label$8 + (set_local $2 + (i32.load + (tee_local $4 + (i32.add + (get_local $4) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $2) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $1) + (get_local $4) + ) + ) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $0) + (i32.const 384) + ) + ) + ) + (br $label$6) + ) + (set_local $4 + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (get_local $1) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 344) + ) + ) + ) + ) + ) + (block $label$11 + (block $label$12 + (br_if $label$12 + (i32.eq + (tee_local $4 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 348) + ) + ) + ) + ) + (get_local $1) + ) + ) + (loop $label$13 + (set_local $2 + (i32.load + (tee_local $4 + (i32.add + (get_local $4) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (get_local $2) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$13 + (i32.ne + (get_local $1) + (get_local $4) + ) + ) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $0) + (i32.const 344) + ) + ) + ) + (br $label$11) + ) + (set_local $4 + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (get_local $1) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 304) + ) + ) + ) + ) + ) + (block $label$16 + (block $label$17 + (br_if $label$17 + (i32.eq + (tee_local $4 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 308) + ) + ) + ) + ) + (get_local $1) + ) + ) + (loop $label$18 + (set_local $2 + (i32.load + (tee_local $4 + (i32.add + (get_local $4) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (block $label$19 + (br_if $label$19 + (i32.eqz + (get_local $2) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$18 + (i32.ne + (get_local $1) + (get_local $4) + ) + ) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $0) + (i32.const 304) + ) + ) + ) + (br $label$16) + ) + (set_local $4 + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (get_local $1) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (block $label$20 + (br_if $label$20 + (i32.eqz + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 264) + ) + ) + ) + ) + ) + (block $label$21 + (block $label$22 + (br_if $label$22 + (i32.eq + (tee_local $4 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 268) + ) + ) + ) + ) + (get_local $1) + ) + ) + (loop $label$23 + (set_local $2 + (i32.load + (tee_local $4 + (i32.add + (get_local $4) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (block $label$24 + (br_if $label$24 + (i32.eqz + (get_local $2) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$23 + (i32.ne + (get_local $1) + (get_local $4) + ) + ) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $0) + (i32.const 264) + ) + ) + ) + (br $label$21) + ) + (set_local $4 + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (get_local $1) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (get_local $0) + ) + (func $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc (param $0 i32) (param $1 i64) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $3 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (set_local $4 + (i32.sub + (i32.const 0) + (get_local $3) + ) + ) + (loop $label$1 + (br_if $label$0 + (i64.eq + (i64.shr_u + (i64.load offset=8 + (i32.load + (get_local $6) + ) + ) + (i64.const 8) + ) + (get_local $1) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $5 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $5) + (get_local $4) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $3) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=48 + (tee_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (get_local $0) + ) + (i32.const 224) + ) + (br $label$2) + ) + (set_local $6 + (i32.const 0) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $5 + (call $db_find_i64 + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + (i64.const -4157508551318700032) + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=48 + (tee_local $6 + (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE31load_object_by_primary_iteratorEl + (get_local $0) + (get_local $5) + ) + ) + ) + (get_local $0) + ) + (i32.const 224) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $6) + (i32.const 0) + ) + (get_local $2) + ) + (get_local $6) + ) + (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_14issue_currencyERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $6 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=48 + (get_local $1) + ) + (get_local $0) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $0) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (i64.store + (get_local $1) + (tee_local $4 + (i64.add + (i64.load + (get_local $1) + ) + (i64.load offset=8 + (i32.load + (get_local $3) + ) + ) + ) + ) + ) + (set_local $5 + (i64.load offset=8 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.xor + (i32.wrap/i64 + (i64.shr_u + (get_local $4) + (i64.const 63) + ) + ) + (i32.const 1) + ) + (i32.const 1216) + ) + (call $eosio_assert + (i64.eq + (tee_local $4 + (i64.shr_u + (get_local $5) + (i64.const 8) + ) + ) + (i64.shr_u + (i64.load offset=8 + (get_local $1) + ) + (i64.const 8) + ) + ) + (i32.const 544) + ) + (i32.store offset=56 + (get_local $6) + (i32.add + (get_local $6) + (i32.const 45) + ) + ) + (i32.store offset=52 + (get_local $6) + (get_local $6) + ) + (i32.store offset=48 + (get_local $6) + (get_local $6) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE + (i32.add + (get_local $6) + (i32.const 48) + ) + (get_local $1) + ) + ) + (call $db_update_i64 + (i32.load offset=52 + (get_local $1) + ) + (get_local $2) + (get_local $6) + (i32.const 45) + ) + (block $label$0 + (br_if $label$0 + (i64.lt_u + (get_local $4) + (i64.load offset=16 + (get_local $0) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 64) + ) + ) + ) + (func $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i64) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 56) + ) + (i32.const 0) + ) + (i64.store offset=40 + (get_local $7) + (i64.const -1) + ) + (i64.store offset=48 + (get_local $7) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $7) + (tee_local $5 + (i64.load + (get_local $0) + ) + ) + ) + (i64.store offset=32 + (get_local $7) + (get_local $1) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.le_s + (tee_local $0 + (call $db_find_i64 + (get_local $5) + (get_local $1) + (i64.const 3607749779137757184) + (i64.shr_u + (i64.load offset=8 + (get_local $2) + ) + (i64.const 8) + ) + ) + ) + (i32.const -1) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=20 + (tee_local $0 + (call $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE31load_object_by_primary_iteratorEl + (i32.add + (get_local $7) + (i32.const 24) + ) + (get_local $0) + ) + ) + ) + (i32.add + (get_local $7) + (i32.const 24) + ) + ) + (i32.const 224) + ) + (call $eosio_assert + (select + (i32.load8_u offset=17 + (get_local $0) + ) + (i32.const 1) + (i32.load8_u offset=44 + (get_local $3) + ) + ) + (i32.const 2304) + ) + (i32.store offset=8 + (get_local $7) + (get_local $2) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 352) + ) + (call $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E0_EEvRKS2_yOS9_ + (i32.add + (get_local $7) + (i32.const 24) + ) + (get_local $0) + (i64.const 0) + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + (br_if $label$1 + (tee_local $3 + (i32.load offset=48 + (get_local $7) + ) + ) + ) + (br $label$0) + ) + (call $eosio_assert + (i32.xor + (i32.load8_u offset=44 + (get_local $3) + ) + (i32.const 1) + ) + (i32.const 2256) + ) + (i32.store offset=16 + (get_local $7) + (get_local $2) + ) + (call $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.add + (get_local $7) + (i32.const 24) + ) + (get_local $4) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.load offset=48 + (get_local $7) + ) + ) + ) + ) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.eq + (tee_local $2 + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const 52) + ) + ) + ) + ) + (get_local $3) + ) + ) + (loop $label$5 + (set_local $0 + (i32.load + (tee_local $2 + (i32.add + (get_local $2) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (block $label$6 + (br_if $label$6 + (i32.eqz + (get_local $0) + ) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (br_if $label$5 + (i32.ne + (get_local $3) + (get_local $2) + ) + ) + ) + (set_local $2 + (i32.load + (i32.add + (get_local $7) + (i32.const 48) + ) + ) + ) + (br $label$3) + ) + (set_local $2 + (get_local $3) + ) + ) + (i32.store + (get_local $6) + (get_local $3) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 64) + ) + ) + ) + (func $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i64.store offset=40 + (get_local $7) + (get_local $2) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $1) + ) + (call $current_receiver) + ) + (i32.const 288) + ) + (i32.store offset=20 + (get_local $7) + (get_local $3) + ) + (i32.store offset=16 + (get_local $7) + (get_local $1) + ) + (i32.store offset=24 + (get_local $7) + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + (i64.store offset=8 + (tee_local $4 + (call $_Znwj + (i32.const 32) + ) + ) + (i64.const 1398362884) + ) + (i64.store + (get_local $4) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $2 + (i64.const 5462355) + ) + (set_local $3 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $2) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $2 + (i64.shr_u + (get_local $2) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $2 + (i64.shr_u + (get_local $2) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $3 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $6 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $3 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $6 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 80) + ) + (i32.store offset=20 + (get_local $4) + (get_local $1) + ) + (i32.store16 offset=16 + (get_local $4) + (i32.const 256) + ) + (call $_ZZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ENKUlSA_E_clINS3_4itemEEEDaSA_ + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $4) + ) + (i32.store offset=32 + (get_local $7) + (get_local $4) + ) + (i64.store offset=16 + (get_local $7) + (tee_local $2 + (i64.shr_u + (i64.load + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + (i64.const 8) + ) + ) + ) + (i32.store offset=12 + (get_local $7) + (tee_local $6 + (i32.load offset=24 + (get_local $4) + ) + ) + ) + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.ge_u + (tee_local $3 + (i32.load + (tee_local $5 + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $3) + (get_local $2) + ) + (i32.store offset=16 + (get_local $3) + (get_local $6) + ) + (i32.store offset=32 + (get_local $7) + (i32.const 0) + ) + (i32.store + (get_local $3) + (get_local $4) + ) + (i32.store + (get_local $5) + (i32.add + (get_local $3) + (i32.const 24) + ) + ) + (br $label$5) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy3607749779137757184ENS1_8currency7accountEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.add + (get_local $7) + (i32.const 32) + ) + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store offset=4 + (get_local $0) + (get_local $4) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (set_local $3 + (i32.load offset=32 + (get_local $7) + ) + ) + (i32.store offset=32 + (get_local $7) + (i32.const 0) + ) + (block $label$7 + (br_if $label$7 + (i32.eqz + (get_local $3) + ) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 48) + ) + ) + ) + (func $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (local $9 i32) + (set_local $8 + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $9) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $2 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $2) + ) + ) + (set_local $5 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i32.eq + (i32.load + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + (set_local $6 + (get_local $5) + ) + (set_local $5 + (tee_local $4 + (i32.add + (get_local $5) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $4) + (get_local $3) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $6) + (get_local $2) + ) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i32.xor + (i32.shr_u + (tee_local $5 + (call $db_get_i64 + (get_local $1) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 31) + ) + (i32.const 1) + ) + (i32.const 656) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.lt_u + (get_local $5) + (i32.const 513) + ) + ) + (set_local $4 + (call $malloc + (get_local $5) + ) + ) + (br $label$4) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (get_local $9) + (i32.and + (i32.add + (get_local $5) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $db_get_i64 + (get_local $1) + (get_local $4) + (get_local $5) + ) + ) + (i32.store offset=36 + (get_local $8) + (get_local $4) + ) + (i32.store offset=32 + (get_local $8) + (get_local $4) + ) + (i32.store offset=40 + (get_local $8) + (i32.add + (get_local $4) + (get_local $5) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.lt_u + (get_local $5) + (i32.const 513) + ) + ) + (call $free + (get_local $4) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.store offset=8 + (tee_local $4 + (call $_Znwj + (i32.const 32) + ) + ) + (i64.const 1398362884) + ) + (i64.store + (get_local $4) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $7 + (i64.const 5462355) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$7 + (block $label$8 + (loop $label$9 + (br_if $label$8 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $7) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$10 + (br_if $label$10 + (i64.ne + (i64.and + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$11 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$11 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $6 + (i32.const 1) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$7) + ) + ) + (set_local $6 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 80) + ) + (i32.store offset=20 + (get_local $4) + (get_local $0) + ) + (i32.store16 offset=16 + (get_local $4) + (i32.const 256) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency7accountE + (i32.add + (get_local $8) + (i32.const 32) + ) + (get_local $4) + ) + ) + (i32.store offset=24 + (get_local $4) + (get_local $1) + ) + (i32.store offset=24 + (get_local $8) + (get_local $4) + ) + (i64.store offset=16 + (get_local $8) + (tee_local $7 + (i64.shr_u + (i64.load + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + (i64.const 8) + ) + ) + ) + (i32.store offset=12 + (get_local $8) + (tee_local $6 + (i32.load offset=24 + (get_local $4) + ) + ) + ) + (block $label$12 + (block $label$13 + (br_if $label$13 + (i32.ge_u + (tee_local $5 + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $5) + (get_local $7) + ) + (i32.store offset=16 + (get_local $5) + (get_local $6) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $5) + (get_local $4) + ) + (i32.store + (get_local $1) + (i32.add + (get_local $5) + (i32.const 24) + ) + ) + (br $label$12) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy3607749779137757184ENS1_8currency7accountEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ + (get_local $3) + (i32.add + (get_local $8) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 12) + ) + ) + ) + (set_local $5 + (i32.load offset=24 + (get_local $8) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $5) + ) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 48) + ) + ) + (get_local $4) + ) + (func $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E0_EEvRKS2_yOS9_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) + (local $4 i64) + (local $5 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $5 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + (get_local $0) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $0) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (i64.store + (get_local $1) + (i64.add + (i64.load + (get_local $1) + ) + (i64.load + (i32.load + (get_local $3) + ) + ) + ) + ) + (set_local $4 + (i64.load offset=8 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 544) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $1) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.or + (get_local $5) + (i32.const 8) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store8 offset=31 + (get_local $5) + (i32.load8_u offset=16 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $5) + (i32.const 16) + ) + (i32.add + (get_local $5) + (i32.const 31) + ) + (i32.const 1) + ) + ) + (i32.store8 offset=31 + (get_local $5) + (i32.load8_u offset=17 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $5) + (i32.const 17) + ) + (i32.add + (get_local $5) + (i32.const 31) + ) + (i32.const 1) + ) + ) + (call $db_update_i64 + (i32.load offset=24 + (get_local $1) + ) + (get_local $2) + (get_local $5) + (i32.const 18) + ) + (block $label$0 + (br_if $label$0 + (i64.lt_u + (tee_local $2 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.load offset=16 + (get_local $0) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.add + (get_local $2) + (i64.const 1) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $5) + (i32.const 32) + ) + ) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency7accountE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 14) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=16 + (get_local $1) + (i32.ne + (i32.load8_u offset=14 + (get_local $3) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store8 offset=17 + (get_local $1) + (i32.ne + (i32.load8_u offset=15 + (get_local $3) + ) + (i32.const 0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZNSt3__16vectorIN5eosio11multi_indexILy3607749779137757184ENS1_8currency7accountEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.add + (tee_local $4 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 24) + ) + ) + (i32.const 1) + ) + ) + (i32.const 178956971) + ) + ) + (set_local $7 + (i32.const 178956970) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $6 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $6) + ) + (i32.const 24) + ) + ) + (i32.const 89478484) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $5) + (tee_local $7 + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $5) + ) + ) + ) + ) + ) + ) + (set_local $6 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $5 + (i32.load + (get_local $1) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $6) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + (get_local $5) + ) + (i64.store offset=8 + (get_local $1) + (i64.load + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $1) + (i32.load + (get_local $3) + ) + ) + (set_local $4 + (i32.add + (get_local $6) + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (loop $label$6 + (set_local $3 + (i32.load + (tee_local $2 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -24) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -8) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -12) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -16) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const -24) + ) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$6 + (i32.ne + (get_local $7) + (get_local $2) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $6 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $5) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $6) + ) + ) + (loop $label$8 + (set_local $1 + (i32.load + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $6) + (get_local $7) + ) + ) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $_ZZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ENKUlSA_E_clINS3_4itemEEEDaSA_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $6 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (set_local $2 + (i32.load + (get_local $0) + ) + ) + (i64.store + (get_local $1) + (i64.load + (tee_local $4 + (i32.load + (i32.load offset=4 + (get_local $0) + ) + ) + ) + ) + ) + (i64.store + (tee_local $5 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (get_local $6) + (get_local $1) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.or + (get_local $6) + (i32.const 8) + ) + (get_local $5) + (i32.const 8) + ) + ) + (i32.store8 offset=31 + (get_local $6) + (i32.load8_u offset=16 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $6) + (i32.const 16) + ) + (i32.add + (get_local $6) + (i32.const 31) + ) + (i32.const 1) + ) + ) + (i32.store8 offset=31 + (get_local $6) + (i32.load8_u offset=17 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $6) + (i32.const 17) + ) + (i32.add + (get_local $6) + (i32.const 31) + ) + (i32.const 1) + ) + ) + (i32.store offset=24 + (get_local $1) + (call $db_store_i64 + (i64.load offset=8 + (get_local $2) + ) + (i64.const 3607749779137757184) + (i64.load + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $3 + (i64.shr_u + (i64.load + (get_local $5) + ) + (i64.const 8) + ) + ) + (get_local $6) + (i32.const 18) + ) + ) + (block $label$0 + (br_if $label$0 + (i64.lt_u + (get_local $3) + (i64.load offset=16 + (get_local $2) + ) + ) + ) + (i64.store + (i32.add + (get_local $2) + (i32.const 16) + ) + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 32) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (i32.store8 offset=11 + (get_local $3) + (i32.load8_u offset=40 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $3) + (i32.const 11) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=12 + (get_local $3) + (i32.load8_u offset=41 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $3) + (i32.const 12) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=13 + (get_local $3) + (i32.load8_u offset=42 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $3) + (i32.const 13) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=14 + (get_local $3) + (i32.load8_u offset=43 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $3) + (i32.const 14) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=15 + (get_local $3) + (i32.load8_u offset=44 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 0) + ) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (set_local $8 + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $9) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $2 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $2) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$1 + (br_if $label$0 + (i32.eq + (i32.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $4 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $4) + (get_local $3) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + (set_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + (br $label$2) + ) + (call $eosio_assert + (i32.xor + (i32.shr_u + (tee_local $6 + (call $db_get_i64 + (get_local $1) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 31) + ) + (i32.const 1) + ) + (i32.const 656) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.lt_u + (get_local $6) + (i32.const 513) + ) + ) + (set_local $4 + (call $malloc + (get_local $6) + ) + ) + (br $label$4) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (get_local $9) + (i32.and + (i32.add + (get_local $6) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $db_get_i64 + (get_local $1) + (get_local $4) + (get_local $6) + ) + ) + (i32.store offset=36 + (get_local $8) + (get_local $4) + ) + (i32.store offset=32 + (get_local $8) + (get_local $4) + ) + (i32.store offset=40 + (get_local $8) + (i32.add + (get_local $4) + (get_local $6) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.lt_u + (get_local $6) + (i32.const 513) + ) + ) + (call $free + (get_local $4) + ) + ) + (set_local $4 + (call $_ZN5eosio8currency14currency_statsC2Ev + (tee_local $6 + (call $_Znwj + (i32.const 64) + ) + ) + ) + ) + (i32.store offset=48 + (get_local $6) + (get_local $0) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency14currency_statsE + (i32.add + (get_local $8) + (i32.const 32) + ) + (get_local $4) + ) + ) + (i32.store offset=52 + (get_local $6) + (get_local $1) + ) + (i32.store offset=24 + (get_local $8) + (get_local $6) + ) + (i64.store offset=16 + (get_local $8) + (tee_local $5 + (i64.shr_u + (i64.load offset=8 + (get_local $6) + ) + (i64.const 8) + ) + ) + ) + (i32.store offset=12 + (get_local $8) + (tee_local $7 + (i32.load offset=52 + (get_local $6) + ) + ) + ) + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ge_u + (tee_local $4 + (i32.load + (tee_local $1 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $4) + (get_local $5) + ) + (i32.store offset=16 + (get_local $4) + (get_local $7) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $4) + (get_local $6) + ) + (i32.store + (get_local $1) + (i32.add + (get_local $4) + (i32.const 24) + ) + ) + (br $label$7) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy14289235522390851584ENS1_8currency14currency_statsEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 24) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 12) + ) + ) + ) + (set_local $4 + (i32.load offset=24 + (get_local $8) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (br_if $label$2 + (i32.eqz + (get_local $4) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 48) + ) + ) + (get_local $6) + ) + (func $_ZN5eosio8currency14currency_statsC2Ev (param $0 i32) (result i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (i64.store offset=8 + (get_local $0) + (i64.const 1398362884) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load offset=8 + (get_local $0) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 1398362884) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$5 + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i32.store8 offset=44 + (get_local $0) + (i32.const 0) + ) + (i32.store offset=40 + (get_local $0) + (i32.const 65793) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency14currency_statsE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 11) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=40 + (get_local $1) + (i32.ne + (i32.load8_u offset=11 + (get_local $3) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 12) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=41 + (get_local $1) + (i32.ne + (i32.load8_u offset=12 + (get_local $3) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 13) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=42 + (get_local $1) + (i32.ne + (i32.load8_u offset=13 + (get_local $3) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 14) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (i32.store8 offset=43 + (get_local $1) + (i32.ne + (i32.load8_u offset=14 + (get_local $3) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store8 offset=44 + (get_local $1) + (i32.ne + (i32.load8_u offset=15 + (get_local $3) + ) + (i32.const 0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZNSt3__16vectorIN5eosio11multi_indexILy14289235522390851584ENS1_8currency14currency_statsEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.add + (tee_local $4 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 24) + ) + ) + (i32.const 1) + ) + ) + (i32.const 178956971) + ) + ) + (set_local $7 + (i32.const 178956970) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $6 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $6) + ) + (i32.const 24) + ) + ) + (i32.const 89478484) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $5) + (tee_local $7 + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $5) + ) + ) + ) + ) + ) + ) + (set_local $6 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $5 + (i32.load + (get_local $1) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $6) + (i32.mul + (get_local $4) + (i32.const 24) + ) + ) + ) + (get_local $5) + ) + (i64.store offset=8 + (get_local $1) + (i64.load + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $1) + (i32.load + (get_local $3) + ) + ) + (set_local $4 + (i32.add + (get_local $6) + (i32.mul + (get_local $7) + (i32.const 24) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (loop $label$6 + (set_local $3 + (i32.load + (tee_local $2 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -24) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -8) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -12) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const -16) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const -24) + ) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$6 + (i32.ne + (get_local $7) + (get_local $2) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $6 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $5) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $6) + ) + ) + (loop $label$8 + (set_local $1 + (i32.load + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $6) + (get_local $7) + ) + ) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $_ZN5eosio8exchange2onERKNS0_8upmarginE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 576) + ) + ) + ) + (call $require_auth + (i64.load + (get_local $1) + ) + ) + (set_local $9 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (i64.load offset=16 + (get_local $1) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $6 + (i64.shr_u + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (i64.const 8) + ) + ) + (set_local $7 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $6) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $8 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $8 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $8) + (i32.const 2384) + ) + (set_local $2 + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + (block $label$5 + (br_if $label$5 + (i64.gt_u + (i64.add + (i64.load offset=40 + (get_local $1) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $6 + (i64.shr_u + (i64.load + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + (i64.const 8) + ) + ) + (set_local $7 + (i32.const 0) + ) + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $6) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $9 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $9 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $9) + (i32.const 2416) + ) + (i64.store offset=120 + (get_local $10) + (i64.shr_u + (i64.load offset=8 + (get_local $1) + ) + (i64.const 8) + ) + ) + (set_local $6 + (i64.load + (get_local $0) + ) + ) + (set_local $7 + (call $_ZN5eosio14exchange_stateC2Ev + (i32.add + (get_local $10) + (i32.const 128) + ) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 376) + ) + (i64.const -1) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 384) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 392) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 368) + ) + (tee_local $3 + (i64.load offset=120 + (get_local $10) + ) + ) + ) + (i64.store offset=360 + (get_local $10) + (get_local $6) + ) + (i64.store offset=400 + (get_local $10) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 408) + ) + (tee_local $5 + (i64.or + (tee_local $4 + (i64.shl + (get_local $3) + (i64.const 4) + ) + ) + (i64.const 1) + ) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 416) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 424) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 428) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 432) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $10) + (i32.const 436) + ) + (i32.const 0) + ) + (i64.store offset=440 + (get_local $10) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 448) + ) + (tee_local $4 + (i64.or + (get_local $4) + (i64.const 2) + ) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 456) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 464) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 468) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 472) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $10) + (i32.const 476) + ) + (i32.const 0) + ) + (i64.store offset=480 + (get_local $10) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 488) + ) + (get_local $5) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 496) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 504) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 508) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 512) + ) + (i32.const 0) + ) + (i64.store offset=520 + (get_local $10) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 528) + ) + (get_local $4) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 536) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 544) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 548) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 552) + ) + (i32.const 0) + ) + (i32.store offset=560 + (get_local $10) + (tee_local $8 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy + (i32.add + (get_local $10) + (i32.const 564) + ) + (i32.add + (get_local $10) + (i32.const 360) + ) + (get_local $3) + ) + (call $eosio_assert + (i32.ne + (i32.load + (tee_local $9 + (i32.add + (get_local $10) + (i32.const 568) + ) + ) + ) + (i32.const 0) + ) + (i32.const 720) + ) + (drop + (call $memcpy + (get_local $7) + (i32.load + (get_local $9) + ) + (i32.const 232) + ) + ) + (call $eosio_assert + (i64.ne + (i64.or + (i64.load + (get_local $2) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i64.const 0) + ) + (i32.const 2448) + ) + (call $eosio_assert + (i32.or + (i64.ne + (i64.load + (tee_local $7 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + ) + (i64.ne + (i64.load + (tee_local $9 + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + ) + ) + (i32.const 2464) + ) + (set_local $6 + (i64.load + (get_local $9) + ) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.ne + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 120) + ) + (i32.const 56) + ) + ) + (tee_local $3 + (i64.load + (get_local $7) + ) + ) + ) + ) + (br_if $label$11 + (i64.ne + (i64.load + (i32.add + (get_local $10) + (i32.const 184) + ) + ) + (get_local $6) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2480) + ) + (br $label$10) + ) + (call $eosio_assert + (i32.and + (i64.eq + (i64.load + (i32.add + (get_local $10) + (i32.const 272) + ) + ) + (get_local $3) + ) + (i64.eq + (i64.load + (i32.add + (get_local $10) + (i32.const 280) + ) + ) + (get_local $6) + ) + ) + (i32.const 2480) + ) + ) + (set_local $6 + (i64.load + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + ) + (block $label$12 + (block $label$13 + (br_if $label$13 + (i64.ne + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 120) + ) + (i32.const 56) + ) + ) + (tee_local $3 + (i64.load + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + ) + ) + ) + (br_if $label$13 + (i64.ne + (i64.load + (i32.add + (get_local $10) + (i32.const 184) + ) + ) + (get_local $6) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2480) + ) + (br $label$12) + ) + (call $eosio_assert + (i32.and + (i64.eq + (i64.load + (i32.add + (get_local $10) + (i32.const 272) + ) + ) + (get_local $3) + ) + (i64.eq + (i64.load + (i32.add + (get_local $10) + (i32.const 280) + ) + ) + (get_local $6) + ) + ) + (i32.const 2480) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + (set_local $6 + (i64.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + (set_local $3 + (i64.load + (get_local $1) + ) + ) + (block $label$14 + (block $label$15 + (br_if $label$15 + (i64.ne + (tee_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const 176) + ) + ) + ) + ) + (br_if $label$15 + (i64.ne + (get_local $6) + (i64.load + (i32.add + (get_local $10) + (i32.const 184) + ) + ) + ) + ) + (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ + (i32.add + (get_local $10) + (i32.const 120) + ) + (get_local $3) + (i32.add + (get_local $10) + (i32.const 400) + ) + (i32.add + (get_local $10) + (i32.const 168) + ) + (get_local $7) + (get_local $2) + ) + (br $label$14) + ) + (block $label$16 + (br_if $label$16 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $10) + (i32.const 272) + ) + ) + ) + ) + (br_if $label$16 + (i64.ne + (get_local $6) + (i64.load + (i32.add + (get_local $10) + (i32.const 280) + ) + ) + ) + ) + (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ + (i32.add + (get_local $10) + (i32.const 120) + ) + (get_local $3) + (i32.add + (get_local $10) + (i32.const 440) + ) + (i32.add + (get_local $10) + (i32.const 264) + ) + (get_local $7) + (get_local $2) + ) + (br $label$14) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1376) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 96) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 20) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 96) + ) + (i32.const 16) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 96) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 96) + ) + (i32.const 8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=96 + (get_local $10) + (i32.load + (get_local $7) + ) + ) + (i32.store offset=100 + (get_local $10) + (i32.load + (i32.add + (get_local $7) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i64.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 80) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=80 + (get_local $10) + (i64.const 0) + ) + (block $label$17 + (block $label$18 + (br_if $label$18 + (i32.ge_u + (tee_local $7 + (call $strlen + (i32.const 2512) + ) + ) + (i32.const -16) + ) + ) + (block $label$19 + (block $label$20 + (block $label$21 + (br_if $label$21 + (i32.ge_u + (get_local $7) + (i32.const 11) + ) + ) + (i32.store8 offset=80 + (get_local $10) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + (set_local $9 + (i32.or + (i32.add + (get_local $10) + (i32.const 80) + ) + (i32.const 1) + ) + ) + (br_if $label$20 + (get_local $7) + ) + (br $label$19) + ) + (set_local $9 + (call $_Znwj + (tee_local $0 + (i32.and + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=80 + (get_local $10) + (i32.or + (get_local $0) + (i32.const 1) + ) + ) + (i32.store offset=88 + (get_local $10) + (get_local $9) + ) + (i32.store offset=84 + (get_local $10) + (get_local $7) + ) + ) + (drop + (call $memcpy + (get_local $9) + (i32.const 2512) + (get_local $7) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $9) + (get_local $7) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 32) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 96) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 32) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 96) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=32 + (get_local $10) + (i64.load offset=96 + (get_local $10) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $8) + (get_local $6) + (i32.add + (get_local $10) + (i32.const 32) + ) + (get_local $10) + ) + (block $label$22 + (br_if $label$22 + (i32.eqz + (i32.and + (i32.load8_u offset=80 + (get_local $10) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=88 + (get_local $10) + ) + ) + ) + (i64.store offset=64 + (get_local $10) + (i64.load + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + ) + (i64.store offset=56 + (get_local $10) + (i64.sub + (i64.const 0) + (i64.load + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + ) + ) + (set_local $6 + (i64.load + (get_local $1) + ) + ) + (i64.store offset=72 + (get_local $10) + (i64.load + (i32.add + (get_local $1) + (i32.const 56) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $10) + (i32.const 80) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=80 + (get_local $10) + (i64.const 0) + ) + (br_if $label$17 + (i32.ge_u + (tee_local $7 + (call $strlen + (i32.const 2528) + ) + ) + (i32.const -16) + ) + ) + (block $label$23 + (block $label$24 + (block $label$25 + (br_if $label$25 + (i32.ge_u + (get_local $7) + (i32.const 11) + ) + ) + (i32.store8 offset=80 + (get_local $10) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + (set_local $1 + (i32.or + (i32.add + (get_local $10) + (i32.const 80) + ) + (i32.const 1) + ) + ) + (br_if $label$24 + (get_local $7) + ) + (br $label$23) + ) + (set_local $1 + (call $_Znwj + (tee_local $9 + (i32.and + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=80 + (get_local $10) + (i32.or + (get_local $9) + (i32.const 1) + ) + ) + (i32.store offset=88 + (get_local $10) + (get_local $1) + ) + (i32.store offset=84 + (get_local $10) + (get_local $7) + ) + ) + (drop + (call $memcpy + (get_local $1) + (i32.const 2528) + (get_local $7) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $1) + (get_local $7) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 8) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 56) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 8) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 56) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=8 + (get_local $10) + (i64.load offset=56 + (get_local $10) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $8) + (get_local $6) + (i32.add + (get_local $10) + (i32.const 8) + ) + (get_local $10) + ) + (block $label$26 + (br_if $label$26 + (i32.eqz + (i32.and + (i32.load8_u offset=80 + (get_local $10) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=88 + (get_local $10) + ) + ) + ) + (call $_ZN5eosio12market_state4saveEv + (i32.add + (get_local $10) + (i32.const 120) + ) + ) + (drop + (call $_ZN5eosio12market_stateD2Ev + (i32.add + (get_local $10) + (i32.const 120) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 576) + ) + ) + (return) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $10) + (i32.const 80) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $10) + (i32.const 80) + ) + ) + (unreachable) + ) + (func $_ZN5eosio8exchange2onERKNS0_11covermarginE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 464) + ) + ) + ) + (call $require_auth + (i64.load + (get_local $1) + ) + ) + (set_local $2 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + (set_local $8 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (i64.load offset=16 + (get_local $1) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $6 + (i64.shr_u + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (i64.const 8) + ) + ) + (set_local $7 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $6) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $8 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $8 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $8) + (i32.const 2544) + ) + (call $eosio_assert + (i64.gt_s + (i64.load + (get_local $2) + ) + (i64.const 0) + ) + (i32.const 2576) + ) + (i64.store offset=8 + (get_local $9) + (i64.shr_u + (i64.load offset=8 + (get_local $1) + ) + (i64.const 8) + ) + ) + (set_local $6 + (i64.load + (get_local $0) + ) + ) + (set_local $7 + (call $_ZN5eosio14exchange_stateC2Ev + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 264) + ) + (i64.const -1) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 272) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 280) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 256) + ) + (tee_local $3 + (i64.load offset=8 + (get_local $9) + ) + ) + ) + (i64.store offset=248 + (get_local $9) + (get_local $6) + ) + (i64.store offset=288 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 296) + ) + (tee_local $5 + (i64.or + (tee_local $4 + (i64.shl + (get_local $3) + (i64.const 4) + ) + ) + (i64.const 1) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 304) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 312) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 316) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 320) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $9) + (i32.const 324) + ) + (i32.const 0) + ) + (i64.store offset=328 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 336) + ) + (tee_local $4 + (i64.or + (get_local $4) + (i64.const 2) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 344) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 352) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 356) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 360) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $9) + (i32.const 364) + ) + (i32.const 0) + ) + (i64.store offset=368 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 376) + ) + (get_local $5) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 384) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 392) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 396) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 400) + ) + (i32.const 0) + ) + (i64.store offset=408 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 416) + ) + (get_local $4) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 424) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 432) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 436) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 440) + ) + (i32.const 0) + ) + (i32.store offset=448 + (get_local $9) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy + (i32.add + (get_local $9) + (i32.const 452) + ) + (i32.add + (get_local $9) + (i32.const 248) + ) + (get_local $3) + ) + (call $eosio_assert + (i32.ne + (i32.load + (tee_local $8 + (i32.add + (get_local $9) + (i32.const 456) + ) + ) + ) + (i32.const 0) + ) + (i32.const 720) + ) + (drop + (call $memcpy + (get_local $7) + (i32.load + (get_local $8) + ) + (i32.const 232) + ) + ) + (set_local $6 + (i64.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + (set_local $3 + (i64.load + (get_local $1) + ) + ) + (block $label$5 + (block $label$6 + (br_if $label$6 + (i64.ne + (tee_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (i64.load + (i32.add + (get_local $9) + (i32.const 64) + ) + ) + ) + ) + (br_if $label$6 + (i64.ne + (get_local $6) + (i64.load + (i32.add + (get_local $9) + (i32.const 72) + ) + ) + ) + ) + (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE + (i32.add + (get_local $9) + (i32.const 8) + ) + (get_local $3) + (i32.add + (get_local $9) + (i32.const 288) + ) + (i32.add + (get_local $9) + (i32.const 56) + ) + (get_local $2) + ) + (br $label$5) + ) + (block $label$7 + (br_if $label$7 + (i64.ne + (get_local $4) + (i64.load + (i32.add + (get_local $9) + (i32.const 160) + ) + ) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $6) + (i64.load + (i32.add + (get_local $9) + (i32.const 168) + ) + ) + ) + ) + (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE + (i32.add + (get_local $9) + (i32.const 8) + ) + (get_local $3) + (i32.add + (get_local $9) + (i32.const 328) + ) + (i32.add + (get_local $9) + (i32.const 152) + ) + (get_local $2) + ) + (br $label$5) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1376) + ) + ) + (call $_ZN5eosio12market_state4saveEv + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosio12market_stateD2Ev + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 464) + ) + ) + ) + (func $_ZN5eosio8exchange7createxEyNS_5assetEmNS_14extended_assetES2_ (type $FUNCSIG$vijiiii) (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i64) + (local $12 i32) + (local $13 i32) + (local $14 i64) + (local $15 i32) + (local $16 i32) + (local $17 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $17 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 464) + ) + ) + ) + (call $require_auth + (get_local $1) + ) + (set_local $16 + (i32.const 0) + ) + (set_local $13 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (tee_local $6 + (i64.load + (get_local $2) + ) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $14 + (i64.shr_u + (i64.load offset=8 + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $15 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $14) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $13 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $13 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $13) + (i32.const 2608) + ) + (call $eosio_assert + (i64.gt_s + (get_local $6) + (i64.const 0) + ) + (i32.const 2640) + ) + (block $label$5 + (br_if $label$5 + (i64.gt_u + (i64.add + (tee_local $6 + (i64.load + (get_local $4) + ) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $14 + (i64.shr_u + (i64.load offset=8 + (get_local $4) + ) + (i64.const 8) + ) + ) + (set_local $15 + (i32.const 0) + ) + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $14) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $16 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $16 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $16) + (i32.const 2672) + ) + (call $eosio_assert + (i64.gt_s + (get_local $6) + (i64.const 0) + ) + (i32.const 2704) + ) + (set_local $6 + (i64.load offset=8 + (get_local $5) + ) + ) + (set_local $13 + (i32.const 0) + ) + (set_local $16 + (i32.const 0) + ) + (block $label$10 + (br_if $label$10 + (i64.gt_u + (i64.add + (tee_local $7 + (i64.load + (get_local $5) + ) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $14 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (set_local $15 + (i32.const 0) + ) + (block $label$11 + (loop $label$12 + (br_if $label$11 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $14) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$13 + (br_if $label$13 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$14 + (br_if $label$11 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$14 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $16 + (i32.const 1) + ) + (br_if $label$12 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$10) + ) + ) + (set_local $16 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $16) + (i32.const 2736) + ) + (call $eosio_assert + (i64.gt_s + (get_local $7) + (i64.const 0) + ) + (i32.const 2768) + ) + (call $eosio_assert + (i32.or + (i64.ne + (tee_local $14 + (i64.load offset=8 + (get_local $4) + ) + ) + (get_local $6) + ) + (i64.ne + (tee_local $7 + (i64.load offset=16 + (get_local $4) + ) + ) + (tee_local $8 + (i64.load offset=16 + (get_local $5) + ) + ) + ) + ) + (i32.const 2800) + ) + (i64.store offset=216 + (get_local $17) + (get_local $7) + ) + (i64.store offset=208 + (get_local $17) + (get_local $14) + ) + (call $prints + (i32.const 2848) + ) + (call $_ZNK5eosio11symbol_type5printEb + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 1) + ) + (call $prints + (i32.const 1280) + ) + (call $printn + (i64.load offset=216 + (get_local $17) + ) + ) + (i64.store offset=216 + (get_local $17) + (get_local $8) + ) + (i64.store offset=208 + (get_local $17) + (get_local $6) + ) + (call $prints + (i32.const 2864) + ) + (call $_ZNK5eosio11symbol_type5printEb + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 1) + ) + (call $prints + (i32.const 1280) + ) + (call $printn + (i64.load offset=216 + (get_local $17) + ) + ) + (set_local $9 + (i64.load offset=8 + (get_local $2) + ) + ) + (call $prints + (i32.const 2880) + ) + (call $printui + (tee_local $10 + (i64.shr_u + (get_local $9) + (i64.const 8) + ) + ) + ) + (call $prints + (i32.const 2896) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 200) + ) + (i32.const 0) + ) + (i64.store offset=176 + (get_local $17) + (get_local $10) + ) + (i64.store offset=184 + (get_local $17) + (i64.const -1) + ) + (i64.store offset=192 + (get_local $17) + (i64.const 0) + ) + (i64.store offset=168 + (get_local $17) + (tee_local $11 + (i64.load + (get_local $0) + ) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.lt_s + (tee_local $15 + (call $db_find_i64 + (get_local $11) + (get_local $10) + (i64.const -7949128877345865728) + (get_local $10) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=232 + (tee_local $13 + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE31load_object_by_primary_iteratorEl + (i32.add + (get_local $17) + (i32.const 168) + ) + (get_local $15) + ) + ) + ) + (i32.add + (get_local $17) + (i32.const 168) + ) + ) + (i32.const 224) + ) + ) + (call $eosio_assert + (i32.eqz + (get_local $13) + ) + (i32.const 2912) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=168 + (get_local $17) + ) + (call $current_receiver) + ) + (i32.const 288) + ) + (set_local $16 + (call $_ZN5eosio14exchange_stateC2Ev + (tee_local $15 + (call $_Znwj + (i32.const 248) + ) + ) + ) + ) + (i32.store offset=232 + (get_local $15) + (i32.add + (get_local $17) + (i32.const 168) + ) + ) + (i64.store + (get_local $15) + (get_local $1) + ) + (i64.store + (tee_local $13 + (i32.add + (i32.add + (get_local $17) + (i32.const 432) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i64.store offset=432 + (get_local $17) + (i64.load + (get_local $2) + ) + ) + (set_local $10 + (i64.load + (get_local $0) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 8) + ) + (tee_local $11 + (i64.load + (get_local $13) + ) + ) + ) + (i64.store + (tee_local $13 + (i32.add + (i32.add + (get_local $17) + (i32.const 448) + ) + (i32.const 8) + ) + ) + (get_local $11) + ) + (i64.store offset=208 + (get_local $17) + (tee_local $11 + (i64.load offset=432 + (get_local $17) + ) + ) + ) + (i64.store offset=448 + (get_local $17) + (get_local $11) + ) + (i64.store offset=24 + (get_local $15) + (get_local $10) + ) + (i64.store offset=16 + (get_local $15) + (i64.load + (get_local $13) + ) + ) + (i64.store offset=8 + (get_local $15) + (i64.load offset=448 + (get_local $17) + ) + ) + (i64.store + (i32.add + (get_local $15) + (i32.const 56) + ) + (i64.load + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $15) + (i32.const 48) + ) + (i64.load + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + ) + (i64.store offset=40 + (get_local $15) + (i64.load + (get_local $4) + ) + ) + (i64.store + (i32.add + (get_local $15) + (i32.const 152) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $15) + (i32.const 144) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i64.store offset=136 + (get_local $15) + (i64.load + (get_local $5) + ) + ) + (i64.store offset=104 + (get_local $15) + (get_local $14) + ) + (i64.store offset=112 + (get_local $15) + (get_local $7) + ) + (i64.store offset=80 + (get_local $15) + (get_local $14) + ) + (i64.store offset=88 + (get_local $15) + (get_local $7) + ) + (i64.store offset=200 + (get_local $15) + (get_local $6) + ) + (i64.store offset=208 + (get_local $15) + (get_local $8) + ) + (i64.store offset=176 + (get_local $15) + (get_local $6) + ) + (i64.store offset=184 + (get_local $15) + (get_local $8) + ) + (i32.store offset=456 + (get_local $17) + (i32.add + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 220) + ) + ) + (i32.store offset=452 + (get_local $17) + (i32.add + (get_local $17) + (i32.const 208) + ) + ) + (i32.store offset=448 + (get_local $17) + (i32.add + (get_local $17) + (i32.const 208) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_stateE + (i32.add + (get_local $17) + (i32.const 448) + ) + (get_local $16) + ) + ) + (i32.store offset=236 + (get_local $15) + (tee_local $13 + (call $db_store_i64 + (i64.load + (i32.add + (i32.add + (get_local $17) + (i32.const 168) + ) + (i32.const 8) + ) + ) + (i64.const -7949128877345865728) + (get_local $1) + (tee_local $14 + (i64.shr_u + (i64.load offset=16 + (get_local $15) + ) + (i64.const 8) + ) + ) + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 220) + ) + ) + ) + (block $label$16 + (br_if $label$16 + (i64.lt_u + (get_local $14) + (i64.load + (tee_local $16 + (i32.add + (i32.add + (get_local $17) + (i32.const 168) + ) + (i32.const 16) + ) + ) + ) + ) + ) + (i64.store + (get_local $16) + (i64.add + (get_local $14) + (i64.const 1) + ) + ) + ) + (i32.store offset=448 + (get_local $17) + (get_local $15) + ) + (i64.store offset=208 + (get_local $17) + (tee_local $14 + (i64.shr_u + (i64.load + (i32.add + (get_local $15) + (i32.const 16) + ) + ) + (i64.const 8) + ) + ) + ) + (i32.store offset=432 + (get_local $17) + (get_local $13) + ) + (block $label$17 + (block $label$18 + (br_if $label$18 + (i32.ge_u + (tee_local $16 + (i32.load + (tee_local $12 + (i32.add + (get_local $17) + (i32.const 196) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $17) + (i32.const 200) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $16) + (get_local $14) + ) + (i32.store offset=16 + (get_local $16) + (get_local $13) + ) + (i32.store offset=448 + (get_local $17) + (i32.const 0) + ) + (i32.store + (get_local $16) + (get_local $15) + ) + (i32.store + (get_local $12) + (i32.add + (get_local $16) + (i32.const 24) + ) + ) + (br $label$17) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497615196363685888ENS1_14exchange_stateEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $17) + (i32.const 192) + ) + (i32.add + (get_local $17) + (i32.const 448) + ) + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.add + (get_local $17) + (i32.const 432) + ) + ) + ) + (set_local $16 + (i32.load offset=448 + (get_local $17) + ) + ) + (set_local $15 + (i32.const 0) + ) + (i32.store offset=448 + (get_local $17) + (i32.const 0) + ) + (block $label$19 + (br_if $label$19 + (i32.eqz + (get_local $16) + ) + ) + (call $_ZdlPv + (get_local $16) + ) + ) + (i64.store + (tee_local $16 + (i32.add + (get_local $17) + (i32.const 224) + ) + ) + (get_local $9) + ) + (i64.store offset=216 + (get_local $17) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $17) + (i64.load + (get_local $0) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $13 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $14 + (i64.shr_u + (i64.load + (get_local $16) + ) + (i64.const 8) + ) + ) + (block $label$20 + (block $label$21 + (loop $label$22 + (br_if $label$21 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $14) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$23 + (br_if $label$23 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$24 + (br_if $label$21 + (i64.ne + (i64.and + (tee_local $14 + (i64.shr_u + (get_local $14) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$24 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $16 + (i32.const 1) + ) + (br_if $label$22 + (i32.lt_s + (tee_local $15 + (i32.add + (get_local $15) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$20) + ) + ) + (set_local $16 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $16) + (i32.const 80) + ) + (i32.store8 offset=234 + (get_local $17) + (i32.const 0) + ) + (i32.store16 offset=232 + (get_local $17) + (i32.const 0) + ) + (call $_ZN5eosio8currency15create_currencyERKNS0_6createE + (get_local $13) + (i32.add + (get_local $17) + (i32.const 208) + ) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 228) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 224) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (i64.store offset=208 + (get_local $17) + (i64.load + (get_local $0) + ) + ) + (i32.store offset=216 + (get_local $17) + (i32.load + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 240) + ) + (i32.const 0) + ) + (i64.store offset=232 + (get_local $17) + (i64.const 0) + ) + (set_local $16 + (i32.add + (get_local $17) + (i32.const 232) + ) + ) + (block $label$25 + (block $label$26 + (block $label$27 + (block $label$28 + (br_if $label$28 + (i32.ge_u + (tee_local $15 + (call $strlen + (i32.const 2944) + ) + ) + (i32.const -16) + ) + ) + (block $label$29 + (block $label$30 + (block $label$31 + (br_if $label$31 + (i32.ge_u + (get_local $15) + (i32.const 11) + ) + ) + (i32.store8 + (i32.add + (get_local $17) + (i32.const 232) + ) + (i32.shl + (get_local $15) + (i32.const 1) + ) + ) + (set_local $16 + (i32.add + (get_local $16) + (i32.const 1) + ) + ) + (br_if $label$30 + (get_local $15) + ) + (br $label$29) + ) + (set_local $16 + (call $_Znwj + (tee_local $12 + (i32.and + (i32.add + (get_local $15) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 232) + ) + (i32.or + (get_local $12) + (i32.const 1) + ) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 240) + ) + (get_local $16) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 236) + ) + (get_local $15) + ) + ) + (drop + (call $memcpy + (get_local $16) + (i32.const 2944) + (get_local $15) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $16) + (get_local $15) + ) + (i32.const 0) + ) + (call $_ZN5eosio8currency14issue_currencyERKNS0_5issueE + (get_local $13) + (i32.add + (get_local $17) + (i32.const 208) + ) + ) + (block $label$32 + (br_if $label$32 + (i32.eqz + (i32.and + (i32.load8_u + (i32.add + (get_local $17) + (i32.const 232) + ) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $17) + (i32.const 240) + ) + ) + ) + ) + (i64.store + (tee_local $15 + (i32.add + (i32.add + (get_local $17) + (i32.const 128) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i64.store offset=128 + (get_local $17) + (i64.load + (get_local $2) + ) + ) + (set_local $14 + (i64.load + (get_local $0) + ) + ) + (i64.store + (tee_local $2 + (i32.add + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 8) + ) + ) + (tee_local $6 + (i64.load + (get_local $15) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 144) + ) + (i32.const 8) + ) + (get_local $6) + ) + (i64.store offset=208 + (get_local $17) + (tee_local $6 + (i64.load offset=128 + (get_local $17) + ) + ) + ) + (i64.store offset=144 + (get_local $17) + (get_local $6) + ) + (i64.store offset=160 + (get_local $17) + (get_local $14) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (i64.store offset=208 + (get_local $17) + (i64.const 0) + ) + (br_if $label$27 + (i32.ge_u + (tee_local $15 + (call $strlen + (i32.const 2976) + ) + ) + (i32.const -16) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (block $label$33 + (block $label$34 + (block $label$35 + (br_if $label$35 + (i32.ge_u + (get_local $15) + (i32.const 11) + ) + ) + (i32.store8 offset=208 + (get_local $17) + (i32.shl + (get_local $15) + (i32.const 1) + ) + ) + (set_local $0 + (i32.or + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 1) + ) + ) + (br_if $label$34 + (get_local $15) + ) + (br $label$33) + ) + (set_local $0 + (call $_Znwj + (tee_local $16 + (i32.and + (i32.add + (get_local $15) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=208 + (get_local $17) + (i32.or + (get_local $16) + (i32.const 1) + ) + ) + (i32.store offset=216 + (get_local $17) + (get_local $0) + ) + (i32.store offset=212 + (get_local $17) + (get_local $15) + ) + ) + (drop + (call $memcpy + (get_local $0) + (i32.const 2976) + (get_local $15) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $0) + (get_local $15) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 56) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $17) + (i32.const 144) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 56) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $17) + (i32.const 144) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=56 + (get_local $17) + (i64.load offset=144 + (get_local $17) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $2) + (get_local $1) + (i32.add + (get_local $17) + (i32.const 56) + ) + (get_local $17) + ) + (block $label$36 + (br_if $label$36 + (i32.eqz + (i32.and + (i32.load8_u offset=208 + (get_local $17) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=216 + (get_local $17) + ) + ) + ) + (i64.store offset=104 + (get_local $17) + (i64.sub + (i64.const 0) + (i64.load + (get_local $4) + ) + ) + ) + (i64.store offset=112 + (get_local $17) + (i64.load + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + ) + (i64.store offset=120 + (get_local $17) + (i64.load + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=208 + (get_local $17) + (i64.const 0) + ) + (br_if $label$26 + (i32.ge_u + (tee_local $15 + (call $strlen + (i32.const 3008) + ) + ) + (i32.const -16) + ) + ) + (block $label$37 + (block $label$38 + (block $label$39 + (br_if $label$39 + (i32.ge_u + (get_local $15) + (i32.const 11) + ) + ) + (i32.store8 offset=208 + (get_local $17) + (i32.shl + (get_local $15) + (i32.const 1) + ) + ) + (set_local $4 + (i32.or + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 1) + ) + ) + (br_if $label$38 + (get_local $15) + ) + (br $label$37) + ) + (set_local $4 + (call $_Znwj + (tee_local $0 + (i32.and + (i32.add + (get_local $15) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=208 + (get_local $17) + (i32.or + (get_local $0) + (i32.const 1) + ) + ) + (i32.store offset=216 + (get_local $17) + (get_local $4) + ) + (i32.store offset=212 + (get_local $17) + (get_local $15) + ) + ) + (drop + (call $memcpy + (get_local $4) + (i32.const 3008) + (get_local $15) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $4) + (get_local $15) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 32) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $17) + (i32.const 104) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 32) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $17) + (i32.const 104) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=32 + (get_local $17) + (i64.load offset=104 + (get_local $17) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $2) + (get_local $1) + (i32.add + (get_local $17) + (i32.const 32) + ) + (get_local $17) + ) + (block $label$40 + (br_if $label$40 + (i32.eqz + (i32.and + (i32.load8_u offset=208 + (get_local $17) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=216 + (get_local $17) + ) + ) + ) + (i64.store offset=80 + (get_local $17) + (i64.sub + (i64.const 0) + (i64.load + (get_local $5) + ) + ) + ) + (i64.store offset=88 + (get_local $17) + (i64.load + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i64.store offset=96 + (get_local $17) + (i64.load + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=208 + (get_local $17) + (i64.const 0) + ) + (br_if $label$25 + (i32.ge_u + (tee_local $15 + (call $strlen + (i32.const 3008) + ) + ) + (i32.const -16) + ) + ) + (block $label$41 + (block $label$42 + (block $label$43 + (br_if $label$43 + (i32.ge_u + (get_local $15) + (i32.const 11) + ) + ) + (i32.store8 offset=208 + (get_local $17) + (i32.shl + (get_local $15) + (i32.const 1) + ) + ) + (set_local $4 + (i32.or + (i32.add + (get_local $17) + (i32.const 208) + ) + (i32.const 1) + ) + ) + (br_if $label$42 + (get_local $15) + ) + (br $label$41) + ) + (set_local $4 + (call $_Znwj + (tee_local $5 + (i32.and + (i32.add + (get_local $15) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=208 + (get_local $17) + (i32.or + (get_local $5) + (i32.const 1) + ) + ) + (i32.store offset=216 + (get_local $17) + (get_local $4) + ) + (i32.store offset=212 + (get_local $17) + (get_local $15) + ) + ) + (drop + (call $memcpy + (get_local $4) + (i32.const 3008) + (get_local $15) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $4) + (get_local $15) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 8) + ) + (i32.const 16) + ) + (i64.load + (i32.add + (i32.add + (get_local $17) + (i32.const 80) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $17) + (i32.const 8) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $17) + (i32.const 80) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=8 + (get_local $17) + (i64.load offset=80 + (get_local $17) + ) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (get_local $2) + (get_local $1) + (i32.add + (get_local $17) + (i32.const 8) + ) + (get_local $17) + ) + (block $label$44 + (br_if $label$44 + (i32.eqz + (i32.and + (i32.load8_u offset=208 + (get_local $17) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=216 + (get_local $17) + ) + ) + ) + (block $label$45 + (br_if $label$45 + (i32.eqz + (tee_local $4 + (i32.load offset=192 + (get_local $17) + ) + ) + ) + ) + (block $label$46 + (block $label$47 + (br_if $label$47 + (i32.eq + (tee_local $15 + (i32.load + (tee_local $5 + (i32.add + (get_local $17) + (i32.const 196) + ) + ) + ) + ) + (get_local $4) + ) + ) + (loop $label$48 + (set_local $2 + (i32.load + (tee_local $15 + (i32.add + (get_local $15) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $15) + (i32.const 0) + ) + (block $label$49 + (br_if $label$49 + (i32.eqz + (get_local $2) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$48 + (i32.ne + (get_local $4) + (get_local $15) + ) + ) + ) + (set_local $15 + (i32.load + (i32.add + (get_local $17) + (i32.const 192) + ) + ) + ) + (br $label$46) + ) + (set_local $15 + (get_local $4) + ) + ) + (i32.store + (get_local $5) + (get_local $4) + ) + (call $_ZdlPv + (get_local $15) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $17) + (i32.const 464) + ) + ) + (return) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $16) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $17) + (i32.const 208) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $17) + (i32.const 208) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $17) + (i32.const 208) + ) + ) + (unreachable) + ) + (func $_ZN5eosio8currency15create_currencyERKNS0_6createE (param $0 i32) (param $1 i32) + (local $2 i64) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $6 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (set_local $5 + (i32.const 0) + ) + (set_local $4 + (tee_local $2 + (i64.shr_u + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + (i64.const 8) + ) + ) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $4) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (set_local $5 + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $6) + (i32.const 56) + ) + (i32.const 0) + ) + (i64.store offset=40 + (get_local $6) + (i64.const -1) + ) + (i64.store offset=48 + (get_local $6) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $6) + (tee_local $4 + (i64.load + (get_local $0) + ) + ) + ) + (i64.store offset=32 + (get_local $6) + (get_local $2) + ) + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.lt_s + (tee_local $3 + (call $db_find_i64 + (get_local $4) + (get_local $2) + (i64.const -4157508551318700032) + (get_local $2) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=48 + (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE31load_object_by_primary_iteratorEl + (i32.add + (get_local $6) + (i32.const 24) + ) + (get_local $3) + ) + ) + (i32.add + (get_local $6) + (i32.const 24) + ) + ) + (i32.const 224) + ) + (br $label$5) + ) + (set_local $5 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 3040) + ) + (set_local $4 + (i64.load + (get_local $1) + ) + ) + (i32.store offset=16 + (get_local $6) + (get_local $1) + ) + (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOS8_ + (i32.add + (get_local $6) + (i32.const 8) + ) + (i32.add + (get_local $6) + (i32.const 24) + ) + (get_local $4) + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (block $label$7 + (br_if $label$7 + (i32.eqz + (tee_local $1 + (i32.load offset=48 + (get_local $6) + ) + ) + ) + ) + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.eq + (tee_local $5 + (i32.load + (tee_local $0 + (i32.add + (get_local $6) + (i32.const 52) + ) + ) + ) + ) + (get_local $1) + ) + ) + (loop $label$10 + (set_local $3 + (i32.load + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $5) + (i32.const 0) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $3) + ) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (br_if $label$10 + (i32.ne + (get_local $1) + (get_local $5) + ) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $6) + (i32.const 48) + ) + ) + ) + (br $label$8) + ) + (set_local $5 + (get_local $1) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 64) + ) + ) + ) + (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOS8_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i64.store offset=40 + (get_local $7) + (get_local $2) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $1) + ) + (call $current_receiver) + ) + (i32.const 288) + ) + (i32.store offset=20 + (get_local $7) + (get_local $3) + ) + (i32.store offset=16 + (get_local $7) + (get_local $1) + ) + (i32.store offset=24 + (get_local $7) + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + (drop + (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE4itemC2IZNS3_7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOSA_EUlSB_E_EEPKS3_SE_ + (tee_local $3 + (call $_Znwj + (i32.const 64) + ) + ) + (get_local $1) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + (i32.store offset=32 + (get_local $7) + (get_local $3) + ) + (i64.store offset=16 + (get_local $7) + (tee_local $2 + (i64.shr_u + (i64.load offset=8 + (get_local $3) + ) + (i64.const 8) + ) + ) + ) + (i32.store offset=12 + (get_local $7) + (tee_local $4 + (i32.load offset=52 + (get_local $3) + ) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.load + (tee_local $6 + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + ) + ) + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + ) + (i64.store offset=8 + (get_local $5) + (get_local $2) + ) + (i32.store offset=16 + (get_local $5) + (get_local $4) + ) + (i32.store offset=32 + (get_local $7) + (i32.const 0) + ) + (i32.store + (get_local $5) + (get_local $3) + ) + (i32.store + (get_local $6) + (i32.add + (get_local $5) + (i32.const 24) + ) + ) + (br $label$0) + ) + (call $_ZNSt3__16vectorIN5eosio11multi_indexILy14289235522390851584ENS1_8currency14currency_statsEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.add + (get_local $7) + (i32.const 32) + ) + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store offset=4 + (get_local $0) + (get_local $3) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (set_local $1 + (i32.load offset=32 + (get_local $7) + ) + ) + (i32.store offset=32 + (get_local $7) + (i32.const 0) + ) + (block $label$2 + (br_if $label$2 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 48) + ) + ) + ) + (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE4itemC2IZNS3_7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOSA_EUlSB_E_EEPKS3_SE_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (set_local $5 + (call $_ZN5eosio8currency14currency_statsC2Ev + (get_local $0) + ) + ) + (i32.store offset=48 + (get_local $0) + (get_local $1) + ) + (i64.store offset=8 + (get_local $0) + (i64.load + (i32.add + (i32.load + (tee_local $1 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + (i32.const 16) + ) + ) + ) + (set_local $3 + (i32.load + (get_local $2) + ) + ) + (i64.store offset=16 + (get_local $0) + (i64.load offset=8 + (tee_local $6 + (i32.load + (get_local $1) + ) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i64.load + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + ) + (i64.store offset=32 + (get_local $0) + (i64.load + (i32.load + (get_local $1) + ) + ) + ) + (i32.store8 offset=40 + (get_local $0) + (i32.ne + (i32.load8_u offset=24 + (i32.load + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (i32.store8 offset=41 + (get_local $0) + (i32.ne + (i32.load8_u offset=25 + (i32.load + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (i32.store8 offset=42 + (get_local $0) + (i32.ne + (i32.load8_u offset=26 + (i32.load + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (i32.store offset=56 + (get_local $7) + (i32.add + (get_local $7) + (i32.const 45) + ) + ) + (i32.store offset=52 + (get_local $7) + (get_local $7) + ) + (i32.store offset=48 + (get_local $7) + (get_local $7) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE + (i32.add + (get_local $7) + (i32.const 48) + ) + (get_local $5) + ) + ) + (i32.store offset=52 + (get_local $0) + (call $db_store_i64 + (i64.load offset=8 + (get_local $3) + ) + (i64.const -4157508551318700032) + (i64.load + (i32.load offset=8 + (get_local $2) + ) + ) + (tee_local $4 + (i64.shr_u + (i64.load offset=8 + (get_local $0) + ) + (i64.const 8) + ) + ) + (get_local $7) + (i32.const 45) + ) + ) + (block $label$0 + (br_if $label$0 + (i64.lt_u + (get_local $4) + (i64.load offset=16 + (get_local $3) + ) + ) + ) + (i64.store + (i32.add + (get_local $3) + (i32.const 16) + ) + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 64) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio8exchange4lendEyNS_11symbol_typeENS_14extended_assetE (type $FUNCSIG$vijji) (param $0 i32) (param $1 i64) (param $2 i64) (param $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 464) + ) + ) + ) + (call $require_auth + (get_local $1) + ) + (set_local $8 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (tee_local $4 + (i64.load + (get_local $3) + ) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $6 + (i64.shr_u + (i64.load offset=8 + (get_local $3) + ) + (i64.const 8) + ) + ) + (set_local $7 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $6) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $8 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $8 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $8) + (i32.const 1840) + ) + (call $eosio_assert + (i64.gt_s + (get_local $4) + (i64.const 0) + ) + (i32.const 3088) + ) + (i64.store offset=8 + (get_local $9) + (i64.shr_u + (get_local $2) + (i64.const 8) + ) + ) + (set_local $6 + (i64.load + (get_local $0) + ) + ) + (set_local $7 + (call $_ZN5eosio14exchange_stateC2Ev + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 264) + ) + (i64.const -1) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 272) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 280) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 256) + ) + (tee_local $2 + (i64.load offset=8 + (get_local $9) + ) + ) + ) + (i64.store offset=248 + (get_local $9) + (get_local $6) + ) + (i64.store offset=288 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 296) + ) + (tee_local $5 + (i64.or + (tee_local $4 + (i64.shl + (get_local $2) + (i64.const 4) + ) + ) + (i64.const 1) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 304) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 312) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 316) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 320) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $9) + (i32.const 324) + ) + (i32.const 0) + ) + (i64.store offset=328 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 336) + ) + (tee_local $4 + (i64.or + (get_local $4) + (i64.const 2) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 344) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 352) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 356) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 360) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $9) + (i32.const 364) + ) + (i32.const 0) + ) + (i64.store offset=368 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 376) + ) + (get_local $5) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 384) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 392) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 396) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 400) + ) + (i32.const 0) + ) + (i64.store offset=408 + (get_local $9) + (get_local $6) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 416) + ) + (get_local $4) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 424) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 432) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 436) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 440) + ) + (i32.const 0) + ) + (i32.store offset=448 + (get_local $9) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy + (i32.add + (get_local $9) + (i32.const 452) + ) + (i32.add + (get_local $9) + (i32.const 248) + ) + (get_local $2) + ) + (call $eosio_assert + (i32.ne + (i32.load + (tee_local $8 + (i32.add + (get_local $9) + (i32.const 456) + ) + ) + ) + (i32.const 0) + ) + (i32.const 720) + ) + (drop + (call $memcpy + (get_local $7) + (i32.load + (get_local $8) + ) + (i32.const 232) + ) + ) + (call $_ZN5eosio12market_state4lendEyRKNS_14extended_assetE + (i32.add + (get_local $9) + (i32.const 8) + ) + (get_local $1) + (get_local $3) + ) + (call $_ZN5eosio12market_state4saveEv + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosio12market_stateD2Ev + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 464) + ) + ) + ) + (func $_ZN5eosio8exchange6unlendEyNS_11symbol_typeEdNS_15extended_symbolE (type $FUNCSIG$vijjdi) (param $0 i32) (param $1 i64) (param $2 i64) (param $3 f64) (param $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 464) + ) + ) + ) + (call $require_auth + (get_local $1) + ) + (call $eosio_assert + (f64.gt + (get_local $3) + (f64.const 0) + ) + (i32.const 3120) + ) + (i64.store offset=8 + (get_local $9) + (i64.shr_u + (get_local $2) + (i64.const 8) + ) + ) + (set_local $2 + (i64.load + (get_local $0) + ) + ) + (set_local $5 + (call $_ZN5eosio14exchange_stateC2Ev + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 264) + ) + (i64.const -1) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 272) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 280) + ) + (i32.const 0) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 256) + ) + (tee_local $6 + (i64.load offset=8 + (get_local $9) + ) + ) + ) + (i64.store offset=248 + (get_local $9) + (get_local $2) + ) + (i64.store offset=288 + (get_local $9) + (get_local $2) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 296) + ) + (tee_local $8 + (i64.or + (tee_local $7 + (i64.shl + (get_local $6) + (i64.const 4) + ) + ) + (i64.const 1) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 304) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 312) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 316) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 320) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $9) + (i32.const 324) + ) + (i32.const 0) + ) + (i64.store offset=328 + (get_local $9) + (get_local $2) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 336) + ) + (tee_local $7 + (i64.or + (get_local $7) + (i64.const 2) + ) + ) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 344) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 352) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 356) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 360) + ) + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $9) + (i32.const 364) + ) + (i32.const 0) + ) + (i64.store offset=368 + (get_local $9) + (get_local $2) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 376) + ) + (get_local $8) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 384) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 392) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 396) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 400) + ) + (i32.const 0) + ) + (i64.store offset=408 + (get_local $9) + (get_local $2) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 416) + ) + (get_local $7) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 424) + ) + (i64.const -1) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 432) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 436) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 440) + ) + (i32.const 0) + ) + (i32.store offset=448 + (get_local $9) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy + (i32.add + (get_local $9) + (i32.const 452) + ) + (i32.add + (get_local $9) + (i32.const 248) + ) + (get_local $6) + ) + (call $eosio_assert + (i32.ne + (i32.load + (tee_local $0 + (i32.add + (get_local $9) + (i32.const 456) + ) + ) + ) + (i32.const 0) + ) + (i32.const 720) + ) + (drop + (call $memcpy + (get_local $5) + (i32.load + (get_local $0) + ) + (i32.const 232) + ) + ) + (call $_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE + (i32.add + (get_local $9) + (i32.const 8) + ) + (get_local $1) + (get_local $3) + (get_local $4) + ) + (call $_ZN5eosio12market_state4saveEv + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosio12market_stateD2Ev + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 464) + ) + ) + ) + (func $_ZN5eosio8exchange2onERKNS_8currency8transferEy (param $0 i32) (param $1 i32) (param $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i64) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $12 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (block $label$0 + (br_if $label$0 + (i64.ne + (tee_local $8 + (i64.load + (get_local $0) + ) + ) + (get_local $2) + ) + ) + (call $_ZN5eosio8currency2onERKNS0_8transferE + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $1) + ) + (set_local $8 + (i64.load + (get_local $0) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i64.ne + (i64.load offset=8 + (get_local $1) + ) + (get_local $8) + ) + ) + (set_local $4 + (i64.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (set_local $10 + (i32.const 0) + ) + (block $label$2 + (br_if $label$2 + (i64.gt_u + (i64.add + (tee_local $3 + (i64.load offset=16 + (get_local $1) + ) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $8 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (set_local $9 + (i32.const 0) + ) + (block $label$3 + (loop $label$4 + (br_if $label$3 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $8) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$5 + (br_if $label$5 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$6 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$6 + (i32.lt_s + (tee_local $9 + (i32.add + (get_local $9) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $10 + (i32.const 1) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $9 + (i32.add + (get_local $9) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$2) + ) + ) + (set_local $10 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $10) + (i32.const 3152) + ) + (call $eosio_assert + (i64.ne + (get_local $3) + (i64.const 0) + ) + (i32.const 3184) + ) + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i64.lt_s + (get_local $3) + (i64.const 1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3232) + ) + (set_local $11 + (i32.add + (get_local $1) + (i32.const 36) + ) + ) + (set_local $10 + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + (br $label$8) + ) + (set_local $9 + (i32.const 1) + ) + (set_local $10 + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + (set_local $6 + (i32.const 0) + ) + (block $label$10 + (br_if $label$10 + (i32.ne + (tee_local $5 + (call $strlen + (i32.const 1968) + ) + ) + (select + (i32.load + (tee_local $11 + (i32.add + (get_local $1) + (i32.const 36) + ) + ) + ) + (i32.shr_u + (tee_local $7 + (i32.load8_u offset=32 + (get_local $1) + ) + ) + (i32.const 1) + ) + (i32.and + (get_local $7) + (i32.const 1) + ) + ) + ) + ) + (set_local $6 + (i32.eqz + (call $_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEjjPKcj + (get_local $10) + (i32.const 0) + (i32.const -1) + (i32.const 1968) + (get_local $5) + ) + ) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 3232) + ) + (br_if $label$7 + (i64.lt_s + (get_local $3) + (i64.const 0) + ) + ) + ) + (set_local $9 + (i32.const 0) + ) + (br_if $label$7 + (i32.ne + (tee_local $6 + (call $strlen + (i32.const 1872) + ) + ) + (select + (i32.load + (get_local $11) + ) + (i32.shr_u + (tee_local $11 + (i32.load8_u + (get_local $10) + ) + ) + (i32.const 1) + ) + (i32.and + (get_local $11) + (i32.const 1) + ) + ) + ) + ) + (set_local $9 + (i32.eqz + (call $_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEjjPKcj + (get_local $10) + (i32.const 0) + (i32.const -1) + (i32.const 1872) + (get_local $6) + ) + ) + ) + ) + (call $eosio_assert + (get_local $9) + (i32.const 3280) + ) + (i64.store offset=32 + (get_local $12) + (get_local $4) + ) + (set_local $8 + (i64.load + (get_local $1) + ) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 8) + ) + (get_local $4) + ) + (i64.store offset=40 + (get_local $12) + (get_local $2) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 16) + ) + (get_local $2) + ) + (i64.store offset=24 + (get_local $12) + (get_local $3) + ) + (i64.store + (get_local $12) + (get_local $3) + ) + (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE + (i32.add + (get_local $0) + (i32.const 16) + ) + (get_local $8) + (get_local $12) + (get_local $9) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $12) + (i32.const 48) + ) + ) + ) + (func $_ZN5eosio8currency2onERKNS0_8transferE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i64) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (call $require_auth + (i64.load + (get_local $1) + ) + ) + (set_local $8 + (i64.load + (tee_local $10 + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + ) + (set_local $9 + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 0) + ) + (i64.store offset=88 + (get_local $11) + (i64.const -1) + ) + (i64.store offset=96 + (get_local $11) + (i64.const 0) + ) + (i64.store offset=72 + (get_local $11) + (i64.load + (get_local $0) + ) + ) + (i64.store offset=80 + (get_local $11) + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + ) + (set_local $2 + (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc + (i32.add + (get_local $11) + (i32.const 72) + ) + (get_local $8) + (i32.const 2224) + ) + ) + (call $require_recipient + (i64.load offset=8 + (get_local $1) + ) + ) + (set_local $3 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (i64.load offset=16 + (get_local $1) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $8 + (i64.shr_u + (i64.load + (get_local $10) + ) + (i64.const 8) + ) + ) + (set_local $10 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $8) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $10 + (i32.add + (get_local $10) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $9 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $10 + (i32.add + (get_local $10) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $9 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $9) + (i32.const 1840) + ) + (call $eosio_assert + (i64.gt_s + (i64.load + (get_local $3) + ) + (i64.const 0) + ) + (i32.const 3328) + ) + (i32.store + (tee_local $10 + (i32.add + (i32.add + (get_local $11) + (i32.const 56) + ) + (i32.const 12) + ) + ) + (i32.load + (tee_local $9 + (i32.add + (get_local $3) + (i32.const 12) + ) + ) + ) + ) + (i32.store + (tee_local $5 + (i32.add + (i32.add + (get_local $11) + (i32.const 56) + ) + (i32.const 8) + ) + ) + (i32.load + (tee_local $4 + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + ) + (i32.store offset=60 + (get_local $11) + (i32.load + (tee_local $6 + (i32.add + (get_local $3) + (i32.const 4) + ) + ) + ) + ) + (i32.store offset=56 + (get_local $11) + (i32.load + (get_local $3) + ) + ) + (set_local $8 + (i64.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.const 12) + ) + (i32.load + (get_local $10) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.const 8) + ) + (i32.load + (get_local $5) + ) + ) + (i32.store offset=28 + (get_local $11) + (i32.load offset=60 + (get_local $11) + ) + ) + (i32.store offset=24 + (get_local $11) + (i32.load offset=56 + (get_local $11) + ) + ) + (call $_ZN5eosio8currency11sub_balanceEyNS_5assetERKNS0_14currency_statsE + (get_local $0) + (get_local $8) + (i32.add + (get_local $11) + (i32.const 24) + ) + (get_local $2) + ) + (i32.store + (i32.add + (i32.add + (get_local $11) + (i32.const 40) + ) + (i32.const 12) + ) + (i32.load + (get_local $9) + ) + ) + (i32.store + (tee_local $10 + (i32.add + (i32.add + (get_local $11) + (i32.const 40) + ) + (i32.const 8) + ) + ) + (i32.load + (get_local $4) + ) + ) + (i32.store offset=44 + (get_local $11) + (i32.load + (get_local $6) + ) + ) + (i32.store offset=40 + (get_local $11) + (i32.load + (get_local $3) + ) + ) + (set_local $8 + (i64.load + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + (set_local $7 + (i64.load + (get_local $1) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.const 8) + ) + (i64.load + (get_local $10) + ) + ) + (i64.store offset=8 + (get_local $11) + (i64.load offset=40 + (get_local $11) + ) + ) + (call $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy + (get_local $0) + (get_local $8) + (i32.add + (get_local $11) + (i32.const 8) + ) + (get_local $2) + (get_local $7) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (tee_local $3 + (i32.load offset=96 + (get_local $11) + ) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.eq + (tee_local $10 + (i32.load + (tee_local $9 + (i32.add + (get_local $11) + (i32.const 100) + ) + ) + ) + ) + (get_local $3) + ) + ) + (loop $label$8 + (set_local $1 + (i32.load + (tee_local $10 + (i32.add + (get_local $10) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $10) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $3) + (get_local $10) + ) + ) + ) + (set_local $10 + (i32.load + (i32.add + (get_local $11) + (i32.const 96) + ) + ) + ) + (br $label$6) + ) + (set_local $10 + (get_local $3) + ) + ) + (i32.store + (get_local $9) + (get_local $3) + ) + (call $_ZdlPv + (get_local $10) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 112) + ) + ) + ) + (func $_ZN5eosio8currency11sub_balanceEyNS_5assetERKNS0_14currency_statsE (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $6 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store + (i32.add + (get_local $6) + (i32.const 40) + ) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $6) + (get_local $1) + ) + (i64.store offset=24 + (get_local $6) + (i64.const -1) + ) + (i64.store offset=32 + (get_local $6) + (i64.const 0) + ) + (i64.store offset=8 + (get_local $6) + (i64.load + (get_local $0) + ) + ) + (call $eosio_assert + (i64.ge_s + (i64.load + (tee_local $0 + (call $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE3getEyPKc + (i32.add + (get_local $6) + (i32.const 8) + ) + (i64.shr_u + (i64.load offset=8 + (get_local $2) + ) + (i64.const 8) + ) + (i32.const 2224) + ) + ) + ) + (i64.load + (get_local $2) + ) + ) + (i32.const 3360) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (call $has_auth + (get_local $1) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (set_local $4 + (i32.const 1) + ) + (block $label$2 + (br_if $label$2 + (i32.eqz + (i32.load8_u offset=40 + (get_local $3) + ) + ) + ) + (set_local $4 + (i32.xor + (i32.load8_u offset=16 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (call $eosio_assert + (get_local $4) + (i32.const 3392) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (i32.load8_u + (i32.add + (get_local $3) + (i32.const 40) + ) + ) + ) + ) + (set_local $5 + (i32.xor + (i32.load8_u offset=43 + (get_local $3) + ) + (i32.const 1) + ) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 3424) + ) + (call $eosio_assert + (select + (i32.load8_u offset=17 + (get_local $0) + ) + (i32.const 1) + (i32.load8_u offset=44 + (get_local $3) + ) + ) + (i32.const 3472) + ) + (br $label$0) + ) + (block $label$4 + (br_if $label$4 + (i32.eqz + (call $has_auth + (i64.load offset=32 + (get_local $3) + ) + ) + ) + ) + (call $eosio_assert + (i32.load8_u offset=41 + (get_local $3) + ) + (i32.const 3504) + ) + (br $label$0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 3536) + ) + ) + (i32.store + (get_local $6) + (get_local $2) + ) + (call $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11sub_balanceEyNS_5assetERKNS1_14currency_statsEEUlRT_E_EEvRKS2_yOS9_ + (i32.add + (get_local $6) + (i32.const 8) + ) + (get_local $0) + (get_local $1) + (get_local $6) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (tee_local $0 + (i32.load offset=32 + (get_local $6) + ) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.eq + (tee_local $2 + (i32.load + (tee_local $5 + (i32.add + (get_local $6) + (i32.const 36) + ) + ) + ) + ) + (get_local $0) + ) + ) + (loop $label$8 + (set_local $3 + (i32.load + (tee_local $2 + (i32.add + (get_local $2) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $2) + (i32.const 0) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $3) + ) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $0) + (get_local $2) + ) + ) + ) + (set_local $2 + (i32.load + (i32.add + (get_local $6) + (i32.const 32) + ) + ) + ) + (br $label$6) + ) + (set_local $2 + (get_local $0) + ) + ) + (i32.store + (get_local $5) + (get_local $0) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 48) + ) + ) + ) + (func $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE3getEyPKc (param $0 i32) (param $1 i64) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (tee_local $3 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (set_local $4 + (i32.sub + (i32.const 0) + (get_local $3) + ) + ) + (loop $label$1 + (br_if $label$0 + (i64.eq + (i64.shr_u + (i64.load offset=8 + (i32.load + (get_local $6) + ) + ) + (i64.const 8) + ) + (get_local $1) + ) + ) + (set_local $7 + (get_local $6) + ) + (set_local $6 + (tee_local $5 + (i32.add + (get_local $6) + (i32.const -24) + ) + ) + ) + (br_if $label$1 + (i32.ne + (i32.add + (get_local $5) + (get_local $4) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $3) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load + (i32.add + (tee_local $6 + (i32.load + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + ) + (i32.const 20) + ) + ) + (get_local $0) + ) + (i32.const 224) + ) + (br $label$2) + ) + (set_local $6 + (i32.const 0) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $5 + (call $db_find_i64 + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + (i64.const 3607749779137757184) + (get_local $1) + ) + ) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=20 + (tee_local $6 + (call $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE31load_object_by_primary_iteratorEl + (get_local $0) + (get_local $5) + ) + ) + ) + (get_local $0) + ) + (i32.const 224) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $6) + (i32.const 0) + ) + (get_local $2) + ) + (get_local $6) + ) + (func $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11sub_balanceEyNS_5assetERKNS1_14currency_statsEEUlRT_E_EEvRKS2_yOS9_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) + (local $4 i64) + (local $5 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $5 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + (get_local $0) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $0) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (i64.store + (get_local $1) + (i64.sub + (i64.load + (get_local $1) + ) + (i64.load + (i32.load + (get_local $3) + ) + ) + ) + ) + (set_local $4 + (i64.load offset=8 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 544) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $1) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.or + (get_local $5) + (i32.const 8) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store8 offset=31 + (get_local $5) + (i32.load8_u offset=16 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $5) + (i32.const 16) + ) + (i32.add + (get_local $5) + (i32.const 31) + ) + (i32.const 1) + ) + ) + (i32.store8 offset=31 + (get_local $5) + (i32.load8_u offset=17 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 608) + ) + (drop + (call $memcpy + (i32.add + (get_local $5) + (i32.const 17) + ) + (i32.add + (get_local $5) + (i32.const 31) + ) + (i32.const 1) + ) + ) + (call $db_update_i64 + (i32.load offset=24 + (get_local $1) + ) + (get_local $2) + (get_local $5) + (i32.const 18) + ) + (block $label$0 + (br_if $label$0 + (i64.lt_u + (tee_local $2 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.load offset=16 + (get_local $0) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.add + (get_local $2) + (i64.const 1) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $5) + (i32.const 32) + ) + ) + ) + (func $_ZN5eosio8exchange5applyEyy (param $0 i32) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 160) + ) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 1904) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $6) + (i64.const 7) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i64.ne + (get_local $7) + (get_local $2) + ) + ) + (call $_ZN5eosio18unpack_action_dataINS_8currency8transferEEET_v + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + (call $_ZN5eosio8exchange2onERKNS_8currency8transferEy + (get_local $0) + (i32.add + (get_local $9) + (i32.const 48) + ) + (get_local $1) + ) + (br_if $label$6 + (i32.eqz + (i32.and + (i32.load8_u offset=80 + (get_local $9) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $9) + (i32.const 88) + ) + ) + ) + (br $label$6) + ) + (br_if $label$6 + (i64.ne + (i64.load + (get_local $0) + ) + (get_local $1) + ) + ) + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (br_if $label$15 + (i64.gt_s + (get_local $2) + (i64.const -2039333636196532225) + ) + ) + (br_if $label$14 + (i64.gt_s + (get_local $2) + (i64.const -3106734271092490241) + ) + ) + (br_if $label$12 + (i64.eq + (get_local $2) + (i64.const -8455912920667127808) + ) + ) + (br_if $label$8 + (i64.ne + (get_local $2) + (i64.const -3617352573452812288) + ) + ) + (call $_ZN5eosio18unpack_action_dataINS_8exchange5tradeEEET_v + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + (call $_ZN5eosio8exchange2onERKNS0_5tradeE + (get_local $0) + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + (br $label$6) + ) + (br_if $label$13 + (i64.gt_s + (get_local $2) + (i64.const 5031766168059248639) + ) + ) + (br_if $label$11 + (i64.eq + (get_local $2) + (i64.const -2039333636196532224) + ) + ) + (br_if $label$8 + (i64.ne + (get_local $2) + (i64.const 4987362516454843904) + ) + ) + (call $_ZN5eosio18unpack_action_dataINS_8exchange11covermarginEEET_v + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + (call $_ZN5eosio8exchange2onERKNS0_11covermarginE + (get_local $0) + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + (br $label$6) + ) + (br_if $label$10 + (i64.eq + (get_local $2) + (i64.const -3106734271092490240) + ) + ) + (br_if $label$8 + (i64.ne + (get_local $2) + (i64.const -3070210634466459648) + ) + ) + (call $_ZN5eosio18unpack_action_dataINS_8exchange8upmarginEEET_v + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + (call $_ZN5eosio8exchange2onERKNS0_8upmarginE + (get_local $0) + (i32.add + (get_local $9) + (i32.const 48) + ) + ) + (br $label$6) + ) + (br_if $label$9 + (i64.eq + (get_local $2) + (i64.const 5380477996647841792) + ) + ) + (br_if $label$8 + (i64.ne + (get_local $2) + (i64.const 5031766168059248640) + ) + ) + (i32.store offset=156 + (get_local $9) + (i32.const 0) + ) + (i32.store offset=152 + (get_local $9) + (i32.const 1) + ) + (i64.store offset=8 align=4 + (get_local $9) + (i64.load offset=152 + (get_local $9) + ) + ) + (drop + (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_5assetEmNS_14extended_assetES3_EEEbPT_MT0_FvDpT1_E + (get_local $0) + (i32.add + (get_local $9) + (i32.const 8) + ) + ) + ) + (br $label$8) + ) + (i32.store offset=132 + (get_local $9) + (i32.const 0) + ) + (i32.store offset=128 + (get_local $9) + (i32.const 2) + ) + (i64.store offset=32 align=4 + (get_local $9) + (i64.load offset=128 + (get_local $9) + ) + ) + (drop + (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeENS_14extended_assetEEEEbPT_MT0_FvDpT1_E + (get_local $0) + (i32.add + (get_local $9) + (i32.const 32) + ) + ) + ) + (br $label$8) + ) + (i32.store offset=140 + (get_local $9) + (i32.const 0) + ) + (i32.store offset=136 + (get_local $9) + (i32.const 3) + ) + (i64.store offset=24 align=4 + (get_local $9) + (i64.load offset=136 + (get_local $9) + ) + ) + (drop + (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_14extended_assetEEEEbPT_MT0_FvDpT1_E + (get_local $0) + (i32.add + (get_local $9) + (i32.const 24) + ) + ) + ) + (br $label$8) + ) + (i32.store offset=124 + (get_local $9) + (i32.const 0) + ) + (i32.store offset=120 + (get_local $9) + (i32.const 4) + ) + (i64.store offset=40 align=4 + (get_local $9) + (i64.load offset=120 + (get_local $9) + ) + ) + (drop + (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeEdNS_15extended_symbolEEEEbPT_MT0_FvDpT1_E + (get_local $0) + (i32.add + (get_local $9) + (i32.const 40) + ) + ) + ) + (br $label$8) + ) + (i32.store offset=148 + (get_local $9) + (i32.const 0) + ) + (i32.store offset=144 + (get_local $9) + (i32.const 5) + ) + (i64.store offset=16 align=4 + (get_local $9) + (i64.load offset=144 + (get_local $9) + ) + ) + (drop + (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_14extended_assetEEEEbPT_MT0_FvDpT1_E + (get_local $0) + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + ) + ) + (drop + (call $_ZN5eosio8currency5applyEyy + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $1) + (get_local $2) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 160) + ) + ) + ) + (func $_ZN5eosio18unpack_action_dataINS_8currency8transferEEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (set_local $6 + (tee_local $4 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $4) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $2 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $4) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $2) + (get_local $1) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i64.const 1398362884) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $3 + (i64.const 5462355) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$2 + (block $label$3 + (loop $label$4 + (br_if $label$3 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $3) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$5 + (br_if $label$5 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$6 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$6 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$2) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 80) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 40) + ) + (i32.const 0) + ) + (i64.store offset=32 align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store offset=4 + (get_local $6) + (get_local $2) + ) + (i32.store + (get_local $6) + (get_local $2) + ) + (i32.store offset=8 + (get_local $6) + (i32.add + (get_local $2) + (get_local $1) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency8transferE + (get_local $6) + (get_local $0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_5assetEmNS_14extended_assetES3_EEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (set_local $10 + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 336) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $8) + ) + (set_local $2 + (i32.load offset=4 + (get_local $1) + ) + ) + (set_local $9 + (i32.load + (get_local $1) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (call $action_data_size) + ) + ) + ) + (br_if $label$2 + (i32.lt_u + (get_local $1) + (i32.const 513) + ) + ) + (set_local $8 + (call $malloc + (get_local $1) + ) + ) + (br $label$1) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (get_local $8) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $8) + (get_local $1) + ) + ) + ) + (call $_ZN5eosio6unpackINSt3__15tupleIJyNS_5assetEmNS_14extended_assetES4_EEEEET_PKcj + (i32.add + (get_local $10) + (i32.const 64) + ) + (get_local $8) + (get_local $1) + ) + (block $label$4 + (br_if $label$4 + (i32.lt_u + (get_local $1) + (i32.const 513) + ) + ) + (call $free + (get_local $8) + ) + ) + (i64.store + (tee_local $1 + (i32.add + (i32.add + (get_local $10) + (i32.const 192) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 16) + ) + ) + ) + (set_local $3 + (i64.load offset=64 + (get_local $10) + ) + ) + (i64.store offset=192 + (get_local $10) + (i64.load offset=72 + (get_local $10) + ) + ) + (set_local $8 + (i32.load offset=88 + (get_local $10) + ) + ) + (i64.store + (tee_local $4 + (i32.add + (i32.add + (get_local $10) + (i32.const 168) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const 112) + ) + ) + ) + (i64.store + (tee_local $5 + (i32.add + (i32.add + (get_local $10) + (i32.const 168) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const 104) + ) + ) + ) + (i64.store offset=168 + (get_local $10) + (i64.load offset=96 + (get_local $10) + ) + ) + (i64.store + (tee_local $6 + (i32.add + (i32.add + (get_local $10) + (i32.const 144) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const 136) + ) + ) + ) + (i64.store + (tee_local $7 + (i32.add + (i32.add + (get_local $10) + (i32.const 144) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $10) + (i32.const 128) + ) + ) + ) + (i64.store offset=144 + (get_local $10) + (i64.load offset=120 + (get_local $10) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 248) + ) + (i32.const 16) + ) + (i64.load + (get_local $6) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 248) + ) + (i32.const 8) + ) + (i64.load + (get_local $7) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 224) + ) + (i32.const 16) + ) + (i64.load + (get_local $4) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 224) + ) + (i32.const 8) + ) + (i64.load + (get_local $5) + ) + ) + (i64.store offset=248 + (get_local $10) + (i64.load offset=144 + (get_local $10) + ) + ) + (i64.store offset=224 + (get_local $10) + (i64.load offset=168 + (get_local $10) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 8) + ) + (i64.load + (get_local $1) + ) + ) + (i64.store offset=208 + (get_local $10) + (i64.load offset=192 + (get_local $10) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.shr_s + (get_local $2) + (i32.const 1) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (i32.and + (get_local $2) + (i32.const 1) + ) + ) + ) + (set_local $9 + (i32.load + (i32.add + (i32.load + (get_local $1) + ) + (get_local $9) + ) + ) + ) + ) + (i64.store + (tee_local $2 + (i32.add + (i32.add + (get_local $10) + (i32.const 320) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 8) + ) + ) + ) + (i64.store + (tee_local $0 + (i32.add + (i32.add + (get_local $10) + (i32.const 296) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 224) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (tee_local $4 + (i32.add + (i32.add + (get_local $10) + (i32.const 296) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 224) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=320 + (get_local $10) + (i64.load offset=208 + (get_local $10) + ) + ) + (i64.store offset=296 + (get_local $10) + (i64.load offset=224 + (get_local $10) + ) + ) + (i64.store + (tee_local $5 + (i32.add + (i32.add + (get_local $10) + (i32.const 272) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 248) + ) + (i32.const 16) + ) + ) + ) + (i64.store + (tee_local $6 + (i32.add + (i32.add + (get_local $10) + (i32.const 272) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (i32.add + (get_local $10) + (i32.const 248) + ) + (i32.const 8) + ) + ) + ) + (i64.store offset=272 + (get_local $10) + (i64.load offset=248 + (get_local $10) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 48) + ) + (i32.const 8) + ) + (i64.load + (get_local $2) + ) + ) + (i64.store offset=48 + (get_local $10) + (i64.load offset=320 + (get_local $10) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.const 16) + ) + (i64.load + (get_local $0) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.const 8) + ) + (i64.load + (get_local $4) + ) + ) + (i64.store offset=24 + (get_local $10) + (i64.load offset=296 + (get_local $10) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 16) + ) + (i64.load + (get_local $5) + ) + ) + (i64.store + (i32.add + (get_local $10) + (i32.const 8) + ) + (i64.load + (get_local $6) + ) + ) + (i64.store + (get_local $10) + (i64.load offset=272 + (get_local $10) + ) + ) + (call_indirect (type $FUNCSIG$vijiiii) + (get_local $1) + (get_local $3) + (i32.add + (get_local $10) + (i32.const 48) + ) + (get_local $8) + (i32.add + (get_local $10) + (i32.const 24) + ) + (get_local $10) + (get_local $9) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 336) + ) + ) + (i32.const 1) + ) + (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_14extended_assetEEEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (local $8 i64) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (set_local $11 + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 128) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $9) + ) + (set_local $2 + (i32.load offset=4 + (get_local $1) + ) + ) + (set_local $10 + (i32.load + (get_local $1) + ) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $7 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $3 + (call $action_data_size) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.lt_u + (get_local $3) + (i32.const 513) + ) + ) + (set_local $7 + (call $malloc + (get_local $3) + ) + ) + (br $label$1) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (get_local $9) + (i32.and + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $7) + (get_local $3) + ) + ) + ) + (i64.store + (tee_local $4 + (i32.add + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 40) + ) + (i64.const 1398362884) + ) + (i64.store offset=24 + (get_local $11) + (i64.const 0) + ) + (i64.store offset=32 + (get_local $11) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $8 + (i64.const 5462355) + ) + (block $label$3 + (loop $label$4 + (set_local $9 + (i32.const 0) + ) + (br_if $label$3 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $8) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$5 + (br_if $label$5 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$6 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$6 + (i32.lt_s + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $9 + (i32.const 1) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (call $eosio_assert + (get_local $9) + (i32.const 80) + ) + (call $eosio_assert + (i32.gt_u + (get_local $3) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $11) + (i32.const 24) + ) + (get_local $7) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (tee_local $9 + (i32.and + (get_local $3) + (i32.const -8) + ) + ) + (i32.const 8) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (tee_local $1 + (i32.add + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $9) + (i32.const 16) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (i32.add + (get_local $11) + (i32.const 24) + ) + (i32.const 16) + ) + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $9) + (i32.const 24) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $4) + (i32.add + (get_local $7) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (block $label$7 + (br_if $label$7 + (i32.lt_u + (get_local $3) + (i32.const 513) + ) + ) + (call $free + (get_local $7) + ) + ) + (i64.store + (tee_local $9 + (i32.add + (i32.add + (get_local $11) + (i32.const 56) + ) + (i32.const 16) + ) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i64.store + (tee_local $7 + (i32.add + (i32.add + (get_local $11) + (i32.const 56) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + (set_local $8 + (i64.load offset=24 + (get_local $11) + ) + ) + (i64.store offset=56 + (get_local $11) + (i64.load + (get_local $1) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 80) + ) + (i32.const 16) + ) + (i64.load + (get_local $9) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 80) + ) + (i32.const 8) + ) + (i64.load + (get_local $7) + ) + ) + (i64.store offset=80 + (get_local $11) + (i64.load offset=56 + (get_local $11) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.shr_s + (get_local $2) + (i32.const 1) + ) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.eqz + (i32.and + (get_local $2) + (i32.const 1) + ) + ) + ) + (set_local $10 + (i32.load + (i32.add + (i32.load + (get_local $1) + ) + (get_local $10) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 16) + ) + (tee_local $5 + (i64.load + (i32.add + (i32.add + (get_local $11) + (i32.const 80) + ) + (i32.const 16) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 8) + ) + (tee_local $6 + (i64.load + (i32.add + (i32.add + (get_local $11) + (i32.const 80) + ) + (i32.const 8) + ) + ) + ) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 16) + ) + (get_local $5) + ) + (i64.store + (i32.add + (get_local $11) + (i32.const 8) + ) + (get_local $6) + ) + (i64.store offset=104 + (get_local $11) + (tee_local $5 + (i64.load offset=80 + (get_local $11) + ) + ) + ) + (i64.store + (get_local $11) + (get_local $5) + ) + (call_indirect (type $FUNCSIG$viji) + (get_local $1) + (get_local $8) + (get_local $11) + (get_local $10) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 128) + ) + ) + (i32.const 1) + ) + (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeENS_14extended_assetEEEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (set_local $9 + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 144) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $7) + ) + (set_local $2 + (i32.load offset=4 + (get_local $1) + ) + ) + (set_local $8 + (i32.load + (get_local $1) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (call $action_data_size) + ) + ) + ) + (br_if $label$2 + (i32.lt_u + (get_local $1) + (i32.const 513) + ) + ) + (set_local $7 + (call $malloc + (get_local $1) + ) + ) + (br $label$1) + ) + (set_local $7 + (i32.const 0) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (get_local $7) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $7) + (get_local $1) + ) + ) + ) + (call $_ZN5eosio6unpackINSt3__15tupleIJyNS_11symbol_typeENS_14extended_assetEEEEEET_PKcj + (i32.add + (get_local $9) + (i32.const 32) + ) + (get_local $7) + (get_local $1) + ) + (block $label$4 + (br_if $label$4 + (i32.lt_u + (get_local $1) + (i32.const 513) + ) + ) + (call $free + (get_local $7) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $9) + (i32.const 72) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (get_local $9) + (i32.const 68) + ) + ) + ) + (i32.store + (tee_local $1 + (i32.add + (i32.add + (get_local $9) + (i32.const 72) + ) + (i32.const 16) + ) + ) + (i32.load + (i32.add + (get_local $9) + (i32.const 64) + ) + ) + ) + (set_local $4 + (i64.load offset=40 + (get_local $9) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 84) + ) + (i32.load + (i32.add + (get_local $9) + (i32.const 60) + ) + ) + ) + (i32.store + (tee_local $7 + (i32.add + (i32.add + (get_local $9) + (i32.const 72) + ) + (i32.const 8) + ) + ) + (i32.load + (i32.add + (get_local $9) + (i32.const 56) + ) + ) + ) + (set_local $3 + (i64.load offset=32 + (get_local $9) + ) + ) + (i32.store offset=72 + (get_local $9) + (i32.load offset=48 + (get_local $9) + ) + ) + (i32.store offset=76 + (get_local $9) + (i32.load + (i32.add + (i32.add + (get_local $9) + (i32.const 32) + ) + (i32.const 20) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 16) + ) + (i64.load + (get_local $1) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 8) + ) + (i64.load + (get_local $7) + ) + ) + (i64.store offset=96 + (get_local $9) + (i64.load offset=72 + (get_local $9) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.shr_s + (get_local $2) + (i32.const 1) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (i32.and + (get_local $2) + (i32.const 1) + ) + ) + ) + (set_local $8 + (i32.load + (i32.add + (i32.load + (get_local $1) + ) + (get_local $8) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 120) + ) + (i32.const 16) + ) + (tee_local $5 + (i64.load + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 16) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 120) + ) + (i32.const 8) + ) + (tee_local $6 + (i64.load + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 8) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 8) + ) + (i32.const 16) + ) + (get_local $5) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 8) + ) + (i32.const 8) + ) + (get_local $6) + ) + (i64.store offset=120 + (get_local $9) + (tee_local $5 + (i64.load offset=96 + (get_local $9) + ) + ) + ) + (i64.store offset=8 + (get_local $9) + (get_local $5) + ) + (call_indirect (type $FUNCSIG$vijji) + (get_local $1) + (get_local $3) + (get_local $4) + (i32.add + (get_local $9) + (i32.const 8) + ) + (get_local $8) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 144) + ) + ) + (i32.const 1) + ) + (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeEdNS_15extended_symbolEEEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 f64) + (local $7 i64) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (set_local $9 + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $10) + ) + (set_local $2 + (i32.load offset=4 + (get_local $1) + ) + ) + (set_local $8 + (i32.load + (get_local $1) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $3 + (call $action_data_size) + ) + ) + ) + (br_if $label$2 + (i32.lt_u + (get_local $3) + (i32.const 513) + ) + ) + (set_local $1 + (call $malloc + (get_local $3) + ) + ) + (br $label$1) + ) + (set_local $1 + (i32.const 0) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $1 + (i32.sub + (get_local $10) + (i32.and + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $1) + (get_local $3) + ) + ) + ) + (i64.store + (tee_local $10 + (i32.add + (get_local $9) + (i32.const 56) + ) + ) + (i64.const 0) + ) + (i64.store offset=40 + (get_local $9) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $9) + (i64.const 0) + ) + (i64.store offset=48 + (get_local $9) + (i64.const 0) + ) + (i32.store offset=100 + (get_local $9) + (get_local $1) + ) + (i32.store offset=96 + (get_local $9) + (get_local $1) + ) + (i32.store offset=104 + (get_local $9) + (i32.add + (get_local $1) + (get_local $3) + ) + ) + (i32.store offset=64 + (get_local $9) + (i32.add + (get_local $9) + (i32.const 96) + ) + ) + (i32.store offset=80 + (get_local $9) + (i32.add + (get_local $9) + (i32.const 24) + ) + ) + (call $_ZN5boost6fusion6detail17for_each_unrolledILi4EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio11symbol_typeEdNS8_15extended_symbolEEEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_dSA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ + (i32.add + (get_local $9) + (i32.const 80) + ) + (i32.add + (get_local $9) + (i32.const 64) + ) + ) + (block $label$4 + (br_if $label$4 + (i32.lt_u + (get_local $3) + (i32.const 513) + ) + ) + (call $free + (get_local $1) + ) + ) + (set_local $5 + (i64.load offset=32 + (get_local $9) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 76) + ) + (i32.load + (i32.add + (get_local $9) + (i32.const 60) + ) + ) + ) + (i32.store + (tee_local $1 + (i32.add + (i32.add + (get_local $9) + (i32.const 64) + ) + (i32.const 8) + ) + ) + (i32.load + (get_local $10) + ) + ) + (set_local $4 + (i64.load offset=24 + (get_local $9) + ) + ) + (i32.store offset=64 + (get_local $9) + (i32.load offset=48 + (get_local $9) + ) + ) + (i32.store offset=68 + (get_local $9) + (i32.load + (i32.add + (get_local $9) + (i32.const 52) + ) + ) + ) + (set_local $6 + (f64.load + (i32.add + (get_local $9) + (i32.const 40) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 80) + ) + (i32.const 8) + ) + (i64.load + (get_local $1) + ) + ) + (i64.store offset=80 + (get_local $9) + (i64.load offset=64 + (get_local $9) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.shr_s + (get_local $2) + (i32.const 1) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (i32.and + (get_local $2) + (i32.const 1) + ) + ) + ) + (set_local $8 + (i32.load + (i32.add + (i32.load + (get_local $1) + ) + (get_local $8) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.const 8) + ) + (tee_local $7 + (i64.load + (i32.add + (i32.add + (get_local $9) + (i32.const 80) + ) + (i32.const 8) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $9) + (i32.const 8) + ) + (i32.const 8) + ) + (get_local $7) + ) + (i64.store offset=96 + (get_local $9) + (tee_local $7 + (i64.load offset=80 + (get_local $9) + ) + ) + ) + (i64.store offset=8 + (get_local $9) + (get_local $7) + ) + (call_indirect (type $FUNCSIG$vijjdi) + (get_local $1) + (get_local $4) + (get_local $5) + (get_local $6) + (i32.add + (get_local $9) + (i32.const 8) + ) + (get_local $8) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 112) + ) + ) + (i32.const 1) + ) + (func $_ZN5eosio18unpack_action_dataINS_8exchange5tradeEEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (set_local $4 + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $2) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $3 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (get_local $2) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $3) + (get_local $1) + ) + ) + (set_local $2 + (call $_ZN5eosio8exchange5tradeC2Ev + (get_local $0) + ) + ) + (i32.store offset=4 + (get_local $4) + (get_local $3) + ) + (i32.store + (get_local $4) + (get_local $3) + ) + (i32.store offset=8 + (get_local $4) + (i32.add + (get_local $3) + (get_local $1) + ) + ) + (i32.store offset=16 + (get_local $4) + (get_local $4) + ) + (i32.store offset=28 + (get_local $4) + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + (i32.store offset=24 + (get_local $4) + (get_local $2) + ) + (i32.store offset=32 + (get_local $4) + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + (i32.store offset=36 + (get_local $4) + (i32.add + (get_local $2) + (i32.const 40) + ) + ) + (i32.store offset=40 + (get_local $4) + (i32.add + (get_local $2) + (i32.const 64) + ) + ) + (i32.store offset=44 + (get_local $4) + (i32.add + (get_local $2) + (i32.const 68) + ) + ) + (call $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_RmRhEEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange5tradeELPv0EEERT_SN_RT0_EUlSN_E_JLj0ELj1ELj2ELj3ELj4ELj5EEEEvSN_OSO_NSt3__116integer_sequenceIjJXspT1_EEEENSS_17integral_constantIbLb0EEE + (i32.add + (get_local $4) + (i32.const 24) + ) + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $4) + (i32.const 48) + ) + ) + ) + (func $_ZN5eosio18unpack_action_dataINS_8exchange8upmarginEEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (set_local $3 + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $2) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $2 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $2) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $2) + (get_local $1) + ) + ) + (set_local $0 + (call $_ZN5eosio8exchange8upmarginC2Ev + (get_local $0) + ) + ) + (i32.store offset=12 + (get_local $3) + (get_local $2) + ) + (i32.store offset=8 + (get_local $3) + (get_local $2) + ) + (i32.store offset=16 + (get_local $3) + (i32.add + (get_local $2) + (get_local $1) + ) + ) + (i32.store offset=24 + (get_local $3) + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + (i32.store offset=36 + (get_local $3) + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (i32.store offset=32 + (get_local $3) + (get_local $0) + ) + (i32.store offset=40 + (get_local $3) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (i32.store offset=44 + (get_local $3) + (i32.add + (get_local $0) + (i32.const 40) + ) + ) + (call $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_EEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange8upmarginELPv0EEERT_SL_RT0_EUlSL_E_JLj0ELj1ELj2ELj3EEEEvSL_OSM_NSt3__116integer_sequenceIjJXspT1_EEEENSQ_17integral_constantIbLb0EEE + (i32.add + (get_local $3) + (i32.const 32) + ) + (i32.add + (get_local $3) + (i32.const 24) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 48) + ) + ) + ) + (func $_ZN5eosio18unpack_action_dataINS_8exchange11covermarginEEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (set_local $3 + (tee_local $2 + (i32.load offset=4 + (i32.const 0) + ) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $2 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $2) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $2) + (get_local $1) + ) + ) + (call $_ZN5eosio6unpackINS_8exchange11covermarginEEET_PKcj + (get_local $0) + (get_local $2) + (get_local $1) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $3) + ) + ) + (func $_ZN5eosio8currency5applyEyy (param $0 i32) (param $1 i64) (param $2 i64) (result i32) + (local $3 i32) + (local $4 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (set_local $3 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i64.ne + (i64.load + (get_local $0) + ) + (get_local $1) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i64.eq + (get_local $2) + (i64.const -3617168760277827584) + ) + ) + (br_if $label$1 + (i64.eq + (get_local $2) + (i64.const 5031766152489992192) + ) + ) + (br_if $label$0 + (i64.ne + (get_local $2) + (i64.const 8516769789752901632) + ) + ) + (call $prints + (i32.const 3568) + ) + (call $_ZN5eosio18unpack_action_dataINS_8currency5issueEEET_v + (get_local $4) + ) + (call $_ZN5eosio8currency2onERKNS0_5issueE + (get_local $0) + (get_local $4) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$0 + (i32.eqz + (i32.and + (i32.load8_u offset=24 + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $4) + (i32.const 32) + ) + ) + ) + (br $label$0) + ) + (call $prints + (i32.const 3584) + ) + (call $_ZN5eosio18unpack_action_dataINS_8currency8transferEEET_v + (get_local $4) + ) + (call $_ZN5eosio8currency2onERKNS0_8transferE + (get_local $0) + (get_local $4) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$0 + (i32.eqz + (i32.and + (i32.load8_u offset=32 + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $4) + (i32.const 40) + ) + ) + ) + (br $label$0) + ) + (call $prints + (i32.const 3600) + ) + (call $_ZN5eosio18unpack_action_dataINS_8currency6createEEET_v + (get_local $4) + ) + (call $require_auth + (i64.load + (get_local $4) + ) + ) + (call $_ZN5eosio8currency15create_currencyERKNS0_6createE + (get_local $0) + (get_local $4) + ) + (set_local $3 + (i32.const 1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $4) + (i32.const 48) + ) + ) + (get_local $3) + ) + (func $_ZN5eosio18unpack_action_dataINS_8currency5issueEEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (set_local $6 + (tee_local $4 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $4) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $2 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $4) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $2) + (get_local $1) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.const 1398362884) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $3 + (i64.const 5462355) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$2 + (block $label$3 + (loop $label$4 + (br_if $label$3 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $3) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$5 + (br_if $label$5 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$6 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$6 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$2) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 80) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (i32.const 0) + ) + (i64.store offset=24 align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store + (get_local $6) + (get_local $2) + ) + (i32.store offset=8 + (get_local $6) + (tee_local $4 + (i32.add + (get_local $2) + (get_local $1) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (get_local $1) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $2) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (get_local $4) + (tee_local $5 + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $5) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (get_local $4) + (tee_local $5 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 16) + ) + (get_local $5) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $6) + (i32.add + (get_local $2) + (i32.const 24) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE + (get_local $6) + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosio8currency2onERKNS0_5issueE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i32) + (local $12 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $12 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 128) + ) + ) + ) + (set_local $8 + (i64.load + (tee_local $11 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 88) + ) + (i32.const 32) + ) + (i32.const 0) + ) + (i64.store offset=104 + (get_local $12) + (i64.const -1) + ) + (i64.store offset=112 + (get_local $12) + (i64.const 0) + ) + (i64.store offset=88 + (get_local $12) + (i64.load + (get_local $0) + ) + ) + (i64.store offset=96 + (get_local $12) + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + ) + (call $require_auth + (i64.load offset=32 + (tee_local $2 + (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc + (i32.add + (get_local $12) + (i32.const 88) + ) + (get_local $8) + (i32.const 2224) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (block $label$0 + (br_if $label$0 + (i64.gt_u + (i64.add + (i64.load offset=8 + (get_local $1) + ) + (i64.const 4611686018427387903) + ) + (i64.const 9223372036854775806) + ) + ) + (set_local $8 + (i64.shr_u + (i64.load + (get_local $11) + ) + (i64.const 8) + ) + ) + (set_local $11 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $8) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $11 + (i32.add + (get_local $11) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $6 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $11 + (i32.add + (get_local $11) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $6 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 1840) + ) + (call $eosio_assert + (i64.gt_s + (i64.load + (get_local $5) + ) + (i64.const 0) + ) + (i32.const 3616) + ) + (i32.store offset=80 + (get_local $12) + (get_local $1) + ) + (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_2onERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ + (i32.add + (get_local $12) + (i32.const 88) + ) + (get_local $2) + (i64.const 0) + (i32.add + (get_local $12) + (i32.const 80) + ) + ) + (set_local $8 + (i64.load + (tee_local $11 + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + ) + (i64.store + (tee_local $6 + (i32.add + (i32.add + (get_local $12) + (i32.const 64) + ) + (i32.const 8) + ) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i64.store offset=64 + (get_local $12) + (i64.load + (get_local $5) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $12) + (i32.const 16) + ) + (i32.const 8) + ) + (i64.load + (get_local $6) + ) + ) + (i32.store offset=16 + (get_local $12) + (i32.load offset=64 + (get_local $12) + ) + ) + (i32.store offset=20 + (get_local $12) + (i32.load offset=68 + (get_local $12) + ) + ) + (call $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy + (get_local $0) + (get_local $8) + (i32.add + (get_local $12) + (i32.const 16) + ) + (get_local $2) + (get_local $8) + ) + (block $label$5 + (br_if $label$5 + (i64.eq + (tee_local $3 + (i64.load + (get_local $1) + ) + ) + (tee_local $4 + (i64.load + (get_local $11) + ) + ) + ) + ) + (i64.store + (i32.add + (i32.add + (get_local $12) + (i32.const 48) + ) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i64.store offset=48 + (get_local $12) + (i64.load + (get_local $5) + ) + ) + (drop + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ + (i32.add + (get_local $12) + (i32.const 32) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + (set_local $8 + (i64.const 0) + ) + (set_local $7 + (i64.const 59) + ) + (set_local $11 + (i32.const 1888) + ) + (set_local $9 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $8) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $11) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $10 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $8) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $10 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $10 + (i64.shl + (i64.and + (get_local $10) + (i64.const 31) + ) + (i64.and + (get_local $7) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $11 + (i32.add + (get_local $11) + (i32.const 1) + ) + ) + (set_local $8 + (i64.add + (get_local $8) + (i64.const 1) + ) + ) + (set_local $9 + (i64.or + (get_local $10) + (get_local $9) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $7 + (i64.add + (get_local $7) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store + (i32.add + (get_local $12) + (i32.const 8) + ) + (i64.load + (i32.add + (i32.add + (get_local $12) + (i32.const 48) + ) + (i32.const 8) + ) + ) + ) + (i64.store + (get_local $12) + (i64.load offset=48 + (get_local $12) + ) + ) + (call $_ZN5eosio8currency15inline_transferEyyNS_5assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy + (get_local $0) + (get_local $4) + (get_local $3) + (get_local $12) + (i32.add + (get_local $12) + (i32.const 32) + ) + (get_local $9) + ) + (br_if $label$5 + (i32.eqz + (i32.and + (i32.load8_u offset=32 + (get_local $12) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=40 + (get_local $12) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $5 + (i32.load offset=112 + (get_local $12) + ) + ) + ) + ) + (block $label$13 + (block $label$14 + (br_if $label$14 + (i32.eq + (tee_local $11 + (i32.load + (tee_local $6 + (i32.add + (get_local $12) + (i32.const 116) + ) + ) + ) + ) + (get_local $5) + ) + ) + (loop $label$15 + (set_local $1 + (i32.load + (tee_local $11 + (i32.add + (get_local $11) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (get_local $11) + (i32.const 0) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (br_if $label$15 + (i32.ne + (get_local $5) + (get_local $11) + ) + ) + ) + (set_local $11 + (i32.load + (i32.add + (get_local $12) + (i32.const 112) + ) + ) + ) + (br $label$13) + ) + (set_local $11 + (get_local $5) + ) + ) + (i32.store + (get_local $6) + (get_local $5) + ) + (call $_ZdlPv + (get_local $11) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $12) + (i32.const 128) + ) + ) + ) + (func $_ZN5eosio18unpack_action_dataINS_8currency6createEEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (set_local $6 + (tee_local $4 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $4) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $2 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $4) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $2) + (get_local $1) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.const 1398362884) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $3 + (i64.const 5462355) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$2 + (block $label$3 + (loop $label$4 + (br_if $label$3 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $3) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$5 + (br_if $label$5 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$6 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$6 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$2) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 80) + ) + (i32.store8 offset=26 + (get_local $0) + (i32.const 1) + ) + (i32.store16 offset=24 + (get_local $0) + (i32.const 257) + ) + (i32.store offset=4 + (get_local $6) + (get_local $2) + ) + (i32.store + (get_local $6) + (get_local $2) + ) + (i32.store offset=8 + (get_local $6) + (i32.add + (get_local $2) + (get_local $1) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency6createE + (get_local $6) + (get_local $0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency6createE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 25) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 26) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 1) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_2onERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) + (local $4 i64) + (local $5 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $5 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=48 + (get_local $1) + ) + (get_local $0) + ) + (i32.const 400) + ) + (call $eosio_assert + (i64.eq + (i64.load + (get_local $0) + ) + (call $current_receiver) + ) + (i32.const 448) + ) + (i64.store + (get_local $1) + (i64.add + (i64.load + (get_local $1) + ) + (i64.load offset=8 + (i32.load + (get_local $3) + ) + ) + ) + ) + (set_local $4 + (i64.load offset=8 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 544) + ) + (i32.store offset=56 + (get_local $5) + (i32.add + (get_local $5) + (i32.const 45) + ) + ) + (i32.store offset=52 + (get_local $5) + (get_local $5) + ) + (i32.store offset=48 + (get_local $5) + (get_local $5) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE + (i32.add + (get_local $5) + (i32.const 48) + ) + (get_local $1) + ) + ) + (call $db_update_i64 + (i32.load offset=52 + (get_local $1) + ) + (get_local $2) + (get_local $5) + (i32.const 45) + ) + (block $label$0 + (br_if $label$0 + (i64.lt_u + (tee_local $2 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.load offset=16 + (get_local $0) + ) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.add + (get_local $2) + (i64.const 1) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $5) + (i32.const 64) + ) + ) + ) + (func $_ZN5eosio8currency15inline_transferEyyNS_5assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy (param $0 i32) (param $1 i64) (param $2 i64) (param $3 i32) (param $4 i32) (param $5 i64) + (local $6 i64) + (local $7 i32) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i64) + (local $12 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $12 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (set_local $6 + (i64.load + (get_local $0) + ) + ) + (set_local $9 + (i64.const 0) + ) + (set_local $8 + (i64.const 59) + ) + (set_local $0 + (i32.const 1904) + ) + (set_local $10 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $9) + (i64.const 7) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $7 + (i32.load8_s + (get_local $0) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $11 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $9) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $7 + (select + (i32.add + (get_local $7) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $7) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $11 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $7) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $11 + (i64.shl + (i64.and + (get_local $11) + (i64.const 31) + ) + (i64.and + (get_local $8) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $9 + (i64.add + (get_local $9) + (i64.const 1) + ) + ) + (set_local $10 + (i64.or + (get_local $11) + (get_local $10) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $8 + (i64.add + (get_local $8) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 28) + ) + (i32.load + (i32.add + (get_local $3) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 24) + ) + (i32.load + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 20) + ) + (i32.load + (i32.add + (get_local $3) + (i32.const 4) + ) + ) + ) + (i64.store offset=16 + (get_local $12) + (get_local $2) + ) + (i64.store offset=8 + (get_local $12) + (get_local $1) + ) + (i32.store offset=24 + (get_local $12) + (i32.load + (get_local $3) + ) + ) + (drop + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 32) + ) + (get_local $4) + ) + ) + (i64.store offset=64 + (get_local $12) + (get_local $10) + ) + (i64.store offset=56 + (get_local $12) + (get_local $6) + ) + (i64.store + (tee_local $0 + (call $_Znwj + (i32.const 16) + ) + ) + (get_local $1) + ) + (i64.store offset=8 + (get_local $0) + (get_local $5) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 32) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 24) + ) + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 20) + ) + (get_local $7) + ) + (i32.store offset=72 + (get_local $12) + (get_local $0) + ) + (i32.store offset=84 + (get_local $12) + (i32.const 0) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 36) + ) + (i32.const 0) + ) + (set_local $0 + (i32.add + (tee_local $7 + (select + (i32.load + (i32.add + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.const 36) + ) + ) + (i32.shr_u + (tee_local $0 + (i32.load8_u offset=40 + (get_local $12) + ) + ) + (i32.const 1) + ) + (i32.and + (get_local $0) + (i32.const 1) + ) + ) + ) + (i32.const 32) + ) + ) + (set_local $9 + (i64.extend_u/i32 + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 28) + ) + ) + (loop $label$6 + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $9 + (i64.shr_u + (get_local $9) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.eqz + (get_local $0) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $0) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $12) + (i32.const 88) + ) + ) + ) + (set_local $0 + (i32.load + (i32.add + (get_local $12) + (i32.const 84) + ) + ) + ) + (br $label$7) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + ) + (i32.store offset=100 + (get_local $12) + (get_local $0) + ) + (i32.store offset=96 + (get_local $12) + (get_local $0) + ) + (i32.store offset=104 + (get_local $12) + (get_local $7) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency8transferE + (i32.add + (get_local $12) + (i32.const 96) + ) + (i32.add + (get_local $12) + (i32.const 8) + ) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (i32.and + (i32.load8_u + (i32.add + (get_local $12) + (i32.const 40) + ) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $12) + (i32.const 48) + ) + ) + ) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $12) + (i32.const 8) + ) + (i32.add + (get_local $12) + (i32.const 56) + ) + ) + (call $send_inline + (tee_local $0 + (i32.load offset=8 + (get_local $12) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $12) + ) + (get_local $0) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $0 + (i32.load offset=8 + (get_local $12) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $12) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (tee_local $0 + (i32.load offset=84 + (get_local $12) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 88) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $0 + (i32.load offset=72 + (get_local $12) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 76) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $12) + (i32.const 112) + ) + ) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i32.store offset=24 + (get_local $7) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $7) + (i64.const 0) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE + (get_local $0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ne + (tee_local $5 + (i32.load offset=20 + (get_local $7) + ) + ) + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + ) + (br_if $label$7 + (i32.and + (i32.load8_u + (get_local $1) + ) + (i32.const 1) + ) + ) + (i32.store16 + (get_local $1) + (i32.const 0) + ) + (set_local $4 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (br $label$6) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (br_if $label$0 + (i32.ge_u + (tee_local $2 + (i32.sub + (get_local $5) + (get_local $4) + ) + ) + (i32.const -16) + ) + ) + (br_if $label$5 + (i32.ge_u + (get_local $2) + (i32.const 11) + ) + ) + (i32.store8 + (get_local $7) + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (set_local $6 + (i32.or + (get_local $7) + (i32.const 1) + ) + ) + (br_if $label$4 + (get_local $2) + ) + (br $label$3) + ) + (i32.store8 + (i32.load offset=8 + (get_local $1) + ) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $1) + (i32.const 0) + ) + (set_local $4 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj + (get_local $1) + (i32.const 0) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (br_if $label$2 + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + (br $label$1) + ) + (set_local $6 + (call $_Znwj + (tee_local $5 + (i32.and + (i32.add + (get_local $2) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.or + (get_local $5) + (i32.const 1) + ) + ) + (i32.store offset=8 + (get_local $7) + (get_local $6) + ) + (i32.store offset=4 + (get_local $7) + (get_local $2) + ) + ) + (set_local $3 + (get_local $2) + ) + (set_local $5 + (get_local $6) + ) + (loop $label$9 + (i32.store8 + (get_local $5) + (i32.load8_u + (get_local $4) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (br_if $label$9 + (tee_local $3 + (i32.add + (get_local $3) + (i32.const -1) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (get_local $2) + ) + ) + ) + (i32.store8 + (get_local $6) + (i32.const 0) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.and + (i32.load8_u + (get_local $1) + ) + (i32.const 1) + ) + ) + (i32.store16 + (get_local $1) + (i32.const 0) + ) + (br $label$10) + ) + (i32.store8 + (i32.load offset=8 + (get_local $1) + ) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $1) + (i32.const 0) + ) + ) + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj + (get_local $1) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i64.store align=4 + (get_local $1) + (i64.load + (get_local $7) + ) + ) + (br_if $label$1 + (i32.eqz + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $7) + (get_local $4) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + (return + (get_local $0) + ) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $7) + ) + (unreachable) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.const 704) + ) + (set_local $4 + (i32.load8_u + (tee_local $5 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $7 + (i32.and + (get_local $7) + (i32.const 255) + ) + ) + ) + ) + (get_local $6) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.le_u + (tee_local $3 + (i32.wrap/i64 + (get_local $6) + ) + ) + (tee_local $2 + (i32.sub + (tee_local $7 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $1) + (i32.sub + (get_local $3) + (get_local $2) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + (set_local $4 + (i32.load + (get_local $1) + ) + ) + (br $label$1) + ) + (br_if $label$1 + (i32.ge_u + (get_local $3) + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (tee_local $7 + (i32.add + (get_local $4) + (get_local $3) + ) + ) + ) + ) + (call $eosio_assert + (i32.ge_u + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $5) + ) + (tee_local $5 + (i32.sub + (get_local $7) + (get_local $4) + ) + ) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $4) + (i32.load + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (get_local $5) + ) + ) + (i32.store + (get_local $7) + (i32.add + (i32.load + (get_local $7) + ) + (get_local $5) + ) + ) + (get_local $0) + ) + (func $_ZN5eosio6unpackINS_8exchange11covermarginEEET_PKcj (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $3 + (i64.const 5462355) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $3) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 80) + ) + (call $eosio_assert + (i32.gt_u + (get_local $2) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $1) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (tee_local $4 + (i32.and + (get_local $2) + (i32.const -8) + ) + ) + (i32.const 8) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $4) + (i32.const 16) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 16) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $4) + (i32.const 24) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $4) + (i32.const 32) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 32) + ) + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.const 8) + ) + ) + ) + (func $_ZN5eosio8exchange8upmarginC2Ev (param $0 i32) (result i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 48) + ) + ) + (i64.const 1398362884) + ) + (i64.store offset=40 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$5 + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (get_local $0) + ) + (func $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_EEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange8upmarginELPv0EEERT_SL_RT0_EUlSL_E_JLj0ELj1ELj2ELj3EEEEvSL_OSM_NSt3__116integer_sequenceIjJXspT1_EEEENSQ_17integral_constantIbLb0EEE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (set_local $3 + (i32.load + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $3 + (i32.load offset=4 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $3 + (i32.load offset=8 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $4) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $4) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $0 + (i32.load offset=12 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $0) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $1 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $1) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $1 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $1) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (func $_ZN5eosio8exchange5tradeC2Ev (param $0 i32) (result i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i64.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 48) + ) + ) + (i64.const 1398362884) + ) + (i64.store offset=40 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $1 + (i64.shr_u + (i64.load + (get_local $2) + ) + (i64.const 8) + ) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$5 + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $1) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $1 + (i64.shr_u + (get_local $1) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $3 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 80) + ) + (i32.store8 offset=68 + (get_local $0) + (i32.const 1) + ) + (i32.store offset=64 + (get_local $0) + (i32.const 0) + ) + (get_local $0) + ) + (func $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_RmRhEEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange5tradeELPv0EEERT_SN_RT0_EUlSN_E_JLj0ELj1ELj2ELj3ELj4ELj5EEEEvSN_OSO_NSt3__116integer_sequenceIjJXspT1_EEEENSS_17integral_constantIbLb0EEE (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (set_local $3 + (i32.load + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $3 + (i32.load offset=4 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $3 + (i32.load offset=8 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $4) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $4) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $3 + (i32.load offset=12 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $4) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $2) + ) + (get_local $4) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $3) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $3 + (i32.load offset=16 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 3) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 4) + ) + ) + (set_local $0 + (i32.load offset=20 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $0) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 1) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 1) + ) + ) + ) + (func $_ZN5boost6fusion6detail17for_each_unrolledILi4EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio11symbol_typeEdNS8_15extended_symbolEEEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_dSA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (set_local $3 + (i32.load + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $2) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $2) + (i32.add + (i32.load offset=4 + (get_local $2) + ) + (i32.const 8) + ) + ) + (set_local $2 + (i32.load + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $0 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $2) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $0 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $2) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $1 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $2) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $1) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $1) + (tee_local $0 + (i32.add + (i32.load offset=4 + (get_local $1) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $1) + ) + (get_local $0) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $2) + (i32.const 32) + ) + (i32.load offset=4 + (get_local $1) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $1) + (i32.add + (i32.load offset=4 + (get_local $1) + ) + (i32.const 8) + ) + ) + ) + (func $_ZN5eosio6unpackINSt3__15tupleIJyNS_11symbol_typeENS_14extended_assetEEEEEET_PKcj (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (i64.store + (get_local $0) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $4 + (i64.const 5462355) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $4) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $6 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $6 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 80) + ) + (call $eosio_assert + (i32.gt_u + (get_local $2) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $1) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (tee_local $5 + (i32.and + (get_local $2) + (i32.const -8) + ) + ) + (i32.const 8) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $5) + (i32.const 16) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 16) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $5) + (i32.const 24) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $5) + (i32.const 32) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $3) + (i32.add + (get_local $1) + (i32.const 32) + ) + (i32.const 8) + ) + ) + ) + (func $_ZN5eosio6unpackINSt3__15tupleIJyNS_5assetEmNS_14extended_assetES4_EEEEET_PKcj (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i64) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $6 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $3 + (i64.const 5462355) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $3) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$3 + (br_if $label$3 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$4 + (br_if $label$1 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$4 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$0) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 80) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 48) + ) + (i64.const 0) + ) + (i32.store offset=24 + (get_local $0) + (i32.const 0) + ) + (i64.store offset=32 + (get_local $0) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 40) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $3 + (i64.const 5462355) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$5 + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $3) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$8 + (br_if $label$8 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$9 + (br_if $label$6 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$9 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (br_if $label$7 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$5) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 80) + ) + (i64.store offset=56 + (get_local $0) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 72) + ) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 64) + ) + (i64.const 1398362884) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 16) + ) + (set_local $3 + (i64.const 5462355) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$10 + (block $label$11 + (loop $label$12 + (br_if $label$11 + (i32.gt_u + (i32.add + (i32.shl + (i32.wrap/i64 + (get_local $3) + ) + (i32.const 24) + ) + (i32.const -1073741825) + ) + (i32.const 452984830) + ) + ) + (block $label$13 + (br_if $label$13 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (loop $label$14 + (br_if $label$11 + (i64.ne + (i64.and + (tee_local $3 + (i64.shr_u + (get_local $3) + (i64.const 8) + ) + ) + (i64.const 255) + ) + (i64.const 0) + ) + ) + (br_if $label$14 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + ) + ) + (set_local $5 + (i32.const 1) + ) + (br_if $label$12 + (i32.lt_s + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 7) + ) + ) + (br $label$10) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $5) + (i32.const 80) + ) + (i32.store offset=4 + (get_local $6) + (get_local $1) + ) + (i32.store + (get_local $6) + (get_local $1) + ) + (i32.store offset=8 + (get_local $6) + (i32.add + (get_local $1) + (get_local $2) + ) + ) + (i32.store offset=16 + (get_local $6) + (get_local $6) + ) + (i32.store offset=24 + (get_local $6) + (get_local $0) + ) + (call $_ZN5boost6fusion6detail17for_each_unrolledILi5EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio5assetEmNS8_14extended_assetESA_EEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_mSA_SA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ + (i32.add + (get_local $6) + (i32.const 24) + ) + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $6) + (i32.const 32) + ) + ) + ) + (func $_ZN5boost6fusion6detail17for_each_unrolledILi5EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio5assetEmNS8_14extended_assetESA_EEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_mSA_SA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (set_local $2 + (i32.load + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $3) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $2) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (set_local $0 + (i32.load + (get_local $0) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $3) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $3) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $3) + ) + ) + (i32.const 3) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $3) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 32) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $3) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 40) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $3) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 48) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (i32.load offset=4 + (get_local $3) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 56) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $1 + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $3) + ) + (get_local $1) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 64) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $1 + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $3) + ) + (get_local $1) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 72) + ) + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.add + (i32.load offset=4 + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency8transferE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 7) + ) + (i32.const 688) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $0) + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 8) + ) + ) + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE + (get_local $0) + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + (func $apply (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i64.store + (i32.add + (get_local $3) + (i32.const 32) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $3) + (i32.const 40) + ) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $3) + (get_local $0) + ) + (i64.store offset=8 + (get_local $3) + (get_local $0) + ) + (i64.store offset=24 + (get_local $3) + (get_local $0) + ) + (call $_ZN5eosio8exchange5applyEyy + (i32.add + (get_local $3) + (i32.const 8) + ) + (get_local $1) + (get_local $2) + ) + (call $eosio_exit + (i32.const 0) + ) + (unreachable) + ) + (func $_Znwj (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (block $label$0 + (br_if $label$0 + (tee_local $0 + (call $malloc + (tee_local $1 + (select + (get_local $0) + (i32.const 1) + (get_local $0) + ) + ) + ) + ) + ) + (loop $label$1 + (set_local $0 + (i32.const 0) + ) + (br_if $label$0 + (i32.eqz + (tee_local $2 + (i32.load offset=3648 + (i32.const 0) + ) + ) + ) + ) + (call_indirect (type $FUNCSIG$v) + (get_local $2) + ) + (br_if $label$1 + (i32.eqz + (tee_local $0 + (call $malloc + (get_local $1) + ) + ) + ) + ) + ) + ) + (get_local $0) + ) + (func $_ZdlPv (param $0 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $0) + ) + ) + (call $free + (get_local $0) + ) + ) + ) + (func $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv (param $0 i32) + (call $abort) + (unreachable) + ) + (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (br_if $label$0 + (i32.ge_u + (get_local $1) + (i32.const -16) + ) + ) + (set_local $2 + (i32.const 10) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.and + (tee_local $5 + (i32.load8_u + (get_local $0) + ) + ) + (i32.const 1) + ) + ) + ) + (set_local $2 + (i32.add + (i32.and + (tee_local $5 + (i32.load + (get_local $0) + ) + ) + (i32.const -2) + ) + (i32.const -1) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + (set_local $3 + (i32.shr_u + (i32.and + (get_local $5) + (i32.const 254) + ) + (i32.const 1) + ) + ) + (br $label$2) + ) + (set_local $3 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (set_local $4 + (i32.const 10) + ) + (block $label$4 + (br_if $label$4 + (i32.lt_u + (tee_local $1 + (select + (get_local $3) + (get_local $1) + (i32.gt_u + (get_local $3) + (get_local $1) + ) + ) + ) + (i32.const 11) + ) + ) + (set_local $4 + (i32.add + (i32.and + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const -16) + ) + (i32.const -1) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eq + (get_local $4) + (get_local $2) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.ne + (get_local $4) + (i32.const 10) + ) + ) + (set_local $6 + (i32.const 1) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (br $label$6) + ) + (set_local $1 + (call $_Znwj + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.gt_u + (get_local $4) + (get_local $2) + ) + ) + (br_if $label$5 + (i32.eqz + (get_local $1) + ) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.and + (tee_local $5 + (i32.load8_u + (get_local $0) + ) + ) + (i32.const 1) + ) + ) + (set_local $7 + (i32.const 1) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$6) + ) + (set_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (set_local $6 + (i32.const 1) + ) + (set_local $7 + (i32.const 1) + ) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + (set_local $5 + (i32.shr_u + (i32.and + (get_local $5) + (i32.const 254) + ) + (i32.const 1) + ) + ) + (br $label$10) + ) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + (drop + (call $memcpy + (get_local $1) + (get_local $2) + (get_local $5) + ) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (get_local $7) + ) + ) + (i32.store offset=4 + (get_local $0) + (get_local $3) + ) + (i32.store offset=8 + (get_local $0) + (get_local $1) + ) + (i32.store + (get_local $0) + (i32.or + (i32.add + (get_local $4) + (i32.const 1) + ) + (i32.const 1) + ) + ) + (return) + ) + (i32.store8 + (get_local $0) + (i32.shl + (get_local $3) + (i32.const 1) + ) + ) + ) + (return) + ) + (call $abort) + (unreachable) + ) + (func $_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEjjPKcj (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) + (local $5 i32) + (local $6 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (tee_local $5 + (i32.and + (tee_local $6 + (i32.load8_u + (get_local $0) + ) + ) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i32.shr_u + (get_local $6) + (i32.const 1) + ) + ) + (br $label$0) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (block $label$2 + (br_if $label$2 + (i32.eq + (get_local $4) + (i32.const -1) + ) + ) + (br_if $label$2 + (i32.lt_u + (get_local $6) + (get_local $1) + ) + ) + (set_local $6 + (select + (tee_local $6 + (i32.sub + (get_local $6) + (get_local $1) + ) + ) + (get_local $2) + (i32.lt_u + (get_local $6) + (get_local $2) + ) + ) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (get_local $5) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br $label$3) + ) + (set_local $0 + (i32.load offset=8 + (get_local $0) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (tee_local $2 + (select + (get_local $4) + (get_local $6) + (tee_local $5 + (i32.gt_u + (get_local $6) + (get_local $4) + ) + ) + ) + ) + ) + ) + (br_if $label$5 + (i32.eqz + (tee_local $1 + (call $memcmp + (i32.add + (get_local $0) + (get_local $1) + ) + (get_local $3) + (get_local $2) + ) + ) + ) + ) + (return + (get_local $1) + ) + ) + (return + (select + (i32.const -1) + (get_local $5) + (i32.lt_u + (get_local $6) + (get_local $4) + ) + ) + ) + ) + (call $abort) + (unreachable) + ) + (func $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv (param $0 i32) + (call $abort) + (unreachable) + ) + (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (i64.store align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.and + (i32.load8_u + (get_local $1) + ) + (i32.const 1) + ) + ) + (i64.store align=4 + (get_local $0) + (i64.load align=4 + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (i32.load + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + (return + (get_local $0) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $3 + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.const -16) + ) + ) + (set_local $2 + (i32.load offset=8 + (get_local $1) + ) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (get_local $3) + (i32.const 11) + ) + ) + (i32.store8 + (get_local $0) + (i32.shl + (get_local $3) + (i32.const 1) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br_if $label$3 + (get_local $3) + ) + (br $label$2) + ) + (set_local $1 + (call $_Znwj + (tee_local $4 + (i32.and + (i32.add + (get_local $3) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (get_local $0) + (i32.or + (get_local $4) + (i32.const 1) + ) + ) + (i32.store offset=8 + (get_local $0) + (get_local $1) + ) + (i32.store offset=4 + (get_local $0) + (get_local $3) + ) + ) + (drop + (call $memcpy + (get_local $1) + (get_local $2) + (get_local $3) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $1) + (get_local $3) + ) + (i32.const 0) + ) + (return + (get_local $0) + ) + ) + (call $abort) + (unreachable) + ) + (func $pow (param $0 f64) (param $1 f64) (result f64) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 f64) + (local $11 i64) + (local $12 f64) + (local $13 f64) + (local $14 f64) + (local $15 f64) + (local $16 f64) + (local $17 f64) + (local $18 f64) + (local $19 i32) + (local $20 f64) + (local $21 f64) + (set_local $21 + (f64.const 1) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (i32.or + (tee_local $8 + (i32.and + (tee_local $5 + (i32.wrap/i64 + (i64.shr_u + (tee_local $4 + (i64.reinterpret/f64 + (get_local $1) + ) + ) + (i64.const 32) + ) + ) + ) + (i32.const 2147483647) + ) + ) + (tee_local $6 + (i32.wrap/i64 + (get_local $4) + ) + ) + ) + ) + ) + (set_local $2 + (i32.wrap/i64 + (i64.shr_u + (tee_local $11 + (i64.reinterpret/f64 + (get_local $0) + ) + ) + (i64.const 32) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (tee_local $3 + (i32.wrap/i64 + (get_local $11) + ) + ) + ) + (br_if $label$0 + (i32.eq + (get_local $2) + (i32.const 1072693248) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $7 + (i32.and + (get_local $2) + (i32.const 2147483647) + ) + ) + (i32.const 2146435072) + ) + ) + (br_if $label$3 + (i32.and + (i32.ne + (get_local $3) + (i32.const 0) + ) + (i32.eq + (get_local $7) + (i32.const 2146435072) + ) + ) + ) + (br_if $label$3 + (i32.gt_u + (get_local $8) + (i32.const 2146435072) + ) + ) + (br_if $label$2 + (i32.eqz + (get_local $6) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $8) + (i32.const 2146435072) + ) + ) + ) + (return + (f64.add + (get_local $0) + (get_local $1) + ) + ) + ) + (set_local $19 + (i32.const 0) + ) + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.gt_s + (get_local $2) + (i32.const -1) + ) + ) + (set_local $19 + (i32.const 2) + ) + (br_if $label$7 + (i32.gt_u + (get_local $8) + (i32.const 1128267775) + ) + ) + (set_local $19 + (i32.const 0) + ) + (br_if $label$7 + (i32.lt_u + (get_local $8) + (i32.const 1072693248) + ) + ) + (br_if $label$6 + (i32.lt_s + (i32.add + (tee_local $9 + (i32.shr_u + (get_local $8) + (i32.const 20) + ) + ) + (i32.const -1023) + ) + (i32.const 21) + ) + ) + (set_local $19 + (select + (i32.sub + (i32.const 2) + (i32.and + (tee_local $9 + (i32.shr_u + (get_local $6) + (tee_local $19 + (i32.sub + (i32.const 1075) + (get_local $9) + ) + ) + ) + ) + (i32.const 1) + ) + ) + (i32.const 0) + (i32.eq + (i32.shl + (get_local $9) + (get_local $19) + ) + (get_local $6) + ) + ) + ) + ) + (br_if $label$5 + (i32.eqz + (get_local $6) + ) + ) + (br $label$4) + ) + (set_local $19 + (i32.const 0) + ) + (br_if $label$4 + (get_local $6) + ) + (set_local $19 + (select + (i32.sub + (i32.const 2) + (i32.and + (tee_local $19 + (i32.shr_u + (get_local $8) + (tee_local $6 + (i32.sub + (i32.const 1043) + (get_local $9) + ) + ) + ) + ) + (i32.const 1) + ) + ) + (i32.const 0) + (i32.eq + (i32.shl + (get_local $19) + (get_local $6) + ) + (get_local $8) + ) + ) + ) + ) + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.ne + (get_local $8) + (i32.const 2146435072) + ) + ) + (br_if $label$0 + (i32.eqz + (i32.or + (i32.add + (get_local $7) + (i32.const -1072693248) + ) + (get_local $3) + ) + ) + ) + (br_if $label$10 + (i32.lt_u + (get_local $7) + (i32.const 1072693248) + ) + ) + (return + (select + (get_local $1) + (f64.const 0) + (i32.gt_s + (get_local $5) + (i32.const -1) + ) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.ne + (get_local $8) + (i32.const 1072693248) + ) + ) + (br_if $label$8 + (i32.le_s + (get_local $5) + (i32.const -1) + ) + ) + (return + (get_local $0) + ) + ) + (br_if $label$9 + (i32.ne + (get_local $5) + (i32.const 1073741824) + ) + ) + (return + (f64.mul + (get_local $0) + (get_local $0) + ) + ) + ) + (return + (select + (f64.const 0) + (f64.neg + (get_local $1) + ) + (i32.gt_s + (get_local $5) + (i32.const -1) + ) + ) + ) + ) + (br_if $label$4 + (i32.lt_s + (get_local $2) + (i32.const 0) + ) + ) + (br_if $label$4 + (i32.ne + (get_local $5) + (i32.const 1071644672) + ) + ) + (return + (call $sqrt + (get_local $0) + ) + ) + ) + (return + (f64.div + (f64.const 1) + (get_local $0) + ) + ) + ) + (set_local $21 + (call $fabs + (get_local $0) + ) + ) + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (block $label$17 + (br_if $label$17 + (get_local $3) + ) + (br_if $label$16 + (i32.eqz + (get_local $7) + ) + ) + (br_if $label$16 + (i32.eq + (i32.or + (get_local $7) + (i32.const 1073741824) + ) + (i32.const 2146435072) + ) + ) + ) + (set_local $10 + (f64.const 1) + ) + (br_if $label$13 + (i32.gt_s + (get_local $2) + (i32.const -1) + ) + ) + (br_if $label$15 + (i32.eq + (get_local $19) + (i32.const 1) + ) + ) + (br_if $label$13 + (get_local $19) + ) + (return + (f64.div + (tee_local $1 + (f64.sub + (get_local $0) + (get_local $0) + ) + ) + (get_local $1) + ) + ) + ) + (set_local $21 + (select + (f64.div + (f64.const 1) + (get_local $21) + ) + (get_local $21) + (i32.lt_s + (get_local $5) + (i32.const 0) + ) + ) + ) + (br_if $label$0 + (i32.gt_s + (get_local $2) + (i32.const -1) + ) + ) + (br_if $label$14 + (i32.eqz + (i32.or + (get_local $19) + (i32.add + (get_local $7) + (i32.const -1072693248) + ) + ) + ) + ) + (return + (select + (f64.neg + (get_local $21) + ) + (get_local $21) + (i32.eq + (get_local $19) + (i32.const 1) + ) + ) + ) + ) + (set_local $10 + (f64.const -1) + ) + (br $label$13) + ) + (return + (f64.div + (tee_local $1 + (f64.sub + (get_local $21) + (get_local $21) + ) + ) + (get_local $1) + ) + ) + ) + (block $label$18 + (block $label$19 + (block $label$20 + (block $label$21 + (block $label$22 + (block $label$23 + (block $label$24 + (block $label$25 + (block $label$26 + (block $label$27 + (br_if $label$27 + (i32.lt_u + (get_local $8) + (i32.const 1105199105) + ) + ) + (br_if $label$26 + (i32.lt_u + (get_local $8) + (i32.const 1139802113) + ) + ) + (br_if $label$23 + (i32.gt_u + (get_local $7) + (i32.const 1072693247) + ) + ) + (return + (select + (f64.const inf) + (f64.const 0) + (i32.lt_s + (get_local $5) + (i32.const 0) + ) + ) + ) + ) + (set_local $8 + (i32.const 0) + ) + (br_if $label$25 + (i32.gt_u + (get_local $7) + (i32.const 1048575) + ) + ) + (set_local $7 + (i32.wrap/i64 + (i64.shr_u + (i64.reinterpret/f64 + (tee_local $21 + (f64.mul + (get_local $21) + (f64.const 9007199254740992) + ) + ) + ) + (i64.const 32) + ) + ) + ) + (set_local $5 + (i32.const -53) + ) + (br $label$24) + ) + (br_if $label$22 + (i32.gt_u + (get_local $7) + (i32.const 1072693246) + ) + ) + (return + (f64.mul + (tee_local $1 + (select + (f64.const 1.e+300) + (f64.const 1e-300) + (i32.lt_s + (get_local $5) + (i32.const 0) + ) + ) + ) + (f64.mul + (get_local $1) + (get_local $10) + ) + ) + ) + ) + (set_local $5 + (i32.const 0) + ) + ) + (set_local $2 + (i32.or + (tee_local $6 + (i32.and + (get_local $7) + (i32.const 1048575) + ) + ) + (i32.const 1072693248) + ) + ) + (set_local $5 + (i32.add + (i32.add + (i32.shr_s + (get_local $7) + (i32.const 20) + ) + (get_local $5) + ) + (i32.const -1023) + ) + ) + (br_if $label$20 + (i32.lt_u + (get_local $6) + (i32.const 235663) + ) + ) + (br_if $label$21 + (i32.ge_u + (get_local $6) + (i32.const 767610) + ) + ) + (set_local $8 + (i32.const 1) + ) + (br $label$20) + ) + (return + (select + (f64.const inf) + (f64.const 0) + (i32.gt_s + (get_local $5) + (i32.const 0) + ) + ) + ) + ) + (br_if $label$19 + (i32.lt_u + (get_local $7) + (i32.const 1072693249) + ) + ) + (return + (f64.mul + (tee_local $1 + (select + (f64.const 1.e+300) + (f64.const 1e-300) + (i32.gt_s + (get_local $5) + (i32.const 0) + ) + ) + ) + (f64.mul + (get_local $1) + (get_local $10) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const -1048576) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + (set_local $20 + (f64.sub + (f64.sub + (f64.sub + (tee_local $0 + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (f64.add + (tee_local $20 + (f64.convert_s/i32 + (get_local $5) + ) + ) + (f64.add + (tee_local $18 + (f64.load + (i32.add + (tee_local $6 + (i32.shl + (get_local $8) + (i32.const 3) + ) + ) + (i32.const 3696) + ) + ) + ) + (f64.add + (tee_local $12 + (f64.mul + (tee_local $0 + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (f64.add + (tee_local $14 + (f64.mul + (tee_local $0 + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (tee_local $21 + (f64.mul + (tee_local $14 + (f64.sub + (tee_local $12 + (f64.reinterpret/i64 + (i64.or + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 32) + ) + (i64.and + (i64.reinterpret/f64 + (get_local $21) + ) + (i64.const 4294967295) + ) + ) + ) + ) + (tee_local $13 + (f64.load + (i32.add + (get_local $6) + (i32.const 3664) + ) + ) + ) + ) + ) + (tee_local $15 + (f64.div + (f64.const 1) + (f64.add + (get_local $13) + (get_local $12) + ) + ) + ) + ) + ) + ) + (i64.const -4294967296) + ) + ) + ) + (tee_local $0 + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (f64.add + (f64.add + (tee_local $17 + (f64.mul + (get_local $0) + (get_local $0) + ) + ) + (f64.const 3) + ) + (tee_local $13 + (f64.add + (f64.mul + (f64.add + (get_local $21) + (get_local $0) + ) + (tee_local $12 + (f64.mul + (get_local $15) + (f64.sub + (f64.sub + (get_local $14) + (f64.mul + (get_local $0) + (tee_local $16 + (f64.reinterpret/i64 + (i64.shl + (i64.extend_u/i32 + (i32.add + (i32.add + (i32.or + (i32.shr_s + (get_local $2) + (i32.const 1) + ) + (i32.const 536870912) + ) + (i32.shl + (get_local $8) + (i32.const 18) + ) + ) + (i32.const 524288) + ) + ) + (i64.const 32) + ) + ) + ) + ) + ) + (f64.mul + (get_local $0) + (f64.sub + (get_local $12) + (f64.sub + (get_local $16) + (get_local $13) + ) + ) + ) + ) + ) + ) + ) + (f64.mul + (f64.mul + (tee_local $0 + (f64.mul + (get_local $21) + (get_local $21) + ) + ) + (get_local $0) + ) + (f64.add + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.const 0.20697501780033842) + ) + (f64.const 0.23066074577556175) + ) + ) + (f64.const 0.272728123808534) + ) + ) + (f64.const 0.33333332981837743) + ) + ) + (f64.const 0.4285714285785502) + ) + ) + (f64.const 0.5999999999999946) + ) + ) + ) + ) + ) + ) + (i64.const -4294967296) + ) + ) + ) + ) + ) + (tee_local $21 + (f64.add + (f64.mul + (get_local $12) + (get_local $0) + ) + (f64.mul + (get_local $21) + (f64.sub + (get_local $13) + (f64.sub + (f64.add + (get_local $0) + (f64.const -3) + ) + (get_local $17) + ) + ) + ) + ) + ) + ) + ) + (i64.const -4294967296) + ) + ) + ) + (f64.const 0.9617967009544373) + ) + ) + (tee_local $13 + (f64.add + (f64.load + (i32.add + (get_local $6) + (i32.const 3680) + ) + ) + (f64.add + (f64.mul + (f64.sub + (get_local $21) + (f64.sub + (get_local $0) + (get_local $14) + ) + ) + (f64.const 0.9617966939259756) + ) + (f64.mul + (get_local $0) + (f64.const -7.028461650952758e-09) + ) + ) + ) + ) + ) + ) + ) + ) + (i64.const -4294967296) + ) + ) + ) + (get_local $20) + ) + (get_local $18) + ) + (get_local $12) + ) + ) + (br $label$18) + ) + (set_local $20 + (f64.sub + (tee_local $0 + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (f64.add + (tee_local $21 + (f64.mul + (tee_local $0 + (f64.add + (get_local $21) + (f64.const -1) + ) + ) + (f64.const 1.4426950216293335) + ) + ) + (tee_local $13 + (f64.add + (f64.mul + (get_local $0) + (f64.const 1.9259629911266175e-08) + ) + (f64.mul + (f64.mul + (f64.mul + (get_local $0) + (get_local $0) + ) + (f64.sub + (f64.const 0.5) + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.const -0.25) + ) + (f64.const 0.3333333333333333) + ) + ) + ) + ) + (f64.const -1.4426950408889634) + ) + ) + ) + ) + ) + (i64.const -4294967296) + ) + ) + ) + (get_local $21) + ) + ) + ) + (set_local $8 + (i32.wrap/i64 + (tee_local $4 + (i64.reinterpret/f64 + (tee_local $0 + (f64.add + (tee_local $21 + (f64.mul + (tee_local $12 + (f64.reinterpret/i64 + (i64.and + (get_local $4) + (i64.const -4294967296) + ) + ) + ) + (get_local $0) + ) + ) + (tee_local $1 + (f64.add + (f64.mul + (f64.sub + (get_local $1) + (get_local $12) + ) + (get_local $0) + ) + (f64.mul + (f64.sub + (get_local $13) + (get_local $20) + ) + (get_local $1) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (block $label$28 + (block $label$29 + (block $label$30 + (block $label$31 + (block $label$32 + (br_if $label$32 + (i32.lt_s + (tee_local $2 + (i32.wrap/i64 + (i64.shr_u + (get_local $4) + (i64.const 32) + ) + ) + ) + (i32.const 1083179008) + ) + ) + (br_if $label$31 + (i32.eqz + (i32.or + (i32.add + (get_local $2) + (i32.const -1083179008) + ) + (get_local $8) + ) + ) + ) + (return + (f64.mul + (f64.mul + (get_local $10) + (f64.const 1.e+300) + ) + (f64.const 1.e+300) + ) + ) + ) + (br_if $label$29 + (i32.lt_u + (i32.and + (get_local $2) + (i32.const 2147482624) + ) + (i32.const 1083231232) + ) + ) + (br_if $label$30 + (i32.eqz + (i32.or + (i32.add + (get_local $2) + (i32.const 1064252416) + ) + (get_local $8) + ) + ) + ) + (return + (f64.mul + (f64.mul + (get_local $10) + (f64.const 1e-300) + ) + (f64.const 1e-300) + ) + ) + ) + (br_if $label$29 + (i32.or + (f64.le + (tee_local $12 + (f64.add + (get_local $1) + (f64.const 8.008566259537294e-17) + ) + ) + (tee_local $0 + (f64.sub + (get_local $0) + (get_local $21) + ) + ) + ) + (i32.or + (f64.ne + (get_local $12) + (get_local $12) + ) + (f64.ne + (get_local $0) + (get_local $0) + ) + ) + ) + ) + (return + (f64.mul + (f64.mul + (get_local $10) + (f64.const 1.e+300) + ) + (f64.const 1.e+300) + ) + ) + ) + (br_if $label$28 + (i32.eqz + (i32.or + (f64.gt + (get_local $1) + (tee_local $0 + (f64.sub + (get_local $0) + (get_local $21) + ) + ) + ) + (i32.or + (f64.ne + (get_local $1) + (get_local $1) + ) + (f64.ne + (get_local $0) + (get_local $0) + ) + ) + ) + ) + ) + ) + (block $label$33 + (block $label$34 + (br_if $label$34 + (i32.lt_u + (tee_local $8 + (i32.and + (get_local $2) + (i32.const 2147483647) + ) + ) + (i32.const 1071644673) + ) + ) + (set_local $2 + (select + (i32.sub + (i32.const 0) + (tee_local $5 + (i32.shr_u + (i32.or + (i32.and + (tee_local $8 + (i32.add + (i32.shr_u + (i32.const 1048576) + (i32.add + (i32.shr_u + (get_local $8) + (i32.const 20) + ) + (i32.const -1022) + ) + ) + (get_local $2) + ) + ) + (i32.const 1048575) + ) + (i32.const 1048576) + ) + (i32.sub + (i32.const 1043) + (tee_local $6 + (i32.and + (i32.shr_u + (get_local $8) + (i32.const 20) + ) + (i32.const 2047) + ) + ) + ) + ) + ) + ) + (get_local $5) + (i32.lt_s + (get_local $2) + (i32.const 0) + ) + ) + ) + (set_local $21 + (f64.sub + (get_local $21) + (f64.reinterpret/i64 + (i64.shl + (i64.extend_u/i32 + (i32.and + (get_local $8) + (i32.xor + (i32.shr_u + (i32.const 1048575) + (i32.add + (get_local $6) + (i32.const -1023) + ) + ) + (i32.const -1) + ) + ) + ) + (i64.const 32) + ) + ) + ) + ) + (br $label$33) + ) + (set_local $2 + (i32.const 0) + ) + ) + (block $label$35 + (br_if $label$35 + (i32.le_s + (i32.shr_s + (tee_local $8 + (i32.add + (i32.wrap/i64 + (i64.shr_u + (tee_local $4 + (i64.reinterpret/f64 + (tee_local $1 + (f64.sub + (f64.const 1) + (f64.sub + (f64.sub + (f64.div + (f64.mul + (tee_local $1 + (f64.add + (tee_local $12 + (f64.mul + (tee_local $0 + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (f64.add + (get_local $1) + (get_local $21) + ) + ) + (i64.const -4294967296) + ) + ) + ) + (f64.const 0.6931471824645996) + ) + ) + (tee_local $21 + (f64.add + (f64.mul + (f64.sub + (get_local $1) + (f64.sub + (get_local $0) + (get_local $21) + ) + ) + (f64.const 0.6931471805599453) + ) + (f64.mul + (get_local $0) + (f64.const -1.904654299957768e-09) + ) + ) + ) + ) + ) + (tee_local $0 + (f64.sub + (get_local $1) + (f64.mul + (tee_local $0 + (f64.mul + (get_local $1) + (get_local $1) + ) + ) + (f64.add + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.add + (f64.mul + (get_local $0) + (f64.const 4.1381367970572385e-08) + ) + (f64.const -1.6533902205465252e-06) + ) + ) + (f64.const 6.613756321437934e-05) + ) + ) + (f64.const -2.7777777777015593e-03) + ) + ) + (f64.const 0.16666666666666602) + ) + ) + ) + ) + ) + (f64.add + (get_local $0) + (f64.const -2) + ) + ) + (f64.add + (tee_local $0 + (f64.sub + (get_local $21) + (f64.sub + (get_local $1) + (get_local $12) + ) + ) + ) + (f64.mul + (get_local $1) + (get_local $0) + ) + ) + ) + (get_local $1) + ) + ) + ) + ) + ) + (i64.const 32) + ) + ) + (i32.shl + (get_local $2) + (i32.const 20) + ) + ) + ) + (i32.const 20) + ) + (i32.const 0) + ) + ) + (return + (f64.mul + (get_local $10) + (f64.reinterpret/i64 + (i64.or + (i64.shl + (i64.extend_u/i32 + (get_local $8) + ) + (i64.const 32) + ) + (i64.and + (get_local $4) + (i64.const 4294967295) + ) + ) + ) + ) + ) + ) + (return + (f64.mul + (get_local $10) + (call $scalbn + (get_local $1) + (get_local $2) + ) + ) + ) + ) + (return + (f64.mul + (f64.mul + (get_local $10) + (f64.const 1e-300) + ) + (f64.const 1e-300) + ) + ) + ) + (get_local $21) + ) + (func $sqrt (param $0 f64) (result f64) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (block $label$0 + (br_if $label$0 + (i32.ne + (i32.and + (tee_local $7 + (i32.wrap/i64 + (i64.shr_u + (tee_local $1 + (i64.reinterpret/f64 + (get_local $0) + ) + ) + (i64.const 32) + ) + ) + ) + (i32.const 2146435072) + ) + (i32.const 2146435072) + ) + ) + (return + (f64.add + (f64.mul + (get_local $0) + (get_local $0) + ) + (get_local $0) + ) + ) + ) + (set_local $2 + (i32.wrap/i64 + (get_local $1) + ) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.le_s + (get_local $7) + (i32.const 0) + ) + ) + (br_if $label$3 + (tee_local $8 + (i32.wrap/i64 + (i64.shr_u + (get_local $1) + (i64.const 52) + ) + ) + ) + ) + (set_local $8 + (i32.const 1) + ) + (set_local $9 + (get_local $2) + ) + (br $label$4) + ) + (br_if $label$2 + (i32.eqz + (i32.or + (i32.and + (get_local $7) + (i32.const 2147483647) + ) + (get_local $2) + ) + ) + ) + (br_if $label$1 + (i32.lt_s + (get_local $7) + (i32.const 0) + ) + ) + (set_local $8 + (i32.const 1) + ) + (loop $label$6 + (set_local $8 + (i32.add + (get_local $8) + (i32.const -21) + ) + ) + (set_local $7 + (i32.shr_u + (get_local $2) + (i32.const 11) + ) + ) + (set_local $2 + (tee_local $9 + (i32.shl + (get_local $2) + (i32.const 21) + ) + ) + ) + (br_if $label$6 + (i32.eqz + (get_local $7) + ) + ) + ) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$7 + (br_if $label$7 + (i32.and + (get_local $7) + (i32.const 1048576) + ) + ) + (set_local $5 + (i32.const 0) + ) + (loop $label$8 + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (br_if $label$8 + (i32.eqz + (i32.and + (tee_local $7 + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + (i32.const 1048576) + ) + ) + ) + ) + ) + (set_local $2 + (i32.shl + (get_local $9) + (get_local $5) + ) + ) + (set_local $8 + (i32.sub + (get_local $8) + (get_local $5) + ) + ) + (set_local $7 + (i32.or + (i32.shr_u + (get_local $9) + (i32.sub + (i32.const 32) + (get_local $5) + ) + ) + (get_local $7) + ) + ) + ) + (set_local $7 + (i32.or + (i32.and + (get_local $7) + (i32.const 1048575) + ) + (i32.const 1048576) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (i32.and + (tee_local $10 + (i32.add + (get_local $8) + (i32.const -1023) + ) + ) + (i32.const 1) + ) + ) + ) + (set_local $7 + (i32.or + (i32.shl + (get_local $7) + (i32.const 1) + ) + (i32.shr_u + (get_local $2) + (i32.const 31) + ) + ) + ) + (set_local $2 + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + ) + (set_local $7 + (i32.or + (i32.shr_u + (get_local $2) + (i32.const 31) + ) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i32.const 0) + ) + (set_local $9 + (i32.const 2097152) + ) + (set_local $8 + (i32.const 0) + ) + (loop $label$10 + (set_local $6 + (get_local $5) + ) + (block $label$11 + (br_if $label$11 + (i32.lt_s + (get_local $7) + (tee_local $5 + (i32.add + (get_local $9) + (get_local $8) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $9) + (get_local $4) + ) + ) + (set_local $7 + (i32.sub + (get_local $7) + (get_local $5) + ) + ) + (set_local $8 + (i32.add + (get_local $5) + (get_local $9) + ) + ) + ) + (set_local $7 + (i32.or + (i32.shl + (get_local $7) + (i32.const 1) + ) + (i32.and + (i32.shr_u + (get_local $2) + (i32.const 30) + ) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (set_local $2 + (get_local $6) + ) + (br_if $label$10 + (tee_local $9 + (i32.shr_u + (get_local $9) + (i32.const 1) + ) + ) + ) + ) + (set_local $3 + (i32.shr_u + (get_local $10) + (i32.const 1) + ) + ) + (set_local $9 + (i32.const -2147483648) + ) + (set_local $10 + (i32.const 0) + ) + (set_local $2 + (i32.const 0) + ) + (loop $label$12 + (set_local $6 + (i32.add + (get_local $2) + (get_local $9) + ) + ) + (block $label$13 + (block $label$14 + (br_if $label$14 + (i32.gt_s + (get_local $7) + (get_local $8) + ) + ) + (br_if $label$13 + (i32.ne + (get_local $7) + (get_local $8) + ) + ) + (br_if $label$13 + (i32.lt_u + (get_local $5) + (get_local $6) + ) + ) + ) + (set_local $7 + (i32.add + (i32.sub + (get_local $7) + (get_local $8) + ) + (select + (i32.const -1) + (i32.const 0) + (i32.lt_u + (get_local $5) + (get_local $6) + ) + ) + ) + ) + (set_local $8 + (i32.add + (i32.and + (i32.lt_s + (get_local $6) + (i32.const 0) + ) + (i32.gt_s + (tee_local $2 + (i32.add + (get_local $6) + (get_local $9) + ) + ) + (i32.const -1) + ) + ) + (get_local $8) + ) + ) + (set_local $10 + (i32.add + (get_local $10) + (get_local $9) + ) + ) + (set_local $5 + (i32.sub + (get_local $5) + (get_local $6) + ) + ) + ) + (set_local $7 + (i32.or + (i32.shr_u + (get_local $5) + (i32.const 31) + ) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i32.shl + (get_local $5) + (i32.const 1) + ) + ) + (br_if $label$12 + (tee_local $9 + (i32.shr_u + (get_local $9) + (i32.const 1) + ) + ) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (i32.or + (get_local $5) + (get_local $7) + ) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eq + (get_local $10) + (i32.const -1) + ) + ) + (set_local $10 + (i32.add + (i32.and + (get_local $10) + (i32.const 1) + ) + (get_local $10) + ) + ) + (br $label$15) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $10 + (i32.const 0) + ) + ) + (set_local $0 + (f64.reinterpret/i64 + (i64.or + (i64.shl + (i64.extend_u/i32 + (i32.add + (i32.add + (i32.shl + (get_local $3) + (i32.const 20) + ) + (i32.shr_s + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 1071644672) + ) + ) + (i64.const 32) + ) + (i64.extend_u/i32 + (i32.or + (i32.shr_u + (get_local $10) + (i32.const 1) + ) + (i32.shl + (get_local $4) + (i32.const 31) + ) + ) + ) + ) + ) + ) + ) + (return + (get_local $0) + ) + ) + (f64.div + (tee_local $0 + (f64.sub + (get_local $0) + (get_local $0) + ) + ) + (get_local $0) + ) + ) + (func $fabs (param $0 f64) (result f64) + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (get_local $0) + ) + (i64.const 9223372036854775807) + ) + ) + ) + (func $scalbn (param $0 f64) (param $1 i32) (result f64) + (local $2 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.lt_s + (get_local $1) + (i32.const 1024) + ) + ) + (set_local $0 + (f64.mul + (get_local $0) + (f64.const 8988465674311579538646525e283) + ) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $2 + (i32.add + (get_local $1) + (i32.const -1023) + ) + ) + (i32.const 1024) + ) + ) + (set_local $1 + (select + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -2046) + ) + ) + (i32.const 1023) + (i32.lt_s + (get_local $1) + (i32.const 1023) + ) + ) + ) + (set_local $0 + (f64.mul + (get_local $0) + (f64.const 8988465674311579538646525e283) + ) + ) + (br $label$0) + ) + (br_if $label$0 + (i32.gt_s + (get_local $1) + (i32.const -1023) + ) + ) + (set_local $0 + (f64.mul + (get_local $0) + (f64.const 2.004168360008973e-292) + ) + ) + (br_if $label$1 + (i32.gt_s + (tee_local $2 + (i32.add + (get_local $1) + (i32.const 969) + ) + ) + (i32.const -1023) + ) + ) + (set_local $1 + (select + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1938) + ) + ) + (i32.const -1022) + (i32.gt_s + (get_local $1) + (i32.const -1022) + ) + ) + ) + (set_local $0 + (f64.mul + (get_local $0) + (f64.const 2.004168360008973e-292) + ) + ) + (br $label$0) + ) + (set_local $1 + (get_local $2) + ) + (br $label$0) + ) + (set_local $1 + (get_local $2) + ) + ) + (f64.mul + (get_local $0) + (f64.reinterpret/i64 + (i64.shl + (i64.extend_u/i32 + (i32.add + (get_local $1) + (i32.const 1023) + ) + ) + (i64.const 52) + ) + ) + ) + ) + (func $memcmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $2) + ) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.ne + (tee_local $3 + (i32.load8_u + (get_local $0) + ) + ) + (tee_local $4 + (i32.load8_u + (get_local $1) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br_if $label$2 + (tee_local $2 + (i32.add + (get_local $2) + (i32.const -1) + ) + ) + ) + (br $label$0) + ) + ) + (set_local $5 + (i32.sub + (get_local $3) + (get_local $4) + ) + ) + ) + (get_local $5) + ) + (func $strlen (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (set_local $2 + (get_local $0) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 3) + ) + ) + ) + (set_local $2 + (get_local $0) + ) + (loop $label$2 + (br_if $label$0 + (i32.eqz + (i32.load8_u + (get_local $2) + ) + ) + ) + (br_if $label$2 + (i32.and + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 3) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const -4) + ) + ) + (loop $label$3 + (br_if $label$3 + (i32.eqz + (i32.and + (i32.and + (i32.xor + (tee_local $1 + (i32.load + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + ) + (i32.const -1) + ) + (i32.add + (get_local $1) + (i32.const -16843009) + ) + ) + (i32.const -2139062144) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (i32.and + (get_local $1) + (i32.const 255) + ) + ) + ) + (loop $label$4 + (br_if $label$4 + (i32.load8_u + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (i32.sub + (get_local $2) + (get_local $0) + ) + ) + (func $malloc (param $0 i32) (result i32) + (call $_ZN5eosio14memory_manager6mallocEm + (i32.const 3712) + (get_local $0) + ) + ) + (func $_ZN5eosio14memory_manager6mallocEm (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (block $label$1 + (br_if $label$1 + (tee_local $13 + (i32.load offset=8384 + (get_local $0) + ) + ) + ) + (set_local $13 + (i32.const 16) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8384) + ) + (i32.const 16) + ) + ) + (set_local $2 + (select + (i32.sub + (i32.add + (get_local $1) + (i32.const 8) + ) + (tee_local $2 + (i32.and + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.const 7) + ) + ) + ) + (get_local $1) + (get_local $2) + ) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (tee_local $10 + (i32.load offset=8388 + (get_local $0) + ) + ) + (get_local $13) + ) + ) + (set_local $1 + (i32.add + (i32.add + (get_local $0) + (i32.mul + (get_local $10) + (i32.const 12) + ) + ) + (i32.const 8192) + ) + ) + (block $label$5 + (br_if $label$5 + (get_local $10) + ) + (br_if $label$5 + (i32.load + (tee_local $13 + (i32.add + (get_local $0) + (i32.const 8196) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 8192) + ) + (i32.store + (get_local $13) + (get_local $0) + ) + ) + (set_local $10 + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + (loop $label$6 + (block $label$7 + (br_if $label$7 + (i32.gt_u + (i32.add + (tee_local $13 + (i32.load offset=8 + (get_local $1) + ) + ) + (get_local $10) + ) + (i32.load + (get_local $1) + ) + ) + ) + (i32.store + (tee_local $13 + (i32.add + (i32.load offset=4 + (get_local $1) + ) + (get_local $13) + ) + ) + (i32.or + (i32.and + (i32.load + (get_local $13) + ) + (i32.const -2147483648) + ) + (get_local $2) + ) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (i32.add + (i32.load + (get_local $1) + ) + (get_local $10) + ) + ) + (i32.store + (get_local $13) + (i32.or + (i32.load + (get_local $13) + ) + (i32.const -2147483648) + ) + ) + (br_if $label$3 + (tee_local $1 + (i32.add + (get_local $13) + (i32.const 4) + ) + ) + ) + ) + (br_if $label$6 + (tee_local $1 + (call $_ZN5eosio14memory_manager16next_active_heapEv + (get_local $0) + ) + ) + ) + ) + ) + (set_local $4 + (i32.sub + (i32.const 2147483644) + (get_local $2) + ) + ) + (set_local $11 + (i32.add + (get_local $0) + (i32.const 8392) + ) + ) + (set_local $12 + (i32.add + (get_local $0) + (i32.const 8384) + ) + ) + (set_local $13 + (tee_local $3 + (i32.load offset=8392 + (get_local $0) + ) + ) + ) + (loop $label$8 + (call $eosio_assert + (i32.eq + (i32.load + (i32.add + (tee_local $1 + (i32.add + (get_local $0) + (i32.mul + (get_local $13) + (i32.const 12) + ) + ) + ) + (i32.const 8200) + ) + ) + (i32.load + (tee_local $5 + (i32.add + (get_local $1) + (i32.const 8192) + ) + ) + ) + ) + (i32.const 12112) + ) + (set_local $13 + (i32.add + (tee_local $6 + (i32.load + (i32.add + (get_local $1) + (i32.const 8196) + ) + ) + ) + (i32.const 4) + ) + ) + (loop $label$9 + (set_local $7 + (i32.add + (get_local $6) + (i32.load + (get_local $5) + ) + ) + ) + (set_local $1 + (i32.and + (tee_local $9 + (i32.load + (tee_local $8 + (i32.add + (get_local $13) + (i32.const -4) + ) + ) + ) + ) + (i32.const 2147483647) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.lt_s + (get_local $9) + (i32.const 0) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.ge_u + (get_local $1) + (get_local $2) + ) + ) + (loop $label$12 + (br_if $label$11 + (i32.ge_u + (tee_local $10 + (i32.add + (get_local $13) + (get_local $1) + ) + ) + (get_local $7) + ) + ) + (br_if $label$11 + (i32.lt_s + (tee_local $10 + (i32.load + (get_local $10) + ) + ) + (i32.const 0) + ) + ) + (br_if $label$12 + (i32.lt_u + (tee_local $1 + (i32.add + (i32.add + (get_local $1) + (i32.and + (get_local $10) + (i32.const 2147483647) + ) + ) + (i32.const 4) + ) + ) + (get_local $2) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.or + (select + (get_local $1) + (get_local $2) + (i32.lt_u + (get_local $1) + (get_local $2) + ) + ) + (i32.and + (get_local $9) + (i32.const -2147483648) + ) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.le_u + (get_local $1) + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $13) + (get_local $2) + ) + (i32.and + (i32.add + (get_local $4) + (get_local $1) + ) + (i32.const 2147483647) + ) + ) + ) + (br_if $label$2 + (i32.ge_u + (get_local $1) + (get_local $2) + ) + ) + ) + (br_if $label$9 + (i32.lt_u + (tee_local $13 + (i32.add + (i32.add + (get_local $13) + (get_local $1) + ) + (i32.const 4) + ) + ) + (get_local $7) + ) + ) + ) + (set_local $1 + (i32.const 0) + ) + (i32.store + (get_local $11) + (tee_local $13 + (select + (i32.const 0) + (tee_local $13 + (i32.add + (i32.load + (get_local $11) + ) + (i32.const 1) + ) + ) + (i32.eq + (get_local $13) + (i32.load + (get_local $12) + ) + ) + ) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $13) + (get_local $3) + ) + ) + ) + ) + (return + (get_local $1) + ) + ) + (i32.store + (get_local $8) + (i32.or + (i32.load + (get_local $8) + ) + (i32.const -2147483648) + ) + ) + (return + (get_local $13) + ) + ) + (i32.const 0) + ) + (func $_ZN5eosio14memory_manager16next_active_heapEv (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (set_local $1 + (i32.load offset=8388 + (get_local $0) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.load8_u offset=12198 + (i32.const 0) + ) + ) + ) + (set_local $7 + (i32.load offset=12200 + (i32.const 0) + ) + ) + (br $label$0) + ) + (set_local $7 + (current_memory) + ) + (i32.store8 offset=12198 + (i32.const 0) + (i32.const 1) + ) + (i32.store offset=12200 + (i32.const 0) + (tee_local $7 + (i32.shl + (get_local $7) + (i32.const 16) + ) + ) + ) + ) + (set_local $3 + (get_local $7) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.le_u + (tee_local $2 + (i32.shr_u + (i32.add + (get_local $7) + (i32.const 65535) + ) + (i32.const 16) + ) + ) + (tee_local $8 + (current_memory) + ) + ) + ) + (drop + (grow_memory + (i32.sub + (get_local $2) + (get_local $8) + ) + ) + ) + (set_local $8 + (i32.const 0) + ) + (br_if $label$4 + (i32.ne + (get_local $2) + (current_memory) + ) + ) + (set_local $3 + (i32.load offset=12200 + (i32.const 0) + ) + ) + ) + (set_local $8 + (i32.const 0) + ) + (i32.store offset=12200 + (i32.const 0) + (get_local $3) + ) + (br_if $label$4 + (i32.lt_s + (get_local $7) + (i32.const 0) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 12) + ) + ) + ) + (set_local $7 + (i32.sub + (i32.sub + (i32.add + (get_local $7) + (select + (i32.const 65536) + (i32.const 131072) + (tee_local $6 + (i32.lt_u + (tee_local $8 + (i32.and + (get_local $7) + (i32.const 65535) + ) + ) + (i32.const 64513) + ) + ) + ) + ) + (select + (get_local $8) + (i32.and + (get_local $7) + (i32.const 131071) + ) + (get_local $6) + ) + ) + (get_local $7) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.load8_u offset=12198 + (i32.const 0) + ) + ) + (set_local $3 + (current_memory) + ) + (i32.store8 offset=12198 + (i32.const 0) + (i32.const 1) + ) + (i32.store offset=12200 + (i32.const 0) + (tee_local $3 + (i32.shl + (get_local $3) + (i32.const 16) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 8192) + ) + ) + (br_if $label$3 + (i32.lt_s + (get_local $7) + (i32.const 0) + ) + ) + (set_local $6 + (get_local $3) + ) + (block $label$7 + (br_if $label$7 + (i32.le_u + (tee_local $8 + (i32.shr_u + (i32.add + (i32.add + (tee_local $5 + (i32.and + (i32.add + (get_local $7) + (i32.const 7) + ) + (i32.const -8) + ) + ) + (get_local $3) + ) + (i32.const 65535) + ) + (i32.const 16) + ) + ) + (tee_local $4 + (current_memory) + ) + ) + ) + (drop + (grow_memory + (i32.sub + (get_local $8) + (get_local $4) + ) + ) + ) + (br_if $label$3 + (i32.ne + (get_local $8) + (current_memory) + ) + ) + (set_local $6 + (i32.load offset=12200 + (i32.const 0) + ) + ) + ) + (i32.store offset=12200 + (i32.const 0) + (i32.add + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$3 + (i32.eq + (get_local $3) + (i32.const -1) + ) + ) + (br_if $label$2 + (i32.eq + (i32.add + (tee_local $6 + (i32.load + (i32.add + (tee_local $1 + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 12) + ) + ) + ) + (i32.const 8196) + ) + ) + ) + (tee_local $8 + (i32.load + (get_local $2) + ) + ) + ) + (get_local $3) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.eq + (get_local $8) + (tee_local $1 + (i32.load + (tee_local $5 + (i32.add + (get_local $1) + (i32.const 8200) + ) + ) + ) + ) + ) + ) + (i32.store + (tee_local $6 + (i32.add + (get_local $6) + (get_local $1) + ) + ) + (i32.or + (i32.and + (i32.load + (get_local $6) + ) + (i32.const -2147483648) + ) + (i32.add + (i32.sub + (i32.const -4) + (get_local $1) + ) + (get_local $8) + ) + ) + ) + (i32.store + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.store + (get_local $6) + (i32.and + (i32.load + (get_local $6) + ) + (i32.const 2147483647) + ) + ) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 8388) + ) + ) + (tee_local $2 + (i32.add + (i32.load + (get_local $2) + ) + (i32.const 1) + ) + ) + ) + (i32.store + (i32.add + (tee_local $0 + (i32.add + (get_local $0) + (i32.mul + (get_local $2) + (i32.const 12) + ) + ) + ) + (i32.const 8196) + ) + (get_local $3) + ) + (i32.store + (tee_local $8 + (i32.add + (get_local $0) + (i32.const 8192) + ) + ) + (get_local $7) + ) + ) + (return + (get_local $8) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eq + (tee_local $8 + (i32.load + (get_local $2) + ) + ) + (tee_local $7 + (i32.load + (tee_local $1 + (i32.add + (tee_local $3 + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 12) + ) + ) + ) + (i32.const 8200) + ) + ) + ) + ) + ) + ) + (i32.store + (tee_local $3 + (i32.add + (i32.load + (i32.add + (get_local $3) + (i32.const 8196) + ) + ) + (get_local $7) + ) + ) + (i32.or + (i32.and + (i32.load + (get_local $3) + ) + (i32.const -2147483648) + ) + (i32.add + (i32.sub + (i32.const -4) + (get_local $7) + ) + (get_local $8) + ) + ) + ) + (i32.store + (get_local $1) + (i32.load + (get_local $2) + ) + ) + (i32.store + (get_local $3) + (i32.and + (i32.load + (get_local $3) + ) + (i32.const 2147483647) + ) + ) + ) + (i32.store offset=8384 + (get_local $0) + (tee_local $3 + (i32.add + (i32.load + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 8388) + ) + ) + ) + (i32.const 1) + ) + ) + ) + (i32.store + (get_local $7) + (get_local $3) + ) + (return + (i32.const 0) + ) + ) + (i32.store + (get_local $2) + (i32.add + (get_local $8) + (get_local $7) + ) + ) + (get_local $2) + ) + (func $free (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (get_local $0) + ) + ) + (br_if $label$1 + (i32.lt_s + (tee_local $2 + (i32.load offset=12096 + (i32.const 0) + ) + ) + (i32.const 1) + ) + ) + (set_local $3 + (i32.const 11904) + ) + (set_local $1 + (i32.add + (i32.mul + (get_local $2) + (i32.const 12) + ) + (i32.const 11904) + ) + ) + (loop $label$2 + (br_if $label$1 + (i32.eqz + (tee_local $2 + (i32.load + (i32.add + (get_local $3) + (i32.const 4) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.gt_u + (i32.add + (get_local $2) + (i32.const 4) + ) + (get_local $0) + ) + ) + (br_if $label$0 + (i32.gt_u + (i32.add + (get_local $2) + (i32.load + (get_local $3) + ) + ) + (get_local $0) + ) + ) + ) + (br_if $label$2 + (i32.lt_u + (tee_local $3 + (i32.add + (get_local $3) + (i32.const 12) + ) + ) + (get_local $1) + ) + ) + ) + ) + (return) + ) + (i32.store + (tee_local $3 + (i32.add + (get_local $0) + (i32.const -4) + ) + ) + (i32.and + (i32.load + (get_local $3) + ) + (i32.const 2147483647) + ) + ) + ) + (func $__wasm_nullptr (type $FUNCSIG$v) + (unreachable) + ) +) diff --git a/tests/test_contracts/test_api.wasm b/tests/test_contracts/test_api.wasm new file mode 100644 index 0000000000000000000000000000000000000000..1e1ccf7bda252b9b8f9818d67659b4e8c0a4bca2 GIT binary patch literal 89736 zcmeFa3t(MUl{bDK_m!M`+fyh~+5#t+f+256LT{N_KOAx%@7q)pN! zt>7RHQXV3s8DRKCWeC2CAR6B&DiOoO|xgO&Zj( z;TwwPo^$rzYp=cb+H0@9_S$P(Eq&W;%d+ed`^bwd>mtj({37S_%lWYDB4^hwi+}K# z+J%4kbxS|iMK+StyDrB+JYSB~44)-mTAo;t5BRl_2YFGPAX(te`2S@VAfpJ=_%Hfp z0alkKxLvyl0QsaWpk2<|F2BeHWWum712Fr|&Z9MJ-L|fsHO?ZO>uUV-nK)4N2PaEK--bbo^ILL-P>f>2GV^+}6^+qqohP&Cdt5^!2s%_BZ#owRZ1p>uv6AyVN>F z^P7bBp0;h9mNhK3a{TO>{C!(mmg$#5>C5ty8YX-@Y1wl9HoLW@tF>)w^QN}VZN0s1 zo2)|#?}*kdZLOWnJ#D?)+WY#5cgv3cE#1BCZ)#yHta;3oZ{2|sUH#4d?c3TcTkzPl zv3YZQ*QVz7hLzSVewl?Y?VB!XSlQgy-;L%K_;C(CZtZ?!Tkpp19m&jje3xueKF_QL zeA>|is2KcL+twzXX=RxX}d%zkdfDR<)0dTS+;zYRl~fR*rkaIX8Y!3QlGvk%)aKW z3R83TZMF^~5PjQWs;HGJcC^QJ_&qx|Zf$Q(P*_;P2hlf4qYd{fG4*qQZ%bF7jtu?m zB{}{TtTo@;wtYu?Z<}zSHlUFFwA^x-ZBFzJ0NQ)n!Ip*+z2zfiUSAtHuB;c^ySBD> zwP}kBk{k~PpP)VYmduqZjk63M;{nE((#Yy>>FMrk-ng|JBdKf0HXZN>CBOFcwry^| z#7Ke!Eg}K&puN{lr_*kYW#v-obSed5ox;OH{NkVa(U-(u$ya(mG+TO3JmpeWHvSLa z7v@rjqO$bDTz28YT+Kp!$S$-FO{H0;0>r`^V6zZ;Qu2?*@DE@3H+ATtH8rW4n)KmE zWU_}Inm)89m9l#*bg*sN*>^8~i%qWX?!DBpUeWwlZQGm9S+-2%P2Y}fAmwY9HCt;Z zBtXRupy*oHbk2FNZC=)p9HMPI+qSN= z&O8Q1mM!aV!+=#zT(&C7vR&Q1+gi4++i9&kdP2sNrPQV!+qPY5$|B$TMHBKhBmwq! zH!nrDzt~T`$kwp36B*AdPJp*k>TTUzs`UJcm9C81-__mU-rBbA(n~M3UKdP&RZgaz z)`eBFn7L$g%htX&VD!I^oB(B+$GelU0JBuPfzu{3{O`q; z8J255RZ1G<{j1|9$s0{lkPB^)yS+k(|8KIsjB;~^0Mx&pNY(~LQKw-}G|2XUgl3Ao zh{a_qB$qrxnj*^^q_N2?rYRKZeaO%}RfcwCxJam;gs{9+$qwddsUr=NIh0Z2$pCpa zO3x(ooRowDX^u>-Q{mEu44bCHrH`H4HdT&I%&~c@9NU@WVxfK#R~>ND9>~aTJzGir zEr*wy-G6CMTOUZkACaO+Z%>d#(^s}`Y3Xgo2usBQy3x1G8bs}Y`qI_cPhE>yw+a7E$f{h^vT0L06%yp@ zngpbDS>KM0m@`DJMAmK@024r-B3VUi?TKb*|Eqv`U~x`Iw(hK+q`i{I~3}!J|lru zy+*}5rjc27Z)Dzi;#81z#A@aU)i;t_lj5Q{8r>f7FX6N@X>MgolRK*5(rHv+mL90! zP1DG2)-}leH`B;%mNCeE*)(zkHWxj}{pM-VUDr6seEBr!u9+jU?3xBLW(@`S1NL+X zUtYr%b`54@4BoA6UDjLVg$nhy9_vbhW*Dut_tKvJ?&ZqJ38mAlDw@qiw%cBYt}id6 zL#j%dXnwrPPD~qG(K2PiL?JZqYI|WNaD`3v66x32A|iF7FmUuml}=>2cB(8;MUmyL zc49I%P;_31Rb%A3t{Nb%2FmMJ%E-6b3Dv*=T254(ySim5ggn<*t1JQ&=la`8aslB4 zthd{VS=!Wha*T5#<2&qER?>0VDMsBebw^z@XeZPz19Me*R@3u;SFQF^&SlLJ$Q!El zb~2*@c;nPqvh5Mbo2JH+Sq;#?w?#lFS!DTgQ+bJ05!{>Yghr*UUmj_0rQ8Pe|Fw@I zRdxEsgxTI@m{=FETpV*Md#Am!`L9lC?e4i$c;JH8j;8Zo+rOe2%J$B-R;>BYZawd{ zOPfz=*@}fwi@dMHKkF7Hn~sab+Gp7^S#HJi+Pk%d6Z4&%$k*Jqt*8G|U~}uVa&K+v zy_lNAZT9hO;zZb|Bw=IF?&uZ8_jZ*a6Y?)#k<70vMRaC6N6q^tEhBU2#N{B$e865( z6|d#m8ObtOSfaoO?GvgOP{xquM}o#Ev1jTMiOi82b%#yaU4>W;()dIPQL#TXNgI}} zO45qYMkoK6irR_9U0w;_^fnhXpR~iONUhLX5=ddhv|oHNG!B@#x_g_qv~+EP{voJ- z%09a)kmU_#B+2-xD2N56S!gax)UwX{%=DX~Y{+KZqq1Q_+n243Oc68_b#YPjS&p|V z-LU*5Ayb?`i4?2&oPAo=ax0W~tCfTKv1e1>S^xmnZ zLYy@k;ScCcF|qTOL*egl+q`3Ib4w4`XAi0PotUwq%pRqgAD&b`cD21RGA07(KTb9* zSE-zCF3R3JHlmdbtArpCFfvRnfDc)pKt`=neZvcU4n56!XlTZ(;0JG(O1avcX%jq_6Od#WXBIqsW4sc&o9W;BwGEq(2+ z;JxqL>6V_Jt(RK=X{R=~Z0xgsXQ%nQ*?Qj2QuC)R{r6&WD2zyr&4?EycJl19R~gj_ByZZWmYLAw9fKsE&t%gk=>^c?D3eg*p)vyf2DV` zZQHv-E41pJR5)&R7Oe&+<=2LV^#FTVV1-BcOZhTt$=j2bzK-c@8gJ?K;eaiP1x*{2 zwWjFrnk#D^B{qOzxwRi2>5RS{&daEY9;d>9hH@iL@a{R+WUG=BVOuT2Z`kfE)*>~uk+n7)u{sh@mcP(nSVT)+6OIBH(&tICe-<8( z@2GdIu%`npud^Gix@_aAb(wJ7sY~M}=dN|)|AK5|=6@BeAbq@L6`k<5T^->*dwY1; zIR!g#!VlOTbxz*#P^tzwz1J6(&FmlZROZ)z%7USJ2g4dH+*t(MExuxERa2GKk)er>(8vgmXK=}rJ!C6KI6)PZj3j9~3j0+(O~>2={Kuqoq#pmwo4 zPxxY{vqDN(A=e?~^IxrO3-qm;#)oatiX$bo{3GV$XGk)WNa=zNo(*c3SUDM!W0Jx` z$uT*YCh&S|PBbP*^aBB`E7&LxDhKHX2ZO`^h0Sh37t}M6qw)A;nvBn3TZZz}w(VjF zQ^5G>>AEx$Qy9hIZbz_PSadmRhco_RY*65aSESAcOxGW9>QZ^zV*z}f-GS~01j+|+ z1d8*szYx-i1Kw)1PIi5Wka-<^qA&^gM0{DH`~+@C(Qa^Z0GB-{972`gmsFVZi}L{x z4;^5~QWD;gQ&IsV^w}Ulv+(4fjh}@b{%b&MaIGYHUvypjatA^yuot_zI>)eCE*wwS zrSOt=*WzymjfC*P7?t*>C~DlKs6pFB)VOFo9#y!wN#O#aOsnY#Qz+*>>bNeZ9cNcSeyz)f=qz>{x;h8RkDpXWo$I3e0tYCZ9gY$q z7mvj(W<1c|4YH`Nm?giZ!hP2EAj1iynCZXUG%Cz?)Mb#C-6^t7SRlQpi1C0bAsO)l zXq}LV#mrw|7=SH75eYyHvb4XW=l}taXs+kbCEmpp z0M})JJR4Ia(tsON2?g;*Nt80r9mNdWF(E65#iY5j7z;&Id={FAn!PI>HwBv7hNc+) zn0|rC1e&HN&@>&Ti5rkUMb2#Oce;OGF&O@+J8EjS?+hOCGTi~zJDd;uTa zbC5p;`DynTGborkdqFX?t^gsQ@qcbZMS*+}UbWEOnb2Bo0SN(5LQ1FF7$QZxVC7RD z1T3^6NCS!+%m1|v&T)baMTx_vr-f?_m<%9*afBBWRyh$6K>M*)Tq8>AJ+a*&N_1(}Xd!a^L}n7Po4 zBp1g53Zc)zH=K>V8VeJDt-o}>=UHf^tIyBOgFwq9bm&3!P7P;?kg|-nl4z54gk$e`Uw9BwBQKU z`^PAZYeFnxULVv@2e^Pe0y0@7lg07mBmG-wtA(!R_>Z zke`J{FLrzUIx3kXri7&B^976paMa;U8c!y9`8*d*DXhC(uDhriK^ZEsQjk(z!=W-{ zCzT-^qm1h=>aZvUVHfKfwo#4jq-q5DVn@0L#!rU2hMUxq&{EFjDXzOX+(b)qsU^9p zB~>Ddb;*oCG`kxzXevZ=GXzmt$tDqnkj+Btv%=vlnDJ1u$54&(ns82S-V^rFVQan2 zB_%V$i)QDSK9@ka9WsGMYVx%&OAspg2@})*Jl?SVxf3`em#29xUiQ~ud8h^e(E&K) zFNJdBZ{QrZ6q7!FR&oh&3g=1rMD;*se|)Dh1@SZj@g(!;LS1Z07C@$sU}-J@Rs$9$ z%M4!TCKBWMGMmqp*mgKuS8d{RX|0!o}MRO*f_56c{=(P!noz7>feNN@m zo`2$m+%9zHaI`ke_@@B=SP~G|DwPxNjMfZvj>>^y(y%hUB&I6jD&&W5w#syXsIHuR z#kN-yUJD~hiMMrVT*6eUpU*>?EG35gG$_`+*&KPJR);JazdX_Ul>vRy;gBcRuW~&q z)0iXQPs6yBi50$S8<*0t!dEgbWvK9F0vM~PN2RIorDL;Lw$d!7m_t>iS*#NC>6*p< zOqh#V%xZj6jGZ>56c!e=Wf=2VZ0w?Kh-*tXyli`zii~DlSt0=o1*CZ+YOZnOT^AT_ zb6hY&v8UnG5|gS}^KHmKDAG10A6GJBKJiQDe43if9!I7TCU{uVVsn1B!kjP2qElcB zQS<>uEHevfg}~|=CVhn`CjBHltnso`&tcjJI{`~TNtk!csy!`s^e4mMzO zSZA1hO*rU5xX~0O#$J5ID!XWvk~s6`Iy4m!)ZPmqj^7ld{MSO_1v&lb?QvWO1}_@D zW3xBvQUjlum}soH8||X`CpIpETB$vCG!&#rEwEivF%xF{(OWPh_O7;Oi+zmv!dfo) zidjz#FIig0)$}RmI<8oynHk+cp>ltQ zEzckpcZ!NGi3OvNAr=jkG;l`5O7lGz(+P$jd?20F#tAwBwp#aSkyA>k?a+at@4N)b zGXw?W4aXA9Z+uJBl2Bp-nEXDMbDUl2%OO2p8logdbXcWzjhkHcW*S9HIRMhSW;ga) zlhRt(;ut3sCs6E8iZLIlKF=H|%qPw>*#xqN%#~Bij6t@Nsxy`!U@tw1Yyc@T3Moz_ zc1>VyC~%`+hu+NR3&GbjE%3bma3DKUmxtq?e=J(zLW^?3fxPTdr^?2qtK-t9*~}_8 zn^|Huv(#*shT$mMq63}8UBODOB`N+Qvl(W|G|gsCtVQ9A4Ov--jX!EpF0JOfF@rhO zq8y_|rTi5!vV$)HWW{D44(0vB_+*D8PgA7z5`p1Y41tWE+;JN#FML%;@22@=oP;*Y+Y2WirXIw);R zptLk*3xFpM_#qD1fk;%1H>vv0XZAkmME(i>2~pLkE_yZ(Qr%MNiW~AG58}}^JgcfG zNO3_mLqtJ+jO@ru3E9!=$Yy68Wi7v6W`(ip2#W{UjAMoI>d4kkpSl~=MR z?O>)bPH5QqDR6CyrCh|f*bAN=4KlDYw-GUe0#R9OPNXd5Cby|9*+idgh83Tkl5qkX zh~?8Nwxu|&Ce_^pPEI(O#3?PPxQ+Qg7OQyPH%*){`?F2y#@SbL{alW4bv+;=q7x2P zL%1-55gx9F@T{4Kuy>60D$BCg_{Yl(g6E!*==u5QmY-yvz2(-K$cBGoYy3r$)x6Id ziQebj@a({CZ}{LD=H0tCIp3BhH#4E`TceX4=Cjg7d(XhyvdQlDM?XJu+ZS&61@dyz z+x_GXSO4_BTb?~Ep7$0f=Dq0I*N4Qs_hr{k#b%TMjxnk_!Lt|23>=d<#rhlt;mB-% zpA8MT2c9(ifZ=L|9^GnOJlOrKEgw3U46? z`y!g)#|iVI1az4Te!TD61URf;#!SM&l0Kq8 zmeZesd0I|?#`I_KFfFG)^PT;>3rY_F+g)I>qHB`0B;)#&@btS#Z?_$BZTF}JX5v|w9u{lpO&HtAo7{A}2}oZXx}6Xx?uMByN582Z2>>h9)3HGwEbth*r`JVN}xZ9#ij=^N8l$cUyw z;Oo{z88z*gn#LDJ$Zy>3_Oqz|18HkP3E>`!K{TfA0Y-EZ+Kwb?J64^x&Wxk2L9~*# z2MWmf z4-}%4&~`LQ+wtnOmF4P;qOC!+lC}p5(Mf1KfKz(V19XZQ3aZM4(q{EckqHLTO4=SM zL?@x`aFVv8)oCksp&7-u2GL5|9wmKV z$b^yVw5^$OI+#JUlC}p5(Mf1KnxySOu`1t+HFJ70VY=4Lsn!l$;J}H*tjoAcE81$! zj3)+zXeDhA6rw`gB%)?rR*d;J6OP2RMJr(FC!z6JlE#CJs_=1a zc%NZ39#Uk>X?$RjorK22ixPZ17SmV_bVgbns71|0OJXD^#$)=<2t+5L?ZD9q+72BZ z@oyQ*2TFmNoVEs0@a~L2bQ0PQCuutt(>5{39oXSEIeo_!*>c(Nia%C)`J*P}NoYKH z40arbJ@}T0pQ^fI#!lW4j-UzH4I0A_kT#BTudLbvF*#1$ zxUaC^{aGC4jC;~<8@my&Okh4-9dp@@m{FJy3?VYnND}q2mkjD7J_1lBQ6H?Y$}b|h zX9Cq@#x{uJAVflPyNw45QHi}#?g1KP;K*2?;OLR+v=x)djH0bUw34<53ekzQ#ld%Y zc!IXx@fIZBIG*q`vRHlwj@38)88}Yg@B?p3u`Z4)W(ERxE z-fAaY9pQsP4+DZcQ6ZFmN*<42eHuQQbhnIr9^pDN_MyYo`9mBX2T!EGB^({?aHs@f z0$54o;$D0UyhE+f(u(7s!KFZP+(xuG2Vr{{W(HY!u7<&;c$kDE1zsIah&TdtYFM(K z&KWqh6gVAxKW_a3909>oQKFBS@FqDpJxF9VhN{6#&Vwd!H>riIDo@eO>ksGc2ruaP zFdWC$Toa@bOX;#k_QPZ1t*=v zD2I&?Z@EhRnj3drwfll_7`%c^%)p%J$;mSjQX;ymM;2YOT) zI!~5z3@#H~m?Kfm#xit~MSP*u9s5&GVjS+50Psx$0i^N7S!;`1uBnZ0PF6Rrd7_4! zEOy+c!R00DNxP@aan*eELRBP~qEs;e>f$Pf6IFmRraUsoIYu=HkxXPLBilH#B*?aA z8dMXykZl|YkHHmXkWaw_Yc>7juPKtL%mw zr_&8!2^=zj6CC@XM6z)u8B^^j)rnbZaAhKm;rU=f_A|HkMaBt`(Q%x2xtKvDnK)s|3-q{A0bbfN)qmPeQoSDoEIVwft*Iw}I6YadxU^zer?g zmF%FOf}cP?o&LwFl=(qfnI0pqmE}&Ih!LomXu*|@2xUBiYzZR%-E@dZ;V!Z}E#zz5 zn5=h9>pcRq5OOEGzl&^#p7X@VGmBr{Y4A`=@RML=p}AVUg7G9;ix>^71}PGDM* zOhsyv)C5Uh)C`=4=pRGniSjRwq;NN<^sh#Zn4~7p6qDV9(#lg5ATQn{QZ0gI>Mr# zmj-HFk+Nf#(<@tI8v|m%mcYZh8XRF%O8Uk-hz4X(;G@19L>wNPS909EYVsJznfED(X4H<^C<{)>__n?aR(J4rEY6YoArdP$7 zRAGo!31fVEFb2OwG$V3V0vYseG*U0^Bt)W;YjM3@A82oaQVwFIKzC0~N#so-2u}UE0(*rWRH)1jL_5OIQ zp@L!~2(ww8VrAoTOzJQctAsH=Js5)zBq>%2WaxouAu=LBB8pW48J!-GaRE}|v11Yf zJhJ>*;ggVoKDb!qHtD*tij=b;+y)+mh%_Q15_5wOPOCY?4@P~b;$eSPa8N~6j7+bJ zv5G1-C0Y@Wr(`q8hEW~klh#o-poSlcnqgRQf9+t$MRklkG%Zq%#dRpD&aBdDL!5Ka zX_&kaR2GqN`*3PaXClj=jd^U`0O3^3E^VIzNU5CgJ$b=A%r=sepHyZNx-uodMNg

zCnc z_@HwtFcCaILiDug!H@AgEq?N2JWq?CP$w`pbxlFxhN>7B$}rw9Lo`JA79unoqK86^ zWkdW_h_P&lpHO2=;eNXmdu$Ammk{(C!Jxunge>`xXpS)B58L4(>%+l^IlAmRXk<9> z7~Wwc@UXi!umh`OvBi%lqt6?{Vdh00jOqnAMpMJau_OG>ap|Ba4?I%WV`vi-XiD^7 z#)>Ms67-&-voM%2jCk@h4kLy0sC0?L4C}uOzf|4?F^#hBdEQTL6VO}&S|RYb1WT9u z3!vv^8J*fHMSBM_NY63Gd?MsKb_k-7?^zA`PA@#3UCp9KiS5OBVn7yA>>cQ$64yN| zN76N}J2oZ|`(L&~|lp+OF5|RAfX~aQGCw64UpruG4v~2i2o}67`J@RTIk!473sOi?juO>KH z{}x*#uSWRpMyxn+_|0L&Xjtzi_$0`Iff==nIOGbVmAi-s%6VeqE+RUaTXWc%!pZE= zXBc!l%%daGhxi5OunQRdj29T>r9ar;Jl>2C*il0VAssQ@kTbv&`W^|sCg9sbz^W&} zdHloJknh3b1+0Nw^NJFR9n8vna;8{nM$rEa0=@|7s5Y=PJS%HV6v20M3|Zm@3M@NB zP*y=Yk%m*)X#Or$}`WWzB_2K@a_V!Fp}3If}~K8AfHoc-n%GK{~+t7AAJ7G3k) zNZa7|o__LMuhH$M&wc-6-@W6B>wjc-&&W3}Q#3NF+O<8MNJOfX^hQgW|J zoQ8W%oakN?5Fdkgq3&>E@DnXwvj9XFnWOZ)%SP~`=vs&i24FX3NpgWQGei;ZY#=k!@)8g4 zXL;WW)EKb6cml|@lN{a%Mj8!o^He#wzxu+Dhd;c(!Hvy)6^fi{A#aic9P^k&807!} zCVCHvjBN(;OchhqBp@9S)`G$cGczOrwGQN={=pv+x{MJDNr)OeG#>LY3c714hD8aP zjX69K=aSdqM8QCf!vXatn)j&n5Clhfkzp&9h?H?vg@O_Z8b**!iUZCSC=4kgB$w@J z1iXAt2H`v_=lfd7RkWQKzELCuwIUAihACg{UoKKpVgpNsqYu;QCJGl!WaWxhEpHp+ zO&siR+ybNmhbAxEk}1w+Tiu|NbJzm=Hr6Ln)F*1o^a+L+ zX8(ykQOg@`=7IC^LFPq#pgw`%E&-mPPar|`iP`|)76KOZ3Et@J!dSwm{J$!n-uow(PybDFDJKh|pE-ZDru4+8AHVCWpN!tM zbBa~a%VMb{mR?>rnG2Pp&{QG~{`3bgX2!bd{r|((O%Lq8=3n<~6nR-3l*GYFiM@c> zuNOKr?&F}J1k_jm4BROAR%obLZ$;6Wr%~$k_2F`Zgn=^u=X-SfC1o2U?Bc%Yak{46AjtF3@P z4bCF{sSonFFK=Y`=>vPh(?AzrKd;2ks<`lJ@e>NNJ-iyy0LDr>dR&RMFjl@f*x<6X zr1M7O@&#p1?_SI>hy#6SqJuo@JGds3 z<{h!5gC9E34Y3(L!(}h{K_cmkpPGtN}A>r;3dQ(<|o1g$K>K<$z|Zw0O?{4Mpc#%xWT9++)9IAL;<}? z$HG0TAYqp7WVk$qwU9#5CBxuC+BHBoSQnL4b|;5uxJ5|C1jVPA6Qd>Y3502L#!5m% zWt0ZErL+hy+_kK-4fAwxpTi{~f4FEaFM12IKUtX(xl@fdSZ^?2-v<(V>t#p(iKuPIB^fIY@$d ze!`_vIlZq8MfAe-lbpHx%>%=_a3j^5dBrS6;obWwgdW1SKE|3yZhMgpBy9Z+(L9X%8Al$dY#sn z8nx*EnMSRYMu9asmeEtZl5G+K8y1kBN}HZSC&?}d$QwFBVeIHkhr$rx5YA;3w!9Cx z(0VIQuj-x^XG^eb3O9&Hx4vfG8KjaH`{+pC`+4#~r!7s6y zC-{{vtt;UtB8fBuQ&PtOPtj>Z#yceeCv~Y&T%P2{K7fr}2TZf&u0sQpYKQa#Ku}4n z%o=$aD1~S{L?uER+<=&c+`}b^_!ap9S%h6m0IJJy{R0x3bITCK*C`20K3Rtt8jTW5eF{57U&{9Gh+K;SL0+PO0J`0cL^H~%&Di9~65%y9|J98fX@5MXe5 z4P0Y59s7slOb1Tq{^7XOfwOi0a8lEOvu*!y($j&{wSPF7>A>kOgVW$l=&dZF(2|fv zC#~#IE!c~V0m3AUkOWIYJ%1XUB`JT!JU8;*e98UbuuqZ3&*(5<~#_ABW&zj-I02nJdux zb%CLB2B@elAu5HH5o`%uGHNmYphTy!B}@j3D=M`mAjj(ywf(i$hMB<&XR?{sYa76;gcND}L} zye;BegHumqd}7Y>_47*nMAq*#%;GvJNeNmxV(WK0jIH0|U7K*SrLPzzC8ZfOOxk5G zfR7M}pSWRV6EuomfW)tt=4o-Lr#>oh=W!-fk?!LQ2qk{? z)0n|i<+}kX*$v>)0zgd8;PBm(-GEebHy{PuRkR!M-#vr>c@g~+&EOYJoWU`@Zvk7C z&EWX935FX{&hZ!A`)Ms0bVbGjcQF{Vz}8FTn}?*0gIQoLdU^S~Wh>vb6}dmG$Ac$Y8!=vqlcvq_G%D zaWUdTD8WD#Ek(e+XI-;)&g3sdHHY*+yh8}V(NL1;)9GZ(IYZhRp2mq0KPNv6dC z=!y-PZs2}r=;MazI1OK3iftdfK59GKCvC_j`VVWgYW*i`w3*X?BW#1WJLlGv*=@$* zS2{;$`$8}$e1zTzoPFnn!*~qhH+=kj4qu`1jL2_;v)BASjNhP;PB&;HKPo+bT`Z7uhy|Wx6BSl1Ih+7UT;>JX9;?CsYw>?rf{;3g zkuk6{qFbogrl&y&p3TNHVoopz;}0B9e+4hx7x}uf5_mqp3oAu@6xRquuIQ-4fT01b zMvB$d8dv-R#w~WZojNKLv&zP8LB}m3U0TK3@^M=$|oaJx>?A9ahs1F5)@G|C=vB55ETYJ0Eqg#>);fU zKop$@rl<{k?qJWMr5vy5R^h{7mV9Mz``9cOZv|=++%}++2wTIPlC8mm36p&#iE{$z zu}~ZNL4bMGPHN4|9PS*?HMSqwO2mQzX}ozAMNkF)Kvx*T7OOccTQ7!EK=X^9-ool8 zGTv#kA|#0mfK)y=@XX#PQUa!+fy4^T#{^iHv5Sxk1KCs&mR_Zty%hOm@KE^?rbbC% zSCrPI0x!~k^kWPdDMsZV7onvvRNt8sj;rTv4nbS~7XD1$^)D;`FDw5q+I;s1EC2US zrTo)2j7TsTd>revF0;kI^-p2a`dAuf-Bcok$uOMJO$d`;!zuSZyN*5(e5{4DK9&dYP~g_R z?w-NjI)3Dri(nW)bV_XUU7%0U)nAWQkjqt&gVN%#7uhdhV34g;hpQmFd=+HNDv0;K zqZDoih*v=f5h%Ktom>UclQ3EZMOO*B@hS*k9InzFfWay#1!vs!ZWu9KE-qYSy?}*8 z{cjG5ah{ox;@uyyt8$Y%y(Vb*TiVq5o zgh%?H!;Sx69GoxoA#zh3I60?+WFE^G`{pxrJ2-wz=v=|zSh|olc6%A$ve?08w!WC9+Q3!?xGQq8d zSRo)4?D7UHU?kqtbgoF9%1+0`;30lioVLX2H(;(Z}< zm5fs$R zKpCix*#FXvud++Quow$w7A^FFmxf# zv$CkN?!t%#u?13MK~1Y3j!pqzpfQ*rr>h3C`uQIio*^2ImUT{v0gbMw$g>S{#Qjh@ zgqd>=-txrM%LD9?2spWj-nZcH>K}#E_V_tM&(ItHSD5w9!p+>nYPzd(20Bo;J*IYJ z;aeuyQ+@#L;T_x&|Kv*$dC#k{8h`!SXAbp`@y@kn$qe3mYLz~ z#$A`;1n(6CW5b`h?KAKBh1Dbnmje6EjltE8!8HJOLZb5n)As}4*<0g3XNUZSVzXM9 zL8B*3BYQFe^)#|4gR@T~`|JcVOB1+L_Y=mgKpuh6!O2FknofbTaMaU42vN{c!L+H9 zj2?ZZiy(x_gLG^Jjyb2e>)qi$X5$xa!ijNFX2T+n4nTva4v9S6Uru+zwW7##n@9=t z5Kxv{4o+_I+?F{PN@IK>cT zaY7l@q%fH9gJk(gbr)$3&Qknf4YLYWLs@qHZ(`rPCa8g7jeq7z8JzVZ1RP?AI8i2r zKDG~+6CL#7lij5TF^~{*zwN)Gh}hEf-+-A*pyF6j1V^{uP0lFsP}E3r=plT;3U!$s zc%%eOAtZ{c)F20GG;H;G@1RnQeFTonUtYXDALay*+0 zq9_0fbHbqt$qau2{a)AHvPScH(v@}M2g@d2dVzqtVfLJGC_~4pz(wn@u;QIGSb^I( z#}*}tey6D@Z035*_GF81m7Vgw)se%Pr6X#i;GxQ6eq@jg4TmZ41y{M~P#P&{!{rf4 z8Z$~qB;DjO#Cl!zvHQ$9O*&3s?x;7X8{?qjv^AqmiDP~^uZl|8J#yeTS+RqPb76)K z&PCFI@Z^KO>Y2aJu+G#8$1+o=tXZ2F&kQ;1sSf7K?O=s934j;XNRNg8gXh%!+{8N!pw>BMDK7es&Q@<<71z_y_oI4 zTh|ZSFw5bV3bQ+SdOiX2K((@!OuVfaG| z2+csKuTXc_(I^c7xpFWOlWIkruqeZYt%qzC9KfK{BN#YDqy&`nlF}mRJx=(BZ2}|B zHbmABJAi|agf_A?4ux<6uE`}sh{Z_FIARNcaGCANO;nV2pk0VLl`;Z2!Ibb_tUa-% z!au%$B!A|?%@TJ^(GudCNn}uiOOWu8IP8o{F~oMG0PY2j#1KRa#1KAE3?)U3qe8?E zFWC-JmOIOc9?BOanRBu@svIZ4ZskDANHHQsz)7P{wf6W6OjAZHn)1;Fc5NKlcnBnp z7AC8$L97MBK@WqCYAF5;Vk?MtCVUq0C|@K|J_oraEMuJ&4*VVMGq@=14+XL=25}XF zGGUoih6jkUA2bjVhPdEP2ZPBzpz=q688ToVy3IY+t^$YrSA{CVmbnvcpmU;4bcPL_ z&yHDt6r2$Q=Oe$}^NGK~oHda^JaS(JBRPo=OEEC2cZkubf%NFzAG!LnKMK;ALQ>-$ z4S0-VKM^s`r&SP>X%^RA1F^;KpuHg+H{e7S5q0E`0yl7jvgD_K_^anJVyYlECB=>< z#f}BVZuFnGU$yV4@1F2~!a)Vu_>DW|zo*x{cm$7QdyhkVZ})#^pLtZ{4f)&O^U$fS z;SfP5X&2scgNA4*`eaT($fi&wpv;=W7Dz zIM*u22(iK;y+77R+3=Clmr5Zq5uH>okcoH_vZHoA`SK!~Vj z(3N5PE6ss?3P)@GeKvIL9?X841XMjvg;1F=r>(}e8YLKxsMDmON-ASzA-YM?Wke_{ zS1yw2n405O$2=B=BPzGDM{&3oJWJV~f$qqY)dFn{=>40Gc?hBgM(ORGU4Z;N*^h??TjF%AAt2K<^}e%|@*;Y+Y^>{~#ttXl zD1pLSa9-5u@)*9;ra~GXv0j;O2+h$c2&F+!kPq?RXaW}0QoT?#hLHz6kR=a*VEhk^ zWq1IKE%3lx@`6OeQ3l9iKLmM{3moYnstY;pVv5QNnh8sQ38Vt7OUMNXrxSBQeTbze3Gb0zhXJ02oR~`^+p^#K?x^%G8}KjR^tSuR>erU zSiPYH0`_IX(F9VWu_P#@-U}qsevyKoLkX$VVx(4;kU~X@6f{5@5KGj;hWD>)&_c>S zN+XU8?zApqbMj|G_JAcYl9z`myuS(*C}I-Q`ciJB?}O4;lwbF)HQO10_R|nTFjh>uXFJA4Air(a71_zo=>Nd0qYm8R|-ew zk04|hl^hxRNIg~Sv^DwYJaEs}A#M+nPC>5fZRSIjgWBd<8zCAC#lVFw`C=KZCusOZ_MKx{^0Q%0zKYcqj^-zyhaH)Qcm#f2a5sK%>l*0@!NxYjc=AsUVq`{3*V2Lwv=d5DgUHD;b#DBmGbNVc zPhwPv3T2_WFh5chQwxE-!37y80Qv_x|34&LC)dUS;^M-T5ZXIoNx;wcqO+iwVt)LI zk~AT`Kxc0a)&>2#H%Kpl9OtOfy)4W)h%m(~-LOau+|D}7T^nQoC7>PWtO7JJAZ5a^ zn8}f)il^8~f8FUBbog~+IPpD;4 z?EoYuEC;a200~1(KGJZEgUaTK!2>`g%l|QtAW^>~F=+u3Vu}q%h$-39{?jor)mCE_ ztxgIoHT)FaPLK_hfvo^WRS<-x4zX_OP1v-3LGu(_5@qmsZ3s86UA5)r1PC04$WGN}-SxY`7`6k)ERxfk6A zk4|R657brM2nf>-av)CKx`L}o_>m-vbnIeDKxG&9In?Z+W~Az;I>=hEK|bvvCmW2p z4xi+f!T1B)jYPmF8uS_goixNJb#&@y(y4W>*xaHo;#>uGbukYJA%Xt_3qo1vJ@yToc1(1b&o!BmkX|*gSO%qD?19v_M|iW3V`3 zZ*V&R07(s47#ApH5J?&?W^4~)5Jaq6kHv`;v_#AQn0kb$fZ^SdvTMrZP%XKy7FVH| zp~FWVI?)sE_0gg8Lkt~$Oku@kQS#zhMvwdm6eE$OK&}6yXb>UDGe}{E4CzKQG1U|~ zQHl?BaMWcuYG_Cx8eDqm7w5}Z!rClAFz&fU2!)-XCS^l0y8u>TWP#j_k~G1BJQGc9 zA;jWb@G{0cE?Yz2$&1;Z&thaC=n(}PqBUZJSp^!!CbU*UqDmWS`V?j;0ih1{f$K$} zxRCSVf&gG3%nB|{%jh0_Pl*Ev0HTd-D1{))2`li6hUlcxQtG9mhnDdTz$hi9oQMp8 zNugbWso4!oBpFRHM>^&RC5Ni<-N2-uhrnbxfk_!G50FQU#zA?+PDL$HcS4-+RYpj8 zYshdiZZXbLoZ65)F(Z>e(UPQw`VvWMfW&&$`@gA#iIN`k8qyAj(8Nc%KH#z2r4Z6V zw6x_b`2uSrlPIjl!^L!`A;aWkGK5n$T+X;!oY_m8Op*bUjQ~+(%rk+2 z(Q83InJ|!pqXLMV`4Af^ec~bWAmWS0)Nz?7SRJRd4p>Jf_t0-iJTwvte7q=0~i~U3!rmk z$nKayXlp{f^E&X`QpW?6 zFna|W)SqPJbH>HY9`#oSI>C8r>}MBukyVVR|X zO+a%+M@u?rE6sIjn(M&G>{Cu2Tu5^MLydsP*$>-3vS$jk&^#FM8ktF%$k))e5QAcGpVt84=cv!Xa}a!F;S^OQpQ% zbR5Fu2qw(!;7lXjg(kyfgLxmYGO{xa1CGw>NXp5VfHw*VSCwXU-sS-6%lOw^Is;=v zoN6;Mz?ev51r%+rM}pz;l$)yzFkFy<$Hs8}1=q5F>G@zmxU;uK6Eg!;>E8&cuf!M4 zO8hy@KDUF@2=JY|+nM|qmFD7l~xuzlz&6!uWMfc`V{Em5QDg{c-@37wN{ zMykd^hYRuC^ErouPvO%$RoZ0ko6hqyk|Y&Mjv4o#@;$arUJM+P`xP zcuQ7LfLJz;MOMIe$eGqSuYj!-CZ-TPC!ANJ@imitSDYPXzAMk5o6%!MPO`?sXHwr4 z2e*h|$%#2}TD~jM=rg`6LNcQSl}N_5YRPxyKOJZ&(HI1?ffumi5SA!9WDxaTfovzv zF24|SD&gEpPSJUVo4~lm2c=;ahLVFk;S2a?(|v`zn)VJdb>JBH6%1BW7Q-|XI{nlg zva;R>H{y|ESjUwNYp4~}4YJe?C{qB_Mk$UD82HqmMZE9SpT)01K1w@ef!0CyBGQp^ zU~1R~Eao#~*P#tZ8=gV4I_qpUQJq^bip6#+$y8P#CduXyTm0czl9fM7$f%c%LGR74X4TK#a zjO8!F6#WFAGB@##vRYXGDL>`@;H7nGiQ`!t{wFrTM9kNQR;Tg0o4@<%zvXKabPU-0ak?z;ABHEafLBBV;Klv|?o$Jg z{^|q6U;DxPcU>se{&Rfw{DqjuoyNU!h`_rH{?fBd6&zWYv-&Z-}a)3xf~-1nJ*J0!iSu+ZO`Kb%0n_|_+W zr@@pJ$nYaS9KJmPFef{H)esq^s^@C@we^TF-R5!-yTGexp{p-JLdQ)M(-=1GUARqYIUBA3DLEi^r z`fH)mMchq=!~Au5`kFNUFz!Un^w~##X*zX7p@8(g*X(^#DcMw*=U*=Sqm5sUds;Ky z{j1+S{$bOTvry=B!vohV<(dkImQ$cgPoB6T9AHn*BR?iu(RCvYyhzxZ$96Jr54<+a?$NZrW|rU9kYw( z{N%5{XxOKzFxUT^{2|Qrv6vk+)Ab*{<*xUd?myVSBu}rN#<92~O{OnA^}_F^qnio` z`JLGAL#DmI`L7S$CFE-=%!aPvDk=v-ekGYFNxBe{UxvYa>=F7qutVryn4j(WTe&-E zg+mpfXezIa)N-2$fF%4-b zw}1$afd$uAc5ue?-;BK&e}GFJzk?FUY5ZW!wGdCD?704K;C*34a!oj%jzls(iCQMd z%bc|o{tPlwc3%Tjb2+O<2YozJcJR~r9b6rTINZ-|95+02``tK8K~;|jLZR>&>y5dV z0S-^QX=G$9ks6I9g4%S-_16P5YoD3_1y19~pWFM~cfNVgZz)YUAADi-mtVb-6Tn}J zT>kLx?|tN2zN%P$Jh}&4Ma|>i{POL)H8aQC6VdC2!jX8r@4I(?LsB;s0=zyxe$Qj_ z+Eh3;_if|z+i=EtfPc2 zVO>5FHZ$(X3h$0RXkjp&OZ;!S_kBP8?boijd7YyB;P0=#|s@!=YKCBtvD6 zpK*>xpYyL_oBrwAn|}AU5()Q2f!MSKaSRnj_=c~2c2qKNC@ezRM+e^V6M1bayc$(P zpN>d}_5RZNxJx)~?h;P(E@7y#&|{*@g!5;!`n$jM)OA1k$gSTP1WDP2pV_-_^k;@4 z*@ySU?^@-}kG%88n!cfMG}3?nwqN|}=Z4|Vf=5h9WtY5mTJpsY$4(Dd#VLswKO8*+ zaeU&WR4E8vGp>q@de#^!Q4E&D49ejxA7V_&^?USG0d(AZ^LHHlh zs{;Mj&|B`2)D4AtWd7LSe)(#VsZE75{V&@2b%b#5d-i-;rH69Q=i_%RH1^ejM>Tyz zVKMUWfikA=O@&wa*V^Kd*ZA$*Kk&V`l<@dY^r~fsZg|(zlDeUAEI>T`@Xz(Nsn8hc zO#exno_tQ@=byR#i{Cc00$J$`@w*m%*YAG+U7a;H6plmsN8(wesSt+a1^-y+NXLc) z7(((eXdd#7g#OlOk)chE*BlD#s_);k=j|$Mjz{KS{@r(faozA|Kk??K!dn0Pc0MG8 zcl`36J-aEhW zGxC#`|3r+xmj7h@-c&dP8u&4dPd;CVzq|Zn=&0y4{`i;wGW2`lD+O>{JUJ+U>t6W# zn>4+taC&k$HDEnkyTlsBp`yOk{7H;E*jK~xhbXY=_SpEvXew5aH$M06zc=&eY5x0c zxI%65z8XW&?U z)1QIk^bJ4ajoLWypGF=ktUdd_`IVoOLz@Z>)oAC_wbp6e9Sb}y_RzN<8dm|>R5;1M z#ui`J#wQ}ZO*1|Hz^{ILHHTPJVWpujCmqwq({U*1trTtacWrz;R%^8E3%~uyXClF~ z!W4!eWNA(w=F9z7M|eM{26Rr*U(UpF>~*@-Vq9wDrkkk7z>SY83^tj-{{yGvtbL@) z6xmBBNiRJVsVj=bvmg2AZ;2>tDlGSJwc&URRPT#*3eEJjA3lAxO0lNGGM)TIH-M); zCtI$U5;}n@5cmr?qtA)q69 zrg?@QdGGsWZfz=@P>p$J(=`~gT`a}4*vIaB;u8_`EJ;d_)l*0T0kaxsu;gx3!j77zlNVlIkoki87n z@8||SMmDIajBJ3lTO8Q{PRjmX8@|U7`b$LUFM-fs0{7!rS(dfNKVG^W&pjj2^YhOw zKgm4jkAWiy1E#~t_$9T(2~3m=_(EfZmajYz3n5;4j8D1pSd(0N49i4zR9SDHHbrkD zf`VbAA}-8J#*)whSIE~@{eEg5TY`y6banD&R&s7zoqU;9HnpuTdz)1@wPEH;sIs$o zR6sF`^gB#m>LZhRMx;s|_2Pf16FCm=2PAY+A8u!^ij9 zr`oad@A$`=A!El+mVaD0%tL9%(Ksa{N#qzrQx!P|xkd3caOX37AH*4;XhCyALSV(u z5Lo&QTbBQjO=FcJ_bD4TDJo9K>nw#I*q{7Oc{rO_G6*7l#0)YxC4-bLO^0P^Iwz{} zb2bc9)0P&nUsYq0(_qpvE%=5Fqn3I8f(_di_-o)qv?l%;T#81)+*O6yX3;smvYm+8 z5w~;Xq3JKdWgyge{_S=iPWA~_ZAiWplHA#ld?}PMXG7Urp^Q19C?r_5kf(u-^H`Ew zWQ8}!#KeP{?M%ou{2N>2FA@$h@3Tgt_c=E_J8;_@K6r+Chf&T@^kk zed7-|5ULP&HBS&&;giu+dMa#Wcpt{D6wW^I>i~lmro8vqa1&QYcB5&xG`?iet)S6NpjY;3;L zQ3Xef)DH<5iyPPkrx^O6;XoHRhq*V$JzH#KBSJ++oMJL?ijlZg89K#a>sp;+0@#<% zaPk6G9gI@288GYxuPn!BZmrkTd4rUT4=0J!4bXyPo_bb@YmmW-`PD}U{`;sN=!lPw zqEiZ(A?TQZ8D;3qg`d`g$!>r%M??d`6zwEt5~~B|0Muuyrh`&3OG?1KfIHj9uR>#W zRHsBDR!5NDQ-m)7x&bFB@PlS_hV^lz4hF9ApS2@5hdK#4fsb+;7>tK-)?xkDB1py% zC*UdgTEbVG#NGmbBT@clA3q-HIiYfK!jqL{{=)YAC1!?{5%+$Rs9a(P15QAtkjP@&jU_PYd^x} z1H?}CvmZ%I$_D92G87yzOh2*{#lKcMD&9#3ps<#vSqiH@SzTYzJQaYun~w4>m0 z=c1#;yHCa&ois{v#JIkQ5HYSVWf!)C=H|k7TxLbSu)HTyIJiY=s{e^-Dyk@h(+3El zE-+apNca|z2IRt63AtKAY!`Kb(Y+R2LW)=&C`A{THRpi2c%I8u514GZ2Mmge2TV#l zU~=?;;bBl)eEc)&;7bn}%w8Y|&!R_OF*u3KBj)gm$)Od(zo-X1UhWl>qr+RmD+b=( z%)*nb(rG9z^%;*FIuuV)U&#xHv6u+QCCQ|AlEzRd6OCp_6&(Bqrs%I69)iq?wm2)Cqg6SEWEQ7JQi`>UyCwTy;wjU|62SQmpBs=sT>1Dae$;R>h~S_mwh!zC$pWWj z_HTq6TFKt4v&p-eI{X260wD{DqYj=hZpn9O5&A$IVdLxwV4|sL1QXcK9EA}vRS-Gx z$TJn=RJHOkGV75jrh5ODo|4DvO^6^vK}?|#qj32|Q%po|Cw%IWTUOL%0Tx{+>ACRZ zPd#!NIgG4ef^law7&p2-3*kz~svLI>MZo3I55_lKh|jqCxelsEBxZCbH4AHnA*r}R z;$XXa+eHz8z@}6SImhHkP7_6l2UF`2MToqW<`Z~}eDz{#1O$3#l)13#uz^ajY8HB+i^F{h&h7c-fpHfiM?o+V!BoOntVc}{;I z&pQ>Nq@}CSNehY$_{K9P?ppAOMcsAeCLBqJ-+kcBu`rM&9ivF(Zx*8vjOxv{2!UhE z@~^~+s?#s8|j!-wtsoQ#&#+4S>?&3)sW9cS`g* zvQG*df`9?#8PgVM9N6ao-OxK5nW@6zC%Kv*y((J(@uaDZ+HmLsfOox@=u z-GPrBYc}A*dyr!igJ0B)7*!w-_d_kuf)d@;fB|48D!*6aE*&nor->GlAtFg8P*V<| z@T)i(#QdGxSTuYz7uU&&k;g9C5%Ttp`DHGLckPTI=6?x!^!ZK@rbnsiG@` z1+|opVF2u6M{;l!#v&RHnaoC&(3KA3GYCa0BEi+rA93vwHC+w;!9@iRlQ8HyX-u5u zFiG49HVL{M8qVnMe8Mo1!z8Gg4LQgPtS^Ywi>?a$tSj&HKq>3<;-s40{zdO$2Qdo` zI;f&AbR|HHs~u_M74y1vR&+9&NRyfjk_g2VE)mpdfEr0r%<>oubi?%p!x(HC_=h44 zy(G{e7yym*UJuWzETmQ%_FNaNk2-@)fwye)5%Ur_2E$WgCQ4P|6>r&{+bZ*?Xshsp z?*m~gXID=PlzG&~WQ00Be=5?Gy{XN7wa^u+S7aJ;Xk>^!9y=WYC8$c==>0>-V6D?_bt z_DgswmuhgqDw?+m~i3t}cmxxHbrHYo5Q4j1zItsOK;phEz)mLJ32crD^= z0Wbj^B(m>Ni9naA8@29QqJq&=ECjWv4Vgu*U~B~i6z0(cOEl0+wg-+36FEKrnj-;4 z6l5uvWGRqfJkE+Hzr|rtKuqS(W29gu)Cq;n3Li!@>)7LLZ(W{bcsMM&bp>G=9PGf% zZim;R0jx%lSCtL>QIGMgsV%KTB9s?!AqflDo~gs3I3T4q7xKv0hC>~wAVcaX>P`UORt(_vq^X1M}sDuEhI zUnrI7m+sw=#$_v{-`F#9#1_+_TrrQqsJifF?*~LU5W?Lk%lTUC*xw32Bvd8 zAUZZnBLRN)V8NY5XAS0PuFjxrb*{Bwkb&NSj~HTQ6#9gCJLe(j!J%q)OLAm6gEhAimBDxPYm!M$JsT{i?xB6K0N`?(SpbRA`M zLYLk$#{ytPVH8E&he6_N8**qvify1ii#7!KfRo)3{)oLn#g+%rh(4sA2q;A#49F2g zwt%^SKNyd&B0z!woN}k0yj0JP zmIb-$5MX z@8!LPVQrW6pysws zfx!tCw|4L7>SxsmG{8cw-Cg}{m-IJp?rm#p-qh0Hf-WZ5maSX6--wd!U3l$UVzLFy zM)c7N02xbpMfAh66(>yH34`e<-_$)Y66c$m{Nrh_kmNo#H{%t~?%LV1wS7}y2sQ{m z-RM)I;TbPY9z&VojCW`S;YwXOn(}p~2OF0L!-r-eAS;{h$ z^=7pj?11AA>F=zUX1}0@k*t^DV=bOXv);V^-j=RDrLy*RiNUhoAs2SFY~0!w^mhj> zn>GcTw|2MmpMZjcIj^|0t+##ir9oRa*sQswudl7QKWJ^~3O2UkXRGq)NX|RDr?-74 zSoY#J4A!3Zpl?g}j;){@`W-n<*8}8u&O557w|mo$*0$a$GY-{whi}?AWtNc|uc%E5 z`r5iSOSKqRue@l07`vO``Wsd@_fv8X6ucvQc5H0!Z{OC&EO_49-l}xww|Zt8DtL?fw}54KKyr2U z2M}LvkWsxALI*iV3*IaGxAhQ`$t;is%6P$ZTQ;)JS>CKxOOOWNb@lh*+u$rO)wcO! zRyNCX$oIpuyiCi+)=kn#d2W>F(OF*2vhDmYq&y#+1v zAY5SL%T|0EobAm@eqx6W&Gu%OePh=RW3BrCcXlnnO;u@_+R|1|k+uXZl(x4o5)hSrTxkv@f6J zcNlt9HMKELYHG!NQcB04h6bI9cWT{st*gh{X16HhO8E>l5{DiLOT$zQhTMD;CAp~? zj5#wcAJ1SOwVBT01HdQ z3<6A91u)-aNufptqXU;TtewHo3lV9UiNVkd{#zx5ni&ke5R!(iWia%Dw?L9x2ZNy( z0@5%GgP|9~(l9H7p%;8pB!$`-480JPhS>#}3cV1KhB+9Fjz&`@g?2I+dLbkYb21ou z!CNTF&Bb8og@827&0y$-ur$oWVCV(kG)bY4G8lRxC=KgkF!Vx18rIEV=mmd~q|hD# zrbaJ>q+z`bhF^cBOz87EK;4K6plui9}4!x2-#(!)C1k8#!1_zbw8U5hAUIe;G7StJDj`LQ(G-F3ND0X@M)6*b z6eq?D5G3$(B)dIE5#UHkVhV;qk`PC3HVx5)IU-C!M_4clLLzS|8E1|bz`d_D=FMSt zkD-t(SW3v+SP2R*C1r^<9D-4KWhAF#s0byNk@CcpA{>=jM#fu2Whk|bR3xSq1F76{ za*I`5h?2`mWn$_$B$ZuGCd3tDUkwc}#PK0qPNt87sS3IJDoAb|*Bbib8(ylUBSi&~ zkAknV8X1QxU`gAn(WvSBmfp0q&>L^1M6ckMDfnIlA-%s6BA*ZQy-HP!j*Ejw`kF##f#Aha9CKvhH+w&mN=T=^w{V?XHhVpLG`i0 zwE5GCjIkW576Kk}GFGEeqW64qa_a~X)**+0oTO7!P);U|Kna*IU{v(QoCu>5Jgfji zYBX(aI-O3Bt6je$HVRSIV9qXL4}hS8j8iIy2to=XTc(JW(9jP|_5m4D5RK8?4Xa0o zU6_SJoB*O8HXQ^dbatzQcbZ+WMD8-XO`HoSn>LTN4Hgh~BP^nIW-BaaP~Z$QSCS2- z)tik*16_k8WZ<1i=8G8AR{uOTW|9UeE~C=owm2=+s-LIDZE;$}aT%2svq+7o6>;k)QP0Vk-9u>u+FBjBB3XY6dX?-r*mp*@9lAR zkCScnSlnhubZHAKSQivvFiWH?EUT~+-cII;3gdJb4VPLR=)7~t1U-aQ^aif2hr@P4 zp>Gbk2?I0!IfNHUh|?2^Xh@K0Xmr}GoE<`iJVXdN9^xcMk4-Qk-U!c@Az?#&RS>3% zMIPKHr@adzjW*8UbkbmB0KSZ&)zT)ZqXuDt9|-!)R##Qg$x;<5mPXZ6Oe85M2=G#r zPnnDppujYNq!`c%Fd-$GrqzO>+~x#&BO;BDr}LI zCPIrMNijl;d}>lC#E3W(4^bjI46|?@4I>BCsEbER617Tl2(~CfAr_Yj9)$#!qi>>W z6eJ13S4^N9yNxttjT#w+QlVeL{Z<2<>K36pUT`W>?`@8R5n<4|3{~uz0h~B)<0w1;__)llV3Xv zc801Ub7C(JLJ4=Yd-6M*(oS5`Xy$*h`e0dkAe|rBdTZ~FH*C(VurA(!1i&Zx^Qb{&?|YP;MA0wmF2P*PgJqo+v-F z?DD0z-aONqb70l-o$9-OIDTbdx2CDS@$hm`ZWt-H)%)%kGXM0Un%yt*y+{A9aV zX_Wb2e!uML{p(&CxAU7X?{58Md+FxBnezJv_thS4EFbvs^09^YE-2SGUbtoE_P^fu z>OFgQfmXl>jU+F8q(&g9vt$HEY>b-c@)K*Y7f8&;Z&#AK$ zPd#__nnHF%Hg8i`&j*)x{bskb@8E&MPx%U#7b$iw8FTHNy0Gty<8R&B@Zl#jzBzn) z`pPw1&#&5W_r;sRgTq*(EhES}_t)>#y}WZ*=fHlgW$dcWEBD@n1{&cW<^QDD> zDZA7+pV7CzUc5DL<1@b1tuOt7t2_OB=e}*zGpt`4H~g{XmR~`yIv%ez?N?AH+xSNI zwead~z5N+WH*WhNu;JT>$qmp1s&buXhry~>)>g$#7(t4B{{wYPcjP>EZmi!T|NQFq zQ*D=T1GBt8f`VEGie>hB1N|M#8|&_SVf&K3ul;gX_OTzpkin4@wDTav>ddFFEIIl8 zdFPSGe^5v!>(j@v7E$u55Xvz<21gEU+kiT~PEe z;d}vp28VEG1IJso-IylZ{=?P3^x5C8kRQ~X)Azr4&z>!Ph28fbX$1oSO#Cp>H9eHg zKe7Hy&AKZ`j(xjQvHVl3H|taG+*tD9q|eu1-Cz2N<>E(+LmxM;e)7A(PwNX#Zdmu# z9NpW>V~aJtkH1={>b)*M)eJg)81D+I6_m+#5yiT5mL=i}`u)DNv7CWRwIGhGp zVU2vRz;6YR5-||M2qRG;Ko!uu6Vbk~Xzv!PvvBXLfrD0fpMm@@F-}Mgh)c%+m>*!n z8ykQ!HEpbjUTd&A+&w88905v&h$y;yZns%_gf)cSCd$k3KbuAh#c&hv;<}u6TRW^E zg&kID1O|to0bxMQjBeNq`2oYEi8twi!1r7lkqZQJ7ZH6TAX<%a-sY;MI10gcrhFCgTiZhf84G(0QG`j`c3^z*J zWpqZK^kvzKPF47(Ng`hl>ZuFugxFI$}m(jqxJx+9b1WKy9U~hOR zA%rRkAdaD2oX2K?i3Vuz)En(i+;xXv8zPk+TP)qk!n@p@#|5??av+CW$fyBeOGQ|= zC(Y^L0i-c1hV#CVM#i?;?Q{zt|HeISlm&lh(hY97fdhg`CPpA}x*mj^EV^HgcW_cK zt)iRK;b;}TgR^pJl@Pkw%&6!c98ya%X-W->!YaKTQY27uI8v76rm?)Z=-ICz6+y6J z;nBGP1P8p5Z0J~HWC+AFSxL?VZfKZJ<8<;pPz2|oQao%d!5y4gO0ph>BrW<-z)_@R zJRJ|XSeXyXa-tlIDOWh+ljOSGdPojIrj09SEo%l|0VvMo9S*83oT>@iPdw@bM@*7T z2ZWDs*9uPCBNa == DUMMY_ACTION_DEFAULT_A\00") + (data (i32.const 240) "dummy13->b == DUMMY_ACTION_DEFAULT_B\00") + (data (i32.const 288) "dummy13->c == DUMMY_ACTION_DEFAULT_C\00") + (data (i32.const 336) "get_action failed\00") + (data (i32.const 368) "testapi\00") + (data (i32.const 384) "incorrect permission actor\00") + (data (i32.const 416) "active\00") + (data (i32.const 432) "incorrect permission name\00") + (data (i32.const 464) "pack_size does not match get_action size\00") + (data (i32.const 512) "expected testapi account\00") + (data (i32.const 544) "get_context_free_data() not allowed in non-context free action\00") + (data (i32.const 608) "dum13.a == DUMMY_ACTION_DEFAULT_A\00") + (data (i32.const 656) "dum13.b == DUMMY_ACTION_DEFAULT_B\00") + (data (i32.const 704) "dum13.c == DUMMY_ACTION_DEFAULT_C\00") + (data (i32.const 752) "dummy_action\00") + (data (i32.const 768) "Invalid name\00") + (data (i32.const 784) "Invalid account\00") + (data (i32.const 800) "read\00") + (data (i32.const 816) "get_action size failed\00") + (data (i32.const 848) "get\00") + (data (i32.const 864) "size determination failed\00") + (data (i32.const 896) "get_context_free_data failed\00") + (data (i32.const 928) "invalid value\00") + (data (i32.const 944) "test\00") + (data (i32.const 960) "test\n\00") + (data (i32.const 976) "transaction_size failed\00") + (data (i32.const 1008) "Unable to add float.\00") + (data (i32.const 1040) "verify eosio_assert can be called\00") + (data (i32.const 1088) "privileged_api should not be allowed\00") + (data (i32.const 1136) "producer_api should not be allowed\00") + (data (i32.const 1184) "db_api should not be allowed\00") + (data (i32.const 1216) "action send should not be allowed\00") + (data (i32.const 1264) "authorization_api should not be allowed\00") + (data (i32.const 1312) "system_api should not be allowed\00") + (data (i32.const 1360) "hello\00") + (data (i32.const 1376) "transaction_api should not be allowed\00") + (data (i32.const 1424) "write\00") + (data (i32.const 1440) "cf_action\00") + (data (i32.const 1456) "acc1\00") + (data (i32.const 1472) "acc2\00") + (data (i32.const 1488) "Should\'ve failed\00") + (data (i32.const 1520) "require_auth\00") + (data (i32.const 1536) "acc3\00") + (data (i32.const 1552) "acc4\00") + (data (i32.const 1568) "test_action::assert_false\00") + (data (i32.const 1600) "test_action::assert_true\00") + (data (i32.const 1632) "total == sizeof(uint64_t)\00") + (data (i32.const 1664) "pub_time == publication_time()\00") + (data (i32.const 1696) "the current receiver does not match\00") + (data (i32.const 1744) "tmp == current_time()\00") + (data (i32.const 1776) "ab\00") + (data (i32.const 1792) "c\00test_prints\00") + (data (i32.const 1808) "efg\00") + (data (i32.const 1824) "\n\00") + (data (i32.const 1840) "abcde\00") + (data (i32.const 1856) "abBde\00") + (data (i32.const 1872) "1q1q1qAA\00") + (data (i32.const 1888) "AAAAAA\00") + (data (i32.const 1904) "abcdefghijk\00") + (data (i32.const 1920) "abcdefghijkl\00") + (data (i32.const 1936) "abcdefghijkl1\00") + (data (i32.const 1952) "abcdefghijkl12\00") + (data (i32.const 1968) "abcdefghijkl123\00") + (data (i32.const 1984) "cvalue\00") + (data (i32.const 2000) "value\00") + (data (i32.const 2016) "int64_t size != 8\00") + (data (i32.const 2048) "uint64_t size != 8\00") + (data (i32.const 2080) "uint32_t size != 4\00") + (data (i32.const 2112) "int32_t size != 4\00") + (data (i32.const 2144) "uint128_t size != 16\00") + (data (i32.const 2176) "int128_t size != 16\00") + (data (i32.const 2208) "uint8_t size != 1\00") + (data (i32.const 2240) "account_name size != 8\00") + (data (i32.const 2272) "table_name size != 8\00") + (data (i32.const 2304) "time size != 4\00") + (data (i32.const 2320) "key256 size != 32\00") + (data (i32.const 2352) "eosio::char_to_symbol(\'1\') != 1\00") + (data (i32.const 2400) "eosio::char_to_symbol(\'2\') != 2\00") + (data (i32.const 2448) "eosio::char_to_symbol(\'3\') != 3\00") + (data (i32.const 2496) "eosio::char_to_symbol(\'4\') != 4\00") + (data (i32.const 2544) "eosio::char_to_symbol(\'5\') != 5\00") + (data (i32.const 2592) "eosio::char_to_symbol(\'a\') != 6\00") + (data (i32.const 2640) "eosio::char_to_symbol(\'b\') != 7\00") + (data (i32.const 2688) "eosio::char_to_symbol(\'c\') != 8\00") + (data (i32.const 2736) "eosio::char_to_symbol(\'d\') != 9\00") + (data (i32.const 2784) "eosio::char_to_symbol(\'e\') != 10\00") + (data (i32.const 2832) "eosio::char_to_symbol(\'f\') != 11\00") + (data (i32.const 2880) "eosio::char_to_symbol(\'g\') != 12\00") + (data (i32.const 2928) "eosio::char_to_symbol(\'h\') != 13\00") + (data (i32.const 2976) "eosio::char_to_symbol(\'i\') != 14\00") + (data (i32.const 3024) "eosio::char_to_symbol(\'j\') != 15\00") + (data (i32.const 3072) "eosio::char_to_symbol(\'k\') != 16\00") + (data (i32.const 3120) "eosio::char_to_symbol(\'l\') != 17\00") + (data (i32.const 3168) "eosio::char_to_symbol(\'m\') != 18\00") + (data (i32.const 3216) "eosio::char_to_symbol(\'n\') != 19\00") + (data (i32.const 3264) "eosio::char_to_symbol(\'o\') != 20\00") + (data (i32.const 3312) "eosio::char_to_symbol(\'p\') != 21\00") + (data (i32.const 3360) "eosio::char_to_symbol(\'q\') != 22\00") + (data (i32.const 3408) "eosio::char_to_symbol(\'r\') != 23\00") + (data (i32.const 3456) "eosio::char_to_symbol(\'s\') != 24\00") + (data (i32.const 3504) "eosio::char_to_symbol(\'t\') != 25\00") + (data (i32.const 3552) "eosio::char_to_symbol(\'u\') != 26\00") + (data (i32.const 3600) "eosio::char_to_symbol(\'v\') != 27\00") + (data (i32.const 3648) "eosio::char_to_symbol(\'w\') != 28\00") + (data (i32.const 3696) "eosio::char_to_symbol(\'x\') != 29\00") + (data (i32.const 3744) "eosio::char_to_symbol(\'y\') != 30\00") + (data (i32.const 3792) "eosio::char_to_symbol(\'z\') != 31\00") + (data (i32.const 3840) "a\00") + (data (i32.const 3856) "eosio::string_to_name(a)\00") + (data (i32.const 3888) "ba\00") + (data (i32.const 3904) "eosio::string_to_name(ba)\00") + (data (i32.const 3936) "cba\00") + (data (i32.const 3952) "eosio::string_to_name(cba)\00") + (data (i32.const 3984) "dcba\00") + (data (i32.const 4000) "eosio::string_to_name(dcba)\00") + (data (i32.const 4032) "edcba\00") + (data (i32.const 4048) "eosio::string_to_name(edcba)\00") + (data (i32.const 4080) "fedcba\00") + (data (i32.const 4096) "eosio::string_to_name(fedcba)\00") + (data (i32.const 4128) "gfedcba\00") + (data (i32.const 4144) "eosio::string_to_name(gfedcba)\00") + (data (i32.const 4176) "hgfedcba\00") + (data (i32.const 4192) "eosio::string_to_name(hgfedcba)\00") + (data (i32.const 4224) "ihgfedcba\00") + (data (i32.const 4240) "eosio::string_to_name(ihgfedcba)\00") + (data (i32.const 4288) "jihgfedcba\00") + (data (i32.const 4304) "eosio::string_to_name(jihgfedcba)\00") + (data (i32.const 4352) "kjihgfedcba\00") + (data (i32.const 4368) "eosio::string_to_name(kjihgfedcba)\00") + (data (i32.const 4416) "lkjihgfedcba\00") + (data (i32.const 4432) "eosio::string_to_name(lkjihgfedcba)\00") + (data (i32.const 4480) "mlkjihgfedcba\00") + (data (i32.const 4496) "eosio::string_to_name(mlkjihgfedcba)\00") + (data (i32.const 4544) "mlkjihgfedcba1\00") + (data (i32.const 4560) "mlkjihgfedcba2\00") + (data (i32.const 4576) "eosio::string_to_name(mlkjihgfedcba2)\00") + (data (i32.const 4624) "mlkjihgfedcba55\00") + (data (i32.const 4640) "mlkjihgfedcba14\00") + (data (i32.const 4656) "eosio::string_to_name(mlkjihgfedcba14)\00") + (data (i32.const 4704) "azAA34\00") + (data (i32.const 4720) "azBB34\00") + (data (i32.const 4736) "eosio::string_to_name N(azBB34)\00") + (data (i32.const 4768) "AZaz12Bc34\00") + (data (i32.const 4784) "eosio::string_to_name AZaz12Bc34\00") + (data (i32.const 4832) "AAAAAAAAAAAAAAA\00") + (data (i32.const 4848) "BBBBBBBBBBBBBDDDDDFFFGG\00") + (data (i32.const 4880) "eosio::string_to_name BBBBBBBBBBBBBDDDDDFFFGG\00") + (data (i32.const 4928) "eosio::name != N(azAA34)\00") + (data (i32.const 4960) "eosio::name != N(0)\00") + (data (i32.const 4992) "AA11\00") + (data (i32.const 5008) "eosio::name != N(AA11)\00") + (data (i32.const 5040) "11\00") + (data (i32.const 5056) "eosio::name != N(11)\00") + (data (i32.const 5088) "22\00") + (data (i32.const 5104) "eosio::name != N(22)\00") + (data (i32.const 5136) "AAAbbcccdd\00") + (data (i32.const 5152) "eosio::name == eosio::name\00") + (data (i32.const 5184) "11bbcccdd\00") + (data (i32.const 5200) "N(11bbcccdd) == tmp\00") + (data (i32.const 5232) "fixed_point128 instances comparison with same number of decimals\00") + (data (i32.const 5312) "fixed_point128 instances with different number of decimals\00") + (data (i32.const 5376) "fixed_point64 instances comparison with same number of decimals\00") + (data (i32.const 5440) "fixed_point64 instances with different number of decimals\00") + (data (i32.const 5504) "fixed_point32 instances comparison with same number of decimals\00") + (data (i32.const 5568) "fixed_point32 instances with different number of decimals\00") + (data (i32.const 5632) "fixed_point32 instances addition with zero decmimals\00") + (data (i32.const 5696) "fixed_point64 instances addition with zero decmimals\00") + (data (i32.const 5760) "fixed_point64 instances subtraction with zero decmimals\00") + (data (i32.const 5824) "fixed_point32 instances subtraction with zero decmimals\00") + (data (i32.const 5888) "fixed_point64 instances multiplication result in fixed_point128\00") + (data (i32.const 5952) "fixed_point32 instances multiplication result in fixed_point64\00") + (data (i32.const 6016) "divide by zero\00") + (data (i32.const 6032) ".\00") + (data (i32.const 6048) "fixed_point64 instances division result from operator and function and compare in fixed_point128\00") + (data (i32.const 6160) "should\'ve thrown an error\00") + (data (i32.const 6192) "__multi3 result should be -3000\00") + (data (i32.const 6224) "__multi3 result should be 900\00") + (data (i32.const 6256) "__multi3 result should be 10000\00") + (data (i32.const 6288) "__multi3 result should be 100\00") + (data (i32.const 6320) "__multi3 result should be -30\00") + (data (i32.const 6352) "__divti3 result should be 0\00") + (data (i32.const 6384) "__divti3 result should be -3\00") + (data (i32.const 6416) "__divti3 result should be 1\00") + (data (i32.const 6448) "__divti3 result should be 33\00") + (data (i32.const 6480) "__divti3 result should be 100\00") + (data (i32.const 6512) "__divti3 result should be -30\00") + (data (i32.const 6544) "Should have eosio_asserted\00") + (data (i32.const 6576) "__udivti3 result should be 0\00") + (data (i32.const 6608) "__udivti3 result should be 1\00") + (data (i32.const 6640) "__lshlti3 result should be 1\00") + (data (i32.const 6672) "__lshlti3 result should be 2\00") + (data (i32.const 6704) "__lshlti3 result should be 2^31\00") + (data (i32.const 6736) "__lshlti3 result should be 2^63\00") + (data (i32.const 6768) "__lshlti3 result should be 2^64\00") + (data (i32.const 6800) "__lshlti3 result should be 2^127\00") + (data (i32.const 6848) "__lshlti3 result should be 2^128\00") + (data (i32.const 6896) "__ashlti3 result should be 1\00") + (data (i32.const 6928) "__ashlti3 result should be 2\00") + (data (i32.const 6960) "__ashlti3 result should be 2^31\00") + (data (i32.const 6992) "__ashlti3 result should be 2^63\00") + (data (i32.const 7024) "__ashlti3 result should be 2^64\00") + (data (i32.const 7056) "__ashlti3 result should be 2^127\00") + (data (i32.const 7104) "__ashlti3 result should be 2^128\00") + (data (i32.const 7152) "__lshrti3 result should be 2^127\00") + (data (i32.const 7200) "__lshrti3 result should be 2^126\00") + (data (i32.const 7248) "__lshrti3 result should be 2^64\00") + (data (i32.const 7280) "__lshrti3 result should be 2^63\00") + (data (i32.const 7312) "__lshrti3 result should be 2^31\00") + (data (i32.const 7344) "__lshrti3 result should be 2^0\00") + (data (i32.const 7376) "__ashrti3 result should be -2^127\00") + (data (i32.const 7424) "__ashrti3 result should be -2^126\00") + (data (i32.const 7472) "__ashrti3 result should be -2^125\00") + (data (i32.const 7520) "__ashrti3 result should be -2^63\00") + (data (i32.const 7568) "__ashrti3 result should be -2^31\00") + (data (i32.const 7616) "__ashrti3 result should be -2^0\00") + (data (i32.const 7648) "__modti3 result should be -30\00") + (data (i32.const 7680) "__modti3 result should be 30\00") + (data (i32.const 7712) "__modti3 result should be 10\00") + (data (i32.const 7744) "__modti3 result should be 0\00") + (data (i32.const 7776) "should have thrown an error\00") + (data (i32.const 7808) "public key does not match\00") + (data (i32.const 7840) "abc\00") + (data (i32.const 7856) "\a9\99>6G\06\81j\ba>%qxP\c2l\9c\d0\d8\9d") + (data (i32.const 7888) "sha1 test1\00") + (data (i32.const 7904) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\00") + (data (i32.const 7968) "\84\98>D\1c;\d2n\ba\aeJ\a1\f9Q)\e5\e5Fp\f1") + (data (i32.const 8000) "sha1 test3\00") + (data (i32.const 8016) "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu\00") + (data (i32.const 8144) "\a4\9b$F\a0,d[\f4\19\f9\95\b6p\91%:\04\a2Y") + (data (i32.const 8176) "sha1 test4\00") + (data (i32.const 8192) "message digest\00") + (data (i32.const 8208) "\c1\"R\ce\da\8b\e8\99M_\a0)\nG#\1c\1d\16\aa\e3") + (data (i32.const 8240) "sha1 test5\00") + (data (i32.const 8256) "\bax\16\bf\8f\01\cf\eaAA@\de]\ae\"#\b0\03a\a3\96\17z\9c\b4\10\ffa\f2\00\15\ad") + (data (i32.const 8288) "sha256 test1\00") + (data (i32.const 8304) "$\8dja\d2\068\b8\e5\c0&\93\0c>`9\a3<\e4Yd\ff!g\f6\ec\ed\d4\19\db\06\c1") + (data (i32.const 8336) "sha256 test3\00") + (data (i32.const 8352) "\cf[\16\a7x\af\83\80\03l\e5\9e{\04\927\0b$\9b\11\e8\f0zQ\af\acE\03z\fe\e9\d1") + (data (i32.const 8384) "sha256 test4\00") + (data (i32.const 8400) "\f7\84oU\cf#\e1N\eb\ea\b5\b4\e1U\0c\ad[P\9e3H\fb\c4\ef\a3\a1A=9<\b6P") + (data (i32.const 8432) "sha256 test5\00") + (data (i32.const 8448) "\dd\af5\a1\93az\ba\ccAsI\ae A1\12\e6\faN\89\a9~\a2\n\9e\ee\e6KU\d3\9a!\92\99*\'O\c1\a86\ba<#\a3\fe\eb\bdEMD#d<\e8\0e*\9a\c9O\a5L\a4\9f") + (data (i32.const 8512) "sha512 test1\00") + (data (i32.const 8528) " J\8f\c6\dd\a8/\n\0c\ed{\eb\8e\08\a4\16W\c1n\f4h\b2(\a8\'\9b\e31\a7\03\c35\96\fd\15\c1;\1b\07\f9\aa\1d;\eaWx\9c\a01\ad\85\c7\a7\1d\d7\03T\ecc\128\ca4E") + (data (i32.const 8592) "sha512 test3\00") + (data (i32.const 8608) "\8e\95\9bu\da\e3\13\da\8c\f4\f7(\14\fc\14?\8fwy\c6\eb\9f\7f\a1r\99\ae\ad\b6\88\90\18P\1d(\9eI\00\f7\e43\1b\99\de\c4\b5C:\c7\d3)\ee\b6\dd&T^\96\e5[\87K\e9\t") + (data (i32.const 8672) "sha512 test4\00") + (data (i32.const 8688) "\10}\bf8\9d\9e\9fq\a3\a9_l\05[\92Q\bcRh\c2\be\16\d6\c14\92\eaE\b0\19\9f3\t\e1dU\ab\1e\96\11\8e\8a\90]U\97\b7 8\dd\b3r\a8\98&\04m\e6f\87\bbB\0e|") + (data (i32.const 8752) "sha512 test5\00") + (data (i32.const 8768) "\8e\b2\08\f7\e0]\98z\9b\04J\8e\98\c6\b0\87\f1Z\0b\fc") + (data (i32.const 8800) "ripemd160 test1\00") + (data (i32.const 8816) "\12\a0S8J\9c\0c\88\e4\05\a0l\'\dc\f4\9a\dab\eb+") + (data (i32.const 8848) "ripemd160 test3\00") + (data (i32.const 8864) "o?\a3\9bkP<8O\91\9aI\a7\aa\\,\08\bd\fbE") + (data (i32.const 8896) "ripemd160 test4\00") + (data (i32.const 8912) "]\06\89\efI\d2\fa\e5r\b8\81\b1#\a8_\fa!Y_6") + (data (i32.const 8944) "ripemd160 test5\00") + (data (i32.const 8976) "\da9\a3\ee^kK\0d2U\bf\ef\95`\18\90\af\d8\07\t") + (data (i32.const 9008) "sha1 test2\00") + (data (i32.const 9024) "\e3\b0\c4B\98\fc\1c\14\9a\fb\f4\c8\99o\b9$\'\aeA\e4d\9b\93L\a4\95\99\1bxR\b8U") + (data (i32.const 9056) "sha256 test2\00") + (data (i32.const 9072) "\cf\83\e15~\ef\b8\bd\f1T(P\d6m\80\07\d6 \e4\05\0bW\15\dc\83\f4\a9!\d3l\e9\ceG\d0\d1<]\85\f2\b0\ff\83\18\d2\87~\ec/c\b91\bdGAz\81\a582z\f9\'\da>") + (data (i32.const 9136) "sha512 test2\00") + (data (i32.const 9152) "\9c\11\85\a5\c5\e9\fcTa(\08\97~\e8\f5H\b2%\8d1") + (data (i32.const 9184) "ripemd160 test2\00") + (data (i32.const 9200) "should have failed\00") + (data (i32.const 9232) "producers.len != 21\00") + (data (i32.const 9264) "Active producer\00") + (data (i32.const 9280) "EwfUD\12\cd\11\ab\12\aeQt") + (data (i32.const 17488) "send_message_large() should\'ve thrown an error\00") + (data (i32.const 17536) "tapos_block_prefix does not match\00") + (data (i32.const 17584) "tapos_block_num does not match\00") + (data (i32.const 17616) "read_transaction failed\00") + (data (i32.const 17648) "size: \00") + (data (i32.const 17664) "transaction size does not match\00") + (data (i32.const 17696) "EwfUD\12\cd\11\ab\12\aeQt") + (data (i32.const 17712) "send_transaction_empty() should\'ve thrown an error\00") + (data (i32.const 17776) "transaction should only have one action\00") + (data (i32.const 17824) "transaction has wrong code\00") + (data (i32.const 17856) "transaction has wrong name\00") + (data (i32.const 17888) "action should only have one authorization\00") + (data (i32.const 17936) "action\'s authorization has wrong actor\00") + (data (i32.const 17984) "action\'s authorization has wrong permission\00") + (data (i32.const 18032) "send_transaction_large() should\'ve thrown an error\00") + (data (i32.const 18096) "deferred executed\n\00") + (data (i32.const 18128) "transaction was not found\00") + (data (i32.const 18160) "transaction was canceled, whild should not be found\00") + (data (i32.const 18224) "context free actions cannot have authorizations\00") + (data (i32.const 18272) "dummy\00") + (data (i32.const 18288) "send_cfa_action_fail() should\'ve thrown an error\00") + (data (i32.const 18352) "test_transaction\00") + (data (i32.const 18384) "table\00") + (data (i32.const 18400) "newfeature\00") + (data (i32.const 18416) "we should not have new features unless hardfork\00") + (data (i32.const 18464) "unexpected last used permission time\00") + (data (i32.const 18512) "unexpected account creation time\00") + (data (i32.const 18560) "bool\00") + (data (i32.const 18576) "int8\00") + (data (i32.const 18592) "uint8\00") + (data (i32.const 18608) "int16\00") + (data (i32.const 18624) "uint16\00") + (data (i32.const 18640) "int32\00") + (data (i32.const 18656) "uint32\00") + (data (i32.const 18672) "int64\00") + (data (i32.const 18688) "uint64\00") + (data (i32.const 18704) "float\00") + (data (i32.const 18720) "double\00") + (data (i32.const 18728) "\01\00\00\00\00\00\00\0082\8f\fc\c1\c0\f3?") + (data (i32.const 18752) "struct\00") + (data (i32.const 18760) "\n\00\00\00\14\00\00\00") + (data (i32.const 18768) "StaticArray\00") + (data (i32.const 18784) "string\00") + (data (i32.const 18800) "vector\00") + (data (i32.const 18816) "empty vector\00") + (data (i32.const 18832) "\n\00\00\00\14\00\00\00\1e\00\00\00") + (data (i32.const 18848) "std::array\00") + (data (i32.const 18864) "apple\00") + (data (i32.const 18880) "cat\00") + (data (i32.const 18896) "panda\00") + (data (i32.const 18912) "map\00") + (data (i32.const 18928) "tuple\00") + (data (i32.const 18944) "eosio\00") + (data (i32.const 18960) "onerror\00") + (data (i32.const 18976) "onerror called\n\00") + (data (i32.const 18992) "Unknown Test\00") + (data (i32.const 27408) "malloc_from_freed was designed to only be called after _heap was completely allocated\00") + (export "memory" (memory $0)) + (export "_ZeqRK11checksum256S1_" (func $_ZeqRK11checksum256S1_)) + (export "_ZeqRK11checksum160S1_" (func $_ZeqRK11checksum160S1_)) + (export "_ZneRK11checksum160S1_" (func $_ZneRK11checksum160S1_)) + (export "now" (func $now)) + (export "_ZN5eosio12require_authERKNS_16permission_levelE" (func $_ZN5eosio12require_authERKNS_16permission_levelE)) + (export "_ZN11test_action18read_action_normalEv" (func $_ZN11test_action18read_action_normalEv)) + (export "_ZN11test_action17test_dummy_actionEv" (func $_ZN11test_action17test_dummy_actionEv)) + (export "_ZN11test_action16read_action_to_0Ev" (func $_ZN11test_action16read_action_to_0Ev)) + (export "_ZN11test_action18read_action_to_64kEv" (func $_ZN11test_action18read_action_to_64kEv)) + (export "_ZN11test_action14test_cf_actionEv" (func $_ZN11test_action14test_cf_actionEv)) + (export "_ZN11test_action14require_noticeEyyy" (func $_ZN11test_action14require_noticeEyyy)) + (export "_ZN11test_action12require_authEv" (func $_ZN11test_action12require_authEv)) + (export "_ZN11test_action12assert_falseEv" (func $_ZN11test_action12assert_falseEv)) + (export "_ZN11test_action11assert_trueEv" (func $_ZN11test_action11assert_trueEv)) + (export "_ZN11test_action14assert_true_cfEv" (func $_ZN11test_action14assert_true_cfEv)) + (export "_ZN11test_action10test_abortEv" (func $_ZN11test_action10test_abortEv)) + (export "_ZN11test_action21test_publication_timeEv" (func $_ZN11test_action21test_publication_timeEv)) + (export "_ZN11test_action21test_current_receiverEyyy" (func $_ZN11test_action21test_current_receiverEyyy)) + (export "_ZN11test_action17test_current_timeEv" (func $_ZN11test_action17test_current_timeEv)) + (export "_ZN11test_action16test_assert_codeEv" (func $_ZN11test_action16test_assert_codeEv)) + (export "_ZN10test_print13test_prints_lEv" (func $_ZN10test_print13test_prints_lEv)) + (export "_ZN10test_print11test_printsEv" (func $_ZN10test_print11test_printsEv)) + (export "_ZN10test_print11test_printiEv" (func $_ZN10test_print11test_printiEv)) + (export "_ZN10test_print12test_printuiEv" (func $_ZN10test_print12test_printuiEv)) + (export "_ZN10test_print14test_printi128Ev" (func $_ZN10test_print14test_printi128Ev)) + (export "_ZN10test_print15test_printui128Ev" (func $_ZN10test_print15test_printui128Ev)) + (export "_ZN10test_print11test_printnEv" (func $_ZN10test_print11test_printnEv)) + (export "_ZN10test_print12test_printsfEv" (func $_ZN10test_print12test_printsfEv)) + (export "_ZN10test_print12test_printdfEv" (func $_ZN10test_print12test_printdfEv)) + (export "_ZN10test_print12test_printqfEv" (func $_ZN10test_print12test_printqfEv)) + (export "_ZN10test_print17test_print_simpleEv" (func $_ZN10test_print17test_print_simpleEv)) + (export "_ZN10test_types10types_sizeEv" (func $_ZN10test_types10types_sizeEv)) + (export "_ZN10test_types14char_to_symbolEv" (func $_ZN10test_types14char_to_symbolEv)) + (export "_ZN10test_types14string_to_nameEv" (func $_ZN10test_types14string_to_nameEv)) + (export "_ZN10test_types10name_classEv" (func $_ZN10test_types10name_classEv)) + (export "_ZN15test_fixedpoint16create_instancesEv" (func $_ZN15test_fixedpoint16create_instancesEv)) + (export "_ZN15test_fixedpoint13test_additionEv" (func $_ZN15test_fixedpoint13test_additionEv)) + (export "_ZN15test_fixedpoint16test_subtractionEv" (func $_ZN15test_fixedpoint16test_subtractionEv)) + (export "_ZN15test_fixedpoint19test_multiplicationEv" (func $_ZN15test_fixedpoint19test_multiplicationEv)) + (export "_ZN15test_fixedpoint13test_divisionEv" (func $_ZN15test_fixedpoint13test_divisionEv)) + (export "_ZN15test_fixedpoint18test_division_by_0Ev" (func $_ZN15test_fixedpoint18test_division_by_0Ev)) + (export "_Zli5_ULLLPKc" (func $_Zli5_ULLLPKc)) + (export "_Zli4_LLLPKc" (func $_Zli4_LLLPKc)) + (export "_ZN22test_compiler_builtins11test_multi3Ev" (func $_ZN22test_compiler_builtins11test_multi3Ev)) + (export "_ZN22test_compiler_builtins11test_divti3Ev" (func $_ZN22test_compiler_builtins11test_divti3Ev)) + (export "_ZN22test_compiler_builtins16test_divti3_by_0Ev" (func $_ZN22test_compiler_builtins16test_divti3_by_0Ev)) + (export "_ZN22test_compiler_builtins12test_udivti3Ev" (func $_ZN22test_compiler_builtins12test_udivti3Ev)) + (export "_ZN22test_compiler_builtins17test_udivti3_by_0Ev" (func $_ZN22test_compiler_builtins17test_udivti3_by_0Ev)) + (export "_ZN22test_compiler_builtins12test_lshlti3Ev" (func $_ZN22test_compiler_builtins12test_lshlti3Ev)) + (export "_ZN22test_compiler_builtins12test_ashlti3Ev" (func $_ZN22test_compiler_builtins12test_ashlti3Ev)) + (export "_ZN22test_compiler_builtins12test_lshrti3Ev" (func $_ZN22test_compiler_builtins12test_lshrti3Ev)) + (export "_ZN22test_compiler_builtins12test_ashrti3Ev" (func $_ZN22test_compiler_builtins12test_ashrti3Ev)) + (export "_ZN22test_compiler_builtins11test_modti3Ev" (func $_ZN22test_compiler_builtins11test_modti3Ev)) + (export "_ZN22test_compiler_builtins16test_modti3_by_0Ev" (func $_ZN22test_compiler_builtins16test_modti3_by_0Ev)) + (export "_ZN22test_compiler_builtins12test_umodti3Ev" (func $_ZN22test_compiler_builtins12test_umodti3Ev)) + (export "_ZN22test_compiler_builtins17test_umodti3_by_0Ev" (func $_ZN22test_compiler_builtins17test_umodti3_by_0Ev)) + (export "my_strlen" (func $my_strlen)) + (export "my_memcmp" (func $my_memcmp)) + (export "_ZN11test_crypto28test_recover_key_assert_trueEv" (func $_ZN11test_crypto28test_recover_key_assert_trueEv)) + (export "_ZN11test_crypto29test_recover_key_assert_falseEv" (func $_ZN11test_crypto29test_recover_key_assert_falseEv)) + (export "_ZN11test_crypto16test_recover_keyEv" (func $_ZN11test_crypto16test_recover_keyEv)) + (export "_ZN11test_crypto9test_sha1Ev" (func $_ZN11test_crypto9test_sha1Ev)) + (export "_ZN11test_crypto11test_sha256Ev" (func $_ZN11test_crypto11test_sha256Ev)) + (export "_ZN11test_crypto11test_sha512Ev" (func $_ZN11test_crypto11test_sha512Ev)) + (export "_ZN11test_crypto14test_ripemd160Ev" (func $_ZN11test_crypto14test_ripemd160Ev)) + (export "_ZN11test_crypto11sha256_nullEv" (func $_ZN11test_crypto11sha256_nullEv)) + (export "_ZN11test_crypto12sha1_no_dataEv" (func $_ZN11test_crypto12sha1_no_dataEv)) + (export "_ZN11test_crypto14sha256_no_dataEv" (func $_ZN11test_crypto14sha256_no_dataEv)) + (export "_ZN11test_crypto14sha512_no_dataEv" (func $_ZN11test_crypto14sha512_no_dataEv)) + (export "_ZN11test_crypto17ripemd160_no_dataEv" (func $_ZN11test_crypto17ripemd160_no_dataEv)) + (export "_ZN11test_crypto19assert_sha256_falseEv" (func $_ZN11test_crypto19assert_sha256_falseEv)) + (export "_ZN11test_crypto18assert_sha256_trueEv" (func $_ZN11test_crypto18assert_sha256_trueEv)) + (export "_ZN11test_crypto17assert_sha1_falseEv" (func $_ZN11test_crypto17assert_sha1_falseEv)) + (export "_ZN11test_crypto16assert_sha1_trueEv" (func $_ZN11test_crypto16assert_sha1_trueEv)) + (export "_ZN11test_crypto19assert_sha512_falseEv" (func $_ZN11test_crypto19assert_sha512_falseEv)) + (export "_ZN11test_crypto18assert_sha512_trueEv" (func $_ZN11test_crypto18assert_sha512_trueEv)) + (export "_ZN11test_crypto22assert_ripemd160_falseEv" (func $_ZN11test_crypto22assert_ripemd160_falseEv)) + (export "_ZN11test_crypto21assert_ripemd160_trueEv" (func $_ZN11test_crypto21assert_ripemd160_trueEv)) + (export "_ZN10test_chain16test_activeprodsEv" (func $_ZN10test_chain16test_activeprodsEv)) + (export "_Z9copy_dataPcjRNSt3__16vectorIcNS0_9allocatorIcEEEE" (func $_Z9copy_dataPcjRNSt3__16vectorIcNS0_9allocatorIcEEEE)) + (export "_ZN16test_transaction11send_actionEv" (func $_ZN16test_transaction11send_actionEv)) + (export "_ZN16test_transaction17send_action_emptyEv" (func $_ZN16test_transaction17send_action_emptyEv)) + (export "_ZN16test_transaction17send_action_largeEv" (func $_ZN16test_transaction17send_action_largeEv)) + (export "_ZN16test_transaction19send_action_recurseEv" (func $_ZN16test_transaction19send_action_recurseEv)) + (export "_ZN16test_transaction23send_action_inline_failEv" (func $_ZN16test_transaction23send_action_inline_failEv)) + (export "_ZN16test_transaction23test_tapos_block_prefixEv" (func $_ZN16test_transaction23test_tapos_block_prefixEv)) + (export "_ZN16test_transaction20test_tapos_block_numEv" (func $_ZN16test_transaction20test_tapos_block_numEv)) + (export "_ZN16test_transaction21test_read_transactionEv" (func $_ZN16test_transaction21test_read_transactionEv)) + (export "_ZN16test_transaction21test_transaction_sizeEv" (func $_ZN16test_transaction21test_transaction_sizeEv)) + (export "_ZN16test_transaction16send_transactionEyyy" (func $_ZN16test_transaction16send_transactionEyyy)) + (export "_ZN16test_transaction18send_action_senderEyyy" (func $_ZN16test_transaction18send_action_senderEyyy)) + (export "_ZN16test_transaction22send_transaction_emptyEyyy" (func $_ZN16test_transaction22send_transaction_emptyEyyy)) + (export "_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy" (func $_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy)) + (export "_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE" (func $_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE)) + (export "_ZN16test_transaction22send_transaction_largeEyyy" (func $_ZN16test_transaction22send_transaction_largeEyyy)) + (export "_ZN16test_transaction14deferred_printEv" (func $_ZN16test_transaction14deferred_printEv)) + (export "_ZN16test_transaction25send_deferred_transactionEyyy" (func $_ZN16test_transaction25send_deferred_transactionEyyy)) + (export "_ZN16test_transaction33send_deferred_transaction_replaceEyyy" (func $_ZN16test_transaction33send_deferred_transaction_replaceEyyy)) + (export "_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv" (func $_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv)) + (export "_ZN16test_transaction35cancel_deferred_transaction_successEv" (func $_ZN16test_transaction35cancel_deferred_transaction_successEv)) + (export "_ZN16test_transaction37cancel_deferred_transaction_not_foundEv" (func $_ZN16test_transaction37cancel_deferred_transaction_not_foundEv)) + (export "_ZN16test_transaction14send_cf_actionEv" (func $_ZN16test_transaction14send_cf_actionEv)) + (export "_ZN16test_transaction19send_cf_action_failEv" (func $_ZN16test_transaction19send_cf_action_failEv)) + (export "_ZN16test_transaction12stateful_apiEv" (func $_ZN16test_transaction12stateful_apiEv)) + (export "_ZN16test_transaction16context_free_apiEv" (func $_ZN16test_transaction16context_free_apiEv)) + (export "_ZN16test_transaction11new_featureEv" (func $_ZN16test_transaction11new_featureEv)) + (export "_ZN16test_transaction18active_new_featureEv" (func $_ZN16test_transaction18active_new_featureEv)) + (export "_ZN14test_checktime14checktime_passEv" (func $_ZN14test_checktime14checktime_passEv)) + (export "_ZN14test_checktime17checktime_failureEv" (func $_ZN14test_checktime17checktime_failureEv)) + (export "_ZN14test_checktime22checktime_sha1_failureEv" (func $_ZN14test_checktime22checktime_sha1_failureEv)) + (export "_ZN14test_checktime29checktime_assert_sha1_failureEv" (func $_ZN14test_checktime29checktime_assert_sha1_failureEv)) + (export "_ZN14test_checktime24checktime_sha256_failureEv" (func $_ZN14test_checktime24checktime_sha256_failureEv)) + (export "_ZN14test_checktime31checktime_assert_sha256_failureEv" (func $_ZN14test_checktime31checktime_assert_sha256_failureEv)) + (export "_ZN14test_checktime24checktime_sha512_failureEv" (func $_ZN14test_checktime24checktime_sha512_failureEv)) + (export "_ZN14test_checktime31checktime_assert_sha512_failureEv" (func $_ZN14test_checktime31checktime_assert_sha512_failureEv)) + (export "_ZN14test_checktime27checktime_ripemd160_failureEv" (func $_ZN14test_checktime27checktime_ripemd160_failureEv)) + (export "_ZN14test_checktime34checktime_assert_ripemd160_failureEv" (func $_ZN14test_checktime34checktime_assert_ripemd160_failureEv)) + (export "_ZN15test_permission19check_authorizationEyyy" (func $_ZN15test_permission19check_authorizationEyyy)) + (export "_ZN15test_permission25test_permission_last_usedEyyy" (func $_ZN15test_permission25test_permission_last_usedEyyy)) + (export "_ZN15test_permission26test_account_creation_timeEyyy" (func $_ZN15test_permission26test_account_creation_timeEyyy)) + (export "_ZN15test_datastream10test_basicEv" (func $_ZN15test_datastream10test_basicEv)) + (export "apply" (func $apply)) + (export "fabs" (func $fabs)) + (export "fabsf" (func $fabsf)) + (export "memccpy" (func $memccpy)) + (export "memcmp" (func $memcmp)) + (export "strlen" (func $strlen)) + (export "malloc" (func $malloc)) + (export "free" (func $free)) + (func $_ZeqRK11checksum256S1_ (param $0 i32) (param $1 i32) (result i32) + (i32.eqz + (call $memcmp + (get_local $0) + (get_local $1) + (i32.const 32) + ) + ) + ) + (func $_ZeqRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) + (i32.eqz + (call $memcmp + (get_local $0) + (get_local $1) + (i32.const 32) + ) + ) + ) + (func $_ZneRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) + (i32.ne + (call $memcmp + (get_local $0) + (get_local $1) + (i32.const 32) + ) + (i32.const 0) + ) + ) + (func $now (result i32) + (i32.wrap/i64 + (i64.div_u + (call $current_time) + (i64.const 1000000) + ) + ) + ) + (func $_ZN5eosio12require_authERKNS_16permission_levelE (param $0 i32) + (call $require_auth2 + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (func $_ZN11test_action18read_action_normalEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (call $eosio_assert + (i32.eq + (call $action_data_size) + (i32.const 13) + ) + (i32.const 32) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (get_local $0) + (i32.const 30) + ) + (i32.const 13) + ) + (i32.const 80) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (get_local $0) + (i32.const 100) + ) + (i32.const 13) + ) + (i32.const 96) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (get_local $0) + (i32.const 5) + ) + (i32.const 5) + ) + (i32.const 128) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (get_local $0) + (i32.const 13) + ) + (i32.const 13) + ) + (i32.const 144) + ) + (call $eosio_assert + (i32.eq + (i32.load8_u + (get_local $0) + ) + (i32.const 69) + ) + (i32.const 192) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=1 align=1 + (get_local $0) + ) + (i64.const -6119884940280240521) + ) + (i32.const 240) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=9 align=1 + (get_local $0) + ) + (i32.const 1951510034) + ) + (i32.const 288) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 112) + ) + ) + ) + (func $_ZN11test_action17test_dummy_actionEv + (local $0 i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 176) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (tee_local $0 + (call $get_action + (i32.const 1) + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 64) + ) + (call $get_action + (i32.const 1) + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 64) + ) + (i32.const 0) + ) + ) + ) + (i32.const 0) + ) + (i32.const 336) + ) + (call $_ZN5eosio10get_actionEmm + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.const 1) + (i32.const 0) + ) + (set_local $1 + (i64.load + (i32.add + (i32.load + (i32.add + (get_local $10) + (i32.const 44) + ) + ) + (i32.const -16) + ) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $2 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $2 + (select + (i32.add + (get_local $2) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $2) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (get_local $8) + ) + (i32.const 384) + ) + (set_local $1 + (i64.load + (i32.add + (i32.load + (i32.add + (get_local $10) + (i32.const 44) + ) + ) + (i32.const -8) + ) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 416) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $7) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $2 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $2 + (select + (i32.add + (get_local $2) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $2) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (get_local $8) + ) + (i32.const 432) + ) + (set_local $5 + (i32.const 16) + ) + (set_local $7 + (i64.extend_u/i32 + (i32.shr_s + (tee_local $4 + (i32.sub + (tee_local $2 + (i32.load + (i32.add + (get_local $10) + (i32.const 44) + ) + ) + ) + (tee_local $3 + (i32.load + (i32.add + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.const 16) + ) + ) + ) + ) + ) + (i32.const 4) + ) + ) + ) + (loop $label$12 + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (br_if $label$12 + (i64.ne + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eq + (get_local $3) + (get_local $2) + ) + ) + (set_local $5 + (i32.add + (i32.and + (get_local $4) + (i32.const -16) + ) + (get_local $5) + ) + ) + ) + (set_local $5 + (i32.sub + (i32.sub + (i32.add + (get_local $0) + (tee_local $2 + (i32.load offset=52 + (get_local $10) + ) + ) + ) + (get_local $5) + ) + (tee_local $0 + (i32.load + (i32.add + (get_local $10) + (i32.const 56) + ) + ) + ) + ) + ) + (set_local $7 + (i64.extend_u/i32 + (i32.sub + (get_local $0) + (get_local $2) + ) + ) + ) + (loop $label$14 + (set_local $5 + (i32.add + (get_local $5) + (i32.const -1) + ) + ) + (br_if $label$14 + (i64.ne + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (call $eosio_assert + (i32.eqz + (get_local $5) + ) + (i32.const 464) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 368) + ) + (set_local $1 + (i64.load offset=24 + (get_local $10) + ) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$15 + (block $label$16 + (block $label$17 + (block $label$18 + (block $label$19 + (block $label$20 + (br_if $label$20 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$19 + (i32.gt_u + (i32.and + (i32.add + (tee_local $2 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 165) + ) + ) + (br $label$18) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$17 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$16) + ) + (set_local $2 + (select + (i32.add + (get_local $2) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $2) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$15 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (get_local $8) + ) + (i32.const 512) + ) + (call $_ZN5eosio6action7data_asI12dummy_actionEET_v + (i32.add + (get_local $10) + (i32.const 8) + ) + (i32.add + (get_local $10) + (i32.const 24) + ) + ) + (block $label$21 + (block $label$22 + (block $label$23 + (br_if $label$23 + (i64.ne + (i64.load offset=9 align=1 + (get_local $10) + ) + (i64.const 200) + ) + ) + (drop + (call $get_context_free_data + (i32.const 0) + (i32.const 0) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 544) + ) + (br_if $label$22 + (tee_local $5 + (i32.load offset=52 + (get_local $10) + ) + ) + ) + (br $label$21) + ) + (call $eosio_assert + (i32.eq + (i32.load8_u offset=8 + (get_local $10) + ) + (i32.const 69) + ) + (i32.const 608) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=9 align=1 + (get_local $10) + ) + (i64.const -6119884940280240521) + ) + (i32.const 656) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=17 align=1 + (get_local $10) + ) + (i32.const 1951510034) + ) + (i32.const 704) + ) + (br_if $label$21 + (i32.eqz + (tee_local $5 + (i32.load offset=52 + (get_local $10) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 56) + ) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (block $label$24 + (br_if $label$24 + (i32.eqz + (tee_local $5 + (i32.load offset=40 + (get_local $10) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 44) + ) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 176) + ) + ) + ) + (func $_ZN5eosio10get_actionEmm (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (set_local $5 + (tee_local $4 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $4) + ) + (call $eosio_assert + (i32.gt_s + (tee_local $3 + (call $get_action + (get_local $1) + (get_local $2) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 0) + ) + (i32.const 816) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (get_local $3) + (i32.const 513) + ) + ) + (set_local $4 + (call $malloc + (get_local $3) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (get_local $4) + (i32.and + (i32.add + (get_local $3) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (call $eosio_assert + (i32.eq + (get_local $3) + (call $get_action + (get_local $1) + (get_local $2) + (get_local $4) + (get_local $3) + ) + ) + (i32.const 336) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i32.store + (get_local $5) + (get_local $4) + ) + (i32.store offset=8 + (get_local $5) + (tee_local $1 + (i32.add + (get_local $4) + (get_local $3) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (get_local $3) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $4) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (get_local $1) + (tee_local $3 + (i32.add + (get_local $4) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $3) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $5) + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE + (call $_ZN5eosiorsINS_10datastreamIPKcEENS_16permission_levelEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE + (get_local $5) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosio6action7data_asI12dummy_actionEET_v (param $0 i32) (param $1 i32) + (local $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (set_local $2 + (i64.load offset=8 + (get_local $1) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $8 + (i64.const 59) + ) + (set_local $4 + (i32.const 752) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$0 + (set_local $6 + (i64.const 0) + ) + (block $label$1 + (br_if $label$1 + (i64.gt_u + (get_local $7) + (i64.const 11) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$2) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.extend_u/i32 + (i32.and + (get_local $3) + (i32.const 31) + ) + ) + (i64.and + (get_local $8) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $8 + (i64.add + (get_local $8) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $5) + ) + (i32.const 768) + ) + (set_local $2 + (i64.load + (get_local $1) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $4 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$8 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$7) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$6 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$5) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $8) + (get_local $5) + ) + ) + (br_if $label$4 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $5) + ) + (i32.const 784) + ) + (call $eosio_assert + (i32.ne + (tee_local $3 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + (tee_local $4 + (i32.load offset=28 + (get_local $1) + ) + ) + ) + ) + (i32.const 0) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $4) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.add + (get_local $3) + (i32.const -1) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 1) + ) + (i32.add + (get_local $4) + (i32.const 1) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.add + (get_local $3) + (i32.const -9) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 9) + ) + (i32.add + (get_local $4) + (i32.const 9) + ) + (i32.const 4) + ) + ) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEENS_16permission_levelEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (set_local $7 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $5 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $7) + (i32.load + (get_local $2) + ) + ) + (i32.const 848) + ) + (set_local $4 + (i32.load8_u + (tee_local $7 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $6 + (i32.and + (get_local $6) + (i32.const 255) + ) + ) + ) + ) + (get_local $5) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.le_u + (tee_local $4 + (i32.wrap/i64 + (get_local $5) + ) + ) + (tee_local $6 + (i32.shr_s + (i32.sub + (tee_local $2 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $7 + (i32.load + (get_local $1) + ) + ) + ) + (i32.const 4) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIN5eosio16permission_levelENS_9allocatorIS2_EEE8__appendEj + (get_local $1) + (i32.sub + (get_local $4) + (get_local $6) + ) + ) + (br_if $label$2 + (i32.ne + (tee_local $7 + (i32.load + (get_local $1) + ) + ) + (tee_local $2 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (br $label$1) + ) + (block $label$4 + (br_if $label$4 + (i32.ge_u + (get_local $4) + (get_local $6) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (tee_local $2 + (i32.add + (get_local $7) + (i32.shl + (get_local $4) + (i32.const 4) + ) + ) + ) + ) + ) + (br_if $label$1 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + ) + (set_local $6 + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (loop $label$5 + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $6) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $7) + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (get_local $3) + ) + (get_local $6) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + ) + (br_if $label$5 + (i32.ne + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $2) + ) + ) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.const 848) + ) + (set_local $4 + (i32.load8_u + (tee_local $5 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $7 + (i32.and + (get_local $7) + (i32.const 255) + ) + ) + ) + ) + (get_local $6) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.le_u + (tee_local $3 + (i32.wrap/i64 + (get_local $6) + ) + ) + (tee_local $2 + (i32.sub + (tee_local $7 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $1) + (i32.sub + (get_local $3) + (get_local $2) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + (set_local $4 + (i32.load + (get_local $1) + ) + ) + (br $label$1) + ) + (br_if $label$1 + (i32.ge_u + (get_local $3) + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (tee_local $7 + (i32.add + (get_local $4) + (get_local $3) + ) + ) + ) + ) + (call $eosio_assert + (i32.ge_u + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $5) + ) + (tee_local $5 + (i32.sub + (get_local $7) + (get_local $4) + ) + ) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $4) + (i32.load + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (get_local $5) + ) + ) + (i32.store + (get_local $7) + (i32.add + (i32.load + (get_local $7) + ) + (get_local $5) + ) + ) + (get_local $0) + ) + (func $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (i32.sub + (tee_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (get_local $1) + ) + ) + (br_if $label$2 + (i32.le_s + (tee_local $4 + (i32.add + (tee_local $3 + (i32.sub + (get_local $6) + (tee_local $5 + (i32.load + (get_local $0) + ) + ) + ) + ) + (get_local $1) + ) + ) + (i32.const -1) + ) + ) + (set_local $6 + (i32.const 2147483647) + ) + (block $label$5 + (br_if $label$5 + (i32.gt_u + (tee_local $2 + (i32.sub + (get_local $2) + (get_local $5) + ) + ) + (i32.const 1073741822) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $6 + (select + (get_local $4) + (tee_local $6 + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $6) + (get_local $4) + ) + ) + ) + ) + ) + ) + (set_local $2 + (call $_Znwj + (get_local $6) + ) + ) + (br $label$1) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$6 + (i32.store8 + (get_local $6) + (i32.const 0) + ) + (i32.store + (get_local $0) + (tee_local $6 + (i32.add + (i32.load + (get_local $0) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$6 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + (br $label$0) + ) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $2 + (i32.const 0) + ) + (br $label$1) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $4 + (i32.add + (get_local $2) + (get_local $6) + ) + ) + (set_local $6 + (tee_local $5 + (i32.add + (get_local $2) + (get_local $3) + ) + ) + ) + (loop $label$7 + (i32.store8 + (get_local $6) + (i32.const 0) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$7 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + ) + (set_local $5 + (i32.sub + (get_local $5) + (tee_local $2 + (i32.sub + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $1 + (i32.load + (get_local $0) + ) + ) + ) + ) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.lt_s + (get_local $2) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $1) + (get_local $2) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $5) + ) + (i32.store + (get_local $3) + (get_local $6) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + (return) + ) + ) + (func $_ZNSt3__16vectorIN5eosio16permission_levelENS_9allocatorIS2_EEE8__appendEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (i32.shr_s + (i32.sub + (tee_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $7 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (i32.const 4) + ) + (get_local $1) + ) + ) + (br_if $label$2 + (i32.ge_u + (tee_local $4 + (i32.add + (tee_local $3 + (i32.shr_s + (i32.sub + (get_local $7) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 4) + ) + ) + (get_local $1) + ) + ) + (i32.const 268435456) + ) + ) + (set_local $5 + (i32.const 268435455) + ) + (block $label$5 + (br_if $label$5 + (i32.gt_u + (i32.shr_s + (tee_local $2 + (i32.sub + (get_local $2) + (get_local $6) + ) + ) + (i32.const 4) + ) + (i32.const 134217726) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $5 + (select + (get_local $4) + (tee_local $5 + (i32.shr_s + (get_local $2) + (i32.const 3) + ) + ) + (i32.lt_u + (get_local $5) + (get_local $4) + ) + ) + ) + ) + ) + (br_if $label$1 + (i32.ge_u + (get_local $5) + (i32.const 268435456) + ) + ) + ) + (set_local $2 + (call $_Znwj + (i32.shl + (get_local $5) + (i32.const 4) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + (br $label$0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.add + (get_local $7) + (i32.shl + (get_local $1) + (i32.const 4) + ) + ) + ) + (return) + ) + (set_local $5 + (i32.const 0) + ) + (set_local $2 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (call $abort) + (unreachable) + ) + (set_local $4 + (i32.sub + (tee_local $3 + (i32.add + (get_local $2) + (i32.shl + (get_local $3) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.sub + (get_local $7) + (get_local $6) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $3) + (i32.shl + (get_local $1) + (i32.const 4) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $2) + (i32.shl + (get_local $5) + (i32.const 4) + ) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.lt_s + (get_local $7) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $4) + (get_local $6) + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $4) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $5) + ) + (block $label$7 + (br_if $label$7 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $_ZN11test_action16read_action_to_0Ev + (drop + (call $read_action_data + (i32.const 0) + (call $action_data_size) + ) + ) + ) + (func $_ZN11test_action18read_action_to_64kEv + (drop + (call $read_action_data + (i32.const 65534) + (call $action_data_size) + ) + ) + ) + (func $_ZN11test_action14test_cf_actionEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 144) + ) + ) + ) + (call $_ZN5eosio10get_actionEmm + (i32.add + (get_local $9) + (i32.const 104) + ) + (i32.const 0) + (i32.const 0) + ) + (call $_ZN5eosio6action7data_asI9cf_actionEET_v + (i32.add + (get_local $9) + (i32.const 96) + ) + (i32.add + (get_local $9) + (i32.const 104) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $2 + (i32.add + (i32.load offset=96 + (get_local $9) + ) + (i32.const -100) + ) + ) + (i32.const 111) + ) + ) + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (br_table $label$16 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$15 $label$14 $label$13 $label$12 $label$11 $label$10 $label$9 $label$8 $label$7 $label$6 $label$5 $label$4 $label$16 + (get_local $2) + ) + ) + (call $eosio_assert + (i32.gt_s + (tee_local $0 + (call $get_context_free_data + (i32.load offset=100 + (get_local $9) + ) + (i32.const 0) + (i32.const 0) + ) + ) + (i32.const 0) + ) + (i32.const 864) + ) + (i32.store offset=88 + (get_local $9) + (i32.const 0) + ) + (i64.store offset=80 + (get_local $9) + (i64.const 0) + ) + (set_local $2 + (i32.const 0) + ) + (block $label$17 + (br_if $label$17 + (i32.eqz + (get_local $0) + ) + ) + (br_if $label$0 + (i32.le_s + (get_local $0) + (i32.const -1) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 88) + ) + (i32.add + (tee_local $2 + (call $_Znwj + (get_local $0) + ) + ) + (get_local $0) + ) + ) + (i32.store offset=80 + (get_local $9) + (get_local $2) + ) + (i32.store offset=84 + (get_local $9) + (get_local $2) + ) + (set_local $1 + (get_local $0) + ) + (loop $label$18 + (i32.store8 + (get_local $2) + (i32.const 0) + ) + (i32.store offset=84 + (get_local $9) + (tee_local $2 + (i32.add + (i32.load offset=84 + (get_local $9) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$18 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + ) + (set_local $2 + (i32.load offset=80 + (get_local $9) + ) + ) + ) + (call $eosio_assert + (i32.eq + (call $get_context_free_data + (i32.load offset=100 + (get_local $9) + ) + (get_local $2) + (get_local $0) + ) + (i32.sub + (i32.load offset=84 + (get_local $9) + ) + (i32.load offset=80 + (get_local $9) + ) + ) + ) + (i32.const 896) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=84 + (get_local $9) + ) + (tee_local $2 + (i32.load offset=80 + (get_local $9) + ) + ) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $9) + (get_local $2) + (i32.const 4) + ) + ) + (i32.store offset=76 + (get_local $9) + (tee_local $2 + (i32.load + (get_local $9) + ) + ) + ) + (call $eosio_assert + (i32.eq + (get_local $2) + (i32.load offset=96 + (get_local $9) + ) + ) + (i32.const 928) + ) + (i32.store8 + (i32.add + (i32.add + (get_local $9) + (i32.const 68) + ) + (i32.const 4) + ) + (i32.load8_u offset=948 + (i32.const 0) + ) + ) + (i32.store offset=68 + (get_local $9) + (i32.load offset=944 align=1 + (i32.const 0) + ) + ) + (call $sha256 + (i32.add + (get_local $9) + (i32.const 68) + ) + (i32.const 5) + (get_local $9) + ) + (call $assert_sha256 + (i32.add + (get_local $9) + (i32.const 68) + ) + (i32.const 5) + (get_local $9) + ) + (drop + (call $action_data_size) + ) + (call $prints + (i32.const 960) + ) + (i32.store offset=64 + (get_local $9) + (i32.const 42) + ) + (drop + (call $memccpy + (i32.add + (get_local $9) + (i32.const 76) + ) + (i32.add + (get_local $9) + (i32.const 64) + ) + (i32.const 4) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.ne + (call $transaction_size) + (i32.const 0) + ) + (i32.const 976) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1008) + ) + (call $__divti3 + (i32.add + (get_local $9) + (i32.const 48) + ) + (i64.const 2) + (i64.const 2) + (i64.const 2) + (i64.const 2) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1040) + ) + (br_if $label$3 + (i32.eqz + (tee_local $2 + (i32.load offset=80 + (get_local $9) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $9) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (drop + (call $is_privileged + (i64.load offset=112 + (get_local $9) + ) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1088) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (drop + (call $get_active_producers + (i32.const 0) + (i32.const 0) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1136) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$19 + (block $label$20 + (block $label$21 + (block $label$22 + (block $label$23 + (block $label$24 + (br_if $label$24 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$23 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$22) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$21 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$20) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$19 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$25 + (block $label$26 + (block $label$27 + (block $label$28 + (block $label$29 + (block $label$30 + (br_if $label$30 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$29 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$28) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$27 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$26) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $6) + (get_local $7) + ) + ) + (br_if $label$25 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$31 + (block $label$32 + (block $label$33 + (block $label$34 + (block $label$35 + (block $label$36 + (br_if $label$36 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$35 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$34) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$33 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$32) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $6) + (get_local $8) + ) + ) + (br_if $label$31 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (drop + (call $db_store_i64 + (get_local $5) + (get_local $7) + (get_local $8) + (i64.const 0) + (i32.const 944) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1184) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (set_local $4 + (i64.const 0) + ) + (i64.store + (get_local $9) + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$37 + (block $label$38 + (block $label$39 + (block $label$40 + (block $label$41 + (block $label$42 + (br_if $label$42 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$41 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$40) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$39 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$38) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$37 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$43 + (block $label$44 + (block $label$45 + (block $label$46 + (block $label$47 + (block $label$48 + (br_if $label$48 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$47 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$46) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$45 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$44) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $6) + (get_local $7) + ) + ) + (br_if $label$43 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$49 + (block $label$50 + (block $label$51 + (block $label$52 + (block $label$53 + (block $label$54 + (br_if $label$54 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$53 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$52) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$51 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$50) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $6) + (get_local $8) + ) + ) + (br_if $label$49 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (drop + (call $db_idx64_store + (get_local $5) + (get_local $7) + (get_local $8) + (i64.const 0) + (get_local $9) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1184) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$55 + (block $label$56 + (block $label$57 + (block $label$58 + (block $label$59 + (block $label$60 + (br_if $label$60 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$59 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$58) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$57 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$56) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$55 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$61 + (block $label$62 + (block $label$63 + (block $label$64 + (block $label$65 + (block $label$66 + (br_if $label$66 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$65 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$64) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$63 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$62) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $6) + (get_local $7) + ) + ) + (br_if $label$61 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$67 + (block $label$68 + (block $label$69 + (block $label$70 + (block $label$71 + (block $label$72 + (br_if $label$72 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$71 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$70) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$69 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$68) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $6) + (get_local $8) + ) + ) + (br_if $label$67 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (drop + (call $db_find_i64 + (get_local $5) + (get_local $7) + (get_local $8) + (i64.const 1) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1184) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 24) + ) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $9) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $9) + (i64.const 0) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $9) + (i32.const 48) + ) + (get_local $9) + ) + (call $send_inline + (tee_local $2 + (i32.load offset=48 + (get_local $9) + ) + ) + (i32.sub + (i32.load offset=52 + (get_local $9) + ) + (get_local $2) + ) + ) + (block $label$73 + (br_if $label$73 + (i32.eqz + (tee_local $2 + (i32.load offset=48 + (get_local $9) + ) + ) + ) + ) + (i32.store offset=52 + (get_local $9) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1216) + ) + (block $label$74 + (br_if $label$74 + (i32.eqz + (tee_local $2 + (i32.load + (i32.add + (get_local $9) + (i32.const 28) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 32) + ) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $2 + (i32.load + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 20) + ) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 944) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$75 + (block $label$76 + (block $label$77 + (block $label$78 + (block $label$79 + (block $label$80 + (br_if $label$80 + (i64.gt_u + (get_local $4) + (i64.const 3) + ) + ) + (br_if $label$79 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$78) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$77 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$76) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$75 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $require_auth + (get_local $5) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1264) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (drop + (call $current_time) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1312) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (drop + (call $current_time) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1312) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (drop + (call $publication_time) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1312) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (call $send_inline + (i32.const 1360) + (i32.const 6) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1376) + ) + (br_if $label$2 + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + (br $label$1) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$81 + (block $label$82 + (block $label$83 + (block $label$84 + (block $label$85 + (block $label$86 + (br_if $label$86 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$85 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$84) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$83 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$82) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$81 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $4 + (i64.const 0) + ) + (i64.store offset=8 + (get_local $9) + (i64.const 0) + ) + (i64.store + (get_local $9) + (get_local $5) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$87 + (block $label$88 + (block $label$89 + (block $label$90 + (block $label$91 + (block $label$92 + (br_if $label$92 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$91 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$90) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$89 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$88) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$87 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $send_deferred + (get_local $9) + (get_local $5) + (i32.const 1360) + (i32.const 6) + (i32.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1376) + ) + ) + (br_if $label$1 + (i32.eqz + (tee_local $2 + (i32.load offset=132 + (get_local $9) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 136) + ) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (block $label$93 + (br_if $label$93 + (i32.eqz + (tee_local $2 + (i32.load offset=120 + (get_local $9) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 124) + ) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 144) + ) + ) + (return) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $9) + (i32.const 80) + ) + ) + (unreachable) + ) + (func $_ZN5eosio6action7data_asI9cf_actionEET_v (param $0 i32) (param $1 i32) + (local $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (set_local $2 + (i64.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 1440) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $6) + (i64.const 8) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $7) + ) + (i32.const 768) + ) + (set_local $2 + (i64.load + (get_local $1) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 368) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $6) + (i64.const 6) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $7) + ) + (i32.const 784) + ) + (i64.store align=4 + (get_local $0) + (i64.const 100) + ) + (call $eosio_assert + (i32.gt_u + (tee_local $3 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + (tee_local $4 + (i32.load offset=28 + (get_local $1) + ) + ) + ) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $4) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.ne + (i32.and + (get_local $3) + (i32.const -4) + ) + (i32.const 4) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.add + (get_local $4) + (i32.const 4) + ) + (i32.const 4) + ) + ) + ) + (func $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=8 + (get_local $0) + (i32.const 0) + ) + (i64.store align=4 + (get_local $0) + (i64.const 0) + ) + (set_local $5 + (i32.const 16) + ) + (set_local $2 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + (set_local $6 + (i64.extend_u/i32 + (i32.shr_s + (tee_local $4 + (i32.sub + (tee_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + ) + (tee_local $3 + (i32.load offset=16 + (get_local $1) + ) + ) + ) + ) + (i32.const 4) + ) + ) + ) + (loop $label$0 + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $3) + (get_local $7) + ) + ) + (set_local $5 + (i32.add + (i32.and + (get_local $4) + (i32.const -16) + ) + (get_local $5) + ) + ) + ) + (set_local $5 + (i32.sub + (i32.sub + (tee_local $7 + (i32.load offset=28 + (get_local $1) + ) + ) + (get_local $5) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + (set_local $6 + (i64.extend_u/i32 + (i32.sub + (get_local $3) + (get_local $7) + ) + ) + ) + (loop $label$2 + (set_local $5 + (i32.add + (get_local $5) + (i32.const -1) + ) + ) + (br_if $label$2 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (set_local $7 + (i32.const 0) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.eqz + (get_local $5) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $0) + (i32.sub + (i32.const 0) + (get_local $5) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $5 + (i32.load + (get_local $0) + ) + ) + (br $label$3) + ) + (set_local $5 + (i32.const 0) + ) + ) + (i32.store + (get_local $8) + (get_local $5) + ) + (i32.store offset=8 + (get_local $8) + (get_local $7) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $7) + (get_local $5) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $1) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $7) + (tee_local $0 + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $0) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $8) + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE + (call $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE + (get_local $8) + (get_local $2) + ) + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $4 + (i64.extend_u/i32 + (i32.shr_s + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + (i32.const 4) + ) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$0 + (set_local $3 + (i32.wrap/i64 + (get_local $4) + ) + ) + (i32.store8 offset=15 + (get_local $7) + (i32.or + (i32.shl + (tee_local $6 + (i64.ne + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $3) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $5) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $6) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $6 + (i32.load + (get_local $1) + ) + ) + (tee_local $1 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$2 + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $5) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $3) + ) + (get_local $6) + (i32.const 8) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $5) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $3) + ) + (i32.add + (get_local $6) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 8) + ) + ) + ) + (br_if $label$2 + (i32.ne + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (get_local $1) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $7 + (i64.extend_u/i32 + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $2 + (i32.wrap/i64 + (get_local $7) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $3 + (i64.ne + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $2) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $5) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $5) + (tee_local $6 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $3) + ) + ) + (call $eosio_assert + (i32.ge_s + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $6) + ) + (tee_local $5 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (tee_local $2 + (i32.load + (get_local $1) + ) + ) + ) + ) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (get_local $2) + (get_local $5) + ) + ) + (i32.store + (get_local $6) + (i32.add + (i32.load + (get_local $6) + ) + (get_local $5) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN11test_action14require_noticeEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 368) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $6) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 1456) + ) + (set_local $9 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $6) + (i64.const 3) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $9 + (i64.or + (get_local $8) + (get_local $9) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (block $label$12 + (block $label$13 + (block $label$14 + (br_if $label$14 + (i64.ne + (get_local $7) + (get_local $0) + ) + ) + (call $require_recipient + (get_local $9) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 1472) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$15 + (block $label$16 + (block $label$17 + (block $label$18 + (block $label$19 + (block $label$20 + (br_if $label$20 + (i64.gt_u + (get_local $6) + (i64.const 3) + ) + ) + (br_if $label$19 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$18) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$17 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$16) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$15 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $require_recipient + (get_local $7) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 1456) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$21 + (block $label$22 + (block $label$23 + (block $label$24 + (block $label$25 + (block $label$26 + (br_if $label$26 + (i64.gt_u + (get_local $6) + (i64.const 3) + ) + ) + (br_if $label$25 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$24) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$23 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$22) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$21 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 1472) + ) + (set_local $9 + (i64.const 0) + ) + (loop $label$27 + (block $label$28 + (block $label$29 + (block $label$30 + (block $label$31 + (block $label$32 + (br_if $label$32 + (i64.gt_u + (get_local $6) + (i64.const 3) + ) + ) + (br_if $label$31 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$30) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$29 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$28) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $9 + (i64.or + (get_local $8) + (get_local $9) + ) + ) + (br_if $label$27 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $require_recipient + (get_local $7) + ) + (call $require_recipient + (get_local $9) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1488) + ) + (br $label$13) + ) + (br_if $label$12 + (i64.eq + (get_local $9) + (get_local $0) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 1472) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$33 + (block $label$34 + (block $label$35 + (block $label$36 + (block $label$37 + (block $label$38 + (br_if $label$38 + (i64.gt_u + (get_local $6) + (i64.const 3) + ) + ) + (br_if $label$37 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$36) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$35 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$34) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$33 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (br_if $label$12 + (i64.eq + (get_local $7) + (get_local $0) + ) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1488) + ) + ) + ) + (func $_ZN11test_action12require_authEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (call $prints + (i32.const 1520) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1536) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 3) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $require_auth + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1552) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $3) + (i64.const 3) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $require_auth + (get_local $4) + ) + ) + (func $_ZN11test_action12assert_falseEv + (call $eosio_assert + (i32.const 0) + (i32.const 1568) + ) + ) + (func $_ZN11test_action11assert_trueEv + (call $eosio_assert + (i32.const 1) + (i32.const 1600) + ) + ) + (func $_ZN11test_action14assert_true_cfEv + (call $eosio_assert + (i32.const 1) + (i32.const 1600) + ) + ) + (func $_ZN11test_action10test_abortEv + (call $abort) + (unreachable) + ) + (func $_ZN11test_action21test_publication_timeEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 1632) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $0) + ) + (call $publication_time) + ) + (i32.const 1664) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN11test_action21test_current_receiverEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $3) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $3) + ) + (get_local $0) + ) + (i32.const 1696) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + (func $_ZN11test_action17test_current_timeEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 1632) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $0) + ) + (call $current_time) + ) + (i32.const 1744) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN11test_action16test_assert_codeEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 1632) + ) + (call $eosio_assert_code + (i32.const 0) + (i64.load offset=8 + (get_local $0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN10test_print13test_prints_lEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store16 offset=14 + (get_local $0) + (i32.const 25185) + ) + (call $prints_l + (i32.add + (get_local $0) + (i32.const 14) + ) + (i32.const 2) + ) + (call $prints_l + (i32.add + (get_local $0) + (i32.const 14) + ) + (i32.const 1) + ) + (call $prints_l + (i32.add + (get_local $0) + (i32.const 14) + ) + (i32.const 0) + ) + (call $prints_l + (i32.const 944) + (i32.const 4) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN10test_print11test_printsEv + (call $prints + (i32.const 1776) + ) + (call $prints + (i32.const 0) + ) + (call $prints + (i32.const 1792) + ) + (call $prints + (i32.const 0) + ) + (call $prints + (i32.const 1808) + ) + (call $prints + (i32.const 0) + ) + ) + (func $_ZN10test_print11test_printiEv + (call $printi + (i64.const 0) + ) + (call $printi + (i64.const 556644) + ) + (call $printi + (i64.const -1) + ) + ) + (func $_ZN10test_print12test_printuiEv + (call $printui + (i64.const 0) + ) + (call $printui + (i64.const 556644) + ) + (call $printui + (i64.const -1) + ) + ) + (func $_ZN10test_print14test_printi128Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (i64.store offset=56 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=48 + (get_local $0) + (i64.const 1) + ) + (i64.store offset=40 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=32 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $0) + (i64.const -9223372036854775808) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -1) + ) + (i64.store + (get_local $0) + (i64.const -87654323456) + ) + (call $printi128 + (i32.add + (get_local $0) + (i32.const 48) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printi128 + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printi128 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printi128 + (get_local $0) + ) + (call $prints + (i32.const 1824) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + (func $_ZN10test_print15test_printui128Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i64.store offset=40 + (get_local $0) + (i64.const -1) + ) + (i64.store offset=32 + (get_local $0) + (i64.const -1) + ) + (i64.store offset=24 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 87654323456) + ) + (call $printui128 + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printui128 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printui128 + (get_local $0) + ) + (call $prints + (i32.const 1824) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 48) + ) + ) + ) + (func $_ZN10test_print11test_printnEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1840) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 4) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1856) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $3) + (i64.const 4) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1872) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (block $label$17 + (br_if $label$17 + (i64.gt_u + (get_local $3) + (i64.const 7) + ) + ) + (br_if $label$16 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$15) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$14 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$13) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$12 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (call $printn + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1888) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$18 + (block $label$19 + (block $label$20 + (block $label$21 + (block $label$22 + (block $label$23 + (br_if $label$23 + (i64.gt_u + (get_local $3) + (i64.const 5) + ) + ) + (br_if $label$22 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$21) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$20 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$19) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$18 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1904) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$24 + (block $label$25 + (block $label$26 + (block $label$27 + (block $label$28 + (block $label$29 + (br_if $label$29 + (i64.gt_u + (get_local $3) + (i64.const 10) + ) + ) + (br_if $label$28 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$27) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$26 + (i64.eq + (get_local $3) + (i64.const 11) + ) + ) + (br $label$25) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$24 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (i64.const 13) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $1 + (i32.const 1920) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$30 + (set_local $2 + (i64.const 0) + ) + (block $label$31 + (br_if $label$31 + (i64.gt_u + (get_local $3) + (i64.const 11) + ) + ) + (block $label$32 + (block $label$33 + (br_if $label$33 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$32) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $2 + (i64.shl + (i64.extend_u/i32 + (i32.and + (get_local $0) + (i32.const 31) + ) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $2) + (get_local $4) + ) + ) + (br_if $label$30 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1936) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$34 + (set_local $5 + (i64.const 0) + ) + (block $label$35 + (block $label$36 + (br_if $label$36 + (i64.gt_u + (get_local $3) + (i64.const 12) + ) + ) + (block $label$37 + (block $label$38 + (br_if $label$38 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$37) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$36 + (i64.gt_u + (get_local $3) + (i64.const 11) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + (br $label$35) + ) + (set_local $5 + (i64.and + (get_local $5) + (i64.const 15) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$34 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1952) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$39 + (set_local $5 + (i64.const 0) + ) + (block $label$40 + (block $label$41 + (br_if $label$41 + (i64.gt_u + (get_local $3) + (i64.const 13) + ) + ) + (block $label$42 + (block $label$43 + (br_if $label$43 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$42) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$41 + (i64.gt_u + (get_local $3) + (i64.const 11) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + (br $label$40) + ) + (set_local $5 + (i64.and + (get_local $5) + (i64.const 15) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$39 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 1968) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$44 + (set_local $5 + (i64.const 0) + ) + (block $label$45 + (block $label$46 + (br_if $label$46 + (i64.gt_u + (get_local $3) + (i64.const 14) + ) + ) + (block $label$47 + (block $label$48 + (br_if $label$48 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$47) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$46 + (i64.gt_u + (get_local $3) + (i64.const 11) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + (br $label$45) + ) + (set_local $5 + (i64.and + (get_local $5) + (i64.const 15) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$44 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $printn + (get_local $4) + ) + ) + (func $_ZN10test_print12test_printsfEv + (call $printsf + (f32.const 0.5) + ) + (call $prints + (i32.const 1824) + ) + (call $printsf + (f32.const -3.75) + ) + (call $prints + (i32.const 1824) + ) + (call $printsf + (f32.const 6.666666649834951e-07) + ) + (call $prints + (i32.const 1824) + ) + ) + (func $_ZN10test_print12test_printdfEv + (call $printdf + (f64.const 0.5) + ) + (call $prints + (i32.const 1824) + ) + (call $printdf + (f64.const -3.75) + ) + (call $prints + (i32.const 1824) + ) + (call $printdf + (f64.const 6.666666666666666e-07) + ) + (call $prints + (i32.const 1824) + ) + ) + (func $_ZN10test_print12test_printqfEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 48) + ) + ) + ) + (i64.store offset=40 + (get_local $0) + (i64.const 4611123068473966592) + ) + (i64.store offset=32 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $0) + (i64.const -4611439727822766080) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 4605605624503281953) + ) + (i64.store + (get_local $0) + (i64.const 1865728291273748996) + ) + (call $printqf + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printqf + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printqf + (get_local $0) + ) + (call $prints + (i32.const 1824) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 48) + ) + ) + ) + (func $_ZN10test_print17test_print_simpleEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i32.store + (i32.add + (get_local $3) + (i32.const 24) + ) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $3) + (i64.const 0) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $0 + (call $strlen + (i32.const 1984) + ) + ) + (i32.const -16) + ) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (get_local $0) + (i32.const 11) + ) + ) + (i32.store8 offset=16 + (get_local $3) + (i32.shl + (get_local $0) + (i32.const 1) + ) + ) + (set_local $2 + (tee_local $1 + (i32.or + (i32.add + (get_local $3) + (i32.const 16) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$3 + (get_local $0) + ) + (br $label$2) + ) + (set_local $2 + (call $_Znwj + (tee_local $1 + (i32.and + (i32.add + (get_local $0) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=16 + (get_local $3) + (i32.or + (get_local $1) + (i32.const 1) + ) + ) + (i32.store offset=24 + (get_local $3) + (get_local $2) + ) + (i32.store offset=20 + (get_local $3) + (get_local $0) + ) + (set_local $1 + (i32.or + (i32.add + (get_local $3) + (i32.const 16) + ) + (i32.const 1) + ) + ) + ) + (drop + (call $memcpy + (get_local $2) + (i32.const 1984) + (get_local $0) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $2) + (get_local $0) + ) + (i32.const 0) + ) + (call $prints_l + (select + (i32.load offset=24 + (get_local $3) + ) + (get_local $1) + (tee_local $2 + (i32.and + (tee_local $0 + (i32.load8_u offset=16 + (get_local $3) + ) + ) + (i32.const 1) + ) + ) + ) + (select + (i32.load offset=20 + (get_local $3) + ) + (i32.shr_u + (get_local $0) + (i32.const 1) + ) + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $3) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store + (get_local $3) + (i64.const 0) + ) + (br_if $label$0 + (i32.ge_u + (tee_local $0 + (call $strlen + (i32.const 2000) + ) + ) + (i32.const -16) + ) + ) + (block $label$5 + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.ge_u + (get_local $0) + (i32.const 11) + ) + ) + (i32.store8 + (get_local $3) + (i32.shl + (get_local $0) + (i32.const 1) + ) + ) + (set_local $2 + (tee_local $1 + (i32.or + (get_local $3) + (i32.const 1) + ) + ) + ) + (br_if $label$6 + (get_local $0) + ) + (br $label$5) + ) + (set_local $2 + (call $_Znwj + (tee_local $1 + (i32.and + (i32.add + (get_local $0) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (get_local $3) + (i32.or + (get_local $1) + (i32.const 1) + ) + ) + (i32.store offset=8 + (get_local $3) + (get_local $2) + ) + (i32.store offset=4 + (get_local $3) + (get_local $0) + ) + (set_local $1 + (i32.or + (get_local $3) + (i32.const 1) + ) + ) + ) + (drop + (call $memcpy + (get_local $2) + (i32.const 2000) + (get_local $0) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $2) + (get_local $0) + ) + (i32.const 0) + ) + (call $prints_l + (select + (i32.load offset=8 + (get_local $3) + ) + (get_local $1) + (tee_local $2 + (i32.and + (tee_local $0 + (i32.load8_u + (get_local $3) + ) + ) + (i32.const 1) + ) + ) + ) + (select + (i32.load offset=4 + (get_local $3) + ) + (i32.shr_u + (get_local $0) + (i32.const 1) + ) + (get_local $2) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.eqz + (i32.and + (i32.load8_u + (get_local $3) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (i32.and + (i32.load8_u offset=16 + (get_local $3) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $3) + (i32.const 24) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 32) + ) + ) + (return) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $3) + ) + (unreachable) + ) + (func $_ZN10test_types10types_sizeEv + (call $eosio_assert + (i32.const 1) + (i32.const 2016) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2048) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2080) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2112) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2144) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2176) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2208) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2240) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2272) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2304) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2320) + ) + ) + (func $_ZN10test_types14char_to_symbolEv + (call $eosio_assert + (i32.const 1) + (i32.const 2352) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2400) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2448) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2496) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2544) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2592) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2640) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2688) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2736) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2784) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2832) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2880) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2928) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 2976) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3024) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3072) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3120) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3168) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3216) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3264) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3312) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3360) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3408) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3456) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3504) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3552) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3600) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3648) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3696) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3744) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 3792) + ) + ) + (func $_ZN10test_types14string_to_nameEv + (local $0 i32) + (local $1 i64) + (local $2 i64) + (local $3 i64) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3840) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i64.eq + (get_local $1) + (i64.const 0) + ) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$1) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$4) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3840) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i64.eq + (get_local $1) + (i64.const 0) + ) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$7) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$10) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 3856) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3888) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (block $label$17 + (br_if $label$17 + (i64.gt_u + (get_local $1) + (i64.const 1) + ) + ) + (br_if $label$16 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$15) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$14 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$13) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$12 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3888) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$18 + (block $label$19 + (block $label$20 + (block $label$21 + (block $label$22 + (block $label$23 + (br_if $label$23 + (i64.gt_u + (get_local $1) + (i64.const 1) + ) + ) + (br_if $label$22 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$21) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$20 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$19) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$18 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 3904) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3936) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$24 + (block $label$25 + (block $label$26 + (block $label$27 + (block $label$28 + (block $label$29 + (br_if $label$29 + (i64.gt_u + (get_local $1) + (i64.const 2) + ) + ) + (br_if $label$28 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$27) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$26 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$25) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$24 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3936) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$30 + (block $label$31 + (block $label$32 + (block $label$33 + (block $label$34 + (block $label$35 + (br_if $label$35 + (i64.gt_u + (get_local $1) + (i64.const 2) + ) + ) + (br_if $label$34 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$33) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$32 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$31) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$30 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 3952) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3984) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$36 + (block $label$37 + (block $label$38 + (block $label$39 + (block $label$40 + (block $label$41 + (br_if $label$41 + (i64.gt_u + (get_local $1) + (i64.const 3) + ) + ) + (br_if $label$40 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$39) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$38 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$37) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$36 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 3984) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$42 + (block $label$43 + (block $label$44 + (block $label$45 + (block $label$46 + (block $label$47 + (br_if $label$47 + (i64.gt_u + (get_local $1) + (i64.const 3) + ) + ) + (br_if $label$46 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$45) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$44 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$43) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$42 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4000) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4032) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$48 + (block $label$49 + (block $label$50 + (block $label$51 + (block $label$52 + (block $label$53 + (br_if $label$53 + (i64.gt_u + (get_local $1) + (i64.const 4) + ) + ) + (br_if $label$52 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$51) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$50 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$49) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$48 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4032) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$54 + (block $label$55 + (block $label$56 + (block $label$57 + (block $label$58 + (block $label$59 + (br_if $label$59 + (i64.gt_u + (get_local $1) + (i64.const 4) + ) + ) + (br_if $label$58 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$57) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$56 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$55) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$54 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4048) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4080) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$60 + (block $label$61 + (block $label$62 + (block $label$63 + (block $label$64 + (block $label$65 + (br_if $label$65 + (i64.gt_u + (get_local $1) + (i64.const 5) + ) + ) + (br_if $label$64 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$63) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$62 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$61) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$60 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4080) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$66 + (block $label$67 + (block $label$68 + (block $label$69 + (block $label$70 + (block $label$71 + (br_if $label$71 + (i64.gt_u + (get_local $1) + (i64.const 5) + ) + ) + (br_if $label$70 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$69) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$68 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$67) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$66 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4096) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4128) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$72 + (block $label$73 + (block $label$74 + (block $label$75 + (block $label$76 + (block $label$77 + (br_if $label$77 + (i64.gt_u + (get_local $1) + (i64.const 6) + ) + ) + (br_if $label$76 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$75) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$74 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$73) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$72 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4128) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$78 + (block $label$79 + (block $label$80 + (block $label$81 + (block $label$82 + (block $label$83 + (br_if $label$83 + (i64.gt_u + (get_local $1) + (i64.const 6) + ) + ) + (br_if $label$82 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$81) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$80 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$79) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$78 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4144) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4176) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$84 + (block $label$85 + (block $label$86 + (block $label$87 + (block $label$88 + (block $label$89 + (br_if $label$89 + (i64.gt_u + (get_local $1) + (i64.const 7) + ) + ) + (br_if $label$88 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$87) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$86 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$85) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$84 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4176) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$90 + (block $label$91 + (block $label$92 + (block $label$93 + (block $label$94 + (block $label$95 + (br_if $label$95 + (i64.gt_u + (get_local $1) + (i64.const 7) + ) + ) + (br_if $label$94 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$93) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$92 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$91) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$90 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4192) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4224) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$96 + (block $label$97 + (block $label$98 + (block $label$99 + (block $label$100 + (block $label$101 + (br_if $label$101 + (i64.gt_u + (get_local $1) + (i64.const 8) + ) + ) + (br_if $label$100 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$99) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$98 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$97) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$96 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4224) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$102 + (block $label$103 + (block $label$104 + (block $label$105 + (block $label$106 + (block $label$107 + (br_if $label$107 + (i64.gt_u + (get_local $1) + (i64.const 8) + ) + ) + (br_if $label$106 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$105) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$104 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$103) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$102 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4240) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4288) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$108 + (block $label$109 + (block $label$110 + (block $label$111 + (block $label$112 + (block $label$113 + (br_if $label$113 + (i64.gt_u + (get_local $1) + (i64.const 9) + ) + ) + (br_if $label$112 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$111) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$110 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$109) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$108 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4288) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$114 + (block $label$115 + (block $label$116 + (block $label$117 + (block $label$118 + (block $label$119 + (br_if $label$119 + (i64.gt_u + (get_local $1) + (i64.const 9) + ) + ) + (br_if $label$118 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$117) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$116 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$115) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$114 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4304) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4352) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$120 + (block $label$121 + (block $label$122 + (block $label$123 + (block $label$124 + (block $label$125 + (br_if $label$125 + (i64.gt_u + (get_local $1) + (i64.const 10) + ) + ) + (br_if $label$124 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$123) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$122 + (i64.eq + (get_local $1) + (i64.const 11) + ) + ) + (br $label$121) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$120 + (i64.ne + (tee_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (i64.const 13) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4352) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$126 + (block $label$127 + (block $label$128 + (block $label$129 + (block $label$130 + (block $label$131 + (br_if $label$131 + (i64.gt_u + (get_local $1) + (i64.const 10) + ) + ) + (br_if $label$130 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$129) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$128 + (i64.eq + (get_local $1) + (i64.const 11) + ) + ) + (br $label$127) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$126 + (i64.ne + (tee_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (i64.const 13) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4368) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $4 + (i32.const 4416) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$132 + (set_local $5 + (i64.const 0) + ) + (block $label$133 + (br_if $label$133 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (block $label$134 + (block $label$135 + (br_if $label$135 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$134) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.extend_u/i32 + (i32.and + (get_local $0) + (i32.const 31) + ) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $5) + (get_local $2) + ) + ) + (br_if $label$132 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $4 + (i32.const 4416) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$136 + (set_local $5 + (i64.const 0) + ) + (block $label$137 + (br_if $label$137 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (block $label$138 + (block $label$139 + (br_if $label$139 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$138) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.extend_u/i32 + (i32.and + (get_local $0) + (i32.const 31) + ) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $5) + (get_local $3) + ) + ) + (br_if $label$136 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4432) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4480) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$140 + (set_local $6 + (i64.const 0) + ) + (block $label$141 + (block $label$142 + (br_if $label$142 + (i64.gt_u + (get_local $1) + (i64.const 12) + ) + ) + (block $label$143 + (block $label$144 + (br_if $label$144 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$143) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$142 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$141) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$140 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4480) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$145 + (set_local $6 + (i64.const 0) + ) + (block $label$146 + (block $label$147 + (br_if $label$147 + (i64.gt_u + (get_local $1) + (i64.const 12) + ) + ) + (block $label$148 + (block $label$149 + (br_if $label$149 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$148) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$147 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$146) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$145 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4496) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4544) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$150 + (set_local $6 + (i64.const 0) + ) + (block $label$151 + (block $label$152 + (br_if $label$152 + (i64.gt_u + (get_local $1) + (i64.const 13) + ) + ) + (block $label$153 + (block $label$154 + (br_if $label$154 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$153) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$152 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$151) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$150 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4560) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$155 + (set_local $6 + (i64.const 0) + ) + (block $label$156 + (block $label$157 + (br_if $label$157 + (i64.gt_u + (get_local $1) + (i64.const 13) + ) + ) + (block $label$158 + (block $label$159 + (br_if $label$159 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$158) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$157 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$156) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$155 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4576) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4624) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$160 + (set_local $6 + (i64.const 0) + ) + (block $label$161 + (block $label$162 + (br_if $label$162 + (i64.gt_u + (get_local $1) + (i64.const 14) + ) + ) + (block $label$163 + (block $label$164 + (br_if $label$164 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$163) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$162 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$161) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$160 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4640) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$165 + (set_local $6 + (i64.const 0) + ) + (block $label$166 + (block $label$167 + (br_if $label$167 + (i64.gt_u + (get_local $1) + (i64.const 14) + ) + ) + (block $label$168 + (block $label$169 + (br_if $label$169 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$168) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$167 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$166) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$165 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4656) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4704) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$170 + (block $label$171 + (block $label$172 + (block $label$173 + (block $label$174 + (block $label$175 + (br_if $label$175 + (i64.gt_u + (get_local $1) + (i64.const 5) + ) + ) + (br_if $label$174 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$173) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$172 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$171) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$170 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4720) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$176 + (block $label$177 + (block $label$178 + (block $label$179 + (block $label$180 + (block $label$181 + (br_if $label$181 + (i64.gt_u + (get_local $1) + (i64.const 5) + ) + ) + (br_if $label$180 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$179) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$178 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$177) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$176 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4736) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4768) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$182 + (block $label$183 + (block $label$184 + (block $label$185 + (block $label$186 + (block $label$187 + (br_if $label$187 + (i64.gt_u + (get_local $1) + (i64.const 9) + ) + ) + (br_if $label$186 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$185) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$184 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$183) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$182 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4768) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$188 + (block $label$189 + (block $label$190 + (block $label$191 + (block $label$192 + (block $label$193 + (br_if $label$193 + (i64.gt_u + (get_local $1) + (i64.const 9) + ) + ) + (br_if $label$192 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$191) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$190 + (i64.le_u + (get_local $1) + (i64.const 11) + ) + ) + (br $label$189) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$188 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4784) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4832) + ) + (set_local $2 + (i64.const 0) + ) + (loop $label$194 + (set_local $6 + (i64.const 0) + ) + (block $label$195 + (block $label$196 + (br_if $label$196 + (i64.gt_u + (get_local $1) + (i64.const 14) + ) + ) + (block $label$197 + (block $label$198 + (br_if $label$198 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$197) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$196 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$195) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $2 + (i64.or + (get_local $6) + (get_local $2) + ) + ) + (br_if $label$194 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $1 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 4848) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$199 + (set_local $6 + (i64.const 0) + ) + (block $label$200 + (block $label$201 + (br_if $label$201 + (i64.gt_u + (get_local $1) + (i64.const 22) + ) + ) + (block $label$202 + (block $label$203 + (br_if $label$203 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$202) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$201 + (i64.gt_u + (get_local $1) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + (br $label$200) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $1 + (i64.add + (get_local $1) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$199 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $2) + (get_local $3) + ) + (i32.const 4880) + ) + ) + (func $_ZN10test_types10name_classEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 4704) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 5) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $4) + (i64.const 4017212585601400832) + ) + (i32.const 4928) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 4960) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 4992) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $3) + (i64.const 3) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $4) + (i64.const 580542139465728) + ) + (i32.const 5008) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 5040) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (block $label$17 + (br_if $label$17 + (i64.gt_u + (get_local $3) + (i64.const 1) + ) + ) + (br_if $label$16 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$15) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$14 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$13) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$12 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $4) + (i64.const 594475150812905472) + ) + (i32.const 5056) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 5088) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$18 + (block $label$19 + (block $label$20 + (block $label$21 + (block $label$22 + (block $label$23 + (br_if $label$23 + (i64.gt_u + (get_local $3) + (i64.const 1) + ) + ) + (br_if $label$22 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$21) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$20 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$19) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$18 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $4) + (i64.const 1188950301625810944) + ) + (i32.const 5104) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 5136) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$24 + (block $label$25 + (block $label$26 + (block $label$27 + (block $label$28 + (block $label$29 + (br_if $label$29 + (i64.gt_u + (get_local $3) + (i64.const 9) + ) + ) + (br_if $label$28 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$27) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$26 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$25) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$24 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 5136) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$30 + (block $label$31 + (block $label$32 + (block $label$33 + (block $label$34 + (block $label$35 + (br_if $label$35 + (i64.gt_u + (get_local $3) + (i64.const 9) + ) + ) + (br_if $label$34 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$33) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$32 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$31) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $5) + (get_local $6) + ) + ) + (br_if $label$30 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $4) + (get_local $6) + ) + (i32.const 5152) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 5184) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$36 + (block $label$37 + (block $label$38 + (block $label$39 + (block $label$40 + (block $label$41 + (br_if $label$41 + (i64.gt_u + (get_local $3) + (i64.const 8) + ) + ) + (br_if $label$40 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$39) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$38 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$37) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$36 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 5184) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$42 + (block $label$43 + (block $label$44 + (block $label$45 + (block $label$46 + (block $label$47 + (br_if $label$47 + (i64.gt_u + (get_local $3) + (i64.const 8) + ) + ) + (br_if $label$46 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$45) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$44 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$43) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $5) + (get_local $6) + ) + ) + (br_if $label$42 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $6) + (get_local $4) + ) + (i32.const 5200) + ) + ) + (func $_ZN15test_fixedpoint16create_instancesEv + (call $eosio_assert + (i32.const 1) + (i32.const 5232) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5312) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5376) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5440) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5504) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5568) + ) + ) + (func $_ZN15test_fixedpoint13test_additionEv + (call $eosio_assert + (i32.const 1) + (i32.const 5632) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5696) + ) + ) + (func $_ZN15test_fixedpoint16test_subtractionEv + (call $eosio_assert + (i32.const 1) + (i32.const 5760) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5760) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5824) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5824) + ) + ) + (func $_ZN15test_fixedpoint19test_multiplicationEv + (call $eosio_assert + (i32.const 1) + (i32.const 5888) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5952) + ) + ) + (func $_ZN15test_fixedpoint13test_divisionEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6016) + ) + (i64.store offset=24 + (get_local $0) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $0) + (i64.const 30030) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 128977867898880) + ) + (call $printui128 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (call $prints + (i32.const 6032) + ) + (call $printui128 + (get_local $0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6048) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 6048) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN15test_fixedpoint18test_division_by_0Ev + (call $eosio_assert + (i32.const 0) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6160) + ) + ) + (func $_Zli5_ULLLPKc (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $1 + (i32.load8_u + (tee_local $6 + (i32.add + (get_local $1) + (select + (select + (i32.const 2) + (i32.const 1) + (tee_local $2 + (i32.eq + (i32.load8_u + (get_local $1) + ) + (i32.const 45) + ) + ) + ) + (get_local $2) + (i32.eq + (i32.load8_u + (i32.add + (get_local $1) + (get_local $2) + ) + ) + (i32.const 43) + ) + ) + ) + ) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (set_local $5 + (i32.add + (get_local $8) + (i32.const 8) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$2 + (call $__multi3 + (get_local $8) + (get_local $7) + (get_local $3) + (i64.const 10) + (i64.const 0) + ) + (set_local $3 + (i64.add + (i64.add + (i64.shr_s + (tee_local $3 + (i64.extend_s/i32 + (i32.add + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const -48) + ) + ) + ) + (i64.const 63) + ) + (i64.load + (get_local $5) + ) + ) + (select + (i64.const 1) + (i64.extend_u/i32 + (i64.lt_u + (tee_local $7 + (i64.add + (get_local $3) + (tee_local $4 + (i64.load + (get_local $8) + ) + ) + ) + ) + (get_local $3) + ) + ) + (i64.lt_u + (get_local $7) + (get_local $4) + ) + ) + ) + ) + (set_local $1 + (i32.load8_u + (get_local $6) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (get_local $1) + ) + (br $label$0) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $3 + (i64.const 0) + ) + ) + (i64.store + (get_local $0) + (select + (i64.sub + (i64.const 0) + (get_local $7) + ) + (get_local $7) + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (select + (i64.sub + (i64.sub + (i64.const 0) + (get_local $3) + ) + (i64.extend_u/i32 + (i64.ne + (get_local $7) + (i64.const 0) + ) + ) + ) + (get_local $3) + (get_local $2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + (func $_Zli4_LLLPKc (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $1 + (i32.load8_u + (tee_local $6 + (i32.add + (get_local $1) + (select + (select + (i32.const 2) + (i32.const 1) + (tee_local $2 + (i32.eq + (i32.load8_u + (get_local $1) + ) + (i32.const 45) + ) + ) + ) + (get_local $2) + (i32.eq + (i32.load8_u + (i32.add + (get_local $1) + (get_local $2) + ) + ) + (i32.const 43) + ) + ) + ) + ) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (set_local $5 + (i32.add + (get_local $8) + (i32.const 8) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$2 + (call $__multi3 + (get_local $8) + (get_local $7) + (get_local $3) + (i64.const 10) + (i64.const 0) + ) + (set_local $3 + (i64.add + (i64.add + (i64.shr_s + (tee_local $3 + (i64.extend_s/i32 + (i32.add + (i32.shr_s + (i32.shl + (get_local $1) + (i32.const 24) + ) + (i32.const 24) + ) + (i32.const -48) + ) + ) + ) + (i64.const 63) + ) + (i64.load + (get_local $5) + ) + ) + (select + (i64.const 1) + (i64.extend_u/i32 + (i64.lt_u + (tee_local $7 + (i64.add + (get_local $3) + (tee_local $4 + (i64.load + (get_local $8) + ) + ) + ) + ) + (get_local $3) + ) + ) + (i64.lt_u + (get_local $7) + (get_local $4) + ) + ) + ) + ) + (set_local $1 + (i32.load8_u + (get_local $6) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (get_local $1) + ) + (br $label$0) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $3 + (i64.const 0) + ) + ) + (i64.store + (get_local $0) + (select + (i64.sub + (i64.const 0) + (get_local $7) + ) + (get_local $7) + (get_local $2) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (select + (i64.sub + (i64.sub + (i64.const 0) + (get_local $3) + ) + (i64.extend_u/i32 + (i64.ne + (get_local $7) + (i64.const 0) + ) + ) + ) + (get_local $3) + (get_local $2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins11test_multi3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__multi3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -3000) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 6192) + ) + (call $__multi3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const -30) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -3000) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 6192) + ) + (call $__multi3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const -30) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 900) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6224) + ) + (call $__multi3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 10000) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6256) + ) + (call $__multi3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 100) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6288) + ) + (call $__multi3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i64.const -30) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -30) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 6320) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins11test_divti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__divti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6352) + ) + (call $__divti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const -30) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -3) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 6384) + ) + (call $__divti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const -30) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 1) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6416) + ) + (call $__divti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 1) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6416) + ) + (call $__divti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 3333) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6352) + ) + (call $__divti3 + (get_local $0) + (i64.const 3333) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 33) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6448) + ) + (call $__divti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 1) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 100) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6480) + ) + (call $__divti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const 1) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -30) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 6512) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins16test_divti3_by_0Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__divti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6544) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins12test_udivti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__udivti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 2951479051793528258) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const 184467440737095516) + ) + ) + ) + (i32.const 6576) + ) + (call $__udivti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const -30) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6576) + ) + (call $__udivti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const -30) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 1) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6608) + ) + (call $__udivti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 1) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6416) + ) + (call $__udivti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 3333) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6352) + ) + (call $__udivti3 + (get_local $0) + (i64.const 3333) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 33) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6448) + ) + (call $__udivti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 1) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 100) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6480) + ) + (call $__udivti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const 1) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -30) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 6512) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins17test_udivti3_by_0Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__udivti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6544) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins12test_lshlti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__lshlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 1) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6640) + ) + (call $__lshlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 2) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6672) + ) + (call $__lshlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 31) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 2147483648) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6704) + ) + (call $__lshlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 63) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6736) + ) + (call $__lshlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 64) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const 1) + ) + ) + ) + (i32.const 6768) + ) + (call $__lshlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 127) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + ) + ) + (i32.const 6800) + ) + (call $__lshlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 128) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6848) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins12test_ashlti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__ashlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 1) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6896) + ) + (call $__ashlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 2) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6928) + ) + (call $__ashlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 31) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 2147483648) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6960) + ) + (call $__ashlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 63) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 6992) + ) + (call $__ashlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 64) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const 1) + ) + ) + ) + (i32.const 7024) + ) + (call $__ashlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 127) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + ) + ) + (i32.const 7056) + ) + (call $__ashlti3 + (get_local $0) + (i64.const 1) + (i64.const 0) + (i32.const 128) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7104) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins12test_lshrti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__lshrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + ) + ) + (i32.const 7152) + ) + (call $__lshrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const 4611686018427387904) + ) + ) + ) + (i32.const 7200) + ) + (call $__lshrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 63) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const 1) + ) + ) + ) + (i32.const 7248) + ) + (call $__lshrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 64) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7280) + ) + (call $__lshrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 96) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 2147483648) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7312) + ) + (call $__lshrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 127) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 1) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7344) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins12test_ashrti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__ashrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + ) + ) + (i32.const 7376) + ) + (call $__ashrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -4611686018427387904) + ) + ) + ) + (i32.const 7424) + ) + (call $__ashrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 2) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -2305843009213693952) + ) + ) + ) + (i32.const 7472) + ) + (call $__ashrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 64) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -9223372036854775808) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 7520) + ) + (call $__ashrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 95) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -4294967296) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 7568) + ) + (call $__ashrti3 + (get_local $0) + (i64.const 0) + (i64.const -9223372036854775808) + (i32.const 127) + ) + (call $eosio_assert + (i64.eq + (i64.and + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + (i64.const -1) + ) + (i32.const 7616) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins11test_modti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__modti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -30) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 7648) + ) + (call $__modti3 + (get_local $0) + (i64.const 30) + (i64.const 0) + (i64.const -100) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 30) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7680) + ) + (call $__modti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const -100) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -30) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 7648) + ) + (call $__modti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 30) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 10) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7712) + ) + (call $__modti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const -100) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7744) + ) + (call $__modti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7744) + ) + (call $__modti3 + (get_local $0) + (i64.const 0) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7744) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins16test_modti3_by_0Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__modti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7776) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins12test_umodti3Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__umodti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -30) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 7648) + ) + (call $__umodti3 + (get_local $0) + (i64.const 30) + (i64.const 0) + (i64.const -100) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 30) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7680) + ) + (call $__umodti3 + (get_local $0) + (i64.const -30) + (i64.const -1) + (i64.const -100) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const -30) + ) + (i64.xor + (i64.load offset=8 + (get_local $0) + ) + (i64.const -1) + ) + ) + ) + (i32.const 7648) + ) + (call $__umodti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 30) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.xor + (i64.load + (get_local $0) + ) + (i64.const 10) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7712) + ) + (call $__umodti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const -100) + (i64.const -1) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7744) + ) + (call $__umodti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7744) + ) + (call $__umodti3 + (get_local $0) + (i64.const 0) + (i64.const 0) + (i64.const 100) + (i64.const 0) + ) + (call $eosio_assert + (i64.eqz + (i64.or + (i64.load + (get_local $0) + ) + (i64.load offset=8 + (get_local $0) + ) + ) + ) + (i32.const 7744) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN22test_compiler_builtins17test_umodti3_by_0Ev + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 0) + ) + (call $__umodti3 + (get_local $0) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7776) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $my_strlen (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (set_local $3 + (i32.const -1) + ) + (loop $label$0 + (set_local $2 + (i32.add + (get_local $0) + (get_local $3) + ) + ) + (set_local $3 + (tee_local $1 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (i32.load8_u + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + (get_local $1) + ) + (func $my_memcmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (get_local $2) + ) + ) + (set_local $3 + (i32.const 0) + ) + (loop $label$2 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (get_local $3) + ) + ) + (i32.load8_u + (i32.add + (get_local $1) + (get_local $3) + ) + ) + ) + ) + (br_if $label$2 + (i32.lt_u + (tee_local $3 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + (get_local $2) + ) + ) + ) + (return + (i32.const 1) + ) + ) + (return + (i32.const 1) + ) + ) + (i32.const 0) + ) + (func $_ZN11test_crypto28test_recover_key_assert_trueEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 144) + ) + ) + ) + (drop + (call $read_action_data + (get_local $0) + (i32.const 144) + ) + ) + (call $assert_recover_key + (get_local $0) + (i32.add + (get_local $0) + (i32.const 66) + ) + (i32.const 66) + (i32.add + (get_local $0) + (i32.const 32) + ) + (i32.const 34) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 144) + ) + ) + ) + (func $_ZN11test_crypto29test_recover_key_assert_falseEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 144) + ) + ) + ) + (drop + (call $read_action_data + (get_local $0) + (i32.const 144) + ) + ) + (call $assert_recover_key + (get_local $0) + (i32.add + (get_local $0) + (i32.const 66) + ) + (i32.const 66) + (i32.add + (get_local $0) + (i32.const 32) + ) + (i32.const 34) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7776) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 144) + ) + ) + ) + (func $_ZN11test_crypto16test_recover_keyEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 192) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $2) + (i32.const 48) + ) + (i32.const 144) + ) + ) + (drop + (call $recover_key + (i32.add + (get_local $2) + (i32.const 48) + ) + (i32.add + (i32.add + (get_local $2) + (i32.const 48) + ) + (i32.const 66) + ) + (i32.const 66) + (i32.add + (get_local $2) + (i32.const 8) + ) + (i32.const 34) + ) + ) + (set_local $0 + (i32.add + (get_local $2) + (i32.const 80) + ) + ) + (set_local $1 + (i32.const 0) + ) + (loop $label$0 + (block $label$1 + (br_if $label$1 + (i32.eq + (i32.load8_u + (i32.add + (i32.add + (get_local $2) + (i32.const 8) + ) + (get_local $1) + ) + ) + (i32.load8_u + (i32.add + (get_local $0) + (get_local $1) + ) + ) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7808) + ) + ) + (br_if $label$0 + (i32.ne + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 34) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 192) + ) + ) + ) + (func $_ZN11test_crypto9test_sha1Ev + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha1 + (i32.const 7840) + (i32.const 3) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 7856) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 7888) + ) + (call $sha1 + (i32.const 7904) + (i32.const 56) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$2 + (loop $label$3 + (br_if $label$2 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 7968) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$3 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8000) + ) + (call $sha1 + (i32.const 8016) + (i32.const 112) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$4 + (loop $label$5 + (br_if $label$4 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8144) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$5 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8176) + ) + (call $sha1 + (i32.const 8192) + (i32.const 14) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8208) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$7 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8240) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto11test_sha256Ev + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha256 + (i32.const 7840) + (i32.const 3) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8256) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8288) + ) + (call $sha256 + (i32.const 7904) + (i32.const 56) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$2 + (loop $label$3 + (br_if $label$2 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8304) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$3 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8336) + ) + (call $sha256 + (i32.const 8016) + (i32.const 112) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$4 + (loop $label$5 + (br_if $label$4 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8352) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$5 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8384) + ) + (call $sha256 + (i32.const 8192) + (i32.const 14) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8400) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$7 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8432) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto11test_sha512Ev + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $sha512 + (i32.const 7840) + (i32.const 3) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8448) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 63) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8512) + ) + (call $sha512 + (i32.const 7904) + (i32.const 56) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$2 + (loop $label$3 + (br_if $label$2 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8528) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$3 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 63) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8592) + ) + (call $sha512 + (i32.const 8016) + (i32.const 112) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$4 + (loop $label$5 + (br_if $label$4 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8608) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$5 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 63) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8672) + ) + (call $sha512 + (i32.const 8192) + (i32.const 14) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8688) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$7 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 63) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8752) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 64) + ) + ) + ) + (func $_ZN11test_crypto14test_ripemd160Ev + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $ripemd160 + (i32.const 7840) + (i32.const 3) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8768) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8800) + ) + (call $ripemd160 + (i32.const 7904) + (i32.const 56) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$2 + (loop $label$3 + (br_if $label$2 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8816) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$3 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8848) + ) + (call $ripemd160 + (i32.const 8016) + (i32.const 112) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$4 + (loop $label$5 + (br_if $label$4 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8864) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$5 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8896) + ) + (call $ripemd160 + (i32.const 8192) + (i32.const 14) + (get_local $2) + ) + (set_local $1 + (i32.const 0) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$6 + (loop $label$7 + (br_if $label$6 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8912) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$7 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 8944) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto11sha256_nullEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha256 + (i32.const 0) + (i32.const 100) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto12sha1_no_dataEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (set_local $1 + (i32.const 0) + ) + (call $sha1 + (i32.const 8960) + (i32.const 0) + (get_local $2) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 8976) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 9008) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto14sha256_no_dataEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (set_local $1 + (i32.const 0) + ) + (call $sha256 + (i32.const 8960) + (i32.const 0) + (get_local $2) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 9024) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 9056) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto14sha512_no_dataEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (set_local $1 + (i32.const 0) + ) + (call $sha512 + (i32.const 8960) + (i32.const 0) + (get_local $2) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 9072) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 63) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 9136) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 64) + ) + ) + ) + (func $_ZN11test_crypto17ripemd160_no_dataEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (set_local $1 + (i32.const 0) + ) + (call $ripemd160 + (i32.const 8960) + (i32.const 0) + (get_local $2) + ) + (set_local $0 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (br_if $label$0 + (i32.ne + (i32.load8_u + (i32.add + (get_local $0) + (i32.const 9152) + ) + ) + (i32.load8_u + (i32.add + (get_local $2) + (get_local $0) + ) + ) + ) + ) + (br_if $label$1 + (i32.le_u + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $1 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $1) + (i32.const 9184) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $2) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto19assert_sha256_falseEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha256 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (i32.store8 + (get_local $0) + (i32.xor + (i32.load8_u + (get_local $0) + ) + (i32.const -1) + ) + ) + (call $assert_sha256 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto18assert_sha256_trueEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha256 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $assert_sha256 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $sha256 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $assert_sha256 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $sha256 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $assert_sha256 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $sha256 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (call $assert_sha256 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto17assert_sha1_falseEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha1 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (i32.store8 + (get_local $0) + (i32.xor + (i32.load8_u + (get_local $0) + ) + (i32.const -1) + ) + ) + (call $assert_sha1 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto16assert_sha1_trueEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha1 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $assert_sha1 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $sha1 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $assert_sha1 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $sha1 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $assert_sha1 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $sha1 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (call $assert_sha1 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto19assert_sha512_falseEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $sha512 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (i32.store8 + (get_local $0) + (i32.xor + (i32.load8_u + (get_local $0) + ) + (i32.const -1) + ) + ) + (call $assert_sha512 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + (func $_ZN11test_crypto18assert_sha512_trueEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $sha512 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $assert_sha512 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $sha512 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $assert_sha512 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $sha512 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $assert_sha512 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $sha512 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (call $assert_sha512 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + (func $_ZN11test_crypto22assert_ripemd160_falseEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $ripemd160 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (i32.store8 + (get_local $0) + (i32.xor + (i32.load8_u + (get_local $0) + ) + (i32.const -1) + ) + ) + (call $assert_ripemd160 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN11test_crypto21assert_ripemd160_trueEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $ripemd160 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $assert_ripemd160 + (i32.const 7840) + (i32.const 3) + (get_local $0) + ) + (call $ripemd160 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $assert_ripemd160 + (i32.const 7904) + (i32.const 56) + (get_local $0) + ) + (call $ripemd160 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $assert_ripemd160 + (i32.const 8016) + (i32.const 112) + (get_local $0) + ) + (call $ripemd160 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (call $assert_ripemd160 + (i32.const 8192) + (i32.const 14) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN10test_chain16test_activeprodsEv + (local $0 i32) + (local $1 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $1 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 352) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $1) + (i32.const 176) + ) + (i32.const 169) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load8_u offset=176 + (get_local $1) + ) + (i32.const 21) + ) + (i32.const 9232) + ) + (set_local $0 + (i32.const 1) + ) + (drop + (call $get_active_producers + (i32.or + (get_local $1) + (i32.const 1) + ) + (i32.const 168) + ) + ) + (loop $label$0 + (call $eosio_assert + (i64.eq + (i64.load align=1 + (i32.add + (get_local $1) + (get_local $0) + ) + ) + (i64.load align=1 + (i32.add + (i32.add + (get_local $1) + (i32.const 176) + ) + (get_local $0) + ) + ) + ) + (i32.const 9264) + ) + (br_if $label$0 + (i32.ne + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (i32.const 169) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $1) + (i32.const 352) + ) + ) + ) + (func $_Z9copy_dataPcjRNSt3__16vectorIcNS0_9allocatorIcEEEE (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (set_local $4 + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + (loop $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (tee_local $3 + (i32.load + (get_local $5) + ) + ) + (i32.load + (get_local $4) + ) + ) + ) + (i32.store8 + (get_local $3) + (i32.load8_u + (get_local $0) + ) + ) + (i32.store + (get_local $5) + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + (br $label$2) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (get_local $2) + (get_local $0) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br_if $label$1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + ) + ) + ) + (func $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.le_s + (tee_local $7 + (i32.add + (tee_local $3 + (i32.sub + (tee_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (tee_local $4 + (i32.load + (get_local $0) + ) + ) + ) + ) + (i32.const 1) + ) + ) + (i32.const -1) + ) + ) + (set_local $6 + (i32.const 2147483647) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $2 + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $4) + ) + ) + (i32.const 1073741822) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $6 + (select + (get_local $7) + (tee_local $6 + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $6) + (get_local $7) + ) + ) + ) + ) + ) + ) + (set_local $7 + (call $_Znwj + (get_local $6) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $4 + (i32.load + (get_local $0) + ) + ) + (br $label$0) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $7 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (i32.store8 + (tee_local $3 + (i32.add + (get_local $7) + (get_local $3) + ) + ) + (i32.load8_u + (get_local $1) + ) + ) + (set_local $1 + (i32.sub + (get_local $3) + (tee_local $5 + (i32.sub + (get_local $5) + (get_local $4) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (get_local $6) + ) + ) + (set_local $7 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + (block $label$4 + (br_if $label$4 + (i32.lt_s + (get_local $5) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $1) + (get_local $4) + (get_local $5) + ) + ) + (set_local $4 + (i32.load + (get_local $0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $7) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $6) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (get_local $4) + ) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + ) + (func $_ZN16test_transaction11send_actionEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 96) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $7) + (i32.const 92) + ) + (i32.load8_u offset=9292 + (i32.const 0) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 88) + ) + (i32.load offset=9288 align=1 + (i32.const 0) + ) + ) + (i64.store offset=80 + (get_local $7) + (i64.load offset=9280 align=1 + (i32.const 0) + ) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 368) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 416) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $3) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $5) + (get_local $6) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 + (get_local $7) + (get_local $6) + ) + (i64.store offset=8 + (get_local $7) + (get_local $4) + ) + (i32.store + (i32.add + (tee_local $1 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.load offset=12 + (get_local $7) + ) + ) + (i32.store offset=24 + (get_local $7) + (get_local $1) + ) + (i32.store + (get_local $1) + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.store offset=32 + (get_local $7) + (tee_local $0 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=16 + (get_local $7) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (set_local $1 + (call $_ZN5eosio6actionC2I17test_dummy_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (i32.add + (get_local $7) + (i32.const 40) + ) + (i32.add + (get_local $7) + (i32.const 24) + ) + (i32.add + (get_local $7) + (i32.const 80) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $0 + (i32.load offset=24 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $7) + (i32.const 8) + ) + (get_local $1) + ) + (call $send_inline + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $7) + ) + (get_local $0) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $0 + (i32.load offset=28 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 32) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (tee_local $0 + (i32.load offset=16 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 20) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 96) + ) + ) + ) + (func $_ZN5eosio6actionC2I17test_dummy_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $5 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -3841127010667593728) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -8665432478272688454) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $4) + (i32.load offset=8 + (get_local $1) + ) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $5) + (i32.const 0) + ) + (i64.store + (get_local $5) + (i64.const 0) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $5) + (i32.const 13) + ) + (call $eosio_assert + (i32.gt_s + (tee_local $4 + (i32.sub + (i32.load offset=4 + (get_local $5) + ) + (tee_local $1 + (i32.load + (get_local $5) + ) + ) + ) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $1) + (get_local $2) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.add + (get_local $4) + (i32.const -1) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 1) + ) + (i32.add + (get_local $2) + (i32.const 1) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.add + (get_local $4) + (i32.const -9) + ) + (i32.const 3) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 9) + ) + (i32.add + (get_local $2) + (i32.const 9) + ) + (i32.const 4) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $1 + (i32.load offset=28 + (get_local $0) + ) + ) + ) + ) + (i32.store + (get_local $3) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 28) + ) + (i64.const 0) + ) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 28) + ) + (i64.load + (get_local $5) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction17send_action_emptyEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 96) + ) + ) + ) + (i32.store offset=88 + (get_local $7) + (i32.const 0) + ) + (set_local $3 + (i64.const 0) + ) + (i64.store offset=80 + (get_local $7) + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 368) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 416) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $3) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $5) + (get_local $6) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 + (get_local $7) + (get_local $6) + ) + (i64.store offset=8 + (get_local $7) + (get_local $4) + ) + (i32.store + (i32.add + (tee_local $1 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.load offset=12 + (get_local $7) + ) + ) + (i32.store offset=24 + (get_local $7) + (get_local $1) + ) + (i32.store + (get_local $1) + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.store offset=32 + (get_local $7) + (tee_local $0 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=16 + (get_local $7) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (set_local $1 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311596421349198EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (i32.add + (get_local $7) + (i32.const 40) + ) + (i32.add + (get_local $7) + (i32.const 24) + ) + (i32.add + (get_local $7) + (i32.const 80) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $0 + (i32.load offset=24 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $7) + (i32.const 8) + ) + (get_local $1) + ) + (call $send_inline + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $7) + ) + (get_local $0) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $0 + (i32.load offset=28 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 32) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (tee_local $0 + (i32.load offset=16 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 20) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (tee_local $1 + (i32.load offset=80 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $7) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 96) + ) + ) + ) + (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311596421349198EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -3841127010667593728) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -8665432477288202418) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $6) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $7) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $1 + (i32.load + (get_local $2) + ) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.sub + (get_local $4) + (get_local $1) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $3) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $2) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $1) + (get_local $4) + ) + ) + (loop $label$2 + (i32.store8 offset=15 + (get_local $7) + (i32.load8_u + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $5) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $6) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + ) + (i64.store align=4 + (get_local $6) + (i64.load + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction17send_action_largeEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 96) + ) + ) + ) + (set_local $2 + (i32.const 0) + ) + (i32.store offset=88 + (get_local $10) + (i32.const 0) + ) + (i64.store offset=80 + (get_local $10) + (i64.const 0) + ) + (set_local $1 + (i32.add + (get_local $10) + (i32.const 88) + ) + ) + (set_local $3 + (i32.const 0) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (set_local $0 + (i32.add + (get_local $4) + (i32.const 9296) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $3) + (get_local $2) + ) + ) + (i32.store8 + (get_local $3) + (i32.load8_u + (get_local $0) + ) + ) + (i32.store offset=84 + (get_local $10) + (i32.add + (i32.load offset=84 + (get_local $10) + ) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (i32.const 8191) + ) + ) + (br $label$0) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $10) + (i32.const 80) + ) + (get_local $0) + ) + (br_if $label$0 + (i32.eq + (get_local $4) + (i32.const 8191) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $2 + (i32.load + (get_local $1) + ) + ) + (set_local $3 + (i32.load offset=84 + (get_local $10) + ) + ) + (br $label$1) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 368) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i64.gt_u + (get_local $6) + (i64.const 6) + ) + ) + (br_if $label$8 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$7) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$6 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$5) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$4 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 416) + ) + (set_local $9 + (i64.const 0) + ) + (loop $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (br_if $label$15 + (i64.gt_u + (get_local $6) + (i64.const 5) + ) + ) + (br_if $label$14 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$13) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$12 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$11) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $9 + (i64.or + (get_local $8) + (get_local $9) + ) + ) + (br_if $label$10 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 + (get_local $10) + (get_local $9) + ) + (i64.store offset=8 + (get_local $10) + (get_local $7) + ) + (i32.store + (i32.add + (tee_local $4 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $10) + (i32.const 8) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 4) + ) + (i32.load offset=12 + (get_local $10) + ) + ) + (i32.store offset=24 + (get_local $10) + (get_local $4) + ) + (i32.store + (get_local $4) + (i32.load offset=8 + (get_local $10) + ) + ) + (i32.store offset=32 + (get_local $10) + (tee_local $3 + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 8) + ) + (i32.load offset=16 + (get_local $10) + ) + ) + (i32.store offset=28 + (get_local $10) + (get_local $3) + ) + (set_local $4 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (i32.add + (get_local $10) + (i32.const 40) + ) + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.add + (get_local $10) + (i32.const 80) + ) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (tee_local $3 + (i32.load offset=24 + (get_local $10) + ) + ) + ) + ) + (i32.store offset=28 + (get_local $10) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $10) + (i32.const 8) + ) + (get_local $4) + ) + (call $send_inline + (tee_local $3 + (i32.load offset=8 + (get_local $10) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $10) + ) + (get_local $3) + ) + ) + (block $label$17 + (br_if $label$17 + (i32.eqz + (tee_local $3 + (i32.load offset=8 + (get_local $10) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $10) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 17488) + ) + (block $label$18 + (br_if $label$18 + (i32.eqz + (tee_local $3 + (i32.load offset=28 + (get_local $4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 32) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (block $label$19 + (br_if $label$19 + (i32.eqz + (tee_local $3 + (i32.load offset=16 + (get_local $4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 20) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (block $label$20 + (br_if $label$20 + (i32.eqz + (tee_local $4 + (i32.load offset=80 + (get_local $10) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $10) + (get_local $4) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 96) + ) + ) + ) + (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -3841127010667593728) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -8665432478272688454) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $6) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $7) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $1 + (i32.load + (get_local $2) + ) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.sub + (get_local $4) + (get_local $1) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $3) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $2) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $1) + (get_local $4) + ) + ) + (loop $label$2 + (i32.store8 offset=15 + (get_local $7) + (i32.load8_u + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $5) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $6) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + ) + (i64.store align=4 + (get_local $6) + (i64.load + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction19send_action_recurseEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 1120) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 96) + ) + (i32.const 1024) + ) + ) + (set_local $2 + (i32.const 0) + ) + (i32.store offset=88 + (get_local $10) + (i32.const 0) + ) + (i64.store offset=80 + (get_local $10) + (i64.const 0) + ) + (set_local $1 + (i32.add + (get_local $10) + (i32.const 88) + ) + ) + (set_local $3 + (i32.const 0) + ) + (set_local $4 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (set_local $0 + (i32.add + (i32.add + (get_local $10) + (i32.const 96) + ) + (get_local $4) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $3) + (get_local $2) + ) + ) + (i32.store8 + (get_local $3) + (i32.load8_u + (get_local $0) + ) + ) + (i32.store offset=84 + (get_local $10) + (i32.add + (i32.load offset=84 + (get_local $10) + ) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (i32.const 1023) + ) + ) + (br $label$0) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $10) + (i32.const 80) + ) + (get_local $0) + ) + (br_if $label$0 + (i32.eq + (get_local $4) + (i32.const 1023) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $2 + (i32.load + (get_local $1) + ) + ) + (set_local $3 + (i32.load offset=84 + (get_local $10) + ) + ) + (br $label$1) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 368) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i64.gt_u + (get_local $6) + (i64.const 6) + ) + ) + (br_if $label$8 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$7) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$6 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$5) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $8) + (get_local $7) + ) + ) + (br_if $label$4 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $5 + (i64.const 59) + ) + (set_local $4 + (i32.const 416) + ) + (set_local $9 + (i64.const 0) + ) + (loop $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (br_if $label$15 + (i64.gt_u + (get_local $6) + (i64.const 5) + ) + ) + (br_if $label$14 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $4) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$13) + ) + (set_local $8 + (i64.const 0) + ) + (br_if $label$12 + (i64.le_u + (get_local $6) + (i64.const 11) + ) + ) + (br $label$11) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $8 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $8 + (i64.shl + (i64.and + (get_local $8) + (i64.const 31) + ) + (i64.and + (get_local $5) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (set_local $6 + (i64.add + (get_local $6) + (i64.const 1) + ) + ) + (set_local $9 + (i64.or + (get_local $8) + (get_local $9) + ) + ) + (br_if $label$10 + (i64.ne + (tee_local $5 + (i64.add + (get_local $5) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 + (get_local $10) + (get_local $9) + ) + (i64.store offset=8 + (get_local $10) + (get_local $7) + ) + (i32.store + (i32.add + (tee_local $4 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $10) + (i32.const 8) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 4) + ) + (i32.load offset=12 + (get_local $10) + ) + ) + (i32.store offset=24 + (get_local $10) + (get_local $4) + ) + (i32.store + (get_local $4) + (i32.load offset=8 + (get_local $10) + ) + ) + (i32.store offset=32 + (get_local $10) + (tee_local $3 + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 8) + ) + (i32.load offset=16 + (get_local $10) + ) + ) + (i32.store offset=28 + (get_local $10) + (get_local $3) + ) + (set_local $4 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730571693710178EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (i32.add + (get_local $10) + (i32.const 40) + ) + (i32.add + (get_local $10) + (i32.const 24) + ) + (i32.add + (get_local $10) + (i32.const 80) + ) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (tee_local $3 + (i32.load offset=24 + (get_local $10) + ) + ) + ) + ) + (i32.store offset=28 + (get_local $10) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $10) + (i32.const 8) + ) + (get_local $4) + ) + (call $send_inline + (tee_local $3 + (i32.load offset=8 + (get_local $10) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $10) + ) + (get_local $3) + ) + ) + (block $label$17 + (br_if $label$17 + (i32.eqz + (tee_local $3 + (i32.load offset=8 + (get_local $10) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $10) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (block $label$18 + (br_if $label$18 + (i32.eqz + (tee_local $3 + (i32.load offset=28 + (get_local $4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 32) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (block $label$19 + (br_if $label$19 + (i32.eqz + (tee_local $3 + (i32.load offset=16 + (get_local $4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 20) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (block $label$20 + (br_if $label$20 + (i32.eqz + (tee_local $4 + (i32.load offset=80 + (get_local $10) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $10) + (get_local $4) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 1120) + ) + ) + ) + (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730571693710178EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -3841127010667593728) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -696013502015841438) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $6) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $7) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $1 + (i32.load + (get_local $2) + ) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.sub + (get_local $4) + (get_local $1) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $3) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $2) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $1) + (get_local $4) + ) + ) + (loop $label$2 + (i32.store8 offset=15 + (get_local $7) + (i32.load8_u + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $5) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $6) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + ) + (i64.store align=4 + (get_local $6) + (i64.load + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction23send_action_inline_failEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 96) + ) + ) + ) + (i32.store offset=88 + (get_local $7) + (i32.const 0) + ) + (set_local $3 + (i64.const 0) + ) + (i64.store offset=80 + (get_local $7) + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 368) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 416) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $3) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $5) + (get_local $6) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 + (get_local $7) + (get_local $6) + ) + (i64.store offset=8 + (get_local $7) + (get_local $4) + ) + (i32.store + (i32.add + (tee_local $1 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.load offset=12 + (get_local $7) + ) + ) + (i32.store offset=24 + (get_local $7) + (get_local $1) + ) + (i32.store + (get_local $1) + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.store offset=32 + (get_local $7) + (tee_local $0 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=16 + (get_local $7) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (set_local $1 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (i32.add + (get_local $7) + (i32.const 40) + ) + (i32.add + (get_local $7) + (i32.const 24) + ) + (i32.add + (get_local $7) + (i32.const 80) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $0 + (i32.load offset=24 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $7) + (i32.const 8) + ) + (get_local $1) + ) + (call $send_inline + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $7) + ) + (get_local $0) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $0 + (i32.load offset=28 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 32) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (tee_local $0 + (i32.load offset=16 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 20) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (tee_local $1 + (i32.load offset=80 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $7) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 96) + ) + ) + ) + (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -3841127010667593728) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -8665432478290165179) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $6) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $7) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $1 + (i32.load + (get_local $2) + ) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.sub + (get_local $4) + (get_local $1) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $3) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $2) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $1) + (get_local $4) + ) + ) + (loop $label$2 + (i32.store8 offset=15 + (get_local $7) + (i32.load8_u + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $5) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $6) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + ) + (i64.store align=4 + (get_local $6) + (i64.load + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction23test_tapos_block_prefixEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $0) + (i32.const 12) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=12 + (get_local $0) + ) + (call $tapos_block_prefix) + ) + (i32.const 17536) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN16test_transaction20test_tapos_block_numEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $0) + (i32.const 12) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=12 + (get_local $0) + ) + (call $tapos_block_num) + ) + (i32.const 17584) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN16test_transaction21test_read_transactionEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $1 + (i32.sub + (get_local $3) + (i32.and + (i32.add + (tee_local $0 + (call $transaction_size) + ) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + (call $eosio_assert + (i32.eq + (get_local $0) + (tee_local $2 + (call $read_transaction + (get_local $1) + (get_local $0) + ) + ) + ) + (i32.const 17616) + ) + (call $sha256 + (get_local $1) + (get_local $2) + (tee_local $0 + (get_local $3) + ) + ) + (call $printhex + (get_local $0) + (i32.const 32) + ) + (drop + (get_local $3) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN16test_transaction21test_transaction_sizeEv + (local $0 i32) + (local $1 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $1 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=12 + (get_local $1) + (i32.const 0) + ) + (drop + (call $read_action_data + (i32.add + (get_local $1) + (i32.const 12) + ) + (i32.const 4) + ) + ) + (set_local $0 + (call $transaction_size) + ) + (call $prints + (i32.const 17648) + ) + (call $printui + (i64.extend_u/i32 + (get_local $0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=12 + (get_local $1) + ) + (call $transaction_size) + ) + (i32.const 17664) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (func $_ZN16test_transaction16send_transactionEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i64) + (local $12 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $12 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 128) + ) + ) + ) + (set_local $4 + (i32.const 0) + ) + (i32.store8 + (i32.add + (i32.add + (get_local $12) + (i32.const 96) + ) + (i32.const 12) + ) + (i32.load8_u offset=17708 + (i32.const 0) + ) + ) + (i32.store + (i32.add + (i32.add + (get_local $12) + (i32.const 96) + ) + (i32.const 8) + ) + (i32.load offset=17704 align=1 + (i32.const 0) + ) + ) + (i64.store offset=96 align=4 + (get_local $12) + (i64.load offset=17696 align=1 + (i32.const 0) + ) + ) + (i32.store offset=88 + (get_local $12) + (i32.const 0) + ) + (i64.store offset=80 + (get_local $12) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (set_local $6 + (i32.const 0) + ) + (block $label$0 + (loop $label$1 + (set_local $3 + (i32.add + (i32.add + (get_local $12) + (i32.const 96) + ) + (get_local $6) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $5) + (get_local $4) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u + (get_local $3) + ) + ) + (i32.store offset=84 + (get_local $12) + (i32.add + (i32.load offset=84 + (get_local $12) + ) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $6) + (i32.const 12) + ) + ) + (br $label$0) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $12) + (i32.const 80) + ) + (get_local $3) + ) + (br_if $label$0 + (i32.eq + (get_local $6) + (i32.const 12) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (set_local $4 + (i32.load + (i32.add + (i32.add + (get_local $12) + (i32.const 80) + ) + (i32.const 8) + ) + ) + ) + (set_local $5 + (i32.load offset=84 + (get_local $12) + ) + ) + (br $label$1) + ) + ) + (set_local $8 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 44) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 48) + ) + (i32.const 0) + ) + (i32.store offset=28 + (get_local $12) + (i32.const 0) + ) + (i32.store8 offset=32 + (get_local $12) + (i32.const 0) + ) + (i32.store offset=36 + (get_local $12) + (i32.const 0) + ) + (i32.store offset=40 + (get_local $12) + (i32.const 0) + ) + (i32.store offset=16 + (get_local $12) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $8) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=52 + (get_local $12) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 56) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 60) + ) + (i32.const 0) + ) + (i32.store offset=64 + (get_local $12) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 68) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 72) + ) + (i32.const 0) + ) + (set_local $4 + (i32.add + (get_local $12) + (i32.const 52) + ) + ) + (set_local $8 + (i64.const 0) + ) + (set_local $7 + (i64.const 59) + ) + (set_local $6 + (i32.const 368) + ) + (set_local $9 + (i64.const 0) + ) + (loop $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i64.gt_u + (get_local $8) + (i64.const 6) + ) + ) + (br_if $label$8 + (i32.gt_u + (i32.and + (i32.add + (tee_local $5 + (i32.load8_s + (get_local $6) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 165) + ) + ) + (br $label$7) + ) + (set_local $10 + (i64.const 0) + ) + (br_if $label$6 + (i64.le_u + (get_local $8) + (i64.const 11) + ) + ) + (br $label$5) + ) + (set_local $5 + (select + (i32.add + (get_local $5) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $5) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $10 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $5) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $10 + (i64.shl + (i64.and + (get_local $10) + (i64.const 31) + ) + (i64.and + (get_local $7) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (set_local $8 + (i64.add + (get_local $8) + (i64.const 1) + ) + ) + (set_local $9 + (i64.or + (get_local $10) + (get_local $9) + ) + ) + (br_if $label$4 + (i64.ne + (tee_local $7 + (i64.add + (get_local $7) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $8 + (i64.const 0) + ) + (set_local $7 + (i64.const 59) + ) + (set_local $6 + (i32.const 416) + ) + (set_local $11 + (i64.const 0) + ) + (loop $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (br_if $label$15 + (i64.gt_u + (get_local $8) + (i64.const 5) + ) + ) + (br_if $label$14 + (i32.gt_u + (i32.and + (i32.add + (tee_local $5 + (i32.load8_s + (get_local $6) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 165) + ) + ) + (br $label$13) + ) + (set_local $10 + (i64.const 0) + ) + (br_if $label$12 + (i64.le_u + (get_local $8) + (i64.const 11) + ) + ) + (br $label$11) + ) + (set_local $5 + (select + (i32.add + (get_local $5) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $5) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $10 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $5) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $10 + (i64.shl + (i64.and + (get_local $10) + (i64.const 31) + ) + (i64.and + (get_local $7) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (set_local $8 + (i64.add + (get_local $8) + (i64.const 1) + ) + ) + (set_local $11 + (i64.or + (get_local $10) + (get_local $11) + ) + ) + (br_if $label$10 + (i64.ne + (tee_local $7 + (i64.add + (get_local $7) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=8 + (get_local $12) + (get_local $11) + ) + (i64.store + (get_local $12) + (get_local $9) + ) + (i32.store + (i32.add + (tee_local $6 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $12) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $6) + (i32.const 4) + ) + (i32.load offset=4 + (get_local $12) + ) + ) + (i32.store offset=112 + (get_local $12) + (get_local $6) + ) + (i32.store + (get_local $6) + (i32.load + (get_local $12) + ) + ) + (i32.store offset=120 + (get_local $12) + (tee_local $5 + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $6) + (i32.const 8) + ) + (i32.load offset=8 + (get_local $12) + ) + ) + (i32.store offset=116 + (get_local $12) + (get_local $5) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEEvDpOT_ + (get_local $4) + (i32.add + (get_local $12) + (i32.const 112) + ) + (i32.add + (get_local $12) + (i32.const 80) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (tee_local $6 + (i32.load offset=112 + (get_local $12) + ) + ) + ) + ) + (i32.store offset=116 + (get_local $12) + (get_local $6) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + (i64.store offset=8 + (get_local $12) + (i64.const 0) + ) + (i64.store + (get_local $12) + (i64.const 0) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $12) + (i32.const 112) + ) + (i32.add + (get_local $12) + (i32.const 16) + ) + ) + (call $send_deferred + (get_local $12) + (get_local $0) + (tee_local $6 + (i32.load offset=112 + (get_local $12) + ) + ) + (i32.sub + (i32.load offset=116 + (get_local $12) + ) + (get_local $6) + ) + (i32.const 0) + ) + (block $label$17 + (br_if $label$17 + (i32.eqz + (tee_local $6 + (i32.load offset=112 + (get_local $12) + ) + ) + ) + ) + (i32.store offset=116 + (get_local $12) + (get_local $6) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $12) + (i32.const 16) + ) + ) + ) + (block $label$18 + (br_if $label$18 + (i32.eqz + (tee_local $6 + (i32.load offset=80 + (get_local $12) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $12) + (get_local $6) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $12) + (i32.const 128) + ) + ) + ) + (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $6 + (i32.add + (tee_local $9 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $8 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 40) + ) + ) + (i32.const 1) + ) + ) + (i32.const 107374183) + ) + ) + (set_local $7 + (i32.const 107374182) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $8 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $8) + ) + (i32.const 40) + ) + ) + (i32.const 53687090) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $6) + (tee_local $7 + (i32.shl + (get_local $8) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $6) + ) + ) + ) + ) + ) + ) + (set_local $8 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $3 + (i32.add + (get_local $8) + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (set_local $4 + (i32.add + (tee_local $8 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (tee_local $9 + (i32.add + (get_local $8) + (i32.mul + (get_local $9) + (i32.const 40) + ) + ) + ) + (get_local $1) + (get_local $2) + ) + ) + (i32.const 40) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (set_local $5 + (i32.sub + (i32.const 0) + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const -20) + ) + ) + (loop $label$6 + (i64.store + (i32.add + (get_local $8) + (i32.const -32) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -12) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -20) + ) + ) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -16) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -20) + ) + (i32.load + (get_local $7) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $1 + (i32.add + (get_local $7) + (i32.const 4) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -12) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $8 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (set_local $8 + (tee_local $9 + (i32.add + (get_local $9) + (i32.const -40) + ) + ) + ) + (br_if $label$6 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $5) + ) + (i32.const -20) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $1 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $9) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $4) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $3) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $1) + ) + ) + (set_local $9 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$8 + (block $label$9 + (br_if $label$9 + (i32.eqz + (tee_local $8 + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $8 + (i32.load + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 4) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$8 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $9) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + ) + (func $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $4 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $3 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $0) + (i32.const 0) + ) + (i64.store align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIjEEEERT_S4_RKNS_11transactionE + (get_local $4) + (get_local $1) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $2 + (i32.load + (get_local $4) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $0) + (get_local $2) + ) + (set_local $3 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $0 + (i32.load + (get_local $0) + ) + ) + (br $label$0) + ) + (set_local $0 + (i32.const 0) + ) + ) + (i32.store offset=4 + (get_local $4) + (get_local $0) + ) + (i32.store + (get_local $4) + (get_local $0) + ) + (i32.store offset=8 + (get_local $4) + (get_local $3) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_18transaction_headerE + (get_local $4) + (get_local $1) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEENSt3__15tupleIJtNS4_6vectorIcNS4_9allocatorIcEEEEEEEEERT_SC_RKNS6_IT0_NS7_ISD_EEEE + (call $_ZN5eosiolsINS_10datastreamIPcEENS_6actionEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE + (call $_ZN5eosiolsINS_10datastreamIPcEENS_6actionEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE + (get_local $4) + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + (i32.add + (get_local $1) + (i32.const 36) + ) + ) + (i32.add + (get_local $1) + (i32.const 48) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosio11transactionD2Ev (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $1 + (i32.load offset=48 + (get_local $0) + ) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.eq + (tee_local $5 + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 52) + ) + ) + ) + ) + (get_local $1) + ) + ) + (set_local $2 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const -12) + ) + ) + (loop $label$3 + (block $label$4 + (br_if $label$4 + (i32.eqz + (tee_local $3 + (i32.load + (get_local $5) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 4) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (br_if $label$3 + (i32.ne + (i32.add + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -16) + ) + ) + (get_local $2) + ) + (i32.const -12) + ) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $0) + (i32.const 48) + ) + ) + ) + (br $label$1) + ) + (set_local $5 + (get_local $1) + ) + ) + (i32.store + (get_local $4) + (get_local $1) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (tee_local $1 + (i32.load offset=36 + (get_local $0) + ) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.eq + (tee_local $5 + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 40) + ) + ) + ) + ) + (get_local $1) + ) + ) + (set_local $2 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const -24) + ) + ) + (loop $label$8 + (block $label$9 + (br_if $label$9 + (i32.eqz + (tee_local $3 + (i32.load + (i32.add + (get_local $5) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 16) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $3 + (i32.load + (get_local $5) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 4) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (br_if $label$8 + (i32.ne + (i32.add + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -40) + ) + ) + (get_local $2) + ) + (i32.const -24) + ) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $0) + (i32.const 36) + ) + ) + ) + (br $label$6) + ) + (set_local $5 + (get_local $1) + ) + ) + (i32.store + (get_local $4) + (get_local $1) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (tee_local $1 + (i32.load offset=24 + (get_local $0) + ) + ) + ) + ) + (block $label$12 + (block $label$13 + (br_if $label$13 + (i32.eq + (tee_local $5 + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + (get_local $1) + ) + ) + (set_local $2 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const -24) + ) + ) + (loop $label$14 + (block $label$15 + (br_if $label$15 + (i32.eqz + (tee_local $3 + (i32.load + (i32.add + (get_local $5) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 16) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (tee_local $3 + (i32.load + (get_local $5) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 4) + ) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (br_if $label$14 + (i32.ne + (i32.add + (tee_local $5 + (i32.add + (get_local $5) + (i32.const -40) + ) + ) + (get_local $2) + ) + (i32.const -24) + ) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + ) + (br $label$12) + ) + (set_local $5 + (get_local $1) + ) + ) + (i32.store + (get_local $4) + (get_local $1) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIjEEEERT_S4_RKNS_11transactionE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i64) + (i32.store + (get_local $0) + (i32.add + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + (i32.const 10) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 11) + ) + ) + (set_local $8 + (i64.load32_u offset=12 + (get_local $1) + ) + ) + (loop $label$0 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + (set_local $8 + (i64.load32_u offset=20 + (get_local $1) + ) + ) + (loop $label$1 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$1 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.div_s + (i32.sub + (tee_local $2 + (i32.load + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + ) + (tee_local $7 + (i32.load offset=24 + (get_local $1) + ) + ) + ) + (i32.const 40) + ) + ) + ) + (loop $label$2 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + (loop $label$4 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.shr_s + (tee_local $5 + (i32.sub + (tee_local $3 + (i32.load + (i32.add + (get_local $7) + (i32.const 20) + ) + ) + ) + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + ) + (i32.const 4) + ) + ) + ) + (loop $label$5 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$5 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.eq + (get_local $4) + (get_local $3) + ) + ) + (set_local $6 + (i32.add + (i32.and + (get_local $5) + (i32.const -16) + ) + (get_local $6) + ) + ) + ) + (set_local $6 + (i32.sub + (i32.add + (get_local $6) + (tee_local $3 + (i32.load + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + ) + ) + (tee_local $4 + (i32.load offset=28 + (get_local $7) + ) + ) + ) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.sub + (get_local $3) + (get_local $4) + ) + ) + ) + (loop $label$7 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$7 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (br_if $label$4 + (i32.ne + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + (get_local $2) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.div_s + (i32.sub + (tee_local $2 + (i32.load + (i32.add + (get_local $1) + (i32.const 40) + ) + ) + ) + (tee_local $7 + (i32.load offset=36 + (get_local $1) + ) + ) + ) + (i32.const 40) + ) + ) + ) + (loop $label$8 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$8 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + (block $label$9 + (br_if $label$9 + (i32.eq + (get_local $7) + (get_local $2) + ) + ) + (loop $label$10 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.shr_s + (tee_local $5 + (i32.sub + (tee_local $3 + (i32.load + (i32.add + (get_local $7) + (i32.const 20) + ) + ) + ) + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + ) + (i32.const 4) + ) + ) + ) + (loop $label$11 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$11 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eq + (get_local $4) + (get_local $3) + ) + ) + (set_local $6 + (i32.add + (i32.and + (get_local $5) + (i32.const -16) + ) + (get_local $6) + ) + ) + ) + (set_local $6 + (i32.sub + (i32.add + (get_local $6) + (tee_local $3 + (i32.load + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + ) + ) + (tee_local $4 + (i32.load offset=28 + (get_local $7) + ) + ) + ) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.sub + (get_local $3) + (get_local $4) + ) + ) + ) + (loop $label$13 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$13 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (br_if $label$10 + (i32.ne + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + (get_local $2) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.shr_s + (i32.sub + (tee_local $5 + (i32.load + (i32.add + (get_local $1) + (i32.const 52) + ) + ) + ) + (tee_local $7 + (i32.load offset=48 + (get_local $1) + ) + ) + ) + (i32.const 4) + ) + ) + ) + (loop $label$14 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$14 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + (block $label$15 + (br_if $label$15 + (i32.eq + (get_local $7) + (get_local $5) + ) + ) + (loop $label$16 + (set_local $6 + (i32.sub + (i32.add + (i32.add + (get_local $6) + (tee_local $3 + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + ) + (i32.const 2) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $7) + ) + ) + ) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.sub + (get_local $3) + (get_local $4) + ) + ) + ) + (loop $label$17 + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$17 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (br_if $label$16 + (i32.ne + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $5) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $6) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_18transaction_headerE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 3) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (get_local $1) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $4) + ) + (i32.const 1) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.const 2) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 2) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $4) + ) + (i32.const 3) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load offset=4 + (get_local $0) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $5 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i64.load32_u offset=12 + (get_local $1) + ) + ) + (loop $label$0 + (set_local $4 + (i32.wrap/i64 + (get_local $6) + ) + ) + (i32.store8 offset=14 + (get_local $7) + (i32.or + (i32.shl + (tee_local $2 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $4) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $5) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.add + (get_local $7) + (i32.const 14) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $4) + (tee_local $5 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $2) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $5) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $4) + (tee_local $5 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i64.load32_u offset=20 + (get_local $1) + ) + ) + (loop $label$1 + (set_local $2 + (i32.wrap/i64 + (get_local $6) + ) + ) + (i32.store8 offset=15 + (get_local $7) + (i32.or + (i32.shl + (tee_local $1 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $2) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $3) + ) + (get_local $5) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $4) + (tee_local $5 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$1 + (get_local $1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEENS_6actionEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $5 + (i64.extend_u/i32 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + (i32.const 40) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $7 + (i32.wrap/i64 + (get_local $5) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $2 + (i64.ne + (tee_local $5 + (i64.shr_u + (get_local $5) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $7) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $3) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $2) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $7 + (i32.load + (get_local $1) + ) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$2 + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $6) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (get_local $7) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $6) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $4) + ) + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE + (call $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE + (get_local $0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (i32.add + (get_local $7) + (i32.const 28) + ) + ) + ) + (br_if $label$1 + (i32.eq + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + (get_local $3) + ) + ) + (set_local $6 + (i32.load + (get_local $4) + ) + ) + (br $label$2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEENSt3__15tupleIJtNS4_6vectorIcNS4_9allocatorIcEEEEEEEEERT_SC_RKNS6_IT0_NS7_ISD_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $5 + (i64.extend_u/i32 + (i32.shr_s + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$0 + (set_local $4 + (i32.wrap/i64 + (get_local $5) + ) + ) + (i32.store8 offset=15 + (get_local $7) + (i32.or + (i32.shl + (tee_local $2 + (i64.ne + (tee_local $5 + (i64.shr_u + (get_local $5) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $4) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $3) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $2) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + (tee_local $2 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$2 + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $3) + ) + (get_local $6) + ) + (i32.const 1) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (get_local $4) + (i32.const 2) + ) + ) + (i32.store + (get_local $6) + (i32.add + (i32.load + (get_local $6) + ) + (i32.const 2) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE + (get_local $0) + (i32.add + (get_local $4) + (i32.const 4) + ) + ) + ) + (br_if $label$1 + (i32.eq + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + (get_local $2) + ) + ) + (set_local $6 + (i32.load + (get_local $6) + ) + ) + (br $label$2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction18send_action_senderEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 128) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 8) + ) + ) + (i32.store offset=96 + (get_local $11) + (i32.const 0) + ) + (i64.store offset=88 + (get_local $11) + (i64.const 0) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.add + (get_local $11) + (i32.const 104) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $5 + (i32.load offset=92 + (get_local $11) + ) + ) + (i32.load offset=96 + (get_local $11) + ) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u offset=105 + (get_local $11) + ) + ) + (i32.store offset=92 + (get_local $11) + (tee_local $5 + (i32.add + (i32.load offset=92 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (br $label$0) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.or + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 1) + ) + ) + (set_local $5 + (i32.load offset=92 + (get_local $11) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $5) + (i32.load + (i32.add + (get_local $11) + (i32.const 96) + ) + ) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u offset=106 + (get_local $11) + ) + ) + (i32.store offset=92 + (get_local $11) + (tee_local $5 + (i32.add + (i32.load offset=92 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (br $label$2) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.or + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 2) + ) + ) + (set_local $5 + (i32.load offset=92 + (get_local $11) + ) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (get_local $5) + (i32.load + (i32.add + (get_local $11) + (i32.const 96) + ) + ) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u offset=107 + (get_local $11) + ) + ) + (i32.store offset=92 + (get_local $11) + (tee_local $5 + (i32.add + (i32.load offset=92 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (br $label$4) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.or + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 3) + ) + ) + (set_local $5 + (i32.load offset=92 + (get_local $11) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $5) + (i32.load + (i32.add + (get_local $11) + (i32.const 96) + ) + ) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u offset=108 + (get_local $11) + ) + ) + (i32.store offset=92 + (get_local $11) + (tee_local $5 + (i32.add + (i32.load offset=92 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (br $label$6) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.or + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 4) + ) + ) + (set_local $5 + (i32.load offset=92 + (get_local $11) + ) + ) + ) + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.eq + (get_local $5) + (i32.load + (i32.add + (get_local $11) + (i32.const 96) + ) + ) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u offset=109 + (get_local $11) + ) + ) + (i32.store offset=92 + (get_local $11) + (tee_local $5 + (i32.add + (i32.load offset=92 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (br $label$8) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.or + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 5) + ) + ) + (set_local $5 + (i32.load offset=92 + (get_local $11) + ) + ) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.eq + (get_local $5) + (i32.load + (i32.add + (get_local $11) + (i32.const 96) + ) + ) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u offset=110 + (get_local $11) + ) + ) + (i32.store offset=92 + (get_local $11) + (tee_local $5 + (i32.add + (i32.load offset=92 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (br $label$10) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.or + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 6) + ) + ) + (set_local $5 + (i32.load offset=92 + (get_local $11) + ) + ) + ) + (block $label$12 + (block $label$13 + (br_if $label$13 + (i32.eq + (get_local $5) + (i32.load + (i32.add + (get_local $11) + (i32.const 96) + ) + ) + ) + ) + (i32.store8 + (get_local $5) + (i32.load8_u offset=111 + (get_local $11) + ) + ) + (i32.store offset=92 + (get_local $11) + (i32.add + (i32.load offset=92 + (get_local $11) + ) + (i32.const 1) + ) + ) + (br $label$12) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.or + (i32.add + (get_local $11) + (i32.const 104) + ) + (i32.const 7) + ) + ) + ) + (set_local $7 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 52) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 56) + ) + (i32.const 0) + ) + (i32.store offset=36 + (get_local $11) + (i32.const 0) + ) + (i32.store8 offset=40 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=44 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=48 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=24 + (get_local $11) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $7) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=60 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 68) + ) + (i32.const 0) + ) + (i32.store offset=72 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 76) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 80) + ) + (i32.const 0) + ) + (set_local $4 + (i32.add + (get_local $11) + (i32.const 60) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$14 + (block $label$15 + (block $label$16 + (block $label$17 + (block $label$18 + (block $label$19 + (br_if $label$19 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$18 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$17) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$16 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$15) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$14 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 416) + ) + (set_local $10 + (i64.const 0) + ) + (loop $label$20 + (block $label$21 + (block $label$22 + (block $label$23 + (block $label$24 + (block $label$25 + (br_if $label$25 + (i64.gt_u + (get_local $7) + (i64.const 5) + ) + ) + (br_if $label$24 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$23) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$22 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$21) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $10 + (i64.or + (get_local $9) + (get_local $10) + ) + ) + (br_if $label$20 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=8 + (get_local $11) + (get_local $10) + ) + (i64.store + (get_local $11) + (get_local $8) + ) + (i32.store + (i32.add + (tee_local $5 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $11) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 4) + ) + (i32.load offset=4 + (get_local $11) + ) + ) + (i32.store offset=112 + (get_local $11) + (get_local $5) + ) + (i32.store + (get_local $5) + (i32.load + (get_local $11) + ) + ) + (i32.store offset=120 + (get_local $11) + (tee_local $3 + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 8) + ) + (i32.load offset=8 + (get_local $11) + ) + ) + (i32.store offset=116 + (get_local $11) + (get_local $3) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEEvDpOT_ + (get_local $4) + (i32.add + (get_local $11) + (i32.const 112) + ) + (i32.add + (get_local $11) + (i32.const 88) + ) + ) + (block $label$26 + (br_if $label$26 + (i32.eqz + (tee_local $5 + (i32.load offset=112 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=116 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i64.store offset=8 + (get_local $11) + (i64.const 0) + ) + (i64.store + (get_local $11) + (i64.const 0) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $11) + (i32.const 112) + ) + (i32.add + (get_local $11) + (i32.const 24) + ) + ) + (call $send_deferred + (get_local $11) + (get_local $0) + (tee_local $5 + (i32.load offset=112 + (get_local $11) + ) + ) + (i32.sub + (i32.load offset=116 + (get_local $11) + ) + (get_local $5) + ) + (i32.const 0) + ) + (block $label$27 + (br_if $label$27 + (i32.eqz + (tee_local $5 + (i32.load offset=112 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=116 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $11) + (i32.const 24) + ) + ) + ) + (block $label$28 + (br_if $label$28 + (i32.eqz + (tee_local $5 + (i32.load offset=88 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=92 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 128) + ) + ) + ) + (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $6 + (i32.add + (tee_local $9 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $8 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 40) + ) + ) + (i32.const 1) + ) + ) + (i32.const 107374183) + ) + ) + (set_local $7 + (i32.const 107374182) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $8 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $8) + ) + (i32.const 40) + ) + ) + (i32.const 53687090) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $6) + (tee_local $7 + (i32.shl + (get_local $8) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $6) + ) + ) + ) + ) + ) + ) + (set_local $8 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $3 + (i32.add + (get_local $8) + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (set_local $4 + (i32.add + (tee_local $8 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (tee_local $9 + (i32.add + (get_local $8) + (i32.mul + (get_local $9) + (i32.const 40) + ) + ) + ) + (get_local $1) + (get_local $2) + ) + ) + (i32.const 40) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (set_local $5 + (i32.sub + (i32.const 0) + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const -20) + ) + ) + (loop $label$6 + (i64.store + (i32.add + (get_local $8) + (i32.const -32) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -12) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -20) + ) + ) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -16) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -20) + ) + (i32.load + (get_local $7) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $1 + (i32.add + (get_local $7) + (i32.const 4) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -12) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $8 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (set_local $8 + (tee_local $9 + (i32.add + (get_local $9) + (i32.const -40) + ) + ) + ) + (br_if $label$6 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $5) + ) + (i32.const -20) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $1 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $9) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $4) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $3) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $1) + ) + ) + (set_local $9 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$8 + (block $label$9 + (br_if $label$9 + (i32.eqz + (tee_local $8 + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $8 + (i32.load + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 4) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$8 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $9) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + ) + (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -3841127010667593728) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -8665432476387013263) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $6) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $7) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $1 + (i32.load + (get_local $2) + ) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.sub + (get_local $4) + (get_local $1) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $3) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $2) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $1) + (get_local $4) + ) + ) + (loop $label$2 + (i32.store8 offset=15 + (get_local $7) + (i32.load8_u + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $5) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $6) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + ) + (i64.store align=4 + (get_local $6) + (i64.load + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction22send_transaction_emptyEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $5 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 96) + ) + ) + ) + (set_local $4 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 44) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 48) + ) + (i32.const 0) + ) + (i32.store offset=28 + (get_local $5) + (i32.const 0) + ) + (i32.store8 offset=32 + (get_local $5) + (i32.const 0) + ) + (i32.store offset=36 + (get_local $5) + (i32.const 0) + ) + (i32.store offset=40 + (get_local $5) + (i32.const 0) + ) + (i32.store offset=16 + (get_local $5) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $4) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=52 + (get_local $5) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 56) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 60) + ) + (i32.const 0) + ) + (i32.store offset=64 + (get_local $5) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 68) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 72) + ) + (i32.const 0) + ) + (i64.store offset=8 + (get_local $5) + (i64.const 0) + ) + (i64.store + (get_local $5) + (i64.const 0) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $5) + (i32.const 80) + ) + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + (call $send_deferred + (get_local $5) + (get_local $0) + (tee_local $3 + (i32.load offset=80 + (get_local $5) + ) + ) + (i32.sub + (i32.load offset=84 + (get_local $5) + ) + (get_local $3) + ) + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.load offset=80 + (get_local $5) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $5) + (get_local $3) + ) + (call $_ZdlPv + (get_local $3) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 17712) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $5) + (i32.const 96) + ) + ) + ) + (func $_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (set_local $7 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 60) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 0) + ) + (i32.store offset=44 + (get_local $11) + (i32.const 0) + ) + (i32.store8 offset=48 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=52 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=56 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=32 + (get_local $11) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $7) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=68 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 72) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 76) + ) + (i32.const 0) + ) + (i32.store offset=80 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 84) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.const 0) + ) + (i32.store offset=24 + (get_local $11) + (i32.const 0) + ) + (set_local $7 + (i64.const 0) + ) + (i64.store offset=16 + (get_local $11) + (i64.const 0) + ) + (set_local $3 + (i32.add + (get_local $11) + (i32.const 68) + ) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $4 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $4 + (select + (i32.add + (get_local $4) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $4) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $4) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 416) + ) + (set_local $10 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $7) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $4 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $4 + (select + (i32.add + (get_local $4) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $4) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $4) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $10 + (i64.or + (get_local $9) + (get_local $10) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=8 + (get_local $11) + (get_local $10) + ) + (i64.store + (get_local $11) + (get_local $8) + ) + (i32.store + (i32.add + (tee_local $5 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $11) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 4) + ) + (i32.load offset=4 + (get_local $11) + ) + ) + (i32.store offset=96 + (get_local $11) + (get_local $5) + ) + (i32.store + (get_local $5) + (i32.load + (get_local $11) + ) + ) + (i32.store offset=104 + (get_local $11) + (tee_local $4 + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 8) + ) + (i32.load offset=8 + (get_local $11) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $4) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEEvDpOT_ + (get_local $3) + (i32.add + (get_local $11) + (i32.const 96) + ) + (i32.add + (get_local $11) + (i32.const 16) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i64.store offset=8 + (get_local $11) + (i64.const 0) + ) + (i64.store + (get_local $11) + (i64.const 0) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $11) + (i32.const 96) + ) + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + (call $send_deferred + (get_local $11) + (get_local $0) + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + (i32.sub + (i32.load offset=100 + (get_local $11) + ) + (get_local $5) + ) + (i32.const 0) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $5 + (i32.load offset=16 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 112) + ) + ) + ) + (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $6 + (i32.add + (tee_local $9 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $8 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 40) + ) + ) + (i32.const 1) + ) + ) + (i32.const 107374183) + ) + ) + (set_local $7 + (i32.const 107374182) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $8 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $8) + ) + (i32.const 40) + ) + ) + (i32.const 53687090) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $6) + (tee_local $7 + (i32.shl + (get_local $8) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $6) + ) + ) + ) + ) + ) + ) + (set_local $8 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $3 + (i32.add + (get_local $8) + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (set_local $4 + (i32.add + (tee_local $8 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (tee_local $9 + (i32.add + (get_local $8) + (i32.mul + (get_local $9) + (i32.const 40) + ) + ) + ) + (get_local $1) + (get_local $2) + ) + ) + (i32.const 40) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (set_local $5 + (i32.sub + (i32.const 0) + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const -20) + ) + ) + (loop $label$6 + (i64.store + (i32.add + (get_local $8) + (i32.const -32) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -12) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -20) + ) + ) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -16) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -20) + ) + (i32.load + (get_local $7) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $1 + (i32.add + (get_local $7) + (i32.const 4) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -12) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $8 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (set_local $8 + (tee_local $9 + (i32.add + (get_local $9) + (i32.const -40) + ) + ) + ) + (br_if $label$6 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $5) + ) + (i32.const -20) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $1 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $9) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $4) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $3) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $1) + ) + ) + (set_local $9 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$8 + (block $label$9 + (br_if $label$9 + (i32.eqz + (tee_local $8 + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $8 + (i32.load + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 4) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$8 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $9) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + ) + (func $_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE (param $0 i32) + (local $1 i64) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (call $eosio_assert + (i32.eq + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 40) + ) + ) + (i32.load offset=36 + (get_local $0) + ) + ) + (i32.const 40) + ) + (i32.const 17776) + ) + (set_local $1 + (i64.load + (i32.load offset=36 + (get_local $0) + ) + ) + ) + (set_local $5 + (i64.const 0) + ) + (set_local $4 + (i64.const 59) + ) + (set_local $3 + (i32.const 368) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $5) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $2 + (i32.load8_s + (get_local $3) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $7 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $5) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $2 + (select + (i32.add + (get_local $2) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $2) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $7 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $7 + (i64.shl + (i64.and + (get_local $7) + (i64.const 31) + ) + (i64.and + (get_local $4) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + (set_local $5 + (i64.add + (get_local $5) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $7) + (get_local $6) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $4 + (i64.add + (get_local $4) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (get_local $6) + ) + (i32.const 17824) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 36) + ) + ) + ) + ) + (i64.const -8665432478290165179) + ) + (i32.const 17856) + ) + (call $eosio_assert + (i32.eq + (i32.sub + (i32.load + (i32.add + (tee_local $2 + (i32.load + (get_local $3) + ) + ) + (i32.const 20) + ) + ) + (i32.load offset=16 + (get_local $2) + ) + ) + (i32.const 16) + ) + (i32.const 17888) + ) + (set_local $1 + (i64.load + (i32.load offset=16 + (i32.load + (get_local $3) + ) + ) + ) + ) + (set_local $5 + (i64.const 0) + ) + (set_local $4 + (i64.const 59) + ) + (set_local $3 + (i32.const 368) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $5) + (i64.const 6) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $2 + (i32.load8_s + (get_local $3) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $7 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $5) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $2 + (select + (i32.add + (get_local $2) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $2) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $7 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $7 + (i64.shl + (i64.and + (get_local $7) + (i64.const 31) + ) + (i64.and + (get_local $4) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + (set_local $5 + (i64.add + (get_local $5) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $7) + (get_local $6) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $4 + (i64.add + (get_local $4) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (get_local $6) + ) + (i32.const 17936) + ) + (set_local $1 + (i64.load offset=8 + (i32.load offset=16 + (i32.load + (i32.add + (get_local $0) + (i32.const 36) + ) + ) + ) + ) + ) + (set_local $5 + (i64.const 0) + ) + (set_local $4 + (i64.const 59) + ) + (set_local $3 + (i32.const 416) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (block $label$17 + (br_if $label$17 + (i64.gt_u + (get_local $5) + (i64.const 5) + ) + ) + (br_if $label$16 + (i32.gt_u + (i32.and + (i32.add + (tee_local $2 + (i32.load8_s + (get_local $3) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 165) + ) + ) + (br $label$15) + ) + (set_local $7 + (i64.const 0) + ) + (br_if $label$14 + (i64.le_u + (get_local $5) + (i64.const 11) + ) + ) + (br $label$13) + ) + (set_local $2 + (select + (i32.add + (get_local $2) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $2) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $7 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $2) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $7 + (i64.shl + (i64.and + (get_local $7) + (i64.const 31) + ) + (i64.and + (get_local $4) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 1) + ) + ) + (set_local $5 + (i64.add + (get_local $5) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $7) + (get_local $6) + ) + ) + (br_if $label$12 + (i64.ne + (tee_local $4 + (i64.add + (get_local $4) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i64.eq + (get_local $1) + (get_local $6) + ) + (i32.const 17984) + ) + ) + (func $_ZN16test_transaction22send_transaction_largeEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i64) + (local $13 i64) + (local $14 i64) + (local $15 i64) + (local $16 i64) + (local $17 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $17 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 1136) + ) + ) + ) + (set_local $13 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 1100) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (i32.add + (get_local $17) + (i32.const 1072) + ) + (i32.const 32) + ) + (i32.const 0) + ) + (i32.store offset=1084 + (get_local $17) + (i32.const 0) + ) + (i32.store8 offset=1088 + (get_local $17) + (i32.const 0) + ) + (i32.store offset=1092 + (get_local $17) + (i32.const 0) + ) + (i32.store offset=1096 + (get_local $17) + (i32.const 0) + ) + (i32.store offset=1072 + (get_local $17) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $13) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=1108 + (get_local $17) + (i32.const 0) + ) + (i32.store + (tee_local $5 + (i32.add + (i32.add + (get_local $17) + (i32.const 1072) + ) + (i32.const 40) + ) + ) + (i32.const 0) + ) + (i32.store + (tee_local $6 + (i32.add + (get_local $17) + (i32.const 1116) + ) + ) + (i32.const 0) + ) + (i32.store offset=1120 + (get_local $17) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 1124) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $17) + (i32.const 1128) + ) + (i32.const 0) + ) + (set_local $3 + (i32.add + (get_local $17) + (i32.const 1108) + ) + ) + (set_local $7 + (i32.add + (i32.add + (get_local $17) + (i32.const 32) + ) + (i32.const 8) + ) + ) + (set_local $8 + (i32.const 0) + ) + (loop $label$0 + (i32.store + (get_local $7) + (i32.const 0) + ) + (i64.store offset=32 + (get_local $17) + (i64.const 0) + ) + (set_local $9 + (i32.const 0) + ) + (set_local $10 + (i32.const 0) + ) + (set_local $11 + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + (set_local $4 + (i32.add + (i32.add + (get_local $17) + (i32.const 48) + ) + (get_local $11) + ) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.eq + (get_local $10) + (get_local $9) + ) + ) + (i32.store8 + (get_local $10) + (i32.load8_u + (get_local $4) + ) + ) + (i32.store offset=36 + (get_local $17) + (i32.add + (i32.load offset=36 + (get_local $17) + ) + (i32.const 1) + ) + ) + (br_if $label$3 + (i32.ne + (get_local $11) + (i32.const 1023) + ) + ) + (br $label$1) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ + (i32.add + (get_local $17) + (i32.const 32) + ) + (get_local $4) + ) + (br_if $label$1 + (i32.eq + (get_local $11) + (i32.const 1023) + ) + ) + ) + (set_local $11 + (i32.add + (get_local $11) + (i32.const 1) + ) + ) + (set_local $9 + (i32.load + (get_local $7) + ) + ) + (set_local $10 + (i32.load offset=36 + (get_local $17) + ) + ) + (br $label$2) + ) + ) + (set_local $13 + (i64.const 0) + ) + (set_local $12 + (i64.const 59) + ) + (set_local $11 + (i32.const 368) + ) + (set_local $14 + (i64.const 0) + ) + (loop $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (br_if $label$10 + (i64.gt_u + (get_local $13) + (i64.const 6) + ) + ) + (br_if $label$9 + (i32.gt_u + (i32.and + (i32.add + (tee_local $10 + (i32.load8_s + (get_local $11) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $10 + (i32.add + (get_local $10) + (i32.const 165) + ) + ) + (br $label$8) + ) + (set_local $15 + (i64.const 0) + ) + (br_if $label$7 + (i64.le_u + (get_local $13) + (i64.const 11) + ) + ) + (br $label$6) + ) + (set_local $10 + (select + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $10) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $15 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $10) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $15 + (i64.shl + (i64.and + (get_local $15) + (i64.const 31) + ) + (i64.and + (get_local $12) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $11 + (i32.add + (get_local $11) + (i32.const 1) + ) + ) + (set_local $13 + (i64.add + (get_local $13) + (i64.const 1) + ) + ) + (set_local $14 + (i64.or + (get_local $15) + (get_local $14) + ) + ) + (br_if $label$5 + (i64.ne + (tee_local $12 + (i64.add + (get_local $12) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $13 + (i64.const 0) + ) + (set_local $12 + (i64.const 59) + ) + (set_local $11 + (i32.const 416) + ) + (set_local $16 + (i64.const 0) + ) + (loop $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (br_if $label$16 + (i64.gt_u + (get_local $13) + (i64.const 5) + ) + ) + (br_if $label$15 + (i32.gt_u + (i32.and + (i32.add + (tee_local $10 + (i32.load8_s + (get_local $11) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $10 + (i32.add + (get_local $10) + (i32.const 165) + ) + ) + (br $label$14) + ) + (set_local $15 + (i64.const 0) + ) + (br_if $label$13 + (i64.le_u + (get_local $13) + (i64.const 11) + ) + ) + (br $label$12) + ) + (set_local $10 + (select + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $10) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $15 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $10) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $15 + (i64.shl + (i64.and + (get_local $15) + (i64.const 31) + ) + (i64.and + (get_local $12) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $11 + (i32.add + (get_local $11) + (i32.const 1) + ) + ) + (set_local $13 + (i64.add + (get_local $13) + (i64.const 1) + ) + ) + (set_local $16 + (i64.or + (get_local $15) + (get_local $16) + ) + ) + (br_if $label$11 + (i64.ne + (tee_local $12 + (i64.add + (get_local $12) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store + (tee_local $10 + (i32.add + (get_local $17) + (i32.const 8) + ) + ) + (get_local $16) + ) + (i32.store + (tee_local $9 + (i32.add + (i32.add + (get_local $17) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.const 0) + ) + (i64.store + (get_local $17) + (get_local $14) + ) + (i64.store offset=16 + (get_local $17) + (i64.const 0) + ) + (i32.store + (get_local $9) + (tee_local $4 + (i32.add + (tee_local $11 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $17) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 4) + ) + (i32.load offset=4 + (get_local $17) + ) + ) + (i32.store offset=16 + (get_local $17) + (get_local $11) + ) + (i32.store + (get_local $11) + (i32.load + (get_local $17) + ) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.load + (get_local $10) + ) + ) + (i32.store offset=20 + (get_local $17) + (get_local $4) + ) + (block $label$17 + (block $label$18 + (block $label$19 + (br_if $label$19 + (i32.ge_u + (tee_local $11 + (i32.load + (get_local $5) + ) + ) + (i32.load + (get_local $6) + ) + ) + ) + (drop + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (get_local $11) + (i32.add + (get_local $17) + (i32.const 16) + ) + (i32.add + (get_local $17) + (i32.const 32) + ) + ) + ) + (i32.store + (get_local $5) + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 40) + ) + ) + (br_if $label$18 + (tee_local $11 + (i32.load offset=16 + (get_local $17) + ) + ) + ) + (br $label$17) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEEvDpOT_ + (get_local $3) + (i32.add + (get_local $17) + (i32.const 16) + ) + (i32.add + (get_local $17) + (i32.const 32) + ) + ) + (br_if $label$17 + (i32.eqz + (tee_local $11 + (i32.load offset=16 + (get_local $17) + ) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $17) + (get_local $11) + ) + (call $_ZdlPv + (get_local $11) + ) + ) + (block $label$20 + (br_if $label$20 + (i32.eqz + (tee_local $11 + (i32.load offset=32 + (get_local $17) + ) + ) + ) + ) + (i32.store offset=36 + (get_local $17) + (get_local $11) + ) + (call $_ZdlPv + (get_local $11) + ) + ) + (br_if $label$0 + (i32.ne + (tee_local $8 + (i32.add + (get_local $8) + (i32.const 1) + ) + ) + (i32.const 32) + ) + ) + ) + (i64.store offset=56 + (get_local $17) + (i64.const 0) + ) + (i64.store offset=48 + (get_local $17) + (i64.const 0) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (get_local $17) + (i32.add + (get_local $17) + (i32.const 1072) + ) + ) + (call $send_deferred + (i32.add + (get_local $17) + (i32.const 48) + ) + (get_local $0) + (tee_local $11 + (i32.load + (get_local $17) + ) + ) + (i32.sub + (i32.load offset=4 + (get_local $17) + ) + (get_local $11) + ) + (i32.const 0) + ) + (block $label$21 + (br_if $label$21 + (i32.eqz + (tee_local $11 + (i32.load + (get_local $17) + ) + ) + ) + ) + (i32.store offset=4 + (get_local $17) + (get_local $11) + ) + (call $_ZdlPv + (get_local $11) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 18032) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $17) + (i32.const 1072) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $17) + (i32.const 1136) + ) + ) + ) + (func $_ZN16test_transaction14deferred_printEv + (call $prints + (i32.const 18096) + ) + ) + (func $_ZN16test_transaction25send_deferred_transactionEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (set_local $7 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 60) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 0) + ) + (i32.store offset=44 + (get_local $11) + (i32.const 0) + ) + (i32.store8 offset=48 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=52 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=56 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=32 + (get_local $11) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $7) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=68 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 72) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 76) + ) + (i32.const 0) + ) + (i32.store offset=80 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 84) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.const 0) + ) + (i32.store offset=24 + (get_local $11) + (i32.const 0) + ) + (set_local $7 + (i64.const 0) + ) + (i64.store offset=16 + (get_local $11) + (i64.const 0) + ) + (set_local $3 + (i32.add + (get_local $11) + (i32.const 68) + ) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $4 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $4 + (select + (i32.add + (get_local $4) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $4) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $4) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 416) + ) + (set_local $10 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $7) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $4 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $4 + (select + (i32.add + (get_local $4) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $4) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $4) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $10 + (i64.or + (get_local $9) + (get_local $10) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=8 + (get_local $11) + (get_local $10) + ) + (i64.store + (get_local $11) + (get_local $8) + ) + (i32.store + (i32.add + (tee_local $5 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $11) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 4) + ) + (i32.load offset=4 + (get_local $11) + ) + ) + (i32.store offset=96 + (get_local $11) + (get_local $5) + ) + (i32.store + (get_local $5) + (i32.load + (get_local $11) + ) + ) + (i32.store offset=104 + (get_local $11) + (tee_local $4 + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 8) + ) + (i32.load offset=8 + (get_local $11) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $4) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEEvDpOT_ + (get_local $3) + (i32.add + (get_local $11) + (i32.const 96) + ) + (i32.add + (get_local $11) + (i32.const 16) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 52) + ) + (i32.const 2) + ) + (i64.store offset=8 + (get_local $11) + (i64.const 0) + ) + (i64.store + (get_local $11) + (i64.const -1) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $11) + (i32.const 96) + ) + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + (call $send_deferred + (get_local $11) + (get_local $0) + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + (i32.sub + (i32.load offset=100 + (get_local $11) + ) + (get_local $5) + ) + (i32.const 0) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $5 + (i32.load offset=16 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 112) + ) + ) + ) + (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $6 + (i32.add + (tee_local $9 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $8 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 40) + ) + ) + (i32.const 1) + ) + ) + (i32.const 107374183) + ) + ) + (set_local $7 + (i32.const 107374182) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $8 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $8) + ) + (i32.const 40) + ) + ) + (i32.const 53687090) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $6) + (tee_local $7 + (i32.shl + (get_local $8) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $6) + ) + ) + ) + ) + ) + ) + (set_local $8 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $3 + (i32.add + (get_local $8) + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (set_local $4 + (i32.add + (tee_local $8 + (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (tee_local $9 + (i32.add + (get_local $8) + (i32.mul + (get_local $9) + (i32.const 40) + ) + ) + ) + (get_local $1) + (get_local $2) + ) + ) + (i32.const 40) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (set_local $5 + (i32.sub + (i32.const 0) + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const -20) + ) + ) + (loop $label$6 + (i64.store + (i32.add + (get_local $8) + (i32.const -32) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -12) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -20) + ) + ) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -16) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -20) + ) + (i32.load + (get_local $7) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $1 + (i32.add + (get_local $7) + (i32.const 4) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -12) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store + (get_local $2) + (i32.load + (tee_local $8 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (set_local $8 + (tee_local $9 + (i32.add + (get_local $9) + (i32.const -40) + ) + ) + ) + (br_if $label$6 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $5) + ) + (i32.const -20) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $1 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $9) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $4) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $3) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $1) + ) + ) + (set_local $9 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$8 + (block $label$9 + (br_if $label$9 + (i32.eqz + (tee_local $8 + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $8 + (i32.load + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 4) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$8 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $9) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + ) + (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -3841127010667593728) + ) + (i64.store offset=8 + (get_local $0) + (i64.const -696013501027893080) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $6) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $7) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $1 + (i32.load + (get_local $2) + ) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.sub + (get_local $4) + (get_local $1) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $3) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $2) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $1) + (get_local $4) + ) + ) + (loop $label$2 + (i32.store8 offset=15 + (get_local $7) + (i32.load8_u + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $5) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $6) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + ) + (i64.store align=4 + (get_local $6) + (i64.load + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction33send_deferred_transaction_replaceEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i64) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 112) + ) + ) + ) + (set_local $7 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 60) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 64) + ) + (i32.const 0) + ) + (i32.store offset=44 + (get_local $11) + (i32.const 0) + ) + (i32.store8 offset=48 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=52 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=56 + (get_local $11) + (i32.const 0) + ) + (i32.store offset=32 + (get_local $11) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $7) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=68 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 72) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 76) + ) + (i32.const 0) + ) + (i32.store offset=80 + (get_local $11) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 84) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 88) + ) + (i32.const 0) + ) + (i32.store offset=24 + (get_local $11) + (i32.const 0) + ) + (set_local $7 + (i64.const 0) + ) + (i64.store offset=16 + (get_local $11) + (i64.const 0) + ) + (set_local $3 + (i32.add + (get_local $11) + (i32.const 68) + ) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 368) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $4 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $4 + (select + (i32.add + (get_local $4) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $4) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $4) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 416) + ) + (set_local $10 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $7) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $4 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $4 + (select + (i32.add + (get_local $4) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $4) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $4) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $10 + (i64.or + (get_local $9) + (get_local $10) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=8 + (get_local $11) + (get_local $10) + ) + (i64.store + (get_local $11) + (get_local $8) + ) + (i32.store + (i32.add + (tee_local $5 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (get_local $11) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 4) + ) + (i32.load offset=4 + (get_local $11) + ) + ) + (i32.store offset=96 + (get_local $11) + (get_local $5) + ) + (i32.store + (get_local $5) + (i32.load + (get_local $11) + ) + ) + (i32.store offset=104 + (get_local $11) + (tee_local $4 + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $5) + (i32.const 8) + ) + (i32.load offset=8 + (get_local $11) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $4) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEEvDpOT_ + (get_local $3) + (i32.add + (get_local $11) + (i32.const 96) + ) + (i32.add + (get_local $11) + (i32.const 16) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (i32.store + (i32.add + (get_local $11) + (i32.const 52) + ) + (i32.const 2) + ) + (i64.store offset=8 + (get_local $11) + (i64.const 0) + ) + (i64.store + (get_local $11) + (i64.const -1) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $11) + (i32.const 96) + ) + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + (call $send_deferred + (get_local $11) + (get_local $0) + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + (i32.sub + (i32.load offset=100 + (get_local $11) + ) + (get_local $5) + ) + (i32.const 1) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $5 + (i32.load offset=96 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=100 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $5 + (i32.load offset=16 + (get_local $11) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $11) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $11) + (i32.const 32) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 112) + ) + ) + ) + (func $_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 176) + ) + ) + ) + (set_local $0 + (call $_ZN10dtt_actionC2Ev + (i32.add + (get_local $7) + (i32.const 120) + ) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $7) + (i32.const 120) + ) + (call $action_data_size) + ) + ) + (set_local $4 + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $7) + (i32.const 104) + ) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $7) + (i32.const 112) + ) + (i64.const 0) + ) + (i64.store offset=96 + (get_local $7) + (i64.const 0) + ) + (i64.store offset=80 + (get_local $7) + (i64.load offset=8 + (get_local $0) + ) + ) + (i64.store offset=88 + (get_local $7) + (i64.load offset=16 + (get_local $0) + ) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 + (get_local $7) + (get_local $5) + ) + (i64.store offset=24 + (get_local $7) + (i64.load offset=24 + (get_local $0) + ) + ) + (i64.store + (i32.add + (tee_local $2 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 8) + ) + (i64.load offset=24 + (get_local $7) + ) + ) + (i64.store + (get_local $2) + (i64.load offset=16 + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 100) + ) + (tee_local $1 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + (i32.store offset=96 + (get_local $7) + (get_local $2) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 104) + ) + (get_local $1) + ) + (set_local $4 + (call $current_time) + ) + (i32.store + (i32.add + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 28) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 48) + ) + (i32.const 0) + ) + (i32.store offset=28 + (get_local $7) + (i32.const 0) + ) + (i32.store8 offset=32 + (get_local $7) + (i32.const 0) + ) + (i32.store offset=36 + (get_local $7) + (i32.const 0) + ) + (i32.store offset=40 + (get_local $7) + (i32.const 0) + ) + (i32.store offset=16 + (get_local $7) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $4) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=52 + (get_local $7) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 56) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 60) + ) + (i32.const 0) + ) + (i32.store offset=64 + (get_local $7) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 68) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 72) + ) + (i32.const 0) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJRS2_EEEvDpOT_ + (i32.add + (get_local $7) + (i32.const 52) + ) + (i32.add + (get_local $7) + (i32.const 80) + ) + ) + (i32.store offset=36 + (get_local $7) + (i32.load offset=32 + (get_local $0) + ) + ) + (i64.store offset=8 + (get_local $7) + (i64.const 0) + ) + (i64.store + (get_local $7) + (i64.const -1) + ) + (drop + (call $cancel_deferred + (get_local $7) + ) + ) + (i64.store offset=8 + (get_local $7) + (i64.const 0) + ) + (i64.store + (get_local $7) + (i64.const -1) + ) + (set_local $4 + (i64.load + (get_local $0) + ) + ) + (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $7) + (i32.const 160) + ) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (call $send_deferred + (get_local $7) + (get_local $4) + (tee_local $2 + (i32.load offset=160 + (get_local $7) + ) + ) + (i32.sub + (i32.load offset=164 + (get_local $7) + ) + (get_local $2) + ) + (i32.const 1) + ) + (block $label$6 + (br_if $label$6 + (i32.eqz + (tee_local $2 + (i32.load offset=160 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=164 + (get_local $7) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + (block $label$7 + (br_if $label$7 + (i32.eqz + (tee_local $2 + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 80) + ) + (i32.const 28) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 112) + ) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.eqz + (tee_local $2 + (i32.load + (i32.add + (get_local $7) + (i32.const 96) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 100) + ) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 176) + ) + ) + ) + (func $_ZN10dtt_actionC2Ev (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store align=1 + (get_local $0) + (get_local $5) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 368) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $4) + (i64.const 6) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 align=1 + (get_local $0) + (i64.const -696013501027893080) + ) + (i64.store align=1 + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $5) + ) + (set_local $4 + (i64.const 0) + ) + (set_local $3 + (i64.const 59) + ) + (set_local $2 + (i32.const 416) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (block $label$16 + (block $label$17 + (br_if $label$17 + (i64.gt_u + (get_local $4) + (i64.const 5) + ) + ) + (br_if $label$16 + (i32.gt_u + (i32.and + (i32.add + (tee_local $1 + (i32.load8_s + (get_local $2) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 165) + ) + ) + (br $label$15) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$14 + (i64.le_u + (get_local $4) + (i64.const 11) + ) + ) + (br $label$13) + ) + (set_local $1 + (select + (i32.add + (get_local $1) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $1) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $1) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $3) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (set_local $4 + (i64.add + (get_local $4) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$12 + (i64.ne + (tee_local $3 + (i64.add + (get_local $3) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i32.store offset=32 align=1 + (get_local $0) + (i32.const 2) + ) + (i64.store align=1 + (i32.add + (get_local $0) + (i32.const 24) + ) + (get_local $5) + ) + (get_local $0) + ) + (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJRS2_EEEvDpOT_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $5 + (i32.add + (tee_local $9 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $0) + ) + (tee_local $8 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 40) + ) + ) + (i32.const 1) + ) + ) + (i32.const 107374183) + ) + ) + (set_local $7 + (i32.const 107374182) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.gt_u + (tee_local $8 + (i32.div_s + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $8) + ) + (i32.const 40) + ) + ) + (i32.const 53687090) + ) + ) + (br_if $label$2 + (i32.eqz + (tee_local $7 + (select + (get_local $5) + (tee_local $7 + (i32.shl + (get_local $8) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $5) + ) + ) + ) + ) + ) + ) + (set_local $8 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $2 + (i32.add + (get_local $8) + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (set_local $3 + (i32.add + (tee_local $8 + (call $_ZN5eosio6actionC2ERKS0_ + (tee_local $9 + (i32.add + (get_local $8) + (i32.mul + (get_local $9) + (i32.const 40) + ) + ) + ) + (get_local $1) + ) + ) + (i32.const 40) + ) + ) + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.eq + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $7 + (i32.load + (get_local $0) + ) + ) + ) + ) + (set_local $4 + (i32.sub + (i32.const 0) + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (get_local $1) + (i32.const -20) + ) + ) + (loop $label$6 + (i64.store + (i32.add + (get_local $8) + (i32.const -32) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -12) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $7) + (i32.const -20) + ) + ) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + (i64.const 0) + ) + (i32.store + (tee_local $5 + (i32.add + (get_local $8) + (i32.const -16) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -20) + ) + (i32.load + (get_local $7) + ) + ) + (i32.store + (get_local $5) + (i32.load + (tee_local $1 + (i32.add + (get_local $7) + (i32.const 4) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -12) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store + (tee_local $5 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $6 + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + (i32.store + (get_local $5) + (i32.load + (tee_local $8 + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (set_local $8 + (tee_local $9 + (i32.add + (get_local $9) + (i32.const -40) + ) + ) + ) + (br_if $label$6 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $4) + ) + (i32.const -20) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + (br $label$4) + ) + (set_local $1 + (get_local $7) + ) + ) + (i32.store + (get_local $0) + (get_local $9) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $2) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (get_local $7) + (get_local $1) + ) + ) + (set_local $9 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const -24) + ) + ) + (loop $label$8 + (block $label$9 + (br_if $label$9 + (i32.eqz + (tee_local $8 + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (tee_local $8 + (i32.load + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 4) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$8 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $9) + ) + (i32.const -24) + ) + ) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + ) + (func $_ZN5eosio6actionC2ERKS0_ (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (i64.store + (get_local $0) + (i64.load + (get_local $1) + ) + ) + (i64.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.const 0) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.eqz + (tee_local $5 + (i32.shr_s + (tee_local $4 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + (i32.load offset=16 + (get_local $1) + ) + ) + ) + (i32.const 4) + ) + ) + ) + ) + (br_if $label$1 + (i32.ge_u + (get_local $5) + (i32.const 268435456) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 16) + ) + (tee_local $4 + (call $_Znwj + (get_local $4) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.add + (get_local $4) + (i32.shl + (get_local $5) + (i32.const 4) + ) + ) + ) + (i32.store + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 20) + ) + ) + (get_local $4) + ) + (br_if $label$2 + (i32.lt_s + (tee_local $3 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + (tee_local $2 + (i32.load + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + ) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $4) + (get_local $2) + (get_local $3) + ) + ) + (i32.store + (get_local $5) + (i32.add + (i32.load + (get_local $5) + ) + (get_local $3) + ) + ) + ) + (i64.store offset=28 align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $4 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + (i32.load offset=28 + (get_local $1) + ) + ) + ) + ) + ) + (br_if $label$0 + (i32.le_s + (get_local $4) + (i32.const -1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 28) + ) + (tee_local $5 + (call $_Znwj + (get_local $4) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.add + (get_local $5) + (get_local $4) + ) + ) + (i32.store + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + (get_local $5) + ) + (br_if $label$3 + (i32.lt_s + (tee_local $1 + (i32.sub + (i32.load + (i32.add + (get_local $1) + (i32.const 32) + ) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + ) + ) + ) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $3) + (get_local $1) + ) + ) + (i32.store + (get_local $4) + (i32.add + (i32.load + (get_local $4) + ) + (get_local $1) + ) + ) + ) + (return + (get_local $0) + ) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + (unreachable) + ) + (func $_ZN16test_transaction35cancel_deferred_transaction_successEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -1) + ) + (call $eosio_assert + (i32.ne + (call $cancel_deferred + (get_local $0) + ) + (i32.const 0) + ) + (i32.const 18128) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN16test_transaction37cancel_deferred_transaction_not_foundEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const -1) + ) + (call $eosio_assert + (i32.eqz + (call $cancel_deferred + (get_local $0) + ) + ) + (i32.const 18160) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (func $_ZN16test_transaction14send_cf_actionEv + (local $0 i32) + (local $1 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $1 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (i64.store + (i32.add + (get_local $1) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $1) + (i32.const 40) + ) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $1) + (i64.const 0) + ) + (i64.store offset=8 + (get_local $1) + (i64.const 5666987383162142720) + ) + (i64.store offset=16 + (get_local $1) + (i64.const 6256973794934521856) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 18224) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $1) + (i32.const 48) + ) + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (call $send_context_free_inline + (tee_local $0 + (i32.load offset=48 + (get_local $1) + ) + ) + (i32.sub + (i32.load offset=52 + (get_local $1) + ) + (get_local $0) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (tee_local $0 + (i32.load offset=48 + (get_local $1) + ) + ) + ) + ) + (i32.store offset=52 + (get_local $1) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $0 + (i32.load offset=36 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 40) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$2 + (br_if $label$2 + (i32.eqz + (tee_local $0 + (i32.load + (i32.add + (get_local $1) + (i32.const 24) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 28) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $1) + (i32.const 64) + ) + ) + ) + (func $_ZN16test_transaction19send_cf_action_failEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 96) + ) + ) + ) + (i32.store offset=88 + (get_local $7) + (i32.const 0) + ) + (set_local $3 + (i64.const 0) + ) + (i64.store offset=80 + (get_local $7) + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 18272) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 4) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 416) + ) + (set_local $6 + (i64.const 0) + ) + (loop $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (block $label$11 + (br_if $label$11 + (i64.gt_u + (get_local $3) + (i64.const 5) + ) + ) + (br_if $label$10 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$9) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$8 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$7) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $6 + (i64.or + (get_local $5) + (get_local $6) + ) + ) + (br_if $label$6 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (i64.store offset=16 + (get_local $7) + (get_local $6) + ) + (i64.store offset=8 + (get_local $7) + (get_local $4) + ) + (i32.store + (i32.add + (tee_local $1 + (call $_Znwj + (i32.const 16) + ) + ) + (i32.const 12) + ) + (i32.load + (i32.add + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 12) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.load offset=12 + (get_local $7) + ) + ) + (i32.store offset=24 + (get_local $7) + (get_local $1) + ) + (i32.store + (get_local $1) + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.store offset=32 + (get_local $7) + (tee_local $0 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=16 + (get_local $7) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (set_local $1 + (call $_ZN5eosio6actionC2I18test_action_actionILy5666987383162142720ELy6256973794934521856EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ + (i32.add + (get_local $7) + (i32.const 40) + ) + (i32.add + (get_local $7) + (i32.const 24) + ) + (i32.add + (get_local $7) + (i32.const 80) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $0 + (i32.load offset=24 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=28 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + (i32.load offset=16 + (get_local $1) + ) + ) + (i32.const 18224) + ) + (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ + (i32.add + (get_local $7) + (i32.const 8) + ) + (get_local $1) + ) + (call $send_context_free_inline + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + (i32.sub + (i32.load offset=12 + (get_local $7) + ) + (get_local $0) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $0 + (i32.load offset=8 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=12 + (get_local $7) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 18288) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $0 + (i32.load offset=28 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 32) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$15 + (br_if $label$15 + (i32.eqz + (tee_local $0 + (i32.load offset=16 + (get_local $1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 20) + ) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (block $label$16 + (br_if $label$16 + (i32.eqz + (tee_local $1 + (i32.load offset=80 + (get_local $7) + ) + ) + ) + ) + (i32.store offset=84 + (get_local $7) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 96) + ) + ) + ) + (func $_ZN5eosio6actionC2I18test_action_actionILy5666987383162142720ELy6256973794934521856EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 24) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $0) + (i32.const 32) + ) + (i64.const 0) + ) + (i64.store + (get_local $0) + (i64.const 5666987383162142720) + ) + (i64.store offset=8 + (get_local $0) + (i64.const 6256973794934521856) + ) + (i32.store offset=16 + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 20) + ) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $6) + (i32.load offset=8 + (get_local $1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $7) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eq + (tee_local $1 + (i32.load + (get_local $2) + ) + ) + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (tee_local $3 + (i32.sub + (get_local $4) + (get_local $1) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $7) + (get_local $3) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $2) + ) + ) + (set_local $5 + (i32.load offset=4 + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $1) + (get_local $4) + ) + ) + (loop $label$2 + (i32.store8 offset=15 + (get_local $7) + (i32.load8_u + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (get_local $5) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $6) + (i32.add + (get_local $7) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $4) + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $1 + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 28) + ) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 32) + ) + (get_local $1) + ) + (call $_ZdlPv + (get_local $1) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + ) + (i64.store align=4 + (get_local $6) + (i64.load + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 36) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN16test_transaction12stateful_apiEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (local $6 i64) + (local $7 i64) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=12 + (get_local $8) + (i32.const 1) + ) + (set_local $2 + (i64.const 0) + ) + (set_local $4 + (i64.const 59) + ) + (set_local $1 + (i32.const 18352) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$0 + (set_local $6 + (i64.const 0) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i64.gt_u + (get_local $2) + (i64.const 15) + ) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$2 + (i64.gt_u + (get_local $2) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $4) + (i64.const 4294967295) + ) + ) + ) + (br $label$1) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i64.add + (get_local $2) + (i64.const 1) + ) + ) + (set_local $3 + (i64.or + (get_local $6) + (get_local $3) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $4 + (i64.add + (get_local $4) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $2 + (i64.const 0) + ) + (set_local $4 + (i64.const 59) + ) + (set_local $1 + (i32.const 18384) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (block $label$10 + (br_if $label$10 + (i64.gt_u + (get_local $2) + (i64.const 4) + ) + ) + (br_if $label$9 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$8) + ) + (set_local $6 + (i64.const 0) + ) + (br_if $label$7 + (i64.le_u + (get_local $2) + (i64.const 11) + ) + ) + (br $label$6) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $4) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i64.add + (get_local $2) + (i64.const 1) + ) + ) + (set_local $5 + (i64.or + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$5 + (i64.ne + (tee_local $4 + (i64.add + (get_local $4) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (set_local $2 + (i64.const 0) + ) + (set_local $4 + (i64.const 59) + ) + (set_local $1 + (i32.const 18352) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$11 + (set_local $6 + (i64.const 0) + ) + (block $label$12 + (block $label$13 + (br_if $label$13 + (i64.gt_u + (get_local $2) + (i64.const 15) + ) + ) + (block $label$14 + (block $label$15 + (br_if $label$15 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$14) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + (br_if $label$13 + (i64.gt_u + (get_local $2) + (i64.const 11) + ) + ) + (set_local $6 + (i64.shl + (i64.and + (get_local $6) + (i64.const 31) + ) + (i64.and + (get_local $4) + (i64.const 4294967295) + ) + ) + ) + (br $label$12) + ) + (set_local $6 + (i64.and + (get_local $6) + (i64.const 15) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $2 + (i64.add + (get_local $2) + (i64.const 1) + ) + ) + (set_local $7 + (i64.or + (get_local $6) + (get_local $7) + ) + ) + (br_if $label$11 + (i64.ne + (tee_local $4 + (i64.add + (get_local $4) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (drop + (call $db_store_i64 + (get_local $3) + (get_local $5) + (get_local $7) + (i64.const 0) + (i32.add + (get_local $8) + (i32.const 12) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + ) + (func $_ZN16test_transaction16context_free_apiEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 128) + ) + ) + ) + (drop + (call $get_context_free_data + (i32.const 0) + (tee_local $0 + (call $memset + (get_local $0) + (i32.const 0) + (i32.const 128) + ) + ) + (i32.const 128) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 128) + ) + ) + ) + (func $_ZN16test_transaction11new_featureEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 18400) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 9) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i32.eqz + (call $is_feature_active + (get_local $4) + ) + ) + (i32.const 18416) + ) + ) + (func $_ZN16test_transaction18active_new_featureEv + (local $0 i32) + (local $1 i32) + (local $2 i64) + (local $3 i64) + (local $4 i64) + (local $5 i64) + (set_local $3 + (i64.const 0) + ) + (set_local $2 + (i64.const 59) + ) + (set_local $1 + (i32.const 18400) + ) + (set_local $4 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $3) + (i64.const 9) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $0 + (i32.load8_s + (get_local $1) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $5 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $3) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $0 + (select + (i32.add + (get_local $0) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $0) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $5 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $0) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $5 + (i64.shl + (i64.and + (get_local $5) + (i64.const 31) + ) + (i64.and + (get_local $2) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (set_local $4 + (i64.or + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $2 + (i64.add + (get_local $2) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $activate_feature + (get_local $4) + ) + ) + (func $_ZN14test_checktime14checktime_passEv + (call $printi + (i64.const 49995000) + ) + ) + (func $_ZN14test_checktime17checktime_failureEv + (local $0 i64) + (local $1 i64) + (local $2 i64) + (local $3 i64) + (set_local $2 + (i64.const 0) + ) + (set_local $1 + (i64.const 1) + ) + (set_local $3 + (i64.const 0) + ) + (loop $label$0 + (set_local $2 + (i64.add + (i64.and + (tee_local $0 + (get_local $2) + ) + (i64.const 4294967295) + ) + (get_local $3) + ) + ) + (set_local $3 + (i64.add + (get_local $3) + (i64.const 1) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $1 + (i64.add + (get_local $1) + (i64.const -1) + ) + ) + (i64.const 8446744073709551617) + ) + ) + ) + (call $printi + (i64.shr_s + (i64.shl + (i64.sub + (get_local $0) + (get_local $1) + ) + (i64.const 32) + ) + (i64.const 32) + ) + ) + ) + (func $_ZN14test_checktime22checktime_sha1_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha1 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN14test_checktime29checktime_assert_sha1_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $assert_sha1 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN14test_checktime24checktime_sha256_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $sha256 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN14test_checktime31checktime_assert_sha256_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $assert_sha256 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN14test_checktime24checktime_sha512_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $sha512 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + (func $_ZN14test_checktime31checktime_assert_sha512_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $assert_sha512 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 64) + ) + ) + ) + (func $_ZN14test_checktime27checktime_ripemd160_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $ripemd160 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN14test_checktime34checktime_assert_ripemd160_failureEv + (local $0 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $0 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $assert_ripemd160 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (get_local $0) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $0) + (i32.const 32) + ) + ) + ) + (func $_ZN15test_permission19check_authorizationEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i64) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $9 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 64) + ) + ) + ) + (call $_ZN5eosio18unpack_action_dataI14check_auth_msgEET_v + (i32.add + (get_local $9) + (i32.const 16) + ) + ) + (i32.store offset=8 + (get_local $9) + (i32.const 0) + ) + (i64.store + (get_local $9) + (i64.const 0) + ) + (set_local $7 + (i32.const 34) + ) + (set_local $8 + (i64.extend_u/i32 + (i32.div_s + (tee_local $6 + (i32.sub + (tee_local $4 + (i32.load + (i32.add + (get_local $9) + (i32.const 36) + ) + ) + ) + (tee_local $5 + (i32.load offset=32 + (get_local $9) + ) + ) + ) + ) + (i32.const 34) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $9) + (i32.const 32) + ) + ) + (loop $label$0 + (set_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $8 + (i64.shr_u + (get_local $8) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $5) + (get_local $4) + ) + ) + (br_if $label$2 + (tee_local $7 + (i32.add + (i32.sub + (tee_local $4 + (i32.add + (get_local $6) + (i32.const -34) + ) + ) + (i32.rem_u + (get_local $4) + (i32.const 34) + ) + ) + (get_local $7) + ) + ) + ) + (set_local $4 + (i32.const 0) + ) + (set_local $7 + (i32.const 0) + ) + (br $label$1) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const -34) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $9) + (get_local $7) + ) + (set_local $4 + (i32.load offset=4 + (get_local $9) + ) + ) + (set_local $7 + (i32.load + (get_local $9) + ) + ) + ) + (i32.store offset=52 + (get_local $9) + (get_local $7) + ) + (i32.store offset=48 + (get_local $9) + (get_local $7) + ) + (i32.store offset=56 + (get_local $9) + (get_local $4) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEE10public_keyEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE + (i32.add + (get_local $9) + (i32.const 48) + ) + (get_local $3) + ) + ) + (i64.store offset=48 + (get_local $9) + (i64.extend_s/i32 + (call $check_permission_authorization + (i64.load offset=16 + (get_local $9) + ) + (i64.load offset=24 + (get_local $9) + ) + (tee_local $7 + (i32.load + (get_local $9) + ) + ) + (i32.sub + (i32.load offset=4 + (get_local $9) + ) + (get_local $7) + ) + (i32.const 0) + (i32.const 0) + (i64.const 9223372036854775807) + ) + ) + ) + (block $label$4 + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.eq + (tee_local $7 + (call $db_lowerbound_i64 + (get_local $0) + (get_local $0) + (get_local $0) + (i64.const 1) + ) + ) + (i32.const -1) + ) + ) + (call $db_update_i64 + (get_local $7) + (get_local $0) + (i32.add + (get_local $9) + (i32.const 48) + ) + (i32.const 8) + ) + (br_if $label$5 + (tee_local $7 + (i32.load + (get_local $9) + ) + ) + ) + (br $label$4) + ) + (drop + (call $db_store_i64 + (get_local $0) + (get_local $0) + (get_local $0) + (i64.const 1) + (i32.add + (get_local $9) + (i32.const 48) + ) + (i32.const 8) + ) + ) + (br_if $label$4 + (i32.eqz + (tee_local $7 + (i32.load + (get_local $9) + ) + ) + ) + ) + ) + (i32.store offset=4 + (get_local $9) + (get_local $7) + ) + (call $_ZdlPv + (get_local $7) + ) + ) + (block $label$7 + (br_if $label$7 + (i32.eqz + (tee_local $7 + (i32.load offset=32 + (get_local $9) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $9) + (i32.const 36) + ) + (get_local $7) + ) + (call $_ZdlPv + (get_local $7) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $9) + (i32.const 64) + ) + ) + ) + (func $_ZN5eosio18unpack_action_dataI14check_auth_msgEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (set_local $4 + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $3) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $3 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (get_local $3) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $3) + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.const 0) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store + (get_local $4) + (get_local $3) + ) + (i32.store offset=8 + (get_local $4) + (tee_local $2 + (i32.add + (get_local $3) + (get_local $1) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (get_local $1) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $3) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (get_local $2) + (tee_local $1 + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $1) + (i32.const 8) + ) + ) + (i32.store offset=4 + (get_local $4) + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEE10public_keyEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE + (get_local $4) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEE10public_keyEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 80) + ) + ) + ) + (set_local $6 + (i64.extend_u/i32 + (i32.div_s + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + (i32.const 34) + ) + ) + ) + (set_local $7 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $2 + (i32.wrap/i64 + (get_local $6) + ) + ) + (i32.store8 offset=40 + (get_local $8) + (i32.or + (i32.shl + (tee_local $3 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $2) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $7) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $5) + ) + (i32.add + (get_local $8) + (i32.const 40) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $5) + (tee_local $7 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $3) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $5 + (i32.load + (get_local $1) + ) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$2 + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 6) + ) + (get_local $5) + (i32.const 34) + ) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 40) + ) + (i32.add + (get_local $8) + (i32.const 6) + ) + (i32.const 34) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $7) + ) + (i32.const 33) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $2) + ) + (i32.add + (get_local $8) + (i32.const 40) + ) + (i32.const 34) + ) + ) + (i32.store + (get_local $2) + (tee_local $7 + (i32.add + (i32.load + (get_local $2) + ) + (i32.const 34) + ) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 34) + ) + ) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 80) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEE10public_keyEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.const 848) + ) + (set_local $4 + (i32.load8_u + (tee_local $5 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $7 + (i32.and + (get_local $7) + (i32.const 255) + ) + ) + ) + ) + (get_local $6) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.le_u + (tee_local $5 + (i32.wrap/i64 + (get_local $6) + ) + ) + (tee_local $7 + (i32.div_s + (i32.sub + (tee_local $3 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + ) + (i32.const 34) + ) + ) + ) + ) + (call $_ZNSt3__16vectorI10public_keyNS_9allocatorIS1_EEE8__appendEj + (get_local $1) + (i32.sub + (get_local $5) + (get_local $7) + ) + ) + (br_if $label$2 + (i32.ne + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (br $label$1) + ) + (block $label$4 + (br_if $label$4 + (i32.ge_u + (get_local $5) + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (tee_local $3 + (i32.add + (get_local $4) + (i32.mul + (get_local $5) + (i32.const 34) + ) + ) + ) + ) + ) + (br_if $label$1 + (i32.eq + (get_local $4) + (get_local $3) + ) + ) + ) + (set_local $7 + (i32.load + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$5 + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $7) + ) + (i32.const 33) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $4) + (i32.load + (get_local $5) + ) + (i32.const 34) + ) + ) + (i32.store + (get_local $5) + (tee_local $7 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 34) + ) + ) + ) + (br_if $label$5 + (i32.ne + (get_local $3) + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 34) + ) + ) + ) + ) + ) + ) + (get_local $0) + ) + (func $_ZNSt3__16vectorI10public_keyNS_9allocatorIS1_EEE8__appendEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (i32.div_s + (i32.sub + (tee_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (i32.const 34) + ) + (get_local $1) + ) + ) + (br_if $label$2 + (i32.ge_u + (tee_local $4 + (i32.add + (tee_local $3 + (i32.div_s + (i32.sub + (get_local $6) + (tee_local $5 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 34) + ) + ) + (get_local $1) + ) + ) + (i32.const 126322568) + ) + ) + (set_local $6 + (i32.const 126322567) + ) + (block $label$5 + (br_if $label$5 + (i32.gt_u + (tee_local $2 + (i32.div_s + (i32.sub + (get_local $2) + (get_local $5) + ) + (i32.const 34) + ) + ) + (i32.const 63161282) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $6 + (select + (get_local $4) + (tee_local $6 + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $6) + (get_local $4) + ) + ) + ) + ) + ) + ) + (set_local $2 + (call $_Znwj + (i32.mul + (get_local $6) + (i32.const 34) + ) + ) + ) + (br $label$1) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$6 + (drop + (call $memset + (get_local $6) + (i32.const 0) + (i32.const 34) + ) + ) + (i32.store + (get_local $0) + (tee_local $6 + (i32.add + (i32.load + (get_local $0) + ) + (i32.const 34) + ) + ) + ) + (br_if $label$6 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + (br $label$0) + ) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $2 + (i32.const 0) + ) + (br $label$1) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $4 + (i32.add + (get_local $2) + (i32.mul + (get_local $6) + (i32.const 34) + ) + ) + ) + (set_local $6 + (tee_local $5 + (i32.add + (get_local $2) + (i32.mul + (get_local $3) + (i32.const 34) + ) + ) + ) + ) + (loop $label$7 + (set_local $6 + (i32.add + (call $memset + (get_local $6) + (i32.const 0) + (i32.const 34) + ) + (i32.const 34) + ) + ) + (br_if $label$7 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.mul + (i32.div_s + (tee_local $2 + (i32.sub + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $1 + (i32.load + (get_local $0) + ) + ) + ) + ) + (i32.const -34) + ) + (i32.const 34) + ) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.lt_s + (get_local $2) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $5) + (get_local $1) + (get_local $2) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $5) + ) + (i32.store + (get_local $3) + (get_local $6) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $4) + ) + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + (return) + ) + ) + (func $_ZN15test_permission25test_permission_last_usedEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + (call $eosio_assert + (i64.eq + (call $get_permission_last_used + (i64.load offset=8 + (get_local $3) + ) + (i64.load offset=16 + (get_local $3) + ) + ) + (i64.load offset=24 + (get_local $3) + ) + ) + (i32.const 18464) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 32) + ) + ) + ) + (func $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (set_local $3 + (tee_local $2 + (i32.load offset=4 + (i32.const 0) + ) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $2 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $2) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $2) + (get_local $1) + ) + ) + (call $eosio_assert + (i32.gt_u + (get_local $1) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $2) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (tee_local $1 + (i32.and + (get_local $1) + (i32.const -8) + ) + ) + (i32.const 8) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 8) + ) + (i32.add + (get_local $2) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.ne + (get_local $1) + (i32.const 16) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $0) + (i32.const 16) + ) + (i32.add + (get_local $2) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $3) + ) + ) + (func $_ZN15test_permission26test_account_creation_timeEyyy (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $3 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + (call $eosio_assert + (i64.eq + (call $get_account_creation_time + (i64.load offset=8 + (get_local $3) + ) + ) + (i64.load offset=24 + (get_local $3) + ) + ) + (i32.const 18512) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 32) + ) + ) + ) + (func $_ZN15test_datastream10test_basicEv + (local $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 160) + ) + ) + ) + (i32.store8 offset=144 + (get_local $8) + (i32.const 1) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.ne + (i32.load8_u offset=144 + (get_local $8) + ) + (i32.const 0) + ) + (i32.const 18560) + ) + (i32.store8 offset=144 + (get_local $8) + (i32.const 0) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.eqz + (i32.load8_u offset=144 + (get_local $8) + ) + ) + (i32.const 18560) + ) + (i32.store8 offset=8 + (get_local $8) + (i32.const 133) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load8_u offset=8 + (get_local $8) + ) + (i32.load8_u offset=144 + (get_local $8) + ) + ) + (i32.const 18576) + ) + (i32.store8 offset=8 + (get_local $8) + (i32.const 127) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 1) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load8_u offset=8 + (get_local $8) + ) + (i32.load8_u offset=144 + (get_local $8) + ) + ) + (i32.const 18592) + ) + (i32.store16 offset=8 + (get_local $8) + (i32.const 53191) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 2) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 2) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load16_u offset=8 + (get_local $8) + ) + (i32.load16_u offset=144 + (get_local $8) + ) + ) + (i32.const 18608) + ) + (i32.store16 offset=8 + (get_local $8) + (i32.const 12345) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 2) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 2) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load16_u offset=8 + (get_local $8) + ) + (i32.load16_u offset=144 + (get_local $8) + ) + ) + (i32.const 18624) + ) + (i32.store offset=8 + (get_local $8) + (i32.const -1234567890) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=8 + (get_local $8) + ) + (i32.load offset=144 + (get_local $8) + ) + ) + (i32.const 18640) + ) + (i32.store offset=8 + (get_local $8) + (i32.const -1060399406) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=8 + (get_local $8) + ) + (i32.load offset=144 + (get_local $8) + ) + ) + (i32.const 18656) + ) + (i64.store offset=8 + (get_local $8) + (i64.const -9223372036854775808) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $8) + ) + (i64.load offset=144 + (get_local $8) + ) + ) + (i32.const 18672) + ) + (i64.store offset=8 + (get_local $8) + (i64.const 9223372036854775807) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=8 + (get_local $8) + ) + (i64.load offset=144 + (get_local $8) + ) + ) + (i32.const 18688) + ) + (i32.store offset=8 + (get_local $8) + (i32.const 1067316150) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (f32.lt + (call $fabsf + (f32.sub + (f32.load offset=8 + (get_local $8) + ) + (f32.load offset=144 + (get_local $8) + ) + ) + ) + (f32.const 1.000000013351432e-10) + ) + (i32.const 18704) + ) + (i64.store offset=8 + (get_local $8) + (i64.const 4599676419421066581) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.add + (get_local $8) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (f64.lt + (call $fabs + (f64.sub + (f64.load offset=8 + (get_local $8) + ) + (f64.load offset=144 + (get_local $8) + ) + ) + ) + (f64.const 1e-20) + ) + (i32.const 18720) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 18728) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (tee_local $7 + (i32.or + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (i32.const 18736) + (i32.const 8) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (tee_local $2 + (i32.add + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 8) + ) + ) + (get_local $7) + (i32.const 8) + ) + ) + (set_local $6 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.ne + (i32.load offset=144 + (get_local $8) + ) + (i32.const 1) + ) + ) + (set_local $6 + (f64.lt + (call $fabs + (f64.sub + (f64.const 1.23456) + (f64.load + (get_local $2) + ) + ) + ) + (f64.const 1e-20) + ) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 18752) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 18760) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $7) + (i32.const 18764) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.or + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 4) + ) + (get_local $7) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.and + (i32.eq + (i32.load offset=144 + (get_local $8) + ) + (i32.const 10) + ) + (i32.eq + (i32.load offset=148 + (get_local $8) + ) + (i32.const 20) + ) + ) + (i32.const 18768) + ) + (i32.store + (i32.add + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $8) + (i64.const 0) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.ge_u + (tee_local $6 + (call $strlen + (i32.const 1360) + ) + ) + (i32.const -16) + ) + ) + (block $label$8 + (block $label$9 + (block $label$10 + (br_if $label$10 + (i32.ge_u + (get_local $6) + (i32.const 11) + ) + ) + (i32.store8 offset=16 + (get_local $8) + (i32.shl + (get_local $6) + (i32.const 1) + ) + ) + (set_local $2 + (i32.or + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 1) + ) + ) + (br_if $label$9 + (get_local $6) + ) + (br $label$8) + ) + (set_local $2 + (call $_Znwj + (tee_local $3 + (i32.and + (i32.add + (get_local $6) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store offset=16 + (get_local $8) + (i32.or + (get_local $3) + (i32.const 1) + ) + ) + (i32.store offset=24 + (get_local $8) + (get_local $2) + ) + (i32.store offset=20 + (get_local $8) + (get_local $6) + ) + ) + (drop + (call $memcpy + (get_local $2) + (i32.const 1360) + (get_local $6) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $2) + (get_local $6) + ) + (i32.const 0) + ) + (call $_ZN8testtypeINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEE3runERKS6_PKc + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 18784) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (i32.and + (i32.load8_u offset=16 + (get_local $8) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load offset=24 + (get_local $8) + ) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $8) + (i64.const 0) + ) + (i64.store align=4 + (tee_local $6 + (call $_Znwj + (i32.const 12) + ) + ) + (i64.const 85899345930) + ) + (i32.store offset=8 + (get_local $6) + (i32.const 30) + ) + (i32.store offset=16 + (get_local $8) + (get_local $6) + ) + (i32.store offset=24 + (get_local $8) + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 12) + ) + ) + ) + (i32.store offset=20 + (get_local $8) + (get_local $6) + ) + (call $_ZN8testtypeINSt3__16vectorIiNS0_9allocatorIiEEEEE3runERKS4_PKc + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 18800) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $6 + (i32.load offset=16 + (get_local $8) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $8) + (get_local $6) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + (set_local $6 + (i32.const 0) + ) + (i32.store offset=24 + (get_local $8) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $8) + (i64.const 0) + ) + (call $_ZN8testtypeINSt3__16vectorIiNS0_9allocatorIiEEEEE3runERKS4_PKc + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 18816) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $2 + (i32.load offset=16 + (get_local $8) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $8) + (get_local $2) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 18832) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (get_local $7) + (i32.const 18836) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (tee_local $2 + (i32.or + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 8) + ) + ) + (i32.const 18840) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.or + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 4) + ) + (get_local $7) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 8) + ) + (get_local $2) + (i32.const 4) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.ne + (i32.load offset=144 + (get_local $8) + ) + (i32.const 10) + ) + ) + (br_if $label$14 + (i32.ne + (i32.load offset=148 + (get_local $8) + ) + (i32.const 20) + ) + ) + (set_local $6 + (i32.eq + (i32.load + (i32.add + (get_local $8) + (i32.const 152) + ) + ) + (i32.const 30) + ) + ) + ) + (call $eosio_assert + (get_local $6) + (i32.const 18848) + ) + (i64.store align=4 + (i32.add + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 8) + ) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $8) + (i64.const 1) + ) + (set_local $6 + (i32.or + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (br_if $label$6 + (i32.ge_u + (tee_local $7 + (call $strlen + (i32.const 18864) + ) + ) + (i32.const -16) + ) + ) + (block $label$15 + (block $label$16 + (block $label$17 + (br_if $label$17 + (i32.ge_u + (get_local $7) + (i32.const 11) + ) + ) + (i32.store8 offset=20 + (get_local $8) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$16 + (get_local $7) + ) + (br $label$15) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 28) + ) + (tee_local $6 + (call $_Znwj + (tee_local $2 + (i32.and + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 24) + ) + (get_local $7) + ) + (i32.store offset=20 + (get_local $8) + (i32.or + (get_local $2) + (i32.const 1) + ) + ) + ) + (drop + (call $memcpy + (get_local $6) + (i32.const 18864) + (get_local $7) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $6) + (get_local $7) + ) + (i32.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $8) + (i32.const 40) + ) + (i64.const 0) + ) + (i64.store offset=32 + (get_local $8) + (i64.const 2) + ) + (set_local $6 + (i32.add + (get_local $8) + (i32.const 36) + ) + ) + (br_if $label$5 + (i32.ge_u + (tee_local $7 + (call $strlen + (i32.const 18880) + ) + ) + (i32.const -16) + ) + ) + (block $label$18 + (block $label$19 + (block $label$20 + (br_if $label$20 + (i32.ge_u + (get_local $7) + (i32.const 11) + ) + ) + (i32.store8 + (i32.add + (get_local $8) + (i32.const 36) + ) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$19 + (get_local $7) + ) + (br $label$18) + ) + (set_local $6 + (call $_Znwj + (tee_local $2 + (i32.and + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 36) + ) + (i32.or + (get_local $2) + (i32.const 1) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 44) + ) + (get_local $6) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 40) + ) + (get_local $7) + ) + ) + (drop + (call $memcpy + (get_local $6) + (i32.const 18880) + (get_local $7) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $6) + (get_local $7) + ) + (i32.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $8) + (i32.const 56) + ) + (i64.const 0) + ) + (i64.store offset=48 + (get_local $8) + (i64.const 3) + ) + (set_local $6 + (i32.add + (get_local $8) + (i32.const 52) + ) + ) + (br_if $label$4 + (i32.ge_u + (tee_local $7 + (call $strlen + (i32.const 18896) + ) + ) + (i32.const -16) + ) + ) + (block $label$21 + (block $label$22 + (block $label$23 + (br_if $label$23 + (i32.ge_u + (get_local $7) + (i32.const 11) + ) + ) + (i32.store8 + (i32.add + (get_local $8) + (i32.const 52) + ) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$22 + (get_local $7) + ) + (br $label$21) + ) + (set_local $6 + (call $_Znwj + (tee_local $2 + (i32.and + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 52) + ) + (i32.or + (get_local $2) + (i32.const 1) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 60) + ) + (get_local $6) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 56) + ) + (get_local $7) + ) + ) + (drop + (call $memcpy + (get_local $6) + (i32.const 18896) + (get_local $7) + ) + ) + ) + (set_local $2 + (i32.const 0) + ) + (i32.store8 + (i32.add + (get_local $6) + (get_local $7) + ) + (i32.const 0) + ) + (i32.store offset=152 + (get_local $8) + (i32.const 0) + ) + (i32.store offset=148 + (get_local $8) + (i32.const 0) + ) + (i32.store offset=144 + (get_local $8) + (tee_local $1 + (i32.or + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 4) + ) + ) + ) + (set_local $0 + (i32.add + (get_local $8) + (i32.const 64) + ) + ) + (set_local $5 + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (set_local $4 + (i32.add + (get_local $8) + (i32.const 152) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $1) + (get_local $1) + ) + ) + (br $label$3) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $6) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $6) + ) + (unreachable) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $6) + ) + (unreachable) + ) + (set_local $9 + (i32.const 21) + ) + (br $label$1) + ) + (set_local $9 + (i32.const 3) + ) + ) + (loop $label$24 + (block $label$25 + (block $label$26 + (block $label$27 + (block $label$28 + (block $label$29 + (block $label$30 + (block $label$31 + (block $label$32 + (block $label$33 + (block $label$34 + (block $label$35 + (block $label$36 + (block $label$37 + (block $label$38 + (block $label$39 + (block $label$40 + (block $label$41 + (block $label$42 + (block $label$43 + (block $label$44 + (block $label$45 + (block $label$46 + (block $label$47 + (block $label$48 + (block $label$49 + (block $label$50 + (block $label$51 + (block $label$52 + (block $label$53 + (block $label$54 + (block $label$55 + (block $label$56 + (block $label$57 + (block $label$58 + (block $label$59 + (block $label$60 + (block $label$61 + (block $label$62 + (block $label$63 + (block $label$64 + (block $label$65 + (block $label$66 + (block $label$67 + (block $label$68 + (block $label$69 + (block $label$70 + (block $label$71 + (block $label$72 + (block $label$73 + (block $label$74 + (block $label$75 + (block $label$76 + (block $label$77 + (block $label$78 + (block $label$79 + (block $label$80 + (block $label$81 + (block $label$82 + (block $label$83 + (block $label$84 + (block $label$85 + (block $label$86 + (block $label$87 + (block $label$88 + (block $label$89 + (block $label$90 + (block $label$91 + (block $label$92 + (block $label$93 + (br_table $label$76 $label$72 $label$93 $label$92 $label$91 $label$87 $label$84 $label$81 $label$79 $label$77 $label$75 $label$74 $label$73 $label$78 $label$82 $label$80 $label$83 $label$86 $label$85 $label$89 $label$88 $label$90 $label$71 $label$70 $label$69 $label$68 $label$67 $label$66 $label$65 $label$64 $label$62 $label$61 $label$60 $label$59 $label$58 $label$63 $label$57 $label$57 + (get_local $9) + ) + ) + (set_local $2 + (i32.load offset=148 + (get_local $8) + ) + ) + (br_if $label$56 + (i32.eq + (i32.load offset=144 + (get_local $8) + ) + (get_local $1) + ) + ) + (set_local $9 + (i32.const 3) + ) + (br $label$24) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$41 + (i32.eqz + (get_local $2) + ) + ) + (set_local $9 + (i32.const 4) + ) + (br $label$24) + ) + (br_if $label$42 + (tee_local $6 + (i32.load offset=4 + (tee_local $7 + (get_local $6) + ) + ) + ) + ) + (br $label$43) + ) + (set_local $7 + (get_local $1) + ) + (br_if $label$33 + (get_local $2) + ) + (br $label$34) + ) + (set_local $6 + (get_local $1) + ) + (set_local $9 + (i32.const 20) + ) + (br $label$24) + ) + (set_local $3 + (i32.eq + (i32.load + (tee_local $7 + (i32.load offset=8 + (get_local $6) + ) + ) + ) + (get_local $6) + ) + ) + (set_local $6 + (get_local $7) + ) + (br_if $label$40 + (get_local $3) + ) + (set_local $9 + (i32.const 5) + ) + (br $label$24) + ) + (br_if $label$39 + (i32.ge_s + (i32.load offset=16 + (get_local $7) + ) + (tee_local $6 + (i32.load + (get_local $5) + ) + ) + ) + ) + (set_local $9 + (i32.const 17) + ) + (br $label$24) + ) + (br_if $label$55 + (i32.eqz + (get_local $2) + ) + ) + (set_local $9 + (i32.const 18) + ) + (br $label$24) + ) + (br_if $label$53 + (i32.load + (tee_local $2 + (i32.add + (get_local $7) + (i32.const 4) + ) + ) + ) + ) + (br $label$54) + ) + (set_local $3 + (get_local $1) + ) + (br_if $label$52 + (get_local $2) + ) + (set_local $9 + (i32.const 16) + ) + (br $label$24) + ) + (set_local $7 + (get_local $1) + ) + (br_if $label$45 + (i32.load + (tee_local $2 + (get_local $1) + ) + ) + ) + (br $label$46) + ) + (set_local $2 + (get_local $7) + ) + (set_local $9 + (i32.const 7) + ) + (br $label$24) + ) + (br_if $label$38 + (i32.ge_s + (get_local $6) + (tee_local $7 + (i32.load offset=16 + (get_local $2) + ) + ) + ) + ) + (set_local $9 + (i32.const 15) + ) + (br $label$24) + ) + (set_local $3 + (get_local $2) + ) + (br_if $label$47 + (tee_local $7 + (i32.load + (get_local $2) + ) + ) + ) + (br $label$48) + ) + (br_if $label$37 + (i32.ge_s + (get_local $7) + (get_local $6) + ) + ) + (set_local $9 + (i32.const 13) + ) + (br $label$24) + ) + (set_local $3 + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + (br_if $label$36 + (tee_local $7 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + (set_local $9 + (i32.const 9) + ) + (br $label$24) + ) + (set_local $7 + (get_local $2) + ) + (br_if $label$50 + (i32.load + (tee_local $2 + (get_local $3) + ) + ) + ) + (br $label$51) + ) + (set_local $7 + (get_local $2) + ) + (br_if $label$49 + (i32.load + (get_local $2) + ) + ) + (set_local $9 + (i32.const 10) + ) + (br $label$24) + ) + (i32.store offset=16 + (tee_local $6 + (call $_Znwj + (i32.const 32) + ) + ) + (i32.load + (get_local $5) + ) + ) + (drop + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ + (i32.add + (get_local $6) + (i32.const 20) + ) + (i32.add + (get_local $5) + (i32.const 4) + ) + ) + ) + (i32.store offset=8 + (get_local $6) + (get_local $7) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store + (get_local $2) + (get_local $6) + ) + (br_if $label$35 + (i32.eqz + (tee_local $7 + (i32.load + (i32.load offset=144 + (get_local $8) + ) + ) + ) + ) + ) + (set_local $9 + (i32.const 11) + ) + (br $label$24) + ) + (i32.store offset=144 + (get_local $8) + (get_local $7) + ) + (set_local $6 + (i32.load + (get_local $2) + ) + ) + (set_local $9 + (i32.const 12) + ) + (br $label$24) + ) + (call $_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_ + (i32.load offset=148 + (get_local $8) + ) + (get_local $6) + ) + (i32.store + (get_local $4) + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + (set_local $9 + (i32.const 1) + ) + (br $label$24) + ) + (br_if $label$44 + (i32.ne + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 16) + ) + ) + (get_local $0) + ) + ) + (set_local $9 + (i32.const 22) + ) + (br $label$24) + ) + (call $_ZN8testtypeINSt3__13mapIiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4lessIiEENS5_INS0_4pairIKiS7_EEEEEEE3runERKSE_PKc + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.const 18912) + ) + (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE + (i32.add + (get_local $8) + (i32.const 144) + ) + (i32.load offset=148 + (get_local $8) + ) + ) + (br_if $label$32 + (i32.eqz + (i32.and + (i32.load8_u + (i32.add + (get_local $8) + (i32.const 52) + ) + ) + (i32.const 1) + ) + ) + ) + (set_local $9 + (i32.const 23) + ) + (br $label$24) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $8) + (i32.const 60) + ) + ) + ) + (set_local $9 + (i32.const 24) + ) + (br $label$24) + ) + (br_if $label$31 + (i32.eqz + (i32.and + (i32.load8_u + (i32.add + (get_local $8) + (i32.const 36) + ) + ) + (i32.const 1) + ) + ) + ) + (set_local $9 + (i32.const 25) + ) + (br $label$24) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $8) + (i32.const 44) + ) + ) + ) + (set_local $9 + (i32.const 26) + ) + (br $label$24) + ) + (br_if $label$30 + (i32.eqz + (i32.and + (i32.load8_u offset=20 + (get_local $8) + ) + (i32.const 1) + ) + ) + ) + (set_local $9 + (i32.const 27) + ) + (br $label$24) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $8) + (i32.const 28) + ) + ) + ) + (set_local $9 + (i32.const 28) + ) + (br $label$24) + ) + (i64.store align=4 + (i32.add + (get_local $8) + (i32.const 24) + ) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $8) + (i64.const 1) + ) + (set_local $6 + (i32.or + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (br_if $label$29 + (i32.gt_u + (tee_local $7 + (call $strlen + (i32.const 7840) + ) + ) + (i32.const -17) + ) + ) + (set_local $9 + (i32.const 29) + ) + (br $label$24) + ) + (br_if $label$28 + (i32.ge_u + (get_local $7) + (i32.const 11) + ) + ) + (set_local $9 + (i32.const 35) + ) + (br $label$24) + ) + (i32.store8 offset=20 + (get_local $8) + (i32.shl + (get_local $7) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$26 + (get_local $7) + ) + (br $label$27) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 28) + ) + (tee_local $6 + (call $_Znwj + (tee_local $2 + (i32.and + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const 24) + ) + (get_local $7) + ) + (i32.store offset=20 + (get_local $8) + (i32.or + (get_local $2) + (i32.const 1) + ) + ) + (set_local $9 + (i32.const 31) + ) + (br $label$24) + ) + (drop + (call $memcpy + (get_local $6) + (i32.const 7840) + (get_local $7) + ) + ) + (set_local $9 + (i32.const 32) + ) + (br $label$24) + ) + (i32.store8 + (i32.add + (get_local $6) + (get_local $7) + ) + (i32.const 0) + ) + (i64.store offset=32 + (get_local $8) + (i64.const 4614688343118974445) + ) + (call $_ZN8testtypeINSt3__15tupleIJiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEdEEEE3runERKS8_PKc + (i32.add + (get_local $8) + (i32.const 16) + ) + (i32.const 18928) + ) + (br_if $label$25 + (i32.eqz + (i32.and + (i32.load8_u offset=20 + (get_local $8) + ) + (i32.const 1) + ) + ) + ) + (set_local $9 + (i32.const 33) + ) + (br $label$24) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $8) + (i32.const 28) + ) + ) + ) + (set_local $9 + (i32.const 34) + ) + (br $label$24) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 160) + ) + ) + (return) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $6) + ) + (unreachable) + ) + (set_local $9 + (i32.const 21) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 16) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 10) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 1) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 7) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 10) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 1) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 1) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 0) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 14) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 10) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 1) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 2) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 5) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 4) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 19) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 20) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 6) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 8) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 9) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 14) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 12) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 16) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 18) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 24) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 26) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 28) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 36) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 30) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 32) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 31) + ) + (br $label$24) + ) + (set_local $9 + (i32.const 34) + ) + (br $label$24) + ) + ) + (func $_ZN8testtypeINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEE3runERKS6_PKc (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 160) + ) + ) + ) + (i32.store offset=24 + (get_local $8) + (i32.add + (get_local $8) + (i32.const 160) + ) + ) + (i32.store offset=20 + (get_local $8) + (i32.add + (get_local $8) + (i32.const 32) + ) + ) + (i32.store offset=16 + (get_local $8) + (i32.add + (get_local $8) + (i32.const 32) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE + (i32.add + (get_local $8) + (i32.const 16) + ) + (get_local $0) + ) + ) + (i64.store + (get_local $8) + (i64.const 0) + ) + (set_local $7 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $8) + (i32.const 0) + ) + (i32.store offset=20 + (get_local $8) + (i32.load offset=16 + (get_local $8) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE + (i32.add + (get_local $8) + (i32.const 16) + ) + (get_local $8) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.ne + (tee_local $4 + (select + (i32.load offset=4 + (get_local $0) + ) + (tee_local $3 + (i32.shr_u + (tee_local $5 + (i32.load8_u + (get_local $0) + ) + ) + (i32.const 1) + ) + ) + (tee_local $2 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + (select + (i32.load offset=4 + (get_local $8) + ) + (i32.shr_u + (tee_local $5 + (i32.load8_u + (get_local $8) + ) + ) + (i32.const 1) + ) + (tee_local $5 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + ) + (set_local $5 + (select + (i32.load + (i32.add + (get_local $8) + (i32.const 8) + ) + ) + (i32.or + (get_local $8) + (i32.const 1) + ) + (get_local $5) + ) + ) + (set_local $6 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (get_local $2) + ) + (br_if $label$2 + (i32.eqz + (get_local $4) + ) + ) + (set_local $0 + (i32.sub + (i32.const 0) + (get_local $3) + ) + ) + (loop $label$4 + (br_if $label$1 + (i32.ne + (i32.load8_u + (get_local $6) + ) + (i32.load8_u + (get_local $5) + ) + ) + ) + (set_local $7 + (i32.const 1) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$4 + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + ) + (br $label$0) + ) + ) + (br_if $label$2 + (i32.eqz + (get_local $4) + ) + ) + (set_local $7 + (i32.eqz + (call $memcmp + (select + (i32.load offset=8 + (get_local $0) + ) + (get_local $6) + (get_local $2) + ) + (get_local $5) + (get_local $4) + ) + ) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 1) + ) + (br $label$0) + ) + (set_local $7 + (i32.const 0) + ) + ) + (call $eosio_assert + (get_local $7) + (get_local $1) + ) + (block $label$5 + (br_if $label$5 + (i32.eqz + (i32.and + (i32.load8_u + (get_local $8) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $8) + (i32.const 8) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 160) + ) + ) + ) + (func $_ZN8testtypeINSt3__16vectorIiNS0_9allocatorIiEEEEE3runERKS4_PKc (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $5 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 160) + ) + ) + ) + (i32.store offset=24 + (get_local $5) + (i32.add + (get_local $5) + (i32.const 160) + ) + ) + (i32.store offset=20 + (get_local $5) + (i32.add + (get_local $5) + (i32.const 32) + ) + ) + (i32.store offset=16 + (get_local $5) + (i32.add + (get_local $5) + (i32.const 32) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEiEERT_S5_RKNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE + (i32.add + (get_local $5) + (i32.const 16) + ) + (get_local $0) + ) + ) + (i64.store + (get_local $5) + (i64.const 0) + ) + (set_local $4 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $5) + (i32.const 0) + ) + (i32.store offset=20 + (get_local $5) + (i32.load offset=16 + (get_local $5) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPcEEiEERT_S5_RNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE + (i32.add + (get_local $5) + (i32.const 16) + ) + (get_local $5) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.ne + (i32.sub + (tee_local $2 + (i32.load offset=4 + (get_local $0) + ) + ) + (tee_local $0 + (i32.load + (get_local $0) + ) + ) + ) + (i32.sub + (i32.load offset=4 + (get_local $5) + ) + (tee_local $3 + (i32.load + (get_local $5) + ) + ) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (get_local $0) + (get_local $2) + ) + ) + (loop $label$2 + (br_if $label$0 + (i32.ne + (i32.load + (get_local $0) + ) + (i32.load + (get_local $3) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 4) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $2) + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + ) + ) + (set_local $4 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $4) + (get_local $1) + ) + (block $label$3 + (br_if $label$3 + (i32.eqz + (tee_local $0 + (i32.load + (get_local $5) + ) + ) + ) + ) + (i32.store offset=4 + (get_local $5) + (get_local $0) + ) + (call $_ZdlPv + (get_local $0) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $5) + (i32.const 160) + ) + ) + ) + (func $_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_ (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (i32.store8 offset=12 + (get_local $1) + (tee_local $3 + (i32.eq + (get_local $1) + (get_local $0) + ) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (br_if $label$2 + (get_local $3) + ) + (block $label$3 + (block $label$4 + (block $label$5 + (loop $label$6 + (br_if $label$2 + (i32.load8_u offset=12 + (tee_local $2 + (i32.load offset=8 + (get_local $1) + ) + ) + ) + ) + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.eq + (tee_local $4 + (i32.load + (tee_local $3 + (i32.load offset=8 + (get_local $2) + ) + ) + ) + ) + (get_local $2) + ) + ) + (br_if $label$7 + (i32.eqz + (get_local $4) + ) + ) + (br_if $label$7 + (i32.load8_u offset=12 + (get_local $4) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 12) + ) + ) + (br $label$8) + ) + (br_if $label$5 + (i32.eqz + (tee_local $4 + (i32.load offset=4 + (get_local $3) + ) + ) + ) + ) + (br_if $label$5 + (i32.load8_u offset=12 + (get_local $4) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 12) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $2) + (i32.const 12) + ) + (i32.const 1) + ) + (i32.store8 offset=12 + (get_local $3) + (tee_local $2 + (i32.eq + (get_local $3) + (get_local $0) + ) + ) + ) + (i32.store8 + (get_local $4) + (i32.const 1) + ) + (set_local $1 + (get_local $3) + ) + (br_if $label$6 + (i32.eqz + (get_local $2) + ) + ) + (br $label$2) + ) + ) + (br_if $label$4 + (i32.eq + (i32.load + (get_local $2) + ) + (get_local $1) + ) + ) + (set_local $4 + (get_local $2) + ) + (br $label$3) + ) + (br_if $label$1 + (i32.eq + (i32.load + (get_local $2) + ) + (get_local $1) + ) + ) + (i32.store offset=4 + (get_local $2) + (tee_local $1 + (i32.load + (tee_local $4 + (i32.load offset=4 + (get_local $2) + ) + ) + ) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.eqz + (get_local $1) + ) + ) + (i32.store offset=8 + (get_local $1) + (get_local $2) + ) + (set_local $3 + (i32.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + ) + (i32.store offset=8 + (get_local $4) + (get_local $3) + ) + (i32.store + (select + (tee_local $3 + (i32.load + (tee_local $1 + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + ) + (i32.add + (get_local $3) + (i32.const 4) + ) + (i32.eq + (i32.load + (get_local $3) + ) + (get_local $2) + ) + ) + (get_local $4) + ) + (i32.store + (get_local $1) + (get_local $4) + ) + (i32.store + (get_local $4) + (get_local $2) + ) + (set_local $3 + (i32.load offset=8 + (get_local $4) + ) + ) + (br $label$0) + ) + (i32.store + (get_local $2) + (tee_local $1 + (i32.load offset=4 + (tee_local $4 + (i32.load + (get_local $2) + ) + ) + ) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (get_local $1) + ) + ) + (i32.store offset=8 + (get_local $1) + (get_local $2) + ) + (set_local $3 + (i32.load + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + ) + (i32.store offset=8 + (get_local $4) + (get_local $3) + ) + (i32.store + (select + (tee_local $3 + (i32.load + (tee_local $1 + (i32.add + (get_local $2) + (i32.const 8) + ) + ) + ) + ) + (i32.add + (get_local $3) + (i32.const 4) + ) + (i32.eq + (i32.load + (get_local $3) + ) + (get_local $2) + ) + ) + (get_local $4) + ) + (i32.store + (get_local $1) + (get_local $4) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 4) + ) + (get_local $2) + ) + (set_local $3 + (i32.load offset=8 + (get_local $4) + ) + ) + ) + (i32.store8 offset=12 + (get_local $4) + (i32.const 1) + ) + (i32.store8 offset=12 + (get_local $3) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $3) + (tee_local $4 + (i32.load + (tee_local $2 + (i32.load offset=4 + (get_local $3) + ) + ) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (get_local $4) + ) + ) + (i32.store offset=8 + (get_local $4) + (get_local $3) + ) + ) + (i32.store offset=8 + (get_local $2) + (i32.load offset=8 + (get_local $3) + ) + ) + (i32.store + (select + (tee_local $4 + (i32.load offset=8 + (get_local $3) + ) + ) + (i32.add + (get_local $4) + (i32.const 4) + ) + (i32.eq + (i32.load + (get_local $4) + ) + (get_local $3) + ) + ) + (get_local $2) + ) + (i32.store offset=8 + (get_local $3) + (get_local $2) + ) + (i32.store + (get_local $2) + (get_local $3) + ) + ) + (return) + ) + (set_local $4 + (get_local $2) + ) + ) + (i32.store8 offset=12 + (get_local $4) + (i32.const 1) + ) + (i32.store8 offset=12 + (get_local $3) + (i32.const 0) + ) + (i32.store + (get_local $3) + (tee_local $4 + (i32.load offset=4 + (tee_local $2 + (i32.load + (get_local $3) + ) + ) + ) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (get_local $4) + ) + ) + (i32.store offset=8 + (get_local $4) + (get_local $3) + ) + ) + (i32.store offset=8 + (get_local $2) + (i32.load offset=8 + (get_local $3) + ) + ) + (i32.store + (select + (tee_local $4 + (i32.load offset=8 + (get_local $3) + ) + ) + (i32.add + (get_local $4) + (i32.const 4) + ) + (i32.eq + (i32.load + (get_local $4) + ) + (get_local $3) + ) + ) + (get_local $2) + ) + (i32.store offset=8 + (get_local $3) + (get_local $2) + ) + (i32.store + (i32.add + (get_local $2) + (i32.const 4) + ) + (get_local $3) + ) + ) + (func $_ZN8testtypeINSt3__13mapIiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4lessIiEENS5_INS0_4pairIKiS7_EEEEEEE3runERKSE_PKc (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 160) + ) + ) + ) + (i32.store offset=24 + (get_local $10) + (i32.add + (get_local $10) + (i32.const 160) + ) + ) + (i32.store offset=20 + (get_local $10) + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + (i32.store offset=16 + (get_local $10) + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RKNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE + (i32.add + (get_local $10) + (i32.const 16) + ) + (get_local $0) + ) + ) + (i32.store + (get_local $10) + (i32.or + (get_local $10) + (i32.const 4) + ) + ) + (set_local $9 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $10) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $10) + (i32.const 0) + ) + (i32.store offset=20 + (get_local $10) + (i32.load offset=16 + (get_local $10) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE + (i32.add + (get_local $10) + (i32.const 16) + ) + (get_local $10) + ) + ) + (block $label$0 + (br_if $label$0 + (i32.ne + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=8 + (get_local $10) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (set_local $7 + (i32.load + (get_local $10) + ) + ) + (set_local $9 + (i32.const 0) + ) + (loop $label$2 + (br_if $label$0 + (i32.ne + (i32.load offset=16 + (tee_local $3 + (get_local $6) + ) + ) + (i32.load offset=16 + (tee_local $8 + (get_local $7) + ) + ) + ) + ) + (br_if $label$0 + (i32.ne + (tee_local $5 + (select + (i32.load offset=24 + (get_local $3) + ) + (tee_local $4 + (i32.shr_u + (tee_local $0 + (i32.load8_u offset=20 + (get_local $3) + ) + ) + (i32.const 1) + ) + ) + (tee_local $7 + (i32.and + (get_local $0) + (i32.const 1) + ) + ) + ) + ) + (select + (i32.load offset=24 + (get_local $8) + ) + (i32.shr_u + (tee_local $0 + (i32.load8_u offset=20 + (get_local $8) + ) + ) + (i32.const 1) + ) + (tee_local $0 + (i32.and + (get_local $0) + (i32.const 1) + ) + ) + ) + ) + ) + (set_local $0 + (select + (i32.load offset=28 + (get_local $8) + ) + (i32.add + (i32.add + (get_local $8) + (i32.const 20) + ) + (i32.const 1) + ) + (get_local $0) + ) + ) + (set_local $6 + (i32.add + (i32.add + (get_local $3) + (i32.const 20) + ) + (i32.const 1) + ) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (get_local $7) + ) + (br_if $label$3 + (i32.eqz + (get_local $5) + ) + ) + (set_local $7 + (i32.sub + (i32.const 0) + (get_local $4) + ) + ) + (loop $label$5 + (br_if $label$0 + (i32.ne + (i32.load8_u + (get_local $6) + ) + (i32.load8_u + (get_local $0) + ) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + (br_if $label$5 + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + ) + (br $label$3) + ) + ) + (br_if $label$3 + (i32.eqz + (get_local $5) + ) + ) + (br_if $label$0 + (call $memcmp + (select + (i32.load offset=28 + (get_local $3) + ) + (get_local $6) + (get_local $7) + ) + (get_local $0) + (get_local $5) + ) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.eqz + (tee_local $0 + (i32.load offset=4 + (get_local $3) + ) + ) + ) + ) + (loop $label$8 + (br_if $label$8 + (tee_local $0 + (i32.load + (tee_local $6 + (get_local $0) + ) + ) + ) + ) + (br $label$6) + ) + ) + (br_if $label$6 + (i32.eq + (i32.load + (tee_local $6 + (i32.load offset=8 + (get_local $3) + ) + ) + ) + (get_local $3) + ) + ) + (set_local $7 + (i32.add + (get_local $3) + (i32.const 8) + ) + ) + (loop $label$9 + (set_local $7 + (i32.add + (tee_local $0 + (i32.load + (get_local $7) + ) + ) + (i32.const 8) + ) + ) + (br_if $label$9 + (i32.ne + (get_local $0) + (i32.load + (tee_local $6 + (i32.load offset=8 + (get_local $0) + ) + ) + ) + ) + ) + ) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.eqz + (tee_local $0 + (i32.load offset=4 + (get_local $8) + ) + ) + ) + ) + (loop $label$12 + (br_if $label$12 + (tee_local $0 + (i32.load + (tee_local $7 + (get_local $0) + ) + ) + ) + ) + (br $label$10) + ) + ) + (br_if $label$10 + (i32.eq + (i32.load + (tee_local $7 + (i32.load offset=8 + (get_local $8) + ) + ) + ) + (get_local $8) + ) + ) + (set_local $8 + (i32.add + (get_local $8) + (i32.const 8) + ) + ) + (loop $label$13 + (set_local $8 + (i32.add + (tee_local $0 + (i32.load + (get_local $8) + ) + ) + (i32.const 8) + ) + ) + (br_if $label$13 + (i32.ne + (get_local $0) + (i32.load + (tee_local $7 + (i32.load offset=8 + (get_local $0) + ) + ) + ) + ) + ) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $6) + (get_local $2) + ) + ) + ) + ) + (set_local $9 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $9) + (get_local $1) + ) + (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE + (get_local $10) + (i32.load offset=4 + (get_local $10) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 160) + ) + ) + ) + (func $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE (param $0 i32) (param $1 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE + (get_local $0) + (i32.load + (get_local $1) + ) + ) + (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE + (get_local $0) + (i32.load offset=4 + (get_local $1) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.and + (i32.load8_u + (i32.add + (get_local $1) + (i32.const 20) + ) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $1) + (i32.const 28) + ) + ) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + ) + (func $_ZN8testtypeINSt3__15tupleIJiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEdEEEE3runERKS8_PKc (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $11 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 176) + ) + ) + ) + (i32.store offset=40 + (get_local $11) + (i32.add + (get_local $11) + (i32.const 176) + ) + ) + (i32.store offset=32 + (get_local $11) + (i32.add + (get_local $11) + (i32.const 48) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.add + (get_local $11) + (i32.const 48) + ) + (get_local $0) + (i32.const 4) + ) + ) + (i32.store offset=36 + (get_local $11) + (i32.or + (i32.add + (get_local $11) + (i32.const 48) + ) + (i32.const 4) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE + (i32.add + (get_local $11) + (i32.const 32) + ) + (tee_local $8 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load offset=40 + (get_local $11) + ) + (i32.load offset=36 + (get_local $11) + ) + ) + (i32.const 7) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load offset=36 + (get_local $11) + ) + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + (i32.const 8) + ) + ) + (i64.store + (tee_local $7 + (i32.add + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.const 8) + ) + ) + (i64.const 0) + ) + (i64.store offset=8 + (get_local $11) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $11) + (i64.const 0) + ) + (i32.store offset=36 + (get_local $11) + (tee_local $9 + (i32.load offset=32 + (get_local $11) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=40 + (get_local $11) + ) + (get_local $9) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.load offset=36 + (get_local $11) + ) + (i32.const 4) + ) + ) + (i32.store offset=36 + (get_local $11) + (i32.add + (i32.load offset=36 + (get_local $11) + ) + (i32.const 4) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE + (i32.add + (get_local $11) + (i32.const 32) + ) + (tee_local $3 + (i32.or + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.const 4) + ) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=40 + (get_local $11) + ) + (i32.load offset=36 + (get_local $11) + ) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.const 16) + ) + (i32.load offset=36 + (get_local $11) + ) + (i32.const 8) + ) + ) + (i32.store offset=36 + (get_local $11) + (i32.add + (i32.load offset=36 + (get_local $11) + ) + (i32.const 8) + ) + ) + (set_local $10 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.ne + (i32.load + (get_local $0) + ) + (i32.load offset=8 + (get_local $11) + ) + ) + ) + (br_if $label$0 + (i32.ne + (tee_local $6 + (select + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (tee_local $5 + (i32.shr_u + (tee_local $9 + (i32.load8_u + (get_local $8) + ) + ) + (i32.const 1) + ) + ) + (tee_local $4 + (i32.and + (get_local $9) + (i32.const 1) + ) + ) + ) + ) + (select + (i32.load + (get_local $7) + ) + (i32.shr_u + (tee_local $9 + (i32.load8_u offset=12 + (get_local $11) + ) + ) + (i32.const 1) + ) + (tee_local $7 + (i32.and + (get_local $9) + (i32.const 1) + ) + ) + ) + ) + ) + (set_local $9 + (i32.add + (get_local $8) + (i32.const 1) + ) + ) + (set_local $8 + (select + (i32.load + (i32.add + (i32.add + (get_local $11) + (i32.const 8) + ) + (i32.const 12) + ) + ) + (i32.add + (get_local $3) + (i32.const 1) + ) + (get_local $7) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (get_local $4) + ) + (br_if $label$1 + (i32.eqz + (get_local $6) + ) + ) + (set_local $10 + (i32.const 0) + ) + (set_local $0 + (i32.sub + (i32.const 0) + (get_local $5) + ) + ) + (loop $label$3 + (br_if $label$0 + (i32.ne + (i32.load8_u + (get_local $9) + ) + (i32.load8_u + (get_local $8) + ) + ) + ) + (set_local $8 + (i32.add + (get_local $8) + (i32.const 1) + ) + ) + (set_local $9 + (i32.add + (get_local $9) + (i32.const 1) + ) + ) + (br_if $label$3 + (tee_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + ) + (br $label$1) + ) + ) + (br_if $label$1 + (i32.eqz + (get_local $6) + ) + ) + (br_if $label$0 + (call $memcmp + (select + (i32.load + (i32.add + (get_local $0) + (i32.const 12) + ) + ) + (get_local $9) + (get_local $4) + ) + (get_local $8) + (get_local $6) + ) + ) + ) + (set_local $10 + (f64.eq + (f64.load + (get_local $2) + ) + (f64.load + (i32.add + (get_local $11) + (i32.const 24) + ) + ) + ) + ) + ) + (call $eosio_assert + (get_local $10) + (get_local $1) + ) + (block $label$4 + (br_if $label$4 + (i32.eqz + (i32.and + (i32.load8_u offset=12 + (get_local $11) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (i32.add + (get_local $11) + (i32.const 20) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $11) + (i32.const 176) + ) + ) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i64) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $7 + (i64.extend_u/i32 + (select + (i32.load offset=4 + (get_local $1) + ) + (i32.shr_u + (tee_local $5 + (i32.load8_u + (get_local $1) + ) + ) + (i32.const 1) + ) + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $2 + (i32.wrap/i64 + (get_local $7) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $3 + (i64.ne + (tee_local $7 + (i64.shr_u + (get_local $7) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $2) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $5) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $5) + (tee_local $6 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $3) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $5 + (select + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (i32.shr_u + (tee_local $5 + (i32.load8_u + (get_local $1) + ) + ) + (i32.const 1) + ) + (tee_local $2 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (set_local $3 + (i32.load offset=8 + (get_local $1) + ) + ) + (call $eosio_assert + (i32.ge_s + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $6) + ) + (get_local $5) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (select + (get_local $3) + (i32.add + (get_local $1) + (i32.const 1) + ) + (get_local $2) + ) + (get_local $5) + ) + ) + (i32.store + (get_local $6) + (i32.add + (i32.load + (get_local $6) + ) + (get_local $5) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $7 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 32) + ) + ) + ) + (i32.store offset=24 + (get_local $7) + (i32.const 0) + ) + (i64.store offset=16 + (get_local $7) + (i64.const 0) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__16vectorIcNS6_9allocatorIcEEEE + (get_local $0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + ) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (block $label$8 + (br_if $label$8 + (i32.ne + (tee_local $5 + (i32.load offset=20 + (get_local $7) + ) + ) + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + ) + (br_if $label$7 + (i32.and + (i32.load8_u + (get_local $1) + ) + (i32.const 1) + ) + ) + (i32.store16 + (get_local $1) + (i32.const 0) + ) + (set_local $4 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (br $label$6) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.const 0) + ) + (i64.store + (get_local $7) + (i64.const 0) + ) + (br_if $label$0 + (i32.ge_u + (tee_local $2 + (i32.sub + (get_local $5) + (get_local $4) + ) + ) + (i32.const -16) + ) + ) + (br_if $label$5 + (i32.ge_u + (get_local $2) + (i32.const 11) + ) + ) + (i32.store8 + (get_local $7) + (i32.shl + (get_local $2) + (i32.const 1) + ) + ) + (set_local $6 + (i32.or + (get_local $7) + (i32.const 1) + ) + ) + (br_if $label$4 + (get_local $2) + ) + (br $label$3) + ) + (i32.store8 + (i32.load offset=8 + (get_local $1) + ) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $1) + (i32.const 0) + ) + (set_local $4 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj + (get_local $1) + (i32.const 0) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (i64.store align=4 + (get_local $1) + (i64.const 0) + ) + (br_if $label$2 + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + (br $label$1) + ) + (set_local $6 + (call $_Znwj + (tee_local $5 + (i32.and + (i32.add + (get_local $2) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.or + (get_local $5) + (i32.const 1) + ) + ) + (i32.store offset=8 + (get_local $7) + (get_local $6) + ) + (i32.store offset=4 + (get_local $7) + (get_local $2) + ) + ) + (set_local $3 + (get_local $2) + ) + (set_local $5 + (get_local $6) + ) + (loop $label$9 + (i32.store8 + (get_local $5) + (i32.load8_u + (get_local $4) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (br_if $label$9 + (tee_local $3 + (i32.add + (get_local $3) + (i32.const -1) + ) + ) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (get_local $2) + ) + ) + ) + (i32.store8 + (get_local $6) + (i32.const 0) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.and + (i32.load8_u + (get_local $1) + ) + (i32.const 1) + ) + ) + (i32.store16 + (get_local $1) + (i32.const 0) + ) + (br $label$10) + ) + (i32.store8 + (i32.load offset=8 + (get_local $1) + ) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $1) + (i32.const 0) + ) + ) + (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj + (get_local $1) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + ) + (i64.store align=4 + (get_local $1) + (i64.load + (get_local $7) + ) + ) + (br_if $label$1 + (i32.eqz + (tee_local $4 + (i32.load offset=16 + (get_local $7) + ) + ) + ) + ) + ) + (i32.store offset=20 + (get_local $7) + (get_local $4) + ) + (call $_ZdlPv + (get_local $4) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $7) + (i32.const 32) + ) + ) + (return + (get_local $0) + ) + ) + (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv + (get_local $7) + ) + (unreachable) + ) + (func $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__16vectorIcNS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.const 848) + ) + (set_local $4 + (i32.load8_u + (tee_local $5 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $7 + (i32.and + (get_local $7) + (i32.const 255) + ) + ) + ) + ) + (get_local $6) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.le_u + (tee_local $3 + (i32.wrap/i64 + (get_local $6) + ) + ) + (tee_local $2 + (i32.sub + (tee_local $7 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj + (get_local $1) + (i32.sub + (get_local $3) + (get_local $2) + ) + ) + (set_local $5 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + (set_local $4 + (i32.load + (get_local $1) + ) + ) + (br $label$1) + ) + (br_if $label$1 + (i32.ge_u + (get_local $3) + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (tee_local $7 + (i32.add + (get_local $4) + (get_local $3) + ) + ) + ) + ) + (call $eosio_assert + (i32.ge_u + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $5) + ) + (tee_local $5 + (i32.sub + (get_local $7) + (get_local $4) + ) + ) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $4) + (i32.load + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (get_local $5) + ) + ) + (i32.store + (get_local $7) + (i32.add + (i32.load + (get_local $7) + ) + (get_local $5) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RKNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i64) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $4 + (i64.load32_u offset=8 + (get_local $1) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $7 + (i32.wrap/i64 + (get_local $4) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $3 + (i64.ne + (tee_local $4 + (i64.shr_u + (get_local $4) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $7) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $6) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $5) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $5) + (tee_local $6 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $3) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $7 + (i32.load + (get_local $1) + ) + ) + (tee_local $2 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$2 + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $1) + ) + (get_local $6) + ) + (i32.const 3) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.add + (get_local $7) + (i32.const 16) + ) + (i32.const 4) + ) + ) + (i32.store + (get_local $3) + (i32.add + (i32.load + (get_local $3) + ) + (i32.const 4) + ) + ) + (drop + (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE + (get_local $0) + (i32.add + (get_local $7) + (i32.const 20) + ) + ) + ) + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.eqz + (tee_local $6 + (i32.load offset=4 + (get_local $7) + ) + ) + ) + ) + (loop $label$5 + (br_if $label$5 + (tee_local $6 + (i32.load + (tee_local $5 + (get_local $6) + ) + ) + ) + ) + (br $label$3) + ) + ) + (br_if $label$3 + (i32.eq + (i32.load + (tee_local $5 + (i32.load offset=8 + (get_local $7) + ) + ) + ) + (get_local $7) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 8) + ) + ) + (loop $label$6 + (set_local $7 + (i32.add + (tee_local $6 + (i32.load + (get_local $7) + ) + ) + (i32.const 8) + ) + ) + (br_if $label$6 + (i32.ne + (get_local $6) + (i32.load + (tee_local $5 + (i32.load offset=8 + (get_local $6) + ) + ) + ) + ) + ) + ) + ) + (br_if $label$1 + (i32.eq + (get_local $5) + (get_local $2) + ) + ) + (set_local $6 + (i32.load + (get_local $3) + ) + ) + (set_local $7 + (get_local $5) + ) + (br $label$2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i64) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $13 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE + (get_local $1) + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.store + (get_local $1) + (tee_local $2 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + (set_local $5 + (i32.const 0) + ) + (i32.store offset=8 + (get_local $1) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $1) + (i32.const 0) + ) + (set_local $6 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $10 + (i64.const 0) + ) + (set_local $9 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $6) + (i32.load + (get_local $9) + ) + ) + (i32.const 848) + ) + (set_local $12 + (i32.load8_u + (tee_local $6 + (i32.load + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + ) + ) + (i32.store + (get_local $7) + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + ) + (set_local $10 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $12) + (i32.const 127) + ) + (tee_local $5 + (i32.and + (get_local $5) + (i32.const 255) + ) + ) + ) + ) + (get_local $10) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $12) + (i32.const 7) + ) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (tee_local $3 + (i32.wrap/i64 + (get_local $10) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (set_local $11 + (i32.const 0) + ) + (loop $label$2 + (i32.store + (tee_local $8 + (i32.add + (get_local $13) + (i32.const 8) + ) + ) + (i32.const 0) + ) + (i64.store + (get_local $13) + (i64.const 0) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (get_local $6) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $13) + (i32.const 12) + ) + (i32.load + (tee_local $9 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.const 4) + ) + ) + (i32.store + (get_local $9) + (i32.add + (i32.load + (get_local $9) + ) + (i32.const 4) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE + (get_local $0) + (get_local $13) + ) + ) + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.eqz + (tee_local $6 + (i32.load + (get_local $2) + ) + ) + ) + ) + (set_local $5 + (i32.load offset=12 + (get_local $13) + ) + ) + (set_local $7 + (get_local $4) + ) + (loop $label$8 + (block $label$9 + (block $label$10 + (br_if $label$10 + (i32.ge_s + (get_local $5) + (tee_local $12 + (i32.load offset=16 + (get_local $6) + ) + ) + ) + ) + (set_local $7 + (get_local $6) + ) + (br_if $label$9 + (tee_local $12 + (i32.load + (get_local $6) + ) + ) + ) + (br $label$6) + ) + (br_if $label$5 + (i32.ge_s + (get_local $12) + (get_local $5) + ) + ) + (set_local $7 + (i32.add + (get_local $6) + (i32.const 4) + ) + ) + (br_if $label$5 + (i32.eqz + (tee_local $12 + (i32.load offset=4 + (get_local $6) + ) + ) + ) + ) + ) + (set_local $6 + (get_local $12) + ) + (br $label$8) + ) + ) + (set_local $6 + (get_local $2) + ) + (br_if $label$3 + (i32.load + (tee_local $7 + (get_local $2) + ) + ) + ) + (br $label$4) + ) + (set_local $7 + (get_local $6) + ) + ) + (br_if $label$3 + (i32.load + (get_local $7) + ) + ) + ) + (i32.store offset=16 + (tee_local $12 + (call $_Znwj + (i32.const 32) + ) + ) + (i32.load offset=12 + (get_local $13) + ) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 28) + ) + (i32.load + (get_local $8) + ) + ) + (i32.store + (i32.add + (get_local $12) + (i32.const 24) + ) + (i32.load offset=4 + (get_local $13) + ) + ) + (i32.store offset=20 + (get_local $12) + (i32.load + (get_local $13) + ) + ) + (i32.store + (get_local $13) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $13) + (i32.const 0) + ) + (i32.store + (get_local $8) + (i32.const 0) + ) + (i32.store + (get_local $12) + (i32.const 0) + ) + (i32.store offset=4 + (get_local $12) + (i32.const 0) + ) + (i32.store offset=8 + (get_local $12) + (get_local $6) + ) + (i32.store + (get_local $7) + (get_local $12) + ) + (block $label$11 + (br_if $label$11 + (i32.eqz + (tee_local $6 + (i32.load + (i32.load + (get_local $1) + ) + ) + ) + ) + ) + (i32.store + (get_local $1) + (get_local $6) + ) + (set_local $12 + (i32.load + (get_local $7) + ) + ) + ) + (call $_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_ + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (get_local $12) + ) + (i32.store + (tee_local $6 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (i32.add + (i32.load + (get_local $6) + ) + (i32.const 1) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (i32.and + (i32.load8_u + (get_local $13) + ) + (i32.const 1) + ) + ) + ) + (call $_ZdlPv + (i32.load + (get_local $8) + ) + ) + ) + (br_if $label$1 + (i32.eq + (tee_local $11 + (i32.add + (get_local $11) + (i32.const 1) + ) + ) + (get_local $3) + ) + ) + (set_local $6 + (i32.load + (get_local $9) + ) + ) + (br $label$2) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $13) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiolsINS_10datastreamIPcEEiEERT_S5_RKNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (local $8 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $8 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (set_local $6 + (i64.extend_u/i32 + (i32.shr_s + (i32.sub + (i32.load offset=4 + (get_local $1) + ) + (i32.load + (get_local $1) + ) + ) + (i32.const 2) + ) + ) + ) + (set_local $7 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (set_local $2 + (i32.wrap/i64 + (get_local $6) + ) + ) + (i32.store8 offset=15 + (get_local $8) + (i32.or + (i32.shl + (tee_local $3 + (i64.ne + (tee_local $6 + (i64.shr_u + (get_local $6) + (i64.const 7) + ) + ) + (i64.const 0) + ) + ) + (i32.const 7) + ) + (i32.and + (get_local $2) + (i32.const 127) + ) + ) + ) + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $7) + ) + (i32.const 0) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (get_local $5) + ) + (i32.add + (get_local $8) + (i32.const 15) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $5) + (tee_local $7 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 1) + ) + ) + ) + (br_if $label$0 + (get_local $3) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.eq + (tee_local $5 + (i32.load + (get_local $1) + ) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$2 + (call $eosio_assert + (i32.gt_s + (i32.sub + (i32.load + (get_local $4) + ) + (get_local $7) + ) + (i32.const 3) + ) + (i32.const 1424) + ) + (drop + (call $memcpy + (i32.load + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (get_local $5) + (i32.const 4) + ) + ) + (i32.store + (get_local $2) + (tee_local $7 + (i32.add + (i32.load + (get_local $2) + ) + (i32.const 4) + ) + ) + ) + (br_if $label$2 + (i32.ne + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 4) + ) + ) + ) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $8) + (i32.const 16) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPcEEiEERT_S5_RNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.const 848) + ) + (set_local $4 + (i32.load8_u + (tee_local $5 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $7 + (i32.and + (get_local $7) + (i32.const 255) + ) + ) + ) + ) + (get_local $6) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.le_u + (tee_local $5 + (i32.wrap/i64 + (get_local $6) + ) + ) + (tee_local $7 + (i32.shr_s + (i32.sub + (tee_local $3 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + ) + (i32.const 2) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIiNS_9allocatorIiEEE8__appendEj + (get_local $1) + (i32.sub + (get_local $5) + (get_local $7) + ) + ) + (br_if $label$2 + (i32.ne + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + (tee_local $3 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + ) + (br $label$1) + ) + (block $label$4 + (br_if $label$4 + (i32.ge_u + (get_local $5) + (get_local $7) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (tee_local $3 + (i32.add + (get_local $4) + (i32.shl + (get_local $5) + (i32.const 2) + ) + ) + ) + ) + ) + (br_if $label$1 + (i32.eq + (get_local $4) + (get_local $3) + ) + ) + ) + (set_local $7 + (i32.load + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$5 + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (get_local $2) + ) + (get_local $7) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $4) + (i32.load + (get_local $5) + ) + (i32.const 4) + ) + ) + (i32.store + (get_local $5) + (tee_local $7 + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 4) + ) + ) + ) + (br_if $label$5 + (i32.ne + (get_local $3) + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 4) + ) + ) + ) + ) + ) + ) + (get_local $0) + ) + (func $_ZNSt3__16vectorIiNS_9allocatorIiEEE8__appendEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (i32.shr_s + (i32.sub + (tee_local $7 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $2 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (i32.const 2) + ) + (get_local $1) + ) + ) + (br_if $label$2 + (i32.ge_u + (tee_local $2 + (i32.add + (tee_local $4 + (i32.shr_s + (i32.sub + (get_local $2) + (tee_local $3 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 2) + ) + ) + (get_local $1) + ) + ) + (i32.const 1073741824) + ) + ) + (set_local $6 + (i32.const 1073741823) + ) + (block $label$5 + (br_if $label$5 + (i32.gt_u + (i32.shr_s + (tee_local $7 + (i32.sub + (get_local $7) + (get_local $3) + ) + ) + (i32.const 2) + ) + (i32.const 536870910) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $6 + (select + (get_local $2) + (tee_local $6 + (i32.shr_s + (get_local $7) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $6) + (get_local $2) + ) + ) + ) + ) + ) + (br_if $label$1 + (i32.ge_u + (get_local $6) + (i32.const 1073741824) + ) + ) + ) + (set_local $7 + (call $_Znwj + (i32.shl + (get_local $6) + (i32.const 2) + ) + ) + ) + (br $label$0) + ) + (set_local $6 + (get_local $2) + ) + (set_local $7 + (get_local $1) + ) + (loop $label$6 + (i32.store + (get_local $6) + (i32.const 0) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 4) + ) + ) + (br_if $label$6 + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.add + (get_local $2) + (i32.shl + (get_local $1) + (i32.const 2) + ) + ) + ) + (return) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $7 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (call $abort) + (unreachable) + ) + (set_local $3 + (i32.add + (get_local $7) + (i32.shl + (get_local $6) + (i32.const 2) + ) + ) + ) + (set_local $6 + (tee_local $2 + (i32.add + (get_local $7) + (i32.shl + (get_local $4) + (i32.const 2) + ) + ) + ) + ) + (set_local $7 + (get_local $1) + ) + (loop $label$7 + (i32.store + (get_local $6) + (i32.const 0) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 4) + ) + ) + (br_if $label$7 + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -1) + ) + ) + ) + ) + (set_local $4 + (i32.add + (get_local $2) + (i32.shl + (get_local $1) + (i32.const 2) + ) + ) + ) + (set_local $1 + (i32.sub + (get_local $2) + (tee_local $7 + (i32.sub + (i32.load + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + ) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.lt_s + (get_local $7) + (i32.const 1) + ) + ) + (drop + (call $memcpy + (get_local $1) + (get_local $6) + (get_local $7) + ) + ) + (set_local $6 + (i32.load + (get_local $0) + ) + ) + ) + (i32.store + (get_local $0) + (get_local $1) + ) + (i32.store + (get_local $5) + (get_local $4) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $3) + ) + (block $label$9 + (br_if $label$9 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $6) + ) + ) + ) + (func $apply (param $0 i64) (param $1 i64) (param $2 i64) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i64) + (local $8 i64) + (local $9 i64) + (local $10 i32) + (i32.store offset=4 + (i32.const 0) + (tee_local $10 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 384) + ) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 18944) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i64.gt_u + (get_local $7) + (i64.const 4) + ) + ) + (br_if $label$4 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$3) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$2 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$1) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$0 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (block $label$6 + (block $label$7 + (block $label$8 + (block $label$9 + (br_if $label$9 + (i64.ne + (get_local $8) + (get_local $1) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 18960) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$10 + (block $label$11 + (block $label$12 + (block $label$13 + (block $label$14 + (block $label$15 + (br_if $label$15 + (i64.gt_u + (get_local $7) + (i64.const 6) + ) + ) + (br_if $label$14 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$13) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$12 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$11) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$10 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (br_if $label$9 + (i64.ne + (get_local $8) + (get_local $2) + ) + ) + (call $_ZN5eosio18unpack_action_dataINS_7onerrorEEET_v + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + (call $prints + (i32.const 18976) + ) + (set_local $3 + (i32.load + (i32.add + (get_local $10) + (i32.const 52) + ) + ) + ) + (set_local $5 + (i32.load offset=48 + (get_local $10) + ) + ) + (set_local $7 + (call $current_time) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 236) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 240) + ) + (i32.const 0) + ) + (i32.store offset=220 + (get_local $10) + (i32.const 0) + ) + (i32.store8 offset=224 + (get_local $10) + (i32.const 0) + ) + (i32.store offset=228 + (get_local $10) + (i32.const 0) + ) + (i32.store offset=232 + (get_local $10) + (i32.const 0) + ) + (i32.store offset=208 + (get_local $10) + (i32.add + (i32.wrap/i64 + (i64.div_u + (get_local $7) + (i64.const 1000000) + ) + ) + (i32.const 60) + ) + ) + (i32.store offset=244 + (get_local $10) + (i32.const 0) + ) + (i32.store + (tee_local $4 + (i32.add + (get_local $10) + (i32.const 248) + ) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 252) + ) + (i32.const 0) + ) + (i32.store offset=256 + (get_local $10) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 260) + ) + (i32.const 0) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 264) + ) + (i32.const 0) + ) + (i32.store offset=20 + (get_local $10) + (get_local $5) + ) + (i32.store offset=16 + (get_local $10) + (get_local $5) + ) + (i32.store offset=24 + (get_local $10) + (get_local $3) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_18transaction_headerE + (i32.add + (get_local $10) + (i32.const 16) + ) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEENSt3__15tupleIJtNS5_6vectorIcNS5_9allocatorIcEEEEEEEEERT_SD_RNS7_IT0_NS8_ISE_EEEE + (call $_ZN5eosiorsINS_10datastreamIPKcEENS_6actionEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE + (call $_ZN5eosiorsINS_10datastreamIPKcEENS_6actionEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE + (i32.add + (get_local $10) + (i32.const 16) + ) + (i32.add + (get_local $10) + (i32.const 232) + ) + ) + (tee_local $3 + (i32.add + (get_local $10) + (i32.const 244) + ) + ) + ) + (i32.add + (get_local $10) + (i32.const 256) + ) + ) + ) + (br_if $label$8 + (i32.eq + (i32.load + (get_local $4) + ) + (tee_local $5 + (i32.load offset=244 + (get_local $10) + ) + ) + ) + ) + (block $label$16 + (br_if $label$16 + (i64.ne + (i64.load offset=8 + (get_local $5) + ) + (i64.const -8665432478290165179) + ) + ) + (call $_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + ) + (drop + (call $_ZN5eosio11transactionD2Ev + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + ) + (br_if $label$6 + (i32.eqz + (tee_local $5 + (i32.load + (i32.add + (get_local $10) + (i32.const 48) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $10) + (i32.const 52) + ) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + (br $label$6) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 1440) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$17 + (block $label$18 + (block $label$19 + (block $label$20 + (block $label$21 + (block $label$22 + (br_if $label$22 + (i64.gt_u + (get_local $7) + (i64.const 8) + ) + ) + (br_if $label$21 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$20) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$19 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$18) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$17 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (block $label$23 + (br_if $label$23 + (i64.ne + (get_local $8) + (get_local $2) + ) + ) + (call $_ZN11test_action14test_cf_actionEv) + (br $label$6) + ) + (block $label$24 + (block $label$25 + (br_if $label$25 + (i64.eq + (get_local $2) + (i64.const -8665432478235101900) + ) + ) + (br_if $label$7 + (i64.eq + (get_local $2) + (i64.const -696013500020145514) + ) + ) + (br_if $label$24 + (i64.ne + (get_local $2) + (i64.const -696013499845391606) + ) + ) + (br $label$7) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1600) + ) + (br $label$6) + ) + (call $require_auth + (get_local $1) + ) + (block $label$26 + (block $label$27 + (block $label$28 + (block $label$29 + (block $label$30 + (block $label$31 + (block $label$32 + (block $label$33 + (block $label$34 + (block $label$35 + (block $label$36 + (block $label$37 + (block $label$38 + (block $label$39 + (block $label$40 + (block $label$41 + (block $label$42 + (block $label$43 + (block $label$44 + (block $label$45 + (block $label$46 + (block $label$47 + (block $label$48 + (block $label$49 + (block $label$50 + (block $label$51 + (block $label$52 + (block $label$53 + (br_if $label$53 + (i64.gt_s + (get_local $2) + (i64.const -6575469300789510042) + ) + ) + (br_if $label$52 + (i64.gt_s + (get_local $2) + (i64.const -8665432477288202419) + ) + ) + (br_if $label$50 + (i64.gt_s + (get_local $2) + (i64.const -8665432478290165180) + ) + ) + (br_if $label$46 + (i64.gt_s + (get_local $2) + (i64.const -8665432478739662526) + ) + ) + (br_if $label$41 + (i64.eq + (get_local $2) + (i64.const -8665432479170847876) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -8665432478848840241) + ) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 1632) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=208 + (get_local $10) + ) + (call $current_time) + ) + (i32.const 1744) + ) + (br $label$6) + ) + (br_if $label$51 + (i64.gt_s + (get_local $2) + (i64.const -6575469299402901114) + ) + ) + (br_if $label$49 + (i64.le_s + (get_local $2) + (i64.const -6575469300549176619) + ) + ) + (br_if $label$45 + (i64.gt_s + (get_local $2) + (i64.const -6575469299641207703) + ) + ) + (br_if $label$40 + (i64.eq + (get_local $2) + (i64.const -6575469300549176618) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -6575469300234199047) + ) + ) + (call $_ZN22test_compiler_builtins11test_divti3Ev) + (br $label$6) + ) + (br_if $label$48 + (i64.le_s + (get_local $2) + (i64.const -8665432476325739330) + ) + ) + (br_if $label$44 + (i64.gt_s + (get_local $2) + (i64.const -6575469302011795920) + ) + ) + (br_if $label$39 + (i64.eq + (get_local $2) + (i64.const -8665432476325739329) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -6575469302268922734) + ) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (call $__divti3 + (i32.add + (get_local $10) + (i32.const 208) + ) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6544) + ) + (br $label$6) + ) + (br_if $label$47 + (i64.le_s + (get_local $2) + (i64.const -5790280401120060142) + ) + ) + (br_if $label$43 + (i64.gt_s + (get_local $2) + (i64.const -5790280400999598625) + ) + ) + (br_if $label$38 + (i64.eq + (get_local $2) + (i64.const -5790280401120060141) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -5790280401000535180) + ) + ) + (call $_ZN10test_types10types_sizeEv) + (br $label$6) + ) + (br_if $label$42 + (i64.gt_s + (get_local $2) + (i64.const -8665432477679290203) + ) + ) + (br_if $label$37 + (i64.eq + (get_local $2) + (i64.const -8665432478290165179) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -8665432478272688454) + ) + ) + (call $_ZN11test_action18read_action_normalEv) + (br $label$6) + ) + (br_if $label$36 + (i64.eq + (get_local $2) + (i64.const -6575469300789510041) + ) + ) + (br_if $label$35 + (i64.eq + (get_local $2) + (i64.const -6575469300788910535) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -6575469300561148988) + ) + ) + (call $_ZN22test_compiler_builtins11test_modti3Ev) + (br $label$6) + ) + (br_if $label$34 + (i64.eq + (get_local $2) + (i64.const -8665432477288202418) + ) + ) + (br_if $label$33 + (i64.eq + (get_local $2) + (i64.const -8665432477185147987) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -8665432476560123846) + ) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 1632) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=208 + (get_local $10) + ) + (call $publication_time) + ) + (i32.const 1664) + ) + (br $label$6) + ) + (br_if $label$32 + (i64.eq + (get_local $2) + (i64.const -6575469299402901113) + ) + ) + (br_if $label$31 + (i64.eq + (get_local $2) + (i64.const -6575469299349951025) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -6575469299199638822) + ) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (call $__umodti3 + (i32.add + (get_local $10) + (i32.const 208) + ) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7776) + ) + (br $label$6) + ) + (br_if $label$30 + (i64.eq + (get_local $2) + (i64.const -8665432478739662525) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -8665432478353100899) + ) + ) + (drop + (call $read_action_data + (i32.const 0) + (call $action_data_size) + ) + ) + (br $label$6) + ) + (br_if $label$29 + (i64.eq + (get_local $2) + (i64.const -6575469299641207702) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -6575469299640583116) + ) + ) + (call $_ZN22test_compiler_builtins12test_ashlti3Ev) + (br $label$6) + ) + (br_if $label$28 + (i64.eq + (get_local $2) + (i64.const -6575469302011795919) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -6575469301755127924) + ) + ) + (call $_ZN22test_compiler_builtins12test_udivti3Ev) + (br $label$6) + ) + (br_if $label$27 + (i64.eq + (get_local $2) + (i64.const -5790280400999598624) + ) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -5790280398527684980) + ) + ) + (call $_ZN10test_types14string_to_nameEv) + (br $label$6) + ) + (br_if $label$26 + (i64.ne + (get_local $2) + (i64.const -8665432477579625276) + ) + ) + (drop + (call $read_action_data + (i32.const 65534) + (call $action_data_size) + ) + ) + (br $label$6) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (call $eosio_assert + (i32.eq + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 8) + ) + (i32.const 8) + ) + (i32.const 1632) + ) + (call $eosio_assert_code + (i32.const 0) + (i64.load offset=208 + (get_local $10) + ) + ) + (br $label$6) + ) + (call $_ZN22test_compiler_builtins11test_multi3Ev) + (br $label$6) + ) + (call $_ZN11test_action12require_authEv) + (br $label$6) + ) + (call $_ZN10test_types10name_classEv) + (br $label$6) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 1568) + ) + (br $label$6) + ) + (call $_ZN22test_compiler_builtins12test_lshrti3Ev) + (br $label$6) + ) + (call $_ZN22test_compiler_builtins12test_lshlti3Ev) + (br $label$6) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 1600) + ) + (br $label$6) + ) + (call $_ZN11test_action14require_noticeEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (call $__udivti3 + (i32.add + (get_local $10) + (i32.const 208) + ) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6544) + ) + (br $label$6) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (call $__modti3 + (i32.add + (get_local $10) + (i32.const 208) + ) + (i64.const 100) + (i64.const 0) + (i64.const 0) + (i64.const 0) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7776) + ) + (br $label$6) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 8) + ) + ) + (call $eosio_assert + (i64.eq + (i64.load offset=208 + (get_local $10) + ) + (get_local $0) + ) + (i32.const 1696) + ) + (br $label$6) + ) + (call $_ZN22test_compiler_builtins12test_ashrti3Ev) + (br $label$6) + ) + (call $_ZN22test_compiler_builtins12test_umodti3Ev) + (br $label$6) + ) + (call $_ZN10test_types14char_to_symbolEv) + (br $label$6) + ) + (br_if $label$7 + (i64.ne + (get_local $2) + (i64.const -8665432477679290202) + ) + ) + (call $abort) + (unreachable) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_out_of_rangeEv + (get_local $3) + ) + (unreachable) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $9 + (i64.const 59) + ) + (set_local $5 + (i32.const 752) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$54 + (set_local $6 + (i64.const 0) + ) + (block $label$55 + (br_if $label$55 + (i64.gt_u + (get_local $7) + (i64.const 11) + ) + ) + (block $label$56 + (block $label$57 + (br_if $label$57 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$56) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $6 + (i64.shl + (i64.extend_u/i32 + (i32.and + (get_local $3) + (i32.const 31) + ) + ) + (i64.and + (get_local $9) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $6) + (get_local $8) + ) + ) + (br_if $label$54 + (i64.ne + (tee_local $9 + (i64.add + (get_local $9) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (block $label$58 + (br_if $label$58 + (i64.ne + (get_local $8) + (get_local $2) + ) + ) + (call $_ZN11test_action17test_dummy_actionEv) + (br $label$6) + ) + (block $label$59 + (block $label$60 + (block $label$61 + (block $label$62 + (block $label$63 + (block $label$64 + (block $label$65 + (block $label$66 + (block $label$67 + (block $label$68 + (block $label$69 + (block $label$70 + (block $label$71 + (block $label$72 + (block $label$73 + (block $label$74 + (block $label$75 + (block $label$76 + (block $label$77 + (block $label$78 + (block $label$79 + (block $label$80 + (block $label$81 + (block $label$82 + (block $label$83 + (block $label$84 + (block $label$85 + (block $label$86 + (block $label$87 + (block $label$88 + (block $label$89 + (block $label$90 + (block $label$91 + (block $label$92 + (block $label$93 + (block $label$94 + (block $label$95 + (block $label$96 + (block $label$97 + (block $label$98 + (block $label$99 + (block $label$100 + (block $label$101 + (block $label$102 + (block $label$103 + (block $label$104 + (block $label$105 + (block $label$106 + (block $label$107 + (block $label$108 + (block $label$109 + (block $label$110 + (block $label$111 + (block $label$112 + (block $label$113 + (block $label$114 + (block $label$115 + (block $label$116 + (block $label$117 + (block $label$118 + (block $label$119 + (block $label$120 + (block $label$121 + (block $label$122 + (block $label$123 + (block $label$124 + (block $label$125 + (block $label$126 + (block $label$127 + (block $label$128 + (block $label$129 + (block $label$130 + (block $label$131 + (block $label$132 + (block $label$133 + (block $label$134 + (block $label$135 + (br_if $label$135 + (i64.le_s + (get_local $2) + (i64.const -5767735918449313230) + ) + ) + (br_if $label$134 + (i64.le_s + (get_local $2) + (i64.const -696013502478964675) + ) + ) + (br_if $label$132 + (i64.gt_s + (get_local $2) + (i64.const -696013501204331988) + ) + ) + (br_if $label$128 + (i64.gt_s + (get_local $2) + (i64.const -696013502015841439) + ) + ) + (br_if $label$120 + (i64.le_s + (get_local $2) + (i64.const -696013502305735711) + ) + ) + (br_if $label$104 + (i64.eq + (get_local $2) + (i64.const -696013502305735710) + ) + ) + (br_if $label$103 + (i64.eq + (get_local $2) + (i64.const -696013502197092929) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013502194763679) + ) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 18400) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$136 + (block $label$137 + (block $label$138 + (block $label$139 + (block $label$140 + (block $label$141 + (br_if $label$141 + (i64.gt_u + (get_local $7) + (i64.const 9) + ) + ) + (br_if $label$140 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$139) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$138 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$137) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$136 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $activate_feature + (get_local $8) + ) + (br $label$6) + ) + (br_if $label$133 + (i64.gt_s + (get_local $2) + (i64.const -7587351443459632866) + ) + ) + (br_if $label$131 + (i64.le_s + (get_local $2) + (i64.const -7587351445379665367) + ) + ) + (br_if $label$127 + (i64.gt_s + (get_local $2) + (i64.const -7587351443887725216) + ) + ) + (br_if $label$119 + (i64.le_s + (get_local $2) + (i64.const -7587351445310893856) + ) + ) + (br_if $label$102 + (i64.eq + (get_local $2) + (i64.const -7587351445310893855) + ) + ) + (br_if $label$101 + (i64.eq + (get_local $2) + (i64.const -7587351445208375855) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351444330131777) + ) + ) + (set_local $3 + (i32.const 0) + ) + (call $sha256 + (i32.const 8960) + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$142 + (loop $label$143 + (br_if $label$142 + (i32.ne + (i32.load8_u + (i32.add + (get_local $5) + (i32.const 9024) + ) + ) + (i32.load8_u + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (get_local $5) + ) + ) + ) + ) + (br_if $label$143 + (i32.le_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 9056) + ) + (br $label$6) + ) + (br_if $label$130 + (i64.le_s + (get_local $2) + (i64.const -4239006003814146663) + ) + ) + (br_if $label$126 + (i64.gt_s + (get_local $2) + (i64.const -696013503128813882) + ) + ) + (br_if $label$118 + (i64.le_s + (get_local $2) + (i64.const -4239006002805448792) + ) + ) + (br_if $label$100 + (i64.eq + (get_local $2) + (i64.const -4239006002805448791) + ) + ) + (br_if $label$99 + (i64.eq + (get_local $2) + (i64.const -696013503327366014) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013503202962952) + ) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $10) + (i64.const -1) + ) + (call $eosio_assert + (i32.ne + (call $cancel_deferred + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (i32.const 0) + ) + (i32.const 18128) + ) + (br $label$6) + ) + (br_if $label$129 + (i64.le_s + (get_local $2) + (i64.const -7078304395291034138) + ) + ) + (br_if $label$125 + (i64.gt_s + (get_local $2) + (i64.const -5767735919218491074) + ) + ) + (br_if $label$117 + (i64.le_s + (get_local $2) + (i64.const -5767735919218491584) + ) + ) + (br_if $label$98 + (i64.eq + (get_local $2) + (i64.const -5767735919218491583) + ) + ) + (br_if $label$97 + (i64.eq + (get_local $2) + (i64.const -5767735919218491512) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -5767735919218491446) + ) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 4611123068473966592) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=40 + (get_local $10) + (i64.const -4611439727822766080) + ) + (i64.store offset=32 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $10) + (i64.const 4605605624503281953) + ) + (i64.store offset=16 + (get_local $10) + (i64.const 1865728291273748996) + ) + (call $printqf + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printqf + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printqf + (i32.add + (get_local $10) + (i32.const 16) + ) + ) + (call $prints + (i32.const 1824) + ) + (br $label$6) + ) + (br_if $label$124 + (i64.gt_s + (get_local $2) + (i64.const -696013500238724021) + ) + ) + (br_if $label$116 + (i64.le_s + (get_local $2) + (i64.const -696013501027893081) + ) + ) + (br_if $label$96 + (i64.eq + (get_local $2) + (i64.const -696013501027893080) + ) + ) + (br_if $label$95 + (i64.eq + (get_local $2) + (i64.const -696013500328286318) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013500268167086) + ) + ) + (i32.store offset=208 + (get_local $10) + (i32.const 0) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 4) + ) + ) + (set_local $5 + (call $transaction_size) + ) + (call $prints + (i32.const 17648) + ) + (call $printui + (i64.extend_u/i32 + (get_local $5) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=208 + (get_local $10) + ) + (call $transaction_size) + ) + (i32.const 17664) + ) + (br $label$6) + ) + (br_if $label$123 + (i64.le_s + (get_local $2) + (i64.const -8022470633028214611) + ) + ) + (br_if $label$115 + (i64.le_s + (get_local $2) + (i64.const -7587351446419414473) + ) + ) + (br_if $label$94 + (i64.eq + (get_local $2) + (i64.const -7587351446419414472) + ) + ) + (br_if $label$93 + (i64.eq + (get_local $2) + (i64.const -7587351446368672234) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351445800925699) + ) + ) + (call $sha512 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha512 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha512 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha512 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha512 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha512 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha512 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha512 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (br_if $label$122 + (i64.le_s + (get_local $2) + (i64.const -4239006005939931649) + ) + ) + (br_if $label$114 + (i64.le_s + (get_local $2) + (i64.const -4239006005058986438) + ) + ) + (br_if $label$92 + (i64.eq + (get_local $2) + (i64.const -4239006005058986437) + ) + ) + (br_if $label$91 + (i64.eq + (get_local $2) + (i64.const -4239006004389140451) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -4239006003864401096) + ) + ) + (call $printi + (i64.const 49995000) + ) + (br $label$6) + ) + (br_if $label$121 + (i64.le_s + (get_local $2) + (i64.const -7587351442891060093) + ) + ) + (br_if $label$113 + (i64.le_s + (get_local $2) + (i64.const -7587351442575377031) + ) + ) + (br_if $label$90 + (i64.eq + (get_local $2) + (i64.const -7587351442575377030) + ) + ) + (br_if $label$89 + (i64.eq + (get_local $2) + (i64.const -7078304397416668495) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7078304396558272662) + ) + ) + (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $eosio_assert + (i64.eq + (call $get_permission_last_used + (i64.load offset=208 + (get_local $10) + ) + (i64.load offset=216 + (get_local $10) + ) + ) + (i64.load offset=224 + (get_local $10) + ) + ) + (i32.const 18464) + ) + (br $label$6) + ) + (br_if $label$112 + (i64.le_s + (get_local $2) + (i64.const -696013501554943132) + ) + ) + (br_if $label$88 + (i64.eq + (get_local $2) + (i64.const -696013501554943131) + ) + ) + (br_if $label$87 + (i64.eq + (get_local $2) + (i64.const -696013501453266856) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013501288626511) + ) + ) + (call $_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv) + (br $label$6) + ) + (br_if $label$111 + (i64.le_s + (get_local $2) + (i64.const -7587351443763769797) + ) + ) + (br_if $label$86 + (i64.eq + (get_local $2) + (i64.const -7587351443763769796) + ) + ) + (br_if $label$85 + (i64.eq + (get_local $2) + (i64.const -7587351443732945056) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351443732941913) + ) + ) + (call $_ZN11test_crypto11test_sha256Ev) + (br $label$6) + ) + (br_if $label$110 + (i64.le_s + (get_local $2) + (i64.const -696013502719373095) + ) + ) + (br_if $label$84 + (i64.eq + (get_local $2) + (i64.const -696013502719373094) + ) + ) + (br_if $label$83 + (i64.eq + (get_local $2) + (i64.const -696013502690195168) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013502688730040) + ) + ) + (call $_ZN16test_transaction22send_transaction_emptyEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (br_if $label$109 + (i64.le_s + (get_local $2) + (i64.const -5767735918831569476) + ) + ) + (br_if $label$82 + (i64.eq + (get_local $2) + (i64.const -5767735918831569475) + ) + ) + (br_if $label$81 + (i64.eq + (get_local $2) + (i64.const -5767735918500807270) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -5767735918449313234) + ) + ) + (call $prints + (i32.const 1776) + ) + (call $prints + (i32.const 0) + ) + (call $prints + (i32.const 1792) + ) + (call $prints + (i32.const 0) + ) + (call $prints + (i32.const 1808) + ) + (call $prints + (i32.const 0) + ) + (br $label$6) + ) + (br_if $label$108 + (i64.le_s + (get_local $2) + (i64.const -696013499845391607) + ) + ) + (br_if $label$80 + (i64.eq + (get_local $2) + (i64.const -696013499845391606) + ) + ) + (br_if $label$79 + (i64.eq + (get_local $2) + (i64.const -696013499608977787) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -187209993639507722) + ) + ) + (call $_ZN15test_datastream10test_basicEv) + (br $label$6) + ) + (br_if $label$107 + (i64.gt_s + (get_local $2) + (i64.const -8022470633505015025) + ) + ) + (br_if $label$78 + (i64.eq + (get_local $2) + (i64.const -8022470634635220200) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -8022470633818130162) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5888) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5952) + ) + (br $label$6) + ) + (br_if $label$106 + (i64.gt_s + (get_local $2) + (i64.const -4239006006334808644) + ) + ) + (br_if $label$77 + (i64.eq + (get_local $2) + (i64.const -5767735918449313229) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -5767735918449313228) + ) + ) + (call $printi + (i64.const 0) + ) + (call $printi + (i64.const 556644) + ) + (call $printi + (i64.const -1) + ) + (br $label$6) + ) + (br_if $label$105 + (i64.gt_s + (get_local $2) + (i64.const -7587351443299599511) + ) + ) + (br_if $label$76 + (i64.eq + (get_local $2) + (i64.const -7587351443459632865) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351443325747446) + ) + ) + (call $ripemd160 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (i32.store8 offset=208 + (get_local $10) + (i32.xor + (i32.load8_u offset=208 + (get_local $10) + ) + (i32.const -1) + ) + ) + (call $assert_ripemd160 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (br $label$6) + ) + (br_if $label$75 + (i64.eq + (get_local $2) + (i64.const -696013502478964674) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013502330537453) + ) + ) + (call $_ZN16test_transaction23send_action_inline_failEv) + (br $label$6) + ) + (br_if $label$74 + (i64.eq + (get_local $2) + (i64.const -7587351445379665366) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351445375451046) + ) + ) + (call $sha256 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha256 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha256 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha256 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha256 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha256 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha256 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha256 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (br_if $label$73 + (i64.eq + (get_local $2) + (i64.const -4239006003814146662) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -4239006002882681946) + ) + ) + (call $ripemd160 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (br_if $label$72 + (i64.eq + (get_local $2) + (i64.const -7078304395291034137) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -5823726059754506790) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 169) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load8_u offset=208 + (get_local $10) + ) + (i32.const 21) + ) + (i32.const 9232) + ) + (set_local $5 + (i32.const 1) + ) + (drop + (call $get_active_producers + (i32.or + (i32.add + (get_local $10) + (i32.const 32) + ) + (i32.const 1) + ) + (i32.const 168) + ) + ) + (loop $label$144 + (call $eosio_assert + (i64.eq + (i64.load align=1 + (i32.add + (i32.add + (get_local $10) + (i32.const 32) + ) + (get_local $5) + ) + ) + (i64.load align=1 + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (get_local $5) + ) + ) + ) + (i32.const 9264) + ) + (br_if $label$144 + (i32.ne + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 8) + ) + ) + (i32.const 169) + ) + ) + (br $label$6) + ) + ) + (br_if $label$71 + (i64.eq + (get_local $2) + (i64.const -696013501204331987) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013501174438164) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=208 + (get_local $10) + ) + (call $tapos_block_prefix) + ) + (i32.const 17536) + ) + (br $label$6) + ) + (br_if $label$70 + (i64.eq + (get_local $2) + (i64.const -8022470633028214610) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -8022470632789685404) + ) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5232) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5312) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5376) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5440) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5504) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5568) + ) + (br $label$6) + ) + (br_if $label$69 + (i64.eq + (get_local $2) + (i64.const -4239006005939931648) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -4239006005769928793) + ) + ) + (call $assert_sha512 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (br_if $label$68 + (i64.eq + (get_local $2) + (i64.const -7587351442891060092) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351442863559481) + ) + ) + (call $_ZN11test_crypto9test_sha1Ev) + (br $label$6) + ) + (br_if $label$67 + (i64.eq + (get_local $2) + (i64.const -696013502015841438) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013501581368598) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 4) + ) + ) + (call $eosio_assert + (i32.eq + (i32.load offset=208 + (get_local $10) + ) + (call $tapos_block_num) + ) + (i32.const 17584) + ) + (br $label$6) + ) + (br_if $label$66 + (i64.eq + (get_local $2) + (i64.const -7587351443887725215) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351443788808834) + ) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 144) + ) + ) + (drop + (call $recover_key + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 66) + ) + (i32.const 66) + (i32.add + (get_local $10) + (i32.const 32) + ) + (i32.const 34) + ) + ) + (set_local $3 + (i32.add + (get_local $10) + (i32.const 240) + ) + ) + (set_local $5 + (i32.const 0) + ) + (loop $label$145 + (block $label$146 + (br_if $label$146 + (i32.eq + (i32.load8_u + (i32.add + (i32.add + (get_local $10) + (i32.const 32) + ) + (get_local $5) + ) + ) + (i32.load8_u + (i32.add + (get_local $3) + (get_local $5) + ) + ) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7808) + ) + ) + (br_if $label$145 + (i32.ne + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 34) + ) + ) + (br $label$6) + ) + ) + (br_if $label$65 + (i64.eq + (get_local $2) + (i64.const -696013503128813881) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013502727104654) + ) + ) + (call $_ZN16test_transaction17send_action_emptyEv) + (br $label$6) + ) + (br_if $label$64 + (i64.eq + (get_local $2) + (i64.const -5767735919218491073) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -5767735918947814449) + ) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $10) + (i64.const 1) + ) + (i64.store offset=40 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=32 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $10) + (i64.const -9223372036854775808) + ) + (i64.store offset=16 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=8 + (get_local $10) + (i64.const -1) + ) + (i64.store + (get_local $10) + (i64.const -87654323456) + ) + (call $printi128 + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printi128 + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printi128 + (i32.add + (get_local $10) + (i32.const 16) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printi128 + (get_local $10) + ) + (call $prints + (i32.const 1824) + ) + (br $label$6) + ) + (br_if $label$63 + (i64.eq + (get_local $2) + (i64.const -696013500238724020) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -696013500020145514) + ) + ) + (drop + (call $memset + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 0) + (i32.const 128) + ) + ) + (drop + (call $get_context_free_data + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 128) + ) + ) + (br $label$6) + ) + (br_if $label$62 + (i64.eq + (get_local $2) + (i64.const -8022470633505015024) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -8022470633369446971) + ) + ) + (call $_ZN15test_fixedpoint13test_divisionEv) + (br $label$6) + ) + (br_if $label$61 + (i64.eq + (get_local $2) + (i64.const -4239006006334808643) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -4239006006118930912) + ) + ) + (call $assert_sha256 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (br_if $label$60 + (i64.eq + (get_local $2) + (i64.const -7587351443299599510) + ) + ) + (br_if $label$59 + (i64.ne + (get_local $2) + (i64.const -7587351442991046735) + ) + ) + (call $sha1 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (i32.store8 offset=208 + (get_local $10) + (i32.xor + (i32.load8_u offset=208 + (get_local $10) + ) + (i32.const -1) + ) + ) + (call $assert_sha1 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (br $label$6) + ) + (call $_ZN16test_transaction16send_transactionEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (call $_ZN16test_transaction19send_cf_action_failEv) + (br $label$6) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 144) + ) + ) + (call $assert_recover_key + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 66) + ) + (i32.const 66) + (i32.add + (get_local $10) + (i32.const 240) + ) + (i32.const 34) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 7776) + ) + (br $label$6) + ) + (call $sha256 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (i32.store8 offset=208 + (get_local $10) + (i32.xor + (i32.load8_u offset=208 + (get_local $10) + ) + (i32.const -1) + ) + ) + (call $assert_sha256 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (br $label$6) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $9 + (i64.const 1) + ) + (set_local $7 + (i64.const 0) + ) + (loop $label$147 + (set_local $6 + (i64.add + (i64.and + (tee_local $8 + (get_local $6) + ) + (i64.const 4294967295) + ) + (get_local $7) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (br_if $label$147 + (i64.ne + (tee_local $9 + (i64.add + (get_local $9) + (i64.const -1) + ) + ) + (i64.const 8446744073709551617) + ) + ) + ) + (call $printi + (i64.shr_s + (i64.shl + (i64.sub + (get_local $8) + (get_local $9) + ) + (i64.const 32) + ) + (i64.const 32) + ) + ) + (br $label$6) + ) + (call $_ZN16test_transaction14send_cf_actionEv) + (br $label$6) + ) + (call $printui + (i64.const 0) + ) + (call $printui + (i64.const 556644) + ) + (call $printui + (i64.const -1) + ) + (br $label$6) + ) + (call $printsf + (f32.const 0.5) + ) + (call $prints + (i32.const 1824) + ) + (call $printsf + (f32.const -3.75) + ) + (call $prints + (i32.const 1824) + ) + (call $printsf + (f32.const 6.666666649834951e-07) + ) + (call $prints + (i32.const 1824) + ) + (br $label$6) + ) + (call $prints + (i32.const 18096) + ) + (br $label$6) + ) + (set_local $7 + (i64.const 0) + ) + (set_local $6 + (i64.const 59) + ) + (set_local $5 + (i32.const 18400) + ) + (set_local $8 + (i64.const 0) + ) + (loop $label$148 + (block $label$149 + (block $label$150 + (block $label$151 + (block $label$152 + (block $label$153 + (br_if $label$153 + (i64.gt_u + (get_local $7) + (i64.const 9) + ) + ) + (br_if $label$152 + (i32.gt_u + (i32.and + (i32.add + (tee_local $3 + (i32.load8_s + (get_local $5) + ) + ) + (i32.const -97) + ) + (i32.const 255) + ) + (i32.const 25) + ) + ) + (set_local $3 + (i32.add + (get_local $3) + (i32.const 165) + ) + ) + (br $label$151) + ) + (set_local $9 + (i64.const 0) + ) + (br_if $label$150 + (i64.le_u + (get_local $7) + (i64.const 11) + ) + ) + (br $label$149) + ) + (set_local $3 + (select + (i32.add + (get_local $3) + (i32.const 208) + ) + (i32.const 0) + (i32.lt_u + (i32.and + (i32.add + (get_local $3) + (i32.const -49) + ) + (i32.const 255) + ) + (i32.const 5) + ) + ) + ) + ) + (set_local $9 + (i64.shr_s + (i64.shl + (i64.extend_u/i32 + (get_local $3) + ) + (i64.const 56) + ) + (i64.const 56) + ) + ) + ) + (set_local $9 + (i64.shl + (i64.and + (get_local $9) + (i64.const 31) + ) + (i64.and + (get_local $6) + (i64.const 4294967295) + ) + ) + ) + ) + (set_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (set_local $7 + (i64.add + (get_local $7) + (i64.const 1) + ) + ) + (set_local $8 + (i64.or + (get_local $9) + (get_local $8) + ) + ) + (br_if $label$148 + (i64.ne + (tee_local $6 + (i64.add + (get_local $6) + (i64.const -5) + ) + ) + (i64.const -6) + ) + ) + ) + (call $eosio_assert + (i32.eqz + (call $is_feature_active + (get_local $8) + ) + ) + (i32.const 18416) + ) + (br $label$6) + ) + (set_local $3 + (i32.const 0) + ) + (call $sha512 + (i32.const 8960) + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$154 + (loop $label$155 + (br_if $label$154 + (i32.ne + (i32.load8_u + (i32.add + (get_local $5) + (i32.const 9072) + ) + ) + (i32.load8_u + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (get_local $5) + ) + ) + ) + ) + (br_if $label$155 + (i32.le_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 63) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 9136) + ) + (br $label$6) + ) + (call $sha512 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (i32.store8 offset=208 + (get_local $10) + (i32.xor + (i32.load8_u offset=208 + (get_local $10) + ) + (i32.const -1) + ) + ) + (call $assert_sha512 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 9200) + ) + (br $label$6) + ) + (call $assert_ripemd160 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (call $sha256 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (call $sha1 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha1 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha1 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha1 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha1 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha1 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $sha1 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_sha1 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $eosio_assert + (i64.eq + (call $get_account_creation_time + (i64.load offset=208 + (get_local $10) + ) + ) + (i64.load offset=224 + (get_local $10) + ) + ) + (i32.const 18512) + ) + (br $label$6) + ) + (call $_ZN16test_transaction21test_read_transactionEv) + (br $label$6) + ) + (call $_ZN16test_transaction11send_actionEv) + (br $label$6) + ) + (call $_ZN11test_crypto14test_ripemd160Ev) + (br $label$6) + ) + (call $_ZN11test_crypto11test_sha512Ev) + (br $label$6) + ) + (call $_ZN16test_transaction17send_action_largeEv) + (br $label$6) + ) + (call $_ZN16test_transaction22send_transaction_largeEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (i32.store16 offset=208 + (get_local $10) + (i32.const 25185) + ) + (call $prints_l + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 2) + ) + (call $prints_l + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 1) + ) + (call $prints_l + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 0) + ) + (call $prints_l + (i32.const 944) + (i32.const 4) + ) + (br $label$6) + ) + (i64.store offset=216 + (get_local $10) + (i64.const -1) + ) + (i64.store offset=208 + (get_local $10) + (i64.const -1) + ) + (i64.store offset=40 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=32 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=24 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=16 + (get_local $10) + (i64.const 87654323456) + ) + (call $printui128 + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printui128 + (i32.add + (get_local $10) + (i32.const 32) + ) + ) + (call $prints + (i32.const 1824) + ) + (call $printui128 + (i32.add + (get_local $10) + (i32.const 16) + ) + ) + (call $prints + (i32.const 1824) + ) + (br $label$6) + ) + (call $_ZN16test_transaction12stateful_apiEv) + (br $label$6) + ) + (call $_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5632) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5696) + ) + (br $label$6) + ) + (call $_ZN10test_print11test_printnEv) + (br $label$6) + ) + (set_local $3 + (i32.const 0) + ) + (call $sha1 + (i32.const 8960) + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$156 + (loop $label$157 + (br_if $label$156 + (i32.ne + (i32.load8_u + (i32.add + (get_local $5) + (i32.const 8976) + ) + ) + (i32.load8_u + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (get_local $5) + ) + ) + ) + ) + (br_if $label$157 + (i32.le_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 9008) + ) + (br $label$6) + ) + (call $_ZN16test_transaction25send_deferred_transactionEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (drop + (call $read_action_data + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 144) + ) + ) + (call $assert_recover_key + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (i32.const 66) + ) + (i32.const 66) + (i32.add + (get_local $10) + (i32.const 240) + ) + (i32.const 34) + ) + (br $label$6) + ) + (call $sha512 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (call $_ZN15test_permission19check_authorizationEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (call $_ZN16test_transaction33send_deferred_transaction_replaceEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6016) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 6160) + ) + (br $label$6) + ) + (call $assert_sha1 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (set_local $3 + (i32.const 0) + ) + (call $ripemd160 + (i32.const 8960) + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (set_local $5 + (i32.const 0) + ) + (block $label$158 + (loop $label$159 + (br_if $label$158 + (i32.ne + (i32.load8_u + (i32.add + (get_local $5) + (i32.const 9152) + ) + ) + (i32.load8_u + (i32.add + (i32.add + (get_local $10) + (i32.const 208) + ) + (get_local $5) + ) + ) + ) + ) + (br_if $label$159 + (i32.le_u + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 31) + ) + ) + ) + (set_local $3 + (i32.const 1) + ) + ) + (call $eosio_assert + (get_local $3) + (i32.const 9184) + ) + (br $label$6) + ) + (call $_ZN16test_transaction19send_action_recurseEv) + (br $label$6) + ) + (call $ripemd160 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_ripemd160 + (i32.const 7840) + (i32.const 3) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $ripemd160 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_ripemd160 + (i32.const 7904) + (i32.const 56) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $ripemd160 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_ripemd160 + (i32.const 8016) + (i32.const 112) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $ripemd160 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (call $assert_ripemd160 + (i32.const 8192) + (i32.const 14) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (i64.store offset=216 + (get_local $10) + (i64.const 0) + ) + (i64.store offset=208 + (get_local $10) + (i64.const -1) + ) + (call $eosio_assert + (i32.eqz + (call $cancel_deferred + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + ) + (i32.const 18160) + ) + (br $label$6) + ) + (call $printdf + (f64.const 0.5) + ) + (call $prints + (i32.const 1824) + ) + (call $printdf + (f64.const -3.75) + ) + (call $prints + (i32.const 1824) + ) + (call $printdf + (f64.const 6.666666666666666e-07) + ) + (call $prints + (i32.const 1824) + ) + (br $label$6) + ) + (call $_ZN16test_transaction18send_action_senderEyyy + (get_local $0) + (get_local $7) + (get_local $7) + ) + (br $label$6) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5760) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5760) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5824) + ) + (call $eosio_assert + (i32.const 1) + (i32.const 5824) + ) + (br $label$6) + ) + (call $sha1 + (call $_Znaj + (i32.const 20000000) + ) + (i32.const 20000000) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (call $sha256 + (i32.const 0) + (i32.const 100) + (i32.add + (get_local $10) + (i32.const 208) + ) + ) + (br $label$6) + ) + (call $eosio_assert + (i32.const 0) + (i32.const 18992) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $10) + (i32.const 384) + ) + ) + ) + (func $_ZN5eosio18unpack_action_dataINS_7onerrorEEET_v (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (set_local $3 + (tee_local $2 + (i32.sub + (i32.load offset=4 + (i32.const 0) + ) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (get_local $2) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.lt_u + (tee_local $1 + (call $action_data_size) + ) + (i32.const 513) + ) + ) + (set_local $2 + (call $malloc + (get_local $1) + ) + ) + (br $label$0) + ) + (i32.store offset=4 + (i32.const 0) + (tee_local $2 + (i32.sub + (get_local $2) + (i32.and + (i32.add + (get_local $1) + (i32.const 15) + ) + (i32.const -16) + ) + ) + ) + ) + ) + (drop + (call $read_action_data + (get_local $2) + (get_local $1) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 24) + ) + (i32.const 0) + ) + (i64.store offset=16 align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store offset=8 + (get_local $3) + (i32.add + (get_local $2) + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (get_local $2) + ) + (call $eosio_assert + (i32.gt_u + (get_local $1) + (i32.const 15) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $0) + (get_local $2) + (i32.const 16) + ) + ) + (i32.store offset=4 + (get_local $3) + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE + (get_local $3) + (i32.add + (get_local $0) + (i32.const 16) + ) + ) + ) + (i32.store offset=4 + (i32.const 0) + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_18transaction_headerE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (i32.load offset=4 + (get_local $0) + ) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $1) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 1) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 2) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $2 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 2) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load offset=8 + (get_local $0) + ) + (get_local $2) + ) + (i32.const 3) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 8) + ) + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + (i32.store offset=4 + (get_local $0) + (tee_local $4 + (i32.add + (i32.load offset=4 + (get_local $0) + ) + (i32.const 4) + ) + ) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $4) + (i32.load + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (i32.const 848) + ) + (set_local $2 + (i32.load8_u + (tee_local $4 + (i32.load + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + ) + ) + (i32.store + (get_local $7) + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $2) + (i32.const 127) + ) + (tee_local $6 + (i32.and + (get_local $6) + (i32.const 255) + ) + ) + ) + ) + (get_local $5) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $2) + (i32.const 7) + ) + ) + ) + (i64.store32 offset=12 + (get_local $1) + (get_local $5) + ) + (call $eosio_assert + (i32.ne + (i32.load + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (get_local $4) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.load + (tee_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (i32.const 1) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $5 + (i64.const 0) + ) + (loop $label$1 + (call $eosio_assert + (i32.lt_u + (get_local $6) + (i32.load + (get_local $3) + ) + ) + (i32.const 848) + ) + (set_local $2 + (i32.load8_u + (tee_local $6 + (i32.load + (get_local $4) + ) + ) + ) + ) + (i32.store + (get_local $4) + (tee_local $6 + (i32.add + (get_local $6) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $2) + (i32.const 127) + ) + (tee_local $7 + (i32.and + (get_local $7) + (i32.const 255) + ) + ) + ) + ) + (get_local $5) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 7) + ) + ) + (br_if $label$1 + (i32.shr_u + (get_local $2) + (i32.const 7) + ) + ) + ) + (i64.store32 offset=20 + (get_local $1) + (get_local $5) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEENS_6actionEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i64) + (local $6 i32) + (local $7 i32) + (set_local $7 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $5 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $7) + (i32.load + (get_local $2) + ) + ) + (i32.const 848) + ) + (set_local $4 + (i32.load8_u + (tee_local $7 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 1) + ) + ) + ) + (set_local $5 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $6 + (i32.and + (get_local $6) + (i32.const 255) + ) + ) + ) + ) + (get_local $5) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.le_u + (tee_local $4 + (i32.wrap/i64 + (get_local $5) + ) + ) + (tee_local $7 + (i32.div_s + (i32.sub + (tee_local $2 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $6 + (i32.load + (get_local $1) + ) + ) + ) + (i32.const 40) + ) + ) + ) + ) + (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE8__appendEj + (get_local $1) + (i32.sub + (get_local $4) + (get_local $7) + ) + ) + (set_local $2 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + (br $label$1) + ) + (br_if $label$1 + (i32.ge_u + (get_local $4) + (get_local $7) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $2) + (tee_local $3 + (i32.add + (get_local $6) + (tee_local $4 + (i32.mul + (get_local $4) + (i32.const 40) + ) + ) + ) + ) + ) + ) + (set_local $6 + (i32.sub + (i32.sub + (i32.const 0) + (get_local $6) + ) + (get_local $4) + ) + ) + (set_local $4 + (i32.add + (get_local $2) + (i32.const -24) + ) + ) + (loop $label$4 + (block $label$5 + (br_if $label$5 + (i32.eqz + (tee_local $7 + (i32.load + (i32.add + (get_local $4) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 16) + ) + (get_local $7) + ) + (call $_ZdlPv + (get_local $7) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.eqz + (tee_local $7 + (i32.load + (get_local $4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 4) + ) + (get_local $7) + ) + (call $_ZdlPv + (get_local $7) + ) + ) + (br_if $label$4 + (i32.ne + (i32.add + (tee_local $4 + (i32.add + (get_local $4) + (i32.const -40) + ) + ) + (get_local $6) + ) + (i32.const -24) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (get_local $3) + ) + (set_local $2 + (get_local $3) + ) + ) + (block $label$7 + (br_if $label$7 + (i32.eq + (tee_local $7 + (i32.load + (get_local $1) + ) + ) + (get_local $2) + ) + ) + (set_local $4 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$8 + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (tee_local $6 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + ) + (i32.load + (get_local $4) + ) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $7) + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (tee_local $3 + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + ) + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (get_local $6) + ) + (get_local $3) + ) + (i32.const 7) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (i32.add + (get_local $7) + (i32.const 8) + ) + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + (i32.store + (get_local $4) + (i32.add + (i32.load + (get_local $4) + ) + (i32.const 8) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE + (call $_ZN5eosiorsINS_10datastreamIPKcEENS_16permission_levelEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE + (get_local $0) + (i32.add + (get_local $7) + (i32.const 16) + ) + ) + (i32.add + (get_local $7) + (i32.const 28) + ) + ) + ) + (br_if $label$8 + (i32.ne + (tee_local $7 + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + (get_local $2) + ) + ) + ) + ) + (get_local $0) + ) + (func $_ZN5eosiorsINS_10datastreamIPKcEENSt3__15tupleIJtNS5_6vectorIcNS5_9allocatorIcEEEEEEEEERT_SD_RNS7_IT0_NS8_ISE_EEEE (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i64) + (local $7 i32) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $6 + (i64.const 0) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$0 + (call $eosio_assert + (i32.lt_u + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.const 848) + ) + (set_local $4 + (i32.load8_u + (tee_local $5 + (i32.load + (get_local $3) + ) + ) + ) + ) + (i32.store + (get_local $3) + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + (set_local $6 + (i64.or + (i64.extend_u/i32 + (i32.shl + (i32.and + (get_local $4) + (i32.const 127) + ) + (tee_local $7 + (i32.and + (get_local $7) + (i32.const 255) + ) + ) + ) + ) + (get_local $6) + ) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 7) + ) + ) + (br_if $label$0 + (i32.shr_u + (get_local $4) + (i32.const 7) + ) + ) + ) + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.le_u + (tee_local $4 + (i32.wrap/i64 + (get_local $6) + ) + ) + (tee_local $5 + (i32.shr_s + (i32.sub + (tee_local $7 + (i32.load offset=4 + (get_local $1) + ) + ) + (tee_local $3 + (i32.load + (get_local $1) + ) + ) + ) + (i32.const 4) + ) + ) + ) + ) + (call $_ZNSt3__16vectorINS_5tupleIJtNS0_IcNS_9allocatorIcEEEEEEENS2_IS5_EEE8__appendEj + (get_local $1) + (i32.sub + (get_local $4) + (get_local $5) + ) + ) + (set_local $7 + (i32.load + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + (br $label$1) + ) + (br_if $label$1 + (i32.ge_u + (get_local $4) + (get_local $5) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.eq + (get_local $7) + (tee_local $2 + (i32.add + (get_local $3) + (tee_local $4 + (i32.shl + (get_local $4) + (i32.const 4) + ) + ) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.sub + (i32.const 0) + (get_local $3) + ) + (get_local $4) + ) + ) + (set_local $4 + (i32.add + (get_local $7) + (i32.const -12) + ) + ) + (loop $label$4 + (block $label$5 + (br_if $label$5 + (i32.eqz + (tee_local $5 + (i32.load + (get_local $4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $4) + (i32.const 4) + ) + (get_local $5) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + (br_if $label$4 + (i32.ne + (i32.add + (tee_local $4 + (i32.add + (get_local $4) + (i32.const -16) + ) + ) + (get_local $3) + ) + (i32.const -12) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $1) + (i32.const 4) + ) + (get_local $2) + ) + (set_local $7 + (get_local $2) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.eq + (tee_local $4 + (i32.load + (get_local $1) + ) + ) + (get_local $7) + ) + ) + (set_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (loop $label$7 + (call $eosio_assert + (i32.gt_u + (i32.sub + (i32.load + (get_local $3) + ) + (i32.load + (tee_local $5 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + ) + (i32.const 1) + ) + (i32.const 800) + ) + (drop + (call $memcpy + (get_local $4) + (i32.load + (get_local $5) + ) + (i32.const 2) + ) + ) + (i32.store + (get_local $5) + (i32.add + (i32.load + (get_local $5) + ) + (i32.const 2) + ) + ) + (drop + (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE + (get_local $0) + (i32.add + (get_local $4) + (i32.const 4) + ) + ) + ) + (br_if $label$7 + (i32.ne + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + (get_local $7) + ) + ) + ) + ) + (get_local $0) + ) + (func $_ZNSt3__16vectorINS_5tupleIJtNS0_IcNS_9allocatorIcEEEEEEENS2_IS5_EEE8__appendEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (i32.shr_s + (i32.sub + (tee_local $8 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $7 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (i32.const 4) + ) + (get_local $1) + ) + ) + (br_if $label$2 + (i32.ge_u + (tee_local $7 + (i32.add + (tee_local $4 + (i32.shr_s + (i32.sub + (get_local $7) + (tee_local $5 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 4) + ) + ) + (get_local $1) + ) + ) + (i32.const 268435456) + ) + ) + (set_local $6 + (i32.const 268435455) + ) + (block $label$5 + (br_if $label$5 + (i32.gt_u + (i32.shr_s + (tee_local $8 + (i32.sub + (get_local $8) + (get_local $5) + ) + ) + (i32.const 4) + ) + (i32.const 134217726) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $6 + (select + (get_local $7) + (tee_local $6 + (i32.shr_s + (get_local $8) + (i32.const 3) + ) + ) + (i32.lt_u + (get_local $6) + (get_local $7) + ) + ) + ) + ) + ) + (br_if $label$1 + (i32.ge_u + (get_local $6) + (i32.const 268435456) + ) + ) + ) + (set_local $8 + (call $_Znwj + (i32.shl + (get_local $6) + (i32.const 4) + ) + ) + ) + (br $label$0) + ) + (set_local $6 + (get_local $7) + ) + (set_local $8 + (get_local $1) + ) + (loop $label$6 + (i32.store16 + (get_local $6) + (i32.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $6) + (i32.const 4) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $6) + (i32.const 12) + ) + (i32.const 0) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (br_if $label$6 + (tee_local $8 + (i32.add + (get_local $8) + (i32.const -1) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (i32.add + (get_local $7) + (i32.shl + (get_local $1) + (i32.const 4) + ) + ) + ) + (return) + ) + (set_local $6 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$0) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (call $abort) + (unreachable) + ) + (set_local $2 + (i32.add + (get_local $8) + (i32.shl + (get_local $6) + (i32.const 4) + ) + ) + ) + (set_local $6 + (tee_local $8 + (i32.add + (get_local $8) + (i32.shl + (get_local $4) + (i32.const 4) + ) + ) + ) + ) + (set_local $7 + (get_local $1) + ) + (loop $label$7 + (i32.store16 + (get_local $6) + (i32.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $6) + (i32.const 4) + ) + (i64.const 0) + ) + (i32.store + (i32.add + (get_local $6) + (i32.const 12) + ) + (i32.const 0) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const 16) + ) + ) + (br_if $label$7 + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -1) + ) + ) + ) + ) + (set_local $3 + (i32.add + (get_local $8) + (i32.shl + (get_local $1) + (i32.const 4) + ) + ) + ) + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.eq + (tee_local $7 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $6 + (i32.load + (get_local $0) + ) + ) + ) + ) + (set_local $4 + (i32.sub + (i32.const 0) + (get_local $6) + ) + ) + (set_local $6 + (i32.add + (get_local $7) + (i32.const -16) + ) + ) + (loop $label$10 + (i32.store16 + (i32.add + (get_local $8) + (i32.const -16) + ) + (i32.load16_u + (get_local $6) + ) + ) + (i64.store align=4 + (tee_local $7 + (i32.add + (get_local $8) + (i32.const -12) + ) + ) + (i64.const 0) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $7) + (i32.load + (tee_local $5 + (i32.add + (get_local $6) + (i32.const 4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $6) + (i32.const 8) + ) + ) + ) + (i32.store + (get_local $1) + (i32.load + (tee_local $7 + (i32.add + (get_local $6) + (i32.const 12) + ) + ) + ) + ) + (i32.store + (get_local $7) + (i32.const 0) + ) + (i64.store align=4 + (get_local $5) + (i64.const 0) + ) + (set_local $8 + (i32.add + (get_local $8) + (i32.const -16) + ) + ) + (br_if $label$10 + (i32.ne + (i32.add + (tee_local $6 + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + (get_local $4) + ) + (i32.const -16) + ) + ) + ) + (set_local $6 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $1 + (i32.load + (get_local $0) + ) + ) + (br $label$8) + ) + (set_local $1 + (get_local $6) + ) + ) + (i32.store + (get_local $0) + (get_local $8) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $3) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $2) + ) + (block $label$11 + (br_if $label$11 + (i32.eq + (get_local $6) + (get_local $1) + ) + ) + (set_local $7 + (i32.sub + (i32.const 0) + (get_local $1) + ) + ) + (set_local $6 + (i32.add + (get_local $6) + (i32.const -12) + ) + ) + (loop $label$12 + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $8 + (i32.load + (get_local $6) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $6) + (i32.const 4) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$12 + (i32.ne + (i32.add + (tee_local $6 + (i32.add + (get_local $6) + (i32.const -16) + ) + ) + (get_local $7) + ) + (i32.const -12) + ) + ) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (get_local $1) + ) + ) + (call $_ZdlPv + (get_local $1) + ) + ) + ) + (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE8__appendEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (i32.div_s + (i32.sub + (tee_local $8 + (i32.load offset=8 + (get_local $0) + ) + ) + (tee_local $7 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (i32.const 40) + ) + (get_local $1) + ) + ) + (br_if $label$2 + (i32.ge_u + (tee_local $6 + (i32.add + (tee_local $5 + (i32.div_s + (i32.sub + (get_local $7) + (tee_local $4 + (i32.load + (get_local $0) + ) + ) + ) + (i32.const 40) + ) + ) + (get_local $1) + ) + ) + (i32.const 107374183) + ) + ) + (set_local $7 + (i32.const 107374182) + ) + (block $label$5 + (br_if $label$5 + (i32.gt_u + (tee_local $8 + (i32.div_s + (i32.sub + (get_local $8) + (get_local $4) + ) + (i32.const 40) + ) + ) + (i32.const 53687090) + ) + ) + (br_if $label$3 + (i32.eqz + (tee_local $7 + (select + (get_local $6) + (tee_local $7 + (i32.shl + (get_local $8) + (i32.const 1) + ) + ) + (i32.lt_u + (get_local $7) + (get_local $6) + ) + ) + ) + ) + ) + ) + (set_local $8 + (call $_Znwj + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (br $label$1) + ) + (set_local $8 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (loop $label$6 + (i64.store + (get_local $7) + (i64.const 0) + ) + (i64.store offset=16 align=4 + (get_local $7) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $7) + (i32.const 24) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $7) + (i32.const 32) + ) + (i64.const 0) + ) + (i32.store + (get_local $8) + (tee_local $7 + (i32.add + (i32.load + (get_local $8) + ) + (i32.const 40) + ) + ) + ) + (br_if $label$6 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + (br $label$0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (set_local $8 + (i32.const 0) + ) + (br $label$1) + ) + (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv + (get_local $0) + ) + (unreachable) + ) + (set_local $2 + (i32.add + (get_local $8) + (i32.mul + (get_local $7) + (i32.const 40) + ) + ) + ) + (set_local $7 + (tee_local $8 + (i32.add + (get_local $8) + (i32.mul + (get_local $5) + (i32.const 40) + ) + ) + ) + ) + (loop $label$7 + (i64.store + (get_local $7) + (i64.const 0) + ) + (i64.store offset=16 align=4 + (get_local $7) + (i64.const 0) + ) + (i64.store + (i32.add + (get_local $7) + (i32.const 8) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $7) + (i32.const 24) + ) + (i64.const 0) + ) + (i64.store align=4 + (i32.add + (get_local $7) + (i32.const 32) + ) + (i64.const 0) + ) + (set_local $7 + (i32.add + (get_local $7) + (i32.const 40) + ) + ) + (br_if $label$7 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -1) + ) + ) + ) + ) + (block $label$8 + (block $label$9 + (br_if $label$9 + (i32.eq + (tee_local $1 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (tee_local $4 + (i32.load + (get_local $0) + ) + ) + ) + ) + (set_local $3 + (i32.sub + (i32.const 0) + (get_local $4) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const -20) + ) + ) + (loop $label$10 + (i64.store + (i32.add + (get_local $8) + (i32.const -32) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const -12) + ) + ) + ) + (i64.store + (i32.add + (get_local $8) + (i32.const -40) + ) + (i64.load + (i32.add + (get_local $1) + (i32.const -20) + ) + ) + ) + (i64.store align=4 + (tee_local $4 + (i32.add + (get_local $8) + (i32.const -24) + ) + ) + (i64.const 0) + ) + (i32.store + (tee_local $5 + (i32.add + (get_local $8) + (i32.const -16) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $4) + (i32.load + (tee_local $6 + (i32.add + (get_local $1) + (i32.const -4) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -20) + ) + (i32.load + (get_local $1) + ) + ) + (i32.store + (get_local $5) + (i32.load + (tee_local $4 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + ) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (i64.store align=4 + (tee_local $4 + (i32.add + (get_local $8) + (i32.const -12) + ) + ) + (i64.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (i32.store + (tee_local $5 + (i32.add + (get_local $8) + (i32.const -4) + ) + ) + (i32.const 0) + ) + (i32.store + (get_local $4) + (i32.load + (tee_local $6 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $8) + (i32.const -8) + ) + (i32.load + (i32.add + (get_local $1) + (i32.const 12) + ) + ) + ) + (i32.store + (get_local $5) + (i32.load + (tee_local $4 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + (i32.store + (get_local $4) + (i32.const 0) + ) + (i64.store align=4 + (get_local $6) + (i64.const 0) + ) + (set_local $8 + (i32.add + (get_local $8) + (i32.const -40) + ) + ) + (br_if $label$10 + (i32.ne + (i32.add + (tee_local $1 + (i32.add + (get_local $1) + (i32.const -40) + ) + ) + (get_local $3) + ) + (i32.const -20) + ) + ) + ) + (set_local $4 + (i32.load + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + ) + (set_local $5 + (i32.load + (get_local $0) + ) + ) + (br $label$8) + ) + (set_local $5 + (get_local $4) + ) + ) + (i32.store + (get_local $0) + (get_local $8) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 4) + ) + (get_local $7) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8) + ) + (get_local $2) + ) + (block $label$11 + (br_if $label$11 + (i32.eq + (get_local $4) + (get_local $5) + ) + ) + (set_local $1 + (i32.sub + (i32.const 0) + (get_local $5) + ) + ) + (set_local $7 + (i32.add + (get_local $4) + (i32.const -24) + ) + ) + (loop $label$12 + (block $label$13 + (br_if $label$13 + (i32.eqz + (tee_local $8 + (i32.load + (i32.add + (get_local $7) + (i32.const 12) + ) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 16) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (tee_local $8 + (i32.load + (get_local $7) + ) + ) + ) + ) + (i32.store + (i32.add + (get_local $7) + (i32.const 4) + ) + (get_local $8) + ) + (call $_ZdlPv + (get_local $8) + ) + ) + (br_if $label$12 + (i32.ne + (i32.add + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -40) + ) + ) + (get_local $1) + ) + (i32.const -24) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (get_local $5) + ) + ) + (call $_ZdlPv + (get_local $5) + ) + ) + ) + (func $_Znwj (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (block $label$0 + (br_if $label$0 + (tee_local $0 + (call $malloc + (tee_local $1 + (select + (get_local $0) + (i32.const 1) + (get_local $0) + ) + ) + ) + ) + ) + (loop $label$1 + (set_local $0 + (i32.const 0) + ) + (br_if $label$0 + (i32.eqz + (tee_local $2 + (i32.load offset=19008 + (i32.const 0) + ) + ) + ) + ) + (call_indirect (type $FUNCSIG$v) + (get_local $2) + ) + (br_if $label$1 + (i32.eqz + (tee_local $0 + (call $malloc + (get_local $1) + ) + ) + ) + ) + ) + ) + (get_local $0) + ) + (func $_Znaj (param $0 i32) (result i32) + (call $_Znwj + (get_local $0) + ) + ) + (func $_ZdlPv (param $0 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $0) + ) + ) + (call $free + (get_local $0) + ) + ) + ) + (func $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv (param $0 i32) + (call $abort) + (unreachable) + ) + (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj (param $0 i32) (param $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (br_if $label$0 + (i32.ge_u + (get_local $1) + (i32.const -16) + ) + ) + (set_local $2 + (i32.const 10) + ) + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.and + (tee_local $5 + (i32.load8_u + (get_local $0) + ) + ) + (i32.const 1) + ) + ) + ) + (set_local $2 + (i32.add + (i32.and + (tee_local $5 + (i32.load + (get_local $0) + ) + ) + (i32.const -2) + ) + (i32.const -1) + ) + ) + ) + (block $label$2 + (block $label$3 + (br_if $label$3 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + (set_local $3 + (i32.shr_u + (i32.and + (get_local $5) + (i32.const 254) + ) + (i32.const 1) + ) + ) + (br $label$2) + ) + (set_local $3 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (set_local $4 + (i32.const 10) + ) + (block $label$4 + (br_if $label$4 + (i32.lt_u + (tee_local $1 + (select + (get_local $3) + (get_local $1) + (i32.gt_u + (get_local $3) + (get_local $1) + ) + ) + ) + (i32.const 11) + ) + ) + (set_local $4 + (i32.add + (i32.and + (i32.add + (get_local $1) + (i32.const 16) + ) + (i32.const -16) + ) + (i32.const -1) + ) + ) + ) + (block $label$5 + (br_if $label$5 + (i32.eq + (get_local $4) + (get_local $2) + ) + ) + (block $label$6 + (block $label$7 + (br_if $label$7 + (i32.ne + (get_local $4) + (i32.const 10) + ) + ) + (set_local $6 + (i32.const 1) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (set_local $7 + (i32.const 0) + ) + (br $label$6) + ) + (set_local $1 + (call $_Znwj + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.gt_u + (get_local $4) + (get_local $2) + ) + ) + (br_if $label$5 + (i32.eqz + (get_local $1) + ) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.and + (tee_local $5 + (i32.load8_u + (get_local $0) + ) + ) + (i32.const 1) + ) + ) + (set_local $7 + (i32.const 1) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $6 + (i32.const 0) + ) + (br $label$6) + ) + (set_local $2 + (i32.load offset=8 + (get_local $0) + ) + ) + (set_local $6 + (i32.const 1) + ) + (set_local $7 + (i32.const 1) + ) + ) + (block $label$10 + (block $label$11 + (br_if $label$11 + (i32.and + (get_local $5) + (i32.const 1) + ) + ) + (set_local $5 + (i32.shr_u + (i32.and + (get_local $5) + (i32.const 254) + ) + (i32.const 1) + ) + ) + (br $label$10) + ) + (set_local $5 + (i32.load offset=4 + (get_local $0) + ) + ) + ) + (block $label$12 + (br_if $label$12 + (i32.eqz + (tee_local $5 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + ) + ) + (drop + (call $memcpy + (get_local $1) + (get_local $2) + (get_local $5) + ) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.eqz + (get_local $6) + ) + ) + (call $_ZdlPv + (get_local $2) + ) + ) + (block $label$14 + (br_if $label$14 + (i32.eqz + (get_local $7) + ) + ) + (i32.store offset=4 + (get_local $0) + (get_local $3) + ) + (i32.store offset=8 + (get_local $0) + (get_local $1) + ) + (i32.store + (get_local $0) + (i32.or + (i32.add + (get_local $4) + (i32.const 1) + ) + (i32.const 1) + ) + ) + (return) + ) + (i32.store8 + (get_local $0) + (i32.shl + (get_local $3) + (i32.const 1) + ) + ) + ) + (return) + ) + (call $abort) + (unreachable) + ) + (func $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv (param $0 i32) + (call $abort) + (unreachable) + ) + (func $_ZNKSt3__120__vector_base_commonILb1EE20__throw_out_of_rangeEv (param $0 i32) + (call $abort) + (unreachable) + ) + (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (i64.store align=4 + (get_local $0) + (i64.const 0) + ) + (i32.store + (tee_local $3 + (i32.add + (get_local $0) + (i32.const 8) + ) + ) + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.and + (i32.load8_u + (get_local $1) + ) + (i32.const 1) + ) + ) + (i64.store align=4 + (get_local $0) + (i64.load align=4 + (get_local $1) + ) + ) + (i32.store + (get_local $3) + (i32.load + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + ) + (return + (get_local $0) + ) + ) + (block $label$1 + (br_if $label$1 + (i32.ge_u + (tee_local $3 + (i32.load offset=4 + (get_local $1) + ) + ) + (i32.const -16) + ) + ) + (set_local $2 + (i32.load offset=8 + (get_local $1) + ) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (get_local $3) + (i32.const 11) + ) + ) + (i32.store8 + (get_local $0) + (i32.shl + (get_local $3) + (i32.const 1) + ) + ) + (set_local $1 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br_if $label$3 + (get_local $3) + ) + (br $label$2) + ) + (set_local $1 + (call $_Znwj + (tee_local $4 + (i32.and + (i32.add + (get_local $3) + (i32.const 16) + ) + (i32.const -16) + ) + ) + ) + ) + (i32.store + (get_local $0) + (i32.or + (get_local $4) + (i32.const 1) + ) + ) + (i32.store offset=8 + (get_local $0) + (get_local $1) + ) + (i32.store offset=4 + (get_local $0) + (get_local $3) + ) + ) + (drop + (call $memcpy + (get_local $1) + (get_local $2) + (get_local $3) + ) + ) + ) + (i32.store8 + (i32.add + (get_local $1) + (get_local $3) + ) + (i32.const 0) + ) + (return + (get_local $0) + ) + ) + (call $abort) + (unreachable) + ) + (func $fabs (param $0 f64) (result f64) + (f64.reinterpret/i64 + (i64.and + (i64.reinterpret/f64 + (get_local $0) + ) + (i64.const 9223372036854775807) + ) + ) + ) + (func $fabsf (param $0 f32) (result f32) + (f32.reinterpret/i32 + (i32.and + (i32.reinterpret/f32 + (get_local $0) + ) + (i32.const 2147483647) + ) + ) + ) + (func $memccpy (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (block $label$0 + (block $label$1 + (block $label$2 + (br_if $label$2 + (i32.eqz + (i32.and + (i32.xor + (get_local $1) + (get_local $0) + ) + (i32.const 3) + ) + ) + ) + (set_local $7 + (get_local $3) + ) + (br $label$1) + ) + (set_local $6 + (i32.ne + (tee_local $7 + (i32.and + (get_local $1) + (i32.const 3) + ) + ) + (i32.const 0) + ) + ) + (block $label$3 + (block $label$4 + (block $label$5 + (block $label$6 + (br_if $label$6 + (i32.eqz + (get_local $3) + ) + ) + (br_if $label$5 + (i32.eqz + (get_local $7) + ) + ) + (set_local $4 + (i32.and + (get_local $2) + (i32.const 255) + ) + ) + (loop $label$7 + (i32.store8 + (get_local $0) + (tee_local $7 + (i32.load8_u + (get_local $1) + ) + ) + ) + (br_if $label$0 + (i32.eq + (get_local $7) + (get_local $4) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $7 + (i32.add + (get_local $3) + (i32.const -1) + ) + ) + (set_local $6 + (i32.ne + (tee_local $5 + (i32.and + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 3) + ) + ) + (i32.const 0) + ) + ) + (br_if $label$4 + (i32.eq + (get_local $3) + (i32.const 1) + ) + ) + (set_local $3 + (get_local $7) + ) + (br_if $label$7 + (get_local $5) + ) + (br $label$4) + ) + ) + (set_local $7 + (get_local $3) + ) + (br_if $label$0 + (get_local $6) + ) + (br $label$3) + ) + (set_local $7 + (get_local $3) + ) + ) + (br_if $label$0 + (get_local $6) + ) + ) + (br_if $label$1 + (i32.lt_u + (get_local $7) + (i32.const 4) + ) + ) + (set_local $6 + (i32.mul + (i32.and + (get_local $2) + (i32.const 255) + ) + (i32.const 16843009) + ) + ) + (loop $label$8 + (br_if $label$1 + (i32.and + (i32.and + (i32.xor + (tee_local $3 + (i32.xor + (tee_local $5 + (i32.load + (get_local $1) + ) + ) + (get_local $6) + ) + ) + (i32.const -1) + ) + (i32.add + (get_local $3) + (i32.const -16843009) + ) + ) + (i32.const -2139062144) + ) + ) + (i32.store + (get_local $0) + (get_local $5) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 4) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 4) + ) + ) + (br_if $label$8 + (i32.gt_u + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -4) + ) + ) + (i32.const 3) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (get_local $7) + ) + ) + (set_local $5 + (i32.and + (get_local $2) + (i32.const 255) + ) + ) + (loop $label$9 + (i32.store8 + (get_local $0) + (tee_local $3 + (i32.load8_u + (get_local $1) + ) + ) + ) + (br_if $label$0 + (i32.eq + (get_local $3) + (get_local $5) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (br_if $label$9 + (tee_local $7 + (i32.add + (get_local $7) + (i32.const -1) + ) + ) + ) + ) + ) + (select + (i32.add + (get_local $0) + (i32.const 1) + ) + (i32.const 0) + (i32.eq + (i32.load8_u + (get_local $1) + ) + (i32.and + (get_local $2) + (i32.const 255) + ) + ) + ) + ) + (func $memcmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (set_local $5 + (i32.const 0) + ) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $2) + ) + ) + (block $label$1 + (loop $label$2 + (br_if $label$1 + (i32.ne + (tee_local $3 + (i32.load8_u + (get_local $0) + ) + ) + (tee_local $4 + (i32.load8_u + (get_local $1) + ) + ) + ) + ) + (set_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (set_local $0 + (i32.add + (get_local $0) + (i32.const 1) + ) + ) + (br_if $label$2 + (tee_local $2 + (i32.add + (get_local $2) + (i32.const -1) + ) + ) + ) + (br $label$0) + ) + ) + (set_local $5 + (i32.sub + (get_local $3) + (get_local $4) + ) + ) + ) + (get_local $5) + ) + (func $strlen (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (set_local $2 + (get_local $0) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.and + (get_local $0) + (i32.const 3) + ) + ) + ) + (set_local $2 + (get_local $0) + ) + (loop $label$2 + (br_if $label$0 + (i32.eqz + (i32.load8_u + (get_local $2) + ) + ) + ) + (br_if $label$2 + (i32.and + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 3) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const -4) + ) + ) + (loop $label$3 + (br_if $label$3 + (i32.eqz + (i32.and + (i32.and + (i32.xor + (tee_local $1 + (i32.load + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + ) + ) + (i32.const -1) + ) + (i32.add + (get_local $1) + (i32.const -16843009) + ) + ) + (i32.const -2139062144) + ) + ) + ) + ) + (br_if $label$0 + (i32.eqz + (i32.and + (get_local $1) + (i32.const 255) + ) + ) + ) + (loop $label$4 + (br_if $label$4 + (i32.load8_u + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + ) + ) + (i32.sub + (get_local $2) + (get_local $0) + ) + ) + (func $malloc (param $0 i32) (result i32) + (call $_ZN5eosio14memory_manager6mallocEm + (i32.const 19012) + (get_local $0) + ) + ) + (func $_ZN5eosio14memory_manager6mallocEm (param $0 i32) (param $1 i32) (result i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (block $label$0 + (br_if $label$0 + (i32.eqz + (get_local $1) + ) + ) + (block $label$1 + (br_if $label$1 + (tee_local $13 + (i32.load offset=8384 + (get_local $0) + ) + ) + ) + (set_local $13 + (i32.const 16) + ) + (i32.store + (i32.add + (get_local $0) + (i32.const 8384) + ) + (i32.const 16) + ) + ) + (set_local $2 + (select + (i32.sub + (i32.add + (get_local $1) + (i32.const 8) + ) + (tee_local $2 + (i32.and + (i32.add + (get_local $1) + (i32.const 4) + ) + (i32.const 7) + ) + ) + ) + (get_local $1) + (get_local $2) + ) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (br_if $label$4 + (i32.ge_u + (tee_local $10 + (i32.load offset=8388 + (get_local $0) + ) + ) + (get_local $13) + ) + ) + (set_local $1 + (i32.add + (i32.add + (get_local $0) + (i32.mul + (get_local $10) + (i32.const 12) + ) + ) + (i32.const 8192) + ) + ) + (block $label$5 + (br_if $label$5 + (get_local $10) + ) + (br_if $label$5 + (i32.load + (tee_local $13 + (i32.add + (get_local $0) + (i32.const 8196) + ) + ) + ) + ) + (i32.store + (get_local $1) + (i32.const 8192) + ) + (i32.store + (get_local $13) + (get_local $0) + ) + ) + (set_local $10 + (i32.add + (get_local $2) + (i32.const 4) + ) + ) + (loop $label$6 + (block $label$7 + (br_if $label$7 + (i32.gt_u + (i32.add + (tee_local $13 + (i32.load offset=8 + (get_local $1) + ) + ) + (get_local $10) + ) + (i32.load + (get_local $1) + ) + ) + ) + (i32.store + (tee_local $13 + (i32.add + (i32.load offset=4 + (get_local $1) + ) + (get_local $13) + ) + ) + (i32.or + (i32.and + (i32.load + (get_local $13) + ) + (i32.const -2147483648) + ) + (get_local $2) + ) + ) + (i32.store + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 8) + ) + ) + (i32.add + (i32.load + (get_local $1) + ) + (get_local $10) + ) + ) + (i32.store + (get_local $13) + (i32.or + (i32.load + (get_local $13) + ) + (i32.const -2147483648) + ) + ) + (br_if $label$3 + (tee_local $1 + (i32.add + (get_local $13) + (i32.const 4) + ) + ) + ) + ) + (br_if $label$6 + (tee_local $1 + (call $_ZN5eosio14memory_manager16next_active_heapEv + (get_local $0) + ) + ) + ) + ) + ) + (set_local $4 + (i32.sub + (i32.const 2147483644) + (get_local $2) + ) + ) + (set_local $11 + (i32.add + (get_local $0) + (i32.const 8392) + ) + ) + (set_local $12 + (i32.add + (get_local $0) + (i32.const 8384) + ) + ) + (set_local $13 + (tee_local $3 + (i32.load offset=8392 + (get_local $0) + ) + ) + ) + (loop $label$8 + (call $eosio_assert + (i32.eq + (i32.load + (i32.add + (tee_local $1 + (i32.add + (get_local $0) + (i32.mul + (get_local $13) + (i32.const 12) + ) + ) + ) + (i32.const 8200) + ) + ) + (i32.load + (tee_local $5 + (i32.add + (get_local $1) + (i32.const 8192) + ) + ) + ) + ) + (i32.const 27408) + ) + (set_local $13 + (i32.add + (tee_local $6 + (i32.load + (i32.add + (get_local $1) + (i32.const 8196) + ) + ) + ) + (i32.const 4) + ) + ) + (loop $label$9 + (set_local $7 + (i32.add + (get_local $6) + (i32.load + (get_local $5) + ) + ) + ) + (set_local $1 + (i32.and + (tee_local $9 + (i32.load + (tee_local $8 + (i32.add + (get_local $13) + (i32.const -4) + ) + ) + ) + ) + (i32.const 2147483647) + ) + ) + (block $label$10 + (br_if $label$10 + (i32.lt_s + (get_local $9) + (i32.const 0) + ) + ) + (block $label$11 + (br_if $label$11 + (i32.ge_u + (get_local $1) + (get_local $2) + ) + ) + (loop $label$12 + (br_if $label$11 + (i32.ge_u + (tee_local $10 + (i32.add + (get_local $13) + (get_local $1) + ) + ) + (get_local $7) + ) + ) + (br_if $label$11 + (i32.lt_s + (tee_local $10 + (i32.load + (get_local $10) + ) + ) + (i32.const 0) + ) + ) + (br_if $label$12 + (i32.lt_u + (tee_local $1 + (i32.add + (i32.add + (get_local $1) + (i32.and + (get_local $10) + (i32.const 2147483647) + ) + ) + (i32.const 4) + ) + ) + (get_local $2) + ) + ) + ) + ) + (i32.store + (get_local $8) + (i32.or + (select + (get_local $1) + (get_local $2) + (i32.lt_u + (get_local $1) + (get_local $2) + ) + ) + (i32.and + (get_local $9) + (i32.const -2147483648) + ) + ) + ) + (block $label$13 + (br_if $label$13 + (i32.le_u + (get_local $1) + (get_local $2) + ) + ) + (i32.store + (i32.add + (get_local $13) + (get_local $2) + ) + (i32.and + (i32.add + (get_local $4) + (get_local $1) + ) + (i32.const 2147483647) + ) + ) + ) + (br_if $label$2 + (i32.ge_u + (get_local $1) + (get_local $2) + ) + ) + ) + (br_if $label$9 + (i32.lt_u + (tee_local $13 + (i32.add + (i32.add + (get_local $13) + (get_local $1) + ) + (i32.const 4) + ) + ) + (get_local $7) + ) + ) + ) + (set_local $1 + (i32.const 0) + ) + (i32.store + (get_local $11) + (tee_local $13 + (select + (i32.const 0) + (tee_local $13 + (i32.add + (i32.load + (get_local $11) + ) + (i32.const 1) + ) + ) + (i32.eq + (get_local $13) + (i32.load + (get_local $12) + ) + ) + ) + ) + ) + (br_if $label$8 + (i32.ne + (get_local $13) + (get_local $3) + ) + ) + ) + ) + (return + (get_local $1) + ) + ) + (i32.store + (get_local $8) + (i32.or + (i32.load + (get_local $8) + ) + (i32.const -2147483648) + ) + ) + (return + (get_local $13) + ) + ) + (i32.const 0) + ) + (func $_ZN5eosio14memory_manager16next_active_heapEv (param $0 i32) (result i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (local $4 i32) + (local $5 i32) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (set_local $1 + (i32.load offset=8388 + (get_local $0) + ) + ) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (i32.load8_u offset=27494 + (i32.const 0) + ) + ) + ) + (set_local $7 + (i32.load offset=27496 + (i32.const 0) + ) + ) + (br $label$0) + ) + (set_local $7 + (current_memory) + ) + (i32.store8 offset=27494 + (i32.const 0) + (i32.const 1) + ) + (i32.store offset=27496 + (i32.const 0) + (tee_local $7 + (i32.shl + (get_local $7) + (i32.const 16) + ) + ) + ) + ) + (set_local $3 + (get_local $7) + ) + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + (br_if $label$5 + (i32.le_u + (tee_local $2 + (i32.shr_u + (i32.add + (get_local $7) + (i32.const 65535) + ) + (i32.const 16) + ) + ) + (tee_local $8 + (current_memory) + ) + ) + ) + (drop + (grow_memory + (i32.sub + (get_local $2) + (get_local $8) + ) + ) + ) + (set_local $8 + (i32.const 0) + ) + (br_if $label$4 + (i32.ne + (get_local $2) + (current_memory) + ) + ) + (set_local $3 + (i32.load offset=27496 + (i32.const 0) + ) + ) + ) + (set_local $8 + (i32.const 0) + ) + (i32.store offset=27496 + (i32.const 0) + (get_local $3) + ) + (br_if $label$4 + (i32.lt_s + (get_local $7) + (i32.const 0) + ) + ) + (set_local $2 + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 12) + ) + ) + ) + (set_local $7 + (i32.sub + (i32.sub + (i32.add + (get_local $7) + (select + (i32.const 65536) + (i32.const 131072) + (tee_local $6 + (i32.lt_u + (tee_local $8 + (i32.and + (get_local $7) + (i32.const 65535) + ) + ) + (i32.const 64513) + ) + ) + ) + ) + (select + (get_local $8) + (i32.and + (get_local $7) + (i32.const 131071) + ) + (get_local $6) + ) + ) + (get_local $7) + ) + ) + (block $label$6 + (br_if $label$6 + (i32.load8_u offset=27494 + (i32.const 0) + ) + ) + (set_local $3 + (current_memory) + ) + (i32.store8 offset=27494 + (i32.const 0) + (i32.const 1) + ) + (i32.store offset=27496 + (i32.const 0) + (tee_local $3 + (i32.shl + (get_local $3) + (i32.const 16) + ) + ) + ) + ) + (set_local $2 + (i32.add + (get_local $2) + (i32.const 8192) + ) + ) + (br_if $label$3 + (i32.lt_s + (get_local $7) + (i32.const 0) + ) + ) + (set_local $6 + (get_local $3) + ) + (block $label$7 + (br_if $label$7 + (i32.le_u + (tee_local $8 + (i32.shr_u + (i32.add + (i32.add + (tee_local $5 + (i32.and + (i32.add + (get_local $7) + (i32.const 7) + ) + (i32.const -8) + ) + ) + (get_local $3) + ) + (i32.const 65535) + ) + (i32.const 16) + ) + ) + (tee_local $4 + (current_memory) + ) + ) + ) + (drop + (grow_memory + (i32.sub + (get_local $8) + (get_local $4) + ) + ) + ) + (br_if $label$3 + (i32.ne + (get_local $8) + (current_memory) + ) + ) + (set_local $6 + (i32.load offset=27496 + (i32.const 0) + ) + ) + ) + (i32.store offset=27496 + (i32.const 0) + (i32.add + (get_local $6) + (get_local $5) + ) + ) + (br_if $label$3 + (i32.eq + (get_local $3) + (i32.const -1) + ) + ) + (br_if $label$2 + (i32.eq + (i32.add + (tee_local $6 + (i32.load + (i32.add + (tee_local $1 + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 12) + ) + ) + ) + (i32.const 8196) + ) + ) + ) + (tee_local $8 + (i32.load + (get_local $2) + ) + ) + ) + (get_local $3) + ) + ) + (block $label$8 + (br_if $label$8 + (i32.eq + (get_local $8) + (tee_local $1 + (i32.load + (tee_local $5 + (i32.add + (get_local $1) + (i32.const 8200) + ) + ) + ) + ) + ) + ) + (i32.store + (tee_local $6 + (i32.add + (get_local $6) + (get_local $1) + ) + ) + (i32.or + (i32.and + (i32.load + (get_local $6) + ) + (i32.const -2147483648) + ) + (i32.add + (i32.sub + (i32.const -4) + (get_local $1) + ) + (get_local $8) + ) + ) + ) + (i32.store + (get_local $5) + (i32.load + (get_local $2) + ) + ) + (i32.store + (get_local $6) + (i32.and + (i32.load + (get_local $6) + ) + (i32.const 2147483647) + ) + ) + ) + (i32.store + (tee_local $2 + (i32.add + (get_local $0) + (i32.const 8388) + ) + ) + (tee_local $2 + (i32.add + (i32.load + (get_local $2) + ) + (i32.const 1) + ) + ) + ) + (i32.store + (i32.add + (tee_local $0 + (i32.add + (get_local $0) + (i32.mul + (get_local $2) + (i32.const 12) + ) + ) + ) + (i32.const 8196) + ) + (get_local $3) + ) + (i32.store + (tee_local $8 + (i32.add + (get_local $0) + (i32.const 8192) + ) + ) + (get_local $7) + ) + ) + (return + (get_local $8) + ) + ) + (block $label$9 + (br_if $label$9 + (i32.eq + (tee_local $8 + (i32.load + (get_local $2) + ) + ) + (tee_local $7 + (i32.load + (tee_local $1 + (i32.add + (tee_local $3 + (i32.add + (get_local $0) + (i32.mul + (get_local $1) + (i32.const 12) + ) + ) + ) + (i32.const 8200) + ) + ) + ) + ) + ) + ) + (i32.store + (tee_local $3 + (i32.add + (i32.load + (i32.add + (get_local $3) + (i32.const 8196) + ) + ) + (get_local $7) + ) + ) + (i32.or + (i32.and + (i32.load + (get_local $3) + ) + (i32.const -2147483648) + ) + (i32.add + (i32.sub + (i32.const -4) + (get_local $7) + ) + (get_local $8) + ) + ) + ) + (i32.store + (get_local $1) + (i32.load + (get_local $2) + ) + ) + (i32.store + (get_local $3) + (i32.and + (i32.load + (get_local $3) + ) + (i32.const 2147483647) + ) + ) + ) + (i32.store offset=8384 + (get_local $0) + (tee_local $3 + (i32.add + (i32.load + (tee_local $7 + (i32.add + (get_local $0) + (i32.const 8388) + ) + ) + ) + (i32.const 1) + ) + ) + ) + (i32.store + (get_local $7) + (get_local $3) + ) + (return + (i32.const 0) + ) + ) + (i32.store + (get_local $2) + (i32.add + (get_local $8) + (get_local $7) + ) + ) + (get_local $2) + ) + (func $free (param $0 i32) + (local $1 i32) + (local $2 i32) + (local $3 i32) + (block $label$0 + (block $label$1 + (br_if $label$1 + (i32.eqz + (get_local $0) + ) + ) + (br_if $label$1 + (i32.lt_s + (tee_local $2 + (i32.load offset=27396 + (i32.const 0) + ) + ) + (i32.const 1) + ) + ) + (set_local $3 + (i32.const 27204) + ) + (set_local $1 + (i32.add + (i32.mul + (get_local $2) + (i32.const 12) + ) + (i32.const 27204) + ) + ) + (loop $label$2 + (br_if $label$1 + (i32.eqz + (tee_local $2 + (i32.load + (i32.add + (get_local $3) + (i32.const 4) + ) + ) + ) + ) + ) + (block $label$3 + (br_if $label$3 + (i32.gt_u + (i32.add + (get_local $2) + (i32.const 4) + ) + (get_local $0) + ) + ) + (br_if $label$0 + (i32.gt_u + (i32.add + (get_local $2) + (i32.load + (get_local $3) + ) + ) + (get_local $0) + ) + ) + ) + (br_if $label$2 + (i32.lt_u + (tee_local $3 + (i32.add + (get_local $3) + (i32.const 12) + ) + ) + (get_local $1) + ) + ) + ) + ) + (return) + ) + (i32.store + (tee_local $3 + (i32.add + (get_local $0) + (i32.const -4) + ) + ) + (i32.and + (i32.load + (get_local $3) + ) + (i32.const 2147483647) + ) + ) + ) +) From 5ea2383569fadc0b40d6a2bcdb75bbc7e7f88b59 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 29 Jun 2018 17:39:26 -0400 Subject: [PATCH 0392/1048] Delete .gitmodules --- .gitmodules | 0 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 .gitmodules diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index e69de29b..00000000 From 08f99653287c7df2e5e710b69fbab272d86c8ef5 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 29 Jun 2018 18:18:03 -0400 Subject: [PATCH 0393/1048] Create README.md --- README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 README.md diff --git a/README.md b/README.md new file mode 100644 index 00000000..07431c24 --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# eosio.contracts + +## Version : 1.0.0 + +This repo houses the following contracts + * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) + * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) + * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) + * [eosio.sudo](https://github.com/eosio/eosio.contracts/tree/master/eosio.sudo) + +Dependencies: +* [eos v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) + +To build the contracts and the unit tests: +* First, ensure that your __eos__ is compiled to the symbol that you are wanting to target. +* Second, make sure that you have ```sudo make install```ed __eos__. +* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. +* Or, you can run the ```build.sh``` in a given contract folder to only build that contract. + +After build: +* The unit tests executable is placed in the top directory and is named __unit_test__. +* The contracts are built into a _bin/\_ folder in their respective directories. +* Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory. From 736de060af6211b3cc75c07a39cbf19a74fe1e31 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Sun, 1 Jul 2018 23:48:11 -0400 Subject: [PATCH 0394/1048] fixed some things for linux --- build.sh | 14 ++++++++++++-- eosio.msig/build.sh | 1 - eosio.sudo/build.sh | 1 - eosio.system/build.sh | 2 +- eosio.token/build.sh | 9 --------- 5 files changed, 13 insertions(+), 14 deletions(-) diff --git a/build.sh b/build.sh index 72fa222d..19660d86 100755 --- a/build.sh +++ b/build.sh @@ -8,6 +8,7 @@ contracts=( "eosio.token" unamestr=`uname` if [[ "${unamestr}" == 'Darwin' ]]; then PREFIX=/usr/local + BOOST=/usr/local OPENSSL=/usr/local/opt/openssl else PREFIX=~/opt @@ -15,23 +16,32 @@ else OPENSSL=/usr/include/openssl fi +EOSIO_PREFIX=/usr/local + +export BOOST=${BOOST} +export PREFIX=${PREFIX} + ### Build all the contracts for contract in "${contracts[@]}"; do pushd ${contract} &> /dev/null echo "Building ${contract}..." CONTRACT_NAME="${contract}" - ./build.sh ${PREFIX} + ./build.sh popd &> /dev/null done +if [ "$1" == "notests" ]; then + exit 0 +fi + ### Build the unit tests root_dir=`pwd` pushd tests &> /dev/null mkdir -p build pushd build &> /dev/null -cmake -DROOT_DIR="${root_dir}" -DEOSIO_INSTALL_PREFIX="${PREFIX}" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="${PREFIX}" ../ +cmake -DROOT_DIR="${root_dir}" -DEOSIO_INSTALL_PREFIX="${EOSIO_PREFIX}" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="${EOSIO_PREFIX}" -DBOOST_ROOT="${BOOST}" ../ make -j8 cp unit_test ../../ popd &> /dev/null diff --git a/eosio.msig/build.sh b/eosio.msig/build.sh index bce26d68..e3afc3bb 100755 --- a/eosio.msig/build.sh +++ b/eosio.msig/build.sh @@ -1,7 +1,6 @@ #! /bin/bash CONTRACT_NAME="eosio.msig" -PREFIX=$1 mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT diff --git a/eosio.sudo/build.sh b/eosio.sudo/build.sh index c93e09c0..26a779e8 100755 --- a/eosio.sudo/build.sh +++ b/eosio.sudo/build.sh @@ -1,7 +1,6 @@ #! /bin/bash CONTRACT_NAME="eosio.sudo" -PREFIX=$1 mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT diff --git a/eosio.system/build.sh b/eosio.system/build.sh index 7cfc9971..1610ffb6 100755 --- a/eosio.system/build.sh +++ b/eosio.system/build.sh @@ -1,7 +1,7 @@ #! /bin/bash CONTRACT_NAME="eosio.system" -PREFIX=$1 + mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I../eosio.token/include -I${BOOST}" diff --git a/eosio.token/build.sh b/eosio.token/build.sh index fed39289..0eeb3214 100755 --- a/eosio.token/build.sh +++ b/eosio.token/build.sh @@ -3,15 +3,6 @@ CONTRACT_NAME="eosio.token" unamestr=`uname` -if [[ "${unamestr}" == 'Darwin' ]]; then - PREFIX=/usr/local - OPENSSL=/usr/local/opt/openssl -else - PREFIX=~/opt - BOOST=~/opt/boost/include - OPENSSL=/usr/include/openssl -fi - mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I${BOOST}" From 2c40e30933ac5cb9fbd2b72cab719386579e95b7 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 2 Jul 2018 09:27:39 -0400 Subject: [PATCH 0395/1048] Update README.md --- eosio.sudo/README.md | 884 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 877 insertions(+), 7 deletions(-) diff --git a/eosio.sudo/README.md b/eosio.sudo/README.md index 9c6873ca..af1031e0 100644 --- a/eosio.sudo/README.md +++ b/eosio.sudo/README.md @@ -1,16 +1,886 @@ -eosio.sudo --------- +# eosio.sudo -Actions: +## 1. Actions: The naming convention is codeaccount::actionname followed by a list of parameters. -Execute a transaction while bypassing regular authorization checks (requires authorization of eosio.sudo which needs to be a privileged account) -## eosio.sudo::exec executer trx +Execute a transaction while bypassing regular authorization checks (requires authorization of eosio.sudo which needs to be a privileged account). + +### eosio.sudo::exec executer trx - **executer** account executing the transaction - **trx** transaction to execute Deferred transaction RAM usage is billed to 'executer' -Cleos usage example. -TODO: Fill in cleos usage example. +## 2. Installing the eosio.sudo contract + +The eosio.sudo contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.sudo`. + +First, the account `eosio.sudo` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.sudo` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.sudo` account. + +The `eosio.sudo` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. + +This guide will be using cleos to carry out the process. + +### 2.1 Create the eosio.sudo account + +#### 2.1.1 Generate the transaction to create the eosio.sudo account + +The transaction to create the `eosio.sudo` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. + +A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. + +Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. + +First, generate a transaction to capture the necessary actions involved in creating a new account: +``` +$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.sudo EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json +726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.sudo","bytes":51200}} +726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.sudo","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} +$ cat generated_account_creation_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305501000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c660100000001000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c6601000000" + },{ + "account": "eosio", + "name": "buyrambytes", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305500c80000" + },{ + "account": "eosio", + "name": "delegatebw", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` +Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. +The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. + +Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: +``` +$ cat newaccount_payload.json +{ + "creator": "eosio", + "name": "eosio.sudo", + "owner": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": {"actor": "eosio", "permission": "active"}, + "weight": 1 + }], + "waits": [] + }, + "active": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": {"actor": "eosio", "permission": "active"}, + "weight": 1 + }], + "waits": [] + } +} +``` + +Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: +``` +$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json +$ cat generated_newaccount_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.sudo` account privileged: +``` +$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.sudo", "is_priv": 1}' -p eosio > generated_setpriv_trx.json +$ cat generated_setpriv_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setpriv", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "00004d1a03ea305501" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_sudo_account_trx.json) and edit the first three fields so it looks something like the following: +``` +$ cat create_sudo_account_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. + +Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_sudo_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_sudo_account_trx.json. The final result is a create_sudo_account_trx.json file that looks like the following: +``` +$ cat create_sudo_account_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + },{ + "account": "eosio", + "name": "buyrambytes", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305500c80000" + },{ + "account": "eosio", + "name": "delegatebw", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" + },{ + "account": "eosio", + "name": "setpriv", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "00004d1a03ea305501" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The transaction in create_sudo_account_trx.json is now ready to be proposed. + +It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. + +This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. + +In that case, create a file producer_permissions.json with the content shown in the command below: +``` +$ cat producer_permissions.json +[ + {"actor": "blkproducera", "permission": "active"}, + {"actor": "blkproducerb", "permission": "active"}, + {"actor": "blkproducerc", "permission": "active"}, + {"actor": "blkproducerd", "permission": "active"}, + {"actor": "blkproducere", "permission": "active"}, + {"actor": "blkproducerf", "permission": "active"}, + {"actor": "blkproducerg", "permission": "active"}, + {"actor": "blkproducerh", "permission": "active"}, + {"actor": "blkproduceri", "permission": "active"}, + {"actor": "blkproducerj", "permission": "active"}, + {"actor": "blkproducerk", "permission": "active"}, + {"actor": "blkproducerl", "permission": "active"}, + {"actor": "blkproducerm", "permission": "active"}, + {"actor": "blkproducern", "permission": "active"}, + {"actor": "blkproducero", "permission": "active"}, + {"actor": "blkproducerp", "permission": "active"}, + {"actor": "blkproducerq", "permission": "active"}, + {"actor": "blkproducerr", "permission": "active"}, + {"actor": "blkproducers", "permission": "active"}, + {"actor": "blkproducert", "permission": "active"}, + {"actor": "blkproduceru", "permission": "active"} +] +``` + +#### 2.1.2 Propose the transaction to create the eosio.sudo account + +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_sudo_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. + +The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). + +The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. + +The lead block producer (`blkproducera`) should propose the transaction stored in create_sudo_account_trx.json: +``` +$ cleos multisig propose_trx createsudo producer_permissions.json create_sudo_account_trx.json blkproducera +executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createsudo","requested":[{"actor":"blkproducera","permis... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.1.3 Review and approve the transaction to create the eosio.sudo account + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. + +The proposed transaction can be reviewed using the `cleos multisig review` command: +``` +$ cleos multisig review blkproducera createsudo > create_sudo_account_trx_to_review.json +$ head -n 30 create_sudo_account_trx_to_review.json +{ + "proposal_name": "createsudo", + "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "creator": "eosio", + "name": "eosio.sudo", + "owner": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": { + "actor": "eosio", + "permission": "active" + }, +``` + +The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: +``` +$ cleos multisig propose_trx -j -s -d createsudo '[]' create_sudo_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_sudo_trx_serialized.hex +$ cat expected_create_sudo_trx_serialized.hex +c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 +$ cat create_sudo_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_sudo_trx_serialized.hex +$ cat proposed_create_sudo_trx_serialized.hex +c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 +$ diff expected_create_sudo_trx_serialized.hex proposed_create_sudo_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera createsudo '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createsudo","level":{"actor":"blkproducerb","permission"... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.1.4 Execute the transaction to create the eosio.sudo account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera createsudo blkproducera +executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createsudo","executer":"blkproducera"} +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +Anyone can now verify that the `eosio.sudo` was created: +``` +$ cleos get account eosio.sudo +privileged: true +permissions: + owner 1: 1 eosio@active, + active 1: 1 eosio@active, +memory: + quota: 49.74 KiB used: 3.33 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 us + available: 460.8 ms + limit: 460.8 ms + +producers: + +``` + +### 2.2 Deploy the eosio.sudo contract + +#### 2.2.1 Generate the transaction to deploy the eosio.sudo contract + +The transaction to deploy the contract to the `eosio.sudo` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. + +The easy way to generate this transaction is using cleos: +``` +$ cleos set contract -s -j -d eosio.sudo contracts/eosio.sudo/ > deploy_sudo_contract_trx.json +Reading WAST/WASM from contracts/eosio.sudo/eosio.sudo.wasm... +Using already assembled WASM... +Publishing contract... +$ cat deploy_sudo_contract_trx.json +{ + "expiration": "2018-06-29T19:55:26", + "ref_block_num": 18544, + "ref_block_prefix": 562790588, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio.sudo", + "permission": "active" + } + ], + "data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + },{ + "account": "eosio", + "name": "setabi", + "authorization": [{ + "actor": "eosio.sudo", + "permission": "active" + } + ], + "data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_sudo_contract_trx.json the first few lines of it may look something like the following: +``` +$ head -n 9 deploy_sudo_contract_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ +``` + +This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. + +#### 2.2.2 Propose the transaction to deploy the eosio.sudo contract + +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_sudo_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. + +The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). + +This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. + +The lead block producer (`blkproducera`) should propose the transaction stored in deploy_sudo_contract_trx.json: +``` +$ cleos multisig propose_trx deploysudo producer_permissions.json deploy_sudo_contract_trx.json blkproducera +executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploysudo","requested":[{"actor":"blkproducera","permis... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.2.3 Review and approve the transaction to deploy the eosio.sudo contract + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. + +The proposed transaction can be reviewed using the `cleos multisig review` command: +``` +$ cleos multisig review blkproducera deploysudo > deploy_sudo_contract_trx_to_review.json +$ cat deploy_sudo_contract_trx_to_review.json +{ + "proposal_name": "deploysudo", + "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio.sudo", + "permission": "active" + } + ], + "data": { + "account": "eosio.sudo", + "vmtype": 0, + "vmversion": 0, + "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + }, + "hex_data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + },{ + "account": "eosio", + "name": "setabi", + "authorization": [{ + "actor": "eosio.sudo", + "permission": "active" + } + ], + "data": { + "account": "eosio.sudo", + "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + }, + "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + } + ], + "transaction_extensions": [] + } +} +``` + +Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.sudo` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.sudo` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. + +This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_sudo_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: +``` +$ cleos multisig propose_trx -j -s -d deploysudo '[]' deploy_sudo_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_sudo_trx_serialized.hex +$ cat expected_deploy_sudo_trx_serialized.hex | cut -c -50 +c0593f5b00000000000000000000020000000000ea30550000 +$ cat deploy_sudo_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_sudo_trx_serialized.hex +$ cat proposed_deploy_sudo_trx_serialized.hex | cut -c -50 +c0593f5b00000000000000000000020000000000ea30550000 +$ diff expected_deploy_sudo_trx_serialized.hex proposed_deploy_sudo_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera deploysudo '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploysudo","level":{"actor":"blkproducerb","permission"... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.2.4 Execute the transaction to create the eosio.sudo account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera deploysudo blkproducera +executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploysudo","executer":"blkproducera"} +``` + +Anyone can now verify that the `eosio.sudo` contract was deployed correctly. + +``` +$ cleos get code -a retrieved-eosio.sudo.abi eosio.sudo +code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c +saving abi to retrieved-eosio.sudo.abi +$ sha256sum contracts/eosio.sudo/eosio.sudo.wasm +1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.sudo/eosio.sudo.wasm +``` + +If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.sudo.abi, can then be compared to the original ABI of the contract (contracts/eosio.sudo/eosio.sudo.abi) to ensure they are semantically the same. + +## 3. Using the eosio.sudo contract + +### 3.1 Example: Updating owner authority of an arbitrary account + +This example will demonstrate how to use the deployed eosio.sudo contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos sudo exec` sub-command. However, the guide also demonstrates what to do if the `cleos sudo exec` sub-command is not available. + +This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. + +The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: +``` +$ cat producer_permissions.json +[ + {"actor": "blkproducera", "permission": "active"}, + {"actor": "blkproducerb", "permission": "active"}, + {"actor": "blkproducerc", "permission": "active"}, + {"actor": "blkproducerd", "permission": "active"}, + {"actor": "blkproducere", "permission": "active"}, + {"actor": "blkproducerf", "permission": "active"}, + {"actor": "blkproducerg", "permission": "active"}, + {"actor": "blkproducerh", "permission": "active"}, + {"actor": "blkproduceri", "permission": "active"}, + {"actor": "blkproducerj", "permission": "active"}, + {"actor": "blkproducerk", "permission": "active"}, + {"actor": "blkproducerl", "permission": "active"}, + {"actor": "blkproducerm", "permission": "active"}, + {"actor": "blkproducern", "permission": "active"}, + {"actor": "blkproducero", "permission": "active"}, + {"actor": "blkproducerp", "permission": "active"}, + {"actor": "blkproducerq", "permission": "active"}, + {"actor": "blkproducerr", "permission": "active"}, + {"actor": "blkproducers", "permission": "active"}, + {"actor": "blkproducert", "permission": "active"}, + {"actor": "blkproduceru", "permission": "active"} +] +``` + +#### 3.1.1 Generate the transaction to change the owner permission of an account + +The goal of this example is for the block producers to change the owner permission of the account `alice`. + +The initial status of the `alice` account might be: +``` +permissions: + owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV + active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +memory: + quota: 49.74 KiB used: 3.365 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 us + available: 460.8 ms + limit: 460.8 ms + +producers: +``` + +Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. + +The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: +``` +$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json +``` + +Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: +``` +$ cat update_alice_owner_trx.json +{ + "expiration": "1970-01-01T00:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "updateauth", + "authorization": [{ + "actor": "alice", + "permission": "active" + } + ], + "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The next step is to generate the transaction containing the `eosio.sudo::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. + +``` +$ cleos sudo exec -s -j -d blkproducera update_alice_owner_trx.json > sudo_update_alice_owner_trx.json +``` + +Once again modify sudo_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. +``` +$ cat sudo_update_alice_owner_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.sudo", + "name": "exec", + "authorization": [{ + "actor": "blkproducera", + "permission": "active" + },{ + "actor": "eosio.sudo", + "permission": "active" + } + ], + "data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +If the `cleos sudo` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the sudo_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos sudo exec` sub-command method. + +First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: +``` +$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex +$ cat update_alice_owner_trx_serialized.hex +0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 +``` + +Then generate the template for the transaction containing the `eosio.sudo::exec` action: +``` +$ cleos push action -s -j -d eosio.sudo exec '{"executer": "blkproducera", "trx": ""}' > sudo_update_alice_owner_trx.json +$ cat sudo_update_alice_owner_trx.json +{ + "expiration": "2018-06-29T23:34:01", + "ref_block_num": 23708, + "ref_block_prefix": 3605208482, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.sudo", + "name": "exec", + "authorization": [], + "data": "60ae423ad15b613c" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Then modify the transaction in sudo_update_alice_owner_trx.json as follows: + * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; + * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); + * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in sudo_update_alice_owner_trx.json. + + +#### 3.1.2 Propose the transaction to change the owner permission of an account + +The lead block producer (`blkproducera`) should propose the transaction stored in sudo_update_alice_owner_trx.json: +``` +$ cleos multisig propose_trx updatealice producer_permissions.json sudo_update_alice_owner_trx.json blkproducera +executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 3.1.3 Review and approve the transaction to change the owner permission of an account + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. +``` +$ cleos multisig review blkproducera updatealice > sudo_update_alice_owner_trx_to_review.json +$ cat sudo_update_alice_owner_trx_to_review.json +{ + "proposal_name": "updatealice", + "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.sudo", + "name": "exec", + "authorization": [{ + "actor": "blkproducera", + "permission": "active" + },{ + "actor": "eosio.sudo", + "permission": "active" + } + ], + "data": { + "executer": "blkproducera", + "trx": { + "expiration": "1970-01-01T00:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "updateauth", + "authorization": [{ + "actor": "alice", + "permission": "active" + } + ], + "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [] + } + }, + "hex_data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" + } + ], + "transaction_extensions": [] + } +} +``` + +The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.sudo::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. + +Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.sudo` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. + +Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file sudo_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: +``` +$ cleos multisig propose_trx -j -s -d updatealice '[]' sudo_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_sudo_update_alice_owner_trx_serialized.hex +$ cat expected_sudo_update_alice_owner_trx_serialized.hex +c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 +$ cat sudo_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_sudo_update_alice_owner_trx_serialized.hex +$ cat proposed_sudo_update_alice_owner_trx_serialized.hex +c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 +$ diff expected_sudo_update_alice_owner_trx_serialized.hex proposed_sudo_update_alice_owner_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 3.1.4 Execute the transaction to change the owner permission of an account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera updatealice blkproducera +executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +Anyone can now verify that the owner authority of `alice` was successfully changed: +``` +$ cleos get account alice +permissions: + owner 1: 1 eosio@active, + active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +memory: + quota: 49.74 KiB used: 3.348 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 413 us + available: 460.4 ms + limit: 460.8 ms + +producers: + +``` From 6789673ff764b0ab0a0073a886c5c1b75d2dd438 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 3 Jul 2018 13:16:38 -0400 Subject: [PATCH 0396/1048] Fixes for compiling unit tests with non-system compiler --- README.md | 2 +- build.sh | 37 +++++++++++++++++++++++++++- eosio.msig/build.sh | 8 +++---- eosio.sudo/build.sh | 8 +++---- eosio.system/build.sh | 8 +++---- eosio.token/build.sh | 9 ++++--- tests/CMakeLists.txt | 48 ++++++++++++++++++++++++++++++++++--- tests/eosio.token_tests.cpp | 2 +- 8 files changed, 99 insertions(+), 23 deletions(-) diff --git a/README.md b/README.md index 07431c24..53338de1 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ Dependencies: To build the contracts and the unit tests: * First, ensure that your __eos__ is compiled to the symbol that you are wanting to target. * Second, make sure that you have ```sudo make install```ed __eos__. -* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. +* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. If you want to skip building the unit tests, the option ```notests``` can be given to ```build.sh```. * Or, you can run the ```build.sh``` in a given contract folder to only build that contract. After build: diff --git a/build.sh b/build.sh index 19660d86..2c3ec5d8 100755 --- a/build.sh +++ b/build.sh @@ -14,12 +14,47 @@ else PREFIX=~/opt BOOST=~/opt/boost/include OPENSSL=/usr/include/openssl + OS_NAME=$( cat /etc/os-release | grep ^NAME | cut -d'=' -f2 | sed 's/\"//gI' ) + + case "$OS_NAME" in + "Amazon Linux AMI") + CXX_COMPILER=g++ + C_COMPILER=gcc + ;; + "CentOS Linux") + CXX_COMPILER=g++ + C_COMPILER=gcc + ;; + "elementary OS") + CXX_COMPILER=clang++-4.0 + C_COMPILER=clang-4.0 + ;; + "Fedora") + CXX_COMPILER=g++ + C_COMPILER=gcc + ;; + "Linux Mint") + CXX_COMPILER=clang++-4.0 + C_COMPILER=clang-4.0 + ;; + "Ubuntu") + CXX_COMPILER=clang++-4.0 + C_COMPILER=clang-4.0 + ;; + *) + printf "\\n\\tUnsupported Linux Distribution. Exiting now.\\n\\n" + exit 1 + esac fi + +CXX_COMPILER=clang++-4.0 + EOSIO_PREFIX=/usr/local export BOOST=${BOOST} export PREFIX=${PREFIX} +export INSTALL_PREFIX=/usr/local ### Build all the contracts @@ -41,7 +76,7 @@ root_dir=`pwd` pushd tests &> /dev/null mkdir -p build pushd build &> /dev/null -cmake -DROOT_DIR="${root_dir}" -DEOSIO_INSTALL_PREFIX="${EOSIO_PREFIX}" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="${EOSIO_PREFIX}" -DBOOST_ROOT="${BOOST}" ../ +cmake -DCMAKE_CXX_COMPILER="${CXX_COMPILER}" -DROOT_DIR="${root_dir}" -DEOSIO_INSTALL_PREFIX="${EOSIO_PREFIX}" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="${EOSIO_PREFIX}" -DBOOST_ROOT="${BOOST}" ../ make -j8 cp unit_test ../../ popd &> /dev/null diff --git a/eosio.msig/build.sh b/eosio.msig/build.sh index e3afc3bb..13d28a8c 100755 --- a/eosio.msig/build.sh +++ b/eosio.msig/build.sh @@ -4,14 +4,14 @@ CONTRACT_NAME="eosio.msig" mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I./include -I${BOOST}" +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="/usr/local/bin/eosio-s2wasm " -W2W="/usr/local/bin/eosio-wast2wasm " +S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " +W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " ${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc ${LLC} -o ${CONTRACT_NAME}.s linked.bc ${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s ${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n diff --git a/eosio.sudo/build.sh b/eosio.sudo/build.sh index 26a779e8..9892f2e8 100755 --- a/eosio.sudo/build.sh +++ b/eosio.sudo/build.sh @@ -4,14 +4,14 @@ CONTRACT_NAME="eosio.sudo" mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I./include -I${BOOST}" +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="/usr/local/bin/eosio-s2wasm " -W2W="/usr/local/bin/eosio-wast2wasm " +S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " +W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " ${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc ${LLC} -o ${CONTRACT_NAME}.s linked.bc ${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s ${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n diff --git a/eosio.system/build.sh b/eosio.system/build.sh index 1610ffb6..f5028c69 100755 --- a/eosio.system/build.sh +++ b/eosio.system/build.sh @@ -4,14 +4,14 @@ CONTRACT_NAME="eosio.system" mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I../eosio.token/include -I${BOOST}" +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I../eosio.token/include -I${BOOST}" LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="/usr/local/bin/eosio-s2wasm " -W2W="/usr/local/bin/eosio-wast2wasm " +S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " +W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " ${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc ${LLC} -o ${CONTRACT_NAME}.s linked.bc ${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s ${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n diff --git a/eosio.token/build.sh b/eosio.token/build.sh index 0eeb3214..7394a451 100755 --- a/eosio.token/build.sh +++ b/eosio.token/build.sh @@ -1,18 +1,17 @@ #! /bin/bash CONTRACT_NAME="eosio.token" -unamestr=`uname` mkdir -p bin/${CONTRACT_NAME} ### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I/usr/local/include/libc++/upstream/include -I/usr/local/include/musl/upstream/include -I/usr/local/include -I${BOOST}" +EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="/usr/local/bin/eosio-s2wasm " -W2W="/usr/local/bin/eosio-wast2wasm " +S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " +W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " ${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc /usr/local/usr/share/eosio/contractsdk/lib/eosiolib.bc /usr/local/usr/share/eosio/contractsdk/lib/libc++.bc /usr/local/usr/share/eosio/contractsdk/lib/libc.bc +${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc ${LLC} -o ${CONTRACT_NAME}.s linked.bc ${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s ${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 06efce9f..a1256102 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,4 +1,10 @@ -#file(GLOB COMMON_SOURCES "common/*.cpp") +cmake_minimum_required( VERSION 3.5 ) +project( EOSIO_CONTRACTS_TESTS ) +set( VERSION_MAJOR 1 ) +set( VERSION_MINOR 0 ) +set( VERSION_PATCH 6 ) + +enable_testing() find_package( Gperftools QUIET ) if( GPERFTOOLS_FOUND ) @@ -11,9 +17,26 @@ find_package(LLVM 4.0 REQUIRED CONFIG) link_directories(${LLVM_LIBRARY_DIR}) set( CMAKE_CXX_STANDARD 14 ) +set( CMAKE_CXX_EXTENSIONS ON ) +set( CXX_STANDARD_REQUIRED ON ) + +if ( APPLE ) + set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-deprecated-declarations" ) +else ( APPLE ) + set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") + set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") +endif ( APPLE ) +set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_SOURCE_DIR}/contracts.hpp) -find_package(Boost 1.67 REQUIRED COMPONENTS date_time filesystem system chrono iostreams date_time) +find_package(Boost 1.67 REQUIRED COMPONENTS + date_time + filesystem + system + chrono + iostreams + date_time + unit_test_framework) file(GLOB UNIT_TESTS "*.cpp") @@ -35,7 +58,25 @@ find_library(libbuiltins builtins ${EOSIO_INSTALL_PREFIX}/lib) find_library(libsecp256k1 secp256k1 ${SECP256K1_INSTALL_LIB}) add_executable( unit_test ${UNIT_TESTS} ) -target_link_libraries( unit_test ${LLVM} ${libchain} ${libtester} ${libfc} ${libir} ${libplatform} ${libbinaryen} ${libwast} ${libwasm} ${libruntime} ${libsoftfloat} ${liboscrypto} ${libosssl} ${liblogging} ${libchainbase} ${libbuiltins} ${libsecp256k1} ${PLATFORM_SPECIFIC_LIBS} +target_link_libraries( unit_test + ${LLVM} + ${libchain} + ${libfc} + ${libbinaryen} + ${libwast} + ${libwasm} + ${libruntime} + ${libplatform} + ${libir} + ${libsoftfloat} + ${liboscrypto} + ${libosssl} + ${liblogging} + ${libchainbase} + ${libbuiltins} + ${libsecp256k1} + ${libtester} + LLVMX86Disassembler LLVMX86AsmParser LLVMX86AsmPrinter @@ -66,6 +107,7 @@ target_link_libraries( unit_test ${LLVM} ${libchain} ${libtester} ${libfc} ${lib ${Boost_CHRONO_LIBRARY} ${Boost_IOSTREAMS_LIBRARY} ${Boost_DATE_TIME_LIBRARY} + ${PLATFORM_SPECIFIC_LIBS} ) target_include_directories( unit_test PUBLIC diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 1c85d7fe..0fcc7b62 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -3,7 +3,7 @@ #include #include "eosio.system_tester.hpp" -#include +#include "Runtime/Runtime.h" #include From 925e68dca79ca47abcef2818dcb327afc4b77474 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 3 Jul 2018 15:36:51 -0400 Subject: [PATCH 0397/1048] fix mistake in eosio.sudo contract fix mistake in eosio.sudo contract from @moskvanaft's review of #4429 --- eosio.sudo/src/eosio.sudo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.sudo/src/eosio.sudo.cpp b/eosio.sudo/src/eosio.sudo.cpp index 10e50193..c64ffa75 100644 --- a/eosio.sudo/src/eosio.sudo.cpp +++ b/eosio.sudo/src/eosio.sudo.cpp @@ -29,7 +29,7 @@ void sudo::exec() { require_auth( executer ); size_t trx_pos = ds.tellp(); - send_deferred( (uint128_t(executer) << 64) | current_time(), executer, buffer+trx_pos, size ); + send_deferred( (uint128_t(executer) << 64) | current_time(), executer, buffer+trx_pos, size-trx_pos ); } } /// namespace eosio From ae744899d423cda33af1cd167d703a2afa9f85da Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Tue, 3 Jul 2018 16:46:19 -0400 Subject: [PATCH 0398/1048] minor edits to README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 53338de1..6becd296 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,8 @@ ## Version : 1.0.0 +This is a collection of contracts offered as examples for various systems which are useful when depoying, managing, and/or using an EOSIO blockchain. They are provided for educational purposes. + This repo houses the following contracts * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) @@ -12,7 +14,7 @@ Dependencies: * [eos v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) To build the contracts and the unit tests: -* First, ensure that your __eos__ is compiled to the symbol that you are wanting to target. +* First, ensure that your __eos__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. * Second, make sure that you have ```sudo make install```ed __eos__. * Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. If you want to skip building the unit tests, the option ```notests``` can be given to ```build.sh```. * Or, you can run the ```build.sh``` in a given contract folder to only build that contract. From 13198e94d41e70fa63c92e5e4219a7d1b1b4294b Mon Sep 17 00:00:00 2001 From: Greg Lee Date: Tue, 3 Jul 2018 17:13:51 -0400 Subject: [PATCH 0399/1048] Added a bit more explanation --- README.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 6becd296..5a7f9a38 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,21 @@ ## Version : 1.0.0 -This is a collection of contracts offered as examples for various systems which are useful when depoying, managing, and/or using an EOSIO blockchain. They are provided for educational purposes. +The design of the EOSIO blockchain calls for a number of smart contracts that are run at a priviledged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, token transfer, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. + +This repository contains examples of these priviledged contracts that are useful when depoying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: -This repo houses the following contracts * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) * [eosio.sudo](https://github.com/eosio/eosio.contracts/tree/master/eosio.sudo) Dependencies: -* [eos v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) +* [eosio v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) To build the contracts and the unit tests: -* First, ensure that your __eos__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. -* Second, make sure that you have ```sudo make install```ed __eos__. +* First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. +* Second, make sure that you have ```sudo make install```ed __eosio__. * Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. If you want to skip building the unit tests, the option ```notests``` can be given to ```build.sh```. * Or, you can run the ```build.sh``` in a given contract folder to only build that contract. From cd8439d659bf17ab9d1649a9728853f1ebbf4a0b Mon Sep 17 00:00:00 2001 From: Greg Lee Date: Tue, 3 Jul 2018 17:16:25 -0400 Subject: [PATCH 0400/1048] Spelling correction --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5a7f9a38..0c8ab65e 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ ## Version : 1.0.0 -The design of the EOSIO blockchain calls for a number of smart contracts that are run at a priviledged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, token transfer, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. +The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, token transfer, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. This repository contains examples of these priviledged contracts that are useful when depoying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: From 8390189cf1c2bd8cb01af66c16d8769e0e1dadfe Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 4 Jul 2018 08:57:12 -0400 Subject: [PATCH 0401/1048] Update README.md --- README.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0c8ab65e..83a6cb1a 100644 --- a/README.md +++ b/README.md @@ -2,14 +2,17 @@ ## Version : 1.0.0 -The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, token transfer, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. +The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. This repository contains examples of these priviledged contracts that are useful when depoying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) - * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) + * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) * [eosio.sudo](https://github.com/eosio/eosio.contracts/tree/master/eosio.sudo) + +The following unpriviledged contract(s) are also part of the system. + * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: * [eosio v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) From fb633dcd8712a3a0b16345a5271d78cc9417aa3c Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 4 Jul 2018 10:20:50 -0400 Subject: [PATCH 0402/1048] Add setramrate method for gradual increase - this change allows the elected producers to set the ramrate as bytes per block - this will also resync the bancor parameters to current eosio.ram balance plus reduce the volatility of the market maker - added revision field so that future updates to system contract can reference it if necessary. - updated ABI --- eosio.system/abi/eosio.system.abi | 21 ++++++- .../include/eosio.system/eosio.system.hpp | 26 ++++++++- eosio.system/src/delegate_bandwidth.cpp | 5 ++ eosio.system/src/eosio.system.cpp | 57 +++++++++++++++++-- eosio.system/src/producer_pay.cpp | 1 + 5 files changed, 102 insertions(+), 8 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 87937c78..5877b1f1 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -240,7 +240,14 @@ {"name":"max_inline_action_size", "type":"uint32"}, {"name":"max_inline_action_depth", "type":"uint16"}, {"name":"max_authority_depth", "type":"uint16"} - + ] + },{ + "name": "eosio_global_state2", + "fields": [ + {"name":"new_ram_per_block", "type":"uint16"}, + {"name":"last_ram_increase", "type":"block_timestamp"}, + {"name":"last_block_num", "type":"block_timestamp"}, + {"name":"revision", "type":"uint8_t"} ] },{ "name": "eosio_global_state", @@ -294,6 +301,12 @@ "fields": [ {"name":"max_ram_size", "type":"uint64"} ] + },{ + "name": "setramrate", + "base": "", + "fields": [ + {"name":"bytes_per_block", "type":"uint16"} + ] },{ "name": "regproxy", "base": "", @@ -535,6 +548,12 @@ "index_type": "i64", "key_names" : [], "key_types" : [] + },{ + "name": "global2", + "type": "eosio_global_state2", + "index_type": "i64", + "key_names" : [], + "key_types" : [] },{ "name": "voters", "type": "voter_info", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index a33238a1..97c70345 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -61,6 +61,21 @@ namespace eosiosystem { (last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) }; + /** + * Defines new global state parameters added after version 1.0 + */ + struct eosio_global_state2 { + eosio_global_state2(){} + + uint16_t new_ram_per_block = 0; + block_timestamp last_ram_increase; + block_timestamp last_block_num; + uint8_t revision = 0; ///< used to track version updates in the future. + + + EOSLIB_SERIALIZE( eosio_global_state2, (new_ram_per_block)(last_ram_increase)(last_block_num)(revision) ) + }; + struct producer_info { account_name owner; double total_votes = 0; @@ -120,6 +135,7 @@ namespace eosiosystem { > producers_table; typedef eosio::singleton global_state_singleton; + typedef eosio::singleton global_state2_singleton; // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; @@ -127,11 +143,13 @@ namespace eosiosystem { class system_contract : public native { private: - voters_table _voters; - producers_table _producers; - global_state_singleton _global; + voters_table _voters; + producers_table _producers; + global_state_singleton _global; + global_state2_singleton _global2; eosio_global_state _gstate; + eosio_global_state2 _gstate2; rammarket _rammarket; public: @@ -200,6 +218,7 @@ namespace eosiosystem { void unregprod( const account_name producer ); void setram( uint64_t max_ram_size ); + void setramrate( uint16_t bytes_per_block ); void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); @@ -217,6 +236,7 @@ namespace eosiosystem { void bidname( account_name bidder, account_name newname, asset bid ); private: void update_elected_producers( block_timestamp timestamp ); + void update_ram_supply(); // Implementation details: diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 9678c28e..2a9ded4c 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -86,6 +86,7 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { + auto itr = _rammarket.find(S(4,RAMCORE)); auto tmp = *itr; auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); @@ -105,6 +106,8 @@ namespace eosiosystem { void system_contract::buyram( account_name payer, account_name receiver, asset quant ) { require_auth( payer ); + update_ram_supply(); + eosio_assert( quant.amount > 0, "must purchase a positive amount" ); auto fee = quant; @@ -161,6 +164,8 @@ namespace eosiosystem { */ void system_contract::sellram( account_name account, int64_t bytes ) { require_auth( account ); + update_ram_supply(); + eosio_assert( bytes > 0, "cannot sell negative byte" ); user_resources_table userres( _self, account ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index a38a4a4f..4d474984 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -14,10 +14,12 @@ namespace eosiosystem { _voters(_self,_self), _producers(_self,_self), _global(_self,_self), + _global2(_self,_self), _rammarket(_self,_self) { //print( "construct system\n" ); - _gstate = _global.exists() ? _global.get() : get_default_parameters(); + _gstate = _global.exists() ? _global.get() : get_default_parameters(); + _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; auto itr = _rammarket.find(S(4,RAMCORE)); @@ -46,9 +48,8 @@ namespace eosiosystem { system_contract::~system_contract() { - //print( "destruct system\n" ); _global.set( _gstate, _self ); - //eosio_exit(0); + _global2.set( _gstate2, _self ); } void system_contract::setram( uint64_t max_ram_size ) { @@ -70,7 +71,55 @@ namespace eosiosystem { }); _gstate.max_ram_size = max_ram_size; - _global.set( _gstate, _self ); + } + + void system_contract::update_ram_supply() { + if( _gstate2.last_block_num <= _gstate2.last_ram_increase ) return; + + auto itr = _rammarket.find(S(4,RAMCORE)); + auto new_ram = (_gstate2.last_block_num.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; + _gstate.max_ram_size += new_ram; + + /** + * Increase or decrease the amount of ram for sale based upon the change in max + * ram size. + */ + _rammarket.modify( itr, 0, [&]( auto& m ) { + m.base.balance.amount += new_ram; + m.base.weight = 500; + m.quote.weight = 500; + }); + _gstate2.last_ram_increase = _gstate2.last_block_num; + } + + /** + * Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to + * a maximum rate of 3 TB per year. + * + * If update_ram_supply hasn't been called for the most recent block, then new ram will + * be allocated at the old rate up to the present block before switching the rate. + * + * This method will also resync the bancor connector balances + * and weights to the actual CORE_SYMBOL held in the eosio.ram account. + */ + void system_contract::setramrate( uint16_t bytes_per_block ) { + _gstate2.new_ram_per_block = bytes_per_block; + if( _gstate2.last_ram_increase == block_timestamp() ) { + _gstate2.last_ram_increase = _gstate2.last_block_num; + } else { + update_ram_supply(); + } + + auto itr = _rammarket.find(S(4,RAMCORE)); + + /** + * Resync the connector state with the eosio.ram CORE token balance. + */ + _rammarket.modify( itr, 0, [&]( auto& m ) { + m.quote.balance = eosio::token(N(eosio.token)).get_balance(N(eosio.ram),eosio::symbol_type(system_token_symbol).name()); + m.base.weight = 500; /// use a connector weight of 50% which minimizes volatility + m.quote.weight = 500;/// use a connector weight of 50% which minimizes volatility + }); } void system_contract::setparams( const eosio::blockchain_parameters& params ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 5ff9e450..39fe64ef 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -21,6 +21,7 @@ namespace eosiosystem { using namespace eosio; require_auth(N(eosio)); + _gstate2.last_block_num = timestamp; /** until activated stake crosses this threshold no new rewards are paid */ if( _gstate.total_activated_stake < min_activated_stake ) From 323e4e53b19d062d705fdb6d3789a6b5cb6bf8fd Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 4 Jul 2018 10:24:47 -0400 Subject: [PATCH 0403/1048] require auth for setramrate to owner of contract --- eosio.system/src/eosio.system.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 4d474984..1e178e8b 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -103,6 +103,8 @@ namespace eosiosystem { * and weights to the actual CORE_SYMBOL held in the eosio.ram account. */ void system_contract::setramrate( uint16_t bytes_per_block ) { + require_auth( _self ); + _gstate2.new_ram_per_block = bytes_per_block; if( _gstate2.last_ram_increase == block_timestamp() ) { _gstate2.last_ram_increase = _gstate2.last_block_num; From 615eb28a6c5f0c5c59e1e25648621985094d6cb6 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 4 Jul 2018 10:30:28 -0400 Subject: [PATCH 0404/1048] add setramrate to abi --- eosio.system/abi/eosio.system.abi | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 5877b1f1..d2f13573 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -487,6 +487,10 @@ "name": "setram", "type": "setram", "ricardian_contract": "" + },{ + "name": "setramrate", + "type": "setramrate", + "ricardian_contract": "Sets the number of new bytes of ram to create per block and resyncs bancor connector balances and weights to eosio.ram and 50% CRR" },{ "name": "bidname", "type": "bidname", From 1a7f6e694554549d43865a7c1b33208b2ac502b5 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 5 Jul 2018 16:46:56 -0400 Subject: [PATCH 0405/1048] Update build.sh --- build.sh | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index 2c3ec5d8..7fec92e4 100755 --- a/build.sh +++ b/build.sh @@ -8,7 +8,7 @@ contracts=( "eosio.token" unamestr=`uname` if [[ "${unamestr}" == 'Darwin' ]]; then PREFIX=/usr/local - BOOST=/usr/local + BOOST=/usr/local/include OPENSSL=/usr/local/opt/openssl else PREFIX=~/opt @@ -47,14 +47,11 @@ else esac fi - -CXX_COMPILER=clang++-4.0 - -EOSIO_PREFIX=/usr/local +EOSIO_PREFIX=/usr/local/eosio export BOOST=${BOOST} export PREFIX=${PREFIX} -export INSTALL_PREFIX=/usr/local +export INSTALL_PREFIX=/usr/local/eosio ### Build all the contracts From f1c689bd5dd36d397318bce73a09bb47805569fa Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 5 Jul 2018 18:57:20 -0400 Subject: [PATCH 0406/1048] weight change removed --- eosio.system/abi/eosio.system.abi | 6 +++--- eosio.system/src/eosio.system.cpp | 13 ------------- 2 files changed, 3 insertions(+), 16 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index d2f13573..f831ea28 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -245,9 +245,9 @@ "name": "eosio_global_state2", "fields": [ {"name":"new_ram_per_block", "type":"uint16"}, - {"name":"last_ram_increase", "type":"block_timestamp"}, - {"name":"last_block_num", "type":"block_timestamp"}, - {"name":"revision", "type":"uint8_t"} + {"name":"last_ram_increase", "type":"block_timestamp_type"}, + {"name":"last_block_num", "type":"block_timestamp_type"}, + {"name":"revision", "type":"uint8"} ] },{ "name": "eosio_global_state", diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 1e178e8b..f34117b5 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -86,8 +86,6 @@ namespace eosiosystem { */ _rammarket.modify( itr, 0, [&]( auto& m ) { m.base.balance.amount += new_ram; - m.base.weight = 500; - m.quote.weight = 500; }); _gstate2.last_ram_increase = _gstate2.last_block_num; } @@ -111,17 +109,6 @@ namespace eosiosystem { } else { update_ram_supply(); } - - auto itr = _rammarket.find(S(4,RAMCORE)); - - /** - * Resync the connector state with the eosio.ram CORE token balance. - */ - _rammarket.modify( itr, 0, [&]( auto& m ) { - m.quote.balance = eosio::token(N(eosio.token)).get_balance(N(eosio.ram),eosio::symbol_type(system_token_symbol).name()); - m.base.weight = 500; /// use a connector weight of 50% which minimizes volatility - m.quote.weight = 500;/// use a connector weight of 50% which minimizes volatility - }); } void system_contract::setparams( const eosio::blockchain_parameters& params ) { From 1dfbbe0c29ffa8b6d87a1174fb98514ff8721f6e Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 5 Jul 2018 21:11:29 -0400 Subject: [PATCH 0407/1048] New changes --- UnitTestsExternalProject.txt | 15 +++++++ build.sh | 81 ----------------------------------- eosio.msig/CMakeLists.txt | 8 ++++ eosio.sudo/CMakeLists.txt | 8 ++++ eosio.system/CMakeLists.txt | 8 ++++ eosio.token/CMakeLists.txt | 8 ++++ tests/CMakeLists.txt | 2 +- tests/contracts.hpp | 25 +++++++++++ tests/contracts.hpp.in | 24 +++++------ tests/eosio.system_tester.hpp | 2 + 10 files changed, 87 insertions(+), 94 deletions(-) create mode 100644 UnitTestsExternalProject.txt delete mode 100755 build.sh create mode 100644 eosio.msig/CMakeLists.txt create mode 100644 eosio.sudo/CMakeLists.txt create mode 100644 eosio.system/CMakeLists.txt create mode 100644 eosio.token/CMakeLists.txt create mode 100644 tests/contracts.hpp diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt new file mode 100644 index 00000000..5efbdc64 --- /dev/null +++ b/UnitTestsExternalProject.txt @@ -0,0 +1,15 @@ +include(ExternalProject) +find_package(Git REQUIRED) +include(GNUInstallDirs) + +ExternalProject_Add( + contracts_unit_tests + UPDATE_COMMAND "" + PATCH_COMMAND "" + CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eosio -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${Boost_INCLUDE_DIRS}/../ + + SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests + BINARY_DIR ${CMAKE_SOURCE_DIR} + TEST_COMMAND "" + INSTALL_COMMAND "" +) diff --git a/build.sh b/build.sh deleted file mode 100755 index 7fec92e4..00000000 --- a/build.sh +++ /dev/null @@ -1,81 +0,0 @@ -#! /bin/bash - -contracts=( "eosio.token" - "eosio.system" - "eosio.msig" - "eosio.sudo" ) - -unamestr=`uname` -if [[ "${unamestr}" == 'Darwin' ]]; then - PREFIX=/usr/local - BOOST=/usr/local/include - OPENSSL=/usr/local/opt/openssl -else - PREFIX=~/opt - BOOST=~/opt/boost/include - OPENSSL=/usr/include/openssl - OS_NAME=$( cat /etc/os-release | grep ^NAME | cut -d'=' -f2 | sed 's/\"//gI' ) - - case "$OS_NAME" in - "Amazon Linux AMI") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "CentOS Linux") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "elementary OS") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Fedora") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "Linux Mint") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Ubuntu") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - *) - printf "\\n\\tUnsupported Linux Distribution. Exiting now.\\n\\n" - exit 1 - esac -fi - -EOSIO_PREFIX=/usr/local/eosio - -export BOOST=${BOOST} -export PREFIX=${PREFIX} -export INSTALL_PREFIX=/usr/local/eosio - -### Build all the contracts - -for contract in "${contracts[@]}"; do - pushd ${contract} &> /dev/null - echo "Building ${contract}..." - CONTRACT_NAME="${contract}" - ./build.sh - popd &> /dev/null -done - - -if [ "$1" == "notests" ]; then - exit 0 -fi - -### Build the unit tests -root_dir=`pwd` -pushd tests &> /dev/null -mkdir -p build -pushd build &> /dev/null -cmake -DCMAKE_CXX_COMPILER="${CXX_COMPILER}" -DROOT_DIR="${root_dir}" -DEOSIO_INSTALL_PREFIX="${EOSIO_PREFIX}" -DOPENSSL_INSTALL_PREFIX="${OPENSSL}" -DSECP256K1_INSTALL_LIB="${EOSIO_PREFIX}" -DBOOST_ROOT="${BOOST}" ../ -make -j8 -cp unit_test ../../ -popd &> /dev/null -rm -r build -popd &> /dev/null diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt new file mode 100644 index 00000000..9fc45cbc --- /dev/null +++ b/eosio.msig/CMakeLists.txt @@ -0,0 +1,8 @@ +add_executable(eosio.msig.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) +target_include_directories(eosio.msig.wasm + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) +#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) +install(TARGETS eosio.msig.wasm + RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt new file mode 100644 index 00000000..b7a9bf15 --- /dev/null +++ b/eosio.sudo/CMakeLists.txt @@ -0,0 +1,8 @@ +add_executable(eosio.sudo.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) +target_include_directories(eosio.sudo.wasm + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) +#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) +install(TARGETS eosio.sudo.wasm + RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt new file mode 100644 index 00000000..6d84c767 --- /dev/null +++ b/eosio.system/CMakeLists.txt @@ -0,0 +1,8 @@ +add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) +target_include_directories(eosio.system.wasm + PUBLIC + ${CMAKE_SOURCE_DIR}/include) +#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) +install(TARGETS eosio.system.wasm + RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt new file mode 100644 index 00000000..a116f748 --- /dev/null +++ b/eosio.token/CMakeLists.txt @@ -0,0 +1,8 @@ +add_executable(eosio.token.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) +target_include_directories(eosio.token.wasm + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) +#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) +install(TARGETS eosio.token.wasm + RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) +install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a1256102..80e6a413 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -2,7 +2,7 @@ cmake_minimum_required( VERSION 3.5 ) project( EOSIO_CONTRACTS_TESTS ) set( VERSION_MAJOR 1 ) set( VERSION_MINOR 0 ) -set( VERSION_PATCH 6 ) +set( VERSION_PATCH 0 ) enable_testing() diff --git a/tests/contracts.hpp b/tests/contracts.hpp new file mode 100644 index 00000000..ef9cb14d --- /dev/null +++ b/tests/contracts.hpp @@ -0,0 +1,25 @@ +#pragma once +#include + +namespace eosio { namespace testing { + +struct contracts { + static std::vector system_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.system/bin/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.system/bin/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.system/bin/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.token/bin/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.token/bin/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.token/bin/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.msig/bin/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.msig/bin/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.msig/bin/eosio.msig.abi"); } + static std::vector sudo_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.sudo/bin/eosio.sudo.wasm"); } + static std::string sudo_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.sudo/bin/eosio.sudo.wast"); } + static std::vector sudo_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.sudo/bin/eosio.sudo.abi"); } + + struct util { + static std::vector test_api_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/tests/test_contracts/test_api.wasm"); } + static std::vector exchange_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/tests/test_contracts/exchange.wasm"); } + }; +}; +}} //ns eosio::testing diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 1d91f506..93556523 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -4,18 +4,18 @@ namespace eosio { namespace testing { struct contracts { - static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wast"); } - static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.abi"); } - static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.abi"); } - static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wast"); } - static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.abi"); } - static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wasm"); } - static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wast"); } - static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi"); } + static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig.abi"); } + static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo.wasm"); } + static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo.wast"); } + static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo.abi"); } struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index ff90f8d3..cedf3b39 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -4,6 +4,8 @@ */ #pragma once +#define CORE_SYMBOL_NAME "EOS" + #include #include #include "contracts.hpp" From bf5e7795dfe6ddf7d47cb2c0372be9fec1c0a975 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 5 Jul 2018 21:24:06 -0400 Subject: [PATCH 0408/1048] Using eosio.wasmsdk --- CMakeLists.txt | 24 ++++++++++++++++++++++++ UnitTestsExternalProject.txt | 2 +- tests/eosio.system_tester.hpp | 2 -- 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..62558d47 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,24 @@ +cmake_minimum_required(VERSION 3.5) +project(eosio_contracts VERSION 1.0.0) + +# if no wasm root is given use default path +if(WASM_ROOT STREQUAL "" OR NOT WASM_ROOT) + set(WASM_ROOT ${CMAKE_INSTALL_PREFIX}) +endif() + +list(APPEND CMAKE_MODULE_PATH ${WASM_ROOT}/lib/cmake) +include(EosioWasmToolchain) + +add_subdirectory(eosio.msig) +add_subdirectory(eosio.sudo) +add_subdirectory(eosio.system) +add_subdirectory(eosio.token) + +if (APPLE) + set(OPENSSL_ROOT "/usr/local/opt/openssl") +elseif (UNIX) + set(OPENSSL_ROOT "/usr/include/openssl") +endif() +set(SECP256K1_ROOT "/usr/local") + +include(UnitTestsExternalProject.txt) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 5efbdc64..19741145 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -9,7 +9,7 @@ ExternalProject_Add( CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eosio -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${Boost_INCLUDE_DIRS}/../ SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests - BINARY_DIR ${CMAKE_SOURCE_DIR} + BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests TEST_COMMAND "" INSTALL_COMMAND "" ) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index cedf3b39..ff90f8d3 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -4,8 +4,6 @@ */ #pragma once -#define CORE_SYMBOL_NAME "EOS" - #include #include #include "contracts.hpp" From a8d404b138e041995149e01a149b2aee372583a4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 6 Jul 2018 11:02:24 -0400 Subject: [PATCH 0409/1048] Added reserved field to eosio_global_state2 to be used later --- eosio.system/abi/eosio.system.abi | 1 + eosio.system/include/eosio.system/eosio.system.hpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index f831ea28..ccbd1c3e 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -247,6 +247,7 @@ {"name":"new_ram_per_block", "type":"uint16"}, {"name":"last_ram_increase", "type":"block_timestamp_type"}, {"name":"last_block_num", "type":"block_timestamp_type"}, + {"name":"reserved", "type":"float64"}, {"name":"revision", "type":"uint8"} ] },{ diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 97c70345..276a61e7 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -70,10 +70,11 @@ namespace eosiosystem { uint16_t new_ram_per_block = 0; block_timestamp last_ram_increase; block_timestamp last_block_num; + double reserved = 0; uint8_t revision = 0; ///< used to track version updates in the future. - EOSLIB_SERIALIZE( eosio_global_state2, (new_ram_per_block)(last_ram_increase)(last_block_num)(revision) ) + EOSLIB_SERIALIZE( eosio_global_state2, (new_ram_per_block)(last_ram_increase)(last_block_num)(reserved)(revision) ) }; struct producer_info { From 6db6e867a7a6722bdec69de132a7c6fd0c3d4fd0 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 6 Jul 2018 15:47:54 -0400 Subject: [PATCH 0410/1048] eosio.ram payment problem --- eosio.token/abi/eosio.token.abi | 7 ++++ .../include/eosio.token/eosio.token.hpp | 5 ++- eosio.token/src/eosio.token.cpp | 22 ++++++----- tests/eosio.token_tests.cpp | 38 +++++++++++++++++++ 4 files changed, 61 insertions(+), 11 deletions(-) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi index d769deb3..35926470 100644 --- a/eosio.token/abi/eosio.token.abi +++ b/eosio.token/abi/eosio.token.abi @@ -28,6 +28,13 @@ {"name":"quantity", "type":"asset"}, {"name":"memo", "type":"string"} ] + },{ + "name": "close", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"symbol", "type":"symbol"}, + ] },{ "name": "account", "base": "", diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 15875134..1ab0ffa1 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -30,8 +30,9 @@ namespace eosio { account_name to, asset quantity, string memo ); - - + + void close( account_name owner, symbol_name symbol ); + inline asset get_supply( symbol_name sym )const; inline asset get_balance( account_name owner, symbol_name sym )const; diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index d85c2362..8abb8c85 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -79,9 +79,10 @@ void token::transfer( account_name from, eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); + auto payer = has_auth( to ) ? to : from; sub_balance( from, quantity ); - add_balance( to, quantity, from ); + add_balance( to, quantity, payer ); } void token::sub_balance( account_name owner, asset value ) { @@ -90,14 +91,9 @@ void token::sub_balance( account_name owner, asset value ) { const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" ); eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); - - if( from.balance.amount == value.amount ) { - from_acnts.erase( from ); - } else { - from_acnts.modify( from, owner, [&]( auto& a ) { - a.balance -= value; + from_acnts.modify( from, owner, [&]( auto& a ) { + a.balance -= value; }); - } } void token::add_balance( account_name owner, asset value, account_name ram_payer ) @@ -115,6 +111,14 @@ void token::add_balance( account_name owner, asset value, account_name ram_payer } } +void token::close( account_name owner, symbol_name symbol ) { + accounts acnts( _self, owner ); + auto it = acnts.find( symbol ); + eosio_assert( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); + eosio_assert( it->balance.amount == 0, "Cannot close because the balance is not zero." ); + acnts.erase( it ); +} + } /// namespace eosio -EOSIO_ABI( eosio::token, (create)(issue)(transfer) ) +EOSIO_ABI( eosio::token, (create)(issue)(transfer)(close) ) diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 0fcc7b62..a73e47eb 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -92,6 +92,16 @@ class eosio_token_tester : public tester { ); } + action_result close( account_name owner, + const string& symbolname ) { + auto symb = eosio::chain::symbol::from_string(symbolname); + auto symbol_code = symb.to_symbol_code().value; + return push_action( owner, N(close), mvo() + ( "owner", owner ) + ( "symbol", symbol_code.to_string() ) + ); + } + abi_serializer abi_ser; }; @@ -263,4 +273,32 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { } FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( close_tests, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("1000 CERO")); + + auto alice_balance = get_account(N(alice), "0,CERO"); + BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); + + BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("1000 CERO"), "hola" ) ); + + alice_balance = get_account(N(alice), "0,CERO"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "1000 CERO") + ); + + BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("1000 CERO"), "hola" ) ); + + alice_balance = get_account(N(alice), "0,CERO"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "0 CERO") + ); + + BOOST_REQUIRE_EQUAL( success(), close( N(alice), "0,CERO" ) ); + alice_balance = get_account(N(alice), "0,CERO"); + BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() From cdd0827ac0b4f82cba06a4c9b7ec0c960c4beb9b Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 6 Jul 2018 15:49:37 -0400 Subject: [PATCH 0411/1048] Fixed some build location problems --- UnitTestsExternalProject.txt | 3 +- eosio.msig/CMakeLists.txt | 10 +- eosio.msig/bin/eosio.msig/eosio.msig.abi | 152 +++++ eosio.sudo/CMakeLists.txt | 9 +- eosio.sudo/bin/eosio.sudo/eosio.sudo.abi | 73 +++ eosio.system/CMakeLists.txt | 10 +- .../bin/eosio.system/eosio.system.abi | 578 ++++++++++++++++++ eosio.token/CMakeLists.txt | 9 +- eosio.token/bin/eosio.token/eosio.token.abi | 78 +++ tests/contracts.hpp | 25 - tests/contracts.hpp.in | 24 +- tests/eosio.system_tests.cpp | 4 +- 12 files changed, 922 insertions(+), 53 deletions(-) create mode 100644 eosio.msig/bin/eosio.msig/eosio.msig.abi create mode 100644 eosio.sudo/bin/eosio.sudo/eosio.sudo.abi create mode 100644 eosio.system/bin/eosio.system/eosio.system.abi create mode 100644 eosio.token/bin/eosio.token/eosio.token.abi delete mode 100644 tests/contracts.hpp diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 19741145..f05d9ec2 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,12 +4,11 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - UPDATE_COMMAND "" - PATCH_COMMAND "" CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eosio -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${Boost_INCLUDE_DIRS}/../ SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests + BUILD_ALWAYS 1 TEST_COMMAND "" INSTALL_COMMAND "" ) diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index 9fc45cbc..c5dd83e7 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,8 +1,12 @@ +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig" COPYONLY) + add_executable(eosio.msig.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set_target_properties(eosio.msig.wasm + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig") + #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) -install(TARGETS eosio.msig.wasm - RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/eosio.msig/bin/eosio.msig/eosio.msig.abi b/eosio.msig/bin/eosio.msig/eosio.msig.abi new file mode 100644 index 00000000..9fcf8a95 --- /dev/null +++ b/eosio.msig/bin/eosio.msig/eosio.msig.abi @@ -0,0 +1,152 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name": "actor", "type": "account_name"}, + {"name": "permission", "type": "permission_name"} + ] + },{ + "name": "action", + "base": "", + "fields": [ + {"name": "account", "type": "account_name"}, + {"name": "name", "type": "action_name"}, + {"name": "authorization", "type": "permission_level[]"}, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction_header", + "base": "", + "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": "extension", + "base": "", + "fields": [ + {"name": "type", "type" : "uint16" }, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction", + "base": "transaction_header", + "fields": [ + {"name": "context_free_actions", "type": "action[]"}, + {"name": "actions", "type": "action[]"}, + {"name": "transaction_extensions", "type": "extension[]"} + ] + },{ + "name": "propose", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"requested", "type":"permission_level[]"}, + {"name":"trx", "type":"transaction"} + ] + },{ + "name": "approve", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"level", "type":"permission_level"} + ] + },{ + "name": "unapprove", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"level", "type":"permission_level"} + ] + },{ + "name": "cancel", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"canceler", "type":"account_name"} + ] + },{ + "name": "exec", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"executer", "type":"account_name"} + ] + },{ + "name": "proposal", + "base": "", + "fields": [ + {"name": "proposal_name", "type": "name"}, + {"name": "packed_transaction", "type": "bytes"} + ] + },{ + "name": "approvals_info", + "base": "", + "fields": [ + {"name": "proposal_name", "type": "name"}, + {"name": "requested_approvals", "type": "permission_level[]"}, + {"name": "provided_approvals", "type": "permission_level[]"} + ] + } + ], + "actions": [{ + "name": "propose", + "type": "propose", + "ricardian_contract": "" + },{ + "name": "approve", + "type": "approve", + "ricardian_contract": "" + },{ + "name": "unapprove", + "type": "unapprove", + "ricardian_contract": "" + }, { + "name": "cancel", + "type": "cancel", + "ricardian_contract": "" + }, { + "name": "exec", + "type": "exec", + "ricardian_contract": "" + } + + ], + "tables": [{ + "name": "proposal", + "type": "proposal", + "index_type": "i64", + "key_names" : ["proposal_name"], + "key_types" : ["name"] + },{ + "name": "approvals", + "type": "approvals_info", + "index_type": "i64", + "key_names" : ["proposal_name"], + "key_types" : ["name"] + } + ], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt index b7a9bf15..f38dae57 100644 --- a/eosio.sudo/CMakeLists.txt +++ b/eosio.sudo/CMakeLists.txt @@ -2,7 +2,10 @@ add_executable(eosio.sudo.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) target_include_directories(eosio.sudo.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set_target_properties(eosio.sudo.wasm + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo") + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) -install(TARGETS eosio.sudo.wasm - RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi b/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi new file mode 100644 index 00000000..6f74921b --- /dev/null +++ b/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi @@ -0,0 +1,73 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name": "actor", "type": "account_name"}, + {"name": "permission", "type": "permission_name"} + ] + },{ + "name": "action", + "base": "", + "fields": [ + {"name": "account", "type": "account_name"}, + {"name": "name", "type": "action_name"}, + {"name": "authorization", "type": "permission_level[]"}, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction_header", + "base": "", + "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": "extension", + "base": "", + "fields": [ + {"name": "type", "type" : "uint16" }, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction", + "base": "transaction_header", + "fields": [ + {"name": "context_free_actions", "type": "action[]"}, + {"name": "actions", "type": "action[]"}, + {"name": "transaction_extensions", "type": "extension[]"} + ] + },{ + "name": "exec", + "base": "", + "fields": [ + {"name":"executer", "type":"account_name"}, + {"name":"trx", "type":"transaction"} + ] + } + ], + "actions": [{ + "name": "exec", + "type": "exec", + "ricardian_contract": "" + } + ], + "tables": [], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index 6d84c767..936d74e1 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -2,7 +2,11 @@ add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cp target_include_directories(eosio.system.wasm PUBLIC ${CMAKE_SOURCE_DIR}/include) + +set_target_properties(eosio.system.wasm + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system") + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system" COPYONLY) + #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) -install(TARGETS eosio.system.wasm - RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/eosio.system/bin/eosio.system/eosio.system.abi b/eosio.system/bin/eosio.system/eosio.system.abi new file mode 100644 index 00000000..87937c78 --- /dev/null +++ b/eosio.system/bin/eosio.system/eosio.system.abi @@ -0,0 +1,578 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + },{ + "new_type_name": "transaction_id_type", + "type": "checksum256" + },{ + "new_type_name": "weight_type", + "type": "uint16" + }], + "____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.", + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name":"actor", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "key_weight", + "base": "", + "fields": [ + {"name":"key", "type":"public_key"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "bidname", + "base": "", + "fields": [ + {"name":"bidder", "type":"account_name"}, + {"name":"newname", "type":"account_name"}, + {"name":"bid", "type":"asset"} + ] + },{ + "name": "permission_level_weight", + "base": "", + "fields": [ + {"name":"permission", "type":"permission_level"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "wait_weight", + "base": "", + "fields": [ + {"name":"wait_sec", "type":"uint32"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "authority", + "base": "", + "fields": [ + {"name":"threshold", "type":"uint32"}, + {"name":"keys", "type":"key_weight[]"}, + {"name":"accounts", "type":"permission_level_weight[]"}, + {"name":"waits", "type":"wait_weight[]"} + ] + },{ + "name": "newaccount", + "base": "", + "fields": [ + {"name":"creator", "type":"account_name"}, + {"name":"name", "type":"account_name"}, + {"name":"owner", "type":"authority"}, + {"name":"active", "type":"authority"} + ] + },{ + "name": "setcode", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"vmtype", "type":"uint8"}, + {"name":"vmversion", "type":"uint8"}, + {"name":"code", "type":"bytes"} + ] + },{ + "name": "setabi", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"abi", "type":"bytes"} + ] + },{ + "name": "updateauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"}, + {"name":"parent", "type":"permission_name"}, + {"name":"auth", "type":"authority"} + ] + },{ + "name": "deleteauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "linkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"}, + {"name":"requirement", "type":"permission_name"} + ] + },{ + "name": "unlinkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"} + ] + },{ + "name": "canceldelay", + "base": "", + "fields": [ + {"name":"canceling_auth", "type":"permission_level"}, + {"name":"trx_id", "type":"transaction_id_type"} + ] + },{ + "name": "onerror", + "base": "", + "fields": [ + {"name":"sender_id", "type":"uint128"}, + {"name":"sent_trx", "type":"bytes"} + ] + },{ + "name": "buyrambytes", + "base": "", + "fields": [ + {"name":"payer", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"bytes", "type":"uint32"} + ] + },{ + "name": "sellram", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"bytes", "type":"uint64"} + ] + },{ + "name": "buyram", + "base": "", + "fields": [ + {"name":"payer", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"quant", "type":"asset"} + ] + },{ + "name": "delegatebw", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"stake_net_quantity", "type":"asset"}, + {"name":"stake_cpu_quantity", "type":"asset"}, + {"name":"transfer", "type":"bool"} + ] + },{ + "name": "undelegatebw", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"unstake_net_quantity", "type":"asset"}, + {"name":"unstake_cpu_quantity", "type":"asset"} + ] + },{ + "name": "refund", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] + },{ + "name": "delegated_bandwidth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"to", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"} + ] + },{ + "name": "user_resources", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"ram_bytes", "type":"uint64"} + ] + },{ + "name": "total_resources", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"ram_bytes", "type":"uint64"} + ] + },{ + "name": "refund_request", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"request_time", "type":"time_point_sec"}, + {"name":"net_amount", "type":"asset"}, + {"name":"cpu_amount", "type":"asset"} + ] + },{ + "name": "blockchain_parameters", + "base": "", + "fields": [ + + {"name":"max_block_net_usage", "type":"uint64"}, + {"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":"uint32"}, + {"name":"max_inline_action_depth", "type":"uint16"}, + {"name":"max_authority_depth", "type":"uint16"} + + ] + },{ + "name": "eosio_global_state", + "base": "blockchain_parameters", + "fields": [ + {"name":"max_ram_size", "type":"uint64"}, + {"name":"total_ram_bytes_reserved", "type":"uint64"}, + {"name":"total_ram_stake", "type":"int64"}, + {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, + {"name":"last_pervote_bucket_fill", "type":"uint64"}, + {"name":"pervote_bucket", "type":"int64"}, + {"name":"perblock_bucket", "type":"int64"}, + {"name":"total_unpaid_blocks", "type":"uint32"}, + {"name":"total_activated_stake", "type":"int64"}, + {"name":"thresh_activated_stake_time", "type":"uint64"}, + {"name":"last_producer_schedule_size", "type":"uint16"}, + {"name":"total_producer_vote_weight", "type":"float64"}, + {"name":"last_name_close", "type":"block_timestamp_type"} + ] + },{ + "name": "producer_info", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"total_votes", "type":"float64"}, + {"name":"producer_key", "type":"public_key"}, + {"name":"is_active", "type":"bool"}, + {"name":"url", "type":"string"}, + {"name":"unpaid_blocks", "type":"uint32"}, + {"name":"last_claim_time", "type":"uint64"}, + {"name":"location", "type":"uint16"} + ] + },{ + "name": "regproducer", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"}, + {"name":"producer_key", "type":"public_key"}, + {"name":"url", "type":"string"}, + {"name":"location", "type":"uint16"} + ] + },{ + "name": "unregprod", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"} + ] + },{ + "name": "setram", + "base": "", + "fields": [ + {"name":"max_ram_size", "type":"uint64"} + ] + },{ + "name": "regproxy", + "base": "", + "fields": [ + {"name":"proxy", "type":"account_name"}, + {"name":"isproxy", "type":"bool"} + ] + },{ + "name": "voteproducer", + "base": "", + "fields": [ + {"name":"voter", "type":"account_name"}, + {"name":"proxy", "type":"account_name"}, + {"name":"producers", "type":"account_name[]"} + ] + },{ + "name": "voter_info", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"proxy", "type":"account_name"}, + {"name":"producers", "type":"account_name[]"}, + {"name":"staked", "type":"int64"}, + {"name":"last_vote_weight", "type":"float64"}, + {"name":"proxied_vote_weight", "type":"float64"}, + {"name":"is_proxy", "type":"bool"} + ] + },{ + "name": "claimrewards", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] + },{ + "name": "setpriv", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"is_priv", "type":"int8"} + ] + },{ + "name": "rmvproducer", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"} + ] + },{ + "name": "set_account_limits", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"ram_bytes", "type":"int64"}, + {"name":"net_weight", "type":"int64"}, + {"name":"cpu_weight", "type":"int64"} + ] + },{ + "name": "set_global_limits", + "base": "", + "fields": [ + {"name":"cpu_usec_per_period", "type":"int64"} + ] + },{ + "name": "producer_key", + "base": "", + "fields": [ + {"name":"producer_name", "type":"account_name"}, + {"name":"block_signing_key", "type":"public_key"} + ] + },{ + "name": "set_producers", + "base": "", + "fields": [ + {"name":"schedule", "type":"producer_key[]"} + ] + },{ + "name": "require_auth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"} + ] + },{ + "name": "setparams", + "base": "", + "fields": [ + {"name":"params", "type":"blockchain_parameters"} + ] + },{ + "name": "connector", + "base": "", + "fields": [ + {"name":"balance", "type":"asset"}, + {"name":"weight", "type":"float64"} + ] + },{ + "name": "exchange_state", + "base": "", + "fields": [ + {"name":"supply", "type":"asset"}, + {"name":"base", "type":"connector"}, + {"name":"quote", "type":"connector"} + ] + }, { + "name": "namebid_info", + "base": "", + "fields": [ + {"name":"newname", "type":"account_name"}, + {"name":"high_bidder", "type":"account_name"}, + {"name":"high_bid", "type":"int64"}, + {"name":"last_bid_time", "type":"uint64"} + ] + } + ], + "actions": [{ + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + },{ + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + },{ + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + },{ + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + },{ + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + },{ + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + },{ + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + },{ + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + },{ + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + },{ + "name": "buyrambytes", + "type": "buyrambytes", + "ricardian_contract": "" + },{ + "name": "buyram", + "type": "buyram", + "ricardian_contract": "" + },{ + "name": "sellram", + "type": "sellram", + "ricardian_contract": "" + },{ + "name": "delegatebw", + "type": "delegatebw", + "ricardian_contract": "" + },{ + "name": "undelegatebw", + "type": "undelegatebw", + "ricardian_contract": "" + },{ + "name": "refund", + "type": "refund", + "ricardian_contract": "" + },{ + "name": "regproducer", + "type": "regproducer", + "ricardian_contract": "" + },{ + "name": "setram", + "type": "setram", + "ricardian_contract": "" + },{ + "name": "bidname", + "type": "bidname", + "ricardian_contract": "" + },{ + "name": "unregprod", + "type": "unregprod", + "ricardian_contract": "" + },{ + "name": "regproxy", + "type": "regproxy", + "ricardian_contract": "" + },{ + "name": "voteproducer", + "type": "voteproducer", + "ricardian_contract": "" + },{ + "name": "claimrewards", + "type": "claimrewards", + "ricardian_contract": "" + },{ + "name": "setpriv", + "type": "setpriv", + "ricardian_contract": "" + },{ + "name": "rmvproducer", + "type": "rmvproducer", + "ricardian_contract": "" + },{ + "name": "setalimits", + "type": "set_account_limits", + "ricardian_contract": "" + },{ + "name": "setglimits", + "type": "set_global_limits", + "ricardian_contract": "" + },{ + "name": "setprods", + "type": "set_producers", + "ricardian_contract": "" + },{ + "name": "reqauth", + "type": "require_auth", + "ricardian_contract": "" + },{ + "name": "setparams", + "type": "setparams", + "ricardian_contract": "" + }], + "tables": [{ + "name": "producers", + "type": "producer_info", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "global", + "type": "eosio_global_state", + "index_type": "i64", + "key_names" : [], + "key_types" : [] + },{ + "name": "voters", + "type": "voter_info", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["account_name"] + },{ + "name": "userres", + "type": "user_resources", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "delband", + "type": "delegated_bandwidth", + "index_type": "i64", + "key_names" : ["to"], + "key_types" : ["uint64"] + },{ + "name": "rammarket", + "type": "exchange_state", + "index_type": "i64", + "key_names" : ["supply"], + "key_types" : ["uint64"] + },{ + "name": "refunds", + "type": "refund_request", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "namebids", + "type": "namebid_info", + "index_type": "i64", + "key_names" : ["newname"], + "key_types" : ["account_name"] + } + ], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt index a116f748..39993201 100644 --- a/eosio.token/CMakeLists.txt +++ b/eosio.token/CMakeLists.txt @@ -2,7 +2,10 @@ add_executable(eosio.token.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) target_include_directories(eosio.token.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set_target_properties(eosio.token.wasm + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token") + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) -install(TARGETS eosio.token.wasm - RUNTIME DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) -install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/bin) diff --git a/eosio.token/bin/eosio.token/eosio.token.abi b/eosio.token/bin/eosio.token/eosio.token.abi new file mode 100644 index 00000000..d769deb3 --- /dev/null +++ b/eosio.token/bin/eosio.token/eosio.token.abi @@ -0,0 +1,78 @@ +{ + "version": "eosio::abi/1.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":"asset"}, + {"name":"memo", "type":"string"} + ] + },{ + "name": "create", + "base": "", + "fields": [ + {"name":"issuer", "type":"account_name"}, + {"name":"maximum_supply", "type":"asset"} + ] + },{ + "name": "issue", + "base": "", + "fields": [ + {"name":"to", "type":"account_name"}, + {"name":"quantity", "type":"asset"}, + {"name":"memo", "type":"string"} + ] + },{ + "name": "account", + "base": "", + "fields": [ + {"name":"balance", "type":"asset"} + ] + },{ + "name": "currency_stats", + "base": "", + "fields": [ + {"name":"supply", "type":"asset"}, + {"name":"max_supply", "type":"asset"}, + {"name":"issuer", "type":"account_name"} + ] + } + ], + "actions": [{ + "name": "transfer", + "type": "transfer", + "ricardian_contract": "" + },{ + "name": "issue", + "type": "issue", + "ricardian_contract": "" + }, { + "name": "create", + "type": "create", + "ricardian_contract": "" + } + + ], + "tables": [{ + "name": "accounts", + "type": "account", + "index_type": "i64", + "key_names" : ["currency"], + "key_types" : ["uint64"] + },{ + "name": "stat", + "type": "currency_stats", + "index_type": "i64", + "key_names" : ["currency"], + "key_types" : ["uint64"] + } + ], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/tests/contracts.hpp b/tests/contracts.hpp deleted file mode 100644 index ef9cb14d..00000000 --- a/tests/contracts.hpp +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once -#include - -namespace eosio { namespace testing { - -struct contracts { - static std::vector system_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.system/bin/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.system/bin/eosio.system.wast"); } - static std::vector system_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.system/bin/eosio.system.abi"); } - static std::vector token_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.token/bin/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.token/bin/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.token/bin/eosio.token.abi"); } - static std::vector msig_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.msig/bin/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.msig/bin/eosio.msig.wast"); } - static std::vector msig_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.msig/bin/eosio.msig.abi"); } - static std::vector sudo_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/eosio.sudo/bin/eosio.sudo.wasm"); } - static std::string sudo_wast() { return read_wast("/Users/judgefudge/eosio.contracts/eosio.sudo/bin/eosio.sudo.wast"); } - static std::vector sudo_abi() { return read_abi("/Users/judgefudge/eosio.contracts/eosio.sudo/bin/eosio.sudo.abi"); } - - struct util { - static std::vector test_api_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/tests/test_contracts/test_api.wasm"); } - static std::vector exchange_wasm() { return read_wasm("/Users/judgefudge/eosio.contracts/tests/test_contracts/exchange.wasm"); } - }; -}; -}} //ns eosio::testing diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 93556523..1d91f506 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -4,18 +4,18 @@ namespace eosio { namespace testing { struct contracts { - static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system.wast"); } - static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system.abi"); } - static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token.abi"); } - static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig.wast"); } - static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig.abi"); } - static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo.wasm"); } - static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo.wast"); } - static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo.abi"); } + static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.abi"); } + static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wasm"); } + static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wast"); } + static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi"); } struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 03351a5e..6ff7a964 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1708,7 +1708,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) prod_perms.push_back( { name(x), config::active_name } ); } //prepare system contract with different hash (contract differs in one byte) - string eosio_system_wast2 = contracts::system_wast(); + string eosio_system_wast2 = wasm_to_wast(contracts::system_wasm(), true); string msg = "producer votes must be unique and sorted"; auto pos = eosio_system_wast2.find(msg); BOOST_REQUIRE( pos != std::string::npos ); @@ -1717,7 +1717,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) transaction trx; { - auto code = wast_to_wasm( eosio_system_wast2 ); + auto code = contracts::system_wasm(); //wast_to_wasm( eosio_system_wast2 ); variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) From c973039199086bd983679d8ad76d04f9937d0622 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 6 Jul 2018 18:17:16 -0400 Subject: [PATCH 0412/1048] Fixed missing debug symbols in fc for debug build --- eosio.system/CMakeLists.txt | 3 ++- tests/CMakeLists.txt | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index 936d74e1..b0bc4431 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -1,7 +1,8 @@ add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) target_include_directories(eosio.system.wasm PUBLIC - ${CMAKE_SOURCE_DIR}/include) + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_CURRENT_SOURCE_DIR}/../eosio.token/include) set_target_properties(eosio.system.wasm PROPERTIES diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 80e6a413..5c3e0d4b 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -40,9 +40,13 @@ find_package(Boost 1.67 REQUIRED COMPONENTS file(GLOB UNIT_TESTS "*.cpp") -find_library(libtester eosio_testing ) +find_library(libtester eosio_testing ${EOSIO_INSTALL_PREFIX}/lib) find_library(libchain eosio_chain ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libfc fc ${EOSIO_INSTALL_PREFIX}/lib) +if ( "${CMAKE_BUILD_TYPE}" EQUAL "Debug" ) + find_library(libfc fc_debug ${EOSIO_INSTALL_PREFIX}/lib) +else() + find_library(libfc fc ${EOSIO_INSTALL_PREFIX}/lib) +endif() find_library(libbinaryen binaryen ${EOSIO_INSTALL_PREFIX}/lib) find_library(libwasm WASM ${EOSIO_INSTALL_PREFIX}/lib) find_library(libwast WAST ${EOSIO_INSTALL_PREFIX}/lib) From 47cee42e85cd96f2391e15b2b8a537c11f2380fc Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 6 Jul 2018 18:35:56 -0400 Subject: [PATCH 0413/1048] added gitignores --- eosio.msig/bin/eosio.msig/.gitignore | 2 + eosio.msig/bin/eosio.msig/eosio.msig.abi | 152 ----- eosio.sudo/bin/eosio.sudo/.gitignore | 2 + eosio.sudo/bin/eosio.sudo/eosio.sudo.abi | 73 --- eosio.system/bin/eosio.system/.gitignore | 2 + .../bin/eosio.system/eosio.system.abi | 578 ------------------ eosio.token/bin/eosio.token/.gitignore | 2 + eosio.token/bin/eosio.token/eosio.token.abi | 78 --- 8 files changed, 8 insertions(+), 881 deletions(-) create mode 100644 eosio.msig/bin/eosio.msig/.gitignore delete mode 100644 eosio.msig/bin/eosio.msig/eosio.msig.abi create mode 100644 eosio.sudo/bin/eosio.sudo/.gitignore delete mode 100644 eosio.sudo/bin/eosio.sudo/eosio.sudo.abi create mode 100644 eosio.system/bin/eosio.system/.gitignore delete mode 100644 eosio.system/bin/eosio.system/eosio.system.abi create mode 100644 eosio.token/bin/eosio.token/.gitignore delete mode 100644 eosio.token/bin/eosio.token/eosio.token.abi diff --git a/eosio.msig/bin/eosio.msig/.gitignore b/eosio.msig/bin/eosio.msig/.gitignore new file mode 100644 index 00000000..db5b01cc --- /dev/null +++ b/eosio.msig/bin/eosio.msig/.gitignore @@ -0,0 +1,2 @@ +eosio.msig.abi +eosio.msig.wasm diff --git a/eosio.msig/bin/eosio.msig/eosio.msig.abi b/eosio.msig/bin/eosio.msig/eosio.msig.abi deleted file mode 100644 index 9fcf8a95..00000000 --- a/eosio.msig/bin/eosio.msig/eosio.msig.abi +++ /dev/null @@ -1,152 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - }], - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name": "actor", "type": "account_name"}, - {"name": "permission", "type": "permission_name"} - ] - },{ - "name": "action", - "base": "", - "fields": [ - {"name": "account", "type": "account_name"}, - {"name": "name", "type": "action_name"}, - {"name": "authorization", "type": "permission_level[]"}, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction_header", - "base": "", - "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": "extension", - "base": "", - "fields": [ - {"name": "type", "type" : "uint16" }, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction", - "base": "transaction_header", - "fields": [ - {"name": "context_free_actions", "type": "action[]"}, - {"name": "actions", "type": "action[]"}, - {"name": "transaction_extensions", "type": "extension[]"} - ] - },{ - "name": "propose", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"requested", "type":"permission_level[]"}, - {"name":"trx", "type":"transaction"} - ] - },{ - "name": "approve", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"level", "type":"permission_level"} - ] - },{ - "name": "unapprove", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"level", "type":"permission_level"} - ] - },{ - "name": "cancel", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"canceler", "type":"account_name"} - ] - },{ - "name": "exec", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"executer", "type":"account_name"} - ] - },{ - "name": "proposal", - "base": "", - "fields": [ - {"name": "proposal_name", "type": "name"}, - {"name": "packed_transaction", "type": "bytes"} - ] - },{ - "name": "approvals_info", - "base": "", - "fields": [ - {"name": "proposal_name", "type": "name"}, - {"name": "requested_approvals", "type": "permission_level[]"}, - {"name": "provided_approvals", "type": "permission_level[]"} - ] - } - ], - "actions": [{ - "name": "propose", - "type": "propose", - "ricardian_contract": "" - },{ - "name": "approve", - "type": "approve", - "ricardian_contract": "" - },{ - "name": "unapprove", - "type": "unapprove", - "ricardian_contract": "" - }, { - "name": "cancel", - "type": "cancel", - "ricardian_contract": "" - }, { - "name": "exec", - "type": "exec", - "ricardian_contract": "" - } - - ], - "tables": [{ - "name": "proposal", - "type": "proposal", - "index_type": "i64", - "key_names" : ["proposal_name"], - "key_types" : ["name"] - },{ - "name": "approvals", - "type": "approvals_info", - "index_type": "i64", - "key_names" : ["proposal_name"], - "key_types" : ["name"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.sudo/bin/eosio.sudo/.gitignore b/eosio.sudo/bin/eosio.sudo/.gitignore new file mode 100644 index 00000000..35898c3b --- /dev/null +++ b/eosio.sudo/bin/eosio.sudo/.gitignore @@ -0,0 +1,2 @@ +eosio.sudo.abi +eosio.sudo.wasm diff --git a/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi b/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi deleted file mode 100644 index 6f74921b..00000000 --- a/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi +++ /dev/null @@ -1,73 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - }], - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name": "actor", "type": "account_name"}, - {"name": "permission", "type": "permission_name"} - ] - },{ - "name": "action", - "base": "", - "fields": [ - {"name": "account", "type": "account_name"}, - {"name": "name", "type": "action_name"}, - {"name": "authorization", "type": "permission_level[]"}, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction_header", - "base": "", - "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": "extension", - "base": "", - "fields": [ - {"name": "type", "type" : "uint16" }, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction", - "base": "transaction_header", - "fields": [ - {"name": "context_free_actions", "type": "action[]"}, - {"name": "actions", "type": "action[]"}, - {"name": "transaction_extensions", "type": "extension[]"} - ] - },{ - "name": "exec", - "base": "", - "fields": [ - {"name":"executer", "type":"account_name"}, - {"name":"trx", "type":"transaction"} - ] - } - ], - "actions": [{ - "name": "exec", - "type": "exec", - "ricardian_contract": "" - } - ], - "tables": [], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.system/bin/eosio.system/.gitignore b/eosio.system/bin/eosio.system/.gitignore new file mode 100644 index 00000000..105891a4 --- /dev/null +++ b/eosio.system/bin/eosio.system/.gitignore @@ -0,0 +1,2 @@ +eosio.system.abi +eosio.system.wasm diff --git a/eosio.system/bin/eosio.system/eosio.system.abi b/eosio.system/bin/eosio.system/eosio.system.abi deleted file mode 100644 index 87937c78..00000000 --- a/eosio.system/bin/eosio.system/eosio.system.abi +++ /dev/null @@ -1,578 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - },{ - "new_type_name": "transaction_id_type", - "type": "checksum256" - },{ - "new_type_name": "weight_type", - "type": "uint16" - }], - "____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.", - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name":"actor", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "key_weight", - "base": "", - "fields": [ - {"name":"key", "type":"public_key"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "bidname", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"newname", "type":"account_name"}, - {"name":"bid", "type":"asset"} - ] - },{ - "name": "permission_level_weight", - "base": "", - "fields": [ - {"name":"permission", "type":"permission_level"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "wait_weight", - "base": "", - "fields": [ - {"name":"wait_sec", "type":"uint32"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "authority", - "base": "", - "fields": [ - {"name":"threshold", "type":"uint32"}, - {"name":"keys", "type":"key_weight[]"}, - {"name":"accounts", "type":"permission_level_weight[]"}, - {"name":"waits", "type":"wait_weight[]"} - ] - },{ - "name": "newaccount", - "base": "", - "fields": [ - {"name":"creator", "type":"account_name"}, - {"name":"name", "type":"account_name"}, - {"name":"owner", "type":"authority"}, - {"name":"active", "type":"authority"} - ] - },{ - "name": "setcode", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"vmtype", "type":"uint8"}, - {"name":"vmversion", "type":"uint8"}, - {"name":"code", "type":"bytes"} - ] - },{ - "name": "setabi", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"abi", "type":"bytes"} - ] - },{ - "name": "updateauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"}, - {"name":"parent", "type":"permission_name"}, - {"name":"auth", "type":"authority"} - ] - },{ - "name": "deleteauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "linkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"}, - {"name":"requirement", "type":"permission_name"} - ] - },{ - "name": "unlinkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"} - ] - },{ - "name": "canceldelay", - "base": "", - "fields": [ - {"name":"canceling_auth", "type":"permission_level"}, - {"name":"trx_id", "type":"transaction_id_type"} - ] - },{ - "name": "onerror", - "base": "", - "fields": [ - {"name":"sender_id", "type":"uint128"}, - {"name":"sent_trx", "type":"bytes"} - ] - },{ - "name": "buyrambytes", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"bytes", "type":"uint32"} - ] - },{ - "name": "sellram", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"bytes", "type":"uint64"} - ] - },{ - "name": "buyram", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"quant", "type":"asset"} - ] - },{ - "name": "delegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"stake_net_quantity", "type":"asset"}, - {"name":"stake_cpu_quantity", "type":"asset"}, - {"name":"transfer", "type":"bool"} - ] - },{ - "name": "undelegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"unstake_net_quantity", "type":"asset"}, - {"name":"unstake_cpu_quantity", "type":"asset"} - ] - },{ - "name": "refund", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "delegated_bandwidth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"} - ] - },{ - "name": "user_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "total_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "refund_request", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"request_time", "type":"time_point_sec"}, - {"name":"net_amount", "type":"asset"}, - {"name":"cpu_amount", "type":"asset"} - ] - },{ - "name": "blockchain_parameters", - "base": "", - "fields": [ - - {"name":"max_block_net_usage", "type":"uint64"}, - {"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":"uint32"}, - {"name":"max_inline_action_depth", "type":"uint16"}, - {"name":"max_authority_depth", "type":"uint16"} - - ] - },{ - "name": "eosio_global_state", - "base": "blockchain_parameters", - "fields": [ - {"name":"max_ram_size", "type":"uint64"}, - {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"int64"}, - {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, - {"name":"last_pervote_bucket_fill", "type":"uint64"}, - {"name":"pervote_bucket", "type":"int64"}, - {"name":"perblock_bucket", "type":"int64"}, - {"name":"total_unpaid_blocks", "type":"uint32"}, - {"name":"total_activated_stake", "type":"int64"}, - {"name":"thresh_activated_stake_time", "type":"uint64"}, - {"name":"last_producer_schedule_size", "type":"uint16"}, - {"name":"total_producer_vote_weight", "type":"float64"}, - {"name":"last_name_close", "type":"block_timestamp_type"} - ] - },{ - "name": "producer_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"total_votes", "type":"float64"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"is_active", "type":"bool"}, - {"name":"url", "type":"string"}, - {"name":"unpaid_blocks", "type":"uint32"}, - {"name":"last_claim_time", "type":"uint64"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "regproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"url", "type":"string"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "unregprod", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "setram", - "base": "", - "fields": [ - {"name":"max_ram_size", "type":"uint64"} - ] - },{ - "name": "regproxy", - "base": "", - "fields": [ - {"name":"proxy", "type":"account_name"}, - {"name":"isproxy", "type":"bool"} - ] - },{ - "name": "voteproducer", - "base": "", - "fields": [ - {"name":"voter", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"} - ] - },{ - "name": "voter_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"}, - {"name":"staked", "type":"int64"}, - {"name":"last_vote_weight", "type":"float64"}, - {"name":"proxied_vote_weight", "type":"float64"}, - {"name":"is_proxy", "type":"bool"} - ] - },{ - "name": "claimrewards", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "setpriv", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"is_priv", "type":"int8"} - ] - },{ - "name": "rmvproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "set_account_limits", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"ram_bytes", "type":"int64"}, - {"name":"net_weight", "type":"int64"}, - {"name":"cpu_weight", "type":"int64"} - ] - },{ - "name": "set_global_limits", - "base": "", - "fields": [ - {"name":"cpu_usec_per_period", "type":"int64"} - ] - },{ - "name": "producer_key", - "base": "", - "fields": [ - {"name":"producer_name", "type":"account_name"}, - {"name":"block_signing_key", "type":"public_key"} - ] - },{ - "name": "set_producers", - "base": "", - "fields": [ - {"name":"schedule", "type":"producer_key[]"} - ] - },{ - "name": "require_auth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"} - ] - },{ - "name": "setparams", - "base": "", - "fields": [ - {"name":"params", "type":"blockchain_parameters"} - ] - },{ - "name": "connector", - "base": "", - "fields": [ - {"name":"balance", "type":"asset"}, - {"name":"weight", "type":"float64"} - ] - },{ - "name": "exchange_state", - "base": "", - "fields": [ - {"name":"supply", "type":"asset"}, - {"name":"base", "type":"connector"}, - {"name":"quote", "type":"connector"} - ] - }, { - "name": "namebid_info", - "base": "", - "fields": [ - {"name":"newname", "type":"account_name"}, - {"name":"high_bidder", "type":"account_name"}, - {"name":"high_bid", "type":"int64"}, - {"name":"last_bid_time", "type":"uint64"} - ] - } - ], - "actions": [{ - "name": "newaccount", - "type": "newaccount", - "ricardian_contract": "" - },{ - "name": "setcode", - "type": "setcode", - "ricardian_contract": "" - },{ - "name": "setabi", - "type": "setabi", - "ricardian_contract": "" - },{ - "name": "updateauth", - "type": "updateauth", - "ricardian_contract": "" - },{ - "name": "deleteauth", - "type": "deleteauth", - "ricardian_contract": "" - },{ - "name": "linkauth", - "type": "linkauth", - "ricardian_contract": "" - },{ - "name": "unlinkauth", - "type": "unlinkauth", - "ricardian_contract": "" - },{ - "name": "canceldelay", - "type": "canceldelay", - "ricardian_contract": "" - },{ - "name": "onerror", - "type": "onerror", - "ricardian_contract": "" - },{ - "name": "buyrambytes", - "type": "buyrambytes", - "ricardian_contract": "" - },{ - "name": "buyram", - "type": "buyram", - "ricardian_contract": "" - },{ - "name": "sellram", - "type": "sellram", - "ricardian_contract": "" - },{ - "name": "delegatebw", - "type": "delegatebw", - "ricardian_contract": "" - },{ - "name": "undelegatebw", - "type": "undelegatebw", - "ricardian_contract": "" - },{ - "name": "refund", - "type": "refund", - "ricardian_contract": "" - },{ - "name": "regproducer", - "type": "regproducer", - "ricardian_contract": "" - },{ - "name": "setram", - "type": "setram", - "ricardian_contract": "" - },{ - "name": "bidname", - "type": "bidname", - "ricardian_contract": "" - },{ - "name": "unregprod", - "type": "unregprod", - "ricardian_contract": "" - },{ - "name": "regproxy", - "type": "regproxy", - "ricardian_contract": "" - },{ - "name": "voteproducer", - "type": "voteproducer", - "ricardian_contract": "" - },{ - "name": "claimrewards", - "type": "claimrewards", - "ricardian_contract": "" - },{ - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "" - },{ - "name": "rmvproducer", - "type": "rmvproducer", - "ricardian_contract": "" - },{ - "name": "setalimits", - "type": "set_account_limits", - "ricardian_contract": "" - },{ - "name": "setglimits", - "type": "set_global_limits", - "ricardian_contract": "" - },{ - "name": "setprods", - "type": "set_producers", - "ricardian_contract": "" - },{ - "name": "reqauth", - "type": "require_auth", - "ricardian_contract": "" - },{ - "name": "setparams", - "type": "setparams", - "ricardian_contract": "" - }], - "tables": [{ - "name": "producers", - "type": "producer_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "global", - "type": "eosio_global_state", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "voters", - "type": "voter_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["account_name"] - },{ - "name": "userres", - "type": "user_resources", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "delband", - "type": "delegated_bandwidth", - "index_type": "i64", - "key_names" : ["to"], - "key_types" : ["uint64"] - },{ - "name": "rammarket", - "type": "exchange_state", - "index_type": "i64", - "key_names" : ["supply"], - "key_types" : ["uint64"] - },{ - "name": "refunds", - "type": "refund_request", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "namebids", - "type": "namebid_info", - "index_type": "i64", - "key_names" : ["newname"], - "key_types" : ["account_name"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.token/bin/eosio.token/.gitignore b/eosio.token/bin/eosio.token/.gitignore new file mode 100644 index 00000000..e5513007 --- /dev/null +++ b/eosio.token/bin/eosio.token/.gitignore @@ -0,0 +1,2 @@ +eosio.token.abi +eosio.token.wasm diff --git a/eosio.token/bin/eosio.token/eosio.token.abi b/eosio.token/bin/eosio.token/eosio.token.abi deleted file mode 100644 index d769deb3..00000000 --- a/eosio.token/bin/eosio.token/eosio.token.abi +++ /dev/null @@ -1,78 +0,0 @@ -{ - "version": "eosio::abi/1.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":"asset"}, - {"name":"memo", "type":"string"} - ] - },{ - "name": "create", - "base": "", - "fields": [ - {"name":"issuer", "type":"account_name"}, - {"name":"maximum_supply", "type":"asset"} - ] - },{ - "name": "issue", - "base": "", - "fields": [ - {"name":"to", "type":"account_name"}, - {"name":"quantity", "type":"asset"}, - {"name":"memo", "type":"string"} - ] - },{ - "name": "account", - "base": "", - "fields": [ - {"name":"balance", "type":"asset"} - ] - },{ - "name": "currency_stats", - "base": "", - "fields": [ - {"name":"supply", "type":"asset"}, - {"name":"max_supply", "type":"asset"}, - {"name":"issuer", "type":"account_name"} - ] - } - ], - "actions": [{ - "name": "transfer", - "type": "transfer", - "ricardian_contract": "" - },{ - "name": "issue", - "type": "issue", - "ricardian_contract": "" - }, { - "name": "create", - "type": "create", - "ricardian_contract": "" - } - - ], - "tables": [{ - "name": "accounts", - "type": "account", - "index_type": "i64", - "key_names" : ["currency"], - "key_types" : ["uint64"] - },{ - "name": "stat", - "type": "currency_stats", - "index_type": "i64", - "key_names" : ["currency"], - "key_types" : ["uint64"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} From 559c243626e2cae702712f77a2e9da5cebc155f7 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 6 Jul 2018 18:32:32 -0400 Subject: [PATCH 0414/1048] eosio.ram payment problem #4 --- eosio.token/abi/eosio.token.abi | 4 ++++ eosio.token/include/eosio.token/eosio.token.hpp | 2 +- eosio.token/src/eosio.token.cpp | 4 ++-- tests/eosio.token_tests.cpp | 4 +--- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi index 35926470..9d600f14 100644 --- a/eosio.token/abi/eosio.token.abi +++ b/eosio.token/abi/eosio.token.abi @@ -63,6 +63,10 @@ "name": "create", "type": "create", "ricardian_contract": "" + }, { + "name": "close", + "type": "close", + "ricardian_contract": "" } ], diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 1ab0ffa1..e5b5fd28 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -31,7 +31,7 @@ namespace eosio { asset quantity, string memo ); - void close( account_name owner, symbol_name symbol ); + void close( account_name owner, symbol_type symbol ); inline asset get_supply( symbol_name sym )const; diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index 8abb8c85..e39b1181 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -111,9 +111,9 @@ void token::add_balance( account_name owner, asset value, account_name ram_payer } } -void token::close( account_name owner, symbol_name symbol ) { +void token::close( account_name owner, symbol_type symbol ) { accounts acnts( _self, owner ); - auto it = acnts.find( symbol ); + auto it = acnts.find( symbol.name() ); eosio_assert( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); eosio_assert( it->balance.amount == 0, "Cannot close because the balance is not zero." ); acnts.erase( it ); diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index a73e47eb..cd5f1f97 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -94,11 +94,9 @@ class eosio_token_tester : public tester { action_result close( account_name owner, const string& symbolname ) { - auto symb = eosio::chain::symbol::from_string(symbolname); - auto symbol_code = symb.to_symbol_code().value; return push_action( owner, N(close), mvo() ( "owner", owner ) - ( "symbol", symbol_code.to_string() ) + ( "symbol", "0,CERO" ) ); } From 329313623ac39a412c8d1a075e22b84fac958f04 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 9 Jul 2018 14:42:54 -0400 Subject: [PATCH 0415/1048] sellram bills eosio.ram balance storage to eosio.ram, unit-test for eosio.ram memory usage #4 --- eosio.system/src/delegate_bandwidth.cpp | 5 ++-- eosio.token/bin/eosio.token/eosio.token.abi | 11 ++++++++ tests/eosio.system_tests.cpp | 31 +++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 9678c28e..567d3a9d 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -117,7 +117,7 @@ namespace eosiosystem { // quant_after_fee.amount should be > 0 if quant.amount > 1. // If quant.amount == 1, then quant_after_fee.amount == 0 and the next inline transfer will fail causing the buyram action to fail. - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{payer,N(active)},{N(eosio.ram),N(active)}}, { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } ); if( fee.amount > 0 ) { @@ -188,12 +188,11 @@ namespace eosiosystem { }); set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.ram),N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.ram),N(active)},{account,N(active)}}, { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); auto fee = ( tokens_out.amount + 199 ) / 200; /// .5% fee (round up) // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount - if( fee > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); diff --git a/eosio.token/bin/eosio.token/eosio.token.abi b/eosio.token/bin/eosio.token/eosio.token.abi index d769deb3..9d600f14 100644 --- a/eosio.token/bin/eosio.token/eosio.token.abi +++ b/eosio.token/bin/eosio.token/eosio.token.abi @@ -28,6 +28,13 @@ {"name":"quantity", "type":"asset"}, {"name":"memo", "type":"string"} ] + },{ + "name": "close", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"symbol", "type":"symbol"}, + ] },{ "name": "account", "base": "", @@ -56,6 +63,10 @@ "name": "create", "type": "create", "ricardian_contract": "" + }, { + "name": "close", + "type": "close", + "ricardian_contract": "" } ], diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 6ff7a964..8a40140d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2584,6 +2584,37 @@ BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { } } FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + + const asset initial_ram_balance = get_balance(N(eosio.ram)); + const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("1000.0000") ) ); + + BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol().to_symbol_code() ).empty() ); + + //remove row + base_tester::push_action( N(eosio.token), N(close), N(alice1111111), mvo() + ( "owner", "alice1111111" ) + ( "symbol", symbol() ) + ); + BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol().to_symbol_code() ).empty() ); + + auto rlm = control->get_resource_limits_manager(); + auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); + auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); + //std::cout << "Sellram" << std::endl; + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 2048 ) ); + + //make sure that ram was billed to alice, not to eosio.ram + BOOST_REQUIRE_EQUAL( true, alice_ram_usage < rlm.get_account_ram_usage(N(alice1111111)) ); + BOOST_REQUIRE_EQUAL( eosioram_ram_usage, rlm.get_account_ram_usage(N(eosio.ram)) ); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() void translate_fc_exception(const fc::exception &e) { From a8ac8306f59a9c9e9557b85cb05aa66f85c7cb8e Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 9 Jul 2018 17:30:34 -0400 Subject: [PATCH 0416/1048] retire tokens #6 --- eosio.token/abi/eosio.token.abi | 11 ++++ .../include/eosio.token/eosio.token.hpp | 2 + eosio.token/src/eosio.token.cpp | 27 +++++++- tests/eosio.token_tests.cpp | 65 +++++++++++++++++++ 4 files changed, 104 insertions(+), 1 deletion(-) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi index 9d600f14..b7352d36 100644 --- a/eosio.token/abi/eosio.token.abi +++ b/eosio.token/abi/eosio.token.abi @@ -28,6 +28,13 @@ {"name":"quantity", "type":"asset"}, {"name":"memo", "type":"string"} ] + },{ + "name": "retire", + "base": "", + "fields": [ + {"name":"quantity", "type":"asset"}, + {"name":"memo", "type":"string"} + ] },{ "name": "close", "base": "", @@ -59,6 +66,10 @@ "name": "issue", "type": "issue", "ricardian_contract": "" + },{ + "name": "retire", + "type": "retire", + "ricardian_contract": "" }, { "name": "create", "type": "create", diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index e5b5fd28..629524ad 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -26,6 +26,8 @@ namespace eosio { void issue( account_name to, asset quantity, string memo ); + void retire( asset quantity, string memo ); + void transfer( account_name from, account_name to, asset quantity, diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index e39b1181..ff25071d 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -59,6 +59,31 @@ void token::issue( account_name to, asset quantity, string memo ) } } +void token::retire( asset quantity, string memo ) +{ + auto sym = quantity.symbol; + eosio_assert( sym.is_valid(), "invalid symbol name" ); + eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); + + auto sym_name = sym.name(); + stats statstable( _self, sym_name ); + auto existing = statstable.find( sym_name ); + eosio_assert( existing != statstable.end(), "token with symbol does not exist" ); + const auto& st = *existing; + + require_auth( st.issuer ); + eosio_assert( quantity.is_valid(), "invalid quantity" ); + eosio_assert( quantity.amount > 0, "must retire positive quantity" ); + + eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); + + statstable.modify( st, 0, [&]( auto& s ) { + s.supply -= quantity; + }); + + sub_balance( st.issuer, quantity ); +} + void token::transfer( account_name from, account_name to, asset quantity, @@ -121,4 +146,4 @@ void token::close( account_name owner, symbol_type symbol ) { } /// namespace eosio -EOSIO_ABI( eosio::token, (create)(issue)(transfer)(close) ) +EOSIO_ABI( eosio::token, (create)(issue)(transfer)(close)(retire) ) diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index cd5f1f97..093d8d0f 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -80,6 +80,14 @@ class eosio_token_tester : public tester { ); } + action_result retire( account_name issuer, asset quantity, string memo ) { + return push_action( issuer, N(retire), mvo() + ( "quantity", quantity) + ( "memo", memo) + ); + + } + action_result transfer( account_name from, account_name to, asset quantity, @@ -225,6 +233,63 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( retire_tests, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("1000.000 TKN")); + produce_blocks(1); + + BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("500.000 TKN"), "hola" ) ); + + auto stats = get_stats("3,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "500.000 TKN") + ("max_supply", "1000.000 TKN") + ("issuer", "alice") + ); + + auto alice_balance = get_account(N(alice), "3,TKN"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "500.000 TKN") + ); + + BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("200.000 TKN"), "hola" ) ); + stats = get_stats("3,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "300.000 TKN") + ("max_supply", "1000.000 TKN") + ("issuer", "alice") + ); + alice_balance = get_account(N(alice), "3,TKN"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "300.000 TKN") + ); + + //should fail to retire more than current supply + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("500.000 TKN"), "hola" ) ); + + BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("200.000 TKN"), "hola" ) ); + //should fail to retire since tokens are not on the issuer's balance + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) ); + //transfer tokens back + BOOST_REQUIRE_EQUAL( success(), transfer( N(bob), N(alice), asset::from_string("200.000 TKN"), "hola" ) ); + + BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) ); + stats = get_stats("3,TKN"); + REQUIRE_MATCHING_OBJECT( stats, mvo() + ("supply", "0.000 TKN") + ("max_supply", "1000.000 TKN") + ("issuer", "alice") + ); + alice_balance = get_account(N(alice), "3,TKN"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "0.000 TKN") + ); + + //trying to retire tokens with zero supply + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("1.000 TKN"), "hola" ) ); + +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { auto token = create( N(alice), asset::from_string("1000 CERO")); From ec31a4300dbbfa595ee56a4433423efb7512f22f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 9 Jul 2018 18:17:43 -0400 Subject: [PATCH 0417/1048] setramrate testing --- eosio.system/src/eosio.system.cpp | 2 ++ tests/eosio.system_tester.hpp | 4 ++++ tests/eosio.system_tests.cpp | 25 ++++++++++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index f34117b5..b26f4a24 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -109,6 +109,8 @@ namespace eosiosystem { } else { update_ram_supply(); } + + _global2.set( _gstate2, _self ); } void system_contract::setparams( const eosio::blockchain_parameters& params ) { diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index ff90f8d3..7ce52211 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -386,7 +386,11 @@ class eosio_system_tester : public TESTER { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); if (data.empty()) std::cout << "\nData is empty\n" << std::endl; return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); + } + fc::variant get_global_state2() { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data ); } fc::variant get_refund_request( name account ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 6ff7a964..cf3cc7f1 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1380,7 +1380,6 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t } FC_LOG_AND_RETHROW() - BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; @@ -2584,6 +2583,30 @@ BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { } } FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { + + const uint64_t init_max_ram_size = 64ll*1024 * 1024 * 1024; + + BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + produce_blocks(20); + BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + transfer( config::system_account_name, "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + produce_block(); + BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + + BOOST_REQUIRE_EQUAL( success(), push_action(config::system_account_name, N(setramrate), mvo()("bytes_per_block", 1000)) ); + BOOST_REQUIRE_EQUAL( 1000, get_global_state2()["new_ram_per_block"].as() ); + produce_blocks(100); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + produce_blocks(100); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() void translate_fc_exception(const fc::exception &e) { From 846b8901de2ce058d9e0f812f206f6b8e85c30b6 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 10 Jul 2018 11:17:21 -0400 Subject: [PATCH 0418/1048] Small changes for Linux and build script --- UnitTestsExternalProject.txt | 2 +- build.sh | 57 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 1 deletion(-) create mode 100755 build.sh diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index f05d9ec2..2091f8d7 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,7 +4,7 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eosio -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${Boost_INCLUDE_DIRS}/../ + CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eosio -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests diff --git a/build.sh b/build.sh new file mode 100755 index 00000000..1175fdef --- /dev/null +++ b/build.sh @@ -0,0 +1,57 @@ +#! /bin/bash + +printf "\t=========== Building eosio.contracts ===========\n\n" + +RED='\033[0;31m' +NC='\033[0m' + +if [ ! -d "/usr/local/eosio.wasmsdk" ]; then + printf "${RED}Error, please ensure that eosio.wasmsdk is installed correctly!\n\n${NC}" + exit -1 +fi + +unamestr=`uname` +if [[ "${unamestr}" == 'Darwin' ]]; then + BOOST=/usr/local + CXX_COMPILER=g++ +else + BOOST=~/opt/boost + OS_NAME=$( cat /etc/os-release | grep ^NAME | cut -d'=' -f2 | sed 's/\"//gI' ) + + case "$OS_NAME" in + "Amazon Linux AMI") + CXX_COMPILER=g++ + C_COMPILER=gcc + ;; + "CentOS Linux") + CXX_COMPILER=g++ + C_COMPILER=gcc + ;; + "elementary OS") + CXX_COMPILER=clang++-4.0 + C_COMPILER=clang-4.0 + ;; + "Fedora") + CXX_COMPILER=g++ + C_COMPILER=gcc + ;; + "Linux Mint") + CXX_COMPILER=clang++-4.0 + C_COMPILER=clang-4.0 + ;; + "Ubuntu") + CXX_COMPILER=clang++-4.0 + C_COMPILER=clang-4.0 + ;; + *) + printf "\\n\\tUnsupported Linux Distribution. Exiting now.\\n\\n" + exit 1 + esac +fi + +CORES=`getconf _NPROCESSORS_ONLN` +mkdir -p build +pushd build &> /dev/null +cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" ../ +make -j${CORES} +popd &> /dev/null From 7c925aa0d286474fcb688e1f5e8c067d62aeedcd Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 10 Jul 2018 11:53:28 -0400 Subject: [PATCH 0419/1048] setramrate testing, fixes --- eosio.system/src/eosio.system.cpp | 4 +--- tests/eosio.system_tests.cpp | 30 +++++++++++++++++++++--------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index b26f4a24..223f4ef9 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -109,8 +109,6 @@ namespace eosiosystem { } else { update_ram_supply(); } - - _global2.set( _gstate2, _self ); } void system_contract::setparams( const eosio::blockchain_parameters& params ) { @@ -229,7 +227,7 @@ EOSIO_ABI( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror) // eosio.system.cpp - (setram)(setparams)(setpriv)(rmvproducer)(bidname) + (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(bidname) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index cf3cc7f1..3a8a456a 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2593,17 +2593,29 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); transfer( config::system_account_name, "alice1111111", core_from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); - produce_block(); - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - - BOOST_REQUIRE_EQUAL( success(), push_action(config::system_account_name, N(setramrate), mvo()("bytes_per_block", 1000)) ); - BOOST_REQUIRE_EQUAL( 1000, get_global_state2()["new_ram_per_block"].as() ); - produce_blocks(100); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + produce_blocks(3); BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - produce_blocks(100); + const uint16_t rate = 1000; + BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); + BOOST_REQUIRE_EQUAL( rate, get_global_state2()["new_ram_per_block"].as() ); + // last time update_ram_supply called is in buyram, num of blocks since then is 1 + 3 = 4 + uint64_t cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); + BOOST_REQUIRE_EQUAL( init_max_ram_size + 4 * rate, get_global_state()["max_ram_size"].as_uint64() ); + produce_blocks(10); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * rate, get_global_state()["max_ram_size"].as_uint64() ); + cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); + produce_blocks(5); + BOOST_REQUIRE_EQUAL( cur_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 100 ) ); + BOOST_REQUIRE_EQUAL( cur_ram_size + 6 * rate, get_global_state()["max_ram_size"].as_uint64() ); + cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); + produce_blocks(); + BOOST_REQUIRE_EQUAL( success(), buyrambytes( "alice1111111", "alice1111111", 100 ) ); + BOOST_REQUIRE_EQUAL( cur_ram_size + 2 * rate, get_global_state()["max_ram_size"].as_uint64() ); + + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), + push_action( "alice1111111", N(setramrate), mvo()("bytes_per_block", rate) ) ); } FC_LOG_AND_RETHROW() From 9a2ae4f853e10d077f089aeabf4f5af3cf8b3db0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 10 Jul 2018 16:44:45 -0400 Subject: [PATCH 0420/1048] Fix unit test build issues --- tests/eosio.msig_tests.cpp | 10 +++++----- tests/eosio.sudo_tests.cpp | 6 +++--- tests/eosio.system_tester.hpp | 26 +++++++++++++------------- tests/eosio.system_tests.cpp | 8 ++++---- tests/eosio.token_tests.cpp | 8 ++++---- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index ce01cc85..d6439d69 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -36,7 +36,7 @@ class eosio_msig_tester : public tester { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, @@ -174,7 +174,7 @@ transaction eosio_msig_tester::reqauth( account_name from, const vectordb().get( N(eosio.sudo) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); while( control->pending_block_state()->header.producer.to_string() == "eosio" ) { produce_block(); @@ -134,7 +134,7 @@ transaction eosio_sudo_tester::sudo_exec( account_name executer, const transacti transaction trx2; set_transaction_headers(trx2, expiration); action act; - abi_serializer::from_variant( act_obj, act, get_resolver() ); + abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer_max_time ); trx2.actions.push_back( std::move(act) ); return trx2; } @@ -155,7 +155,7 @@ transaction eosio_sudo_tester::reqauth( account_name from, const vectordb().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi); + token_abi_ser.set_abi(abi, abi_serializer_max_time); } create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); @@ -63,7 +63,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } produce_blocks(); @@ -219,7 +219,7 @@ class eosio_system_tester : public TESTER { action act; act.account = config::system_account_name; act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); } @@ -320,22 +320,22 @@ class eosio_system_tester : public TESTER { asset get_balance( const account_name& act ) { vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYMBOL).to_symbol_code().value ); - return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data)["balance"].as(); + return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); } fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); } fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data ); + return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); } void create_currency( name contract, name manager, asset maxsupply ) { @@ -375,7 +375,7 @@ class eosio_system_tester : public TESTER { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } asset get_token_supply() { @@ -385,17 +385,17 @@ class eosio_system_tester : public TESTER { fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); if (data.empty()) std::cout << "\nData is empty\n" << std::endl; - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer_max_time ); } fc::variant get_global_state2() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer_max_time ); } fc::variant get_refund_request( name account ) { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer_max_time ); } abi_serializer initialize_multisig() { @@ -418,7 +418,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def msig_abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi); + msig_abi_ser.set_abi(msig_abi, abi_serializer_max_time); } return msig_abi_ser; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 3a8a456a..325c219d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1697,7 +1697,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -1736,7 +1736,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -2457,7 +2457,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -2493,7 +2493,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 0fcc7b62..28a6b596 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -33,7 +33,7 @@ class eosio_token_tester : public tester { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) { @@ -42,7 +42,7 @@ class eosio_token_tester : public tester { action act; act.account = N(eosio.token); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), uint64_t(signer)); } @@ -52,7 +52,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } fc::variant get_account( account_name acc, const string& symbolname) @@ -60,7 +60,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); } action_result create( account_name issuer, From 2efcc4ac20a9ffe12a8b41027a97de4cdb7df61b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 10 Jul 2018 17:59:03 -0400 Subject: [PATCH 0421/1048] Fix rammarket connector weights --- eosio.system/src/exchange_state.cpp | 6 ++---- tests/eosio.system_tests.cpp | 11 +++++------ 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/eosio.system/src/exchange_state.cpp b/eosio.system/src/exchange_state.cpp index 621d3e71..b0116903 100644 --- a/eosio.system/src/exchange_state.cpp +++ b/eosio.system/src/exchange_state.cpp @@ -5,12 +5,11 @@ namespace eosiosystem { real_type R(supply.amount); real_type C(c.balance.amount+in.amount); - real_type F(c.weight/1000.0); + real_type F(c.weight); real_type T(in.amount); real_type ONE(1.0); real_type E = -R * (ONE - std::pow( ONE + T / C, F) ); - //print( "E: ", E, "\n"); int64_t issued = int64_t(E); supply.amount += issued; @@ -24,7 +23,7 @@ namespace eosiosystem { real_type R(supply.amount - in.amount); real_type C(c.balance.amount); - real_type F(1000.0/c.weight); + real_type F(1.0/c.weight); real_type E(in.amount); real_type ONE(1.0); @@ -36,7 +35,6 @@ namespace eosiosystem { // real_type T = C * std::expm1( F * std::log1p(E/R) ); real_type T = C * (std::pow( ONE + E/R, F) - ONE); - //print( "T: ", T, "\n"); int64_t out = int64_t(T); supply.amount -= in.amount; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 325c219d..b161126d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -68,7 +68,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { wdump((init_bytes)(bought_bytes)(bytes) ); BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - BOOST_REQUIRE_EQUAL( core_from_string("99901248.0041"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99901248.0048"), get_balance( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); @@ -79,7 +79,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99900688.0041"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99900688.0048"), get_balance( "alice1111111" ) ); auto newtotal = get_total_stake( "alice1111111" ); @@ -88,8 +88,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { wdump((newbytes)(bytes)(bought_bytes) ); BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99901242.4179"), get_balance( "alice1111111" ) ); - + BOOST_REQUIRE_EQUAL( core_from_string("99901242.4187"), get_balance( "alice1111111" ) ); newtotal = get_total_stake( "alice1111111" ); auto startbytes = newtotal["ram_bytes"].as_uint64(); @@ -103,7 +102,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("300000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("49301242.4179"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("49301242.4187"), get_balance( "alice1111111" ) ); auto finaltotal = get_total_stake( "alice1111111" ); auto endbytes = finaltotal["ram_bytes"].as_uint64(); @@ -113,7 +112,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99396507.4142"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_from_string("99396507.4158"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() From 6f4618fe657ccfd698918f50f56fd8f76ea90514 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 10 Jul 2018 18:07:38 -0400 Subject: [PATCH 0422/1048] Fix setramrate documentation --- eosio.system/src/eosio.system.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 223f4ef9..3fde58e4 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -96,9 +96,6 @@ namespace eosiosystem { * * If update_ram_supply hasn't been called for the most recent block, then new ram will * be allocated at the old rate up to the present block before switching the rate. - * - * This method will also resync the bancor connector balances - * and weights to the actual CORE_SYMBOL held in the eosio.ram account. */ void system_contract::setramrate( uint16_t bytes_per_block ) { require_auth( _self ); From ec9286322e786b92cfd19160afc50126d82b7c35 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 10 Jul 2018 18:29:49 -0400 Subject: [PATCH 0423/1048] Fixed to use eosio v1.0.8 install path --- UnitTestsExternalProject.txt | 2 +- build.sh | 7 ++++++- tests/CMakeLists.txt | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 2091f8d7..e66cc6b1 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,7 +4,7 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eosio -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} + CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests diff --git a/build.sh b/build.sh index 1175fdef..b7950559 100755 --- a/build.sh +++ b/build.sh @@ -5,6 +5,11 @@ printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' NC='\033[0m' +if [ ! -d "/usr/local/eosio" ]; then + printf "${RED}Error, please ensure that eosio is installed correctly!\n\n${NC}" + exit -1 +fi + if [ ! -d "/usr/local/eosio.wasmsdk" ]; then printf "${RED}Error, please ensure that eosio.wasmsdk is installed correctly!\n\n${NC}" exit -1 @@ -52,6 +57,6 @@ fi CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" ../ +cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ make -j${CORES} popd &> /dev/null diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 5c3e0d4b..bc85714e 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -117,6 +117,7 @@ target_link_libraries( unit_test target_include_directories( unit_test PUBLIC ${Boost_INCLUDE_DIRS} ${OPENSSL_INSTALL_PREFIX}/include + ${EOSIO_INSTALL_PREFIX} ${EOSIO_INSTALL_PREFIX}/include ${EOSIO_INSTALL_PREFIX}/include/eosio/wasm-jit/Include ${EOSIO_INSTALL_PREFIX}/include/eosio/softfloat/include From daa907efb187fc28b027c5b82623a1dd23dc0b22 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 10 Jul 2018 18:33:21 -0400 Subject: [PATCH 0424/1048] Revert "Fix unit test build issues" This reverts commit 9a2ae4f853e10d077f089aeabf4f5af3cf8b3db0. --- tests/eosio.msig_tests.cpp | 10 +++++----- tests/eosio.sudo_tests.cpp | 6 +++--- tests/eosio.system_tester.hpp | 26 +++++++++++++------------- tests/eosio.system_tests.cpp | 8 ++++---- tests/eosio.token_tests.cpp | 8 ++++---- 5 files changed, 29 insertions(+), 29 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index d6439d69..ce01cc85 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -36,7 +36,7 @@ class eosio_msig_tester : public tester { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi); } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, @@ -174,7 +174,7 @@ transaction eosio_msig_tester::reqauth( account_name from, const vectordb().get( N(eosio.sudo) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi); while( control->pending_block_state()->header.producer.to_string() == "eosio" ) { produce_block(); @@ -134,7 +134,7 @@ transaction eosio_sudo_tester::sudo_exec( account_name executer, const transacti transaction trx2; set_transaction_headers(trx2, expiration); action act; - abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer_max_time ); + abi_serializer::from_variant( act_obj, act, get_resolver() ); trx2.actions.push_back( std::move(act) ); return trx2; } @@ -155,7 +155,7 @@ transaction eosio_sudo_tester::reqauth( account_name from, const vectordb().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi, abi_serializer_max_time); + token_abi_ser.set_abi(abi); } create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); @@ -63,7 +63,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi); } produce_blocks(); @@ -219,7 +219,7 @@ class eosio_system_tester : public TESTER { action act; act.account = config::system_account_name; act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = abi_ser.variant_to_binary( action_type_name, data ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); } @@ -320,22 +320,22 @@ class eosio_system_tester : public TESTER { asset get_balance( const account_name& act ) { vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYMBOL).to_symbol_code().value ); - return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); + return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data)["balance"].as(); } fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data ); } fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data ); } fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); + return abi_ser.binary_to_variant( "producer_info", data ); } void create_currency( name contract, name manager, asset maxsupply ) { @@ -375,7 +375,7 @@ class eosio_system_tester : public TESTER { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data ); } asset get_token_supply() { @@ -385,17 +385,17 @@ class eosio_system_tester : public TESTER { fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); if (data.empty()) std::cout << "\nData is empty\n" << std::endl; - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); } fc::variant get_global_state2() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data ); } fc::variant get_refund_request( name account ) { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); } abi_serializer initialize_multisig() { @@ -418,7 +418,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def msig_abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi, abi_serializer_max_time); + msig_abi_ser.set_abi(msig_abi); } return msig_abi_ser; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b161126d..5bcb7e88 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1696,7 +1696,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -1735,7 +1735,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -2456,7 +2456,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -2492,7 +2492,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); + abi_serializer::from_variant(pretty_trx, trx, get_resolver()); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 28a6b596..0fcc7b62 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -33,7 +33,7 @@ class eosio_token_tester : public tester { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) { @@ -42,7 +42,7 @@ class eosio_token_tester : public tester { action act; act.account = N(eosio.token); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = abi_ser.variant_to_binary( action_type_name, data ); return base_tester::push_action( std::move(act), uint64_t(signer)); } @@ -52,7 +52,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data ); } fc::variant get_account( account_name acc, const string& symbolname) @@ -60,7 +60,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data ); } action_result create( account_name issuer, From c8b57e492b4d47e355105235479f9c1ff985671e Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 10 Jul 2018 19:07:37 -0400 Subject: [PATCH 0425/1048] Update README.md --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 83a6cb1a..e48049cb 100644 --- a/README.md +++ b/README.md @@ -16,14 +16,14 @@ The following unpriviledged contract(s) are also part of the system. Dependencies: * [eosio v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) +* [eosio.wasmsdk v1.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. * Second, make sure that you have ```sudo make install```ed __eosio__. -* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. If you want to skip building the unit tests, the option ```notests``` can be given to ```build.sh```. -* Or, you can run the ```build.sh``` in a given contract folder to only build that contract. +* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. After build: -* The unit tests executable is placed in the top directory and is named __unit_test__. +* The unit tests executable is placed in the _build/tests_ directory and is named __unit_test__. * The contracts are built into a _bin/\_ folder in their respective directories. * Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory. From 869424d498f933bf032479ed181dc4caaf22b7c4 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 11 Jul 2018 11:16:22 -0400 Subject: [PATCH 0426/1048] fixing producers_upgrade_system_contract test #10 --- tests/eosio.system_tests.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 8a40140d..89686bcd 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1707,17 +1707,17 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) for ( auto& x : producer_names ) { prod_perms.push_back( { name(x), config::active_name } ); } - //prepare system contract with different hash (contract differs in one byte) - string eosio_system_wast2 = wasm_to_wast(contracts::system_wasm(), true); - string msg = "producer votes must be unique and sorted"; - auto pos = eosio_system_wast2.find(msg); - BOOST_REQUIRE( pos != std::string::npos ); - msg[0] = 'P'; - eosio_system_wast2.replace( pos, msg.size(), msg ); transaction trx; { - auto code = contracts::system_wasm(); //wast_to_wasm( eosio_system_wast2 ); + //prepare system contract with different hash (contract differs in one byte) + auto code = contracts::system_wasm(); + string msg = "producer votes must be unique and sorted"; + auto it = std::search( code.begin(), code.end(), msg.begin(), msg.end() ); + BOOST_REQUIRE( it != code.end() ); + msg[0] = 'P'; + std::copy( msg.begin(), msg.end(), it ); + variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) From 4d1d7b57b7b48f8cd24a8cb2ae7f448b68e90430 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 11 Jul 2018 11:22:00 -0400 Subject: [PATCH 0427/1048] Added defaults to cmake variables --- CMakeLists.txt | 8 ++++++++ build.sh | 8 ++++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 62558d47..834e6c1e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,14 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts VERSION 1.0.0) +if(CXX_COMPILER STREQUAL "" OR NOT CXX_COMPILER) + set(CXX_COMPILER ${CMAKE_CXX_COMPILER}) +endif() + +if(EOSIO_INSTALL_PREFIX STREQUAL "" OR NOT EOSIO_INSTALL_PREFIX) + set(EOSIO_INSTALL_PREFIX "/usr/local") +endif() + # if no wasm root is given use default path if(WASM_ROOT STREQUAL "" OR NOT WASM_ROOT) set(WASM_ROOT ${CMAKE_INSTALL_PREFIX}) diff --git a/build.sh b/build.sh index b7950559..815e9f27 100755 --- a/build.sh +++ b/build.sh @@ -5,10 +5,10 @@ printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' NC='\033[0m' -if [ ! -d "/usr/local/eosio" ]; then - printf "${RED}Error, please ensure that eosio is installed correctly!\n\n${NC}" - exit -1 -fi +#if [ ! -d "/usr/local/eosio" ]; then +# printf "${RED}Error, please ensure that eosio is installed correctly!\n\n${NC}" +# exit -1 +#fi if [ ! -d "/usr/local/eosio.wasmsdk" ]; then printf "${RED}Error, please ensure that eosio.wasmsdk is installed correctly!\n\n${NC}" From 97d9d5884ee52f4fd3947f8c4770cf18c9726ba9 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 11 Jul 2018 11:27:52 -0400 Subject: [PATCH 0428/1048] Added support for debug test builds --- CMakeLists.txt | 6 ++++++ UnitTestsExternalProject.txt | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 834e6c1e..9aff3657 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,12 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts VERSION 1.0.0) +if(CMAKE_BUILD_TYPE STREQUAL "Debug") + set(TEST_BUILD_TYPE "Debug") + set(CMAKE_BUILD_TYPE "Release") +else() + set(TEST_BUILD_TYPE ${CMAKE_BUILD_TYPE}) +endif() if(CXX_COMPILER STREQUAL "" OR NOT CXX_COMPILER) set(CXX_COMPILER ${CMAKE_CXX_COMPILER}) endif() diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index e66cc6b1..73ccd2d9 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,7 +4,7 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests From 4aa06db4cad7b7cbed810a4e79774f0800c24ec6 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 11 Jul 2018 15:03:26 -0400 Subject: [PATCH 0429/1048] Changed link ordering Fix for unresolved references --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index bc85714e..2a22a3ea 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -64,6 +64,7 @@ find_library(libsecp256k1 secp256k1 ${SECP256K1_INSTALL_LIB}) add_executable( unit_test ${UNIT_TESTS} ) target_link_libraries( unit_test ${LLVM} + ${libtester} ${libchain} ${libfc} ${libbinaryen} @@ -79,7 +80,6 @@ target_link_libraries( unit_test ${libchainbase} ${libbuiltins} ${libsecp256k1} - ${libtester} LLVMX86Disassembler LLVMX86AsmParser From 595e99ba9ecd9c0e723378b0cd06476d4aad6364 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Jul 2018 17:25:18 -0400 Subject: [PATCH 0430/1048] Fixed comments and ricardian contract --- eosio.system/abi/eosio.system.abi | 2 +- eosio.system/src/eosio.system.cpp | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index ccbd1c3e..4e30369a 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -491,7 +491,7 @@ },{ "name": "setramrate", "type": "setramrate", - "ricardian_contract": "Sets the number of new bytes of ram to create per block and resyncs bancor connector balances and weights to eosio.ram and 50% CRR" + "ricardian_contract": "Sets the number of new bytes of ram to create per block and resyncs bancor base connector balance" },{ "name": "bidname", "type": "bidname", diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 3fde58e4..1f0b6a11 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -63,8 +63,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); /** - * Increase or decrease the amount of ram for sale based upon the change in max - * ram size. + * Increase the amount of ram for sale based upon the change in max ram size. */ _rammarket.modify( itr, 0, [&]( auto& m ) { m.base.balance.amount += delta; @@ -81,8 +80,7 @@ namespace eosiosystem { _gstate.max_ram_size += new_ram; /** - * Increase or decrease the amount of ram for sale based upon the change in max - * ram size. + * Increase the amount of ram for sale based upon the change in max ram size. */ _rammarket.modify( itr, 0, [&]( auto& m ) { m.base.balance.amount += new_ram; From a5ef132e0c661be4168a5eb993581ac486ceef9e Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 11 Jul 2018 18:28:43 -0400 Subject: [PATCH 0431/1048] change to v1.1.0 --- CMakeLists.txt | 2 +- README.md | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9aff3657..11c809ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.0.0) +project(eosio_contracts VERSION 1.1.0) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(TEST_BUILD_TYPE "Debug") diff --git a/README.md b/README.md index 83a6cb1a..37c72112 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.0.0 +## Version : 1.1.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. @@ -16,14 +16,14 @@ The following unpriviledged contract(s) are also part of the system. Dependencies: * [eosio v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) +* [eosio.wasmsdk v1.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. * Second, make sure that you have ```sudo make install```ed __eosio__. -* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. If you want to skip building the unit tests, the option ```notests``` can be given to ```build.sh```. -* Or, you can run the ```build.sh``` in a given contract folder to only build that contract. +* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. After build: -* The unit tests executable is placed in the top directory and is named __unit_test__. +* The unit tests executable is placed in the _build/tests_ and is named __unit_test__. * The contracts are built into a _bin/\_ folder in their respective directories. * Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory. From a06955b38e85ba408eadc889bc64f5d523e142b7 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 11 Jul 2018 18:30:52 -0400 Subject: [PATCH 0432/1048] Point to correct wasmsdk tag --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 37c72112..4aebc8a6 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The following unpriviledged contract(s) are also part of the system. Dependencies: * [eosio v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) -* [eosio.wasmsdk v1.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.0) +* [eosio.wasmsdk v1.0.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.0.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From d522388f75a1098f0540ff4bce2f9210462395b7 Mon Sep 17 00:00:00 2001 From: Robert Kowalski Date: Thu, 12 Jul 2018 14:34:53 +0200 Subject: [PATCH 0433/1048] add license file --- LICENSE | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..55e80764 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +Copyright (c) 2018, Respective Authors all rights reserved. + +The MIT License + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. From f3d75b318eafee2830e4d6b22c2f57d58ad05c60 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 16 Jul 2018 10:49:11 -0400 Subject: [PATCH 0434/1048] 1400 bytes RAM gift to new account #18 --- tests/eosio.system_tests.cpp | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 89686bcd..866daa1c 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2606,7 +2606,7 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { auto rlm = control->get_resource_limits_manager(); auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - //std::cout << "Sellram" << std::endl; + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 2048 ) ); //make sure that ram was billed to alice, not to eosio.ram @@ -2615,6 +2615,38 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { + active_and_vote_producers(); + + auto rlm = control->get_resource_limits_manager(); + int64_t ram_bytes_orig, net_weight, cpu_weight; + rlm.get_account_limits( N(alice1111111), ram_bytes_orig, net_weight, cpu_weight ); + + /* + * It seems impossible to write this test, because buyrambytes action doesn't give you exact amount of bytes requested + * + //check that it's possible to create account bying required_bytes(2724) + userres table(112) + userres row(160) - ram_gift_bytes(1400) + create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 ); + + //check that one byte less is not enough + BOOST_REQUIRE_THROW( create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 - 1 ), + ram_usage_exceeded ); + */ + + //check that stake/unstake keeps the gift + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + int64_t ram_bytes_after_stake; + rlm.get_account_limits( N(alice1111111), ram_bytes_after_stake, net_weight, cpu_weight ); + BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_stake ); + + BOOST_REQUIRE_EQUAL( success(), unstake( "eosio", "alice1111111", core_from_string("20.0000"), core_from_string("10.0000") ) ); + int64_t ram_bytes_after_unstake; + rlm.get_account_limits( N(alice1111111), ram_bytes_after_unstake, net_weight, cpu_weight ); + BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_unstake ); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() void translate_fc_exception(const fc::exception &e) { From 641ed30332b0032f7ab5497bdb472d525526b93b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 16 Jul 2018 10:50:16 -0400 Subject: [PATCH 0435/1048] 1400 bytes RAM gift to new account #18 --- eosio.system/src/delegate_bandwidth.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 567d3a9d..5c5f79b1 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -30,6 +30,7 @@ namespace eosiosystem { static constexpr time refund_delay = 3*24*3600; static constexpr time refund_expiration_time = 3600; + static constexpr int64_t ram_gift_bytes = 1400; struct user_resources { account_name owner; @@ -149,7 +150,7 @@ namespace eosiosystem { res.ram_bytes += bytes_out; }); } - set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } @@ -265,7 +266,10 @@ namespace eosiosystem { eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); - set_resource_limits( receiver, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + int64_t ram_bytes, net, cpu; + get_resource_limits( receiver, ram_bytes, net, cpu ); + + set_resource_limits( receiver, ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); From 9f33f25eb3de92556a33e9a4b4d67f358a92ad48 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 13:57:21 -0400 Subject: [PATCH 0436/1048] Add second producers table --- eosio.system/abi/eosio.system.abi | 14 +++++++++++++ .../include/eosio.system/eosio.system.hpp | 20 +++++++++++++++---- eosio.system/src/eosio.system.cpp | 1 + 3 files changed, 31 insertions(+), 4 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 4e30369a..6ae50df9 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -281,6 +281,14 @@ {"name":"last_claim_time", "type":"uint64"}, {"name":"location", "type":"uint16"} ] + },{ + "name": "producer_info2", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"votepay_share", "type":"float64"}, + {"name":"last_votepay_share_update", "type":"uint64"} + ] },{ "name": "regproducer", "base": "", @@ -547,6 +555,12 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["uint64"] + },{ + "name": "producers2", + "type": "producer_info2", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] },{ "name": "global", "type": "eosio_global_state", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 276a61e7..a5afc035 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -97,6 +97,17 @@ namespace eosiosystem { (unpaid_blocks)(last_claim_time)(location) ) }; + struct producer_info2 { + account_name owner; + double votepay_share = 0; + uint64_t last_votepay_share_update = 0; + + uint64_t primary_key()const { return owner; } + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) + }; + struct voter_info { account_name owner = 0; /// the voter account_name proxy = 0; /// the proxy set by the voter, if any @@ -134,6 +145,7 @@ namespace eosiosystem { typedef eosio::multi_index< N(producers), producer_info, indexed_by > > producers_table; + typedef eosio::multi_index< N(producers2), producer_info2 > producers_table2; typedef eosio::singleton global_state_singleton; typedef eosio::singleton global_state2_singleton; @@ -146,12 +158,12 @@ namespace eosiosystem { private: voters_table _voters; producers_table _producers; + producers_table2 _producers2; global_state_singleton _global; global_state2_singleton _global2; - - eosio_global_state _gstate; - eosio_global_state2 _gstate2; - rammarket _rammarket; + eosio_global_state _gstate; + eosio_global_state2 _gstate2; + rammarket _rammarket; public: system_contract( account_name s ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 1f0b6a11..645a062d 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -13,6 +13,7 @@ namespace eosiosystem { :native(s), _voters(_self,_self), _producers(_self,_self), + _producers2(_self,_self), _global(_self,_self), _global2(_self,_self), _rammarket(_self,_self) From 47ef955a21650de60a6b269f58bbdf3ee803dbf4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 14:14:35 -0400 Subject: [PATCH 0437/1048] Update eosio_global_state2 reserved field --- eosio.system/abi/eosio.system.abi | 10 +++++----- eosio.system/include/eosio.system/eosio.system.hpp | 6 +++--- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 6ae50df9..09499201 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -244,11 +244,11 @@ },{ "name": "eosio_global_state2", "fields": [ - {"name":"new_ram_per_block", "type":"uint16"}, - {"name":"last_ram_increase", "type":"block_timestamp_type"}, - {"name":"last_block_num", "type":"block_timestamp_type"}, - {"name":"reserved", "type":"float64"}, - {"name":"revision", "type":"uint8"} + {"name":"new_ram_per_block", "type":"uint16"}, + {"name":"last_ram_increase", "type":"block_timestamp_type"}, + {"name":"last_block_num", "type":"block_timestamp_type"}, + {"name":"total_producer_votepay_share", "type":"float64"}, + {"name":"revision", "type":"uint8"} ] },{ "name": "eosio_global_state", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index a5afc035..29e03b63 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -70,11 +70,11 @@ namespace eosiosystem { uint16_t new_ram_per_block = 0; block_timestamp last_ram_increase; block_timestamp last_block_num; - double reserved = 0; + double total_producer_votepay_share = 0; uint8_t revision = 0; ///< used to track version updates in the future. - - EOSLIB_SERIALIZE( eosio_global_state2, (new_ram_per_block)(last_ram_increase)(last_block_num)(reserved)(revision) ) + EOSLIB_SERIALIZE( eosio_global_state2, (new_ram_per_block)(last_ram_increase)(last_block_num) + (total_producer_votepay_share)(revision) ) }; struct producer_info { From 69d083829605ceb2146718b5d50319bb7cb12e6c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 14:50:07 -0400 Subject: [PATCH 0438/1048] Add producer votepay share calculations --- eosio.system/src/voting.cpp | 75 ++++++++++++++++++++++++++++++------- 1 file changed, 62 insertions(+), 13 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index a625dcc6..0e6caf3e 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -40,24 +40,40 @@ namespace eosiosystem { require_auth( producer ); auto prod = _producers.find( producer ); + const auto ct = current_time(); if ( prod != _producers.end() ) { _producers.modify( prod, producer, [&]( producer_info& info ){ - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; + info.producer_key = producer_key; + info.is_active = true; + info.url = url; + info.location = location; + if ( info.last_claim_time == 0 ) + info.last_claim_time = ct; + }); + + auto prod2 = _producers2.find( producer ); + if ( prod2 == _producers2.end() ) { + _producers2.emplace( producer, [&]( producer_info2& info ){ + info.owner = producer; + info.last_votepay_share_update = prod->last_claim_time; }); + } } else { _producers.emplace( producer, [&]( producer_info& info ){ - info.owner = producer; - info.total_votes = 0; - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; + info.owner = producer; + info.total_votes = 0; + info.producer_key = producer_key; + info.is_active = true; + info.url = url; + info.location = location; + info.last_claim_time = ct; + }); + _producers2.emplace( producer, [&]( producer_info2& info ){ + info.owner = producer; }); } + } void system_contract::unregprod( const account_name producer ) { @@ -66,8 +82,15 @@ namespace eosiosystem { const auto& prod = _producers.get( producer, "producer not found" ); _producers.modify( prod, 0, [&]( producer_info& info ){ - info.deactivate(); + info.deactivate(); }); + + auto prod2 = _producers2.find( producer ); + if ( prod2 == _producers2.end() ) { + _producers2.emplace( producer, [&]( producer_info2& info ){ + info.owner = producer; + }); + } } void system_contract::update_elected_producers( block_timestamp block_time ) { @@ -204,6 +227,7 @@ namespace eosiosystem { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); + double init_total_votes = pitr->total_votes; _producers.modify( pitr, 0, [&]( auto& p ) { p.total_votes += pd.second.first; if ( p.total_votes < 0 ) { // floating point arithmetics can give small negative numbers @@ -212,6 +236,18 @@ namespace eosiosystem { _gstate.total_producer_vote_weight += pd.second.first; //eosio_assert( p.total_votes >= 0, "something bad happened" ); }); + auto prod2 = _producers2.find( pd.first ); + if( prod2 != _producers2.end() ) { + _producers2.modify( prod2, 0, [&]( auto& p ) { + auto ct = current_time(); + if( ct - pitr->last_claim_time < 3 * useconds_per_day ) { + double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + _gstate2.total_producer_votepay_share += delta_votepay_share; + } + p.last_votepay_share_update = ct; + }); + } } else { eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } @@ -272,10 +308,23 @@ namespace eosiosystem { auto delta = new_weight - voter.last_vote_weight; for ( auto acnt : voter.producers ) { auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption + double init_total_votes = pitr.total_votes; _producers.modify( pitr, 0, [&]( auto& p ) { - p.total_votes += delta; - _gstate.total_producer_vote_weight += delta; + p.total_votes += delta; + _gstate.total_producer_vote_weight += delta; }); + auto prod2 = _producers2.find( acnt ); + if ( prod2 != _producers2.end() ) { + _producers2.modify( prod2, 0, [&]( auto& p ) { + auto ct = current_time(); + if( ct - pitr.last_claim_time < 3 * useconds_per_day ) { + double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + _gstate2.total_producer_votepay_share += delta_votepay_share; + } + p.last_votepay_share_update = ct; + }); + } } } } From d1cb104036f5f0f29b81657d0e08fece17ce7268 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 15:03:50 -0400 Subject: [PATCH 0439/1048] Update producer votepay to use new metric --- eosio.system/src/producer_pay.cpp | 66 +++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 11 deletions(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 39fe64ef..78570aa3 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -67,7 +67,7 @@ namespace eosiosystem { using namespace eosio; void system_contract::claimrewards( const account_name& owner ) { - require_auth(owner); + require_auth( owner ); const auto& prod = _producers.get( owner ); eosio_assert( prod.active(), "producer does not have an active key" ); @@ -75,23 +75,33 @@ namespace eosiosystem { eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" ); - auto ct = current_time(); + const auto ct = current_time(); eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" ); + if ( _producers2.find( owner ) == _producers2.end() ) { + _producers2.emplace( owner, [&]( producer_info2& info ) { + info.owner = owner; + if ( prod.last_claim_time > 0 ) + info.last_votepay_share_update = prod.last_claim_time; + else + info.last_votepay_share_update = ct; + }); + } + const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill; if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > 0 ) { auto new_tokens = static_cast( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); - auto to_producers = new_tokens / 5; - auto to_savings = new_tokens - to_producers; - auto to_per_block_pay = to_producers / 4; - auto to_per_vote_pay = to_producers - to_per_block_pay; + auto to_producers = new_tokens / 5; + auto to_savings = new_tokens - to_producers; + auto to_per_block_pay = to_producers / 4; + auto to_per_vote_pay = to_producers - to_per_block_pay; INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - {N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings")} ); + { N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings") } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, { N(eosio), N(eosio.saving), asset(to_savings), "unallocated inflation" } ); @@ -108,24 +118,58 @@ namespace eosiosystem { _gstate.last_pervote_bucket_fill = ct; } + auto prod2 = _producers2.find( owner ); + if ( prod2 == _producers2.end() ) { + prod2 = _producers2.emplace( owner, [&]( producer_info2& info ) { + info.owner = owner; + if ( prod.last_claim_time > 0 ) + info.last_votepay_share_update = prod.last_claim_time; + else + info.last_votepay_share_update = ct; + }); + } + int64_t producer_per_block_pay = 0; if( _gstate.total_unpaid_blocks > 0 ) { producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; } + + /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and + /// time duration the vote weight has been held into one metric. + double delta_votepay_share = prod.total_votes * ( double(current_time() - prod2->last_votepay_share_update) / 1000000 ); + double producer_votepay_share = prod2->votepay_share + delta_votepay_share; + double total_votepay_share = _gstate2.total_producer_votepay_share + delta_votepay_share; + int64_t producer_per_vote_pay = 0; - if( _gstate.total_producer_vote_weight > 0 ) { - producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes ) / _gstate.total_producer_vote_weight); + if( _gstate2.revision > 0 ) { + if( total_votepay_share > 0 ) { + producer_per_vote_pay = int64_t((producer_votepay_share * _gstate.pervote_bucket) / total_votepay_share); + if( producer_per_vote_pay > _gstate.pervote_bucket ) + producer_per_vote_pay = _gstate.pervote_bucket; + } + } else { + if( _gstate.total_producer_vote_weight > 0 ) { + producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes) / _gstate.total_producer_vote_weight); + } } + if( producer_per_vote_pay < min_pervote_daily_pay ) { producer_per_vote_pay = 0; } + _gstate.pervote_bucket -= producer_per_vote_pay; _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.unpaid_blocks; _producers.modify( prod, 0, [&](auto& p) { - p.last_claim_time = ct; - p.unpaid_blocks = 0; + p.last_claim_time = ct; + p.unpaid_blocks = 0; + }); + + _producers2.modify( prod2, 0, [&](auto& p) { + p.last_votepay_share_update = ct; + _gstate2.total_producer_votepay_share -= p.votepay_share; + p.votepay_share = 0; }); if( producer_per_block_pay > 0 ) { From 10c7b137a8d0416c6dc5b44297795c00f8263d71 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 15:13:31 -0400 Subject: [PATCH 0440/1048] Add updtrevision system contract action --- eosio.system/abi/eosio.system.abi | 10 ++++++++++ eosio.system/include/eosio.system/eosio.system.hpp | 2 ++ eosio.system/src/eosio.system.cpp | 8 +++++++- 3 files changed, 19 insertions(+), 1 deletion(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 09499201..a754f911 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -362,6 +362,12 @@ "fields": [ {"name":"producer", "type":"account_name"} ] + },{ + "name": "updtrevision", + "base": "", + "fields": [ + {"name":"revision", "type":"uint8"} + ] },{ "name": "set_account_limits", "base": "", @@ -528,6 +534,10 @@ "name": "rmvproducer", "type": "rmvproducer", "ricardian_contract": "" + },{ + "name": "updtrevision", + "type": "updtrevision", + "ricardian_contract": "" },{ "name": "setalimits", "type": "set_account_limits", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 29e03b63..9a22aaf0 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -245,6 +245,8 @@ namespace eosiosystem { void setpriv( account_name account, uint8_t ispriv ); void rmvproducer( account_name producer ); + + void updtrevision( uint8_t revision ); void bidname( account_name bidder, account_name newname, asset bid ); private: diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 645a062d..3e1851de 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -128,6 +128,12 @@ namespace eosiosystem { }); } + void system_contract::updtrevision( uint8_t revision ) { + require_auth( _self ); + eosio_assert( revision == _gstate2.revision + 1, "can only increment revision by one" ); + _gstate2.revision = revision; + } + void system_contract::bidname( account_name bidder, account_name newname, asset bid ) { require_auth( bidder ); eosio_assert( eosio::name_suffix(newname) == newname, "you can only bid on top-level suffix" ); @@ -223,7 +229,7 @@ EOSIO_ABI( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror) // eosio.system.cpp - (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(bidname) + (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(updtrevision)(bidname) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp From ecccabf0ec75c61faef2f99fcc2dbac568d5471d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 15:48:28 -0400 Subject: [PATCH 0441/1048] Update system contract unit tests --- tests/eosio.system_tester.hpp | 6 +++- tests/eosio.system_tests.cpp | 68 +++++++++++++++++++++++++++++++++-- 2 files changed, 71 insertions(+), 3 deletions(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 7ce52211..af38fe56 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -338,6 +338,11 @@ class eosio_system_tester : public TESTER { return abi_ser.binary_to_variant( "producer_info", data ); } + fc::variant get_producer_info2( const account_name& act ) { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers2), act ); + return abi_ser.binary_to_variant( "producer_info2", data ); + } + void create_currency( name contract, name manager, asset maxsupply ) { auto act = mutable_variant_object() ("issuer", manager ) @@ -384,7 +389,6 @@ class eosio_system_tester : public TESTER { fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); - if (data.empty()) std::cout << "\nData is empty\n" << std::endl; return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index ac21342b..08eda85d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1202,6 +1202,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t create_account_with_resources( N(producvoterb), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); + produce_block(fc::hours(24)); auto prod = get_producer_info( N(defproducera) ); BOOST_REQUIRE_EQUAL("defproducera", prod["owner"].as_string()); BOOST_REQUIRE_EQUAL(0, prod["total_votes"].as_double()); @@ -1225,7 +1226,6 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t prod = get_producer_info("defproducera"); const uint32_t unpaid_blocks = prod["unpaid_blocks"].as(); BOOST_REQUIRE(1 < unpaid_blocks); - BOOST_REQUIRE_EQUAL(0, prod["last_claim_time"].as()); BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); @@ -1359,6 +1359,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t { regproducer(N(defproducerb)); regproducer(N(defproducerc)); + produce_block(fc::hours(24)); const asset initial_supply = get_token_supply(); const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); for (uint32_t i = 0; i < 7 * 52; ++i) { @@ -1422,6 +1423,8 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni } } + produce_block( fc::hours(24) ); + // producvotera votes for defproducera ... defproducerj // producvoterb votes for defproducera ... defproduceru // producvoterc votes for defproducera ... defproducerz @@ -1442,7 +1445,6 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni auto prodz = get_producer_info( N(defproducerz) ); BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); - BOOST_REQUIRE (0 == proda["last_claim_time"].as() && 0 == prodz["last_claim_time"].as()); // check vote ratios BOOST_REQUIRE ( 0 < proda["total_votes"].as() && 0 < prodz["total_votes"].as() ); @@ -1682,6 +1684,66 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni push_action( config::system_account_name, N(rmvproducer), mvo()("producer", "nonexistingp") ) ); } + produce_block(fc::hours(24)); + + // switch to new producer pay metric + { + BOOST_REQUIRE_EQUAL( 0, get_global_state2()["revision"].as() ); + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), + push_action(producer_names[1], N(updtrevision), mvo()("revision", 1) ) ); + BOOST_REQUIRE_EQUAL( success(), + push_action(config::system_account_name, N(updtrevision), mvo()("revision", 1) ) ); + BOOST_REQUIRE_EQUAL( 1, get_global_state2()["revision"].as() ); + + const uint32_t prod_index = 2; + const auto prod_name = producer_names[prod_index]; + + const auto initial_prod_info = get_producer_info(prod_name); + const auto initial_global_state = get_global_state(); + const double initial_tot_votepay_share = get_global_state2()["total_producer_votepay_share"].as_double(); + const uint64_t initial_bucket_fill_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); + const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); + const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); + const asset initial_supply = get_token_supply(); + const asset initial_balance = get_balance(prod_name); + const uint32_t initial_unpaid_blocks = initial_prod_info["unpaid_blocks"].as(); + const uint64_t initial_claim_time = initial_prod_info["last_claim_time"].as_uint64(); + + BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); + BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); + + const auto prod_info = get_producer_info(prod_name); + const auto global_state = get_global_state(); + const uint64_t bucket_fill_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const int64_t pervote_bucket = global_state["pervote_bucket"].as(); + const int64_t perblock_bucket = global_state["perblock_bucket"].as(); + const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); + const asset supply = get_token_supply(); + const asset balance = get_balance(prod_name); + const uint32_t unpaid_blocks = prod_info["unpaid_blocks"].as(); + const uint64_t claim_time = prod_info["last_claim_time"].as_uint64(); + + const uint64_t usecs_between_fills = bucket_fill_time - initial_bucket_fill_time; + const uint64_t secs_between_claims = (claim_time - initial_claim_time) / 1000000; + const double votepay_share = secs_between_claims * prod_info["total_votes"].as_double(); + const double tot_votepay_share = initial_tot_votepay_share + votepay_share; + + const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) + + initial_perblock_bucket; + const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) + + initial_pervote_bucket; + const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; + const int64_t from_pervote_bucket = int64_t( ( votepay_share / tot_votepay_share ) * expected_pervote_bucket ); + + const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; + BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); + + BOOST_REQUIRE_EQUAL( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ); + BOOST_REQUIRE_EQUAL( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); + } + } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { @@ -1809,6 +1871,8 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { for (auto a:producer_names) regproducer(a); + produce_block(fc::hours(24)); + BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.front() )["total_votes"].as()); BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.back() )["total_votes"].as()); From 4446a0b0b27ce288872b2f0b38fbde00cb7af7df Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 16:06:56 -0400 Subject: [PATCH 0442/1048] Add producer votepay unit tests --- tests/eosio.system_tests.cpp | 204 +++++++++++++++++++++++++++++++++++ 1 file changed, 204 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 08eda85d..9b9935f6 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1746,6 +1746,210 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni } FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; + for (const auto& v: voters) { + create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + } + + // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + { + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'z'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + } + { + const std::string root("abcproducer"); + for ( char c = 'a'; c <= 'n'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + } + setup_producer_accounts(producer_names); + for (const auto& p: producer_names) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + produce_blocks(1); + ilog( "------ get pro----------" ); + wdump((p)); + BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); + BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); + BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["last_votepay_share_update"].as_uint64()); + } + } + + produce_block( fc::hours(24) ); + + // producvotera votes for defproducera ... defproducerj + // producvoterb votes for defproducera ... defproduceru + // producvoterc votes for defproducera ... defproducerz + // producvoterd votes for abcproducera ... abcproducern + { + BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+10)) ); + produce_block( fc::hours(10) ); + BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); + const auto& init_info = get_producer_info(producer_names[0]); + const auto& init_info2 = get_producer_info2(producer_names[0]); + uint64_t init_update = init_info2["last_votepay_share_update"].as_uint64(); + double init_votes = init_info["total_votes"].as_double(); + BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21)) ); + const auto& info = get_producer_info(producer_names[0]); + const auto& info2 = get_producer_info2(producer_names[0]); + BOOST_TEST_REQUIRE( ((info2["last_votepay_share_update"].as_uint64() - init_update)/double(1E6)) * init_votes == info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( info2["votepay_share"].as_double() * 10, get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[11])["votepay_share"].as_double() ); + produce_block( fc::hours(13) ); + BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.begin()+26)) ); + BOOST_REQUIRE( 0 < get_producer_info2(producer_names[11])["votepay_share"].as_double() ); + BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end())) ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[26])["votepay_share"].as_double() ); + } + + { + auto proda = get_producer_info( N(defproducera) ); + auto prodj = get_producer_info( N(defproducerj) ); + auto prodk = get_producer_info( N(defproducerk) ); + auto produ = get_producer_info( N(defproduceru) ); + auto prodv = get_producer_info( N(defproducerv) ); + auto prodz = get_producer_info( N(defproducerz) ); + + BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); + + // check vote ratios + BOOST_REQUIRE ( 0 < proda["total_votes"].as_double() && 0 < prodz["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( proda["total_votes"].as_double() == prodj["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( prodk["total_votes"].as_double() == produ["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( prodv["total_votes"].as_double() == prodz["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( 2 * proda["total_votes"].as_double() == 3 * produ["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( proda["total_votes"].as_double() == 3 * prodz["total_votes"].as_double() ); + } + + std::vector vote_shares(producer_names.size()); + { + double total_votes = 0; + for (uint32_t i = 0; i < producer_names.size(); ++i) { + vote_shares[i] = get_producer_info(producer_names[i])["total_votes"].as_double(); + total_votes += vote_shares[i]; + } + BOOST_TEST( total_votes == get_global_state()["total_producer_vote_weight"].as_double() ); + std::for_each(vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; }); + + BOOST_TEST_REQUIRE( double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0)) ); + BOOST_TEST_REQUIRE( double(3./71.) == vote_shares.front() ); + BOOST_TEST_REQUIRE( double(1./71.) == vote_shares.back() ); + } + + std::vector votepay_shares(producer_names.size()); + { + double total_votepay_shares = 0; + for (uint32_t i = 0; i < producer_names.size(); ++i) { + votepay_shares[i] = get_producer_info2(producer_names[i])["votepay_share"].as_double(); + total_votepay_shares += votepay_shares[i]; + } + BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); + } + + { + const uint32_t prod_index = 15; + const account_name prod_name = producer_names[prod_index]; + const auto& init_info = get_producer_info(prod_name); + const auto& init_info2 = get_producer_info2(prod_name); + BOOST_REQUIRE( 0 < init_info2["votepay_share"].as_double() ); + BOOST_REQUIRE( 0 < init_info2["last_votepay_share_update"].as_uint64() ); + + BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name)) ); + + BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); + BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_uint64(), + get_producer_info2(prod_name)["last_votepay_share_update"].as_uint64() ); + double total_votepay_shares = 0; + for (uint32_t i = 0; i < producer_names.size(); ++i) { + total_votepay_shares += get_producer_info2(producer_names[i])["votepay_share"].as_double(); + } + BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); + } + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_test::tolerance(1e-5)) try { + + cross_15_percent_threshold(); + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + } + const auto alice = accounts[0]; + const auto bob = accounts[1]; + const auto carol = accounts[2]; + + // alice becomes a proxy + BOOST_REQUIRE_EQUAL( success(), push_action( alice, N(regproxy), mvo()("proxy", alice)("isproxy", true) ) ); + REQUIRE_MATCHING_OBJECT( proxy( alice ), get_voter_info( alice ) ); + + // carol becomes a producer + BOOST_REQUIRE_EQUAL( success(), regproducer( carol, 1) ); + + // bob chooses alice as a proxy + BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0002"), core_from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( alice, core_from_string("150.0000"), core_from_string("150.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_voter_info(alice)["proxied_vote_weight"].as_double() ); + + BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); + double total_votes = get_producer_info(carol)["total_votes"].as_double(); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == total_votes ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); + uint64_t last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); + produce_block( fc::hours(15) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); + auto cur_info2 = get_producer_info2(carol); + double expected_votepay_share = ( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1000000 ) * total_votes; + BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == get_producer_info(carol)["total_votes"].as_double() ); + last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); + total_votes = get_producer_info(carol)["total_votes"].as_double(); + + produce_block( fc::hours(40) ); + BOOST_REQUIRE_EQUAL( success(), unstake( bob, core_from_string("10.0002"), core_from_string("10.0001") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); + + cur_info2 = get_producer_info2(carol); + expected_votepay_share += ( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1000000 ) * total_votes; + BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); + total_votes = get_producer_info(carol)["total_votes"].as_double(); + + BOOST_REQUIRE_EQUAL( success(), push_action(carol, N(claimrewards), mvo()("owner", carol)) ); + + produce_block( fc::hours(20) ); + BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); + BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); + cur_info2 = get_producer_info2(carol); + expected_votepay_share = ( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1000000 ) * total_votes; + BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + + produce_block( fc::hours(53) ); + BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_producer_info2(carol)["votepay_share"].as_double() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { //install multisig contract abi_serializer msig_abi_ser = initialize_multisig(); From 268f9f761eabfc37d0cd010e76775b07b2b7ec66 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 18 Jul 2018 17:31:16 -0400 Subject: [PATCH 0443/1048] Add table transition unit test --- tests/eosio.system_tests.cpp | 60 ++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 9b9935f6..697e4a74 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1950,6 +1950,66 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; + for (const auto& v: voters) { + create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + } + + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + { + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'd'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + } + setup_producer_accounts(producer_names); + for (const auto& p: producer_names) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); + BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); + BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["last_votepay_share_update"].as_uint64()); + } + } + + BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); + auto* tbl = control->db().find( boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); + BOOST_REQUIRE( tbl ); + BOOST_REQUIRE( 0 < get_producer_info2("defproducera")["last_votepay_share_update"].as_uint64() ); + + control->db().remove( *tbl ); + tbl = control->db().find( boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); + BOOST_REQUIRE( !tbl ); + + BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); + tbl = control->db().find( boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); + BOOST_REQUIRE( !tbl ); + BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducera)) ); + BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducera))["last_claim_time"].as_uint64(), + get_producer_info2(N(defproducera))["last_votepay_share_update"].as_uint64() ); + + create_account_with_resources( N(defproducer1), config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducer1)) ); + BOOST_REQUIRE( 0 < get_producer_info(N(defproducer1))["last_claim_time"].as_uint64() ); + BOOST_REQUIRE_EQUAL( 0, get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_uint64() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { //install multisig contract abi_serializer msig_abi_ser = initialize_multisig(); From b30a7b3773a4a10a99d0dab1c76c2757ce6ea7c2 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 19 Jul 2018 16:50:41 -0400 Subject: [PATCH 0444/1048] use lower_bound to find top open bid #21 --- eosio.system/src/producer_pay.cpp | 2 +- tests/eosio.system_tester.hpp | 1 + tests/eosio.system_tests.cpp | 15 +++++++++++++++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 39fe64ef..84e2444a 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -50,7 +50,7 @@ namespace eosiosystem { if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { name_bid_table bids(_self,_self); auto idx = bids.get_index(); - auto highest = idx.begin(); + auto highest = idx.lower_bound( std::numeric_limits::max()/2 ); if( highest != idx.end() && highest->high_bid > 0 && highest->last_bid_time < (current_time() - useconds_per_day) && diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 7ce52211..d2896a39 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -518,6 +518,7 @@ class eosio_system_tester : public TESTER { trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); trx.sign( get_private_key( N(producer1111), "active" ), control->get_chain_id() ); push_transaction( trx ); + produce_block(); } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index ac21342b..b8f5380d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2367,6 +2367,21 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( namebid_pending_winner, eosio_system_tester ) try { + cross_15_percent_threshold(); + produce_block( fc::hours(14*24) ); //wait 14 day for name auction activation + transfer( config::system_account_name, N(alice1111111), core_from_string("10000.0000") ); + transfer( config::system_account_name, N(bob111111111), core_from_string("10000.0000") ); + + BOOST_REQUIRE_EQUAL( success(), bidname( "alice1111111", "prefa", core_from_string( "50.0000" ) )); + BOOST_REQUIRE_EQUAL( success(), bidname( "bob111111111", "prefb", core_from_string( "30.0000" ) )); + produce_block( fc::hours(100) ); //should close "perfa" + produce_block( fc::hours(100) ); //should close "perfb" + + //despite "perfa" account hasn't been created, we should be able to create "perfb" account + create_account_with_resources( N(prefb), N(bob111111111) ); +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { const asset net = core_from_string("80.0000"); From feff971d259b03bbce48582a773349991bc2cb6f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 19 Jul 2018 17:10:17 -0400 Subject: [PATCH 0445/1048] Change global state updates --- eosio.system/abi/eosio.system.abi | 12 ++++++ .../include/eosio.system/eosio.system.hpp | 11 +++++ eosio.system/src/eosio.system.cpp | 3 ++ eosio.system/src/producer_pay.cpp | 10 +++-- eosio.system/src/voting.cpp | 41 ++++++++++++------- 5 files changed, 59 insertions(+), 18 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index a754f911..baa4e894 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -250,6 +250,12 @@ {"name":"total_producer_votepay_share", "type":"float64"}, {"name":"revision", "type":"uint8"} ] + },{ + "name": "eosio_global_state3", + "fields": [ + {"name":"last_vpay_state_update", "type":"uint64"}, + {"name":"total_vpay_share_change_rate", "type":"float64"} + ] },{ "name": "eosio_global_state", "base": "blockchain_parameters", @@ -583,6 +589,12 @@ "index_type": "i64", "key_names" : [], "key_types" : [] + },{ + "name": "global3", + "type": "eosio_global_state3", + "index_type": "i64", + "key_names" : [], + "key_types" : [] },{ "name": "voters", "type": "voter_info", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 9a22aaf0..d3c68aee 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -77,6 +77,14 @@ namespace eosiosystem { (total_producer_votepay_share)(revision) ) }; + struct eosio_global_state3 { + eosio_global_state3() { } + uint64_t last_vpay_state_update = 0; + double total_vpay_share_change_rate = 0; + + EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) + }; + struct producer_info { account_name owner; double total_votes = 0; @@ -149,6 +157,7 @@ namespace eosiosystem { typedef eosio::singleton global_state_singleton; typedef eosio::singleton global_state2_singleton; + typedef eosio::singleton global_state3_singleton; // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; @@ -161,8 +170,10 @@ namespace eosiosystem { producers_table2 _producers2; global_state_singleton _global; global_state2_singleton _global2; + global_state3_singleton _global3; eosio_global_state _gstate; eosio_global_state2 _gstate2; + eosio_global_state3 _gstate3; rammarket _rammarket; public: diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 3e1851de..81f02153 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -16,11 +16,13 @@ namespace eosiosystem { _producers2(_self,_self), _global(_self,_self), _global2(_self,_self), + _global3(_self,_self), _rammarket(_self,_self) { //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; + _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; auto itr = _rammarket.find(S(4,RAMCORE)); @@ -51,6 +53,7 @@ namespace eosiosystem { system_contract::~system_contract() { _global.set( _gstate, _self ); _global2.set( _gstate2, _self ); + _global3.set( _gstate3, _self ); } void system_contract::setram( uint64_t max_ram_size ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 78570aa3..52d6e9a8 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -136,14 +136,15 @@ namespace eosiosystem { /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and /// time duration the vote weight has been held into one metric. - double delta_votepay_share = prod.total_votes * ( double(current_time() - prod2->last_votepay_share_update) / 1000000 ); - double producer_votepay_share = prod2->votepay_share + delta_votepay_share; - double total_votepay_share = _gstate2.total_producer_votepay_share + delta_votepay_share; + double delta_votepay_share = prod.total_votes * ( double(current_time() - prod2->last_votepay_share_update) / 1E6 ); + double delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update)/1E6) ; + double votepay_share = prod2->votepay_share + delta_votepay_share; + double total_votepay_share = _gstate2.total_producer_votepay_share + delta_total_votepay_share; int64_t producer_per_vote_pay = 0; if( _gstate2.revision > 0 ) { if( total_votepay_share > 0 ) { - producer_per_vote_pay = int64_t((producer_votepay_share * _gstate.pervote_bucket) / total_votepay_share); + producer_per_vote_pay = int64_t((votepay_share * _gstate.pervote_bucket) / total_votepay_share); if( producer_per_vote_pay > _gstate.pervote_bucket ) producer_per_vote_pay = _gstate.pervote_bucket; } @@ -169,6 +170,7 @@ namespace eosiosystem { _producers2.modify( prod2, 0, [&](auto& p) { p.last_votepay_share_update = ct; _gstate2.total_producer_votepay_share -= p.votepay_share; + _gstate3.last_vpay_state_update = ct; p.votepay_share = 0; }); diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 0e6caf3e..368fc71e 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -222,7 +222,9 @@ namespace eosiosystem { } } } - + + const auto ct = current_time(); + bool update = false; for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { @@ -238,20 +240,25 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( pd.first ); if( prod2 != _producers2.end() ) { + update = true; _producers2.modify( prod2, 0, [&]( auto& p ) { - auto ct = current_time(); - if( ct - pitr->last_claim_time < 3 * useconds_per_day ) { - double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - _gstate2.total_producer_votepay_share += delta_votepay_share; + if ( ct - pitr->last_claim_time < 2 * useconds_per_day ) { + double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update) / 1E6) ; + p.last_votepay_share_update = ct; + _gstate3.total_vpay_share_change_rate += pd.second.first; } - p.last_votepay_share_update = ct; }); } } else { eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } } + + if ( update ) { + _gstate3.last_vpay_state_update = ct; + } _voters.modify( voter, 0, [&]( auto& av ) { av.last_vote_weight = new_vote_weight; @@ -306,26 +313,32 @@ namespace eosiosystem { propagate_weight_change( proxy ); } else { auto delta = new_weight - voter.last_vote_weight; + bool update = false; + const auto ct = current_time(); for ( auto acnt : voter.producers ) { auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption - double init_total_votes = pitr.total_votes; + const double init_total_votes = pitr.total_votes; _producers.modify( pitr, 0, [&]( auto& p ) { p.total_votes += delta; _gstate.total_producer_vote_weight += delta; }); auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { + update = true; _producers2.modify( prod2, 0, [&]( auto& p ) { - auto ct = current_time(); - if( ct - pitr.last_claim_time < 3 * useconds_per_day ) { - double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - _gstate2.total_producer_votepay_share += delta_votepay_share; + if ( ct - pitr.last_claim_time < 2 * useconds_per_day ) { + double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update)/1E6) ; + p.last_votepay_share_update = ct; + _gstate3.total_vpay_share_change_rate += delta; } - p.last_votepay_share_update = ct; }); } } + if ( update ) { + _gstate3.last_vpay_state_update = ct; + } } } _voters.modify( voter, 0, [&]( auto& v ) { From 65feffa8fb962e669e7071026a5b635e3156f916 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 19 Jul 2018 18:43:03 -0400 Subject: [PATCH 0446/1048] Global state testing --- eosio.system/src/voting.cpp | 16 ++++++++++------ tests/eosio.system_tester.hpp | 5 +++++ tests/eosio.system_tests.cpp | 5 +++-- 3 files changed, 18 insertions(+), 8 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 368fc71e..1f2db19a 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -225,6 +225,7 @@ namespace eosiosystem { const auto ct = current_time(); bool update = false; + double delta_change_rate = 0; for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { @@ -242,12 +243,12 @@ namespace eosiosystem { if( prod2 != _producers2.end() ) { update = true; _producers2.modify( prod2, 0, [&]( auto& p ) { - if ( ct - pitr->last_claim_time < 2 * useconds_per_day ) { + if ( ct - pitr->last_claim_time < 3 * useconds_per_day ) { double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); p.votepay_share += delta_votepay_share; _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update) / 1E6) ; p.last_votepay_share_update = ct; - _gstate3.total_vpay_share_change_rate += pd.second.first; + delta_change_rate += pd.second.first; } }); } @@ -257,7 +258,8 @@ namespace eosiosystem { } if ( update ) { - _gstate3.last_vpay_state_update = ct; + _gstate3.last_vpay_state_update = ct; + _gstate3.total_vpay_share_change_rate += delta_change_rate; } _voters.modify( voter, 0, [&]( auto& av ) { @@ -315,6 +317,7 @@ namespace eosiosystem { auto delta = new_weight - voter.last_vote_weight; bool update = false; const auto ct = current_time(); + double delta_change_rate = 0; for ( auto acnt : voter.producers ) { auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption const double init_total_votes = pitr.total_votes; @@ -326,18 +329,19 @@ namespace eosiosystem { if ( prod2 != _producers2.end() ) { update = true; _producers2.modify( prod2, 0, [&]( auto& p ) { - if ( ct - pitr.last_claim_time < 2 * useconds_per_day ) { + if ( ct - pitr.last_claim_time < 3 * useconds_per_day ) { double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); p.votepay_share += delta_votepay_share; _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update)/1E6) ; p.last_votepay_share_update = ct; - _gstate3.total_vpay_share_change_rate += delta; + delta_change_rate += delta; } }); } } if ( update ) { - _gstate3.last_vpay_state_update = ct; + _gstate3.last_vpay_state_update = ct; + _gstate3.total_vpay_share_change_rate += delta_change_rate; } } } diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index af38fe56..1636d1bf 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -397,6 +397,11 @@ class eosio_system_tester : public TESTER { return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data ); } + fc::variant get_global_state3() { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global3), N(global3) ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data ); + } + fc::variant get_refund_request( name account ) { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 697e4a74..780278f0 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1793,6 +1793,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * // producvoterc votes for defproducera ... defproducerz // producvoterd votes for abcproducera ... abcproducern { + BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+10)) ); produce_block( fc::hours(10) ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); @@ -1854,7 +1855,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * votepay_shares[i] = get_producer_info2(producer_names[i])["votepay_share"].as_double(); total_votepay_shares += votepay_shares[i]; } - BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); + // BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); } { @@ -1874,7 +1875,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * for (uint32_t i = 0; i < producer_names.size(); ++i) { total_votepay_shares += get_producer_info2(producer_names[i])["votepay_share"].as_double(); } - BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); + // BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); } } FC_LOG_AND_RETHROW() From f60515e92bebc81f0094a2d5222cdf462b89dabd Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 20 Jul 2018 10:11:54 -0400 Subject: [PATCH 0447/1048] ram gift fixes after review #18 --- UnitTestsExternalProject.txt | 4 ++++ build.sh | 2 +- eosio.system/src/delegate_bandwidth.cpp | 4 ++-- tests/eosio.system_tests.cpp | 13 +++++++++++++ 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 73ccd2d9..71b6abc1 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -5,6 +5,10 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} +# CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} +# CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} +# CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} -DCMAKE_BUILD_TYPE=Debug +# CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eos -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${Boost_INCLUDE_DIRS}/../ -DCMAKE_BUILD_TYPE=Debug SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests diff --git a/build.sh b/build.sh index 815e9f27..f6fa4e38 100755 --- a/build.sh +++ b/build.sh @@ -57,6 +57,6 @@ fi CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ +cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ -DCMAKE_BUILD_TYPE=Debug make -j${CORES} popd &> /dev/null diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index b81217de..12fcd2ee 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -192,7 +192,7 @@ namespace eosiosystem { userres.modify( res_itr, account, [&]( auto& res ) { res.ram_bytes -= bytes; }); - set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.ram),N(active)},{account,N(active)}}, { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); @@ -274,7 +274,7 @@ namespace eosiosystem { int64_t ram_bytes, net, cpu; get_resource_limits( receiver, ram_bytes, net, cpu ); - set_resource_limits( receiver, ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + set_resource_limits( receiver, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 72f91169..95a2700f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2678,6 +2678,19 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { rlm.get_account_limits( N(alice1111111), ram_bytes_after_unstake, net_weight, cpu_weight ); BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_unstake ); + uint64_t ram_gift = 1400; + + int64_t ram_bytes; + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("1000.0000") ) ); + rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); + auto userres = get_total_stake( N(alice1111111) ); + BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); + + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 1024 ) ); + rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); + userres = get_total_stake( N(alice1111111) ); + BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); + } FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_SUITE_END() From acc0d18a9306fd88aa210abd31212d37ac6e83b5 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 20 Jul 2018 11:51:40 -0400 Subject: [PATCH 0448/1048] unintentional changes reverted #18 --- UnitTestsExternalProject.txt | 4 ---- build.sh | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 71b6abc1..73ccd2d9 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -5,10 +5,6 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} -# CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} -# CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} -# CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} -DCMAKE_BUILD_TYPE=Debug -# CMAKE_ARGS -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${WASM_ROOT}/eos -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${Boost_INCLUDE_DIRS}/../ -DCMAKE_BUILD_TYPE=Debug SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests diff --git a/build.sh b/build.sh index f6fa4e38..815e9f27 100755 --- a/build.sh +++ b/build.sh @@ -57,6 +57,6 @@ fi CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ -DCMAKE_BUILD_TYPE=Debug +cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ make -j${CORES} popd &> /dev/null From 918b2e9a859209363936e4254469e30a1cbfd365 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 20 Jul 2018 19:12:10 -0400 Subject: [PATCH 0449/1048] Global state testing - 2 --- eosio.system/src/producer_pay.cpp | 16 +++++------ eosio.system/src/voting.cpp | 20 ++++++------- tests/eosio.system_tests.cpp | 48 ++++++++++++++++++++++--------- 3 files changed, 52 insertions(+), 32 deletions(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 52d6e9a8..29f30290 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -136,21 +136,21 @@ namespace eosiosystem { /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and /// time duration the vote weight has been held into one metric. - double delta_votepay_share = prod.total_votes * ( double(current_time() - prod2->last_votepay_share_update) / 1E6 ); - double delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update)/1E6) ; + double delta_votepay_share = prod.total_votes * double( (ct - prod2->last_votepay_share_update) / 1E6 ); + double delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6) ; double votepay_share = prod2->votepay_share + delta_votepay_share; double total_votepay_share = _gstate2.total_producer_votepay_share + delta_total_votepay_share; int64_t producer_per_vote_pay = 0; if( _gstate2.revision > 0 ) { if( total_votepay_share > 0 ) { - producer_per_vote_pay = int64_t((votepay_share * _gstate.pervote_bucket) / total_votepay_share); + producer_per_vote_pay = int64_t((votepay_share * _gstate.pervote_bucket) / total_votepay_share); if( producer_per_vote_pay > _gstate.pervote_bucket ) producer_per_vote_pay = _gstate.pervote_bucket; } } else { if( _gstate.total_producer_vote_weight > 0 ) { - producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes) / _gstate.total_producer_vote_weight); + producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes) / _gstate.total_producer_vote_weight); } } @@ -168,10 +168,10 @@ namespace eosiosystem { }); _producers2.modify( prod2, 0, [&](auto& p) { - p.last_votepay_share_update = ct; - _gstate2.total_producer_votepay_share -= p.votepay_share; - _gstate3.last_vpay_state_update = ct; - p.votepay_share = 0; + _gstate2.total_producer_votepay_share += ( delta_total_votepay_share - p.votepay_share - delta_votepay_share ); + _gstate3.last_vpay_state_update = ct; + p.votepay_share = 0; + p.last_votepay_share_update = ct; }); if( producer_per_block_pay > 0 ) { diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 1f2db19a..0be8bc81 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -224,7 +224,7 @@ namespace eosiosystem { } const auto ct = current_time(); - bool update = false; + bool update_global = false; double delta_change_rate = 0; for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); @@ -241,12 +241,11 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( pd.first ); if( prod2 != _producers2.end() ) { - update = true; + update_global = true; _producers2.modify( prod2, 0, [&]( auto& p ) { if ( ct - pitr->last_claim_time < 3 * useconds_per_day ) { - double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); p.votepay_share += delta_votepay_share; - _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update) / 1E6) ; p.last_votepay_share_update = ct; delta_change_rate += pd.second.first; } @@ -257,7 +256,8 @@ namespace eosiosystem { } } - if ( update ) { + if ( update_global ) { + _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; _gstate3.last_vpay_state_update = ct; _gstate3.total_vpay_share_change_rate += delta_change_rate; } @@ -315,7 +315,7 @@ namespace eosiosystem { propagate_weight_change( proxy ); } else { auto delta = new_weight - voter.last_vote_weight; - bool update = false; + bool update_global = false; const auto ct = current_time(); double delta_change_rate = 0; for ( auto acnt : voter.producers ) { @@ -327,19 +327,19 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { - update = true; + update_global = true; _producers2.modify( prod2, 0, [&]( auto& p ) { if ( ct - pitr.last_claim_time < 3 * useconds_per_day ) { - double delta_votepay_share = init_total_votes * ( double(ct - p.last_votepay_share_update) / 1E6 ); + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); p.votepay_share += delta_votepay_share; - _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * (double(ct - _gstate3.last_vpay_state_update)/1E6) ; p.last_votepay_share_update = ct; delta_change_rate += delta; } }); } } - if ( update ) { + if ( update_global ) { + _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; _gstate3.last_vpay_state_update = ct; _gstate3.total_vpay_share_change_rate += delta_change_rate; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 780278f0..71131e67 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1805,11 +1805,13 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * const auto& info = get_producer_info(producer_names[0]); const auto& info2 = get_producer_info2(producer_names[0]); BOOST_TEST_REQUIRE( ((info2["last_votepay_share_update"].as_uint64() - init_update)/double(1E6)) * init_votes == info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( info2["votepay_share"].as_double() * 10, get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( info2["votepay_share"].as_double() * 10 == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[11])["votepay_share"].as_double() ); produce_block( fc::hours(13) ); BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.begin()+26)) ); BOOST_REQUIRE( 0 < get_producer_info2(producer_names[11])["votepay_share"].as_double() ); + produce_block( fc::hours(1) ); BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end())) ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[26])["votepay_share"].as_double() ); } @@ -1840,24 +1842,35 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * vote_shares[i] = get_producer_info(producer_names[i])["total_votes"].as_double(); total_votes += vote_shares[i]; } - BOOST_TEST( total_votes == get_global_state()["total_producer_vote_weight"].as_double() ); - std::for_each(vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; }); - + BOOST_TEST_REQUIRE( total_votes == get_global_state()["total_producer_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); + BOOST_REQUIRE_EQUAL( get_producer_info2(producer_names.back())["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); + + std::for_each( vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; } ); BOOST_TEST_REQUIRE( double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0)) ); BOOST_TEST_REQUIRE( double(3./71.) == vote_shares.front() ); BOOST_TEST_REQUIRE( double(1./71.) == vote_shares.back() ); } - + std::vector votepay_shares(producer_names.size()); { - double total_votepay_shares = 0; - for (uint32_t i = 0; i < producer_names.size(); ++i) { - votepay_shares[i] = get_producer_info2(producer_names[i])["votepay_share"].as_double(); - total_votepay_shares += votepay_shares[i]; + const auto& gs3 = get_global_state3(); + double total_votepay_shares = 0; + double expected_total_votepay_shares = 0; + for (uint32_t i = 0; i < producer_names.size() ; ++i) { + const auto& info = get_producer_info(producer_names[i]); + const auto& info2 = get_producer_info2(producer_names[i]); + votepay_shares[i] = info2["votepay_share"].as_double(); + total_votepay_shares += votepay_shares[i]; + expected_total_votepay_shares += votepay_shares[i]; + expected_total_votepay_shares += info["total_votes"].as_double() * double( ( gs3["last_vpay_state_update"].as_uint64() - + info2["last_votepay_share_update"].as_uint64() ) / 1E6 ); } - // BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); + BOOST_TEST( expected_total_votepay_shares > total_votepay_shares ); + BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); } - + { const uint32_t prod_index = 15; const account_name prod_name = producer_names[prod_index]; @@ -1871,11 +1884,18 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_uint64(), get_producer_info2(prod_name)["last_votepay_share_update"].as_uint64() ); - double total_votepay_shares = 0; + BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); + const auto& gs3 = get_global_state3(); + double expected_total_votepay_shares = 0; for (uint32_t i = 0; i < producer_names.size(); ++i) { - total_votepay_shares += get_producer_info2(producer_names[i])["votepay_share"].as_double(); + const auto& info = get_producer_info(producer_names[i]); + const auto& info2 = get_producer_info2(producer_names[i]); + expected_total_votepay_shares += info2["votepay_share"].as_double(); + expected_total_votepay_shares += info["total_votes"].as_double() * double( ( gs3["last_vpay_state_update"].as_uint64() - + info2["last_votepay_share_update"].as_uint64() ) / 1E6 ); } - // BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == total_votepay_shares ); + BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); } } FC_LOG_AND_RETHROW() From 8cc5cf8ca69b80ef2a88372b4407475d937f95bc Mon Sep 17 00:00:00 2001 From: Alexandre Bourget Date: Sun, 22 Jul 2018 17:33:16 -0400 Subject: [PATCH 0450/1048] Fixup invalid JSON in eosio.token's ABI --- eosio.token/abi/eosio.token.abi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi index b7352d36..ce5861f2 100644 --- a/eosio.token/abi/eosio.token.abi +++ b/eosio.token/abi/eosio.token.abi @@ -40,7 +40,7 @@ "base": "", "fields": [ {"name":"owner", "type":"account_name"}, - {"name":"symbol", "type":"symbol"}, + {"name":"symbol", "type":"symbol"} ] },{ "name": "account", From 881f224f41245e90be5b977a570444b68e846901 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 23 Jul 2018 14:31:32 -0400 Subject: [PATCH 0451/1048] Global state testing - 3 --- tests/eosio.system_tests.cpp | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 71131e67..be789161 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1698,9 +1698,12 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const uint32_t prod_index = 2; const auto prod_name = producer_names[prod_index]; - const auto initial_prod_info = get_producer_info(prod_name); + const auto initial_prod_info = get_producer_info(prod_name); + const auto initial_prod_info2 = get_producer_info2(prod_name); const auto initial_global_state = get_global_state(); const double initial_tot_votepay_share = get_global_state2()["total_producer_votepay_share"].as_double(); + const double initial_tot_vpay_rate = get_global_state3()["total_vpay_share_change_rate"].as_double(); + const uint64_t initial_vpay_state_update = get_global_state3()["last_vpay_state_update"].as_uint64(); const uint64_t initial_bucket_fill_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); @@ -1709,12 +1712,15 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const asset initial_balance = get_balance(prod_name); const uint32_t initial_unpaid_blocks = initial_prod_info["unpaid_blocks"].as(); const uint64_t initial_claim_time = initial_prod_info["last_claim_time"].as_uint64(); - + const uint64_t initial_prod_update_time = initial_prod_info2["last_votepay_share_update"].as_uint64(); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); const auto prod_info = get_producer_info(prod_name); + const auto prod_info2 = get_producer_info2(prod_name); const auto global_state = get_global_state(); + const uint64_t vpay_state_update = get_global_state3()["last_vpay_state_update"].as_uint64(); const uint64_t bucket_fill_time = global_state["last_pervote_bucket_fill"].as_uint64(); const int64_t pervote_bucket = global_state["pervote_bucket"].as(); const int64_t perblock_bucket = global_state["perblock_bucket"].as(); @@ -1723,24 +1729,27 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const asset balance = get_balance(prod_name); const uint32_t unpaid_blocks = prod_info["unpaid_blocks"].as(); const uint64_t claim_time = prod_info["last_claim_time"].as_uint64(); + const uint64_t prod_update_time = prod_info2["last_votepay_share_update"].as_uint64(); - const uint64_t usecs_between_fills = bucket_fill_time - initial_bucket_fill_time; - const uint64_t secs_between_claims = (claim_time - initial_claim_time) / 1000000; - const double votepay_share = secs_between_claims * prod_info["total_votes"].as_double(); - const double tot_votepay_share = initial_tot_votepay_share + votepay_share; + const uint64_t usecs_between_fills = bucket_fill_time - initial_bucket_fill_time; + const double secs_between_global_updates = (vpay_state_update - initial_vpay_state_update) / 1E6; + const double secs_between_prod_updates = (prod_update_time - initial_prod_update_time) / 1E6; + const double votepay_share = initial_prod_info2["votepay_share"].as_double() + secs_between_prod_updates * prod_info["total_votes"].as_double(); + const double tot_votepay_share = initial_tot_votepay_share + initial_tot_vpay_rate * secs_between_global_updates; const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) + initial_perblock_bucket; const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) + initial_pervote_bucket; - const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; - const int64_t from_pervote_bucket = int64_t( ( votepay_share / tot_votepay_share ) * expected_pervote_bucket ); + const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks; + const int64_t from_pervote_bucket = int64_t( ( votepay_share * expected_pervote_bucket ) / tot_votepay_share ); const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); - - BOOST_REQUIRE_EQUAL( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ); - BOOST_REQUIRE_EQUAL( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ); + BOOST_REQUIRE_EQUAL( claim_time, vpay_state_update ); + BOOST_REQUIRE( 100 * 10000 < from_pervote_bucket ); + BOOST_CHECK_EQUAL( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ); + BOOST_CHECK_EQUAL( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); } From 94f5d09f8e2dc0dfbac4337e97d9ccc6be892a9c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 23 Jul 2018 15:13:21 -0400 Subject: [PATCH 0452/1048] Global state testing - 4 --- eosio.system/src/voting.cpp | 20 ++++++++++---------- tests/eosio.system_tests.cpp | 17 +++++++++++++---- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 0be8bc81..a88c2796 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -241,13 +241,13 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( pd.first ); if( prod2 != _producers2.end() ) { - update_global = true; _producers2.modify( prod2, 0, [&]( auto& p ) { if ( ct - pitr->last_claim_time < 3 * useconds_per_day ) { - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - p.last_votepay_share_update = ct; - delta_change_rate += pd.second.first; + update_global = true; + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + p.last_votepay_share_update = ct; + delta_change_rate += pd.second.first; } }); } @@ -327,13 +327,13 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { - update_global = true; _producers2.modify( prod2, 0, [&]( auto& p ) { if ( ct - pitr.last_claim_time < 3 * useconds_per_day ) { - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - p.last_votepay_share_update = ct; - delta_change_rate += delta; + update_global = true; + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + p.last_votepay_share_update = ct; + delta_change_rate += delta; } }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index be789161..7db3bc90 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1751,6 +1751,11 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_CHECK_EQUAL( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ); BOOST_CHECK_EQUAL( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); + + produce_block(fc::hours(2)); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("already claimed rewards within past day"), + push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); } } FC_LOG_AND_RETHROW() @@ -1944,11 +1949,14 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); uint64_t last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); produce_block( fc::hours(15) ); + + // alice votes for carol BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); auto cur_info2 = get_producer_info2(carol); - double expected_votepay_share = ( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1000000 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); + double expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == get_producer_info(carol)["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); total_votes = get_producer_info(carol)["total_votes"].as_double(); @@ -1957,7 +1965,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); cur_info2 = get_producer_info2(carol); - expected_votepay_share += ( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1000000 ) * total_votes; + expected_votepay_share += double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); @@ -1969,13 +1977,14 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); cur_info2 = get_producer_info2(carol); - expected_votepay_share = ( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1000000 ) * total_votes; + expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); produce_block( fc::hours(53) ); BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_TEST_REQUIRE( expected_votepay_share == get_producer_info2(carol)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); } FC_LOG_AND_RETHROW() From 35fce23dde8e77674cba4a558a996e5c680900ce Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 24 Jul 2018 14:01:39 -0400 Subject: [PATCH 0453/1048] Changes following code review --- eosio.system/src/producer_pay.cpp | 10 ---------- eosio.system/src/voting.cpp | 13 +++---------- tests/eosio.system_tests.cpp | 10 +++++----- 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 29f30290..a65a89b8 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -79,16 +79,6 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" ); - if ( _producers2.find( owner ) == _producers2.end() ) { - _producers2.emplace( owner, [&]( producer_info2& info ) { - info.owner = owner; - if ( prod.last_claim_time > 0 ) - info.last_votepay_share_update = prod.last_claim_time; - else - info.last_votepay_share_update = ct; - }); - } - const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill; diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index a88c2796..30a7d3e3 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -56,7 +56,7 @@ namespace eosiosystem { if ( prod2 == _producers2.end() ) { _producers2.emplace( producer, [&]( producer_info2& info ){ info.owner = producer; - info.last_votepay_share_update = prod->last_claim_time; + info.last_votepay_share_update = ct; }); } } else { @@ -70,7 +70,8 @@ namespace eosiosystem { info.last_claim_time = ct; }); _producers2.emplace( producer, [&]( producer_info2& info ){ - info.owner = producer; + info.owner = producer; + info.last_votepay_share_update = ct; }); } @@ -80,17 +81,9 @@ namespace eosiosystem { require_auth( producer ); const auto& prod = _producers.get( producer, "producer not found" ); - _producers.modify( prod, 0, [&]( producer_info& info ){ info.deactivate(); }); - - auto prod2 = _producers2.find( producer ); - if ( prod2 == _producers2.end() ) { - _producers2.emplace( producer, [&]( producer_info2& info ){ - info.owner = producer; - }); - } } void system_contract::update_elected_producers( block_timestamp block_time ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7db3bc90..fb3e4cfb 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1796,7 +1796,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * wdump((p)); BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["last_votepay_share_update"].as_uint64()); + BOOST_REQUIRE(0 < get_producer_info2(p)["last_votepay_share_update"].as_uint64()); } } @@ -2015,7 +2015,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["last_votepay_share_update"].as_uint64()); + BOOST_REQUIRE(0 < get_producer_info2(p)["last_votepay_share_update"].as_uint64()); } } @@ -2038,13 +2038,13 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t N(producers2) ) ); BOOST_REQUIRE( !tbl ); BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducera)) ); - BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducera))["last_claim_time"].as_uint64(), - get_producer_info2(N(defproducera))["last_votepay_share_update"].as_uint64() ); + BOOST_REQUIRE( get_producer_info(N(defproducera))["last_claim_time"].as_uint64() < get_producer_info2(N(defproducera))["last_votepay_share_update"].as_uint64() ); create_account_with_resources( N(defproducer1), config::system_account_name, core_from_string("1.0000"), false, net, cpu ); BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducer1)) ); BOOST_REQUIRE( 0 < get_producer_info(N(defproducer1))["last_claim_time"].as_uint64() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducer1))["last_claim_time"].as_uint64(), + get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_uint64() ); } FC_LOG_AND_RETHROW() From 249e0297c731f43f33b20bed3c6d9116a05104cf Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 24 Jul 2018 14:06:49 -0400 Subject: [PATCH 0454/1048] Changes following code review - 2 --- eosio.system/src/eosio.system.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 81f02153..383ddd54 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -134,6 +134,7 @@ namespace eosiosystem { void system_contract::updtrevision( uint8_t revision ) { require_auth( _self ); eosio_assert( revision == _gstate2.revision + 1, "can only increment revision by one" ); + eosio_assert( _gstate2.revision < 255, "can not increment revision" ); _gstate2.revision = revision; } From 613cda0b9a2633c79f41465f3af67f69b42fbdf0 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 24 Jul 2018 18:11:29 -0400 Subject: [PATCH 0455/1048] typo fixes and upgrade version to 1.1.1 in CMakeLists.txt and README --- CMakeLists.txt | 2 +- README.md | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11c809ca..4bf8cab8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.1.0) +project(eosio_contracts VERSION 1.1.1) if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(TEST_BUILD_TYPE "Debug") diff --git a/README.md b/README.md index 4aebc8a6..883c887f 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,16 @@ # eosio.contracts -## Version : 1.1.0 +## Version : 1.1.1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. -This repository contains examples of these priviledged contracts that are useful when depoying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: +This repository contains examples of these privileged contracts that are useful when deploying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) - * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) * [eosio.sudo](https://github.com/eosio/eosio.contracts/tree/master/eosio.sudo) - -The following unpriviledged contract(s) are also part of the system. + +The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: From 5cadb0498dc9d0c36c4367388f846b38b41e6ae8 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 20 Jul 2018 20:32:28 -0400 Subject: [PATCH 0456/1048] port over abi serializer max time changes from EOSIO/eos@ad2d0ed and EOSIO/eos@3cbb676 --- tests/eosio.msig_tests.cpp | 22 +++++++++++----------- tests/eosio.system_tester.hpp | 22 +++++++++++----------- tests/eosio.system_tests.cpp | 12 ++++++------ tests/eosio.token_tests.cpp | 6 +++--- 4 files changed, 31 insertions(+), 31 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index ce01cc85..37ee41d3 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -138,19 +138,19 @@ class eosio_msig_tester : public tester { action act; act.account = N(eosio.msig); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); //std::cout << "test:\n" << fc::to_hex(act.data.data(), act.data.size()) << " size = " << act.data.size() << std::endl; return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : 0 ); */ } - transaction reqauth( account_name from, const vector& auths ); + transaction reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ); abi_serializer abi_ser; }; -transaction eosio_msig_tester::reqauth( account_name from, const vector& auths ) { +transaction eosio_msig_tester::reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ) { fc::variants v; for ( auto& level : auths ) { v.push_back(fc::mutable_variant_object() @@ -174,14 +174,14 @@ transaction eosio_msig_tester::reqauth( account_name from, const vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -304,7 +304,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { - auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); //try with not enough requested auth BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -345,7 +345,7 @@ BOOST_FIXTURE_TEST_CASE( big_transaction, eosio_msig_tester ) try { ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -451,7 +451,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); // propose action push_action( N(alice), N(propose), mvo() @@ -562,7 +562,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); // propose action push_action( N(alice), N(propose), mvo() diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 7ce52211..69601090 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -45,7 +45,7 @@ class eosio_system_tester : public TESTER { produce_blocks( 100 ); set_code( N(eosio.token), contracts::token_wasm()); - set_abi( N(eosio.token), contracts::token_abi().data() ); + set_abi( N(eosio.token), contracts::token_abi().data() ); { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; @@ -219,7 +219,7 @@ class eosio_system_tester : public TESTER { action act; act.account = config::system_account_name; act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); } @@ -320,22 +320,22 @@ class eosio_system_tester : public TESTER { asset get_balance( const account_name& act ) { vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYMBOL).to_symbol_code().value ); - return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data)["balance"].as(); + return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); } fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); } fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data ); + return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); } void create_currency( name contract, name manager, asset maxsupply ) { @@ -375,7 +375,7 @@ class eosio_system_tester : public TESTER { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } asset get_token_supply() { @@ -385,17 +385,17 @@ class eosio_system_tester : public TESTER { fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); if (data.empty()) std::cout << "\nData is empty\n" << std::endl; - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer_max_time ); } fc::variant get_global_state2() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer_max_time ); } fc::variant get_refund_request( name account ) { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer_max_time ); } abi_serializer initialize_multisig() { @@ -410,7 +410,7 @@ class eosio_system_tester : public TESTER { ("account", "eosio.msig") ("is_priv", 1) ); - + set_code( N(eosio.msig), contracts::msig_wasm() ); set_abi( N(eosio.msig), contracts::msig_abi().data() ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index ac21342b..119df40d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1696,7 +1696,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -1735,7 +1735,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -2456,7 +2456,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -2492,7 +2492,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -2615,9 +2615,9 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), push_action( "alice1111111", N(setramrate), mvo()("bytes_per_block", rate) ) ); - + } FC_LOG_AND_RETHROW() - + BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 093d8d0f..b1a97f65 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -42,7 +42,7 @@ class eosio_token_tester : public tester { action act; act.account = N(eosio.token); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data,abi_serializer_max_time ); return base_tester::push_action( std::move(act), uint64_t(signer)); } @@ -52,7 +52,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } fc::variant get_account( account_name acc, const string& symbolname) @@ -60,7 +60,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); } action_result create( account_name issuer, From bf604ccc043cc38c14cc376d0263b29687a0324b Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 20 Jul 2018 20:34:57 -0400 Subject: [PATCH 0457/1048] port over "Pass abi serialization max time to abi_serializer constructor." commit from EOSIO/eos@ae430b4 --- tests/eosio.msig_tests.cpp | 2 +- tests/eosio.sudo_tests.cpp | 6 +++--- tests/eosio.system_tester.hpp | 6 +++--- tests/eosio.token_tests.cpp | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 37ee41d3..0683a552 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -36,7 +36,7 @@ class eosio_msig_tester : public tester { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, diff --git a/tests/eosio.sudo_tests.cpp b/tests/eosio.sudo_tests.cpp index 607b2677..8de7a93f 100644 --- a/tests/eosio.sudo_tests.cpp +++ b/tests/eosio.sudo_tests.cpp @@ -77,7 +77,7 @@ class eosio_sudo_tester : public tester { const auto& accnt = control->db().get( N(eosio.sudo) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); while( control->pending_block_state()->header.producer.to_string() == "eosio" ) { produce_block(); @@ -134,7 +134,7 @@ transaction eosio_sudo_tester::sudo_exec( account_name executer, const transacti transaction trx2; set_transaction_headers(trx2, expiration); action act; - abi_serializer::from_variant( act_obj, act, get_resolver() ); + abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer_max_time ); trx2.actions.push_back( std::move(act) ); return trx2; } @@ -155,7 +155,7 @@ transaction eosio_sudo_tester::reqauth( account_name from, const vectordb().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi); + token_abi_ser.set_abi(abi, abi_serializer_max_time); } create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); @@ -63,7 +63,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } produce_blocks(); @@ -418,7 +418,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def msig_abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi); + msig_abi_ser.set_abi(msig_abi, abi_serializer_max_time); } return msig_abi_ser; } diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index b1a97f65..e77ddf70 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -33,7 +33,7 @@ class eosio_token_tester : public tester { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) { From c0b3d3f5199b41dd9b1372f53b8d5940f2880505 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 20 Jul 2018 20:41:15 -0400 Subject: [PATCH 0458/1048] port over effect of commits that only removed unneeded comments: EOSIO/eos@e82f778b and EOSIO/eos@dcc4761 --- tests/eosio.system_tester.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 3ec97bc0..fee46f52 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -423,8 +423,6 @@ class eosio_system_tester : public TESTER { return msig_abi_ser; } - //helper function - vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain transfer( "eosio", "alice1111111", core_from_string("650000000.0000"), "eosio" ); From fa455c504ae0450344973bb12db2f0f93234f3b0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 24 Jul 2018 18:50:11 -0400 Subject: [PATCH 0459/1048] Change votepay share logic for inactive producers - voting --- eosio.system/src/voting.cpp | 41 +++++++++++++++++++++++------------- tests/eosio.system_tests.cpp | 11 ++++++++++ 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 30a7d3e3..f37a4c48 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -235,25 +235,30 @@ namespace eosiosystem { auto prod2 = _producers2.find( pd.first ); if( prod2 != _producers2.end() ) { _producers2.modify( prod2, 0, [&]( auto& p ) { - if ( ct - pitr->last_claim_time < 3 * useconds_per_day ) { - update_global = true; - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - p.last_votepay_share_update = ct; - delta_change_rate += pd.second.first; + const uint64_t last_claim_plus_3days = pitr->last_claim_time + 3 * useconds_per_day; + if ( ct < last_claim_plus_3days ) { + update_global = true; + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + delta_change_rate += pd.second.first; + } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { + update_global = true; + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + delta_change_rate -= init_total_votes; } + p.last_votepay_share_update = ct; }); } } else { eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } } - if ( update_global ) { _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; - _gstate3.last_vpay_state_update = ct; _gstate3.total_vpay_share_change_rate += delta_change_rate; } + _gstate3.last_vpay_state_update = ct; _voters.modify( voter, 0, [&]( auto& av ) { av.last_vote_weight = new_vote_weight; @@ -321,21 +326,27 @@ namespace eosiosystem { auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { _producers2.modify( prod2, 0, [&]( auto& p ) { - if ( ct - pitr.last_claim_time < 3 * useconds_per_day ) { - update_global = true; - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - p.last_votepay_share_update = ct; - delta_change_rate += delta; + const uint64_t last_claim_plus_3days = pitr.last_claim_time + 3 * useconds_per_day; + if ( ct < last_claim_plus_3days ) { + update_global = true; + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + delta_change_rate += delta; + } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { + update_global = true; + double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); + p.votepay_share += delta_votepay_share; + delta_change_rate -= init_total_votes; } + p.last_votepay_share_update = ct; }); } } if ( update_global ) { _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; - _gstate3.last_vpay_state_update = ct; _gstate3.total_vpay_share_change_rate += delta_change_rate; } + _gstate3.last_vpay_state_update = ct; } } _voters.modify( voter, 0, [&]( auto& v ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index fb3e4cfb..b8b02050 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1971,6 +1971,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); total_votes = get_producer_info(carol)["total_votes"].as_double(); + // carol claims rewards BOOST_REQUIRE_EQUAL( success(), push_action(carol, N(claimrewards), mvo()("owner", carol)) ); produce_block( fc::hours(20) ); @@ -1982,6 +1983,16 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); produce_block( fc::hours(53) ); + last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); + total_votes = get_producer_info(carol)["total_votes"].as_double(); + BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); + cur_info2 = get_producer_info2(carol); + expected_votepay_share += double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + BOOST_TEST_REQUIRE( expected_votepay_share == get_producer_info2(carol)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + + produce_block( fc::hours(20) ); + BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_TEST_REQUIRE( expected_votepay_share == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); From 8d93d5db37b3d0105001263b27a2d989eb03bbf8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 25 Jul 2018 11:36:10 -0400 Subject: [PATCH 0460/1048] Change votepay share logic for inactive producers - claimrewards --- eosio.system/src/producer_pay.cpp | 30 +++++++++++++++++++++--------- 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index a65a89b8..05443d81 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -102,9 +102,8 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, { N(eosio), N(eosio.vpay), asset(to_per_vote_pay), "fund per-vote bucket" } ); - _gstate.pervote_bucket += to_per_vote_pay; - _gstate.perblock_bucket += to_per_block_pay; - + _gstate.pervote_bucket += to_per_vote_pay; + _gstate.perblock_bucket += to_per_block_pay; _gstate.last_pervote_bucket_fill = ct; } @@ -126,14 +125,23 @@ namespace eosiosystem { /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and /// time duration the vote weight has been held into one metric. - double delta_votepay_share = prod.total_votes * double( (ct - prod2->last_votepay_share_update) / 1E6 ); - double delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6) ; - double votepay_share = prod2->votepay_share + delta_votepay_share; - double total_votepay_share = _gstate2.total_producer_votepay_share + delta_total_votepay_share; + + const uint64_t last_claim_plus_3days = prod.last_claim_time + 3 * useconds_per_day; + double delta_votepay_share = 0; + double delta_total_votepay_share = 0; + double votepay_share = 0; + double total_votepay_share = 0; + + if( ct < last_claim_plus_3days || ( ct >= last_claim_plus_3days && last_claim_plus_3days < prod2->last_votepay_share_update ) ) { + delta_votepay_share = prod.total_votes * double( (ct - prod2->last_votepay_share_update) / 1E6 ); + delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6) ; + votepay_share = prod2->votepay_share + delta_votepay_share; + total_votepay_share = _gstate2.total_producer_votepay_share + delta_total_votepay_share; + } int64_t producer_per_vote_pay = 0; if( _gstate2.revision > 0 ) { - if( total_votepay_share > 0 ) { + if( total_votepay_share > 0 && ct < last_claim_plus_3days ) { producer_per_vote_pay = int64_t((votepay_share * _gstate.pervote_bucket) / total_votepay_share); if( producer_per_vote_pay > _gstate.pervote_bucket ) producer_per_vote_pay = _gstate.pervote_bucket; @@ -152,9 +160,13 @@ namespace eosiosystem { _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.unpaid_blocks; + if( ct > prod2->last_votepay_share_update && prod2->last_votepay_share_update > last_claim_plus_3days ) { + _gstate3.total_vpay_share_change_rate += prod.total_votes; + } + _producers.modify( prod, 0, [&](auto& p) { p.last_claim_time = ct; - p.unpaid_blocks = 0; + p.unpaid_blocks = 0; }); _producers2.modify( prod2, 0, [&](auto& p) { From d78f7862611d3ba643790617c246ddf6ac301300 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 25 Jul 2018 14:28:41 -0400 Subject: [PATCH 0461/1048] Big commit (sorry), changed how builds and dependency tracking --- CMakeLists.txt | 16 ++-- UnitTestsExternalProject.txt | 2 +- build.sh | 41 +------- eosio.msig/CMakeLists.txt | 4 +- eosio.msig/build.sh | 21 ---- eosio.sudo/CMakeLists.txt | 4 +- eosio.sudo/build.sh | 21 ---- eosio.system/CMakeLists.txt | 4 +- eosio.system/build.sh | 21 ---- eosio.token/CMakeLists.txt | 4 +- eosio.token/build.sh | 21 ---- tests/CMakeLists.txt | 179 ++--------------------------------- tests/contracts.hpp.in | 24 ++--- tests/eosio.system_tests.cpp | 27 ------ tests/main.cpp | 42 ++++++++ 15 files changed, 79 insertions(+), 352 deletions(-) delete mode 100755 eosio.msig/build.sh delete mode 100755 eosio.sudo/build.sh delete mode 100755 eosio.system/build.sh delete mode 100755 eosio.token/build.sh create mode 100644 tests/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 11c809ca..b3834680 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,20 +7,16 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") else() set(TEST_BUILD_TYPE ${CMAKE_BUILD_TYPE}) endif() -if(CXX_COMPILER STREQUAL "" OR NOT CXX_COMPILER) - set(CXX_COMPILER ${CMAKE_CXX_COMPILER}) -endif() -if(EOSIO_INSTALL_PREFIX STREQUAL "" OR NOT EOSIO_INSTALL_PREFIX) - set(EOSIO_INSTALL_PREFIX "/usr/local") +if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) + set(EOSIO_ROOT "/usr/local/eosio") endif() - -# if no wasm root is given use default path -if(WASM_ROOT STREQUAL "" OR NOT WASM_ROOT) - set(WASM_ROOT ${CMAKE_INSTALL_PREFIX}) +if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT) + set(EOSIO_WASMSDK_ROOT "/usr/local") + set(WASM_ROOT "/usr/local") endif() -list(APPEND CMAKE_MODULE_PATH ${WASM_ROOT}/lib/cmake) +list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake) include(EosioWasmToolchain) add_subdirectory(eosio.msig) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 73ccd2d9..9c55e9d0 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,7 +4,7 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests diff --git a/build.sh b/build.sh index 815e9f27..1e0ab314 100755 --- a/build.sh +++ b/build.sh @@ -15,48 +15,9 @@ if [ ! -d "/usr/local/eosio.wasmsdk" ]; then exit -1 fi -unamestr=`uname` -if [[ "${unamestr}" == 'Darwin' ]]; then - BOOST=/usr/local - CXX_COMPILER=g++ -else - BOOST=~/opt/boost - OS_NAME=$( cat /etc/os-release | grep ^NAME | cut -d'=' -f2 | sed 's/\"//gI' ) - - case "$OS_NAME" in - "Amazon Linux AMI") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "CentOS Linux") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "elementary OS") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Fedora") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "Linux Mint") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Ubuntu") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - *) - printf "\\n\\tUnsupported Linux Distribution. Exiting now.\\n\\n" - exit 1 - esac -fi - CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ +cmake ../ make -j${CORES} popd &> /dev/null diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index c5dd83e7..1741e7c9 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,4 +1,4 @@ -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_executable(eosio.msig.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm @@ -7,6 +7,6 @@ target_include_directories(eosio.msig.wasm set_target_properties(eosio.msig.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.msig/build.sh b/eosio.msig/build.sh deleted file mode 100755 index 13d28a8c..00000000 --- a/eosio.msig/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.msig" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt index f38dae57..b02d424e 100644 --- a/eosio.sudo/CMakeLists.txt +++ b/eosio.sudo/CMakeLists.txt @@ -5,7 +5,7 @@ target_include_directories(eosio.sudo.wasm set_target_properties(eosio.sudo.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE__CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.sudo/build.sh b/eosio.sudo/build.sh deleted file mode 100755 index 9892f2e8..00000000 --- a/eosio.sudo/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.sudo" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index b0bc4431..8b47085e 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -6,8 +6,8 @@ target_include_directories(eosio.system.wasm set_target_properties(eosio.system.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.system/build.sh b/eosio.system/build.sh deleted file mode 100755 index f5028c69..00000000 --- a/eosio.system/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.system" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I../eosio.token/include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt index 39993201..9ff728c3 100644 --- a/eosio.token/CMakeLists.txt +++ b/eosio.token/CMakeLists.txt @@ -5,7 +5,7 @@ target_include_directories(eosio.token.wasm set_target_properties(eosio.token.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.token/build.sh b/eosio.token/build.sh deleted file mode 100755 index 7394a451..00000000 --- a/eosio.token/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.token" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2a22a3ea..d49e0300 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,179 +1,18 @@ cmake_minimum_required( VERSION 3.5 ) -project( EOSIO_CONTRACTS_TESTS ) -set( VERSION_MAJOR 1 ) -set( VERSION_MINOR 0 ) -set( VERSION_PATCH 0 ) -enable_testing() +list(APPEND CMAKE_MODULE_PATH ${EOSIO_ROOT}/lib/cmake) +include(EosioTester) -find_package( Gperftools QUIET ) -if( GPERFTOOLS_FOUND ) - message( STATUS "Found gperftools; compiling tests with TCMalloc") - list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc ) +if (NOT "${EOSIO_VERSION}" EQUAL "1.1.0") + message(FATAL_ERROR "Incorrect EOSIO version, please use version 1.1.0") endif() -find_package(LLVM 4.0 REQUIRED CONFIG) - -link_directories(${LLVM_LIBRARY_DIR}) - -set( CMAKE_CXX_STANDARD 14 ) -set( CMAKE_CXX_EXTENSIONS ON ) -set( CXX_STANDARD_REQUIRED ON ) - -if ( APPLE ) - set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-deprecated-declarations" ) -else ( APPLE ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") -endif ( APPLE ) - -set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) -configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_SOURCE_DIR}/contracts.hpp) -find_package(Boost 1.67 REQUIRED COMPONENTS - date_time - filesystem - system - chrono - iostreams - date_time - unit_test_framework) - -file(GLOB UNIT_TESTS "*.cpp") - -find_library(libtester eosio_testing ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libchain eosio_chain ${EOSIO_INSTALL_PREFIX}/lib) -if ( "${CMAKE_BUILD_TYPE}" EQUAL "Debug" ) - find_library(libfc fc_debug ${EOSIO_INSTALL_PREFIX}/lib) -else() - find_library(libfc fc ${EOSIO_INSTALL_PREFIX}/lib) -endif() -find_library(libbinaryen binaryen ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libwasm WASM ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libwast WAST ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libir IR ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libplatform Platform ${EOSIO_INSTALL_PREFIX}/lib) -find_library(liblogging Logging ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libruntime Runtime ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libsoftfloat softfloat ${EOSIO_INSTALL_PREFIX}/lib) -find_library(liboscrypto crypto ${OPENSSL_INSTALL_PREFIX}/lib) -find_library(libosssl ssl ${OPENSSL_INSTALL_PREFIX}/lib) -find_library(libchainbase chainbase ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libbuiltins builtins ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libsecp256k1 secp256k1 ${SECP256K1_INSTALL_LIB}) - -add_executable( unit_test ${UNIT_TESTS} ) -target_link_libraries( unit_test - ${LLVM} - ${libtester} - ${libchain} - ${libfc} - ${libbinaryen} - ${libwast} - ${libwasm} - ${libruntime} - ${libplatform} - ${libir} - ${libsoftfloat} - ${liboscrypto} - ${libosssl} - ${liblogging} - ${libchainbase} - ${libbuiltins} - ${libsecp256k1} - - LLVMX86Disassembler - LLVMX86AsmParser - LLVMX86AsmPrinter - LLVMX86CodeGen - - LLVMSelectionDAG - - LLVMDebugInfoDWARF - LLVMAsmPrinter - LLVMMCParser - LLVMX86Info - - LLVMOrcJIT - LLVMExecutionEngine - - LLVMCodeGen - LLVMScalarOpts - LLVMTransformUtils - - LLVMipo - LLVMAnalysis - LLVMTarget - LLVMMC - LLVMCore - LLVMSupport - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_SYSTEM_LIBRARY} - ${Boost_CHRONO_LIBRARY} - ${Boost_IOSTREAMS_LIBRARY} - ${Boost_DATE_TIME_LIBRARY} - ${PLATFORM_SPECIFIC_LIBS} - ) - -target_include_directories( unit_test PUBLIC - ${Boost_INCLUDE_DIRS} - ${OPENSSL_INSTALL_PREFIX}/include - ${EOSIO_INSTALL_PREFIX} - ${EOSIO_INSTALL_PREFIX}/include - ${EOSIO_INSTALL_PREFIX}/include/eosio/wasm-jit/Include - ${EOSIO_INSTALL_PREFIX}/include/eosio/softfloat/include - ${CMAKE_CURRENT_BINARY_DIR}/include ) - -#Manually run unit_test for all supported runtimes -#To run unit_test with all log from blockchain displayed, put --verbose after --, i.e. unit_test -- --verbose -add_test(NAME unit_test_binaryen COMMAND unit_test - --report_level=detailed --color_output -- --binaryen) -add_test(NAME unit_test_wavm COMMAND unit_test - --report_level=detailed --color_output --catch_system_errors=no -- --wavm) - -if(ENABLE_COVERAGE_TESTING) - - set(Coverage_NAME ${PROJECT_NAME}_ut_coverage) - - if(NOT LCOV_PATH) - message(FATAL_ERROR "lcov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT LLVMCOV_PATH) - message(FATAL_ERROR "llvm-cov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT GENHTML_PATH) - message(FATAL_ERROR "genhtml not found! Aborting...") - endif() # NOT GENHTML_PATH - - # no spaces allowed within tests list - set(ctest_tests 'unit_test_binaryen|unit_test_wavm') - set(ctest_exclude_tests '') - - # Setup target - add_custom_target(${Coverage_NAME} - - # Cleanup lcov - COMMAND ${LCOV_PATH} --directory . --zerocounters - - # Run tests - COMMAND ./tools/ctestwrapper.sh -R ${ctest_tests} -E ${ctest_exclude_tests} - - COMMAND ${LCOV_PATH} --directory . --capture --gcov-tool ./tools/llvm-gcov.sh --output-file ${Coverage_NAME}.info - - COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/fc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info +enable_testing() - COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info +configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contracts.hpp) - COMMAND if [ "$CI" != "true" ]\; then ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.info ${Coverage_NAME}_filtered.info ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info.cleaned\; fi +include_directories(${CMAKE_BINARY_DIR}) - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMENT "Resetting code coverage counters to zero. Processing code coverage counters and generating report. Report published in ./${Coverage_NAME}" - ) +file(GLOB UNIT_TESTS "*.cpp" "*.hpp") - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." - ) -endif() +add_eosio_test( unit_test ${UNIT_TESTS} ) diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 1d91f506..2db2153f 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -4,18 +4,18 @@ namespace eosio { namespace testing { struct contracts { - static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wast"); } - static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.abi"); } - static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.abi"); } - static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wast"); } - static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.abi"); } - static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wasm"); } - static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wast"); } - static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi"); } + static std::vector system_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.abi"); } + static std::vector sudo_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wasm"); } + static std::string sudo_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wast"); } + static std::vector sudo_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.abi"); } struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 119df40d..cf66e89f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -2649,29 +2648,3 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_SUITE_END() - -void translate_fc_exception(const fc::exception &e) { - std::cerr << "\033[33m" << e.to_detail_string() << "\033[0m" << std::endl; - BOOST_TEST_FAIL("Caught Unexpected Exception"); -} - -boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { - // Turn off blockchain logging if no --verbose parameter is not added - // To have verbose enabled, call "tests/chain_test -- --verbose" - bool is_verbose = false; - std::string verbose_arg = "--verbose"; - for (int i = 0; i < argc; i++) { - if (verbose_arg == argv[i]) { - is_verbose = true; - break; - } - } - if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); - - // Register fc::exception translator - boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); - - std::srand(time(NULL)); - std::cout << "Random number generator seeded to " << time(NULL) << std::endl; - return nullptr; -} diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 00000000..2c658f31 --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eosio.system_tester.hpp" + +using namespace eosio_system; +#define BOOST_TEST_STATIC_LINK + +void translate_fc_exception(const fc::exception &e) { + std::cerr << "\033[33m" << e.to_detail_string() << "\033[0m" << std::endl; + BOOST_TEST_FAIL("Caught Unexpected Exception"); +} + +boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { + // Turn off blockchain logging if no --verbose parameter is not added + // To have verbose enabled, call "tests/chain_test -- --verbose" + bool is_verbose = false; + std::string verbose_arg = "--verbose"; + for (int i = 0; i < argc; i++) { + if (verbose_arg == argv[i]) { + is_verbose = true; + break; + } + } + if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + + // Register fc::exception translator + boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); + + std::srand(time(NULL)); + std::cout << "Random number generator seeded to " << time(NULL) << std::endl; + return nullptr; +} From ff78ee9e8770c5ee2c6113ba12a0e14d83149e2a Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 25 Jul 2018 14:36:59 -0400 Subject: [PATCH 0462/1048] Moved unit_test output binary dir --- UnitTestsExternalProject.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 9c55e9d0..5f440ab3 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -7,7 +7,7 @@ ExternalProject_Add( CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests - BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests + BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 TEST_COMMAND "" INSTALL_COMMAND "" From 6fb4cddb7eaafce6e562e8b853006889c14f88f7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 25 Jul 2018 15:10:02 -0400 Subject: [PATCH 0463/1048] Bug fixes --- eosio.system/src/producer_pay.cpp | 14 +++++--------- tests/eosio.system_tests.cpp | 7 +++++++ 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 05443d81..cbf6f5cb 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -110,12 +110,9 @@ namespace eosiosystem { auto prod2 = _producers2.find( owner ); if ( prod2 == _producers2.end() ) { prod2 = _producers2.emplace( owner, [&]( producer_info2& info ) { - info.owner = owner; - if ( prod.last_claim_time > 0 ) - info.last_votepay_share_update = prod.last_claim_time; - else - info.last_votepay_share_update = ct; - }); + info.owner = owner; + info.last_votepay_share_update = ct; + }); } int64_t producer_per_block_pay = 0; @@ -125,14 +122,13 @@ namespace eosiosystem { /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and /// time duration the vote weight has been held into one metric. - const uint64_t last_claim_plus_3days = prod.last_claim_time + 3 * useconds_per_day; double delta_votepay_share = 0; double delta_total_votepay_share = 0; double votepay_share = 0; double total_votepay_share = 0; - if( ct < last_claim_plus_3days || ( ct >= last_claim_plus_3days && last_claim_plus_3days < prod2->last_votepay_share_update ) ) { + if( ct < last_claim_plus_3days || ( ct >= last_claim_plus_3days && last_claim_plus_3days > prod2->last_votepay_share_update ) ) { delta_votepay_share = prod.total_votes * double( (ct - prod2->last_votepay_share_update) / 1E6 ); delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6) ; votepay_share = prod2->votepay_share + delta_votepay_share; @@ -160,7 +156,7 @@ namespace eosiosystem { _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.unpaid_blocks; - if( ct > prod2->last_votepay_share_update && prod2->last_votepay_share_update > last_claim_plus_3days ) { + if( ct >= prod2->last_votepay_share_update && prod2->last_votepay_share_update > last_claim_plus_3days ) { _gstate3.total_vpay_share_change_rate += prod.total_votes; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b8b02050..26cb1a17 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1996,6 +1996,13 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_TEST_REQUIRE( expected_votepay_share == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); + + produce_block( fc::hours(24) ); + BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); + BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); } FC_LOG_AND_RETHROW() From 20ea266aa96f302f903172dd0daa6c73ef76122f Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 25 Jul 2018 18:27:22 -0400 Subject: [PATCH 0464/1048] Added dependency checking for eosio and wasmsdk --- CMakeLists.txt | 15 +++++++++++++-- UnitTestsExternalProject.txt | 2 +- build.sh | 2 +- eosio.msig/bin/eosio.msig/.gitignore | 2 -- eosio.sudo/bin/eosio.sudo/.gitignore | 2 -- eosio.system/bin/eosio.system/.gitignore | 2 -- eosio.token/bin/eosio.token/.gitignore | 2 -- tests/CMakeLists.txt | 7 +++++-- 8 files changed, 20 insertions(+), 14 deletions(-) delete mode 100644 eosio.msig/bin/eosio.msig/.gitignore delete mode 100644 eosio.sudo/bin/eosio.sudo/.gitignore delete mode 100644 eosio.system/bin/eosio.system/.gitignore delete mode 100644 eosio.token/bin/eosio.token/.gitignore diff --git a/CMakeLists.txt b/CMakeLists.txt index b3834680..080dc6db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,9 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts VERSION 1.1.0) +set(EOSIO_DEPENDENCY "1.1") +set(EOSIO_WASMSDK_DEPENDENCY "1.1") + if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(TEST_BUILD_TYPE "Debug") set(CMAKE_BUILD_TYPE "Release") @@ -11,14 +14,22 @@ endif() if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) set(EOSIO_ROOT "/usr/local/eosio") endif() + if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT) - set(EOSIO_WASMSDK_ROOT "/usr/local") - set(WASM_ROOT "/usr/local") + set(EOSIO_WASMSDK_ROOT "/usr/local/eosio.wasmsdk") + set(WASM_ROOT "/usr/local/eosio.wasmsdk") endif() list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake) include(EosioWasmToolchain) +### Check the version of wasmsdk +string(FIND "${EOSIO_WASMSDK_VERSION}" "${EOSIO_WASMSDK_DEPENDENCY}" output) + +if (NOT "${output}" EQUAL 0) + message(FATAL_ERROR "Incorrect EOSIO.WasmSDK version, please use version ${EOSIO_WASMSDK_DEPENDENCY}.x") +endif() + add_subdirectory(eosio.msig) add_subdirectory(eosio.sudo) add_subdirectory(eosio.system) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 5f440ab3..b7f9af50 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,7 +4,7 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} -DEOSIO_DEPENDENCY=${EOSIO_DEPENDENCY} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_BINARY_DIR}/tests diff --git a/build.sh b/build.sh index 1e0ab314..90df0ab4 100755 --- a/build.sh +++ b/build.sh @@ -18,6 +18,6 @@ fi CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake ../ +cmake -DEOSIO_ROOT=/Users/judgefudge/master_eos/eos/build ../ make -j${CORES} popd &> /dev/null diff --git a/eosio.msig/bin/eosio.msig/.gitignore b/eosio.msig/bin/eosio.msig/.gitignore deleted file mode 100644 index db5b01cc..00000000 --- a/eosio.msig/bin/eosio.msig/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.msig.abi -eosio.msig.wasm diff --git a/eosio.sudo/bin/eosio.sudo/.gitignore b/eosio.sudo/bin/eosio.sudo/.gitignore deleted file mode 100644 index 35898c3b..00000000 --- a/eosio.sudo/bin/eosio.sudo/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.sudo.abi -eosio.sudo.wasm diff --git a/eosio.system/bin/eosio.system/.gitignore b/eosio.system/bin/eosio.system/.gitignore deleted file mode 100644 index 105891a4..00000000 --- a/eosio.system/bin/eosio.system/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.system.abi -eosio.system.wasm diff --git a/eosio.token/bin/eosio.token/.gitignore b/eosio.token/bin/eosio.token/.gitignore deleted file mode 100644 index e5513007..00000000 --- a/eosio.token/bin/eosio.token/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.token.abi -eosio.token.wasm diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index d49e0300..12b6d8f1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,10 +3,13 @@ cmake_minimum_required( VERSION 3.5 ) list(APPEND CMAKE_MODULE_PATH ${EOSIO_ROOT}/lib/cmake) include(EosioTester) -if (NOT "${EOSIO_VERSION}" EQUAL "1.1.0") - message(FATAL_ERROR "Incorrect EOSIO version, please use version 1.1.0") +### check the version of EOSIO +string(FIND "${EOSIO_VERSION}" "${EOSIO_DEPENDENCY}" output) +if (NOT "${output}" EQUAL 0) + message(FATAL_ERROR "Incorrect EOSIO version, please use version ${EOSIO_DEPENDENCY}.x") endif() + enable_testing() configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contracts.hpp) From 63511074a9e4be799fab40c63d1acf94e18fd948 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 25 Jul 2018 18:34:50 -0400 Subject: [PATCH 0465/1048] Votepay share optimization --- eosio.system/src/voting.cpp | 48 +++++++++++++++++++++--------------- tests/eosio.system_tests.cpp | 9 ++++--- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index f37a4c48..d20ec78a 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -217,8 +217,10 @@ namespace eosiosystem { } const auto ct = current_time(); - bool update_global = false; - double delta_change_rate = 0; + bool update_global_time = false; + bool update_global_share = false; + double delta_change_rate = 0; + double total_inactive_vpay_share = 0; for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { @@ -234,17 +236,17 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( pd.first ); if( prod2 != _producers2.end() ) { + update_global_time = true; _producers2.modify( prod2, 0, [&]( auto& p ) { - const uint64_t last_claim_plus_3days = pitr->last_claim_time + 3 * useconds_per_day; + const uint64_t last_claim_plus_3days = pitr->last_claim_time + 3 * useconds_per_day; if ( ct < last_claim_plus_3days ) { - update_global = true; + update_global_share = true; double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); p.votepay_share += delta_votepay_share; delta_change_rate += pd.second.first; } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { - update_global = true; - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; + total_inactive_vpay_share += p.votepay_share; + p.votepay_share = 0; delta_change_rate -= init_total_votes; } p.last_votepay_share_update = ct; @@ -254,11 +256,13 @@ namespace eosiosystem { eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } } - if ( update_global ) { + if ( update_global_share ) { _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; - _gstate3.total_vpay_share_change_rate += delta_change_rate; } - _gstate3.last_vpay_state_update = ct; + _gstate2.total_producer_votepay_share -= total_inactive_vpay_share; + _gstate3.total_vpay_share_change_rate += delta_change_rate; + if ( update_global_time ) + _gstate3.last_vpay_state_update = ct; _voters.modify( voter, 0, [&]( auto& av ) { av.last_vote_weight = new_vote_weight; @@ -313,9 +317,11 @@ namespace eosiosystem { propagate_weight_change( proxy ); } else { auto delta = new_weight - voter.last_vote_weight; - bool update_global = false; const auto ct = current_time(); - double delta_change_rate = 0; + bool update_global_time = false; + bool update_global_share = false; + double delta_change_rate = 0; + double total_inactive_vpay_share = 0; for ( auto acnt : voter.producers ) { auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption const double init_total_votes = pitr.total_votes; @@ -325,28 +331,30 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { + update_global_time = true; _producers2.modify( prod2, 0, [&]( auto& p ) { const uint64_t last_claim_plus_3days = pitr.last_claim_time + 3 * useconds_per_day; if ( ct < last_claim_plus_3days ) { - update_global = true; + update_global_share = true; double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); p.votepay_share += delta_votepay_share; delta_change_rate += delta; } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { - update_global = true; - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; + total_inactive_vpay_share += p.votepay_share; + p.votepay_share = 0; delta_change_rate -= init_total_votes; } p.last_votepay_share_update = ct; - }); + }); } } - if ( update_global ) { + if ( update_global_share ) { _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; - _gstate3.total_vpay_share_change_rate += delta_change_rate; } - _gstate3.last_vpay_state_update = ct; + _gstate2.total_producer_votepay_share -= total_inactive_vpay_share; + _gstate3.total_vpay_share_change_rate += delta_change_rate; + if ( update_global_time ) + _gstate3.last_vpay_state_update = ct; } } _voters.modify( voter, 0, [&]( auto& v ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 26cb1a17..0950d46c 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1988,14 +1988,15 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); cur_info2 = get_producer_info2(carol); expected_votepay_share += double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); produce_block( fc::hours(20) ); BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); produce_block( fc::hours(24) ); From 2bafb9226e3d5f9975a6df3c10686fbf0e0331ba Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 25 Jul 2018 19:18:50 -0400 Subject: [PATCH 0466/1048] More testing --- tests/eosio.system_tests.cpp | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0950d46c..33e49357 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1921,7 +1921,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ const asset net = core_from_string("80.0000"); const asset cpu = core_from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; for (const auto& a: accounts) { create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); @@ -1929,13 +1929,15 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ const auto alice = accounts[0]; const auto bob = accounts[1]; const auto carol = accounts[2]; + const auto emily = accounts[3]; // alice becomes a proxy BOOST_REQUIRE_EQUAL( success(), push_action( alice, N(regproxy), mvo()("proxy", alice)("isproxy", true) ) ); REQUIRE_MATCHING_OBJECT( proxy( alice ), get_voter_info( alice ) ); - // carol becomes a producer + // carol and emily become producers BOOST_REQUIRE_EQUAL( success(), regproducer( carol, 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( emily, 1) ); // bob chooses alice as a proxy BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0002"), core_from_string("50.0001") ) ); @@ -2005,6 +2007,18 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); + produce_block( fc::hours(1) ); + + last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); + BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol, emily } ) ); + cur_info2 = get_producer_info2(carol); + expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(emily)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == + get_global_state3()["total_vpay_share_change_rate"].as_double() ); + } FC_LOG_AND_RETHROW() From 994945aeffb55d59e4439ca8d72cf42fd912bd98 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 26 Jul 2018 10:48:35 -0400 Subject: [PATCH 0467/1048] Small changes in unit test --- tests/eosio.system_tests.cpp | 44 +++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 33e49357..f2665618 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1945,14 +1945,16 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_voter_info(alice)["proxied_vote_weight"].as_double() ); + // alice (proxy) votes for carol BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); double total_votes = get_producer_info(carol)["total_votes"].as_double(); BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == total_votes ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); uint64_t last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); + produce_block( fc::hours(15) ); - // alice votes for carol + // alice (proxy) votes again for carol BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); auto cur_info2 = get_producer_info2(carol); double expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; @@ -1963,6 +1965,8 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ total_votes = get_producer_info(carol)["total_votes"].as_double(); produce_block( fc::hours(40) ); + + // bob unstakes BOOST_REQUIRE_EQUAL( success(), unstake( bob, core_from_string("10.0002"), core_from_string("10.0001") ) ); BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); @@ -1977,6 +1981,8 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), push_action(carol, N(claimrewards), mvo()("owner", carol)) ); produce_block( fc::hours(20) ); + + // bob votes for carol BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); cur_info2 = get_producer_info2(carol); @@ -1985,39 +1991,55 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); produce_block( fc::hours(53) ); - last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); - total_votes = get_producer_info(carol)["total_votes"].as_double(); + + // bob votes for carol again + // carol hasn't claimed rewards in over 3 days + total_votes = get_producer_info(carol)["total_votes"].as_double(); BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - cur_info2 = get_producer_info2(carol); - expected_votepay_share += double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + BOOST_REQUIRE_EQUAL( get_producer_info2(carol)["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); produce_block( fc::hours(20) ); + // bob votes for carol again + // carol still hasn't claimed rewards BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); + BOOST_REQUIRE_EQUAL(get_producer_info2(carol)["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); produce_block( fc::hours(24) ); + + // carol claims rewards BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - produce_block( fc::hours(1) ); + produce_block( fc::hours(5) ); + // alice votes for carol and emily + // emily hasn't claimed rewards in over 3 days last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol, emily } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); cur_info2 = get_producer_info2(carol); + auto cur_info2_emily = get_producer_info2(emily); + expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(emily)["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); + BOOST_REQUIRE_EQUAL(cur_info2["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL(cur_info2_emily["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); } FC_LOG_AND_RETHROW() From f63385893d09fb99d2a7a4adc9f672cc4ae679b4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 26 Jul 2018 11:00:39 -0400 Subject: [PATCH 0468/1048] Small changes in unit test - 2 --- tests/eosio.system_tests.cpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index f2665618..11573b20 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2015,7 +2015,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ produce_block( fc::hours(24) ); - // carol claims rewards + // carol finally claims rewards BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); @@ -2036,10 +2036,30 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL(cur_info2["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); - BOOST_REQUIRE_EQUAL(cur_info2_emily["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); + + produce_block( fc::hours(10) ); + + // bob chooses alice as proxy + // emily still hasn't claimed rewards + last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); + cur_info2 = get_producer_info2(carol); + cur_info2_emily = get_producer_info2(emily); + + expected_votepay_share += double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == + get_global_state3()["total_vpay_share_change_rate"].as_double() ); + BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_uint64(), + get_global_state3()["last_vpay_state_update"].as_uint64() ); } FC_LOG_AND_RETHROW() From 9b129b816e2599ed23d141f3cdedf1dcc01405f9 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 26 Jul 2018 11:02:53 -0400 Subject: [PATCH 0469/1048] Small changes in unit test - 3 --- tests/eosio.system_tests.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 11573b20..2792c599 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2046,7 +2046,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ // bob chooses alice as proxy // emily still hasn't claimed rewards last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); cur_info2 = get_producer_info2(carol); cur_info2_emily = get_producer_info2(emily); From be8798a43a48b713c34110a0457801618048f767 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 26 Jul 2018 18:32:42 -0400 Subject: [PATCH 0470/1048] Fix time boundary case --- eosio.system/src/producer_pay.cpp | 2 +- tests/eosio.system_tests.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index cbf6f5cb..7e46130f 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -156,7 +156,7 @@ namespace eosiosystem { _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.unpaid_blocks; - if( ct >= prod2->last_votepay_share_update && prod2->last_votepay_share_update > last_claim_plus_3days ) { + if( ct >= last_claim_plus_3days && last_claim_plus_3days <= prod2->last_votepay_share_update ) { _gstate3.total_vpay_share_change_rate += prod.total_votes; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 2792c599..6dcaede1 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1939,7 +1939,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), regproducer( carol, 1) ); BOOST_REQUIRE_EQUAL( success(), regproducer( emily, 1) ); - // bob chooses alice as a proxy + // bob chooses alice as proxy BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0002"), core_from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, core_from_string("150.0000"), core_from_string("150.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); From 358366ec4116e3164b98705a9af51b498d5d7134 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 27 Jul 2018 03:09:11 -0400 Subject: [PATCH 0471/1048] Cleaning up, and fixes for pointing to proper sdk and eosio --- CMakeLists.txt | 2 +- build.sh | 12 +----------- 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 080dc6db..f4360f6b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -17,7 +17,6 @@ endif() if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT) set(EOSIO_WASMSDK_ROOT "/usr/local/eosio.wasmsdk") - set(WASM_ROOT "/usr/local/eosio.wasmsdk") endif() list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake) @@ -30,6 +29,7 @@ if (NOT "${output}" EQUAL 0) message(FATAL_ERROR "Incorrect EOSIO.WasmSDK version, please use version ${EOSIO_WASMSDK_DEPENDENCY}.x") endif() +include_directories(AFTER ${BOOST_ROOT}/include) add_subdirectory(eosio.msig) add_subdirectory(eosio.sudo) add_subdirectory(eosio.system) diff --git a/build.sh b/build.sh index 90df0ab4..5ef9e1eb 100755 --- a/build.sh +++ b/build.sh @@ -5,19 +5,9 @@ printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' NC='\033[0m' -#if [ ! -d "/usr/local/eosio" ]; then -# printf "${RED}Error, please ensure that eosio is installed correctly!\n\n${NC}" -# exit -1 -#fi - -if [ ! -d "/usr/local/eosio.wasmsdk" ]; then - printf "${RED}Error, please ensure that eosio.wasmsdk is installed correctly!\n\n${NC}" - exit -1 -fi - CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake -DEOSIO_ROOT=/Users/judgefudge/master_eos/eos/build ../ +cmake ../ make -j${CORES} popd &> /dev/null From 32d6c7c83e9d3dbb3111e7ceb12e3b6e1cb8da9b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 27 Jul 2018 13:15:59 -0400 Subject: [PATCH 0472/1048] Votepay share update order unit test --- tests/eosio.system_tests.cpp | 66 ++++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 6dcaede1..0d6dd0dd 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2063,6 +2063,72 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { + + cross_15_percent_threshold(); + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + } + const auto alice = accounts[0]; + const auto bob = accounts[1]; + const auto carol = accounts[2]; + const auto emily = accounts[3]; + + BOOST_REQUIRE_EQUAL( success(), regproducer( carol ) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( emily ) ); + + produce_block( fc::hours(24) ); + + BOOST_REQUIRE_EQUAL( success(), stake( alice, core_from_string("100.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0000"), core_from_string("100.0000") ) ); + + BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); + + + BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); + produce_block( fc::hours(1) ); + BOOST_REQUIRE_EQUAL( success(), push_action( emily, N(claimrewards), mvo()("owner", emily) ) ); + + produce_block( fc::hours(3 * 24 + 1) ); + + { + signed_transaction trx; + set_transaction_headers(trx); + + trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {carol, config::active_name} }, mvo()("owner", carol) ) ); + + std::vector prods = { carol, emily }; + trx.actions.emplace_back( get_action( config::system_account_name, N(voteproducer), { {alice, config::active_name} }, + mvo()("voter", alice)("proxy", name(0))("producers", prods) ) ); + + trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {emily, config::active_name} }, mvo()("owner", emily) ) ); + + trx.sign( get_private_key( carol, "active" ), control->get_chain_id() ); + trx.sign( get_private_key( alice, "active" ), control->get_chain_id() ); + trx.sign( get_private_key( emily, "active" ), control->get_chain_id() ); + + push_transaction( trx ); + } + + const auto& carol_info = get_producer_info(carol); + const auto& carol_info2 = get_producer_info2(carol); + const auto& emily_info = get_producer_info(emily); + const auto& emily_info2 = get_producer_info2(emily); + const auto& gs3 = get_global_state3(); + BOOST_REQUIRE_EQUAL( carol_info2["last_votepay_share_update"].as_uint64(), gs3["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( emily_info2["last_votepay_share_update"].as_uint64(), gs3["last_vpay_state_update"].as_uint64() ); + BOOST_TEST_REQUIRE( 0 == carol_info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( 0 == emily_info2["votepay_share"].as_double() ); + BOOST_REQUIRE( 0 < carol_info["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( carol_info["total_votes"].as_double() == emily_info["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( gs3["total_vpay_share_change_rate"].as_double() == 2 * carol_info["total_votes"].as_double() ); + +} FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { From b1f3662c6cb07ca6262f194abbbc2b823d7ec21b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 27 Jul 2018 17:30:01 -0400 Subject: [PATCH 0473/1048] Bug fix - add corresponding unit test --- eosio.system/src/voting.cpp | 2 ++ tests/eosio.system_tests.cpp | 62 ++++++++++++++++++++++++++++++++++-- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index d20ec78a..afc91fcf 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -246,6 +246,7 @@ namespace eosiosystem { delta_change_rate += pd.second.first; } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { total_inactive_vpay_share += p.votepay_share; + total_inactive_vpay_share += init_total_votes * double( (_gstate3.last_vpay_state_update - p.last_votepay_share_update) / 1E6 ); p.votepay_share = 0; delta_change_rate -= init_total_votes; } @@ -341,6 +342,7 @@ namespace eosiosystem { delta_change_rate += delta; } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { total_inactive_vpay_share += p.votepay_share; + total_inactive_vpay_share += init_total_votes * double( (_gstate3.last_vpay_state_update - p.last_votepay_share_update) / 1E6 ); p.votepay_share = 0; delta_change_rate -= init_total_votes; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0d6dd0dd..52813400 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1914,6 +1914,62 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { + + cross_15_percent_threshold(); + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + } + const auto vota = accounts[0]; + const auto votb = accounts[1]; + const auto proda = accounts[2]; + const auto prodb = accounts[3]; + + BOOST_REQUIRE_EQUAL( success(), stake( vota, core_from_string("100.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( votb, core_from_string("100.0000"), core_from_string("100.0000") ) ); + + BOOST_REQUIRE_EQUAL( success(), regproducer( proda ) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( prodb ) ); + + BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); + + produce_block( fc::hours(25) ); + + BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); + + produce_block( fc::hours(1) ); + + BOOST_REQUIRE_EQUAL( success(), push_action(proda, N(claimrewards), mvo()("owner", proda)) ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(proda)["votepay_share"].as_double() ); + + produce_block( fc::hours(24) ); + + BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); + + produce_block( fc::hours(24) ); + + BOOST_REQUIRE_EQUAL( success(), push_action(prodb, N(claimrewards), mvo()("owner", prodb)) ); + BOOST_TEST_REQUIRE( 0 == get_producer_info2(prodb)["votepay_share"].as_double() ); + + produce_block( fc::hours(10) ); + + BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); + + produce_block( fc::hours(16) ); + + BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); + BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == + get_producer_info2(prodb)["votepay_share"].as_double() ); + +} FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_test::tolerance(1e-5)) try { @@ -2100,13 +2156,15 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost signed_transaction trx; set_transaction_headers(trx); - trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {carol, config::active_name} }, mvo()("owner", carol) ) ); + trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {carol, config::active_name} }, + mvo()("owner", carol) ) ); std::vector prods = { carol, emily }; trx.actions.emplace_back( get_action( config::system_account_name, N(voteproducer), { {alice, config::active_name} }, mvo()("voter", alice)("proxy", name(0))("producers", prods) ) ); - trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {emily, config::active_name} }, mvo()("owner", emily) ) ); + trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {emily, config::active_name} }, + mvo()("owner", emily) ) ); trx.sign( get_private_key( carol, "active" ), control->get_chain_id() ); trx.sign( get_private_key( alice, "active" ), control->get_chain_id() ); From 65b9a556fd8bfa7a8f598a96eef6aef7690fa9d5 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 31 Jul 2018 21:31:06 -0400 Subject: [PATCH 0474/1048] Use C definition of get_resource_limits which takes pointers. --- eosio.system/src/delegate_bandwidth.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 12fcd2ee..667a2c12 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -87,7 +87,7 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - + auto itr = _rammarket.find(S(4,RAMCORE)); auto tmp = *itr; auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); @@ -180,7 +180,7 @@ namespace eosiosystem { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); }); - + eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); _gstate.total_ram_bytes_reserved -= static_cast(bytes); // bytes > 0 is asserted above @@ -272,7 +272,7 @@ namespace eosiosystem { eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); int64_t ram_bytes, net, cpu; - get_resource_limits( receiver, ram_bytes, net, cpu ); + get_resource_limits( receiver, &ram_bytes, &net, &cpu ); set_resource_limits( receiver, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); @@ -290,8 +290,8 @@ namespace eosiosystem { auto net_balance = stake_net_delta; auto cpu_balance = stake_cpu_delta; bool need_deferred_trx = false; - - + + // net and cpu are same sign by assertions in delegatebw and undelegatebw // redundant assertion also at start of changebw to protect against misuse of changebw bool is_undelegating = (net_balance.amount + cpu_balance.amount ) < 0; From b02165e3754a199008ff089120be5ccb4c0bf076 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 31 Jul 2018 23:03:43 -0400 Subject: [PATCH 0475/1048] update_ram_supply() before setting new rate; use current_time() rather than tracking last_block_num (makes last_block_num field obsolete) This code also properly handles the edge case where the first setramrate action is called in the same block in which the system contract introducing eosio_global_state2 is upgraded. --- .../include/eosio.system/eosio.system.hpp | 17 +++++++------- eosio.system/src/eosio.system.cpp | 23 +++++++++++-------- eosio.system/src/producer_pay.cpp | 2 +- tests/eosio.system_tests.cpp | 19 ++++++++++++--- 4 files changed, 39 insertions(+), 22 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 276a61e7..6564ec9b 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -67,9 +67,9 @@ namespace eosiosystem { struct eosio_global_state2 { eosio_global_state2(){} - uint16_t new_ram_per_block = 0; + uint16_t new_ram_per_block = 0; block_timestamp last_ram_increase; - block_timestamp last_block_num; + block_timestamp last_block_num; /* unnecessary now; deprecated? */ double reserved = 0; uint8_t revision = 0; ///< used to track version updates in the future. @@ -236,18 +236,19 @@ namespace eosiosystem { void bidname( account_name bidder, account_name newname, asset bid ); private: - void update_elected_producers( block_timestamp timestamp ); - void update_ram_supply(); - // Implementation details: - //defind in delegate_bandwidth.cpp + //defined in eosio.system.cpp + static eosio_global_state get_default_parameters(); + static block_timestamp current_block_time(); + void update_ram_supply(); + + //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); //defined in voting.hpp - static eosio_global_state get_default_parameters(); - + void update_elected_producers( block_timestamp timestamp ); void update_votes( const account_name voter, const account_name proxy, const std::vector& producers, bool voting ); // defined in voting.cpp diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 1f0b6a11..7766ec8d 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -46,6 +46,11 @@ namespace eosiosystem { return dp; } + block_timestamp system_contract::current_block_time() { + const /* static */ block_timestamp cbt{ time_point{ microseconds{ static_cast( current_time() ) } } }; + // static causes linking errors: undefined symbols __cxa_guard_acquire and __cxa_guard_release + return cbt; + } system_contract::~system_contract() { _global.set( _gstate, _self ); @@ -73,10 +78,12 @@ namespace eosiosystem { } void system_contract::update_ram_supply() { - if( _gstate2.last_block_num <= _gstate2.last_ram_increase ) return; + auto cbt = current_block_time(); + + if( cbt <= _gstate2.last_ram_increase ) return; auto itr = _rammarket.find(S(4,RAMCORE)); - auto new_ram = (_gstate2.last_block_num.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; + auto new_ram = (cbt.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; _gstate.max_ram_size += new_ram; /** @@ -85,12 +92,12 @@ namespace eosiosystem { _rammarket.modify( itr, 0, [&]( auto& m ) { m.base.balance.amount += new_ram; }); - _gstate2.last_ram_increase = _gstate2.last_block_num; + _gstate2.last_ram_increase = cbt; } /** - * Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to - * a maximum rate of 3 TB per year. + * Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to + * a maximum rate of 3 TB per year. * * If update_ram_supply hasn't been called for the most recent block, then new ram will * be allocated at the old rate up to the present block before switching the rate. @@ -98,12 +105,8 @@ namespace eosiosystem { void system_contract::setramrate( uint16_t bytes_per_block ) { require_auth( _self ); + update_ram_supply(); _gstate2.new_ram_per_block = bytes_per_block; - if( _gstate2.last_ram_increase == block_timestamp() ) { - _gstate2.last_ram_increase = _gstate2.last_block_num; - } else { - update_ram_supply(); - } } void system_contract::setparams( const eosio::blockchain_parameters& params ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 84e2444a..2244f9d9 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -21,7 +21,7 @@ namespace eosiosystem { using namespace eosio; require_auth(N(eosio)); - _gstate2.last_block_num = timestamp; + _gstate2.last_block_num = timestamp; // QUESTION: Should this be removed now that last_block_num is not neeeded? /** until activated stake crosses this threshold no new rewards are paid */ if( _gstate.total_activated_stake < min_activated_stake ) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 96b549d8..06bae27d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2608,12 +2608,15 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); produce_blocks(3); BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - const uint16_t rate = 1000; + uint16_t rate = 1000; BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); BOOST_REQUIRE_EQUAL( rate, get_global_state2()["new_ram_per_block"].as() ); - // last time update_ram_supply called is in buyram, num of blocks since then is 1 + 3 = 4 + // last time update_ram_supply called is in buyram, num of blocks since then to + // the block that includes the setramrate action is 1 + 3 = 4. + // However, those 4 blocks were accumulating at a rate of 0, so the max_ram_size should not have changed. + BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); + // But with additional blocks, it should start accumulating at the new rate. uint64_t cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - BOOST_REQUIRE_EQUAL( init_max_ram_size + 4 * rate, get_global_state()["max_ram_size"].as_uint64() ); produce_blocks(10); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * rate, get_global_state()["max_ram_size"].as_uint64() ); @@ -2630,6 +2633,16 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), push_action( "alice1111111", N(setramrate), mvo()("bytes_per_block", rate) ) ); + cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); + produce_blocks(10); + uint16_t old_rate = rate; + rate = 5000; + BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); + BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate, get_global_state()["max_ram_size"].as_uint64() ); + produce_blocks(5); + BOOST_REQUIRE_EQUAL( success(), buyrambytes( "alice1111111", "alice1111111", 100 ) ); + BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate + 6 * rate, get_global_state()["max_ram_size"].as_uint64() ); + } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { From 776ae6f322711c01742985a691befbdea64c0eec Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 31 Jul 2018 23:51:24 -0400 Subject: [PATCH 0476/1048] Merge branch 'get-resource-limits-fix' into metric3 --- CMakeLists.txt | 27 ++-- README.md | 9 +- UnitTestsExternalProject.txt | 4 +- build.sh | 51 +------ eosio.msig/CMakeLists.txt | 4 +- eosio.msig/bin/eosio.msig/.gitignore | 2 - eosio.msig/build.sh | 21 --- eosio.sudo/CMakeLists.txt | 4 +- eosio.sudo/bin/eosio.sudo/.gitignore | 2 - eosio.sudo/build.sh | 21 --- eosio.system/CMakeLists.txt | 4 +- eosio.system/bin/eosio.system/.gitignore | 2 - eosio.system/build.sh | 21 --- eosio.system/src/delegate_bandwidth.cpp | 18 ++- eosio.system/src/producer_pay.cpp | 2 +- eosio.token/CMakeLists.txt | 4 +- eosio.token/abi/eosio.token.abi | 2 +- eosio.token/bin/eosio.token/.gitignore | 2 - eosio.token/build.sh | 21 --- tests/CMakeLists.txt | 180 ++--------------------- tests/contracts.hpp.in | 24 +-- tests/eosio.msig_tests.cpp | 24 +-- tests/eosio.sudo_tests.cpp | 6 +- tests/eosio.system_tester.hpp | 36 ++--- tests/eosio.system_tests.cpp | 95 ++++++++---- tests/eosio.token_tests.cpp | 8 +- tests/main.cpp | 42 ++++++ 27 files changed, 211 insertions(+), 425 deletions(-) delete mode 100644 eosio.msig/bin/eosio.msig/.gitignore delete mode 100755 eosio.msig/build.sh delete mode 100644 eosio.sudo/bin/eosio.sudo/.gitignore delete mode 100755 eosio.sudo/build.sh delete mode 100644 eosio.system/bin/eosio.system/.gitignore delete mode 100755 eosio.system/build.sh delete mode 100644 eosio.token/bin/eosio.token/.gitignore delete mode 100755 eosio.token/build.sh create mode 100644 tests/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 11c809ca..8da6ec3f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,8 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.1.0) +project(eosio_contracts VERSION 1.1.1) + +set(EOSIO_DEPENDENCY "1.1") +set(EOSIO_WASMSDK_DEPENDENCY "1.1") if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(TEST_BUILD_TYPE "Debug") @@ -7,22 +10,26 @@ if(CMAKE_BUILD_TYPE STREQUAL "Debug") else() set(TEST_BUILD_TYPE ${CMAKE_BUILD_TYPE}) endif() -if(CXX_COMPILER STREQUAL "" OR NOT CXX_COMPILER) - set(CXX_COMPILER ${CMAKE_CXX_COMPILER}) -endif() -if(EOSIO_INSTALL_PREFIX STREQUAL "" OR NOT EOSIO_INSTALL_PREFIX) - set(EOSIO_INSTALL_PREFIX "/usr/local") +if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) + set(EOSIO_ROOT "/usr/local/eosio") endif() -# if no wasm root is given use default path -if(WASM_ROOT STREQUAL "" OR NOT WASM_ROOT) - set(WASM_ROOT ${CMAKE_INSTALL_PREFIX}) +if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT) + set(EOSIO_WASMSDK_ROOT "/usr/local/eosio.wasmsdk") endif() -list(APPEND CMAKE_MODULE_PATH ${WASM_ROOT}/lib/cmake) +list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake) include(EosioWasmToolchain) +### Check the version of wasmsdk +string(FIND "${EOSIO_WASMSDK_VERSION}" "${EOSIO_WASMSDK_DEPENDENCY}" output) + +if (NOT "${output}" EQUAL 0) + message(FATAL_ERROR "Incorrect EOSIO.WasmSDK version, please use version ${EOSIO_WASMSDK_DEPENDENCY}.x") +endif() + +include_directories(AFTER ${BOOST_ROOT}/include) add_subdirectory(eosio.msig) add_subdirectory(eosio.sudo) add_subdirectory(eosio.system) diff --git a/README.md b/README.md index 4aebc8a6..883c887f 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,16 @@ # eosio.contracts -## Version : 1.1.0 +## Version : 1.1.1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. -This repository contains examples of these priviledged contracts that are useful when depoying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: +This repository contains examples of these privileged contracts that are useful when deploying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) - * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) * [eosio.sudo](https://github.com/eosio/eosio.contracts/tree/master/eosio.sudo) - -The following unpriviledged contract(s) are also part of the system. + +The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 73ccd2d9..b7f9af50 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -4,10 +4,10 @@ include(GNUInstallDirs) ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DROOT_DIR=${CMAKE_SOURCE_DIR} -DEOSIO_INSTALL_PREFIX=${EOSIO_INSTALL_PREFIX} -DOPENSSL_INSTALL_PREFIX=${OPENSSL_ROOT} -DSECP256K1_INSTALL_LIB=${SECP256K1_ROOT} -DBOOST_ROOT=${BOOST_ROOT}/include -DCMAKE_CXX_COMPILER=${CXX_COMPILER} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} -DEOSIO_DEPENDENCY=${EOSIO_DEPENDENCY} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests - BINARY_DIR ${CMAKE_SOURCE_DIR}/build/tests + BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 TEST_COMMAND "" INSTALL_COMMAND "" diff --git a/build.sh b/build.sh index 815e9f27..5ef9e1eb 100755 --- a/build.sh +++ b/build.sh @@ -5,58 +5,9 @@ printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' NC='\033[0m' -#if [ ! -d "/usr/local/eosio" ]; then -# printf "${RED}Error, please ensure that eosio is installed correctly!\n\n${NC}" -# exit -1 -#fi - -if [ ! -d "/usr/local/eosio.wasmsdk" ]; then - printf "${RED}Error, please ensure that eosio.wasmsdk is installed correctly!\n\n${NC}" - exit -1 -fi - -unamestr=`uname` -if [[ "${unamestr}" == 'Darwin' ]]; then - BOOST=/usr/local - CXX_COMPILER=g++ -else - BOOST=~/opt/boost - OS_NAME=$( cat /etc/os-release | grep ^NAME | cut -d'=' -f2 | sed 's/\"//gI' ) - - case "$OS_NAME" in - "Amazon Linux AMI") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "CentOS Linux") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "elementary OS") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Fedora") - CXX_COMPILER=g++ - C_COMPILER=gcc - ;; - "Linux Mint") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - "Ubuntu") - CXX_COMPILER=clang++-4.0 - C_COMPILER=clang-4.0 - ;; - *) - printf "\\n\\tUnsupported Linux Distribution. Exiting now.\\n\\n" - exit 1 - esac -fi - CORES=`getconf _NPROCESSORS_ONLN` mkdir -p build pushd build &> /dev/null -cmake -DCXX_COMPILER="${CXX_COMPILER}" -DBOOST_ROOT="${BOOST}" -DEOSIO_INSTALL_PREFIX=/usr/local ../ +cmake ../ make -j${CORES} popd &> /dev/null diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index c5dd83e7..1741e7c9 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,4 +1,4 @@ -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) add_executable(eosio.msig.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm @@ -7,6 +7,6 @@ target_include_directories(eosio.msig.wasm set_target_properties(eosio.msig.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.msig") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.msig/bin/eosio.msig/.gitignore b/eosio.msig/bin/eosio.msig/.gitignore deleted file mode 100644 index db5b01cc..00000000 --- a/eosio.msig/bin/eosio.msig/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.msig.abi -eosio.msig.wasm diff --git a/eosio.msig/build.sh b/eosio.msig/build.sh deleted file mode 100755 index 13d28a8c..00000000 --- a/eosio.msig/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.msig" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt index f38dae57..b02d424e 100644 --- a/eosio.sudo/CMakeLists.txt +++ b/eosio.sudo/CMakeLists.txt @@ -5,7 +5,7 @@ target_include_directories(eosio.sudo.wasm set_target_properties(eosio.sudo.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.sudo" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE__CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.sudo/bin/eosio.sudo/.gitignore b/eosio.sudo/bin/eosio.sudo/.gitignore deleted file mode 100644 index 35898c3b..00000000 --- a/eosio.sudo/bin/eosio.sudo/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.sudo.abi -eosio.sudo.wasm diff --git a/eosio.sudo/build.sh b/eosio.sudo/build.sh deleted file mode 100755 index 9892f2e8..00000000 --- a/eosio.sudo/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.sudo" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index b0bc4431..8b47085e 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -6,8 +6,8 @@ target_include_directories(eosio.system.wasm set_target_properties(eosio.system.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.system" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.system/bin/eosio.system/.gitignore b/eosio.system/bin/eosio.system/.gitignore deleted file mode 100644 index 105891a4..00000000 --- a/eosio.system/bin/eosio.system/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.system.abi -eosio.system.wasm diff --git a/eosio.system/build.sh b/eosio.system/build.sh deleted file mode 100755 index f5028c69..00000000 --- a/eosio.system/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.system" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I../eosio.token/include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 3b1599b7..667a2c12 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -30,6 +30,7 @@ namespace eosiosystem { static constexpr time refund_delay = 3*24*3600; static constexpr time refund_expiration_time = 3600; + static constexpr int64_t ram_gift_bytes = 1400; struct user_resources { account_name owner; @@ -86,7 +87,7 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - + auto itr = _rammarket.find(S(4,RAMCORE)); auto tmp = *itr; auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); @@ -152,7 +153,7 @@ namespace eosiosystem { res.ram_bytes += bytes_out; }); } - set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } @@ -179,7 +180,7 @@ namespace eosiosystem { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); }); - + eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); _gstate.total_ram_bytes_reserved -= static_cast(bytes); // bytes > 0 is asserted above @@ -191,7 +192,7 @@ namespace eosiosystem { userres.modify( res_itr, account, [&]( auto& res ) { res.ram_bytes -= bytes; }); - set_resource_limits( res_itr->owner, res_itr->ram_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.ram),N(active)},{account,N(active)}}, { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); @@ -270,7 +271,10 @@ namespace eosiosystem { eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); - set_resource_limits( receiver, tot_itr->ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + int64_t ram_bytes, net, cpu; + get_resource_limits( receiver, &ram_bytes, &net, &cpu ); + + set_resource_limits( receiver, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); @@ -286,8 +290,8 @@ namespace eosiosystem { auto net_balance = stake_net_delta; auto cpu_balance = stake_cpu_delta; bool need_deferred_trx = false; - - + + // net and cpu are same sign by assertions in delegatebw and undelegatebw // redundant assertion also at start of changebw to protect against misuse of changebw bool is_undelegating = (net_balance.amount + cpu_balance.amount ) < 0; diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 7e46130f..3fc9a94b 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -50,7 +50,7 @@ namespace eosiosystem { if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { name_bid_table bids(_self,_self); auto idx = bids.get_index(); - auto highest = idx.begin(); + auto highest = idx.lower_bound( std::numeric_limits::max()/2 ); if( highest != idx.end() && highest->high_bid > 0 && highest->last_bid_time < (current_time() - useconds_per_day) && diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt index 39993201..9ff728c3 100644 --- a/eosio.token/CMakeLists.txt +++ b/eosio.token/CMakeLists.txt @@ -5,7 +5,7 @@ target_include_directories(eosio.token.wasm set_target_properties(eosio.token.wasm PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token") + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_SOURCE_DIR}/bin/eosio.token" COPYONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) #install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi index b7352d36..ce5861f2 100644 --- a/eosio.token/abi/eosio.token.abi +++ b/eosio.token/abi/eosio.token.abi @@ -40,7 +40,7 @@ "base": "", "fields": [ {"name":"owner", "type":"account_name"}, - {"name":"symbol", "type":"symbol"}, + {"name":"symbol", "type":"symbol"} ] },{ "name": "account", diff --git a/eosio.token/bin/eosio.token/.gitignore b/eosio.token/bin/eosio.token/.gitignore deleted file mode 100644 index e5513007..00000000 --- a/eosio.token/bin/eosio.token/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -eosio.token.abi -eosio.token.wasm diff --git a/eosio.token/build.sh b/eosio.token/build.sh deleted file mode 100755 index 7394a451..00000000 --- a/eosio.token/build.sh +++ /dev/null @@ -1,21 +0,0 @@ -#! /bin/bash - -CONTRACT_NAME="eosio.token" - -mkdir -p bin/${CONTRACT_NAME} -### BUILD THE CONTRACT -EOSCLANG="${PREFIX}/wasm/bin/clang++ -I${INSTALL_PREFIX}/include/libc++/upstream/include -I${INSTALL_PREFIX}/include/musl/upstream/include -I${INSTALL_PREFIX}/include -I./include -I${BOOST}" -LINK="${PREFIX}/wasm/bin/llvm-link -only-needed " -LLC="${PREFIX}/wasm/bin/llc -thread-model=single --asm-verbose=false" -S2W="${INSTALL_PREFIX}/bin/eosio-s2wasm " -W2W="${INSTALL_PREFIX}/bin/eosio-wast2wasm " - -${EOSCLANG} -Iinclude -c -emit-llvm -O3 --std=c++14 --target=wasm32 -nostdinc -DBOOST_DISABLE_ASSERTS -DBOOST_EXCEPTION_DISABLE -nostdlib -nostdlibinc -ffreestanding -nostdlib -fno-threadsafe-statics -fno-rtti -fno-exceptions -o ${CONTRACT_NAME}.bc src/${CONTRACT_NAME}.cpp -${LINK} -o linked.bc ${CONTRACT_NAME}.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/eosiolib.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc++.bc ${INSTALL_PREFIX}/usr/share/eosio/contractsdk/lib/libc.bc -${LLC} -o ${CONTRACT_NAME}.s linked.bc -${S2W} -o ${CONTRACT_NAME}.wast -s 16384 ${CONTRACT_NAME}.s -${W2W} ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wasm -n -cp abi/${CONTRACT_NAME}.abi bin/${CONTRACT_NAME}/${CONTRACT_NAME}.abi -cp ${CONTRACT_NAME}.wast bin/${CONTRACT_NAME}/${CONTRACT_NAME}.wast - -rm ${CONTRACT_NAME}.bc linked.bc ${CONTRACT_NAME}.wast ${CONTRACT_NAME}.s diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2a22a3ea..12b6d8f1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,179 +1,21 @@ cmake_minimum_required( VERSION 3.5 ) -project( EOSIO_CONTRACTS_TESTS ) -set( VERSION_MAJOR 1 ) -set( VERSION_MINOR 0 ) -set( VERSION_PATCH 0 ) -enable_testing() +list(APPEND CMAKE_MODULE_PATH ${EOSIO_ROOT}/lib/cmake) +include(EosioTester) -find_package( Gperftools QUIET ) -if( GPERFTOOLS_FOUND ) - message( STATUS "Found gperftools; compiling tests with TCMalloc") - list( APPEND PLATFORM_SPECIFIC_LIBS tcmalloc ) +### check the version of EOSIO +string(FIND "${EOSIO_VERSION}" "${EOSIO_DEPENDENCY}" output) +if (NOT "${output}" EQUAL 0) + message(FATAL_ERROR "Incorrect EOSIO version, please use version ${EOSIO_DEPENDENCY}.x") endif() -find_package(LLVM 4.0 REQUIRED CONFIG) - -link_directories(${LLVM_LIBRARY_DIR}) - -set( CMAKE_CXX_STANDARD 14 ) -set( CMAKE_CXX_EXTENSIONS ON ) -set( CXX_STANDARD_REQUIRED ON ) - -if ( APPLE ) - set( CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} -Wall -Wno-deprecated-declarations" ) -else ( APPLE ) - set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") - set( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libstdc++ -static-libgcc") -endif ( APPLE ) - -set( Boost_USE_STATIC_LIBS ON CACHE STRING "ON or OFF" ) -configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_SOURCE_DIR}/contracts.hpp) -find_package(Boost 1.67 REQUIRED COMPONENTS - date_time - filesystem - system - chrono - iostreams - date_time - unit_test_framework) - -file(GLOB UNIT_TESTS "*.cpp") - -find_library(libtester eosio_testing ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libchain eosio_chain ${EOSIO_INSTALL_PREFIX}/lib) -if ( "${CMAKE_BUILD_TYPE}" EQUAL "Debug" ) - find_library(libfc fc_debug ${EOSIO_INSTALL_PREFIX}/lib) -else() - find_library(libfc fc ${EOSIO_INSTALL_PREFIX}/lib) -endif() -find_library(libbinaryen binaryen ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libwasm WASM ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libwast WAST ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libir IR ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libplatform Platform ${EOSIO_INSTALL_PREFIX}/lib) -find_library(liblogging Logging ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libruntime Runtime ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libsoftfloat softfloat ${EOSIO_INSTALL_PREFIX}/lib) -find_library(liboscrypto crypto ${OPENSSL_INSTALL_PREFIX}/lib) -find_library(libosssl ssl ${OPENSSL_INSTALL_PREFIX}/lib) -find_library(libchainbase chainbase ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libbuiltins builtins ${EOSIO_INSTALL_PREFIX}/lib) -find_library(libsecp256k1 secp256k1 ${SECP256K1_INSTALL_LIB}) - -add_executable( unit_test ${UNIT_TESTS} ) -target_link_libraries( unit_test - ${LLVM} - ${libtester} - ${libchain} - ${libfc} - ${libbinaryen} - ${libwast} - ${libwasm} - ${libruntime} - ${libplatform} - ${libir} - ${libsoftfloat} - ${liboscrypto} - ${libosssl} - ${liblogging} - ${libchainbase} - ${libbuiltins} - ${libsecp256k1} - - LLVMX86Disassembler - LLVMX86AsmParser - LLVMX86AsmPrinter - LLVMX86CodeGen - - LLVMSelectionDAG - - LLVMDebugInfoDWARF - LLVMAsmPrinter - LLVMMCParser - LLVMX86Info - - LLVMOrcJIT - LLVMExecutionEngine - - LLVMCodeGen - LLVMScalarOpts - LLVMTransformUtils - - LLVMipo - LLVMAnalysis - LLVMTarget - LLVMMC - LLVMCore - LLVMSupport - ${Boost_FILESYSTEM_LIBRARY} - ${Boost_SYSTEM_LIBRARY} - ${Boost_CHRONO_LIBRARY} - ${Boost_IOSTREAMS_LIBRARY} - ${Boost_DATE_TIME_LIBRARY} - ${PLATFORM_SPECIFIC_LIBS} - ) -target_include_directories( unit_test PUBLIC - ${Boost_INCLUDE_DIRS} - ${OPENSSL_INSTALL_PREFIX}/include - ${EOSIO_INSTALL_PREFIX} - ${EOSIO_INSTALL_PREFIX}/include - ${EOSIO_INSTALL_PREFIX}/include/eosio/wasm-jit/Include - ${EOSIO_INSTALL_PREFIX}/include/eosio/softfloat/include - ${CMAKE_CURRENT_BINARY_DIR}/include ) - -#Manually run unit_test for all supported runtimes -#To run unit_test with all log from blockchain displayed, put --verbose after --, i.e. unit_test -- --verbose -add_test(NAME unit_test_binaryen COMMAND unit_test - --report_level=detailed --color_output -- --binaryen) -add_test(NAME unit_test_wavm COMMAND unit_test - --report_level=detailed --color_output --catch_system_errors=no -- --wavm) - -if(ENABLE_COVERAGE_TESTING) - - set(Coverage_NAME ${PROJECT_NAME}_ut_coverage) - - if(NOT LCOV_PATH) - message(FATAL_ERROR "lcov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT LLVMCOV_PATH) - message(FATAL_ERROR "llvm-cov not found! Aborting...") - endif() # NOT LCOV_PATH - - if(NOT GENHTML_PATH) - message(FATAL_ERROR "genhtml not found! Aborting...") - endif() # NOT GENHTML_PATH - - # no spaces allowed within tests list - set(ctest_tests 'unit_test_binaryen|unit_test_wavm') - set(ctest_exclude_tests '') - - # Setup target - add_custom_target(${Coverage_NAME} - - # Cleanup lcov - COMMAND ${LCOV_PATH} --directory . --zerocounters - - # Run tests - COMMAND ./tools/ctestwrapper.sh -R ${ctest_tests} -E ${ctest_exclude_tests} - - COMMAND ${LCOV_PATH} --directory . --capture --gcov-tool ./tools/llvm-gcov.sh --output-file ${Coverage_NAME}.info - - COMMAND ${LCOV_PATH} -remove ${Coverage_NAME}.info '*/boost/*' '/usr/lib/*' '/usr/include/*' '*/externals/*' '*/fc/*' '*/wasm-jit/*' --output-file ${Coverage_NAME}_filtered.info +enable_testing() - COMMAND ${GENHTML_PATH} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info +configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contracts.hpp) - COMMAND if [ "$CI" != "true" ]\; then ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.info ${Coverage_NAME}_filtered.info ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned ${PROJECT_BINARY_DIR}/${Coverage_NAME}_filtered.info.cleaned\; fi +include_directories(${CMAKE_BINARY_DIR}) - WORKING_DIRECTORY ${PROJECT_BINARY_DIR} - COMMENT "Resetting code coverage counters to zero. Processing code coverage counters and generating report. Report published in ./${Coverage_NAME}" - ) +file(GLOB UNIT_TESTS "*.cpp" "*.hpp") - # Show info where to find the report - add_custom_command(TARGET ${Coverage_NAME} POST_BUILD - COMMAND ; - COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report." - ) -endif() +add_eosio_test( unit_test ${UNIT_TESTS} ) diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 1d91f506..2db2153f 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -4,18 +4,18 @@ namespace eosio { namespace testing { struct contracts { - static std::vector system_wasm() { return read_wasm("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.wast"); } - static std::vector system_abi() { return read_abi("${ROOT_DIR}/eosio.system/bin/eosio.system/eosio.system.abi"); } - static std::vector token_wasm() { return read_wasm("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("${ROOT_DIR}/eosio.token/bin/eosio.token/eosio.token.abi"); } - static std::vector msig_wasm() { return read_wasm("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.wast"); } - static std::vector msig_abi() { return read_abi("${ROOT_DIR}/eosio.msig/bin/eosio.msig/eosio.msig.abi"); } - static std::vector sudo_wasm() { return read_wasm("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wasm"); } - static std::string sudo_wast() { return read_wast("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.wast"); } - static std::vector sudo_abi() { return read_abi("${ROOT_DIR}/eosio.sudo/bin/eosio.sudo/eosio.sudo.abi"); } + static std::vector system_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.abi"); } + static std::vector sudo_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wasm"); } + static std::string sudo_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wast"); } + static std::vector sudo_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.abi"); } struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index ce01cc85..0683a552 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -36,7 +36,7 @@ class eosio_msig_tester : public tester { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, @@ -138,19 +138,19 @@ class eosio_msig_tester : public tester { action act; act.account = N(eosio.msig); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); //std::cout << "test:\n" << fc::to_hex(act.data.data(), act.data.size()) << " size = " << act.data.size() << std::endl; return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : 0 ); */ } - transaction reqauth( account_name from, const vector& auths ); + transaction reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ); abi_serializer abi_ser; }; -transaction eosio_msig_tester::reqauth( account_name from, const vector& auths ) { +transaction eosio_msig_tester::reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ) { fc::variants v; for ( auto& level : auths ) { v.push_back(fc::mutable_variant_object() @@ -174,14 +174,14 @@ transaction eosio_msig_tester::reqauth( account_name from, const vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -304,7 +304,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { - auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } } ); + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); //try with not enough requested auth BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -345,7 +345,7 @@ BOOST_FIXTURE_TEST_CASE( big_transaction, eosio_msig_tester ) try { ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -451,7 +451,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); // propose action push_action( N(alice), N(propose), mvo() @@ -562,7 +562,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ); transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); // propose action push_action( N(alice), N(propose), mvo() diff --git a/tests/eosio.sudo_tests.cpp b/tests/eosio.sudo_tests.cpp index 607b2677..8de7a93f 100644 --- a/tests/eosio.sudo_tests.cpp +++ b/tests/eosio.sudo_tests.cpp @@ -77,7 +77,7 @@ class eosio_sudo_tester : public tester { const auto& accnt = control->db().get( N(eosio.sudo) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); while( control->pending_block_state()->header.producer.to_string() == "eosio" ) { produce_block(); @@ -134,7 +134,7 @@ transaction eosio_sudo_tester::sudo_exec( account_name executer, const transacti transaction trx2; set_transaction_headers(trx2, expiration); action act; - abi_serializer::from_variant( act_obj, act, get_resolver() ); + abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer_max_time ); trx2.actions.push_back( std::move(act) ); return trx2; } @@ -155,7 +155,7 @@ transaction eosio_sudo_tester::reqauth( account_name from, const vectordb().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi); + token_abi_ser.set_abi(abi, abi_serializer_max_time); } create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); @@ -63,7 +63,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } produce_blocks(); @@ -219,7 +219,7 @@ class eosio_system_tester : public TESTER { action act; act.account = config::system_account_name; act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); } @@ -320,27 +320,27 @@ class eosio_system_tester : public TESTER { asset get_balance( const account_name& act ) { vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYMBOL).to_symbol_code().value ); - return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data)["balance"].as(); + return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); } fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); } fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data ); + return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); } fc::variant get_producer_info2( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers2), act ); - return abi_ser.binary_to_variant( "producer_info2", data ); + return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer_max_time ); } void create_currency( name contract, name manager, asset maxsupply ) { @@ -380,7 +380,7 @@ class eosio_system_tester : public TESTER { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } asset get_token_supply() { @@ -389,22 +389,23 @@ class eosio_system_tester : public TESTER { fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data ); + if (data.empty()) std::cout << "\nData is empty\n" << std::endl; + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer_max_time ); } fc::variant get_global_state2() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer_max_time ); } fc::variant get_global_state3() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global3), N(global3) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data, abi_serializer_max_time ); } fc::variant get_refund_request( name account ) { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer_max_time ); } abi_serializer initialize_multisig() { @@ -419,7 +420,7 @@ class eosio_system_tester : public TESTER { ("account", "eosio.msig") ("is_priv", 1) ); - + set_code( N(eosio.msig), contracts::msig_wasm() ); set_abi( N(eosio.msig), contracts::msig_abi().data() ); @@ -427,13 +428,11 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def msig_abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi); + msig_abi_ser.set_abi(msig_abi, abi_serializer_max_time); } return msig_abi_ser; } - //helper function - vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain transfer( "eosio", "alice1111111", core_from_string("650000000.0000"), "eosio" ); @@ -527,6 +526,7 @@ class eosio_system_tester : public TESTER { trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); trx.sign( get_private_key( N(producer1111), "active" ), control->get_chain_id() ); push_transaction( trx ); + produce_block(); } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 52813400..09151899 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -2260,7 +2259,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -2299,7 +2298,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -2933,6 +2932,21 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( namebid_pending_winner, eosio_system_tester ) try { + cross_15_percent_threshold(); + produce_block( fc::hours(14*24) ); //wait 14 day for name auction activation + transfer( config::system_account_name, N(alice1111111), core_from_string("10000.0000") ); + transfer( config::system_account_name, N(bob111111111), core_from_string("10000.0000") ); + + BOOST_REQUIRE_EQUAL( success(), bidname( "alice1111111", "prefa", core_from_string( "50.0000" ) )); + BOOST_REQUIRE_EQUAL( success(), bidname( "bob111111111", "prefb", core_from_string( "30.0000" ) )); + produce_block( fc::hours(100) ); //should close "perfa" + produce_block( fc::hours(100) ); //should close "perfb" + + //despite "perfa" account hasn't been created, we should be able to create "perfb" account + create_account_with_resources( N(prefb), N(bob111111111) ); +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { const asset net = core_from_string("80.0000"); @@ -3022,7 +3036,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); }; @@ -3058,7 +3072,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver()); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -3181,9 +3195,9 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), push_action( "alice1111111", N(setramrate), mvo()("bytes_per_block", rate) ) ); - + } FC_LOG_AND_RETHROW() - + BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); @@ -3205,7 +3219,7 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { auto rlm = control->get_resource_limits_manager(); auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - //std::cout << "Sellram" << std::endl; + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 2048 ) ); //make sure that ram was billed to alice, not to eosio.ram @@ -3214,30 +3228,49 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_SUITE_END() +BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { + active_and_vote_producers(); -void translate_fc_exception(const fc::exception &e) { - std::cerr << "\033[33m" << e.to_detail_string() << "\033[0m" << std::endl; - BOOST_TEST_FAIL("Caught Unexpected Exception"); -} + auto rlm = control->get_resource_limits_manager(); + int64_t ram_bytes_orig, net_weight, cpu_weight; + rlm.get_account_limits( N(alice1111111), ram_bytes_orig, net_weight, cpu_weight ); -boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { - // Turn off blockchain logging if no --verbose parameter is not added - // To have verbose enabled, call "tests/chain_test -- --verbose" - bool is_verbose = false; - std::string verbose_arg = "--verbose"; - for (int i = 0; i < argc; i++) { - if (verbose_arg == argv[i]) { - is_verbose = true; - break; - } - } - if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + /* + * It seems impossible to write this test, because buyrambytes action doesn't give you exact amount of bytes requested + * + //check that it's possible to create account bying required_bytes(2724) + userres table(112) + userres row(160) - ram_gift_bytes(1400) + create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 ); + + //check that one byte less is not enough + BOOST_REQUIRE_THROW( create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 - 1 ), + ram_usage_exceeded ); + */ - // Register fc::exception translator - boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); + //check that stake/unstake keeps the gift + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + int64_t ram_bytes_after_stake; + rlm.get_account_limits( N(alice1111111), ram_bytes_after_stake, net_weight, cpu_weight ); + BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_stake ); - std::srand(time(NULL)); - std::cout << "Random number generator seeded to " << time(NULL) << std::endl; - return nullptr; -} + BOOST_REQUIRE_EQUAL( success(), unstake( "eosio", "alice1111111", core_from_string("20.0000"), core_from_string("10.0000") ) ); + int64_t ram_bytes_after_unstake; + rlm.get_account_limits( N(alice1111111), ram_bytes_after_unstake, net_weight, cpu_weight ); + BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_unstake ); + + uint64_t ram_gift = 1400; + + int64_t ram_bytes; + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("1000.0000") ) ); + rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); + auto userres = get_total_stake( N(alice1111111) ); + BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); + + BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 1024 ) ); + rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); + userres = get_total_stake( N(alice1111111) ); + BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); + +} FC_LOG_AND_RETHROW() + +BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 093d8d0f..e77ddf70 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -33,7 +33,7 @@ class eosio_token_tester : public tester { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi); + abi_ser.set_abi(abi, abi_serializer_max_time); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) { @@ -42,7 +42,7 @@ class eosio_token_tester : public tester { action act; act.account = N(eosio.token); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data ); + act.data = abi_ser.variant_to_binary( action_type_name, data,abi_serializer_max_time ); return base_tester::push_action( std::move(act), uint64_t(signer)); } @@ -52,7 +52,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } fc::variant get_account( account_name acc, const string& symbolname) @@ -60,7 +60,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); } action_result create( account_name issuer, diff --git a/tests/main.cpp b/tests/main.cpp new file mode 100644 index 00000000..2c658f31 --- /dev/null +++ b/tests/main.cpp @@ -0,0 +1,42 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eosio.system_tester.hpp" + +using namespace eosio_system; +#define BOOST_TEST_STATIC_LINK + +void translate_fc_exception(const fc::exception &e) { + std::cerr << "\033[33m" << e.to_detail_string() << "\033[0m" << std::endl; + BOOST_TEST_FAIL("Caught Unexpected Exception"); +} + +boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { + // Turn off blockchain logging if no --verbose parameter is not added + // To have verbose enabled, call "tests/chain_test -- --verbose" + bool is_verbose = false; + std::string verbose_arg = "--verbose"; + for (int i = 0; i < argc; i++) { + if (verbose_arg == argv[i]) { + is_verbose = true; + break; + } + } + if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + + // Register fc::exception translator + boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); + + std::srand(time(NULL)); + std::cout << "Random number generator seeded to " << time(NULL) << std::endl; + return nullptr; +} From 16068f51fa32db9f074bc5540bb585e6886374fa Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 1 Aug 2018 14:34:56 -0400 Subject: [PATCH 0477/1048] Added back static, removed deprecated --- eosio.system/include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/eosio.system.cpp | 3 +-- eosio.system/src/producer_pay.cpp | 1 - 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 6564ec9b..659d8c81 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -69,7 +69,7 @@ namespace eosiosystem { uint16_t new_ram_per_block = 0; block_timestamp last_ram_increase; - block_timestamp last_block_num; /* unnecessary now; deprecated? */ + block_timestamp last_block_num; /* deprecated */ double reserved = 0; uint8_t revision = 0; ///< used to track version updates in the future. diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 7766ec8d..4d7c5f50 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -47,8 +47,7 @@ namespace eosiosystem { } block_timestamp system_contract::current_block_time() { - const /* static */ block_timestamp cbt{ time_point{ microseconds{ static_cast( current_time() ) } } }; - // static causes linking errors: undefined symbols __cxa_guard_acquire and __cxa_guard_release + const static block_timestamp cbt{ time_point{ microseconds{ static_cast( current_time() ) } } }; return cbt; } diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 2244f9d9..52270cb9 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -21,7 +21,6 @@ namespace eosiosystem { using namespace eosio; require_auth(N(eosio)); - _gstate2.last_block_num = timestamp; // QUESTION: Should this be removed now that last_block_num is not neeeded? /** until activated stake crosses this threshold no new rewards are paid */ if( _gstate.total_activated_stake < min_activated_stake ) From 7d4e5cb1d444dd616ff76187f6eaecad9f9d734f Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 1 Aug 2018 15:25:13 -0400 Subject: [PATCH 0478/1048] maintain the same behavior wrt to the last_block_num field even though it is no longer used --- .gitignore | 2 ++ eosio.system/src/producer_pay.cpp | 5 +++++ 2 files changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 259148fa..ce341760 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ *.exe *.out *.app + +build/* diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 52270cb9..e661be74 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -22,6 +22,11 @@ namespace eosiosystem { require_auth(N(eosio)); + // _gstate2.last_block_num is not used anywhere in the system contract code anymore. + // Although this field is deprecated, we will continue updating it for now until the last_block_num field + // is eventually completely removed, at which point this line can be removed. + _gstate2.last_block_num = timestamp; + /** until activated stake crosses this threshold no new rewards are paid */ if( _gstate.total_activated_stake < min_activated_stake ) return; From 44eb7904d48a9ea9a966e614b3327d2267380243 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 1 Aug 2018 17:19:44 -0400 Subject: [PATCH 0479/1048] update version number --- CMakeLists.txt | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8da6ec3f..3061de8f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.1.1) +project(eosio_contracts VERSION 1.2.0) set(EOSIO_DEPENDENCY "1.1") set(EOSIO_WASMSDK_DEPENDENCY "1.1") diff --git a/README.md b/README.md index 883c887f..b27fdc4b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.1.1 +## Version : 1.2.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.0.8](https://github.com/eosio/eos/tree/v1.0.8) -* [eosio.wasmsdk v1.0.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.0.0) +* [eosio v1.1.2](https://github.com/eosio/eos/tree/v1.1.2) +* [eosio.wasmsdk v1.1.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.1.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From b89ed8794858cf6149b721ae2401af8544e80148 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 1 Aug 2018 18:01:04 -0400 Subject: [PATCH 0480/1048] initial work on refactor/cleanup of new producer pay algorithm --- .../include/eosio.system/eosio.system.hpp | 11 +- eosio.system/src/producer_pay.cpp | 32 ++--- eosio.system/src/voting.cpp | 117 +++++++++++------- 3 files changed, 99 insertions(+), 61 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index d3c68aee..6b16a565 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -67,7 +67,7 @@ namespace eosiosystem { struct eosio_global_state2 { eosio_global_state2(){} - uint16_t new_ram_per_block = 0; + uint16_t new_ram_per_block = 0; block_timestamp last_ram_increase; block_timestamp last_block_num; double total_producer_votepay_share = 0; @@ -109,9 +109,9 @@ namespace eosiosystem { account_name owner; double votepay_share = 0; uint64_t last_votepay_share_update = 0; - + uint64_t primary_key()const { return owner; } - + // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) }; @@ -256,7 +256,7 @@ namespace eosiosystem { void setpriv( account_name account, uint8_t ispriv ); void rmvproducer( account_name producer ); - + void updtrevision( uint8_t revision ); void bidname( account_name bidder, account_name newname, asset bid ); @@ -277,6 +277,9 @@ namespace eosiosystem { // defined in voting.cpp void propagate_weight_change( const voter_info& voter ); + + double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, + /*time_point*/ uint64_t ct, double shares_rate, bool reset_to_zero = false ); }; } /// eosiosystem diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 3fc9a94b..f80bd996 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -127,18 +127,26 @@ namespace eosiosystem { double delta_total_votepay_share = 0; double votepay_share = 0; double total_votepay_share = 0; - - if( ct < last_claim_plus_3days || ( ct >= last_claim_plus_3days && last_claim_plus_3days > prod2->last_votepay_share_update ) ) { - delta_votepay_share = prod.total_votes * double( (ct - prod2->last_votepay_share_update) / 1E6 ); + + bool crossed_threshold = (last_claim_plus_3days <= ct); + bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); + // Note: update_after_threshold implies cross_threshold + + if( !updated_after_threshold ) { delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6) ; - votepay_share = prod2->votepay_share + delta_votepay_share; total_votepay_share = _gstate2.total_producer_votepay_share + delta_total_votepay_share; } + double new_votepay_share = update_producer_votepay_share( prod2, + ct, + updated_after_threshold ? 0.0 : prod.total_votes, + true // reset votepay_share to zero after updating + ); + int64_t producer_per_vote_pay = 0; if( _gstate2.revision > 0 ) { - if( total_votepay_share > 0 && ct < last_claim_plus_3days ) { - producer_per_vote_pay = int64_t((votepay_share * _gstate.pervote_bucket) / total_votepay_share); + if( total_votepay_share > 0 && !crossed_threshold ) { + producer_per_vote_pay = int64_t((new_votepay_share * _gstate.pervote_bucket) / total_votepay_share); if( producer_per_vote_pay > _gstate.pervote_bucket ) producer_per_vote_pay = _gstate.pervote_bucket; } @@ -151,12 +159,12 @@ namespace eosiosystem { if( producer_per_vote_pay < min_pervote_daily_pay ) { producer_per_vote_pay = 0; } - + _gstate.pervote_bucket -= producer_per_vote_pay; _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.unpaid_blocks; - if( ct >= last_claim_plus_3days && last_claim_plus_3days <= prod2->last_votepay_share_update ) { + if( updated_after_threshold ) { _gstate3.total_vpay_share_change_rate += prod.total_votes; } @@ -165,12 +173,8 @@ namespace eosiosystem { p.unpaid_blocks = 0; }); - _producers2.modify( prod2, 0, [&](auto& p) { - _gstate2.total_producer_votepay_share += ( delta_total_votepay_share - p.votepay_share - delta_votepay_share ); - _gstate3.last_vpay_state_update = ct; - p.votepay_share = 0; - p.last_votepay_share_update = ct; - }); + _gstate2.total_producer_votepay_share += ( delta_total_votepay_share - new_votepay_share ); + _gstate3.last_vpay_state_update = ct; if( producer_per_block_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.bpay),N(active)}, diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index afc91fcf..b9907d3a 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -123,6 +123,30 @@ namespace eosiosystem { double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } + + double system_contract::update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, + /*time_point*/ uint64_t ct, + double shares_rate, + bool reset_to_zero ) + { + double delta_votepay_share = 0.0; + if( shares_rate != 0.0 ) { + delta_votepay_share = shares_rate * double( (ct - prod_itr->last_votepay_share_update) / 1E6 ); + } + + double new_votepay_share = prod_itr->votepay_share + delta_votepay_share; + _producers2.modify( prod_itr, 0, [&](auto& p) { + if( reset_to_zero ) + p.votepay_share = 0.0; + else + p.votepay_share = new_votepay_share; + + p.last_votepay_share_update = ct; + } ); + + return new_votepay_share; + } + /** * @pre producers must be sorted from lowest to highest and must be registered and active * @pre if proxy is set then no producers can be voted for @@ -215,12 +239,12 @@ namespace eosiosystem { } } } - + const auto ct = current_time(); bool update_global_time = false; bool update_global_share = false; - double delta_change_rate = 0; - double total_inactive_vpay_share = 0; + double delta_change_rate = 0.0; + double total_inactive_vpay_share = 0.0; for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first ); if( pitr != _producers.end() ) { @@ -236,33 +260,37 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( pd.first ); if( prod2 != _producers2.end() ) { + const uint64_t last_claim_plus_3days = pitr->last_claim_time + 3 * useconds_per_day; + bool crossed_threshold = (last_claim_plus_3days <= ct); + bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); + // Note: update_after_threshold implies cross_threshold + update_global_time = true; - _producers2.modify( prod2, 0, [&]( auto& p ) { - const uint64_t last_claim_plus_3days = pitr->last_claim_time + 3 * useconds_per_day; - if ( ct < last_claim_plus_3days ) { - update_global_share = true; - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - delta_change_rate += pd.second.first; - } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { - total_inactive_vpay_share += p.votepay_share; - total_inactive_vpay_share += init_total_votes * double( (_gstate3.last_vpay_state_update - p.last_votepay_share_update) / 1E6 ); - p.votepay_share = 0; - delta_change_rate -= init_total_votes; - } - p.last_votepay_share_update = ct; - }); + update_global_share = true; //|= !updated_after_threshold; + + double new_votepay_share = update_producer_votepay_share( prod2, + ct, + updated_after_threshold ? 0.0 : init_total_votes, + crossed_threshold && !updated_after_threshold // only reset votepay_share once after threshold + ); + + if( !crossed_threshold ) { + delta_change_rate += pd.second.first; + } else if( !updated_after_threshold ) { + total_inactive_vpay_share += new_votepay_share; + delta_change_rate -= init_total_votes; + } } } else { eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } } - if ( update_global_share ) { - _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; - } - _gstate2.total_producer_votepay_share -= total_inactive_vpay_share; + //if ( update_global_share ) { + _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) - total_inactive_vpay_share; + //} + //_gstate2.total_producer_votepay_share -= total_inactive_vpay_share; _gstate3.total_vpay_share_change_rate += delta_change_rate; - if ( update_global_time ) + //if ( update_global_time ) _gstate3.last_vpay_state_update = ct; _voters.modify( voter, 0, [&]( auto& av ) { @@ -333,29 +361,32 @@ namespace eosiosystem { auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { update_global_time = true; - _producers2.modify( prod2, 0, [&]( auto& p ) { - const uint64_t last_claim_plus_3days = pitr.last_claim_time + 3 * useconds_per_day; - if ( ct < last_claim_plus_3days ) { - update_global_share = true; - double delta_votepay_share = init_total_votes * double( (ct - p.last_votepay_share_update) / 1E6 ); - p.votepay_share += delta_votepay_share; - delta_change_rate += delta; - } else if ( last_claim_plus_3days > p.last_votepay_share_update ) { - total_inactive_vpay_share += p.votepay_share; - total_inactive_vpay_share += init_total_votes * double( (_gstate3.last_vpay_state_update - p.last_votepay_share_update) / 1E6 ); - p.votepay_share = 0; - delta_change_rate -= init_total_votes; - } - p.last_votepay_share_update = ct; - }); + + const uint64_t last_claim_plus_3days = pitr.last_claim_time + 3 * useconds_per_day; + bool crossed_threshold = (last_claim_plus_3days <= ct); + bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); + // Note: update_after_threshold implies cross_threshold + + double new_votepay_share = update_producer_votepay_share( prod2, + ct, + updated_after_threshold ? 0.0 : init_total_votes, + crossed_threshold && !updated_after_threshold // only reset votepay_share once after threshold + ); + + if( !crossed_threshold ) { + delta_change_rate += delta; + } else if( !updated_after_threshold ) { + total_inactive_vpay_share += new_votepay_share; + delta_change_rate -= init_total_votes; + } } } - if ( update_global_share ) { - _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) ; - } - _gstate2.total_producer_votepay_share -= total_inactive_vpay_share; + //if ( update_global_share ) { + _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) - total_inactive_vpay_share; + //} + //_gstate2.total_producer_votepay_share -= total_inactive_vpay_share; _gstate3.total_vpay_share_change_rate += delta_change_rate; - if ( update_global_time ) + //if ( update_global_time ) _gstate3.last_vpay_state_update = ct; } } From a67280188f1c0fb51d6d9d7fe557bccb64c24f98 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Tue, 7 Aug 2018 18:23:08 -0400 Subject: [PATCH 0481/1048] Start implementation of REX --- .../include/eosio.system/eosio.system.hpp | 51 ++++++ eosio.system/src/eosio.system.cpp | 164 ++++++++++++++++++ 2 files changed, 215 insertions(+) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 659d8c81..f49ab45b 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -142,6 +142,39 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint64_t system_token_symbol = CORE_SYMBOL; + struct rex_pool { + asset total_lent; + asset total_lendable; + asset total_rent; + asset total_rex; + uint64_t loan_num = 0; /// increments with each new loan + auto primary_key()const { return 0; } + }; + + typedef eosio::multi_index< N(regpool), rex_pool > rex_pool_table; + + struct rex_balance { + account_name owner; + asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote + asset rex_balance; /// the amount of REX owned by owner + + auto primary_key()const { return owner; } + }; + typedef eosio::multi_index< N(rexbal), rex_balance > rex_balance_table; + + struct rex_loan { + account_name receiver; + asset total_staked; + uint64_t loan_num; + + eosio::time_point expiration; + + auto primary_key()const { return loan_num; } + }; + + typedef eosio::multi_index< N(cpuloan), rex_loan> rex_cpu_loan_table; + typedef eosio::multi_index< N(cpunet), rex_loan> rex_net_loan_table; + class system_contract : public native { private: voters_table _voters; @@ -172,6 +205,24 @@ namespace eosiosystem { asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + /** + * Transfers SYS tokens from user balance and credits converts them to REX stake. + */ + void lendrex( account_name from, asset amount ); + + /** + * Converts REX stake back into SYS tokens at current exchange rate + */ + void unlendrex( account_name from, asset rex ); + + /** + * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, + * after 30 days the rented SYS delegation of CPU or NET will expire. + */ + void rent( account_name from, account_name receiver, asset payment, bool cpu ); + void runrex( uint16_t max ); + + /** * Decreases the total tokens delegated by from to receiver and/or * frees the memory associated with the delegation if there is nothing diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 4d7c5f50..be2068ea 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -217,6 +217,169 @@ namespace eosiosystem { set_resource_limits( newact, 0, 0, 0 ); } + /** + * Transfers SYS tokens from user balance and credits converts them to REX stake. + */ + void system_contract::lendrex( account_name from, asset amount ) { + require_auth( from ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio.rex), amount, "buy REX" } ); + + rex_pool_table rextable(_self,_self); + + asset rex_received( 0, S(4,REX) ); + + auto itr = rextable.begin(); + if( itr == rextable.end() ) { + rextable.emplace( _self, [&]( auto& rp ){ + rex_received.amount = amount.amount * 10000; + + rp.total_lendable = amount; + rp.total_lent = asset( 0, CORE_SYMBOL ); + rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available + rp.total_rex = rex_received; + }); + } else { + const auto S0 = itr->total_lendable.amount; + const auto S1 = S0 + amount.amount; + const auto R0 = itr->total_rex.amount; + + const auto R1 = (uint128_t(S1) * R0) / S0; + + rex_received.amount = R1 - R0; + + rextable.modify( itr, 0, [&]( auto& rp ) { + rp.total_lendable.amount = S1; + rp.total_rex.amount = R1; + }); + } + + rex_balance_table rbalance(_self,_self); + auto bitr = rbalance.find( from ); + if( bitr == rbalance.end() ) { + rbalance.emplace( from, [&]( auto& rb ) { + rb.owner = from; + rb.rex_balance = rex_received; + }); + } + else { + rbalance.modify( bitr, 0, [&]( auto& rb ) { + rb.rex_balance.amount += rex_received.amount; + }); + } + } + + /** + * Converts REX stake back into SYS tokens at current exchange rate + */ + void system_contract::unlendrex( account_name from, asset rex ) { + require_auth( from ); + + rex_pool_table rextable(_self,_self); + auto itr = rextable.begin(); + eosio_assert( itr != rextable.end(), "rex system not initialized yet" ); + + rex_balance_table rbalance(_self,_self); + auto bitr = rbalance.find( from ); + eosio_assert( bitr != rbalance.end(), "user must first lendrex" ); + eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); + + const auto S0 = itr->total_lendable.amount; + const auto R0 = itr->total_rex.amount; + const auto R1 = R0 - rex.amount; + const auto S1 = (uint128_t(R1) * S0) / R0; + + asset proceeds(S0-S1, CORE_SYMBOL); + + rextable.modify( itr, 0, [&]( auto& rt ) { + rt.total_rex.amount = R1; + rt.total_lendable.amount = S1; + eosio_assert( rt.total_lendable.amount > rt.total_lent.amount, "unable to unlendrex until loans expire" ); + }); + + rbalance.modify( bitr, 0, [&]( auto& rb ) { + rb.rex_balance.amount -= rex.amount; + }); + + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, + { N(eosio.rex), from, proceeds, "sell REX" } ); + + } + + int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { + double T0 = double(conout); + double F0 = double(conin); + double I = double(in); + + auto out = int64_t((I*T0) / (I+F0)); + + if( out < 0 ) out = 0; + + conin += in; + conout -= out; + + return out; + } + + /** + * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, + * after 30 days the rented SYS delegation of CPU or NET will expire. + */ + void system_contract::rent( account_name from, account_name receiver, asset payment, bool cpu ) { + require_auth( from ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio.rex), payment, string("rent ") + (cpu ? "CPU" : "NET") } ); + + rex_pool_table rextable(_self,_self); + auto itr = rextable.begin(); + eosio_assert( itr != rextable.end(), "rex system not initialized yet" ); + + int64_t rented_tokens = 0; + rextable.modify( itr, 0, [&]( auto& rt ) { + rt.total_lendable.amount += payment.amount; + int64_t unlent = rt.total_lendable.amount - rt.total_lent.amount; + rented_tokens = bancor_convert( unlent, rt.total_rent.amount, payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.loan_num++; + }); + + if( cpu ) { + rex_cpu_loan_table cpu_loans(_self,_self); + auto citr = cpu_loans.find( receiver ); + if( citr == cpu_loans.end() ) { + cpu_loans.emplace( from, [&]( auto& c ) { + c.receiver = receiver; + c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; + }); + /// TODO: increase the total staked for CPU + } + } + else { + rex_cpu_loan_table net_loans(_self,_self); + } + } + + void system_contract::runrex( uint16_t max ) { + rex_cpu_loan_table cpu_loans(_self,_self); + for( uint32_t i = 0; i < max; ++i ) { + auto itr = cpu_loans.begin(); + if( itr == cpu_loans.end() ) break; + if( itr->expiration.elapsed.count() > current_time() ) break; + + /// TODO sell total_staked back via bancor and decrease total_lent by staked + /// proceeds from "sale" are burnt. + /// decrease receiver's CPU weight by itr->total_staked + /// remove itr + } + rex_cpu_loan_table net_loans(_self,_self); + /// copy pattern from loans... + } + } /// eosio.system @@ -225,6 +388,7 @@ EOSIO_ABI( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror) // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(bidname) + (lendrex)(unlendrex)(rent)(runrex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp From 5395578d481f4b1049c2421bd29f22d579fa4bf4 Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Wed, 8 Aug 2018 10:16:08 -0400 Subject: [PATCH 0482/1048] more progress implementing rex --- .../include/eosio.system/eosio.system.hpp | 10 +- eosio.system/src/eosio.system.cpp | 114 ++++++++++++++---- 2 files changed, 94 insertions(+), 30 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index f49ab45b..5541e244 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -143,10 +143,11 @@ namespace eosiosystem { static constexpr uint64_t system_token_symbol = CORE_SYMBOL; struct rex_pool { - asset total_lent; - asset total_lendable; - asset total_rent; - asset total_rex; + asset total_lent; /// total EOS in open rex_loans + asset total_unlent; /// total EOS available to be lent (connector) + asset total_rent; /// fees received in exchange for lent (connector) + asset total_lendable; /// total EOS that have been lent (total_unlent + total_lent) + asset total_rex; /// total number of REX shares allocated to contributors to total_lendable uint64_t loan_num = 0; /// increments with each new loan auto primary_key()const { return 0; } }; @@ -297,6 +298,7 @@ namespace eosiosystem { //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + void update_resource_limits( account_name receiver, int64_t delta_cpu, int64_t delta_net ); //defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index be2068ea..d129d421 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -235,10 +235,11 @@ namespace eosiosystem { rextable.emplace( _self, [&]( auto& rp ){ rex_received.amount = amount.amount * 10000; - rp.total_lendable = amount; - rp.total_lent = asset( 0, CORE_SYMBOL ); - rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available - rp.total_rex = rex_received; + rp.total_lendable = amount; + rp.total_lent = asset( 0, CORE_SYMBOL ); + rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available + rp.total_rex = rex_received; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; }); } else { const auto S0 = itr->total_lendable.amount; @@ -251,7 +252,9 @@ namespace eosiosystem { rextable.modify( itr, 0, [&]( auto& rp ) { rp.total_lendable.amount = S1; - rp.total_rex.amount = R1; + rp.total_rex.amount = R1; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); }); } @@ -268,12 +271,15 @@ namespace eosiosystem { rb.rex_balance.amount += rex_received.amount; }); } + runrex(2); } /** * Converts REX stake back into SYS tokens at current exchange rate */ void system_contract::unlendrex( account_name from, asset rex ) { + runrex(2); + require_auth( from ); rex_pool_table rextable(_self,_self); @@ -295,7 +301,9 @@ namespace eosiosystem { rextable.modify( itr, 0, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; + rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; eosio_assert( rt.total_lendable.amount > rt.total_lent.amount, "unable to unlendrex until loans expire" ); + eosio_assert( rt.total_unlent.amount >= 0, "programmer error, this should never go negative" ); }); rbalance.modify( bitr, 0, [&]( auto& rb ) { @@ -308,10 +316,18 @@ namespace eosiosystem { } + /** + * Given two connector balances (conin, and conout), and an incoming amount of + * in, this function will modify conin and conout and return the delta out. + * + * @param in - same units as conin + * @param conin - the input connector balance + * @param conout - the output connector balance + */ int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { - double T0 = double(conout); - double F0 = double(conin); - double I = double(in); + const double T0 = double(conout); + const double F0 = double(conin); + const double I = double(in); auto out = int64_t((I*T0) / (I+F0)); @@ -323,6 +339,22 @@ namespace eosiosystem { return out; } + void system_contract::update_resource_limits( account_name receiver, int64_t delta_cpu, int64_t delta_net ) { + user_resources_table totals_tbl( _self, receiver ); + auto tot_itr = totals_tbl.find( receiver ); + eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); + totals_tbl.modify( tot_itr, 0, [&]( auto& tot ) { + tot.cpu_weight.amount += delta_cpu; + tot.net_weight.amount += delta_net; + }); + eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); + eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); + + int64_t ram_bytes, net, cpu; + get_resource_limits( receiver, &ram_bytes, &net, &cpu ); + set_resource_limits( receiver, ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + } + /** * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. @@ -330,6 +362,8 @@ namespace eosiosystem { void system_contract::rent( account_name from, account_name receiver, asset payment, bool cpu ) { require_auth( from ); + runrex(2); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), payment, string("rent ") + (cpu ? "CPU" : "NET") } ); @@ -348,36 +382,64 @@ namespace eosiosystem { if( cpu ) { rex_cpu_loan_table cpu_loans(_self,_self); - auto citr = cpu_loans.find( receiver ); - if( citr == cpu_loans.end() ) { - cpu_loans.emplace( from, [&]( auto& c ) { - c.receiver = receiver; - c.total_staked = asset( rented_tokens, CORE_SYMBOL ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); - c.loan_num = itr->loan_num; - }); - /// TODO: increase the total staked for CPU - } - } - else { - rex_cpu_loan_table net_loans(_self,_self); + + cpu_loans.emplace( from, [&]( auto& c ) { + c.receiver = receiver; + c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; + }); + update_resource_limits( receiver, rented_tokens, 0 ); + } else { + rex_net_loan_table net_loans(_self,_self); + + net_loans.emplace( from, [&]( auto& c ) { + c.receiver = receiver; + c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; + }); + update_resource_limits( receiver, 0, rented_tokens ); } } + /** + * Perform maitenance operations on expired rex + */ void system_contract::runrex( uint16_t max ) { + rex_pool_table rextable(_self,_self); + auto rexi = rextable.begin(); + eosio_assert( rexi != rextable.end(), "rex system not initialized yet" ); + + auto unrent = [&]( int64_t rented_tokens ) { + rextable.modify( rexi, 0, [&]( auto& rt ) { + int64_t unlent = rt.total_lendable.amount - rt.total_lent.amount; + int64_t rent_earned = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); + rt.total_lent.amount = rt.total_lendable.amount - rt.total_unlent.amount; + }); + }; + rex_cpu_loan_table cpu_loans(_self,_self); for( uint32_t i = 0; i < max; ++i ) { auto itr = cpu_loans.begin(); if( itr == cpu_loans.end() ) break; if( itr->expiration.elapsed.count() > current_time() ) break; - /// TODO sell total_staked back via bancor and decrease total_lent by staked - /// proceeds from "sale" are burnt. - /// decrease receiver's CPU weight by itr->total_staked - /// remove itr + update_resource_limits( itr->receiver, -itr->total_staked.amount, 0 ); + unrent( itr->total_staked.amount ); + cpu_loans.erase( itr ); } + rex_cpu_loan_table net_loans(_self,_self); - /// copy pattern from loans... + for( uint32_t i = 0; i < max; ++i ) { + auto itr = net_loans.begin(); + if( itr == net_loans.end() ) break; + if( itr->expiration.elapsed.count() > current_time() ) break; + + update_resource_limits( itr->receiver, 0, -itr->total_staked.amount ); + unrent( itr->total_staked.amount ); + net_loans.erase( itr ); + } } } /// eosio.system From 01a36d303894e0970e60fc4240168b82334befaa Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 17 Aug 2018 11:33:03 -0400 Subject: [PATCH 0483/1048] ABI and first simple tests fro bandwidth rental market #46 --- eosio.system/abi/eosio.system.abi | 69 +++++++++++++++++++++++++++++++ eosio.system/src/eosio.system.cpp | 4 +- tests/eosio.system_tester.hpp | 61 ++++++++++++++++++++++++++- tests/eosio.system_tests.cpp | 38 +++++++++++++++++ 4 files changed, 169 insertions(+), 3 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 4e30369a..b6c9d999 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -191,6 +191,45 @@ {"name":"net_weight", "type":"asset"}, {"name":"cpu_weight", "type":"asset"} ] + },{ + "name": "lendrex", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"amount", "type":"asset"} + ] + },{ + "name": "unlendrex", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"rex", "type":"asset"} + ] + },{ + "name": "rex_balance", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"vote_stake", "type":"asset"}, + {"name":"rex_balance", "type":"asset"} + ] + },{ + "name": "rex_loan", + "base": "", + "fields": [ + {"name":"receiver", "type":"account_name"}, + {"name":"total_stake", "type":"asset"}, + {"name":"loan_num", "type":"uint64"} + ] + },{ + "name": "rent", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"payment", "type":"asset"}, + {"name":"cpu", "type":"bool"} + ] },{ "name": "user_resources", "base": "", @@ -480,6 +519,18 @@ "name": "refund", "type": "refund", "ricardian_contract": "" + },{ + "name": "lendrex", + "type": "lendrex", + "ricardian_contract": "" + },{ + "name": "unlendrex", + "type": "unlendrex", + "ricardian_contract": "" + },{ + "name": "rent", + "type": "rent", + "ricardian_contract": "" },{ "name": "regproducer", "type": "regproducer", @@ -577,6 +628,24 @@ "index_type": "i64", "key_names" : ["to"], "key_types" : ["uint64"] + },{ + "name": "rexbal", + "type": "rex_balance", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "cpuloan", + "type": "rex_loan", + "index_type": "i64", + "key_names" : ["loan_num"], + "key_types" : ["uint64"] + },{ + "name": "netloan", + "type": "rex_loan", + "index_type": "i64", + "key_names" : ["loan_num"], + "key_types" : ["uint64"] },{ "name": "rammarket", "type": "exchange_state", diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index d129d421..a7640eaa 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -302,7 +302,7 @@ namespace eosiosystem { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; - eosio_assert( rt.total_lendable.amount > rt.total_lent.amount, "unable to unlendrex until loans expire" ); + eosio_assert( rt.total_lendable.amount >= rt.total_lent.amount, "unable to unlendrex until loans expire" );// XXX > or >= eosio_assert( rt.total_unlent.amount >= 0, "programmer error, this should never go negative" ); }); @@ -430,7 +430,7 @@ namespace eosiosystem { cpu_loans.erase( itr ); } - rex_cpu_loan_table net_loans(_self,_self); + rex_net_loan_table net_loans(_self,_self); for( uint32_t i = 0; i < max; ++i ) { auto itr = net_loans.begin(); if( itr == net_loans.end() ) break; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 32bbed03..66147111 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -40,7 +40,7 @@ class eosio_system_tester : public TESTER { 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) }); + N(eosio.bpay), N(eosio.vpay), N(eosio.saving), N(eosio.names), N(eosio.rex) }); produce_blocks( 100 ); @@ -265,6 +265,65 @@ class eosio_system_tester : public TESTER { return unstake( acnt, acnt, net, cpu ); } + action_result lendrex( const account_name& from, const asset& amount ) { + return push_action( name(from), N(lendrex), mvo() + ("from", from) + ("amount", amount) + ); + } + + action_result unlendrex( const account_name& from, const asset& rex ) { + return push_action( name(from), N(unlendrex), mvo() + ("from", from) + ("rex", rex) + ); + } + + action_result rent( const account_name& from, const account_name& receiver, const asset& payment, bool cpu ) { + return push_action( name(from), N(rent), mvo() + ("from", from) + ("receiver", receiver) + ("payment", payment) + ("cpu", cpu) + ); + } + + fc::variant get_last_loan(bool cpu) { + vector data; + const auto& db = control->db(); + namespace chain = eosio::chain; + auto table = cpu ? N(cpuloan) : N(netloan); + const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, table ) ); + if ( !t_id ) { + return fc::variant(); + } + + const auto& idx = db.get_index(); + + auto itr = idx.end(); + if (itr == idx.begin()) { + return fc::variant(); + } + --itr; + + data.resize( itr->value.size() ); + memcpy( data.data(), itr->value.data(), data.size() ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer_max_time ); + } + + fc::variant get_last_cpu_loan() { + return get_last_loan( true ); + } + + fc::variant get_last_net_loan() { + return get_last_loan( false ); + } + + asset get_rex_balance( const account_name& act ) const { + vector data = get_row_by_account( N(eosio), N(eosio), N(rexbal), act ); + return data.empty() ? asset(0, symbol(N(REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); + } + action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { return push_action( name(bidder), N(bidname), mvo() ("bidder", bidder) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 06bae27d..2578f1ff 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2720,4 +2720,42 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( lend_unlendrex, eosio_system_tester ) try { + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + + BOOST_REQUIRE_EQUAL( success(), lendrex( N(alice1111111), core_from_string("300.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + + //BOOST_REQUIRE_EQUAL( eosio::chain::asset::from_string("900.0000 REX"), get_rex_balance( "alice1111111" ) ); + asset init_rex_balance = get_rex_balance( "alice1111111" ); + + BOOST_REQUIRE_EQUAL( success(), lendrex( N(alice1111111), core_from_string("300.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("400.0000"), get_balance( "alice1111111" ) ); + asset rex_balance = get_rex_balance( "alice1111111" ); + + BOOST_REQUIRE_EQUAL( init_rex_balance * 2, rex_balance ); + + BOOST_REQUIRE_EQUAL( success(), unlendrex( N(alice1111111), rex_balance/2 ) ); + BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( rent_bandwidth, eosio_system_tester ) try { + transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + + BOOST_REQUIRE_EQUAL( success(), lendrex( N(alice1111111), core_from_string("1000.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + + asset init_rex_balance = get_rex_balance( "alice1111111" ); + + transfer( "eosio", "bob111111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), rent( N(bob111111111), N(bob111111111), core_from_string("10.0000"), true ) ); + + auto loan = get_last_cpu_loan(); + //std::cout << loan << std::endl; + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() From 5ef0af39f9ff6cf54d2ac376284f6ab58f8fbc6a Mon Sep 17 00:00:00 2001 From: Daniel Larimer Date: Mon, 6 Aug 2018 18:18:02 -0400 Subject: [PATCH 0484/1048] adding setabi handler to store abi hash --- .../include/eosio.system/eosio.system.hpp | 1 + eosio.system/include/eosio.system/native.hpp | 9 +++++++++ eosio.system/src/eosio.system.cpp | 19 ++++++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 659d8c81..49326127 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -161,6 +161,7 @@ namespace eosiosystem { void onblock( block_timestamp timestamp, account_name producer ); // const block_header& header ); /// only parse first 3 fields of block header + // functions defined in delegate_bandwidth.cpp /** diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index e6395807..476da787 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -61,6 +61,14 @@ namespace eosiosystem { }; + struct abi_hash { + account_name owner; + checksum256 hash; + auto primary_key()const { return owner; } + + EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) + }; + /* * Method parameters commented out to prevent generation of code that parses input data. */ @@ -108,5 +116,6 @@ namespace eosiosystem { void onerror( /*const bytes&*/ ) {} + void setabi( account_name acnt, const bytes& abi ); }; } diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 4d7c5f50..1e9f452d 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "producer_pay.cpp" #include "delegate_bandwidth.cpp" @@ -217,12 +218,28 @@ namespace eosiosystem { set_resource_limits( newact, 0, 0, 0 ); } + void native::setabi( account_name acnt, const bytes& abi ) { + eosio::multi_index< N(abihash), abi_hash> table(_self,_self); + + auto itr = table.find( acnt ); + if( itr == table.end() ) { + table.emplace( acnt, [&]( auto& row ) { + row.owner= acnt; + sha256( const_cast(abi.data()), abi.size(), &row.hash ); + }); + } else { + table.modify( itr, 0, [&]( auto& row ) { + sha256( const_cast(abi.data()), abi.size(), &row.hash ); + }); + } + } + } /// eosio.system EOSIO_ABI( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) - (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror) + (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(bidname) // delegate_bandwidth.cpp From d2edef57df59c8e563bf63c255ce96d73e2d8ae8 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 20 Aug 2018 11:10:55 -0400 Subject: [PATCH 0485/1048] Copy eosio.bios from eos repo --- .gitignore | 1 + CMakeLists.txt | 3 +- eosio.bios/CMakeLists.txt | 10 + eosio.bios/abi/eosio.bios.abi | 231 +++++++++++++++++++ eosio.bios/include/eosio.bios/eosio.bios.hpp | 44 ++++ eosio.bios/src/eosio.bios.cpp | 3 + 6 files changed, 291 insertions(+), 1 deletion(-) create mode 100644 eosio.bios/CMakeLists.txt create mode 100644 eosio.bios/abi/eosio.bios.abi create mode 100644 eosio.bios/include/eosio.bios/eosio.bios.hpp create mode 100644 eosio.bios/src/eosio.bios.cpp diff --git a/.gitignore b/.gitignore index ce341760..1f63cf48 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,4 @@ *.app build/* +.DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index 3061de8f..6a14bb21 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts VERSION 1.2.0) -set(EOSIO_DEPENDENCY "1.1") +set(EOSIO_DEPENDENCY "1.2") set(EOSIO_WASMSDK_DEPENDENCY "1.1") if(CMAKE_BUILD_TYPE STREQUAL "Debug") @@ -30,6 +30,7 @@ if (NOT "${output}" EQUAL 0) endif() include_directories(AFTER ${BOOST_ROOT}/include) +add_subdirectory(eosio.bios) add_subdirectory(eosio.msig) add_subdirectory(eosio.sudo) add_subdirectory(eosio.system) diff --git a/eosio.bios/CMakeLists.txt b/eosio.bios/CMakeLists.txt new file mode 100644 index 00000000..9f8841b0 --- /dev/null +++ b/eosio.bios/CMakeLists.txt @@ -0,0 +1,10 @@ +add_executable(eosio.bios.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) +target_include_directories(eosio.bios.wasm + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set_target_properties(eosio.bios.wasm + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.bios.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) diff --git a/eosio.bios/abi/eosio.bios.abi b/eosio.bios/abi/eosio.bios.abi new file mode 100644 index 00000000..c81d774c --- /dev/null +++ b/eosio.bios/abi/eosio.bios.abi @@ -0,0 +1,231 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + },{ + "new_type_name": "transaction_id_type", + "type": "checksum256" + },{ + "new_type_name": "weight_type", + "type": "uint16" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name":"actor", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "key_weight", + "base": "", + "fields": [ + {"name":"key", "type":"public_key"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "permission_level_weight", + "base": "", + "fields": [ + {"name":"permission", "type":"permission_level"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "wait_weight", + "base": "", + "fields": [ + {"name":"wait_sec", "type":"uint32"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "authority", + "base": "", + "fields": [ + {"name":"threshold", "type":"uint32"}, + {"name":"keys", "type":"key_weight[]"}, + {"name":"accounts", "type":"permission_level_weight[]"}, + {"name":"waits", "type":"wait_weight[]"} + ] + },{ + "name": "newaccount", + "base": "", + "fields": [ + {"name":"creator", "type":"account_name"}, + {"name":"name", "type":"account_name"}, + {"name":"owner", "type":"authority"}, + {"name":"active", "type":"authority"} + ] + },{ + "name": "setcode", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"vmtype", "type":"uint8"}, + {"name":"vmversion", "type":"uint8"}, + {"name":"code", "type":"bytes"} + ] + },{ + "name": "setabi", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"abi", "type":"bytes"} + ] + },{ + "name": "updateauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"}, + {"name":"parent", "type":"permission_name"}, + {"name":"auth", "type":"authority"} + ] + },{ + "name": "deleteauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "linkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"}, + {"name":"requirement", "type":"permission_name"} + ] + },{ + "name": "unlinkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"} + ] + },{ + "name": "canceldelay", + "base": "", + "fields": [ + {"name":"canceling_auth", "type":"permission_level"}, + {"name":"trx_id", "type":"transaction_id_type"} + ] + },{ + "name": "onerror", + "base": "", + "fields": [ + {"name":"sender_id", "type":"uint128"}, + {"name":"sent_trx", "type":"bytes"} + ] + },{ + "name": "set_account_limits", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"ram_bytes", "type":"int64"}, + {"name":"net_weight", "type":"int64"}, + {"name":"cpu_weight", "type":"int64"} + ] + },{ + "name": "setpriv", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"is_priv", "type":"int8"} + ] + },{ + "name": "set_global_limits", + "base": "", + "fields": [ + {"name":"cpu_usec_per_period", "type":"int64"} + ] + },{ + "name": "producer_key", + "base": "", + "fields": [ + {"name":"producer_name", "type":"account_name"}, + {"name":"block_signing_key", "type":"public_key"} + ] + },{ + "name": "set_producers", + "base": "", + "fields": [ + {"name":"schedule", "type":"producer_key[]"} + ] + },{ + "name": "require_auth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"} + ] + }], + "actions": [{ + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + },{ + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + },{ + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + },{ + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + },{ + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + },{ + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + },{ + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + },{ + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + },{ + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + },{ + "name": "setalimits", + "type": "set_account_limits", + "ricardian_contract": "" + },{ + "name": "setglimits", + "type": "set_global_limits", + "ricardian_contract": "" + },{ + "name": "setpriv", + "type": "setpriv", + "ricardian_contract": "" + },{ + "name": "setprods", + "type": "set_producers", + "ricardian_contract": "" + },{ + "name": "reqauth", + "type": "require_auth", + "ricardian_contract": "" + } + ], + "tables": [], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp new file mode 100644 index 00000000..99807d81 --- /dev/null +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -0,0 +1,44 @@ +#pragma once +#include +#include + +namespace eosio { + + class bios : public contract { + public: + bios( action_name self ):contract(self){} + + void setpriv( account_name account, uint8_t ispriv ) { + require_auth( _self ); + set_privileged( account, ispriv ); + } + + void setalimits( account_name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { + require_auth( _self ); + set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); + } + + void setglimits( uint64_t ram, uint64_t net, uint64_t cpu ) { + (void)ram; (void)net; (void)cpu; + require_auth( _self ); + } + + void setprods( std::vector schedule ) { + (void)schedule; // schedule argument just forces the deserialization of the action data into vector (necessary check) + require_auth( _self ); + + constexpr size_t max_stack_buffer_size = 512; + size_t size = action_data_size(); + char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); + read_action_data( buffer, size ); + set_proposed_producers(buffer, size); + } + + void reqauth( action_name from ) { + require_auth( from ); + } + + private: + }; + +} /// namespace eosio diff --git a/eosio.bios/src/eosio.bios.cpp b/eosio.bios/src/eosio.bios.cpp new file mode 100644 index 00000000..70279d6e --- /dev/null +++ b/eosio.bios/src/eosio.bios.cpp @@ -0,0 +1,3 @@ +#include + +EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(reqauth) ) From bcc53650adafa1f9028c9a3a001ed2d01b05964f Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 20 Aug 2018 17:10:00 -0400 Subject: [PATCH 0486/1048] fixing tests for setabi --- eosio.system/abi/eosio.system.abi | 7 ++++ eosio.system/src/eosio.system.cpp | 1 - tests/contracts.hpp.in | 3 ++ tests/eosio.system_tests.cpp | 59 +++++++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 1 deletion(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 4e30369a..6f6c7775 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -24,6 +24,13 @@ {"name":"actor", "type":"account_name"}, {"name":"permission", "type":"permission_name"} ] + },{ + "name": "abi_hash", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"hash", "type":"checksum256"} + ] },{ "name": "key_weight", "base": "", diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 1e9f452d..d9f5b71b 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -220,7 +220,6 @@ namespace eosiosystem { void native::setabi( account_name acnt, const bytes& abi ) { eosio::multi_index< N(abihash), abi_hash> table(_self,_self); - auto itr = table.find( acnt ); if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 2db2153f..7cb86179 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -16,6 +16,9 @@ struct contracts { static std::vector sudo_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wasm"); } static std::string sudo_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wast"); } static std::vector sudo_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.abi"); } + static std::vector bios_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.wasm"); } + static std::string bios_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.wast"); } + static std::vector bios_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.abi"); } struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 06bae27d..84999d5f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -10,6 +10,11 @@ #include #include "eosio.system_tester.hpp" +struct _abi_hash { + name owner; + fc::sha256 hash; +}; +FC_REFLECT( _abi_hash, (owner)(hash) ); using namespace eosio_system; @@ -2720,4 +2725,58 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { + abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); + set_code( config::system_account_name, contracts::bios_wasm() ); + set_abi( config::system_account_name, contracts::bios_abi().data() ); + set_abi( N(eosio.token), contracts::token_abi().data() ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + _abi_hash abi_hash; + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); + abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); + auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); + + BOOST_REQUIRE( abi_hash.hash == result ); + } + + set_abi( N(eosio.token), contracts::system_abi().data() ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + _abi_hash abi_hash; + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); + abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); + auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); + + BOOST_REQUIRE( abi_hash.hash == result ); + } +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { + set_abi( N(eosio.token), contracts::token_abi().data() ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + _abi_hash abi_hash; + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); + abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); + auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); + + BOOST_REQUIRE( abi_hash.hash == result ); + } + + set_abi( N(eosio.token), contracts::system_abi().data() ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + _abi_hash abi_hash; + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); + abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); + auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); + + BOOST_REQUIRE( abi_hash.hash == result ); + } +} FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_SUITE_END() From bfd127e2e625ec1a362dd5c9bd459cebb7fa6198 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 20 Aug 2018 14:35:24 -0400 Subject: [PATCH 0487/1048] bios: hash abi (untested) --- eosio.bios/abi/eosio.bios.abi | 15 ++++++++++- eosio.bios/include/eosio.bios/eosio.bios.hpp | 26 ++++++++++++++++++++ eosio.bios/src/eosio.bios.cpp | 2 +- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/eosio.bios/abi/eosio.bios.abi b/eosio.bios/abi/eosio.bios.abi index c81d774c..26aabc01 100644 --- a/eosio.bios/abi/eosio.bios.abi +++ b/eosio.bios/abi/eosio.bios.abi @@ -78,6 +78,13 @@ {"name":"account", "type":"account_name"}, {"name":"abi", "type":"bytes"} ] + },{ + "name": "abi_hash", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"hash", "type":"checksum256"} + ] },{ "name": "updateauth", "base": "", @@ -225,7 +232,13 @@ "ricardian_contract": "" } ], - "tables": [], + "tables": [{ + "name": "abihash", + "type": "abi_hash", + "index_type": "i64", + "key_names": ["owner"], + "key_types": ["account_name"] + }], "ricardian_clauses": [], "abi_extensions": [] } diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 99807d81..391d8ea1 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -1,9 +1,20 @@ #pragma once +#include #include #include namespace eosio { + struct abi_hash { + account_name owner; + checksum256 hash; + auto primary_key()const { return owner; } + + EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) + }; + + typedef eosio::multi_index< N(abihash), abi_hash> abi_hash_table; + class bios : public contract { public: bios( action_name self ):contract(self){} @@ -38,6 +49,21 @@ namespace eosio { require_auth( from ); } + void setabi( account_name acnt, const bytes& abi ) { + abi_hash_table table(_self, _self); + auto itr = table.find( acnt ); + if( itr == table.end() ) { + table.emplace( acnt, [&]( auto& row ) { + row.owner = acnt; + sha256( const_cast(abi.data()), abi.size(), &row.hash ); + }); + } else { + table.modify( itr, 0, [&]( auto& row ) { + sha256( const_cast(abi.data()), abi.size(), &row.hash ); + }); + } + } + private: }; diff --git a/eosio.bios/src/eosio.bios.cpp b/eosio.bios/src/eosio.bios.cpp index 70279d6e..8d7b4732 100644 --- a/eosio.bios/src/eosio.bios.cpp +++ b/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,3 @@ #include -EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(reqauth) ) +EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(reqauth)(setabi) ) From 840170ee6a6928c6c726cfd734181325829360c7 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 20 Aug 2018 17:18:58 -0400 Subject: [PATCH 0488/1048] fixed bios test --- tests/eosio.system_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 84999d5f..45c93c34 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2729,6 +2729,7 @@ BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); set_code( config::system_account_name, contracts::bios_wasm() ); set_abi( config::system_account_name, contracts::bios_abi().data() ); + create_account(N(eosio.token)); set_abi( N(eosio.token), contracts::token_abi().data() ); { auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); From 4e4a3ca86d5d3482dfac85182e69f33c49e62fa9 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Wed, 22 Aug 2018 18:00:27 -0400 Subject: [PATCH 0489/1048] Consolidated Security Fixes for 1.2.1 - add setalimits to eosio.system to allow management of resource limits for accounts that were instantiated prior to the resource markets - migrate inline transfer of bidname refunds to a deferred transaction with a manual failsafe action Co-authored-by: Bucky Kittinger Co-authored-by: Anton Perkov --- eosio.system/abi/eosio.system.abi | 32 ++++++++++++-- .../include/eosio.system/eosio.system.hpp | 12 +++++ eosio.system/src/delegate_bandwidth.cpp | 3 +- eosio.system/src/eosio.system.cpp | 44 +++++++++++++++++-- eosio.system/src/producer_pay.cpp | 4 +- 5 files changed, 83 insertions(+), 12 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 4e30369a..5445473a 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -39,6 +39,13 @@ {"name":"newname", "type":"account_name"}, {"name":"bid", "type":"asset"} ] + },{ + "name": "bidrefund", + "base": "", + "fields": [ + {"name":"bidder", "type":"account_name"}, + {"name":"newname", "type":"account_name"} + ] },{ "name": "permission_level_weight", "base": "", @@ -410,7 +417,7 @@ {"name":"quote", "type":"connector"} ] }, { - "name": "namebid_info", + "name": "name_bid", "base": "", "fields": [ {"name":"newname", "type":"account_name"}, @@ -418,7 +425,14 @@ {"name":"high_bid", "type":"int64"}, {"name":"last_bid_time", "type":"uint64"} ] - } + }, { + "name": "bid_refund", + "base": "", + "fields": [ + {"name":"bidder", "type":"account_name"}, + {"name":"amount", "type":"asset"} + ] + } ], "actions": [{ "name": "newaccount", @@ -496,6 +510,10 @@ "name": "bidname", "type": "bidname", "ricardian_contract": "" + },{ + "name": "bidrefund", + "type": "bidrefund", + "ricardian_contract": "" },{ "name": "unregprod", "type": "unregprod", @@ -591,11 +609,17 @@ "key_types" : ["uint64"] },{ "name": "namebids", - "type": "namebid_info", + "type": "name_bid", "index_type": "i64", "key_names" : ["newname"], "key_types" : ["account_name"] - } + },{ + "name": "bidrefunds", + "type": "bid_refund", + "index_type": "i64", + "key_names" : ["bidder"], + "key_types" : ["account_name"] + } ], "ricardian_clauses": [], "abi_extensions": [] diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 659d8c81..57d771b2 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -30,10 +30,18 @@ namespace eosiosystem { uint64_t by_high_bid()const { return static_cast(-high_bid); } }; + struct bid_refund { + account_name bidder; + asset amount; + + auto primary_key() const { return bidder; } + }; + typedef eosio::multi_index< N(namebids), name_bid, indexed_by > > name_bid_table; + typedef eosio::multi_index< N(bidrefunds), bid_refund> bid_refund_table; struct eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } @@ -161,6 +169,7 @@ namespace eosiosystem { void onblock( block_timestamp timestamp, account_name producer ); // const block_header& header ); /// only parse first 3 fields of block header + void setalimits( account_name act, int64_t ram, int64_t net, int64_t cpu ); // functions defined in delegate_bandwidth.cpp /** @@ -235,6 +244,9 @@ namespace eosiosystem { void rmvproducer( account_name producer ); void bidname( account_name bidder, account_name newname, asset bid ); + + void bidrefund( account_name bidder, account_name newname ); + private: // Implementation details: diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 667a2c12..edede0e5 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -156,7 +156,6 @@ namespace eosiosystem { set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } - /** * The system contract now buys and sells RAM allocations at prevailing market prices. * This may result in traders buying RAM today in anticipation of potential shortages @@ -422,7 +421,7 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.stake),N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.stake),N(active)},{req->owner,N(active)}}, { N(eosio.stake), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); refunds_tbl.erase( req ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 4d7c5f50..59a27abd 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -119,6 +119,14 @@ namespace eosiosystem { require_auth( _self ); set_privileged( account, ispriv ); } + + void system_contract::setalimits( account_name account, int64_t ram, int64_t net, int64_t cpu ) { + require_auth( N(eosio) ); + user_resources_table userres( _self, account ); + auto ritr = userres.find( account ); + eosio_assert( ritr == userres.end(), "only supports unlimited accounts" ); + set_resource_limits(account, ram, net, cpu); + } void system_contract::rmvproducer( account_name producer ) { require_auth( _self ); @@ -158,9 +166,27 @@ namespace eosiosystem { eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); eosio_assert( current->high_bidder != bidder, "account is already highest bidder" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.names),N(active)}, - { N(eosio.names), current->high_bidder, asset(current->high_bid), - std::string("refund bid on name ")+(name{newname}).to_string() } ); + bid_refund_table refunds_table(_self, newname); + + auto it = refunds_table.find( current->high_bidder ); + if ( it != refunds_table.end() ) { + refunds_table.modify( it, 0, [&](auto& r) { + r.amount += asset( current->high_bid, system_token_symbol ); + }); + } else { + refunds_table.emplace( bidder, [&](auto& r) { + r.bidder = current->high_bidder; + r.amount = asset( current->high_bid, system_token_symbol ); + }); + } + + action a( {N(eosio),N(active)}, N(eosio), N(bidrefund), std::make_tuple( current->high_bidder, newname ) ); + transaction t; + t.actions.push_back( std::move(a) ); + t.delay_sec = 0; + uint128_t deferred_id = (uint128_t(newname) << 64) | current->high_bidder; + cancel_deferred( deferred_id ); + t.send( deferred_id, bidder ); bids.modify( current, bidder, [&]( auto& b ) { b.high_bidder = bidder; @@ -170,6 +196,16 @@ namespace eosiosystem { } } + void system_contract::bidrefund( account_name bidder, account_name newname ) { + bid_refund_table refunds_table(_self, newname); + auto it = refunds_table.find( bidder ); + eosio_assert( it != refunds_table.end(), "refund not found" ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.names),N(active)},{bidder,N(active)}}, + { N(eosio.names), bidder, asset(it->amount), + std::string("refund bid on name ")+(name{newname}).to_string() } ); + refunds_table.erase( it ); + } + /** * Called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. @@ -224,7 +260,7 @@ EOSIO_ABI( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror) // eosio.system.cpp - (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(bidname) + (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(bidname)(bidrefund) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index e661be74..37706027 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -133,11 +133,11 @@ namespace eosiosystem { }); if( producer_per_block_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.bpay),N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.bpay),N(active)},{owner,N(active)}}, { N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } ); } if( producer_per_vote_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.vpay),N(active)}, + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.vpay),N(active)},{owner,N(active)}}, { N(eosio.vpay), owner, asset(producer_per_vote_pay), std::string("producer vote pay") } ); } } From 55f8062fd03491527260ada1e838adcc1de27741 Mon Sep 17 00:00:00 2001 From: Bart Wyatt Date: Fri, 24 Aug 2018 11:59:33 -0400 Subject: [PATCH 0490/1048] bump version to 1.2.1 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3061de8f..20f90a6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.2.0) +project(eosio_contracts VERSION 1.2.1) set(EOSIO_DEPENDENCY "1.1") set(EOSIO_WASMSDK_DEPENDENCY "1.1") diff --git a/README.md b/README.md index b27fdc4b..1c8da8a0 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.2.0 +## Version : 1.2.1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. From 99bd71ae6d885d96159b581f0d4d987f5b3d59d8 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 27 Aug 2018 14:14:34 -0400 Subject: [PATCH 0491/1048] more ABI, test helper functions fixed, table name fixed #6 --- eosio.system/abi/eosio.system.abi | 17 +++++++++++ .../include/eosio.system/eosio.system.hpp | 2 +- tests/eosio.system_tester.hpp | 28 +++++++++++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index b6c9d999..7ca74410 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -213,6 +213,17 @@ {"name":"vote_stake", "type":"asset"}, {"name":"rex_balance", "type":"asset"} ] + },{ + "name": "rex_pool", + "base": "", + "fields": [ + {"name":"total_lent", "type":"asset"}, + {"name":"total_unlent", "type":"asset"}, + {"name":"total_rent", "type":"asset"}, + {"name":"total_lendable", "type":"asset"}, + {"name":"total_rex", "type":"asset"}, + {"name":"loan_num", "type":"uint64"} + ] },{ "name": "rex_loan", "base": "", @@ -628,6 +639,12 @@ "index_type": "i64", "key_names" : ["to"], "key_types" : ["uint64"] + },{ + "name": "rexpool", + "type": "rex_pool", + "index_type": "i64", + "key_names" : ["zero"], + "key_types" : ["uint64"] },{ "name": "rexbal", "type": "rex_balance", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 5541e244..22bcf441 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -152,7 +152,7 @@ namespace eosiosystem { auto primary_key()const { return 0; } }; - typedef eosio::multi_index< N(regpool), rex_pool > rex_pool_table; + typedef eosio::multi_index< N(rexpool), rex_pool > rex_pool_table; struct rex_balance { account_name owner; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 66147111..dc1391e3 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -300,11 +300,14 @@ class eosio_system_tester : public TESTER { const auto& idx = db.get_index(); - auto itr = idx.end(); - if (itr == idx.begin()) { + auto itr = idx.upper_bound( boost::make_tuple( t_id->id, std::numeric_limits::max() )); + if ( itr == idx.begin() ) { return fc::variant(); } --itr; + if ( itr->t_id != t_id->id ) { + return fc::variant(); + } data.resize( itr->value.size() ); memcpy( data.data(), itr->value.data(), data.size() ); @@ -324,6 +327,27 @@ class eosio_system_tester : public TESTER { return data.empty() ? asset(0, symbol(N(REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); } + fc::variant get_rex_pool() const { + vector data; + const auto& db = control->db(); + namespace chain = eosio::chain; + const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(rexpool) ) ); + if ( !t_id ) { + return fc::variant(); + } + + const auto& idx = db.get_index(); + + auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); + if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { + return fc::variant(); + } + + data.resize( itr->value.size() ); + memcpy( data.data(), itr->value.data(), data.size() ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer_max_time ); + } + action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { return push_action( name(bidder), N(bidname), mvo() ("bidder", bidder) From 17240f45fabaa958c75dec9b4cd91e52802654f4 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Mon, 27 Aug 2018 14:22:40 -0400 Subject: [PATCH 0492/1048] formula changed #6 --- eosio.system/src/eosio.system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index a7640eaa..41fc4934 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -329,7 +329,7 @@ namespace eosiosystem { const double F0 = double(conin); const double I = double(in); - auto out = int64_t((I*T0) / (I+F0)); + auto out = int64_t((I*F0) / (T0+I)); if( out < 0 ) out = 0; From 4845726dd866bad6be0dadc73a7bd0c848c5670c Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 29 Aug 2018 18:00:37 -0400 Subject: [PATCH 0493/1048] refactor out global state updates in new producer pay algorithm --- .../include/eosio.system/eosio.system.hpp | 5 +- eosio.system/src/producer_pay.cpp | 19 +--- eosio.system/src/voting.cpp | 44 ++++----- tests/eosio.system_tests.cpp | 97 ++++++++++--------- 4 files changed, 78 insertions(+), 87 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 20f11bc5..49f89ae9 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -281,7 +281,10 @@ namespace eosiosystem { void propagate_weight_change( const voter_info& voter ); double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, - /*time_point*/ uint64_t ct, double shares_rate, bool reset_to_zero = false ); + /*time_point*/ uint64_t ct, + double shares_rate, bool reset_to_zero = false ); + double update_total_votepay_share( /*time_point*/ uint64_t ct, + double additional_shares_delta = 0.0, double shares_rate_delta = 0.0 ); }; } /// eosiosystem diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 641bcded..11e8a86e 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -127,28 +127,20 @@ namespace eosiosystem { /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and /// time duration the vote weight has been held into one metric. const uint64_t last_claim_plus_3days = prod.last_claim_time + 3 * useconds_per_day; - double delta_votepay_share = 0; - double delta_total_votepay_share = 0; - double votepay_share = 0; - double total_votepay_share = 0; bool crossed_threshold = (last_claim_plus_3days <= ct); bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); // Note: update_after_threshold implies cross_threshold - if( !updated_after_threshold ) { - delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6) ; - total_votepay_share = _gstate2.total_producer_votepay_share + delta_total_votepay_share; - } - double new_votepay_share = update_producer_votepay_share( prod2, ct, updated_after_threshold ? 0.0 : prod.total_votes, true // reset votepay_share to zero after updating - ); + ); int64_t producer_per_vote_pay = 0; if( _gstate2.revision > 0 ) { + double total_votepay_share = update_total_votepay_share( ct ); if( total_votepay_share > 0 && !crossed_threshold ) { producer_per_vote_pay = int64_t((new_votepay_share * _gstate.pervote_bucket) / total_votepay_share); if( producer_per_vote_pay > _gstate.pervote_bucket ) @@ -168,18 +160,13 @@ namespace eosiosystem { _gstate.perblock_bucket -= producer_per_block_pay; _gstate.total_unpaid_blocks -= prod.unpaid_blocks; - if( updated_after_threshold ) { - _gstate3.total_vpay_share_change_rate += prod.total_votes; - } + update_total_votepay_share( ct, -new_votepay_share, (updated_after_threshold ? prod.total_votes : 0.0) ); _producers.modify( prod, 0, [&](auto& p) { p.last_claim_time = ct; p.unpaid_blocks = 0; }); - _gstate2.total_producer_votepay_share += ( delta_total_votepay_share - new_votepay_share ); - _gstate3.last_vpay_state_update = ct; - if( producer_per_block_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.bpay),N(active)}, { N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } ); diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index b9907d3a..450983f1 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -124,6 +124,23 @@ namespace eosiosystem { return double(staked) * std::pow( 2, weight ); } + double system_contract::update_total_votepay_share( /*time_point*/ uint64_t ct, + double additional_shares_delta, + double shares_rate_delta ) + { + double delta_total_votepay_share = 0.0; + if( ct > _gstate3.last_vpay_state_update ) { + delta_total_votepay_share = _gstate3.total_vpay_share_change_rate + * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ); + } + + _gstate2.total_producer_votepay_share += (delta_total_votepay_share + additional_shares_delta); + _gstate3.last_vpay_state_update = ct; + _gstate3.total_vpay_share_change_rate += shares_rate_delta; + + return _gstate2.total_producer_votepay_share; + } + double system_contract::update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, /*time_point*/ uint64_t ct, double shares_rate, @@ -241,8 +258,6 @@ namespace eosiosystem { } const auto ct = current_time(); - bool update_global_time = false; - bool update_global_share = false; double delta_change_rate = 0.0; double total_inactive_vpay_share = 0.0; for( const auto& pd : producer_deltas ) { @@ -265,9 +280,6 @@ namespace eosiosystem { bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); // Note: update_after_threshold implies cross_threshold - update_global_time = true; - update_global_share = true; //|= !updated_after_threshold; - double new_votepay_share = update_producer_votepay_share( prod2, ct, updated_after_threshold ? 0.0 : init_total_votes, @@ -285,13 +297,8 @@ namespace eosiosystem { eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } } - //if ( update_global_share ) { - _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) - total_inactive_vpay_share; - //} - //_gstate2.total_producer_votepay_share -= total_inactive_vpay_share; - _gstate3.total_vpay_share_change_rate += delta_change_rate; - //if ( update_global_time ) - _gstate3.last_vpay_state_update = ct; + + update_total_votepay_share( ct, -total_inactive_vpay_share, delta_change_rate ); _voters.modify( voter, 0, [&]( auto& av ) { av.last_vote_weight = new_vote_weight; @@ -347,8 +354,6 @@ namespace eosiosystem { } else { auto delta = new_weight - voter.last_vote_weight; const auto ct = current_time(); - bool update_global_time = false; - bool update_global_share = false; double delta_change_rate = 0; double total_inactive_vpay_share = 0; for ( auto acnt : voter.producers ) { @@ -360,8 +365,6 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { - update_global_time = true; - const uint64_t last_claim_plus_3days = pitr.last_claim_time + 3 * useconds_per_day; bool crossed_threshold = (last_claim_plus_3days <= ct); bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); @@ -381,13 +384,8 @@ namespace eosiosystem { } } } - //if ( update_global_share ) { - _gstate2.total_producer_votepay_share += _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ) - total_inactive_vpay_share; - //} - //_gstate2.total_producer_votepay_share -= total_inactive_vpay_share; - _gstate3.total_vpay_share_change_rate += delta_change_rate; - //if ( update_global_time ) - _gstate3.last_vpay_state_update = ct; + + update_total_votepay_share( ct, -total_inactive_vpay_share, delta_change_rate ); } } _voters.modify( voter, 0, [&]( auto& v ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 2f7214d5..5eb14a6c 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1689,7 +1689,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni } produce_block(fc::hours(24)); - + // switch to new producer pay metric { BOOST_REQUIRE_EQUAL( 0, get_global_state2()["revision"].as() ); @@ -1698,10 +1698,10 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_REQUIRE_EQUAL( success(), push_action(config::system_account_name, N(updtrevision), mvo()("revision", 1) ) ); BOOST_REQUIRE_EQUAL( 1, get_global_state2()["revision"].as() ); - + const uint32_t prod_index = 2; const auto prod_name = producer_names[prod_index]; - + const auto initial_prod_info = get_producer_info(prod_name); const auto initial_prod_info2 = get_producer_info2(prod_name); const auto initial_global_state = get_global_state(); @@ -1720,7 +1720,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); - + const auto prod_info = get_producer_info(prod_name); const auto prod_info2 = get_producer_info2(prod_name); const auto global_state = get_global_state(); @@ -1734,20 +1734,20 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const uint32_t unpaid_blocks = prod_info["unpaid_blocks"].as(); const uint64_t claim_time = prod_info["last_claim_time"].as_uint64(); const uint64_t prod_update_time = prod_info2["last_votepay_share_update"].as_uint64(); - + const uint64_t usecs_between_fills = bucket_fill_time - initial_bucket_fill_time; const double secs_between_global_updates = (vpay_state_update - initial_vpay_state_update) / 1E6; const double secs_between_prod_updates = (prod_update_time - initial_prod_update_time) / 1E6; const double votepay_share = initial_prod_info2["votepay_share"].as_double() + secs_between_prod_updates * prod_info["total_votes"].as_double(); const double tot_votepay_share = initial_tot_votepay_share + initial_tot_vpay_rate * secs_between_global_updates; - + const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) + initial_perblock_bucket; const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) + initial_pervote_bucket; const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks; const int64_t from_pervote_bucket = int64_t( ( votepay_share * expected_pervote_bucket ) / tot_votepay_share ); - + const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); BOOST_REQUIRE_EQUAL( claim_time, vpay_state_update ); @@ -1755,9 +1755,9 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_CHECK_EQUAL( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ); BOOST_CHECK_EQUAL( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - + produce_block(fc::hours(2)); - + BOOST_REQUIRE_EQUAL( wasm_assert_msg("already claimed rewards within past day"), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); } @@ -1775,7 +1775,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); } - + // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers std::vector producer_names; { @@ -1805,7 +1805,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * } produce_block( fc::hours(24) ); - + // producvotera votes for defproducera ... defproducerj // producvoterb votes for defproducera ... defproduceru // producvoterc votes for defproducera ... defproducerz @@ -1833,7 +1833,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end())) ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[26])["votepay_share"].as_double() ); } - + { auto proda = get_producer_info( N(defproducera) ); auto prodj = get_producer_info( N(defproducerj) ); @@ -1841,9 +1841,9 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * auto produ = get_producer_info( N(defproduceru) ); auto prodv = get_producer_info( N(defproducerv) ); auto prodz = get_producer_info( N(defproducerz) ); - + BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); - + // check vote ratios BOOST_REQUIRE ( 0 < proda["total_votes"].as_double() && 0 < prodz["total_votes"].as_double() ); BOOST_TEST_REQUIRE( proda["total_votes"].as_double() == prodj["total_votes"].as_double() ); @@ -1882,7 +1882,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * votepay_shares[i] = info2["votepay_share"].as_double(); total_votepay_shares += votepay_shares[i]; expected_total_votepay_shares += votepay_shares[i]; - expected_total_votepay_shares += info["total_votes"].as_double() * double( ( gs3["last_vpay_state_update"].as_uint64() - + expected_total_votepay_shares += info["total_votes"].as_double() * double( ( gs3["last_vpay_state_update"].as_uint64() - info2["last_votepay_share_update"].as_uint64() ) / 1E6 ); } BOOST_TEST( expected_total_votepay_shares > total_votepay_shares ); @@ -1896,9 +1896,9 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * const auto& init_info2 = get_producer_info2(prod_name); BOOST_REQUIRE( 0 < init_info2["votepay_share"].as_double() ); BOOST_REQUIRE( 0 < init_info2["last_votepay_share_update"].as_uint64() ); - + BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name)) ); - + BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_uint64(), get_producer_info2(prod_name)["last_votepay_share_update"].as_uint64() ); @@ -1921,7 +1921,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { cross_15_percent_threshold(); - + const asset net = core_from_string("80.0000"); const asset cpu = core_from_string("80.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; @@ -1944,7 +1944,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::u BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); produce_block( fc::hours(25) ); - + BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); @@ -1956,29 +1956,29 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::u produce_block( fc::hours(24) ); BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - + produce_block( fc::hours(24) ); - + BOOST_REQUIRE_EQUAL( success(), push_action(prodb, N(claimrewards), mvo()("owner", prodb)) ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(prodb)["votepay_share"].as_double() ); produce_block( fc::hours(10) ); - + BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - + produce_block( fc::hours(16) ); BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == + BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == get_producer_info2(prodb)["votepay_share"].as_double() ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_test::tolerance(1e-5)) try { - + cross_15_percent_threshold(); - + const asset net = core_from_string("80.0000"); const asset cpu = core_from_string("80.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; @@ -1990,7 +1990,9 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ const auto bob = accounts[1]; const auto carol = accounts[2]; const auto emily = accounts[3]; - + + wlog("start"); + // alice becomes a proxy BOOST_REQUIRE_EQUAL( success(), push_action( alice, N(regproxy), mvo()("proxy", alice)("isproxy", true) ) ); REQUIRE_MATCHING_OBJECT( proxy( alice ), get_voter_info( alice ) ); @@ -1999,7 +2001,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), regproducer( carol, 1) ); BOOST_REQUIRE_EQUAL( success(), regproducer( emily, 1) ); - // bob chooses alice as proxy + // bob chooses alice as proxy BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0002"), core_from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, core_from_string("150.0000"), core_from_string("150.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); @@ -2011,7 +2013,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == total_votes ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); uint64_t last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); - + produce_block( fc::hours(15) ); // alice (proxy) votes again for carol @@ -2041,7 +2043,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), push_action(carol, N(claimrewards), mvo()("owner", carol)) ); produce_block( fc::hours(20) ); - + // bob votes for carol BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); @@ -2050,11 +2052,12 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - produce_block( fc::hours(53) ); + produce_block( fc::hours(/*53*/ 54) ); // bob votes for carol again // carol hasn't claimed rewards in over 3 days total_votes = get_producer_info(carol)["total_votes"].as_double(); + wlog("bob is about to revote for carol"); BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_REQUIRE_EQUAL( get_producer_info2(carol)["last_votepay_share_update"].as_uint64(), get_global_state3()["last_vpay_state_update"].as_uint64() ); @@ -2082,14 +2085,14 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); produce_block( fc::hours(5) ); - + // alice votes for carol and emily // emily hasn't claimed rewards in over 3 days last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); cur_info2 = get_producer_info2(carol); auto cur_info2_emily = get_producer_info2(emily); - + expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); @@ -2148,9 +2151,9 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0000"), core_from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); - - BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); + + BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); produce_block( fc::hours(1) ); BOOST_REQUIRE_EQUAL( success(), push_action( emily, N(claimrewards), mvo()("owner", emily) ) ); @@ -2159,7 +2162,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost { signed_transaction trx; set_transaction_headers(trx); - + trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {carol, config::active_name} }, mvo()("owner", carol) ) ); @@ -2173,7 +2176,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost trx.sign( get_private_key( carol, "active" ), control->get_chain_id() ); trx.sign( get_private_key( alice, "active" ), control->get_chain_id() ); trx.sign( get_private_key( emily, "active" ), control->get_chain_id() ); - + push_transaction( trx ); } @@ -2193,7 +2196,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - + const asset net = core_from_string("80.0000"); const asset cpu = core_from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; @@ -2248,7 +2251,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t BOOST_REQUIRE( 0 < get_producer_info(N(defproducer1))["last_claim_time"].as_uint64() ); BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducer1))["last_claim_time"].as_uint64(), get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_uint64() ); - + } FC_LOG_AND_RETHROW() @@ -3297,8 +3300,8 @@ BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { set_abi( config::system_account_name, contracts::bios_abi().data() ); create_account(N(eosio.token)); set_abi( N(eosio.token), contracts::token_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); @@ -3309,8 +3312,8 @@ BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { } set_abi( N(eosio.token), contracts::system_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); @@ -3323,8 +3326,8 @@ BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { set_abi( N(eosio.token), contracts::token_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); @@ -3335,8 +3338,8 @@ BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { } set_abi( N(eosio.token), contracts::system_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + { + auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); From 2ad2aa41f86ba8e9c9e1b4c584050322568df58b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Wed, 29 Aug 2018 18:12:35 -0400 Subject: [PATCH 0494/1048] "invalidate" action in msig.eosio contract #53 --- eosio.msig/abi/eosio.msig.abi | 21 ++- eosio.msig/include/eosio.msig/eosio.msig.hpp | 31 ++++- eosio.msig/src/eosio.msig.cpp | 133 ++++++++++++++----- tests/eosio.msig_tests.cpp | 43 ++++++ 4 files changed, 189 insertions(+), 39 deletions(-) diff --git a/eosio.msig/abi/eosio.msig.abi b/eosio.msig/abi/eosio.msig.abi index 9fcf8a95..48608077 100644 --- a/eosio.msig/abi/eosio.msig.abi +++ b/eosio.msig/abi/eosio.msig.abi @@ -93,6 +93,12 @@ {"name":"proposal_name", "type":"name"}, {"name":"executer", "type":"account_name"} ] + },{ + "name": "invalidate", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + ] },{ "name": "proposal", "base": "", @@ -108,6 +114,13 @@ {"name": "requested_approvals", "type": "permission_level[]"}, {"name": "provided_approvals", "type": "permission_level[]"} ] + },{ + "name": "invalidation", + "base": "", + "fields": [ + {"name": "account", "type": "account_name"}, + {"name": "last_invalidation_time", "type": "uint64"} + ] } ], "actions": [{ @@ -122,14 +135,18 @@ "name": "unapprove", "type": "unapprove", "ricardian_contract": "" - }, { + },{ "name": "cancel", "type": "cancel", "ricardian_contract": "" - }, { + },{ "name": "exec", "type": "exec", "ricardian_contract": "" + },{ + "name": "invalidate", + "type": "invalidate", + "ricardian_contract": "" } ], diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index 48ce2e3d..cb370e83 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -13,6 +13,7 @@ namespace eosio { void unapprove( account_name proposer, name proposal_name, permission_level level ); void cancel( account_name proposer, name proposal_name, account_name canceler ); void exec( account_name proposer, name proposal_name, account_name executer ); + void invalidate( account_name account ); private: struct proposal { @@ -23,14 +24,38 @@ namespace eosio { }; typedef eosio::multi_index proposals; - struct approvals_info { + struct old_approvals_info { name proposal_name; vector requested_approvals; vector provided_approvals; auto primary_key()const { return proposal_name.value; } }; - typedef eosio::multi_index approvals; - }; + typedef eosio::multi_index old_approvals; + + struct approval { + permission_level level; + uint64_t time; + }; + + struct approvals_info { + uint8_t version; + name proposal_name; + vector requested_approvals; + vector provided_approvals; + + auto primary_key()const { return proposal_name.value; } + }; + typedef eosio::multi_index approvals; + + struct invalidation { + account_name account; + uint64_t last_invalidation_time; + + auto primary_key() const { return account; } + }; + + typedef eosio::multi_index invalidations; +}; } /// namespace eosio diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index 9d04a1a9..e9a9cea1 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -63,29 +63,51 @@ void multisig::approve( account_name proposer, name proposal_name, permission_le require_auth( level ); approvals apptable( _self, proposer ); - auto& apps = apptable.get( proposal_name, "proposal not found" ); - - auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level ); - eosio_assert( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" ); - - apptable.modify( apps, proposer, [&]( auto& a ) { - a.provided_approvals.push_back( level ); - a.requested_approvals.erase( itr ); - }); + auto apps_it = apptable.find( proposal_name ); + if ( apps_it != apptable.end() ) { + auto itr = std::find( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), level ); + eosio_assert( itr != apps_it->requested_approvals.end(), "approval is not on the list of requested approvals" ); + + apptable.modify( apps_it, proposer, [&]( auto& a ) { + a.provided_approvals.push_back( approval{ level, now() } ); + a.requested_approvals.erase( itr ); + }); + } else { + old_approvals old_apptable( _self, proposer ); + auto& apps = old_apptable.get( proposal_name, "proposal not found" ); + + auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level ); + eosio_assert( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" ); + + old_apptable.modify( apps, proposer, [&]( auto& a ) { + a.provided_approvals.push_back( level ); + a.requested_approvals.erase( itr ); + }); + } } void multisig::unapprove( account_name proposer, name proposal_name, permission_level level ) { require_auth( level ); approvals apptable( _self, proposer ); - auto& apps = apptable.get( proposal_name, "proposal not found" ); - auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); - eosio_assert( itr != apps.provided_approvals.end(), "no approval previously granted" ); - - apptable.modify( apps, proposer, [&]( auto& a ) { - a.requested_approvals.push_back(level); - a.provided_approvals.erase(itr); - }); + auto apps_it = apptable.find( proposal_name ); + if ( apps_it != apptable.end() ) { + auto itr = std::find_if( apps_it->provided_approvals.begin(), apps_it->provided_approvals.end(), [&](const approval& a) { return a.level == level; } ); + eosio_assert( itr != apps_it->provided_approvals.end(), "no approval previously granted" ); + apptable.modify( apps_it, proposer, [&]( auto& a ) { + a.requested_approvals.push_back( level ); + a.provided_approvals.erase( itr ); + }); + } else { + old_approvals old_apptable( _self, proposer ); + auto apps = old_apptable.get( proposal_name, "proposal not found" ); + auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); + eosio_assert( itr != apps.provided_approvals.end(), "no approval previously granted" ); + old_apptable.modify( apps, proposer, [&]( auto& a ) { + a.requested_approvals.push_back( level ); + a.provided_approvals.erase( itr ); + }); + } } void multisig::cancel( account_name proposer, name proposal_name, account_name canceler ) { @@ -97,12 +119,19 @@ void multisig::cancel( account_name proposer, name proposal_name, account_name c if( canceler != proposer ) { eosio_assert( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(now()), "cannot cancel until expiration" ); } + proptable.erase(prop); + //remove from new table approvals apptable( _self, proposer ); - auto& apps = apptable.get( proposal_name, "proposal not found" ); - - proptable.erase(prop); - apptable.erase(apps); + auto apps_it = apptable.find( proposal_name ); + if ( apps_it != apptable.end() ) { + apptable.erase(apps_it); + } else { + old_approvals old_apptable( _self, proposer ); + auto apps_it = old_apptable.find( proposal_name ); + eosio_assert( apps_it != old_apptable.end(), "proposal not found" ); + old_apptable.erase(apps_it); + } } void multisig::exec( account_name proposer, name proposal_name, account_name executer ) { @@ -110,28 +139,64 @@ void multisig::exec( account_name proposer, name proposal_name, account_name exe proposals proptable( _self, proposer ); auto& prop = proptable.get( proposal_name, "proposal not found" ); - - approvals apptable( _self, proposer ); - auto& apps = apptable.get( proposal_name, "proposal not found" ); - transaction_header trx_header; datastream ds( prop.packed_transaction.data(), prop.packed_transaction.size() ); ds >> trx_header; eosio_assert( trx_header.expiration >= eosio::time_point_sec(now()), "transaction expired" ); - bytes packed_provided_approvals = pack(apps.provided_approvals); - auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), - (const char*)0, 0, - packed_provided_approvals.data(), packed_provided_approvals.size() - ); - eosio_assert( res > 0, "transaction authorization failed" ); - + approvals apptable( _self, proposer ); + auto apps_it = apptable.find( proposal_name ); + if ( apps_it != apptable.end() ) { + vector approvals; + approvals.reserve( apps_it->provided_approvals.size() ); + + invalidations inv_table( _self, _self ); + for ( auto& p : apps_it->provided_approvals ) { + auto it = inv_table.find( p.level.actor ); + if ( it == inv_table.end() || it->last_invalidation_time < p.time ) { + approvals.push_back(p.level); + } + } + bytes packed_provided_approvals = pack(approvals); + auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), + (const char*)0, 0, + packed_provided_approvals.data(), packed_provided_approvals.size() + ); + eosio_assert( res > 0, "transaction authorization failed" ); + apptable.erase(apps_it); + } else { + old_approvals old_apptable( _self, proposer ); + auto& apps = old_apptable.get( proposal_name, "proposal not found" ); + + bytes packed_provided_approvals = pack(apps.provided_approvals); + auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), + (const char*)0, 0, + packed_provided_approvals.data(), packed_provided_approvals.size() + ); + eosio_assert( res > 0, "transaction authorization failed" ); + old_apptable.erase(apps); + } send_deferred( (uint128_t(proposer) << 64) | proposal_name, executer, prop.packed_transaction.data(), prop.packed_transaction.size() ); proptable.erase(prop); - apptable.erase(apps); +} + +void multisig::invalidate( account_name account ) { + require_auth( account ); + invalidations inv_table( _self, _self ); + auto it = inv_table.find( account ); + if ( it == inv_table.end() ) { + inv_table.emplace( account, [&](auto& i) { + i.account = account; + i.last_invalidation_time = now(); + }); + } else { + inv_table.modify( it, account, [&](auto& i) { + i.last_invalidation_time = now(); + }); + } } } /// namespace eosio -EOSIO_ABI( eosio::multisig, (propose)(approve)(unapprove)(cancel)(exec) ) +EOSIO_ABI( eosio::multisig, (propose)(approve)(unapprove)(cancel)(exec)(invalidate) ) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 0683a552..c35dfa94 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -272,6 +272,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { ); //fail because approval by bob is missing + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -624,5 +625,47 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ); } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { + auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + //fail to execute before approval + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + + //approve + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + //invalidate + push_action( N(alice), N(invalidate), mvo() + ("account", "alice") + ); + + //fail to execute after invalidation + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); +} FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_SUITE_END() From 65ca0471e7f8481f80fc4bede6ef0312b8ef15e4 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 29 Aug 2018 18:24:36 -0400 Subject: [PATCH 0495/1048] update global state variables should be tolerant of small floating point errors; should maintain invariant that accumulators never become negative --- eosio.system/src/voting.cpp | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 450983f1..dd53800e 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -128,15 +128,44 @@ namespace eosiosystem { double additional_shares_delta, double shares_rate_delta ) { + static const double relative_tolerance = 1e-10; + double delta_total_votepay_share = 0.0; if( ct > _gstate3.last_vpay_state_update ) { delta_total_votepay_share = _gstate3.total_vpay_share_change_rate * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ); } - _gstate2.total_producer_votepay_share += (delta_total_votepay_share + additional_shares_delta); + delta_total_votepay_share += additional_shares_delta; + if( delta_total_votepay_share < 0 && _gstate2.total_producer_votepay_share < -delta_total_votepay_share ) { + // Some amount of over subtracting is acceptable because of floating point errors. + // If it is too much though, the caller of this function is passing in delta values that are too negative. + { + double delta_total_votepay_share_magnitude = -delta_total_votepay_share; // must be positive + double relative_error = (delta_total_votepay_share_magnitude - _gstate2.total_producer_votepay_share) + / delta_total_votepay_share_magnitude; // must be positive and no greater than 1.0 + eosio_assert( relative_error < relative_tolerance, "subtracting too much from total_producer_votepay_share" ); + } + _gstate2.total_producer_votepay_share = 0.0; + } else { + _gstate2.total_producer_votepay_share += delta_total_votepay_share; + } + + if( shares_rate_delta < 0 && _gstate3.total_vpay_share_change_rate < -shares_rate_delta ) { + // Some amount of over subtracting is acceptable because of floating point errors. + // If it is too much though, the caller of this function is passing in delta values that are too negative. + { + double shares_rate_delta_magnitude = -shares_rate_delta; // must be positive + double relative_error = (shares_rate_delta_magnitude - _gstate3.total_vpay_share_change_rate) + / shares_rate_delta_magnitude; // must be positive and no greater than 1.0 + eosio_assert( relative_error < relative_tolerance, "subtracting too much from total_vpay_share_change_rate" ); + } + _gstate3.total_vpay_share_change_rate = 0.0; + } else { + _gstate3.total_vpay_share_change_rate += shares_rate_delta; + } + _gstate3.last_vpay_state_update = ct; - _gstate3.total_vpay_share_change_rate += shares_rate_delta; return _gstate2.total_producer_votepay_share; } @@ -147,8 +176,8 @@ namespace eosiosystem { bool reset_to_zero ) { double delta_votepay_share = 0.0; - if( shares_rate != 0.0 ) { - delta_votepay_share = shares_rate * double( (ct - prod_itr->last_votepay_share_update) / 1E6 ); + if( shares_rate > 0.0 && ct > prod_itr->last_votepay_share_update ) { + delta_votepay_share = shares_rate * double( (ct - prod_itr->last_votepay_share_update) / 1E6 ); // cannot be negative } double new_votepay_share = prod_itr->votepay_share + delta_votepay_share; From a8840ef3b2ba93b151bcd39a598a22a3c97236b0 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 29 Aug 2018 18:34:25 -0400 Subject: [PATCH 0496/1048] revert unneeded changes to eosio_system_tests/votepay_share_proxy --- tests/eosio.system_tests.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 5eb14a6c..934898ad 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1991,8 +1991,6 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ const auto carol = accounts[2]; const auto emily = accounts[3]; - wlog("start"); - // alice becomes a proxy BOOST_REQUIRE_EQUAL( success(), push_action( alice, N(regproxy), mvo()("proxy", alice)("isproxy", true) ) ); REQUIRE_MATCHING_OBJECT( proxy( alice ), get_voter_info( alice ) ); @@ -2052,12 +2050,11 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - produce_block( fc::hours(/*53*/ 54) ); + produce_block( fc::hours(54) ); // bob votes for carol again // carol hasn't claimed rewards in over 3 days total_votes = get_producer_info(carol)["total_votes"].as_double(); - wlog("bob is about to revote for carol"); BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_REQUIRE_EQUAL( get_producer_info2(carol)["last_votepay_share_update"].as_uint64(), get_global_state3()["last_vpay_state_update"].as_uint64() ); From 6be53f340f0b2c45e2c2157e6fc8418d52299914 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 29 Aug 2018 18:29:27 -0400 Subject: [PATCH 0497/1048] Fix unit test --- tests/eosio.system_tests.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 5eb14a6c..df64fd8f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1969,9 +1969,18 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::u produce_block( fc::hours(16) ); BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); + produce_block( fc::hours(2) ); BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - BOOST_TEST_REQUIRE( get_global_state2()["total_producer_votepay_share"].as_double() == - get_producer_info2(prodb)["votepay_share"].as_double() ); + + const auto& info = get_producer_info(prodb); + const auto& info2 = get_producer_info2(prodb); + const auto& gs2 = get_global_state2(); + const auto& gs3 = get_global_state3(); + + double expected_total_vpay_share = info2["votepay_share"].as_double() + + info["total_votes"].as_double() * (gs3["last_vpay_state_update"].as_uint64() - info2["last_votepay_share_update"].as_uint64()) / 1E6; + + BOOST_TEST_REQUIRE( expected_total_vpay_share == gs2["total_producer_votepay_share"].as_double() ); } FC_LOG_AND_RETHROW() From 4416f8ac6e3d58ec38c2838a690e9c1a92d74055 Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 30 Aug 2018 14:48:12 -0400 Subject: [PATCH 0498/1048] "invalidate" action in msig.eosio contract: small changes #53 --- eosio.msig/src/eosio.msig.cpp | 31 +++++++++++++++---------------- tests/contracts.hpp.in | 2 ++ 2 files changed, 17 insertions(+), 16 deletions(-) diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index e9a9cea1..8d28a316 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -146,36 +146,35 @@ void multisig::exec( account_name proposer, name proposal_name, account_name exe approvals apptable( _self, proposer ); auto apps_it = apptable.find( proposal_name ); + vector approvals; + invalidations inv_table( _self, _self ); if ( apps_it != apptable.end() ) { - vector approvals; approvals.reserve( apps_it->provided_approvals.size() ); - - invalidations inv_table( _self, _self ); for ( auto& p : apps_it->provided_approvals ) { auto it = inv_table.find( p.level.actor ); if ( it == inv_table.end() || it->last_invalidation_time < p.time ) { approvals.push_back(p.level); } } - bytes packed_provided_approvals = pack(approvals); - auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), - (const char*)0, 0, - packed_provided_approvals.data(), packed_provided_approvals.size() - ); - eosio_assert( res > 0, "transaction authorization failed" ); apptable.erase(apps_it); } else { old_approvals old_apptable( _self, proposer ); auto& apps = old_apptable.get( proposal_name, "proposal not found" ); - - bytes packed_provided_approvals = pack(apps.provided_approvals); - auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), - (const char*)0, 0, - packed_provided_approvals.data(), packed_provided_approvals.size() - ); - eosio_assert( res > 0, "transaction authorization failed" ); + for ( auto& level : apps.provided_approvals ) { + auto it = inv_table.find( level.actor ); + if ( it == inv_table.end() ) { + approvals.push_back( level ); + } + } old_apptable.erase(apps); } + bytes packed_provided_approvals = pack(approvals); + auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), + (const char*)0, 0, + packed_provided_approvals.data(), packed_provided_approvals.size() + ); + eosio_assert( res > 0, "transaction authorization failed" ); + send_deferred( (uint128_t(proposer) << 64) | proposal_name, executer, prop.packed_transaction.data(), prop.packed_transaction.size() ); proptable.erase(prop); diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 7cb86179..18b38970 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -23,6 +23,8 @@ struct contracts { struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } static std::vector exchange_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/exchange.wasm"); } + static std::string msig_wast_old() { return read_wast("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old.wast"); } + static std::vector msig_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old.abi"); } }; }; }} //ns eosio::testing From 7ac69cd78b32c6de3a44b09cf0d358f23db32d3b Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Thu, 30 Aug 2018 17:46:59 -0400 Subject: [PATCH 0499/1048] unit-test for new eosio.msig contract with old data, small bugfix #53 --- eosio.msig/src/eosio.msig.cpp | 2 +- tests/contracts.hpp.in | 4 +- tests/eosio.msig_tests.cpp | 139 ++++++++++++++++ .../test_contracts/eosio.msig.old/Readme.txt | 4 + .../eosio.msig.old/eosio.msig.abi | 152 ++++++++++++++++++ .../eosio.msig.old/eosio.msig.wasm | Bin 0 -> 16573 bytes 6 files changed, 298 insertions(+), 3 deletions(-) create mode 100644 tests/test_contracts/eosio.msig.old/Readme.txt create mode 100644 tests/test_contracts/eosio.msig.old/eosio.msig.abi create mode 100755 tests/test_contracts/eosio.msig.old/eosio.msig.wasm diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index 8d28a316..e0a9e08b 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -100,7 +100,7 @@ void multisig::unapprove( account_name proposer, name proposal_name, permission_ }); } else { old_approvals old_apptable( _self, proposer ); - auto apps = old_apptable.get( proposal_name, "proposal not found" ); + auto& apps = old_apptable.get( proposal_name, "proposal not found" ); auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); eosio_assert( itr != apps.provided_approvals.end(), "no approval previously granted" ); old_apptable.modify( apps, proposer, [&]( auto& a ) { diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 18b38970..390c8909 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -23,8 +23,8 @@ struct contracts { struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } static std::vector exchange_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/exchange.wasm"); } - static std::string msig_wast_old() { return read_wast("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old.wast"); } - static std::vector msig_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old.abi"); } + static std::vector msig_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old/eosio.msig.wasm"); } + static std::vector msig_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old/eosio.msig.abi"); } }; }; }} //ns eosio::testing diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index c35dfa94..c5bd2ec8 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -668,4 +668,143 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { ); } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( approve_execute_old, eosio_msig_tester ) try { + set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); + set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); + produce_blocks(); + + //propose with old version of eosio.msig + auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + set_code( N(eosio.msig), contracts::msig_wasm() ); + set_abi( N(eosio.msig), contracts::msig_abi().data() ); + produce_blocks(); + + //approve and execute with new version + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( approve_unapprove_old, eosio_msig_tester ) try { + set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); + set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); + produce_blocks(); + + //propose with old version of eosio.msig + auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + //approve with old version + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + set_code( N(eosio.msig), contracts::msig_wasm() ); + set_abi( N(eosio.msig), contracts::msig_abi().data() ); + produce_blocks(); + + //unapprove with old version + push_action( N(alice), N(unapprove), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { + set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); + set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); + produce_blocks(); + + auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }) + ); + + //approve by alice + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + set_code( N(eosio.msig), contracts::msig_wasm() ); + set_abi( N(eosio.msig), contracts::msig_abi().data() ); + produce_blocks(); + + //fail because approval by bob is missing + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + + //approve and execute with new version + push_action( N(bob), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(bob), config::active_name }) + ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/test_contracts/eosio.msig.old/Readme.txt b/tests/test_contracts/eosio.msig.old/Readme.txt new file mode 100644 index 00000000..526cf983 --- /dev/null +++ b/tests/test_contracts/eosio.msig.old/Readme.txt @@ -0,0 +1,4 @@ +Compiled with +eosio.contracts ee6415b0d3f9cff3bafebf98b2e06b80545dfa36 +eosio.wasmsdk 0d4befeee7abbef1db775b2e8833f7db8fca7ad2 +eos 2ad412773d6ccc72045dae760ae3d81cf229c8ee diff --git a/tests/test_contracts/eosio.msig.old/eosio.msig.abi b/tests/test_contracts/eosio.msig.old/eosio.msig.abi new file mode 100644 index 00000000..9fcf8a95 --- /dev/null +++ b/tests/test_contracts/eosio.msig.old/eosio.msig.abi @@ -0,0 +1,152 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + }], + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name": "actor", "type": "account_name"}, + {"name": "permission", "type": "permission_name"} + ] + },{ + "name": "action", + "base": "", + "fields": [ + {"name": "account", "type": "account_name"}, + {"name": "name", "type": "action_name"}, + {"name": "authorization", "type": "permission_level[]"}, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction_header", + "base": "", + "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": "extension", + "base": "", + "fields": [ + {"name": "type", "type" : "uint16" }, + {"name": "data", "type": "bytes"} + ] + },{ + "name": "transaction", + "base": "transaction_header", + "fields": [ + {"name": "context_free_actions", "type": "action[]"}, + {"name": "actions", "type": "action[]"}, + {"name": "transaction_extensions", "type": "extension[]"} + ] + },{ + "name": "propose", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"requested", "type":"permission_level[]"}, + {"name":"trx", "type":"transaction"} + ] + },{ + "name": "approve", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"level", "type":"permission_level"} + ] + },{ + "name": "unapprove", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"level", "type":"permission_level"} + ] + },{ + "name": "cancel", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"canceler", "type":"account_name"} + ] + },{ + "name": "exec", + "base": "", + "fields": [ + {"name":"proposer", "type":"account_name"}, + {"name":"proposal_name", "type":"name"}, + {"name":"executer", "type":"account_name"} + ] + },{ + "name": "proposal", + "base": "", + "fields": [ + {"name": "proposal_name", "type": "name"}, + {"name": "packed_transaction", "type": "bytes"} + ] + },{ + "name": "approvals_info", + "base": "", + "fields": [ + {"name": "proposal_name", "type": "name"}, + {"name": "requested_approvals", "type": "permission_level[]"}, + {"name": "provided_approvals", "type": "permission_level[]"} + ] + } + ], + "actions": [{ + "name": "propose", + "type": "propose", + "ricardian_contract": "" + },{ + "name": "approve", + "type": "approve", + "ricardian_contract": "" + },{ + "name": "unapprove", + "type": "unapprove", + "ricardian_contract": "" + }, { + "name": "cancel", + "type": "cancel", + "ricardian_contract": "" + }, { + "name": "exec", + "type": "exec", + "ricardian_contract": "" + } + + ], + "tables": [{ + "name": "proposal", + "type": "proposal", + "index_type": "i64", + "key_names" : ["proposal_name"], + "key_types" : ["name"] + },{ + "name": "approvals", + "type": "approvals_info", + "index_type": "i64", + "key_names" : ["proposal_name"], + "key_types" : ["name"] + } + ], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/tests/test_contracts/eosio.msig.old/eosio.msig.wasm b/tests/test_contracts/eosio.msig.old/eosio.msig.wasm new file mode 100755 index 0000000000000000000000000000000000000000..4c07755757c2e30bbeb5b562de4a43ae894ab160 GIT binary patch literal 16573 zcmeI3e~e{kS;x=Md+*Gd>7K$A#%-nVJ*+ZCiYqO%+k$q^Mz*b>-I7KL|IFTlk?JlW1Lu_#WK}oC$8WT%G(poHO2!uuxveiYK2nh;Bq7nBGV~XJqW6)Hi;OG0i z=iGZ|e?Sq8sO)C$`SJdG-si{ndEV!JPtfVFg+UO6zaGBkXtI6&{Q1Bx+riP0zaTi; z*tUP+_R;3~^SV9HZNOi&y=`~rbr&3sDdIU)2Xv!aQPrD@(`_}TJC#|@M4hSKd9~x| zyq+l4(BXFU7x7JTcm2$*ODDTaD~p4z&U(MIG+5qPU+kP7oZQ%2eqTpVL84l(^R+g+ zTWibx{?(OIRm!XO$2)`0Vt@I4-JoHwx4NC*9VJ(<+X0mvRB;= z`d;kx``xWUFrinCweH%|=DA?f%D1|wPA_kDjlv+)tL*r(#S_cx#}}99?+m8&Ca?S5 z>MnJc&vdtZ-_zr5-x5r#YLm{_HqLZ?@6&X3dK2Qi*4YiJp?6zd)vAJe-k(IKYZ1zn-k%ygI7&V1T%Wsys3Fp zbkj`{|B^J^3>%F!4ui1qns_@bcP<9mc2Hip5Z0IG11)vEv2`vAvc<)d-OlFXu};4m zhm(toCS^DgM`>qsbM;(sdt>pv$5)S>3GPZ4-@E=uFF2rUrxzSlL5G67C$cao!z_K% zkGJPuJ9)W3N57wm!p3&AQ2%$qT+}KeU6LYRap42gfs6GR6v;}Fy0BL?%I$YeN9DKp z*K9YV1s6GrqVk)(h~G*5hKtH@KrfMN+<$Y?e8+T@xn_Q#9ZkiV3(BO|4&ntDm%-gZ z;P_APB^}4}QQ*RIyH|wM!BmoEWzcT&7fppU%ik7c^w{jRn@|+?7_^=6BJCAvJ0A5H z(^Z=aRX=LOfQd_Oy}Gi*mpfF}1rcjQ7B=Z(Eq+}4;b5=jl0=n|Bzo@*M7 z@1S;=-?b;pK668g^uPoCy*?=akzT`nlonAQX+|%E;w?kGKe=DL%U~Cz`k3JbZ)el$38$5gM23Ea%IiR=liLjT?)}5)7vn%t_fC689f#M&b__p}DFmL(^ z&WZYJG7rc+jJTJAo@S0@4s9QZ-@^qy9fiu^wip#X5Z@zCR0h2?`3q^7$c=vRWMGO8vN*EqS3!2EC#__$=lCVh` z(d2{F34t<%6ZM}n_;HJuHQisn?PS+ zz?Cv!6kZ-I&@1}nRnDuQD?j+WF<6{4vx>?~AI)rgS}?1Z3#bfw;wm25?P->4|<3 z35YQZUB;bO8%o4(UnK^?B$cSVY}yPCc)ECj=KiQSd3BQzu{-EP&x99oIfasGfHc1= zV@mu)<$lmh(qmXDwBrIp=9p%!&=T)Zp*`cVruk?}@4aNi6|@~0B)bLBqFyBc$>IwB z@4uS=5(E6#W!A)?W)M|L;dKlIw=Tn(tHiKR0P(p>4AFv#;!Tw#m~$n9z>5G`3`Ib1 zaL3Ca7|Gyrh!L3psDK2*DZEHj&WZPMonL82RDKQ#+$srN-qm1Q@|uh0#C!?Q%VMSo zyewvW&R`@!48EvU7a^u$k;F9YMx9VMD#xaUHOC9MhLgQQZVZwG!zcC0NWSZtA{>rt zvc`7|N3Dt&by(z;1BZ1l*ui*nQeY1ZxH^2P*CVNr=rL>7045wvdiegRsa{3(&@N(^ zda`4YjfMtosi!7QcVdt(Qe2}gkm8PL6UV?Yu*+z}BEAE0PlSb7;i>y5vQ!5Vp0c+u z$i5uK5xz6t)__Sn!tBsK5J=v(4GR=4G+;4~o^kFk|HHhLym%4a9uOe-aHCh4t4@H{ zZw05A&9}l+MLc-sF}jLNf`*uqo$%BUj2&2?$o8zK70??*Or9*79w>-0R&rOB0u6~~ zS)>3qY6yGi?&pOl6hIo_KfsV-ATtwp6+BR6IApY1Oaj9Scv8E*`O+B2O7gOH8drYWy;}#*!{0wwdeg?{C+dz^p2JXzu$P4k#eo!2FZk+rT zb!Fot&O-=D(kc=mT`0t~HA5n-1MP=3vyViv77K|M3pu)=wF1UvNFx+_MlM89sM!bt zWh+lgsc_3gl%V6g2{xMphvo&Rw(bu07&3~rgmM35@Hn(3R1q1QzBinVYpB0XLqZR5 zihVr5S#+w_hPh@*f?bna-MJxC(~GX^6l}BUUbk-Vn$?>EEe7|XB?yBXLH4yIZo(p4 zPt`0ko|vyf3#4H1NNxh5B)Y>K3k;YNEE%65fws79Ra%0T%tcewM89;~(yiilb4{_9 zv>~m)u9&EZNEE`PDh=1t1x=;^)M#i0nBW0wfm?eMxP>r^7lby2sT8s`JFt+Rw{qTi z4)thFsyjxtQD7=}1pavV*2**O3CSLb@nS-@!QVj{5K6IWLgpcy`%fEQD^rd0i1w=M1k>DS*&&FYD=?~K{Q!4Tt#xpd^ zkG=Txi&{IBPwPhM4ndB5q_38gUwZn*H~Opx&S8K$!xEqM03e#>>?(XLCzbnY2t*8aVH}pgbTLqJf*uACRu;{bV!}WlE41W+0t{enQszEcn>$^# zB-9Dg2A0f{7-nQ^(gNQdT$?E-R*KAbhuE*()r9XV8+K*WPbxG?hz?pFO_Dk~Xc?M# zgo-skTs6NVctJsHN8Uo%;G>*&P7VSf(*=dDO#IhA|M{aAu#NW@$Cr23SF?-MDK zYh~k;YGyW$QMa&h|KcHeUfC};J}DcYtZh85ZQS2vmw#y8So05@bX6 z^3g0wG1kIoI9hGkK-cncAn3j2^Ym%6G^Al9rJ<($h=3k9ED>HW8s?(?+F)R!dMfYi z6%!s0(EYOBcKP4%@-ytysT^Q z{g}jr_ZwC#fyqj7JQaosF@`{ImK;O9*pnx;#a<#3%^LuBVB&*BqNze#Tg}^&55*Av z6L~uqRHkGf71k=zjpvc#1mNsG4K?Zo*Hw3uW}iqBB@L>T zDxr6RDoRUmF4p9mmfF=Q$}|4{B}s{3+M*abYe;(S#g`m2z&xX+NeroUtu97)CC(5VRMQD@6-4ZBH=gmYjBsZ)oM&UK|7WxKy(^ z1f>}A!SZiKDIQkFNB{sO>Ix&1nCZ+r%_;N+6H~Z7CI36+{jZVJW+5T}qluXBBw8l& zto<*`1oilxy1G^$rn%$Md_yci{I&mW$p0c`si%-3Hvb!s{I9^m!h1@Yp8Rj>CggZi zm?Hnn`WzskXo}VDZRBGc_*nnKe5@=KAKR3VZPq?E<>fxG4874!_UZo@nGL1N zugGjDrX#bV%Pforyqr0ZQFag8spF!n6CCV@#Xj3HV_RdE?bs)y|3S!h+$ysk&x~9v z+c8sTJMaU;YzHcCR`nedA-_9v-9AjOmM`QyanhD(BirPibYQ#9z>FD-z?t+cS&%VL zo#K1&)FdQa%JQp0DhF$*+GD8=@2L?~wQ}*pkyY2mTN^NKr@Q^K#HX|_jw15n9yzH@j=L zLSR|7d;r$I2Y3CASK_YUz~ufnxa&`Sznq|!k#Y)hg1O>^@74**NqQ$(`BNF?E+>e} zc_)avdned1Cy05x0w-8ygMR1-;obM_2cJvGBoSC&t^@0w^*ug=`jJQ@4tyZ)+=-12i6lu+&G?;0keDtF6NkRTf9_Fo!=#3Tc2Dg$!dyKZx}d zi$3HpN4Nkm@1gD&NP#Atw(uRHmUXlH%imD)SoyPEG_yJv&5VPuiI>titIvGRW)p7?G z@&llR=EEW%n!~0lG&f{xTRhp&`hujUp)SzssaqJQ?h@HxBabNClQ-JamCsOahi2Nz z*F|xoktgwt(O_HqjcVi8768KhYZ3v+F5CLx_r9O&12&sp>H45P4Rgf;VXqblqi%LB z5T1%-Ee_aK#K&8m-~O!D0QHLCPyLe?I&5;mD4eXeXAHEoYbD+xc9?<+`Sedii$k`x zE$f6o(jtODoIJ8NztZvu2{x}QF{=^DNKMtsmPU-DoO*O``L7yW0Rn?yB2+9QK`zbc zk4do`P$`=4&+?C!Yah8@wUu!FszSo``F}0@Y~xy6b2K+Vmp-LrOZgeDWrzf{{P9|- zxhh3k?eE!^5+%0Dq|NtsGlR6zHax4TYiXJhW12Q1#x#vxYD%=rNnVnwHPV;7xJzDEHpK4N!!9EX}8^{r118{=2Zp$z>1UPXQnxcpgN z?hfwrPw%2hbId&*Y;##2lWDov`$y&OK%|1Jqrw$ld z-SKMtT%H9F>Ll`hmt~^xjb%O;$SH&T2I$dg%7%Qf31!R=+X*xy=oTohJ>W?*9s|sz z{5l@ca%bc+ya#N^K`T=N!&o0(=>e;=RHo7@GzX07nM%u#!))+#SY!js4Ob5OC4X|r zvs8S8|AweT`aTqn6ZkkAaz-Ftz!Nx%AaMINfj;E$%4JlD&0|zF1mz}PB^}ETg_gp* zCKVKO)Q%*_pU06l?W^!E-WTLI9b&f&eM(4JWLn zD=Jx)or{0);TQ3L50;;>kjq36x`2T18vS0;D;h`^k;AWEZQ*!yNQbe%sI8S>g6)wt z_>vx#OZ1NypZdrbpJxCL4SEuGo_P8%Ih?9Q6C%2k3#sG%bWJXJzarAO{0iz6V}|*g z_bQ+58$NDlXzPwH{?*t1`pbX+(7UH;=dC_2S>4J5)6at9#k!x_UjCDNwOwl!-^GQr z>V3ZAeRiy)8ZfttB#Ese=h;eD$p?MKgUU(QJvyUI{Ls)3alzt__=-ogaava-TfBcS z%lurO`Kaq-QPkLuB~mv$k)x<4A@j-wosTS(h!!}O5p2FU`o8nV4QcaciDTQaU`#hd)5>}=Qk}`-WS33=!cA#_h0~y7#cOSc`@)fGpy5L; zkUMc63b7}WkvH-T&_TrCgrPr1s6%voIo{svK?eo9 z+ml7ZA3nvKtq@j>GL_ZwEUyKqs)UPA9-ctu$caBTig01OWEriXPV^f+P@RF)GK3SU z@J0wRJOJq;q!e)KYBDIF`x9>RJG0Lx;goi)sskBF@M2j+9D>Phr}N_T*hfw)?SIHl z=(lWg+;#;$j&Ih&PyZ$POC{;kNV5_iO|ACyAqSu&&C|>BF&+z@-V+k3P{gomwB7-J zGO4lpf=&7^i49dTOk1;D>6*qm03BGS_bdm0x72~i!sJ!ejw`6kQ7x;&HZN7Cm5$Bd zst=C%-00u+NfQ}e;+>#;fmxDu2}(^@AtWEnlts(VNYS4rQ-tLO=+`JlyN^!}m!H0< zMR918qp%{9q1PhGYc0Bg*&Hli3<9t1uix!tH z;+HlNA8^>vJ{eG)gf*a#8b$ix_bSrG$PhXgJ$8YQ2(^tB-AMRg#Sm$y z`x|gKKakxZtF|>xK&+G5+q<$f(6JKGIs3!rjEN+h8T-K4bqHDV_mmIP2O})@G-5kPgbq!(#G26Dj(QV$-3ezUyaWYiENINgWFhxr`aQ%FWUyLG9vu5P(3bywZ#^}+J0XQKZ^JJ2F7 zTi96Vi{yQilFKTWneeB-=`C@Ll_ue-I=tApi5 zKF{u+r6r#NWUuuks@vuDhh5!_Qa;+t?x-h9`2gB&l)j^iFHX1)j5vvCmp0as z+ma~aOi1?Tt0-FAIKF)1+;xfJ=*V!ms_H8oj-wpe+x&;(kWoqIWM}>1E)rZ`>ujBK zE8TPMk&|5*U_@x9o%L!u5KJO8yZtJHVPL;|U3y7uXK$%S^EF=~xg@2tw{`{ydUGH{ U@t?C-#GnqHffk5heC$jo-@Bjb+ literal 0 HcmV?d00001 From c9e6a82ae8dac6c48537478b91c324185d8702d2 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 30 Aug 2018 18:34:29 -0400 Subject: [PATCH 0500/1048] use time_point to replace raw uint64_t for microseconds since epoch --- eosio.system/abi/eosio.system.abi | 12 +- .../include/eosio.system/eosio.system.hpp | 21 +-- eosio.system/src/eosio.system.cpp | 15 +- eosio.system/src/producer_pay.cpp | 31 ++-- eosio.system/src/voting.cpp | 30 ++-- tests/eosio.system_tester.hpp | 4 + tests/eosio.system_tests.cpp | 136 +++++++++--------- 7 files changed, 134 insertions(+), 115 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 73c316f1..d4baf192 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -260,7 +260,7 @@ },{ "name": "eosio_global_state3", "fields": [ - {"name":"last_vpay_state_update", "type":"uint64"}, + {"name":"last_vpay_state_update", "type":"time_point"}, {"name":"total_vpay_share_change_rate", "type":"float64"} ] },{ @@ -271,12 +271,12 @@ {"name":"total_ram_bytes_reserved", "type":"uint64"}, {"name":"total_ram_stake", "type":"int64"}, {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, - {"name":"last_pervote_bucket_fill", "type":"uint64"}, + {"name":"last_pervote_bucket_fill", "type":"time_point"}, {"name":"pervote_bucket", "type":"int64"}, {"name":"perblock_bucket", "type":"int64"}, {"name":"total_unpaid_blocks", "type":"uint32"}, {"name":"total_activated_stake", "type":"int64"}, - {"name":"thresh_activated_stake_time", "type":"uint64"}, + {"name":"thresh_activated_stake_time", "type":"time_point"}, {"name":"last_producer_schedule_size", "type":"uint16"}, {"name":"total_producer_vote_weight", "type":"float64"}, {"name":"last_name_close", "type":"block_timestamp_type"} @@ -291,7 +291,7 @@ {"name":"is_active", "type":"bool"}, {"name":"url", "type":"string"}, {"name":"unpaid_blocks", "type":"uint32"}, - {"name":"last_claim_time", "type":"uint64"}, + {"name":"last_claim_time", "type":"time_point"}, {"name":"location", "type":"uint16"} ] },{ @@ -300,7 +300,7 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"votepay_share", "type":"float64"}, - {"name":"last_votepay_share_update", "type":"uint64"} + {"name":"last_votepay_share_update", "type":"time_point"} ] },{ "name": "regproducer", @@ -443,7 +443,7 @@ {"name":"newname", "type":"account_name"}, {"name":"high_bidder", "type":"account_name"}, {"name":"high_bid", "type":"int64"}, - {"name":"last_bid_time", "type":"uint64"} + {"name":"last_bid_time", "type":"time_point"} ] } ], diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 49f89ae9..ea397298 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -19,12 +19,14 @@ namespace eosiosystem { using eosio::indexed_by; using eosio::const_mem_fun; using eosio::block_timestamp; + using eosio::time_point; + using eosio::microseconds; struct name_bid { account_name newname; account_name high_bidder; int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed - uint64_t last_bid_time = 0; + time_point last_bid_time; auto primary_key()const { return newname; } uint64_t by_high_bid()const { return static_cast(-high_bid); } @@ -43,12 +45,12 @@ namespace eosiosystem { int64_t total_ram_stake = 0; block_timestamp last_producer_schedule_update; - uint64_t last_pervote_bucket_fill = 0; + time_point last_pervote_bucket_fill; int64_t pervote_bucket = 0; int64_t perblock_bucket = 0; uint32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid int64_t total_activated_stake = 0; - uint64_t thresh_activated_stake_time = 0; + time_point thresh_activated_stake_time; uint16_t last_producer_schedule_size = 0; double total_producer_vote_weight = 0; /// the sum of all producer votes block_timestamp last_name_close; @@ -79,8 +81,8 @@ namespace eosiosystem { struct eosio_global_state3 { eosio_global_state3() { } - uint64_t last_vpay_state_update = 0; - double total_vpay_share_change_rate = 0; + time_point last_vpay_state_update; + double total_vpay_share_change_rate = 0; EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) }; @@ -92,7 +94,7 @@ namespace eosiosystem { bool is_active = true; std::string url; uint32_t unpaid_blocks = 0; - uint64_t last_claim_time = 0; + time_point last_claim_time; uint16_t location = 0; uint64_t primary_key()const { return owner; } @@ -108,7 +110,7 @@ namespace eosiosystem { struct producer_info2 { account_name owner; double votepay_share = 0; - uint64_t last_votepay_share_update = 0; + time_point last_votepay_share_update; uint64_t primary_key()const { return owner; } @@ -266,6 +268,7 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); + static time_point current_time_point(); static block_timestamp current_block_time(); void update_ram_supply(); @@ -281,9 +284,9 @@ namespace eosiosystem { void propagate_weight_change( const voter_info& voter ); double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, - /*time_point*/ uint64_t ct, + time_point ct, double shares_rate, bool reset_to_zero = false ); - double update_total_votepay_share( /*time_point*/ uint64_t ct, + double update_total_votepay_share( time_point ct, double additional_shares_delta = 0.0, double shares_rate_delta = 0.0 ); }; diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 7696498d..4e5876aa 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -50,8 +50,13 @@ namespace eosiosystem { return dp; } + time_point system_contract::current_time_point() { + const static time_point ct{ microseconds{ static_cast( current_time() ) } }; + return ct; + } + block_timestamp system_contract::current_block_time() { - const static block_timestamp cbt{ time_point{ microseconds{ static_cast( current_time() ) } } }; + const static block_timestamp cbt{ current_time_point() }; return cbt; } @@ -163,7 +168,7 @@ namespace eosiosystem { b.newname = newname; b.high_bidder = bidder; b.high_bid = bid.amount; - b.last_bid_time = current_time(); + b.last_bid_time = current_time_point(); }); } else { eosio_assert( current->high_bid > 0, "this auction has already closed" ); @@ -177,7 +182,7 @@ namespace eosiosystem { bids.modify( current, bidder, [&]( auto& b ) { b.high_bidder = bidder; b.high_bid = bid.amount; - b.last_bid_time = current_time(); + b.last_bid_time = current_time_point(); }); } } @@ -235,11 +240,11 @@ namespace eosiosystem { if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { row.owner= acnt; - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } else { table.modify( itr, 0, [&]( auto& row ) { - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } } diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 11e8a86e..744ffdfb 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -13,8 +13,8 @@ namespace eosiosystem { const uint32_t seconds_per_year = 52*7*24*3600; const uint32_t blocks_per_day = 2 * 24 * 3600; const uint32_t blocks_per_hour = 2 * 3600; - const uint64_t useconds_per_day = 24 * 3600 * uint64_t(1000000); - const uint64_t useconds_per_year = seconds_per_year*1000000ll; + const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); + const int64_t useconds_per_year = seconds_per_year*1000000ll; void system_contract::onblock( block_timestamp timestamp, account_name producer ) { @@ -31,8 +31,8 @@ namespace eosiosystem { if( _gstate.total_activated_stake < min_activated_stake ) return; - if( _gstate.last_pervote_bucket_fill == 0 ) /// start the presses - _gstate.last_pervote_bucket_fill = current_time(); + if( _gstate.last_pervote_bucket_fill == time_point() ) /// start the presses + _gstate.last_pervote_bucket_fill = current_time_point(); /** @@ -57,12 +57,13 @@ namespace eosiosystem { auto highest = idx.lower_bound( std::numeric_limits::max()/2 ); if( highest != idx.end() && highest->high_bid > 0 && - highest->last_bid_time < (current_time() - useconds_per_day) && - _gstate.thresh_activated_stake_time > 0 && - (current_time() - _gstate.thresh_activated_stake_time) > 14 * useconds_per_day ) { - _gstate.last_name_close = timestamp; - idx.modify( highest, 0, [&]( auto& b ){ - b.high_bid = -b.high_bid; + (current_time_point() - highest->last_bid_time) > microseconds(useconds_per_day) && + _gstate.thresh_activated_stake_time > time_point() && + (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) + ) { + _gstate.last_name_close = timestamp; + idx.modify( highest, 0, [&]( auto& b ){ + b.high_bid = -b.high_bid; }); } } @@ -79,14 +80,14 @@ namespace eosiosystem { eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" ); - const auto ct = current_time(); + const auto ct = current_time_point(); - eosio_assert( ct - prod.last_claim_time > useconds_per_day, "already claimed rewards within past day" ); + eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); - const auto usecs_since_last_fill = ct - _gstate.last_pervote_bucket_fill; + const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); - if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > 0 ) { + if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { auto new_tokens = static_cast( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); auto to_producers = new_tokens / 5; @@ -126,7 +127,7 @@ namespace eosiosystem { /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and /// time duration the vote weight has been held into one metric. - const uint64_t last_claim_plus_3days = prod.last_claim_time + 3 * useconds_per_day; + const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); bool crossed_threshold = (last_claim_plus_3days <= ct); bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index dd53800e..51f1b9c5 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -40,7 +40,7 @@ namespace eosiosystem { require_auth( producer ); auto prod = _producers.find( producer ); - const auto ct = current_time(); + const auto ct = current_time_point(); if ( prod != _producers.end() ) { _producers.modify( prod, producer, [&]( producer_info& info ){ @@ -48,7 +48,7 @@ namespace eosiosystem { info.is_active = true; info.url = url; info.location = location; - if ( info.last_claim_time == 0 ) + if ( info.last_claim_time == time_point() ) info.last_claim_time = ct; }); @@ -124,7 +124,7 @@ namespace eosiosystem { return double(staked) * std::pow( 2, weight ); } - double system_contract::update_total_votepay_share( /*time_point*/ uint64_t ct, + double system_contract::update_total_votepay_share( time_point ct, double additional_shares_delta, double shares_rate_delta ) { @@ -133,7 +133,7 @@ namespace eosiosystem { double delta_total_votepay_share = 0.0; if( ct > _gstate3.last_vpay_state_update ) { delta_total_votepay_share = _gstate3.total_vpay_share_change_rate - * double( (ct - _gstate3.last_vpay_state_update) / 1E6 ); + * double( (ct - _gstate3.last_vpay_state_update).count() / 1E6 ); } delta_total_votepay_share += additional_shares_delta; @@ -171,13 +171,13 @@ namespace eosiosystem { } double system_contract::update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, - /*time_point*/ uint64_t ct, + time_point ct, double shares_rate, bool reset_to_zero ) { double delta_votepay_share = 0.0; if( shares_rate > 0.0 && ct > prod_itr->last_votepay_share_update ) { - delta_votepay_share = shares_rate * double( (ct - prod_itr->last_votepay_share_update) / 1E6 ); // cannot be negative + delta_votepay_share = shares_rate * double( (ct - prod_itr->last_votepay_share_update).count() / 1E6 ); // cannot be negative } double new_votepay_share = prod_itr->votepay_share + delta_votepay_share; @@ -238,8 +238,8 @@ namespace eosiosystem { */ if( voter->last_vote_weight <= 0.0 ) { _gstate.total_activated_stake += voter->staked; - if( _gstate.total_activated_stake >= min_activated_stake && _gstate.thresh_activated_stake_time == 0 ) { - _gstate.thresh_activated_stake_time = current_time(); + if( _gstate.total_activated_stake >= min_activated_stake && _gstate.thresh_activated_stake_time == time_point() ) { + _gstate.thresh_activated_stake_time = current_time_point(); } } @@ -286,7 +286,7 @@ namespace eosiosystem { } } - const auto ct = current_time(); + const auto ct = current_time_point(); double delta_change_rate = 0.0; double total_inactive_vpay_share = 0.0; for( const auto& pd : producer_deltas ) { @@ -304,7 +304,7 @@ namespace eosiosystem { }); auto prod2 = _producers2.find( pd.first ); if( prod2 != _producers2.end() ) { - const uint64_t last_claim_plus_3days = pitr->last_claim_time + 3 * useconds_per_day; + const auto last_claim_plus_3days = pitr->last_claim_time + microseconds(3 * useconds_per_day); bool crossed_threshold = (last_claim_plus_3days <= ct); bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); // Note: update_after_threshold implies cross_threshold @@ -382,19 +382,19 @@ namespace eosiosystem { propagate_weight_change( proxy ); } else { auto delta = new_weight - voter.last_vote_weight; - const auto ct = current_time(); + const auto ct = current_time_point(); double delta_change_rate = 0; double total_inactive_vpay_share = 0; for ( auto acnt : voter.producers ) { - auto& pitr = _producers.get( acnt, "producer not found" ); //data corruption - const double init_total_votes = pitr.total_votes; - _producers.modify( pitr, 0, [&]( auto& p ) { + auto& prod = _producers.get( acnt, "producer not found" ); //data corruption + const double init_total_votes = prod.total_votes; + _producers.modify( prod, 0, [&]( auto& p ) { p.total_votes += delta; _gstate.total_producer_vote_weight += delta; }); auto prod2 = _producers2.find( acnt ); if ( prod2 != _producers2.end() ) { - const uint64_t last_claim_plus_3days = pitr.last_claim_time + 3 * useconds_per_day; + const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); bool crossed_threshold = (last_claim_plus_3days <= ct); bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); // Note: update_after_threshold implies cross_threshold diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 7f7b28e2..f7d9342d 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -387,6 +387,10 @@ class eosio_system_tester : public TESTER { return get_stats("4," CORE_SYMBOL_NAME)["supply"].as(); } + uint64_t microseconds_since_epoch_of_iso_string( const fc::variant& v ) { + return static_cast( time_point::from_iso_string( v.as_string() ).time_since_epoch().count() ); + } + fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); if (data.empty()) std::cout << "\nData is empty\n" << std::endl; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d2856cae..8db44886 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1221,7 +1221,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t produce_blocks(50); const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); @@ -1239,7 +1239,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); const auto global_state = get_global_state(); - const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); const int64_t pervote_bucket = global_state["pervote_bucket"].as(); const int64_t perblock_bucket = global_state["perblock_bucket"].as(); const int64_t savings = get_balance(N(eosio.saving)).get_amount(); @@ -1251,7 +1251,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t const asset supply = get_token_supply(); const asset balance = get_balance(N(defproducera)); - BOOST_REQUIRE_EQUAL(claim_time, prod["last_claim_time"].as()); + BOOST_REQUIRE_EQUAL(claim_time, microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); auto usecs_between_fills = claim_time - initial_claim_time; int32_t secs_between_fills = usecs_between_fills/1000000; @@ -1297,7 +1297,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t produce_block(fc::seconds(5 * 60)); const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); @@ -1310,7 +1310,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); BOOST_REQUIRE(0 < prod["total_votes"].as()); BOOST_TEST(initial_tot_vote_weight, prod["total_votes"].as()); - BOOST_REQUIRE(0 < prod["last_claim_time"].as()); + BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); @@ -1320,7 +1320,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); const auto global_state = get_global_state(); - const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); const int64_t pervote_bucket = global_state["pervote_bucket"].as(); const int64_t perblock_bucket = global_state["perblock_bucket"].as(); const int64_t savings = get_balance(N(eosio.saving)).get_amount(); @@ -1332,7 +1332,7 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t const asset supply = get_token_supply(); const asset balance = get_balance(N(defproducera)); - BOOST_REQUIRE_EQUAL(claim_time, prod["last_claim_time"].as()); + BOOST_REQUIRE_EQUAL(claim_time, microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); auto usecs_between_fills = claim_time - initial_claim_time; BOOST_REQUIRE_EQUAL(int64_t( ( double(initial_supply.get_amount()) * double(usecs_between_fills) * continuous_rate / usecs_per_year ) ), @@ -1497,7 +1497,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const auto prod_name = producer_names[prod_index]; const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); @@ -1511,7 +1511,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); const auto global_state = get_global_state(); - const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); const int64_t pervote_bucket = global_state["pervote_bucket"].as(); const int64_t perblock_bucket = global_state["perblock_bucket"].as(); const int64_t savings = get_balance(N(eosio.saving)).get_amount(); @@ -1573,7 +1573,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const auto prod_name = producer_names[prod_index]; const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); @@ -1587,7 +1587,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); const auto global_state = get_global_state(); - const uint64_t claim_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); const int64_t pervote_bucket = global_state["pervote_bucket"].as(); const int64_t perblock_bucket = global_state["perblock_bucket"].as(); const int64_t savings = get_balance(N(eosio.saving)).get_amount(); @@ -1707,16 +1707,16 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const auto initial_global_state = get_global_state(); const double initial_tot_votepay_share = get_global_state2()["total_producer_votepay_share"].as_double(); const double initial_tot_vpay_rate = get_global_state3()["total_vpay_share_change_rate"].as_double(); - const uint64_t initial_vpay_state_update = get_global_state3()["last_vpay_state_update"].as_uint64(); - const uint64_t initial_bucket_fill_time = initial_global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t initial_vpay_state_update = microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ); + const uint64_t initial_bucket_fill_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); const asset initial_supply = get_token_supply(); const asset initial_balance = get_balance(prod_name); const uint32_t initial_unpaid_blocks = initial_prod_info["unpaid_blocks"].as(); - const uint64_t initial_claim_time = initial_prod_info["last_claim_time"].as_uint64(); - const uint64_t initial_prod_update_time = initial_prod_info2["last_votepay_share_update"].as_uint64(); + const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_prod_info["last_claim_time"] ); + const uint64_t initial_prod_update_time = microseconds_since_epoch_of_iso_string( initial_prod_info2["last_votepay_share_update"] ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); @@ -1724,16 +1724,16 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const auto prod_info = get_producer_info(prod_name); const auto prod_info2 = get_producer_info2(prod_name); const auto global_state = get_global_state(); - const uint64_t vpay_state_update = get_global_state3()["last_vpay_state_update"].as_uint64(); - const uint64_t bucket_fill_time = global_state["last_pervote_bucket_fill"].as_uint64(); + const uint64_t vpay_state_update = microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ); + const uint64_t bucket_fill_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); const int64_t pervote_bucket = global_state["pervote_bucket"].as(); const int64_t perblock_bucket = global_state["perblock_bucket"].as(); const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); const asset supply = get_token_supply(); const asset balance = get_balance(prod_name); const uint32_t unpaid_blocks = prod_info["unpaid_blocks"].as(); - const uint64_t claim_time = prod_info["last_claim_time"].as_uint64(); - const uint64_t prod_update_time = prod_info2["last_votepay_share_update"].as_uint64(); + const uint64_t claim_time = microseconds_since_epoch_of_iso_string( prod_info["last_claim_time"] ); + const uint64_t prod_update_time = microseconds_since_epoch_of_iso_string( prod_info2["last_votepay_share_update"] ); const uint64_t usecs_between_fills = bucket_fill_time - initial_bucket_fill_time; const double secs_between_global_updates = (vpay_state_update - initial_vpay_state_update) / 1E6; @@ -1800,7 +1800,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * wdump((p)); BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_REQUIRE(0 < get_producer_info2(p)["last_votepay_share_update"].as_uint64()); + BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( get_producer_info2(p)["last_votepay_share_update"] )); } } @@ -1817,12 +1817,12 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); const auto& init_info = get_producer_info(producer_names[0]); const auto& init_info2 = get_producer_info2(producer_names[0]); - uint64_t init_update = init_info2["last_votepay_share_update"].as_uint64(); + uint64_t init_update = microseconds_since_epoch_of_iso_string( init_info2["last_votepay_share_update"] ); double init_votes = init_info["total_votes"].as_double(); BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21)) ); const auto& info = get_producer_info(producer_names[0]); const auto& info2 = get_producer_info2(producer_names[0]); - BOOST_TEST_REQUIRE( ((info2["last_votepay_share_update"].as_uint64() - init_update)/double(1E6)) * init_votes == info2["votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( ((microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) - init_update)/double(1E6)) * init_votes == info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( info2["votepay_share"].as_double() * 10 == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[11])["votepay_share"].as_double() ); @@ -1862,8 +1862,8 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * } BOOST_TEST_REQUIRE( total_votes == get_global_state()["total_producer_vote_weight"].as_double() ); BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( get_producer_info2(producer_names.back())["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( microseconds_since_epoch_of_iso_string( get_producer_info2(producer_names.back())["last_votepay_share_update"] ), + microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ) ); std::for_each( vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; } ); BOOST_TEST_REQUIRE( double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0)) ); @@ -1882,8 +1882,10 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * votepay_shares[i] = info2["votepay_share"].as_double(); total_votepay_shares += votepay_shares[i]; expected_total_votepay_shares += votepay_shares[i]; - expected_total_votepay_shares += info["total_votes"].as_double() * double( ( gs3["last_vpay_state_update"].as_uint64() - - info2["last_votepay_share_update"].as_uint64() ) / 1E6 ); + expected_total_votepay_shares += info["total_votes"].as_double() + * double( ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) + - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) + ) / 1E6 ); } BOOST_TEST( expected_total_votepay_shares > total_votepay_shares ); BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); @@ -1895,23 +1897,25 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * const auto& init_info = get_producer_info(prod_name); const auto& init_info2 = get_producer_info2(prod_name); BOOST_REQUIRE( 0 < init_info2["votepay_share"].as_double() ); - BOOST_REQUIRE( 0 < init_info2["last_votepay_share_update"].as_uint64() ); + BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( init_info2["last_votepay_share_update"] ) ); BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name)) ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_uint64(), - get_producer_info2(prod_name)["last_votepay_share_update"].as_uint64() ); - BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_string(), + get_producer_info2(prod_name)["last_votepay_share_update"].as_string() ); + BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_string(), + get_global_state3()["last_vpay_state_update"].as_string() ); const auto& gs3 = get_global_state3(); double expected_total_votepay_shares = 0; for (uint32_t i = 0; i < producer_names.size(); ++i) { const auto& info = get_producer_info(producer_names[i]); const auto& info2 = get_producer_info2(producer_names[i]); expected_total_votepay_shares += info2["votepay_share"].as_double(); - expected_total_votepay_shares += info["total_votes"].as_double() * double( ( gs3["last_vpay_state_update"].as_uint64() - - info2["last_votepay_share_update"].as_uint64() ) / 1E6 ); + expected_total_votepay_shares += info["total_votes"].as_double() + * double( ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) + - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) + ) / 1E6 ); } BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); } @@ -1977,8 +1981,10 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::u const auto& gs2 = get_global_state2(); const auto& gs3 = get_global_state3(); - double expected_total_vpay_share = info2["votepay_share"].as_double() + - info["total_votes"].as_double() * (gs3["last_vpay_state_update"].as_uint64() - info2["last_votepay_share_update"].as_uint64()) / 1E6; + double expected_total_vpay_share = info2["votepay_share"].as_double() + + info["total_votes"].as_double() + * ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) + - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) ) / 1E6; BOOST_TEST_REQUIRE( expected_total_vpay_share == gs2["total_producer_votepay_share"].as_double() ); @@ -2019,18 +2025,18 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ double total_votes = get_producer_info(carol)["total_votes"].as_double(); BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == total_votes ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - uint64_t last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); + uint64_t last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); produce_block( fc::hours(15) ); // alice (proxy) votes again for carol BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); auto cur_info2 = get_producer_info2(carol); - double expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + double expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == get_producer_info(carol)["total_votes"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); + last_update_time = microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ); total_votes = get_producer_info(carol)["total_votes"].as_double(); produce_block( fc::hours(40) ); @@ -2040,10 +2046,10 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); cur_info2 = get_producer_info2(carol); - expected_votepay_share += double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + expected_votepay_share += double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - last_update_time = cur_info2["last_votepay_share_update"].as_uint64(); + last_update_time = microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ); total_votes = get_producer_info(carol)["total_votes"].as_double(); // carol claims rewards @@ -2055,7 +2061,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); cur_info2 = get_producer_info2(carol); - expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); @@ -2065,8 +2071,8 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ // carol hasn't claimed rewards in over 3 days total_votes = get_producer_info(carol)["total_votes"].as_double(); BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_REQUIRE_EQUAL( get_producer_info2(carol)["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( get_producer_info2(carol)["last_votepay_share_update"].as_string(), + get_global_state3()["last_vpay_state_update"].as_string() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); @@ -2076,8 +2082,8 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ // bob votes for carol again // carol still hasn't claimed rewards BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_REQUIRE_EQUAL(get_producer_info2(carol)["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL(get_producer_info2(carol)["last_votepay_share_update"].as_string(), + get_global_state3()["last_vpay_state_update"].as_string() ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); @@ -2094,41 +2100,41 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ // alice votes for carol and emily // emily hasn't claimed rewards in over 3 days - last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); + last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); cur_info2 = get_producer_info2(carol); auto cur_info2_emily = get_producer_info2(emily); - expected_votepay_share = double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); - BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_string(), + get_global_state3()["last_vpay_state_update"].as_string() ); + BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_string(), + get_global_state3()["last_vpay_state_update"].as_string() ); produce_block( fc::hours(10) ); // bob chooses alice as proxy // emily still hasn't claimed rewards - last_update_time = get_producer_info2(carol)["last_votepay_share_update"].as_uint64(); + last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); cur_info2 = get_producer_info2(carol); cur_info2_emily = get_producer_info2(emily); - expected_votepay_share += double( (cur_info2["last_votepay_share_update"].as_uint64() - last_update_time) / 1E6 ) * total_votes; + expected_votepay_share += double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); - BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_uint64(), - get_global_state3()["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_string(), + get_global_state3()["last_vpay_state_update"].as_string() ); + BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_string(), + get_global_state3()["last_vpay_state_update"].as_string() ); } FC_LOG_AND_RETHROW() @@ -2191,8 +2197,8 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost const auto& emily_info = get_producer_info(emily); const auto& emily_info2 = get_producer_info2(emily); const auto& gs3 = get_global_state3(); - BOOST_REQUIRE_EQUAL( carol_info2["last_votepay_share_update"].as_uint64(), gs3["last_vpay_state_update"].as_uint64() ); - BOOST_REQUIRE_EQUAL( emily_info2["last_votepay_share_update"].as_uint64(), gs3["last_vpay_state_update"].as_uint64() ); + BOOST_REQUIRE_EQUAL( carol_info2["last_votepay_share_update"].as_string(), gs3["last_vpay_state_update"].as_string() ); + BOOST_REQUIRE_EQUAL( emily_info2["last_votepay_share_update"].as_string(), gs3["last_vpay_state_update"].as_string() ); BOOST_TEST_REQUIRE( 0 == carol_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( 0 == emily_info2["votepay_share"].as_double() ); BOOST_REQUIRE( 0 < carol_info["total_votes"].as_double() ); @@ -2227,7 +2233,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_REQUIRE(0 < get_producer_info2(p)["last_votepay_share_update"].as_uint64()); + BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( get_producer_info2(p)["last_votepay_share_update"] )); } } @@ -2236,7 +2242,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t config::system_account_name, N(producers2) ) ); BOOST_REQUIRE( tbl ); - BOOST_REQUIRE( 0 < get_producer_info2("defproducera")["last_votepay_share_update"].as_uint64() ); + BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info2("defproducera")["last_votepay_share_update"] ) ); control->db().remove( *tbl ); tbl = control->db().find( boost::make_tuple( config::system_account_name, @@ -2250,13 +2256,13 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t N(producers2) ) ); BOOST_REQUIRE( !tbl ); BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducera)) ); - BOOST_REQUIRE( get_producer_info(N(defproducera))["last_claim_time"].as_uint64() < get_producer_info2(N(defproducera))["last_votepay_share_update"].as_uint64() ); + BOOST_REQUIRE( microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducera))["last_claim_time"] ) < microseconds_since_epoch_of_iso_string( get_producer_info2(N(defproducera))["last_votepay_share_update"] ) ); create_account_with_resources( N(defproducer1), config::system_account_name, core_from_string("1.0000"), false, net, cpu ); BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducer1)) ); - BOOST_REQUIRE( 0 < get_producer_info(N(defproducer1))["last_claim_time"].as_uint64() ); - BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducer1))["last_claim_time"].as_uint64(), - get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_uint64() ); + BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducer1))["last_claim_time"] ) ); + BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducer1))["last_claim_time"].as_string(), + get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_string() ); } FC_LOG_AND_RETHROW() From 660fde8e96641220c43f672f8cf2929a0bb036af Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 31 Aug 2018 11:23:25 -0400 Subject: [PATCH 0501/1048] uint64_t changed to time_point, now() changed to current_time() #53 --- eosio.msig/abi/eosio.msig.abi | 2 +- eosio.msig/include/eosio.msig/eosio.msig.hpp | 4 ++-- eosio.msig/src/eosio.msig.cpp | 17 +++++++++++------ 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/eosio.msig/abi/eosio.msig.abi b/eosio.msig/abi/eosio.msig.abi index 48608077..2c08ef18 100644 --- a/eosio.msig/abi/eosio.msig.abi +++ b/eosio.msig/abi/eosio.msig.abi @@ -119,7 +119,7 @@ "base": "", "fields": [ {"name": "account", "type": "account_name"}, - {"name": "last_invalidation_time", "type": "uint64"} + {"name": "last_invalidation_time", "type": "time_point"} ] } ], diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index cb370e83..2408b4de 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -35,7 +35,7 @@ namespace eosio { struct approval { permission_level level; - uint64_t time; + time_point time; }; struct approvals_info { @@ -50,7 +50,7 @@ namespace eosio { struct invalidation { account_name account; - uint64_t last_invalidation_time; + time_point last_invalidation_time; auto primary_key() const { return account; } }; diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index e0a9e08b..66b2aefc 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -4,6 +4,11 @@ namespace eosio { +static time_point current_time_point() { + const static time_point ct{ microseconds{ static_cast( current_time() ) } }; + return ct; +} + /* propose function manually parses input data (instead of taking parsed arguments from dispatcher) because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big @@ -34,7 +39,7 @@ void multisig::propose() { ds >> trx_header; require_auth( proposer ); - eosio_assert( trx_header.expiration >= eosio::time_point_sec(now()), "transaction expired" ); + eosio_assert( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); //eosio_assert( trx_header.actions.size() > 0, "transaction must have at least one action" ); proposals proptable( _self, proposer ); @@ -69,7 +74,7 @@ void multisig::approve( account_name proposer, name proposal_name, permission_le eosio_assert( itr != apps_it->requested_approvals.end(), "approval is not on the list of requested approvals" ); apptable.modify( apps_it, proposer, [&]( auto& a ) { - a.provided_approvals.push_back( approval{ level, now() } ); + a.provided_approvals.push_back( approval{ level, current_time_point() } ); a.requested_approvals.erase( itr ); }); } else { @@ -117,7 +122,7 @@ void multisig::cancel( account_name proposer, name proposal_name, account_name c auto& prop = proptable.get( proposal_name, "proposal not found" ); if( canceler != proposer ) { - eosio_assert( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(now()), "cannot cancel until expiration" ); + eosio_assert( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(current_time_point()), "cannot cancel until expiration" ); } proptable.erase(prop); @@ -142,7 +147,7 @@ void multisig::exec( account_name proposer, name proposal_name, account_name exe transaction_header trx_header; datastream ds( prop.packed_transaction.data(), prop.packed_transaction.size() ); ds >> trx_header; - eosio_assert( trx_header.expiration >= eosio::time_point_sec(now()), "transaction expired" ); + eosio_assert( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); approvals apptable( _self, proposer ); auto apps_it = apptable.find( proposal_name ); @@ -187,11 +192,11 @@ void multisig::invalidate( account_name account ) { if ( it == inv_table.end() ) { inv_table.emplace( account, [&](auto& i) { i.account = account; - i.last_invalidation_time = now(); + i.last_invalidation_time = current_time_point(); }); } else { inv_table.modify( it, account, [&](auto& i) { - i.last_invalidation_time = now(); + i.last_invalidation_time = current_time_point(); }); } } From 68d128f1dd74a53d32454ce8f7fa09c927527ddc Mon Sep 17 00:00:00 2001 From: Anton Perkov Date: Fri, 31 Aug 2018 15:31:52 -0400 Subject: [PATCH 0502/1048] type for reqeusted approvals changed, ABI updated, approvals_info version set to 1, new unit-test added #53 --- eosio.msig/abi/eosio.msig.abi | 23 +++++++++- eosio.msig/include/eosio.msig/eosio.msig.hpp | 11 +++-- eosio.msig/src/eosio.msig.cpp | 9 ++-- tests/eosio.msig_tests.cpp | 47 ++++++++++++++++++++ 4 files changed, 82 insertions(+), 8 deletions(-) diff --git a/eosio.msig/abi/eosio.msig.abi b/eosio.msig/abi/eosio.msig.abi index 2c08ef18..4fe2325c 100644 --- a/eosio.msig/abi/eosio.msig.abi +++ b/eosio.msig/abi/eosio.msig.abi @@ -107,13 +107,28 @@ {"name": "packed_transaction", "type": "bytes"} ] },{ - "name": "approvals_info", + "name": "old_approvals_info", "base": "", "fields": [ {"name": "proposal_name", "type": "name"}, {"name": "requested_approvals", "type": "permission_level[]"}, {"name": "provided_approvals", "type": "permission_level[]"} ] + },{ + "name": "approval", + "base": "", + "fields": [ + {"name": "level", "type": "permission_level"}, + {"name": "time", "type": "time_point"} + ] + },{ + "name": "approvals_info", + "base": "", + "fields": [ + {"name": "proposal_name", "type": "name"}, + {"name": "requested_approvals", "type": "approval[]"}, + {"name": "provided_approvals", "type": "approval[]"} + ] },{ "name": "invalidation", "base": "", @@ -158,6 +173,12 @@ "key_types" : ["name"] },{ "name": "approvals", + "type": "old_approvals_info", + "index_type": "i64", + "key_names" : ["proposal_name"], + "key_types" : ["name"] + },{ + "name": "approvals2", "type": "approvals_info", "index_type": "i64", "key_names" : ["proposal_name"], diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index 2408b4de..adfad2b8 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -39,10 +39,13 @@ namespace eosio { }; struct approvals_info { - uint8_t version; - name proposal_name; - vector requested_approvals; - vector provided_approvals; + uint8_t version = 1; + name proposal_name; + //requested approval doesn't need to cointain time, but we want requested approval + //to be of exact the same size ad provided approval, in this case approve/unapprove + //doesn't change serialized data size. So, we use the same type. + vector requested_approvals; + vector provided_approvals; auto primary_key()const { return proposal_name.value; } }; diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index 66b2aefc..5a8c1af2 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -60,7 +60,10 @@ void multisig::propose() { approvals apptable( _self, proposer ); apptable.emplace( proposer, [&]( auto& a ) { a.proposal_name = proposal_name; - a.requested_approvals = std::move(requested); + a.requested_approvals.reserve( requested.size() ); + for ( auto& level : requested ) { + a.requested_approvals.push_back( approval{ level, time_point{ microseconds{0} } } ); + } }); } @@ -70,7 +73,7 @@ void multisig::approve( account_name proposer, name proposal_name, permission_le approvals apptable( _self, proposer ); auto apps_it = apptable.find( proposal_name ); if ( apps_it != apptable.end() ) { - auto itr = std::find( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), level ); + auto itr = std::find_if( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), [&](const approval& a) { return a.level == level; } ); eosio_assert( itr != apps_it->requested_approvals.end(), "approval is not on the list of requested approvals" ); apptable.modify( apps_it, proposer, [&]( auto& a ) { @@ -100,7 +103,7 @@ void multisig::unapprove( account_name proposer, name proposal_name, permission_ auto itr = std::find_if( apps_it->provided_approvals.begin(), apps_it->provided_approvals.end(), [&](const approval& a) { return a.level == level; } ); eosio_assert( itr != apps_it->provided_approvals.end(), "no approval previously granted" ); apptable.modify( apps_it, proposer, [&]( auto& a ) { - a.requested_approvals.push_back( level ); + a.requested_approvals.push_back( approval{ level, current_time_point() } ); a.provided_approvals.erase( itr ); }); } else { diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index c5bd2ec8..9bf3fc16 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -668,6 +668,53 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { ); } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( propose_invalidate_approve, eosio_msig_tester ) try { + auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + //fail to execute before approval + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ), + eosio_assert_message_exception, + eosio_assert_message_is("transaction authorization failed") + ); + + //invalidate + push_action( N(alice), N(invalidate), mvo() + ("account", "alice") + ); + + //approve + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ); + + //successfully execute + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + + push_action( N(bob), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "bob") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( approve_execute_old, eosio_msig_tester ) try { set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); From c88a09ae334b2046165662506448fd800deee93b Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 31 Aug 2018 16:33:54 -0400 Subject: [PATCH 0503/1048] fix corner case in producer pay algorithm transition --- eosio.system/src/producer_pay.cpp | 24 +++++++++++++++--------- eosio.system/src/voting.cpp | 6 ++++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 744ffdfb..c1df8496 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -113,26 +113,32 @@ namespace eosiosystem { } auto prod2 = _producers2.find( owner ); - if ( prod2 == _producers2.end() ) { + + /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and + /// time duration the vote weight has been held into one metric. + const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); + + bool crossed_threshold = (last_claim_plus_3days <= ct); + bool updated_after_threshold = true; + if ( prod2 != _producers2.end() ) { + updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); + } else { prod2 = _producers2.emplace( owner, [&]( producer_info2& info ) { info.owner = owner; info.last_votepay_share_update = ct; }); } + // Note: updated_after_threshold implies cross_threshold (except if claiming rewards when the producers2 table row did not exist). + // The exception leads to updated_after_threshold to be treated as true regardless of whether the threshold was crossed. + // This is okay because in this case the producer will not get paid anything either way. + // In fact it is desired behavior because the producers votes need to be counted in the global total_producer_votepay_share for the first time. + int64_t producer_per_block_pay = 0; if( _gstate.total_unpaid_blocks > 0 ) { producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; } - /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and - /// time duration the vote weight has been held into one metric. - const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); - - bool crossed_threshold = (last_claim_plus_3days <= ct); - bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); - // Note: update_after_threshold implies cross_threshold - double new_votepay_share = update_producer_votepay_share( prod2, ct, updated_after_threshold ? 0.0 : prod.total_votes, diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 51f1b9c5..52be4cdd 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -58,6 +58,8 @@ namespace eosiosystem { info.owner = producer; info.last_votepay_share_update = ct; }); + update_total_votepay_share( ct, 0.0, prod->total_votes ); + // When introducing the producer2 table row for the first time, the producer's votes must also be accounted for in the global total_producer_votepay_share at the same time. } } else { _producers.emplace( producer, [&]( producer_info& info ){ @@ -307,7 +309,7 @@ namespace eosiosystem { const auto last_claim_plus_3days = pitr->last_claim_time + microseconds(3 * useconds_per_day); bool crossed_threshold = (last_claim_plus_3days <= ct); bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); - // Note: update_after_threshold implies cross_threshold + // Note: updated_after_threshold implies cross_threshold double new_votepay_share = update_producer_votepay_share( prod2, ct, @@ -397,7 +399,7 @@ namespace eosiosystem { const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); bool crossed_threshold = (last_claim_plus_3days <= ct); bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); - // Note: update_after_threshold implies cross_threshold + // Note: updated_after_threshold implies cross_threshold double new_votepay_share = update_producer_votepay_share( prod2, ct, From 0b1770cca3fe158591fd2b8bc37d68b6f16d1675 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 31 Aug 2018 17:29:01 -0400 Subject: [PATCH 0504/1048] closing a zero-balance token table row should still require the owner's authorization --- eosio.token/src/eosio.token.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index ff25071d..55a9cb38 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -136,7 +136,9 @@ void token::add_balance( account_name owner, asset value, account_name ram_payer } } -void token::close( account_name owner, symbol_type symbol ) { +void token::close( account_name owner, symbol_type symbol ) +{ + require_auth( owner ); accounts acnts( _self, owner ); auto it = acnts.find( symbol.name() ); eosio_assert( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); From 6713e56ccaab171007de2c6d96df6733d7d87cf3 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 31 Aug 2018 17:37:11 -0400 Subject: [PATCH 0505/1048] add eosio.token::open action --- eosio.token/abi/eosio.token.abi | 12 ++++++++++++ eosio.token/include/eosio.token/eosio.token.hpp | 4 +++- eosio.token/src/eosio.token.cpp | 14 +++++++++++++- 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi index ce5861f2..91f76404 100644 --- a/eosio.token/abi/eosio.token.abi +++ b/eosio.token/abi/eosio.token.abi @@ -35,6 +35,14 @@ {"name":"quantity", "type":"asset"}, {"name":"memo", "type":"string"} ] + },{ + "name": "open", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"symbol", "type":"symbol"}, + {"name":"ram_payer", "type":"account_name"} + ] },{ "name": "close", "base": "", @@ -74,6 +82,10 @@ "name": "create", "type": "create", "ricardian_contract": "" + }, { + "name": "open", + "type": "open", + "ricardian_contract": "" }, { "name": "close", "type": "close", diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 629524ad..512e877a 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -33,10 +33,12 @@ namespace eosio { asset quantity, string memo ); + void open( account_name owner, symbol_type symbol, account_name payer ); + void close( account_name owner, symbol_type symbol ); inline asset get_supply( symbol_name sym )const; - + inline asset get_balance( account_name owner, symbol_name sym )const; private: diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index 55a9cb38..74831f48 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -136,6 +136,18 @@ void token::add_balance( account_name owner, asset value, account_name ram_payer } } +void token::open( account_name owner, symbol_type symbol, account_name ram_payer ) +{ + require_auth( ram_payer ); + accounts acnts( _self, owner ); + auto it = acnts.find( symbol.name() ); + if( it == acnts.end() ) { + acnts.emplace( ram_payer, [&]( auto& a ){ + a.balance = asset{0, symbol}; + }); + } +} + void token::close( account_name owner, symbol_type symbol ) { require_auth( owner ); @@ -148,4 +160,4 @@ void token::close( account_name owner, symbol_type symbol ) } /// namespace eosio -EOSIO_ABI( eosio::token, (create)(issue)(transfer)(close)(retire) ) +EOSIO_ABI( eosio::token, (create)(issue)(transfer)(open)(close)(retire) ) From 957ddf20ff94e632c569c4f89feed1ee487ce86e Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 31 Aug 2018 17:44:30 -0400 Subject: [PATCH 0506/1048] add eosio_token_tests/open_tests to test new eosio.token::open action --- tests/eosio.token_tests.cpp | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index e77ddf70..7a3c0eb0 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -100,6 +100,16 @@ class eosio_token_tester : public tester { ); } + action_result open( account_name owner, + const string& symbolname, + account_name ram_payer ) { + return push_action( ram_payer, N(open), mvo() + ( "owner", owner ) + ( "symbol", "0,CERO" ) + ( "ram_payer", ram_payer ) + ); + } + action_result close( account_name owner, const string& symbolname ) { return push_action( owner, N(close), mvo() @@ -336,6 +346,38 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( open_tests, eosio_token_tester ) try { + + auto token = create( N(alice), asset::from_string("1000 CERO")); + + auto alice_balance = get_account(N(alice), "0,CERO"); + BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); + + BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("1000 CERO"), "issue" ) ); + + alice_balance = get_account(N(alice), "0,CERO"); + REQUIRE_MATCHING_OBJECT( alice_balance, mvo() + ("balance", "1000 CERO") + ); + + auto bob_balance = get_account(N(bob), "0,CERO"); + BOOST_REQUIRE_EQUAL(true, bob_balance.is_null() ); + + BOOST_REQUIRE_EQUAL( success(), open( N(bob), "0,CERO", N(alice) ) ); + + bob_balance = get_account(N(bob), "0,CERO"); + REQUIRE_MATCHING_OBJECT( bob_balance, mvo() + ("balance", "0 CERO") + ); + + BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("200 CERO"), "hola" ) ); + + bob_balance = get_account(N(bob), "0,CERO"); + REQUIRE_MATCHING_OBJECT( bob_balance, mvo() + ("balance", "200 CERO") + ); + +} FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( close_tests, eosio_token_tester ) try { From 7f252a7dcdb81257b6f40c6608ac9fa223b7d255 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 4 Sep 2018 17:32:59 -0400 Subject: [PATCH 0507/1048] Add producer pay transition unit test --- tests/contracts.hpp.in | 2 + tests/eosio.system_tests.cpp | 64 ++ .../eosio.system.old/Readme.txt | 2 + .../eosio.system.old/eosio.system.abi | 626 ++++++++++++++++++ .../eosio.system.old/eosio.system.wasm | Bin 0 -> 132041 bytes 5 files changed, 694 insertions(+) create mode 100644 tests/test_contracts/eosio.system.old/Readme.txt create mode 100644 tests/test_contracts/eosio.system.old/eosio.system.abi create mode 100755 tests/test_contracts/eosio.system.old/eosio.system.wasm diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index 390c8909..cde28e1c 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -23,6 +23,8 @@ struct contracts { struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } static std::vector exchange_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/exchange.wasm"); } + static std::vector system_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/eosio.system.old/eosio.system.wasm"); } + static std::vector system_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.system.old/eosio.system.abi"); } static std::vector msig_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old/eosio.msig.wasm"); } static std::vector msig_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old/eosio.msig.abi"); } }; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 8db44886..743e853a 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2267,6 +2267,70 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE(votepay_transition2, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { + + set_code( config::system_account_name, contracts::util::system_wasm_old() ); + set_abi( config::system_account_name, contracts::util::system_abi_old().data() ); + + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; + for (const auto& v: voters) { + create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + } + + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + { + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'd'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + } + setup_producer_accounts(producer_names); + for (const auto& p: producer_names) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); + } + } + + BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); + produce_block( fc::hours(20) ); + BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); + produce_block( fc::hours(30) ); + BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.end())) ); + BOOST_REQUIRE_EQUAL( success(), push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); + BOOST_REQUIRE_EQUAL( success(), push_action(producer_names[1], N(claimrewards), mvo()("owner", producer_names[1])) ); + auto* tbl = control->db().find( boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); + BOOST_REQUIRE( !tbl ); + + produce_block( fc::hours(2*24) ); + + set_code( config::system_account_name, contracts::system_wasm() ); + set_abi( config::system_account_name, contracts::system_abi().data() ); + + produce_blocks(2); + produce_block( fc::hours(24 + 1) ); + + BOOST_REQUIRE_EQUAL( success(), push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); + BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( get_producer_info(producer_names[0])["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); + + produce_block( fc::hours(5) ); + + BOOST_REQUIRE_EQUAL( success(), regproducer(producer_names[1]) ); + BOOST_TEST_REQUIRE( get_producer_info(producer_names[0])["total_votes"].as_double() + get_producer_info(producer_names[1])["total_votes"].as_double() == + get_global_state3()["total_vpay_share_change_rate"].as_double() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { //install multisig contract abi_serializer msig_abi_ser = initialize_multisig(); diff --git a/tests/test_contracts/eosio.system.old/Readme.txt b/tests/test_contracts/eosio.system.old/Readme.txt new file mode 100644 index 00000000..fd0bee79 --- /dev/null +++ b/tests/test_contracts/eosio.system.old/Readme.txt @@ -0,0 +1,2 @@ +Compiled with +eosio.contracts tag: v1.2.1 diff --git a/tests/test_contracts/eosio.system.old/eosio.system.abi b/tests/test_contracts/eosio.system.old/eosio.system.abi new file mode 100644 index 00000000..5445473a --- /dev/null +++ b/tests/test_contracts/eosio.system.old/eosio.system.abi @@ -0,0 +1,626 @@ +{ + "version": "eosio::abi/1.0", + "types": [{ + "new_type_name": "account_name", + "type": "name" + },{ + "new_type_name": "permission_name", + "type": "name" + },{ + "new_type_name": "action_name", + "type": "name" + },{ + "new_type_name": "transaction_id_type", + "type": "checksum256" + },{ + "new_type_name": "weight_type", + "type": "uint16" + }], + "____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.", + "structs": [{ + "name": "permission_level", + "base": "", + "fields": [ + {"name":"actor", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "key_weight", + "base": "", + "fields": [ + {"name":"key", "type":"public_key"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "bidname", + "base": "", + "fields": [ + {"name":"bidder", "type":"account_name"}, + {"name":"newname", "type":"account_name"}, + {"name":"bid", "type":"asset"} + ] + },{ + "name": "bidrefund", + "base": "", + "fields": [ + {"name":"bidder", "type":"account_name"}, + {"name":"newname", "type":"account_name"} + ] + },{ + "name": "permission_level_weight", + "base": "", + "fields": [ + {"name":"permission", "type":"permission_level"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "wait_weight", + "base": "", + "fields": [ + {"name":"wait_sec", "type":"uint32"}, + {"name":"weight", "type":"weight_type"} + ] + },{ + "name": "authority", + "base": "", + "fields": [ + {"name":"threshold", "type":"uint32"}, + {"name":"keys", "type":"key_weight[]"}, + {"name":"accounts", "type":"permission_level_weight[]"}, + {"name":"waits", "type":"wait_weight[]"} + ] + },{ + "name": "newaccount", + "base": "", + "fields": [ + {"name":"creator", "type":"account_name"}, + {"name":"name", "type":"account_name"}, + {"name":"owner", "type":"authority"}, + {"name":"active", "type":"authority"} + ] + },{ + "name": "setcode", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"vmtype", "type":"uint8"}, + {"name":"vmversion", "type":"uint8"}, + {"name":"code", "type":"bytes"} + ] + },{ + "name": "setabi", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"abi", "type":"bytes"} + ] + },{ + "name": "updateauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"}, + {"name":"parent", "type":"permission_name"}, + {"name":"auth", "type":"authority"} + ] + },{ + "name": "deleteauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"permission", "type":"permission_name"} + ] + },{ + "name": "linkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"}, + {"name":"requirement", "type":"permission_name"} + ] + },{ + "name": "unlinkauth", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"code", "type":"account_name"}, + {"name":"type", "type":"action_name"} + ] + },{ + "name": "canceldelay", + "base": "", + "fields": [ + {"name":"canceling_auth", "type":"permission_level"}, + {"name":"trx_id", "type":"transaction_id_type"} + ] + },{ + "name": "onerror", + "base": "", + "fields": [ + {"name":"sender_id", "type":"uint128"}, + {"name":"sent_trx", "type":"bytes"} + ] + },{ + "name": "buyrambytes", + "base": "", + "fields": [ + {"name":"payer", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"bytes", "type":"uint32"} + ] + },{ + "name": "sellram", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"bytes", "type":"uint64"} + ] + },{ + "name": "buyram", + "base": "", + "fields": [ + {"name":"payer", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"quant", "type":"asset"} + ] + },{ + "name": "delegatebw", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"stake_net_quantity", "type":"asset"}, + {"name":"stake_cpu_quantity", "type":"asset"}, + {"name":"transfer", "type":"bool"} + ] + },{ + "name": "undelegatebw", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"unstake_net_quantity", "type":"asset"}, + {"name":"unstake_cpu_quantity", "type":"asset"} + ] + },{ + "name": "refund", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] + },{ + "name": "delegated_bandwidth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"to", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"} + ] + },{ + "name": "user_resources", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"ram_bytes", "type":"uint64"} + ] + },{ + "name": "total_resources", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"net_weight", "type":"asset"}, + {"name":"cpu_weight", "type":"asset"}, + {"name":"ram_bytes", "type":"uint64"} + ] + },{ + "name": "refund_request", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"request_time", "type":"time_point_sec"}, + {"name":"net_amount", "type":"asset"}, + {"name":"cpu_amount", "type":"asset"} + ] + },{ + "name": "blockchain_parameters", + "base": "", + "fields": [ + + {"name":"max_block_net_usage", "type":"uint64"}, + {"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":"uint32"}, + {"name":"max_inline_action_depth", "type":"uint16"}, + {"name":"max_authority_depth", "type":"uint16"} + ] + },{ + "name": "eosio_global_state2", + "fields": [ + {"name":"new_ram_per_block", "type":"uint16"}, + {"name":"last_ram_increase", "type":"block_timestamp_type"}, + {"name":"last_block_num", "type":"block_timestamp_type"}, + {"name":"reserved", "type":"float64"}, + {"name":"revision", "type":"uint8"} + ] + },{ + "name": "eosio_global_state", + "base": "blockchain_parameters", + "fields": [ + {"name":"max_ram_size", "type":"uint64"}, + {"name":"total_ram_bytes_reserved", "type":"uint64"}, + {"name":"total_ram_stake", "type":"int64"}, + {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, + {"name":"last_pervote_bucket_fill", "type":"uint64"}, + {"name":"pervote_bucket", "type":"int64"}, + {"name":"perblock_bucket", "type":"int64"}, + {"name":"total_unpaid_blocks", "type":"uint32"}, + {"name":"total_activated_stake", "type":"int64"}, + {"name":"thresh_activated_stake_time", "type":"uint64"}, + {"name":"last_producer_schedule_size", "type":"uint16"}, + {"name":"total_producer_vote_weight", "type":"float64"}, + {"name":"last_name_close", "type":"block_timestamp_type"} + ] + },{ + "name": "producer_info", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"total_votes", "type":"float64"}, + {"name":"producer_key", "type":"public_key"}, + {"name":"is_active", "type":"bool"}, + {"name":"url", "type":"string"}, + {"name":"unpaid_blocks", "type":"uint32"}, + {"name":"last_claim_time", "type":"uint64"}, + {"name":"location", "type":"uint16"} + ] + },{ + "name": "regproducer", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"}, + {"name":"producer_key", "type":"public_key"}, + {"name":"url", "type":"string"}, + {"name":"location", "type":"uint16"} + ] + },{ + "name": "unregprod", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"} + ] + },{ + "name": "setram", + "base": "", + "fields": [ + {"name":"max_ram_size", "type":"uint64"} + ] + },{ + "name": "setramrate", + "base": "", + "fields": [ + {"name":"bytes_per_block", "type":"uint16"} + ] + },{ + "name": "regproxy", + "base": "", + "fields": [ + {"name":"proxy", "type":"account_name"}, + {"name":"isproxy", "type":"bool"} + ] + },{ + "name": "voteproducer", + "base": "", + "fields": [ + {"name":"voter", "type":"account_name"}, + {"name":"proxy", "type":"account_name"}, + {"name":"producers", "type":"account_name[]"} + ] + },{ + "name": "voter_info", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"proxy", "type":"account_name"}, + {"name":"producers", "type":"account_name[]"}, + {"name":"staked", "type":"int64"}, + {"name":"last_vote_weight", "type":"float64"}, + {"name":"proxied_vote_weight", "type":"float64"}, + {"name":"is_proxy", "type":"bool"} + ] + },{ + "name": "claimrewards", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] + },{ + "name": "setpriv", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"is_priv", "type":"int8"} + ] + },{ + "name": "rmvproducer", + "base": "", + "fields": [ + {"name":"producer", "type":"account_name"} + ] + },{ + "name": "set_account_limits", + "base": "", + "fields": [ + {"name":"account", "type":"account_name"}, + {"name":"ram_bytes", "type":"int64"}, + {"name":"net_weight", "type":"int64"}, + {"name":"cpu_weight", "type":"int64"} + ] + },{ + "name": "set_global_limits", + "base": "", + "fields": [ + {"name":"cpu_usec_per_period", "type":"int64"} + ] + },{ + "name": "producer_key", + "base": "", + "fields": [ + {"name":"producer_name", "type":"account_name"}, + {"name":"block_signing_key", "type":"public_key"} + ] + },{ + "name": "set_producers", + "base": "", + "fields": [ + {"name":"schedule", "type":"producer_key[]"} + ] + },{ + "name": "require_auth", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"} + ] + },{ + "name": "setparams", + "base": "", + "fields": [ + {"name":"params", "type":"blockchain_parameters"} + ] + },{ + "name": "connector", + "base": "", + "fields": [ + {"name":"balance", "type":"asset"}, + {"name":"weight", "type":"float64"} + ] + },{ + "name": "exchange_state", + "base": "", + "fields": [ + {"name":"supply", "type":"asset"}, + {"name":"base", "type":"connector"}, + {"name":"quote", "type":"connector"} + ] + }, { + "name": "name_bid", + "base": "", + "fields": [ + {"name":"newname", "type":"account_name"}, + {"name":"high_bidder", "type":"account_name"}, + {"name":"high_bid", "type":"int64"}, + {"name":"last_bid_time", "type":"uint64"} + ] + }, { + "name": "bid_refund", + "base": "", + "fields": [ + {"name":"bidder", "type":"account_name"}, + {"name":"amount", "type":"asset"} + ] + } + ], + "actions": [{ + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "" + },{ + "name": "setcode", + "type": "setcode", + "ricardian_contract": "" + },{ + "name": "setabi", + "type": "setabi", + "ricardian_contract": "" + },{ + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "" + },{ + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "" + },{ + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "" + },{ + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "" + },{ + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "" + },{ + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + },{ + "name": "buyrambytes", + "type": "buyrambytes", + "ricardian_contract": "" + },{ + "name": "buyram", + "type": "buyram", + "ricardian_contract": "" + },{ + "name": "sellram", + "type": "sellram", + "ricardian_contract": "" + },{ + "name": "delegatebw", + "type": "delegatebw", + "ricardian_contract": "" + },{ + "name": "undelegatebw", + "type": "undelegatebw", + "ricardian_contract": "" + },{ + "name": "refund", + "type": "refund", + "ricardian_contract": "" + },{ + "name": "regproducer", + "type": "regproducer", + "ricardian_contract": "" + },{ + "name": "setram", + "type": "setram", + "ricardian_contract": "" + },{ + "name": "setramrate", + "type": "setramrate", + "ricardian_contract": "Sets the number of new bytes of ram to create per block and resyncs bancor base connector balance" + },{ + "name": "bidname", + "type": "bidname", + "ricardian_contract": "" + },{ + "name": "bidrefund", + "type": "bidrefund", + "ricardian_contract": "" + },{ + "name": "unregprod", + "type": "unregprod", + "ricardian_contract": "" + },{ + "name": "regproxy", + "type": "regproxy", + "ricardian_contract": "" + },{ + "name": "voteproducer", + "type": "voteproducer", + "ricardian_contract": "" + },{ + "name": "claimrewards", + "type": "claimrewards", + "ricardian_contract": "" + },{ + "name": "setpriv", + "type": "setpriv", + "ricardian_contract": "" + },{ + "name": "rmvproducer", + "type": "rmvproducer", + "ricardian_contract": "" + },{ + "name": "setalimits", + "type": "set_account_limits", + "ricardian_contract": "" + },{ + "name": "setglimits", + "type": "set_global_limits", + "ricardian_contract": "" + },{ + "name": "setprods", + "type": "set_producers", + "ricardian_contract": "" + },{ + "name": "reqauth", + "type": "require_auth", + "ricardian_contract": "" + },{ + "name": "setparams", + "type": "setparams", + "ricardian_contract": "" + }], + "tables": [{ + "name": "producers", + "type": "producer_info", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "global", + "type": "eosio_global_state", + "index_type": "i64", + "key_names" : [], + "key_types" : [] + },{ + "name": "global2", + "type": "eosio_global_state2", + "index_type": "i64", + "key_names" : [], + "key_types" : [] + },{ + "name": "voters", + "type": "voter_info", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["account_name"] + },{ + "name": "userres", + "type": "user_resources", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "delband", + "type": "delegated_bandwidth", + "index_type": "i64", + "key_names" : ["to"], + "key_types" : ["uint64"] + },{ + "name": "rammarket", + "type": "exchange_state", + "index_type": "i64", + "key_names" : ["supply"], + "key_types" : ["uint64"] + },{ + "name": "refunds", + "type": "refund_request", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] + },{ + "name": "namebids", + "type": "name_bid", + "index_type": "i64", + "key_names" : ["newname"], + "key_types" : ["account_name"] + },{ + "name": "bidrefunds", + "type": "bid_refund", + "index_type": "i64", + "key_names" : ["bidder"], + "key_types" : ["account_name"] + } + ], + "ricardian_clauses": [], + "abi_extensions": [] +} diff --git a/tests/test_contracts/eosio.system.old/eosio.system.wasm b/tests/test_contracts/eosio.system.old/eosio.system.wasm new file mode 100755 index 0000000000000000000000000000000000000000..912604751ecfd98bb35740ae65c44fd3030a9b38 GIT binary patch literal 132041 zcmeFa54>GhRqwn0?7wI4owJfA?P-(JwKoAzDS;!DB>jVAo!h@4l0pj+@g|`OHYfd) zCTXqSwC5lZs!y>9ctfokpwQyA8u{S8Eg}X*Z$W%i{&?|S;6)#5L9VY?QBisHeSc%l zx%S%UoTNz$N=j2WYwfw_nrqH6$GeP)Qs>vKe)EM{E_{tj z4OOz=R^2+GcU)_+Rn!M!y{RT{Q&Hr9xQ6U2$?QJ8d@FzWz0dyMYTvTa=q|N|A6q_Jq58!xkM``n0nliKr>MD8^xfUt z_uO#P?yI+NzIMlTJNE90mg|Y2asBpN_FCN)R`*91se7uPj9UrZYq$RhEl;SGu^oFh zZ@v2J8*bwD(^b#_-q-KF-nHd^?1>^hS>hUIUToyi8CD(8)2;)3w)N`0J8rmsGxNE1 z^PU|)zCBv0I@#{+TetC*@|o+;80`rTf}qXZDdh*Qz2Qf*^G(;^uzTCy*FDeSeslBY?KhUcTAMdtchj|dU-$f|siE<6>o)2R zf9|>IwdGGm7V1~w{6GG)!tk?(wn`zZ@T{Ky|3Fw8@cM!U1l_lo9_Aw zdnoFwLM|M9?X@>tz4Pj8w(huo^RBJCw_dk>FZ9Xn)jPpT;~%;3;+WM|q+f{tXWU6v z#PNXtP8-DWiumbIU%h&;qPF50wP!|8U$J7vY0pdtW4iE=I`K2VCq9jvXSVqNU@#bK zHR>xS<7YPF+SB>j9>gooR_)W0WRic4IBqw2_N+Ksp|_qHr~G#gKUS=;Km3it4Q2F% z7UC6rM^*g4m~ZoMDG#2#<~d8h=b3{Q&*VQRC%E zIc>#hQLP^DidU_wr*RZFPEBXyV(xI%nT?7s{Yo4z%`01CeK+j>u_R)Wui3tJ*XGx5 z-LpN7!9gQJrZ`RNTX*fc_Q#@Mj~km`z3tkKH%H%$>ziMF{g2K>->{plGtvKN&$jaH z(YXEmI4a`K%HN3Zj4!|N1MzD%?)#PaK>We@_3>TthvMIfe=UAT{NuOBzZCy!{EFX? z|I-`dUyOfj>^DE%{GT!1__Jn;+`Fwl`}C-|Bi=bkS4Y$Jel6XQ*QVorgW7cO<-Mpg zJ*R(%KX~A?Q5NM<@klb0$7_=)*}#v($;{blG(C6di~scLb6(MNg$I+FL0!cW@8|U_ zUYAB4Do@Sy8_5R!$Bzf2naLy?G`anRyKP;f_xXCOxP}Jwv`s5{az!uB>-|>V%Q{g-h3d=lDyrEsgO7HVpObmy_=i+@Z0ac=WF-P=1GP2)J zEjH-c3kU7Vg4_Ee6Ft-@eIQ(;^GT;s^v!B&c3gc$J9BHsP8+Ae~vDv6Hy*# zFS7C@zWnunIHm_F-!CHC$kXZBb?GFRXk9u*d31hsVV>p@y&Tlmr4!t9$+@J(1Ygal z`e^vaI~yo(&G0AFpTp5iwgDiflSy|_zgRFnJI$tJ;IF%hES{b_{I0ir_||=|R`-er z{d{cfMH!Ifqqk1Ke(smveCN}zwC8l&X4E%WM3?#@0|ojtnPh|Ll49-`1qF3Et6fq2 zy8U86d7VxTT5427*_F366zfRTuK~S3cQswVi=5G2W8-8LYm;rm+bwo`M5VWITW7#) zll`%7*Cuniw$>)M+i!!>&v0AJ#RACJ0Z5@aTTOoqK1H6@fly8T&DqdG+C-Yb(*_mfBx5?UMwYz|EDrWL0i-)7^8?gvh zBmqFzrGid;eze|xB^SEOMef-~LGFThQw~(uLe?qR29f_+dk~^)M88kIN%r%X0_cEJ!scI)aF^xDfWbp;=ZG2I$>hiItu;}!@;n$*421fC+>>$q zf+XuV;6VK*NZX`^elu@OH*X&_jN1zzAZ)`V`aftD@y$RczHud>Y^rkWzJ6ozR}E>J z9%-5tq-l;Ijp0gHNU}C*=|a11KH!jX_OdfHwk;4J4~z+fCJoxa7wi~i3U#C%7*sNa zqd{Ymm;G!`RyhRU+cs!A<`5TOf`^DpmJA}u9*>TlLDTp{lP;$4maOZj8iIJ&Skj!W z-R8wHB;sU^W6tniXx~_1QXFWDFu=oo43o<(x=_k<5G)D8<3}Yr5{ZtaxE)rRnCzHl z9EoIyFwK<}Yi7hE^qAWHn!iP2*VV#gvTxAP<(8er`s<42FM&zK=cKKRBL8n2q_46y z(fW(ICg6N=CNxB+*36t8Me8Dch{6eYDTR{~%n}nZB|@>b!?ZD7vVI2|fnZ{2kB5V< zYTD}*4u3GLww~1Tj$JfPSHQRPrvGe>FBp@zMpShIV2wGUisVa*6*EO5gg>870)*#A zD=y#;Uh&*`(*<#4c$rAZ@Bv|VMH9FTsKIIA_$})uOi$egHX;b-q_I|S=c(ALp{B7q zUKZjFz$%TUCP`$t0G_7l2KRUseSnWjm@*_Wt#UFd$YvAak*b^okAdX`#9&_eKEM}i ztiWF+xXLrhL42uW^y&}1=aNb}6Hr8bI_-p)fwg4-Li`$t8as=r>+b8fA+T7CG|t;% zq;1DYHG7P$k!!$K zh=E+>F2GvTfKU*+8l1Ds&TuehDQ2zY@y@J0J^Ly^ZMdXDk1Jpb1Ow)&jQYl3)O?pd zpvJfdU`P32m3yH2x6m0X44>@_&zw>--pR(I&QByME3Dg6X*QXyS)5vJqQK1)!>Xwv z@L>Rvf-dt_H5f0{@-(*;04sU!mL~2cME`{3l~G8HQUg_B!P7? zuR&F6<*J?6q&YYJqD0i%gdgz=e@2wXMwVvpjt3*v#r$9*PK%_ewF&x~lL1-)NV|*U zWLBzN)MxV4A8;Q4OeVFRMf1hQeYRlHPiC+sa${k^F9vOmar<~*Y(3r=yT}*oD&0n_ z8ttlnYEINuu&V6p6PoQ(?z-6?d>dyws9VRF@z5L1_zN}RuPO0^3D<0Ila{~8Z2x5v zH)f3)2rvWm0Gn|!b9ijba z#qZ@S2QYL{6aIcJT)bb0oNK1wyHE5}R??nLxaCInCR^BmpX;xkfsF+|TayGt90WdT z_*>z-H8J@L-!+k3;k#bgmwZ=J#UL7%ZgG5a$;{Sb@t!oT9 zMQ+=G{VY^(-_e8^OW=>ucbIJrLhL2VIw(~hzUl^(9ou?_PDta19W4(C3RnX>(je6M zJdTtGj+BZcflQv!8Aqx?X)MBr97(ld1m09~+&BuOtKuj?cQ`6Q8b~E6rK5Jfd}gCL zo8ZrgZ|lyc(qCC~Vofr!b;qoxiMd1j7Z!_?y6a+p^EhW!Ead_0j*7Zety=M>^!s78 zb?zRCt_KAM(M-Q3$Q3{JTd8Ipiw!@H#P*Q>X_dyM$r9_!F&x?!dSj*r4mwx%+T9il zbn2+WR~A%wb+1VU+K-kr#>b;Zy=DvD%K$Y~Ip9@YdatHWG3(~OY*Ok1sK_6T2!pn@ zt99qS5GWITNv{VwWfCI&$PGNNnSG1qv|Lbg!ctW3C3*X~@l=0Ya-)~iT{Hs<2IG0e zg|(%xW@~?5mFm()WLWR|J@6?SDxYm=&pjBk2c-tumM*UG^v|#dr5f61THS+{_Mjw7 ztZ}XWDj6ICX~JRD{L;LqK4@(;SSHn4_cU@!eulem%?y_3GPyvUt8{6LV`#7_qF%)o zxSgFL)8bMv$_3RXodK|BVsb#LVHcPgEaBCDw}erej~92e<`kq9NPDctXkNDkWMq)ryBIC0KMQ!F=fC<_tXT!BXzT7^zw1UAQA z%9v_dWL-VxdI@D*#>+D196ODsJ`6yL7C0em-XL_n&FE<=bbg$lv=Ulg%1;^yjh@0! z-VNeZsv#Pg`|H`t%%SMZO%Qh8+PJ|EG^ghtw3 z(!*Ls5g$U3H2U3igN9hbr<4@37&e?*VuK(KSOqGO!QsFZ zI8YM~w6!=xggCgtRg#WpPbLj|UaG*pi&p=1h`VU_Pe*zjOUwn)m!H05EJSi4{A+y^;gq+?58>Mh*l3VV2d9P8#Jb};ITswIp$q1i=>rN|iC@}IUUy%p2 zUJU;xN^YcCbYg5gU&74Y0+o99(=~<;2AU#s$x6HePSFk6DA8x)MDv0|k&hV*lyakA zoqWhi#P*FDfL^e*OOT4Dr06xc$Qa|g%;TJNjmp~|%Opds0koW$+Uvm(agzqqXtRdw zDt6KNawdVXw1jIIUReg91;Q;%Xjuldmr}Ng2`$S2`6-lb914gf$WU4g6Or+g#zM=> z_(?mV(dGQ4iO^n&W?FuWk#%`K>4s~3&D#!#;<{uW%Su_BmGT%t>)Tn82Z1HW zIUzfo#+J!t1A7Xvon^w*M<#=&24dQdS2!^Z`}bh?M1DE^M%1!inw`NOP6a!F-4vT8m4b^etXTpELiL?$@EE14Rr$U&o4hPn^7rFKxv)^V8j!KZQOqe^)#{N zyP65gG_hq_OY~~A6zH{0XPMEV24FK9T3*Ui8VHRd+%==2J=taGT4<`&05sE@(PlY; zi}C!$GyrMUTAk7G6k|3LoYDfq6agbJI2Zh^Xx@k}T6;-PD`P-dGcPnZf)jeYx?sQ$ zYCCOBNfJwGuduu!SQ!XXM&lVF9*KZ zjhR~Rq%F_|tZgYnKsm|28hZ{1xMKUwDyU_Yk=M`G+P z#@N-oSkv2-r7MxzD`QMQf^(({$AA%9^RlPmfB?&i*_lD?bY|49CjU1dcI1p;@;b6$ zz}CcSa3|aYuwaRkM+A(@+*8;)1$wku%@eu zH-ALMNk%Bby7cR2h&nsncq>shU-;XPB(E&~UeBlTlTTlOQ{@+b4|L&ItGWQdzdZIz zkg~ZZBCM(SmD!o%(fG#Vba_(S#e1-kwUH^jHAcZEUuEwD0zP z)9c?jz5Y#o^zyOkv)+IMUQ{sthBvCDbjts$%JxB}*uC~EtVBUwbr;kHX%M9)*HpyB zw+Me>dI5{&x1$-k)qdIYu?H@CXzPbR6#eVHFM3yA|KPhWilVs-ufOv{)9)Vi z-oX$3JMtf{?nN%LP0?+${U!Qp?~qJIOQ!3yu$U#&%V!7Uw_;9V*?Vh$DRXo3%!$JWt_g{-?$I;RG%+Id|a<#FUw41rh2;t{*VKwaLS=uF@d* z@reCcn|w81Hi}Z zsnn-iw;Sfwr{}(zzF|7L0u&fifQry-fFu`JW(7)wpO`$4z`;=Y<#?^F1^Gc5ml;OF zv_Lkg8d}A+d3V@^DcJN$G*`U&9g2TTFfs?a5uJQ4F7ElgDEqkt!M+PEPrV1hn?*+= zOTdZuo*#V<&=jBJ#dxYT=c8?jJ>jzkg$V|{w}+C+8p_S)o#u7LIPAZA-1fe>0} z$mZLm1Cm%w#pmR!i~BaD26E@?-! z;6gneN642r^3Q2N96_Iam~hTRx~Gr#a}^Z819N-K%^m#mfq&Ge4q0RcTqFB_z>%zp z4j_yzn5hFVa1^Z$9|CY<1~$|W@HaeK1JL{%26O+`laLA*p%y>NvEomD&&iS{=?2Og zfD-9|97znx7RVCG3MWepX^tj65E)~o$Y_)zL)-#%YUE4yHDHvKP9?I&Xe z1LsRi+C9n1_;5Tz8V{9JEu23D@r)3|y%gk2*QNLC0SNyf*Wy7qMZ5T7h5XUs^j}H- zs^VFIriS_eJA{nzNuD_#&=sdOX_pkAP`MM#UE>H3GMOEH$8!MMa2&uh=#idMsmjy| zO_1zn&BqN^YibVB$DN`X+fzRiTSQV-RJGd8iFei54 zn)g0i=?r>$KToAnh=CjobqJm_#lu*}{h$5GPyW?QdE0s@hVfFzFb*!xFeWPeV%3mc zsK1ay$uR)#cO%DW6ki*142O({koD>I@oS%(p1AhuS;?4VC5^yJ8dX*@{$yb#cZ{-< zgCneDF3v|;i9$8U5vwYPzz%SgClXHbXoZuc$vjRXXQfjn7IG54xF{#NYd$AAV4Q^S zJW)=fV94X;B=r2aILR#~BXOaY#-{=!xqUt(QJrrKBcZ!hMgnZVI~mE_f4@{c94_iF z>c@8;BgvjDjO0i(qLUCI5LW2uBpdTlK0=IUo~=taQ4AZo1};L}16<_b?+=$FnC5KO z!g54aj><(8w6K^y@>P{r^^t3&j_{c$%0!5vIBq6F$B&DNTvjp>wLVW9*)&fXQI&5C z523eJ9s*=N55cx{P%9%DEu>sU#l5V_d~j&C&lRzD3Ps~8a>j7mnnp8D|B1B1ftsK8e6nJl+6DI?dsw~ ziwB~?CfSX*h#^UDlp&sGWt!AZEV%+p->R7f*3*pn3*kZ=biX#autbTI2Fm%9M@*Fp zu2?c=n%}C3oNt>2jE{JMbNm)C+4r%in{Byj2ouvS4Pl3)1%@zTJN(G7*ECQBZFLzd z2EKlw8En0?f|X0!p%LuZYuZJPU^1F5Y661>#%;52NdqT?$D!=(NuyUT%I2! zIBbyD?mP2G)#S%iT8M$=mWW+a3c`(tNhwfYwbP;zc3MOsDMh1*F2#LJ9KyIZ)YSDE z>F)d)-7P|P3O1W41OUaJZ9;tSHDm~Ixh)jB>)WY!e(glM+rn#>AFIcc$z=H%`hV=+ zGM8U^?YW3Z0imefG^iI^eGmvjtPVzV(ju5jSubjPnHMcCYT|$j!4o3{#EA<$u$Bf5g@#yg z1^d;R3xX@Cn4<@<6UcTEH2Zi$YQ?kN-XQKwp>@0a^+mT7uN4=DyPOqVPAiOI!hLnp zkH{{`xrB3AmW4cB6JfU2R(Srf6<)?}`RVTKN7Uh-h$Ve)6mlXd z-^YV<-OASDuIRnkn%gqUv&ry`>6!nm<)7KSyO-$5Ly=1q9s0#U{j|B;i$;@f+id!gv7I2hq<$47}ce-bim#6Fu!3I}`43>#t>m*ucX zs=C}7^*b?)jO5lZ)`TFCanF`2gz;AsZ8VF+P&6DNk?RmD7Dpho$UL#fNVJitGKn@6 zXtl_zW)w<%qK!m}Hc~~uDF1`c&cX=ALztz$6S8_=9r2o%^O)~prAP-i>Bc= zG^9iu3Rq-ppHA37?KY5GmW`urNoMLS3{P5tMb!ck7{1?HTk=yqwP~JL-S6Cnc8Ohs z*RxrhC^JRWSrdA#5>#ic41?;>0rXLs#`q-7UpNDg9aP>-LpYwj8H=I{ORnHwCCKoY z{e|S_b$GOXJgIwUlL-rDh`KY)(MYwq*5;#A@KX=WR$4@BLE~_HMqAkxO2ag4M+hRQ5c#V;bViy& z9+kn0wQF&tj7VE;yc{V5_u3%fNSQ2J@V1dM#Hn^#j+8-I^2LWTZw7;nPR{`n@@lOY z9o|P0F&Kploch#H{8rK*WArV78G;{MG;nH6fm0&Nu}a`nhZhwv)EZc90=Wyyz$qT7 zEniuIQ`Q2ZgbJME6%cdKCaSRM0;hkSU>>vLU5tu5f2iRf=&v`#IFHx~eIv81U7zBLo#o zoA8ORT1tGSHc;CyQv6~QWHB$dg@my{g~qhpW|u)zehX@|9-*hwc2PK0#->Y&X}btpkD#x_ zd=)ZQz3j>y8L3i-qSlPiatn9bG6xUSCr!+ou^UeKfW2?KZ1Tpw2j1=7GmpIJAP;i6 zY_gwr`9?8( z-QdQWSH?Q2vF494R?&Q3*C!W@m0%+cW8qlWKd!OD6~jM`Rk`pEDI=bPa$YxgnzS!X zr{b!QWoUBztx;j5jYS!0LyWWuRW&M%l(i#_v;!k0VoO|*osvERl}9krP+5%BT3|xO zNO?t!w96|U$4Iq>bJ#>+q{zKa8G#B)8r!p|DsAc|1>cuHNeDXA&F$yymc0(&jnI&Y zD=}PDjuv9{EP~X2f^wsu?ZEe%zKJBai))ktj8OlSqX@MK8)JutgwrEhE_A+jYCWE9 z!l9G}1I6-?@?RlgV(m4^u98{S_DU&D-c`l_g<%jp02BUuyl?u!cy`dd6%1fA6}g?* zLojB02-u0y_dAUpM+1Xx4*^R#vKx%i^=qXCn?;+^AJp|qA9s(5MZrDS> z-r%105DWuCDM^KbDP?{S!I(C*?FU;QE1=wyWC$onE5Hvdp66({*PKfN~-wy$YXNq;^Q@HnZc1Y zCY}h7N0)KI1!ij^JboN~hSD1OJro{K)x2vK1VQN{u}eN++oiN)B<1^xjh8|wvzm3o z0uaDwGds%mK=4?|6nH!AcU(>Jjxv8Jw~uxwrhXj4;4OTUS-yq~_U&C<2xpxW58yK! ziEPy^ow}E+KDaTrtjXTuT`LryXS#vKw$|1}bFmLp9p__1L&m{)U)+}avh|ve*;vE%q4qlyk=q!BDq-(p!W8rfZcZ7y_qxg39 zk;PE@ptgG$is`jU5KfdKOuZLPREj@Zmn2|x9O`Q$)CZ$_fcq5$5mPg=d zXwGi*_S5Bm^tWmb0HoQgNbzeW*pv}BI80xAs8OG^xu+i6?m(olh)Bm>$5gu&4ZotWr{C4 zun510_d;T0j%oIT2EKE(W;gInWiF)`O9t(XR}QT1e9*~gSyylFQf@Y8$p|2OwP?vEZ~l0C)wN#nhFNorqC5<3umfS5&|@m=4IsgD4c4+W`Yyws=6Bg! zRW)$mhLbM5&Q#HWOz{Irg@Fj$oIKh{M)oCPa90cZj0aq3gK>(Al}pF3z9%UTEI}2V zD3#5Hmr60jJt&?1kXXoQeM<<~b*pdTpyqe_>tp+LV+!g-wnV)gNoPLnGj<7VbF6nP zFWrbF<*lyh-!)Flw(Cc5N)N9LlqaM%6o@)cK+n-Jo^ljfc zt?jQUKCH!$Tfhehv&z;`>bF)G*u!OXatnziZ#0# z?uD$`UP!Q=Y>DXb%F@e9)ON1(NUfD7JuE-=sXWn2H0FXT#Aox^twfnj*FmhV+8l!nhehi*5pbq`)l0x zdSyeIZ%t+wEVS1M)?`#US(Ax$0BJ|8$u5rw%|C`U8IysSX^O|;3Pnr|+fg_y!K_NR zDFhUIXEe6)f2R_SJ)B&7-@vhSc1DLo7eW*MyafqD-X1bt3l`3Dy+^R5BpxP&;5A~p zp%bac;Ih24cG=*H@tGl|XkSuF6-`1Zd5*)!|t!NvKvSp>UW(lNeTH2xqnX zz7q;Qc#Oz{4aXgM5UlyEsz*W(u2AH`u$hs_gKs2pY^ib?rny@dIBiB9JPZ_+l7lDN zIrNO{RYo5?2;6YcUeSEpmh|I z(dq`5&M&5xQ#CkFPu627oMur+vmkG-nD zQ{SykMSaO>6;ed`G&yJq8iDz^S+LF!cG!=F1d2aI??y?cm!>1rqJ2WkT}5(P^L$cP z?u3MV2z2S5u{Dt^FV7JrKf+LM>ofMkdV@K5E<3pv z#ez3n4kxY~wOKegAxhb5<^X~4;C8NV@yjZ27jF=Az~?y!i+^s-CY>RuYBJiRu5FUu zAXd)Lkr+$jq`qeBadaYE*dB;~u-N|xT3Mul{I79e-cr&IE2L|TIFk+O2D*R-adaNg zR{ttIpxqY_z(heG;Q=V9jt9t#b2J`M6Av(yof(Yj6~_ZwIZk~wF{UPzBeGQzzrrz? z4nAHg&|+&o9D^jY%rCgs2)H&FTc|+S_$D0<3N$iG3iOyXu+E4AJ(hQ*_CBTp4K_=G zhDo77kF=whq*R-u*Crp(45wOduT99#FgDbeN%F!2)`{5@z*4rTXiVO9K^gU@4oF$KMbf}Ti0 zPf7({x;w1jB2jF)P5}!|8EckIv!uiO(lwtFmZE+y1p&f;G-5s_EO9ubM}0~SGp;tA zPl*IIrBA8hd`gX~Pl@2!M(`;qUygiA-O}nxi9(sc%5Lx}b;)GY+mFpnV;Lm=u))w- zxr)@;QCAVtPp+cl>#TPbJ(13;Yp_j{Mk*sp=sI@EVMY{OMNUQ!2LWd=yMXh8Y0hyT zOf6awtUv_d6|B4T{|&pOc^> zpA%q`eI5oHjAVQWf76)!O$3ODjpA<-G?C;OzXViNsfHSdS1A`0FY|5JmeylpE55_! zRKP9RJ(f%QbE*T6k=M|zTBRbci_elww+6v1Xp)|yhK8ItG?qI(n9j~{coGM z%JV47Y|FtgInzQOg?{N7s!WAPWufrRcF8v_WYzelXGLAdirT?j)vmCj67G#*Hh#luTXSW{9J{a6ZIWDokz`?qr2lE zXljbiCLA6w*Jo*eAwlaLI!~ayLU>>xUY{3_)t7PQD(i->MWsPU41^60J4ONrnc};= zXrv1X8|ku-3aT8EupC%o+Y%jI&YefF=n78ZnNP1MPZfHds*vlsj#@?CSxKuCRa%|o zY}LUS^li{hi=PogqCGg;m{a#{2b8Tqq;!fWF%5PmT*Hj@V}5aw7WmY8(=C(GOfkrb z6$!>JtnY|7>Zi`2FOF$_)m_;K4Xv9_?>5Tdk=m*( z-+k;?HT&RLzmk2h+C*5sSF#W42nF;!lZajrnEHu;k^YBCN+}Ze`^Z^sp<*$M8VK9R z#_e7d+Ip&sCtY*Zud~(S! zH_E^oxE5F_kF|h*Me%pa7U@VyNZ2D)DI@wAj7%O*((jVun+M4J`1%XXBXHQocw_Ep?#`e86KRCZi?mHGoGybbNBS+d>K2c)l##az@Ue&xH}V z7raNQQE0)c69wc^YA)hY5;Xg#$c~oH_uwzfwnAphXpuS+n9DS$bWrP?115BrNtb0J zGlL}3uv`&wFo-?L4KhY*_FKH=xW?49F}aVsW~&I{z{KGeez?5>f=!NpmCPS=TO6=m zF47zMG95n6#kD&C>oR`Q!bTyVrMKjv6*QFuZDZUc9!YeEiPjNRAa5 zPB7`72^(z%)6UQTcUcrq)?s;4H`$_LqVG0G zBSWIl1rTZ9CO@J}u`hp8AxkJ3;aEv=Q6tZ6oTnynIQJymEF*(So@Lq9GNeP|=;>v~ zb;mGxSqx)A#&u~iUQd^1pO2aT4ZkoafH4N%tYlnYR>`>TzDw8LQtT)K6t*M*3WIh6 z6sx!K%VDtDJo&k4q5O1woz!(FAV+0immD=z8IgW1$x&jyxR!FRDn}PnGbBfCjz(G{ ziVi%q#wL!^*hKk>p-?s%QEJr3DR!30_-jaj@`N-=u2^a4KyaCS8S(_flNs)DN>vk; zXqQ0&sfNfc!;!sEz=E1ysxkn{iAAL9gu&@?NmUKc55k0X1xwoEWzj%ml+r;oofoRd zIqFibS}XsaLiLB9%tF6LHhjZ$tZnFUBT0RIjo5=tZ!;qcoBo@gw}-9P??q> zsx6=^SZl$NsDtgi^@^1choQC};CMON)C{9~NN7ZOnLM^pouu;EiQbVls$YFs9t8&N zB=+MF&YLR2dE39OaGpl~;neFD?|o4A5vEn~#SNIm5wx7w!7@UU;Ev$X zKZ<6-0#=%Z2{J8}&@V)0CO01Wz*qk0gR|rSN`tcGl%!_1eW7|G4T{ANv{@Btcw)eH zMPJ)`NKa*#u`*Ut&XB=pH%j(G@B3t982;z14Xx?ft6XqxYdT^hj_Ylnu+z63wJ1o+ zmlOe5$l7GN-O?kLa;3`Sl|1TT3w_dhJ@GtB}segA_`%7xb-pNzwT=h-}s zF#5p#Ve=66f_1-arHj~Iz18%1?XI{2=G$G<6STXgc#9TxPlS1tF6wBSe`nJ${NtKY zV2h)OV`#rj%YVC%fXW}NDOprKk6E~+t!>cPM?jS4YNz-z5i(}m_ zY`Gp|VO#R*iv0W$7hPBR7$DlT0B9ShXURPcN0%9QB8Uf5`NcSwoTQ}Bajq^h75rs7vz^1aR!+3JFOQoURLJ3Hm-=9Z!xt4X)dym! z6T^nUn`<==f$5OWJL5{YS#xI*XUjBQuGqIw3LC>;}9^_ty-vU`L=) z!ZG&YC9y&Cr!++ji%QeMBFx}Bnz4DY&uC5H1FP|{AK7WAAu;iHvUa)%>MhW&lkXhu zI@wQD!YDx%_YYNRF#k|oJd9crj-(3#6aEYcxRHfFiS1dCAt4iR80RYp$3NJSbnqtm zJc)r)U3ne|Rxk$l0l3GQJ^~>q42t)$5-JP|Y(HciMI@-#CV45uFx~I>D3gcB{L%9m z0Shr5Xd%K}uk_q}kbB4c%rPuhilI?#pNNT^3v>+gWkj-zDXhw>E65N^^8rp`{gAj~ zB^qlY5@*dng^oUAJuS(b#FUP@*F-?l)ouvHRC5phElsfI>JRG{&$mkFSIZ8c54^^h z8=FH}!m#v`k9^C3ayv5_%c9k3gKTU!b8qn{<~cJv%>I?`mG?3NPbgDif>8 zc`RP=1SsfsizwH})LhdAK@Aow-ZClbA|U1mHMr&aU>S4ZlMSV4{T9@)EX0bZKAM4G z9)*oMRc$O2kUTwV&V^o9M1Eo^HiuAbn9|i=t7&pS8I+pRbvaaOAAoDoqK+K-vbv#QS`32opIgt zyL1ZF9an9)U+`+fK=V#B%+qdSeR~2_Dx&cOLVFPqzjL|T7 zkyQqz|$;`l3e!sP_djHg}Jj)Du^6bj{T9VdmSDpeprxa=XbHAhr1x3k8 zVfv8!r7WrJ;ug|DgyacTJn+C}UI0t3k$6H{i4e&zDrs4FxjkIUds82YNWBClua3U~ zsjHU;DSIKcHCnIgEz=?Sjy8ZLmll7kkBfElT_U3ONo_&Qc@1?(QOeekLLFRtQch8- zP(3KpOOlf=rAVEPl2ppnQ&)eNewUVik}8V1)Gb6poulb+7=$Hm<4G(lQ)=q*`2wJe%G({IN9UJYlGD{8)#jqhtY&Z!aCCMhb{sGXXG zk=nLZf!x3@k+kKaxuSUYFKcGm6RzNBB@VvTA+SH-+!<3p?JCWWkN&cXPdYsCNvs#5 zg0u+$pu-=)hm&qxZhB=(VbLmUlcmdYrG^t)c;Q0No7$m$(hX0uV}nzITyN=dM5}z) z!fAAUQS%5+=R=&%#Z3G^Om!trk4EaBtT^ogY^qK}V{fsuqnxxj?Gtu@w)4m zsqPt@e?Sa$rR3V*%C*T;TC(3M^;m0@r;IMPT3u|9^mnS!<-u0H?)T4@#~ZN>))7Z> zE)$zA*CAaoEPhL4W;IPlmy=H9V(6Z)G0XUkzWjse%eBCQDZ#5CwMxPkuLY3sYKFz$ z9Y9NT`z=obb-El?&@oJBVoW4gvE&j@x>>Yr5_V>Y%_0us`LmdxbYoVODWpemtk)EW zvshUYk-)W-s(1$_RqcWqtCXrZHJntHqA?N}3vFw?Z~CW z0GMB`QoVTpUwz_qrN9F}lmZW&%$t|5)cLC{)mz1+rNFCW_mnY(|Jwr2r@$j`4HcB< zRtG1E$A;i)thvr(t~{0lXB(xmWvVB+Y33d)w2bI2GshyWfV_e^SU?&6s=Wl738@OK zeYth5P6LxFsYfrR35!>dcX-vHn!DBZ+bfkRCT4Y0o1$2c>2v`s!#)KbQD2gW&a8|% zXJ=mnjj{5e>yqZR*uwX8*W%6(GATB}kN8vm#*$svc-7%u<#_d7p484x>=9(Fhq78b z`?Fn=LdV#Km-p$D?lHA_lKPiPH)G9HN*$TZ)dmxyixT~CQJ&sS_?FCqt?pwV44MA0 z+VhTIe(S6x=1Q+xrayDZTc$s9JwyNpTezkE&@H_Xfb2kCxiy>}yJZG$K|)AHE%N{j zED2yzT+5`Xb$6Us3l9^pFjF{nhX(S_opGEFk7ESzDIH=+Sl$CfY=9s{_UZTxn>aHb zSUw`eJ@X$%$g3J*yT;h?#o63MY_L~f?exu9 z-VVB>s^Q!ZzPY;kO{@qb->iJhWoFXHh}#fET&5M~#dXQei|-QiV)ypL#9J5Ok z)h^)z`nGq;^3)uqOC$jOBbQ`2WQ&ou`)_fuU%fc%W@QWfh;&Fpin>|5HPalaYB@sX zO!7ynavGFQCL=>@b|z;XXqr~LORh^^XQ4dFT?!u?Inj?Yk%Es$igVBdZkYY0OHu~D zD3g(Sek^=}dj;i4V^F6+5%be=%q857`!ew`TuxRuf(gZljWT`47hnf;YtypI5xd$fPxi^RS8}- z;N_D!wgfK>U>;rs3dk+n6ufG19tW?Q;Pu$FVI(0f*BDqJ34EupYJ-6#YOtaEeR*$WMHUP5JohXq!Q<*J=`6<-@t_5uY? zgj&UgFip~@!RCwF?tTw73Sj$0zVkzNT~6iM@24?hf(Y3?-X>A;IMGHb-oh{H_^asB z;w^s+pn+P0&ubdGoScogb$J5+s~+;8drmreQRM$^=P?z@CPsQ+3x?(`=VRD6u!wW= zK_B|!KYjWfxm2U#K~)1rZXa+XQx$#OMRyXQ5?bCcKgjc+KmMV8`=;mqVfCyw~jE=j&Y=xzibDs#e%9$r%)Mg&p!pyS>)6BDRPE($7+FjQ(`RtOOV!J*< zDyF4er?f|wy}5Rmk)DZZ!Ysyrq%?2L^x3%Dt0~eNo+<I|VP*B;Q8a~=v+YHpRY){Uov%NBUs4KdJa6__j2xy}h3=E-K3}oq0{kV-C~mdKI^FSX=_$+m&w1|D_n!NL zwd>D2f8Fz*KY04;XFThiv!A`@ncp*+FY7H?aq4Lkr=PKM)mcwFvr%VBXjvbz1Hcc5 z6Mu2<0)y)=1^-Q42df$f$@&WXZ-XW)x;L=jkVo;&*sUfo2DF&I!KvD@ZOC}#ptTZQ zJXJASD=pA_mQ!qZGN-MTgGLY1rj6@~P|ufN(mSt6_;npw<9K(#H@IBcJFk1bE9u9@ zc|70AHUp!h97NUT6L5GkI(x0|V8tNI+3>KL=SI;5R@CrCjhQu()knwC{*k&)tpwp@ z`T)Id(#Unhc~1&Yw@CTaj6&xXQLWE#Jis|9&f-1qJdc}kFdm{JB740d+YUhJP?G}C zu6vD?wnd0`ebM6Sk93MQm)8Nm1q6IvF~+0qz&z0Ly6##}f9s1iJi8jQ7$L*+WVkpk zGF(@5X<#cS3mfkqX{PA$Xp5)GcJapl(=+27S-P$`hliVa2#dpYu!LX#QE2hYs+HF{ zPpjl)uM;O*TZ~iXhXD%^RwlVAhU&I((1?Tj&ABJ)fOWm~-F3V{V}m85&Ap;{F3tUr ztu=H^n&hrTAc*sdVv0wv<~?I-ItFw%Zqbqa9R4vX zkLKeG(R{o(Q8X8b`%8+oeCp*M%{iM(XuiY{9l-^%3&*?p@=JR!DV{~mD-3>)KU~~< z7OR34-HjzokriD~erl$Fsu1Sc#nX8FGEu=N5H+0eCW=GkL~QixFE7sG=@0N}2kE7n z7pO`X#LNqeoX0O+j5=Oe^m+9C73w&@d!DC`3yVpfy;vCh`AF!IpX#?E<)p&eP@K)v z%Ox?;xlB@DSgfY#GR=E@WAW<_m9_FdSF8b?m7~G79i19*_D5j~Fu7*ly|nlI?(;hN zsf-|B&L0JHeE98m-}ANmW>H7|!4u~dPv;AlPz`!}p`_ny%1)IXfz3XHS{J*SfKi#w zqhW~wx!=X7t#`wZujxMfsK8xDYtu&q?&{(c9v6!NcXhFxM;j`@WllYCpI)5Fv+r9J zxV>j|S3edc2F0nof8pYgIE_aaFf%7U2WNCoKPH$?D<)_gP(u2vn0U+-Zh8Y(5`U8Q zWj#oM3L03HbR-1BEnLiXb8+t(#p$%P-XT28jp7V`id`wght}aH5?|mnl5;!7`8v&+Zh@rtlnB_^gicasz9+OQT~<8x2qF6Ae$C7!7Yd7c@L^Ni;lhFxE*AK28e~I=Weq z5I|0{Pkpx=k=~e^EiT??#`zpGk~`H=aA|2N62reei;@i+CZ>q}!d7Qyk|S_83BvpM zS5Z1?vwmJG^P&HO7E)Rh#9Bz%Gp$PP_vAaXp9}wJ%8JVG+i%DWO-{8&PP15?%7!0*1XX=S%E5@+Mt#Ib-il*_)AI6Ll6* zEXmaci+aTt3|(}3kaTZ%LX-6eNh+rtwnVs7&aMd!^BSs9NZvB#KpM2Jq?9$?t9uwt z@CXhttLWpX`Dka(K8hSgwTIwoUZ>46FtabTt{ik%VmTcv(C0flkr3UL1BE@)lD-Cg zGE>~|wB+*CQ>(JLo^Xr4NuY&t9)_h4sMGS?X~rs#_-V#hIi>)PTLv?^GI?@jNX#t% zFWq}cSo47bIDKtT@c^Eka}GI2e;5e9Rfb`RHM% za>i?-3$c91H=`KDH?D+8HvxgE`e1eoak1arxc{g6mASG4mPKc@DVgM_oRU zFbg)Z7C=#%SS-=vSD3)%Gcxxq7n@l5HoOmnH3KlCxbzvRQMY@!;xnqt&(ZLc3?KBf zJQ7|zGmW=ES z@zQ%_T;y0>5)y(~CS*&6Vp|K!93aD@G6zVQ=9A{^iFuId>bOXoSdsF}MVote7Y}Hr zS<9JW+f*)bhOQ!re6B|nHRVgex+YDCLphWyMqJb?$tk0}Avl3xT*DuBo*VSV`90Dc zmB7kf@*Hu2-k??}sb~L@TZ93${nbEScI>673yKe52mKm84Ao;{^XMDZq|b!CXQb22 zTNvqMM$o|WYQa8s@S{I~MvN*{u547(@sfH)SUAQ~xQ)hUjZ~Wm8`Xvf&^YuH$k-JZ z^6LwL9DL#rPkeYGbt$wKH;z%)cl5Zxf!3fG#$~$kl9PH|c`s+0+#w^lq4puCj1};w zfE#Y$}RGL8^Hgb3YJsUEA-6fu8%$t;#u*OY;`dp{MB;M{R14wTG3}HCdwAX8cw)fTbEu23QLhf5E}%2 z0$SPjqQYESiFpyCY`Z&D)_!`6qwGTF+WLD3D>MzIs+;j{#d}^_{EQsTT}vDn73@+-45#iJN03D}HLG~P2y@Eyw_-eUby=JRd2e7>z}K3{fP zwn9E%)Ph)tbk@ql=1ft5gTNibA)SmjZ|+A-rApzKmWOnv*4g(y81>cJ_IFNa+xx}K ztDSB1Q+Qyti0L&da486LrWp>7&s*3TlMZfSeHOg3^!n%%_g=(%;LW5vrjuVJ{WhEw zLd&ecl@=YE@^DgkYcW(#&(!;vm)Gk8<`1~v;EFC34xTgs7Thvurj8=dc)40~*+Co_ z507w%340dso?%hRdjOprZCY>}6(a45dm#_f*+tdUJR^6Sr+}x^Je_St2YTWc5AkX= z6b|&{xeN{@v(uf0yczged9>7i9$6+kUiMx-W=x05xjtxhkUiYQ!$cbx-)$MBtU36*p0OZ-}RG)Yj znG0-9DTvC~@f;Z@rGuJZ3oS6GR(2atm3`G<`g*#SN%6-=8{3aI-mJI9lIquK}cBehssbr@~r6mRvcO~Ku&XPw00)Zf>WZ4amR(&@ z%NNi8nNx}vTxva2iV`69czq9wk_uC8d@7unSnnU~WHHw?@b zE%mkR>WY^6BD=bxQ+$zKUD0x1WLH34V3a;{>HChshHez+!=hx*=U=0!X9PK9kf6Tv*$u9_9D4K#5d@a#4>WsOI zye-~CtIn8fdjiauD?U;+=HhvhG1o5g5~*D=BQrjf#$2fk@Mf(+LX*d9%v}VC4umr1 zYGW3E78-Nwk7>-6O~j13lF;T|vW8^LmB|I0$D3+t9cyB|4*{LC^wP>o$m6(uEWS1p zjBY9dl0?X(eaX19Mv+IoEs=$<%g$2%wt=8?d*os}u|N~&5#%al$ttV9MEQt89f%EM;87)rEFlJdi%qOUJlmGRZyZ+W=`#6? z;udcF^eNC->d7s_P(@6Z$jz){K)?~=*qwyGRNX2p5T&CAWdu=5kJ(ez*NLGiI07O( z_*4k}wnV}=;CPxdQmlpzbJZ1>}P!EZ#dWZ|4XMYevp<~MiTT4hs>72o5 zz1}s0d>e z_s5o~QER`DxQOm1%R5_hyW&{&MEgObk4r6IJN>96m8v}VATG|u3dIK{M^ZJR7@V-)1OhnS!vnD6k-@?*iDqf2q0abrEy5dpwrRMrX>=)vC~fUlSU7#_uW5}p~`(ek)L|83EK0$)ue=0`US&ZB?Ge4*bT zOX*^-8vQ5Ve!oA9U#|ps`qx1ccqwmvKo8U9gS60o<+*>-@A&*sBhijeFLgyM$cOWzaq)Cno}JVt6uu^86W2pE6D?qT z^ZSUj+0}S!!y?4=&?%ShfCmN4mIpjQO5&|#AQ+y}pb$Vj7iNhu0mIBVn{UZd;lA#G z2krkEc^Nw_aoBl6wqHdz7aVXzCvAftooH?B6Q$8C-tb9zn9NMZ(0Y{o@LAKf|ucz{)H&xl5t*~{=c5tCz zm`Mm#K^jBuE|cyu<@AU3uI7cV@G>s@-}{$$))$-v5ex7@51+!Kp5Hj6D8>I&Nm0t$ zhF6*_lwe0XKEYCyq8+yTF{~z3mgm=6Kv|dPS4XB`uf}tnH=O4ev$JbLDNLpI!KPeZ zZ!@rMGU%dJ{50!n+481z0eZ5y31o=J*9#U|R>D zh9S6Q7Y(zv=_rU$wetknk137ozuVc*iElU$aPxecWxx3JQyb2s&QH|h5dWstlh*iV zD%n{yUtHX0wtC7;Rx7WK)sU}!VD^2ho-R^Xs(ZD%oB>j)P{kjP<(@g(R}}g(^5(HW zWVWR0hmKu+YVp=#SjYnjurQ!#WbhUd8CSXmKN}f;I#ONMpQ2W&&R*?fR%c;y%=+`E z0$;!hK?$$Hy!x7tgxS!PcRswdMk+rd?=2Ybh!0#~y2L*1LM{CwBepKAO>~(<{LzGN zc@8^OOoQ(78Mow(Wa_gev>ZvH9)k@P8Aqt8F8ZpU(XH0Tk=zsEwTFkVJ%WEl>t^_P zRD6B-;vI3>^6fY;eZO#)hPt>k!$; z!`u6ZbqQMujj{1N+&-iV7sUD+OMp;%WcV5nAC`~#>%*sCwObqLTpGZlk=?Fk>K*BD zlxaEkgWP)H+^csa<)VUv8iP8PY{+AYYyKU6_^uCp$th0m7WW={22xqQlyen1{IhV& z!}$Axi!ds_W(G>sIV57_4p?wWfB0Rgsd)KB1Kq+!pPK{Pn_ST~;2&MXO|1&Jsdbr) z-Su{^dMbCd$~kAqt_QgahQVij$bQ>laY^=;gzur&2r_gXg@GF|C}@Vq7^@ql&Q+-N zUcx=PwD_ha{g$cVuvmZsT<3tLY^F)^Ar&PXhX3*OE<3($0K=1`-T=h19yOO+d1X;y z0wim_m=4!mzx4twyMBYfq2C`J&XKzfoBX66HL^D|JHsZ`y+t~py$6eQfDd03`G4Ae z&kkGd1;7~lIJ*@2E{%?p#oiE-cqAtj3aPE2=d zmpHQL9mO8I&@CV=@6kx;R%)SJ+QGtGJ*dBP1qbxl7OIW#2(bHQF3_uf`AXYa6+*Xq zoxG>etxg%bMG4LbxCv$d`skyNj_)HrrRR=fj};9SyU;DjBlqlw4LoAA7WI~Kfutw6 zeER)=3_~DD#_o!_!%_AUAk&Y5S0Y=Sl<7p!OHjaN7K4CnF__9k;Da25DaPffS2=ve zO_0_WE~l6IK^np*ixZHgO}Sg>v8CwHcYEb5l?ydI?mC*Umi?Tza*<_PkyEwGgsJ~E znA?}%@S9&eRfFUQ$U>~mgiIXM4>#vzG2j)q7Mr3JG_=4*ea>#kL=RZ#D#CGX^0`>| zYm?9T>qA_NhmdG#_Np`N^#vFN{4G#cHGyJJ%cG0vY0M`Mq=-v~Cx1+eGe&d7pJ0a} zE@*9{PXI-?kIe)pM$5IyCzuIZG4gQW7js3bFcVs0*?M38BU@r6ngv<{PNF-cgI{AY zmk-6@OQ-yCH(sn5b6 zfqIqExT1rS4WNzAn!c#A|mYbOrl@r=VEgw zj|ibcelEe%`(4eLZqRkP*qB$X_qpV{~C?G zIXrYCBxI#o27sLXMpoMOpp~1fwBLt(z5BT;cI>cLq^xr5*&}2KtINalQOzCf6MKI} zI}mO%(fA963<9l)(bE3NfoGN-TW^oNqlGu`l-b_=!dun=x9}F!7RmO8LYWrbne2Z{ zWS#JdE+0%!dQ_M)OmLc_CN2RfHP2=MIzPeyq}c;`+~oaTm^@)sW$v7+aAI>8-g%;P z_xF!$?tZFXbKbl}XYYA-$pS=!k7Ru_pNjcTI6)3_RJ@YW^fAm>Dfk*JQ`*3g@}jXK z)Ldkkyk6m?9Uj3SLgk7XE0GyX+>2!&TU7I!Gh>N)44ViW7?3Zua7rDRK1jkyA~%vU z6}at{m8I=u7>VX!(um#hrn$LCUgQ=|Q`I4svqXq#bh3<%wduS;J(ZGLmKqS=M5Sc8 zTs8dOCB;?q9wQ<9P`M1kKEte%+fo#A<02Xmvo2lbw<3lBr-IbA#UlmYqR3o6&9aZb zEOpJ#n*F@GGpApLmJ9N|W^av6f_c?nX+phBV+Alk^+0nTX4yqI&QUW$4uRkN}zKO8IPtcx57 z8ZsC=j22kTfWgW~PA(~*Kg%-33>cvmxuY}yab;)8Md8Jek-ZIgn(@y(R#cG+&+?2? zaz?y8JnbAl;W6ZoF@(iz8I>Wt*@iG|dr68&$zKmaMgM;1UOM6k}# zSAud37_1`P&$Y=1hPSLSY&a|`1QHe%A=1SSI8Q1739Y%+>PKThM)mn1v-8g8gG`F9 zzEx>Wnl82hze+(su}0C+tYYWGHOlC^rd+w2{eT8dgO=yeuUxe?#13?Eqtfu{wXIHI z`|1Uh?3e_kcPN$#OM=4AsJ8^@KJ7WPs@S7Xdvs)_>ao#q{piSO3wI}Q3A<9S%#|ep zYzrkqQiDK7K#P3c?-A@hMN3SFyQ|$Lr<*MO;_M%VxXvYSsC&vN<~nj6!Q8M$FwC{c z+d~0y*%o7?8bRFSSk8cJxkt5fyjptu!QcnyhaV}cpdlD!VKJ1{2=TDn52e`(cNkmb z!>!vmE7<4;;jz*Ga1A+RTwTS*ArMMjtO7w;z;_H4L;3NeVt8W|70u%AG9!@ciQ8cs=xZh1le4)hWup4D2HqW1CO&ki-l+8jOUs-(qEed0Et^!%_ zuPpx2N`l==b>95*s$=F&^dxAAhHljcR=yoHqpFEjnT(PRh+zvC6@O9W2Pf3rT{W?$ z*oLvIhVVMf29lOI`4Q1xNV*UZtZ#gfFD_#~QbpSu&cMFvt0O+u zU>X(HIcO~MDHiA$eM%o-U0%Oo_=VnGpJ4vHa*U3p zq?GEy;|VPd@rX%f?21*^TAP*^-Kyt(d5Y0}p-gtKK?e?7_3-sviWNjL)iQ%P{KxE@ z{qj@s)es0I%Ss>)G8l5K`0Dqc)pTL`O7G*dD;**wo2dp$hL9bEsa#R~ zi_vRBGNa;G-YOB2Opm`|WAPb(|47P@pM9G>$WA52O7R!=1M%W`Zb%h$QY16Mglh)P zD~f;CD5k|4B`B5b;%#qN$pr`!dG$ENsy~uEoGmYwkf9;3UVGH5*EX+S+j;fiR;5?3 z?GiGyt6n{&Rta7`C1;RVuU>lfDDm5g>cOk01ZAE5eVD6QeABadl3j^)R*M*o_5VF@ zC&w-Q@1_X<@ZZ00|GWE10#fZPx)T;5WA-R*7_)8(9W8#7iD2u0qq_CK;kN#>vaqfH zxA3|mPT2cTMjO9XT8pBv_a9fb-}_Hh`Jd;sI$~L}Pl<2&0@R}*0^X(*igIB|zAinY zg%h%!zen(by;DE=j?598+!H=2Bgsa(7vDH&uhgR})vKHH_R8#ybek<`QkobOYztoB zQWrH)R3z4qga9dPK&e)nE(8j$OCLh7mD2&?tEEQ6RM|O~c|z~96{hE0=}MrMkJ(Fl zonhIcSmK+X_;@F{kTeB-m`{@qjT%~~sphZgimvt$wR2p@XeIZ5_9s92S1;uYQc0xK zW-mnmGfEO5TjBtvMVE+G=_KDWhj7`P#a6l(Hu@K8G67azS`*z8o=h?oCa!D6gF^&B zC(%+?h;UdyXG%Vyj!ON}3Gg;Pu8bniPAh&J6u~=|y(=z0Vz&u}f2g~FMZ>GQd^iSl zY`k_MA<7D8s&89fNAsWwm~cZ(I7++T8y=hi#HI0$DY(M`yc^;C1Mz5jyp;kW+Ny`Or=ER5GDhxT>A#COL^4Sif6kc)pzIuAW2NBC96gNzzo zOa0e0Q95YeDq^1{e~&$L#q8^QdGY#RpfU;}PI(2z1o8v=x6>Oz{|>Gt)I~c`#T+5T zxl9K4-}w*k`NGF8@E>Y15Do&c;BKRmc6K+Yfklnhp_(eBfDcYcRCK4_II2=FK(_b9 z9OS?)ByzXDUV*D1IW)f58dfhE+;bKtbPhrhz1TKdfFKgEb3H@?M#U(Np8V}6EFe5t zn`nU67v%sDt+c4STz7Jrdg1}xYD^nZwH3=R`rr~-!MEp6FBn8OP;ULlwK-GkSQQ8( zphmr-D1i3DEtz^3?qPNg-9q=%HrJ8GCXi6Jib|Rn1L5h;vOupjBG&=O3>rSrpFuD} zQNTd>Kpt4v9W$Te|AiAmUfRh?O@^-7xJB$yxCRl};3Lt}Ervbzn7EL77d2c!v>B#? zCW9}Xo!(MToSr+ddRPmz#%F~Z_@`f5uOye)hw{UcDQWGDQp&K zhqQA>@*W3m8jc|2X@_}G1s6nAD-Ih6H<6{@7?87j=*j53F>RR2YXza2{5|5?KDP&x znM}-Ul2)tjTkMB1dX}3D6pux8kwt0+_2k{Z;M9}(>QzeyuH#d$Ho5UW5%o&S2$bek ztDtNV`|&TtQhhR3YER}71_SMj=3wAjx*Ku_2I%IM^gf%s`#4oto^NcmSD+uXuYQ#)C&BfA`gj=voj1Q@tyDqJE7n%5)(}(xJaPA&nbc}=M zR|m{{AE>0!QeB{gn+-w7aI>YvQI+VIG0xoMp2%V{`4X7DlW3o1P`06DMe)!xr$FvM9M>>*Ov>mBUvGeK%X#W7+pN?;894oM`$yr3Bq zEVo0Xcj=zHBGNtR#ZR`kc;15jZh-EpN zD$SM?B6LS0q*mM?FS4^=Lz9$YR0pwsP>pD6{?a@XA2RqV2ZS@lG+gEfgo4*y@P+WY z&^M?p)+;P64Jnh*20(NTW)c7(RdyW_xE>*K=Ti2_|KHyEz}Zz*_x_%9@64TD zqP3K&z)(@qisIj*qA&gPQBa?vwMx;F_x-KC_qpfZxiew(gDtH==bp3A-fQo@_S$Q$ zz4qE`L(C>WG7WKke1RWAqx8l{mAg8!c;V9AC@cnPl8W0poSDdusDTs(CoqM&K*nxW z)op~(V_KVMYs%IsI}uzw)0r}YK_BEw5OcgV_FbK|E&)aj(N`TRLJG%Nl)UF?PI&$p zO`12=vwf37MU}hbST|wDh`RLD6l;FLes^Vk5CTx(7~&80rIDfN-arLN7Vh8C{QC;G;%$fbpLDGrtI zNobOoLA;Jm_g_{ko=qP_hXH(#-7;^L%m8K$8m8oBuj)>0en;bKJ(D^xBknOQx% z2=iE(QP+ID&E$opY`#3uVeeu4tLc$Zm30R|1P)N z(<_T67OB$i^cbI{jZr0aH98%bCqNb1=1)GKeu;A48X zv|28WjTcLMdM*ufx}_bTOXEzVrJbBhGovhZJU^EfxzjeP`qV3L2pe1Afpx$M=E2O` zwy4!^372G-xqvp5@EX}N3U6PAB`L}mxyYpeHR35k)B6M~J(0;Po5nsZqqIRGrc3EU z_0kxI!4y_4fafzGaV6KR^#MuT(pcIkYq7`nC23kK!#m0qVhA=ahl54 zBSoelDupglP#B|H6zsq!7rLOQ8t!BGSE2-9=l2%$o=ebqFpyu28W5f5LJH`kYY(!L zPToK?PDI?p#a$z{2+|@PCrs2glt$>1ak-{B*hM0zbiRsxpl;AHSSZq4?Cc$^&T5rS zJ(v8S8?af+`asA!J|`9Vx~hH}M*TRoQ+!|b*z}FpYr#uh)#K7@?HNOP^#@E4`uZhZ z76IFMGCALBGO;(Kd4SxL>X5oEN@@RodqSIx3~xdnnM=$e)^;77?=BmD`lQ%4?jB`# zec>dn5rEL#E;7duA$iSITt?gICC;$U}xtMXbL&6$b zIu2YyK-e)6?KNV?E#gXRjp5>Cso~3arTvTl9#>u4DllSpXr!zErp1R1jAEWBDuawb zA{I{B9R1U}>6(R*3%n&=K;cy6hOt&t)Cd4_$!+Quor`*>W@EgsWV5lRy9{XY+N2Ov zQQObUwlOWPH3=mQhBRbZP5*`4mm)v3>;j7zcmKXg{YSD zi3`ed#?u(kk2jtrH=Z(hA9g%TZaj5x2>S+>@uutYK^*H_7$FF@3s#E$^euEp5;tjY=ar&OGew<+T zmP zZ8r=bTGz?d&?T7xT}kq)UC&KsE*_{%JXjG_yc-!|{0UxT$+F3nRis;bWS1+f7U}S7 zH#U<&Hp0|#e+g}`P{8^^3!EtF9pS!NnhP&S)b3#YcmY?7=&6GzUq_Uludt`*H{RKZ zDu%XC2!FP&k#@_M6?9I`&`}pY%2`XAr>P<8>~ya1#i}wZ%okxsg=JUgM>-98QyN#NUqz@+vBI{<(YfS+uSi&cj0W3jl>Ue_i&O8`Q&-^H3%Vuk=cdlbDg9KrebAKw@K35^z z=d$-^Po8pmvo_h-i0{g7b|3_pD8~HnoLS&8vJxF!#j9JFC6wefQ1XrhI>D^Q%4+~eh!(Gh|Io&o z*F#fdIXKM3$|td2HVx7l+0SM)vB#gWsa-}nfQeW1l@$Vde!N{jVmmxfxTH~$*^>sh;*TiHm~7D=vYui0MyFlR zM~k%SIg4fvTkYu`koqFGGzc5IrGW*UisGr!(|SuouUNe7WxaMwgO+-5kHjJGXk9f7 zd<;c$)SxgnAel;RD)XbJ7UiNL_*$81VUD_wg9dj1bm6gx$*O0azQCd7pwVLv8U;xT zY+H^UO4C%!)G^kVI9UKgWZ;mI;Q_MXHjh(Czek2?w+COe3uVaP1LwlQrN^U3MtNf@ zjyfR7Ik6eYj3p(eF>`XjsPT;AcDa3!)N9AhB>{>eB))Jp1kMiKB3197QIz)x4Vc3- zpG?t(DF%?(M2Hs5nE$=l+r+Z<_iO(|juK)0{Q>vJ+Pua( zj%sC8fTDe?&;UKT19#rkp(=Bx4(5rVNx&S9 zf}~otl&&U~@09UQjxVtTG!Ns^jufV-iB}9E9Q@@i-XsG*?MKGS`tP1**&Far+B)!$ zv)Wq-&$H}4WY5~5$X;d}5KR{3z}kBQw!LN*$jqXD5_@e`9X>79 zL3@o@8efq<6yBI^=5d?`uGfaVat}PGlAxUjXw#b zOHUemYx03mj~OYV@D;poH8vX~AQOn9&rV2MM%7oOH>p{A>yn||dt|$vwxZ-AUi}V% zwgGIIgHxLX0i8x0Fh)oy^A}-bN3yuH`Wu+su>rdLj|D3?pi^UwbWNnzk z3JSvVuOFq7!IK+DXOlaA2=_o1Q@*}pmFgAw;)&REitf93~fMovho@Nx6 zF!N~#I~In)c_o#VPm+nB3j)`|*M>Q1SXm!mAXBIN>^&KsK(me*%@m1QUHwgsU_Nid zC4-rSG}}}#Z+mjBHSVvr0hpGF6Y1!OW4ebMYPho>Y8SA@c2OB{23URJv*)>N?_zBE zP|iMG^>?j_ys>yL%5gD^s%?(r+M!Svht$ZB#%3J1tXYUEr!662Ww6UQF4QQF+lf+a zd%>_P#VZm?tEfsD$E6-Dw{WZUTRD!)DoO~kU_lfsLjAlOAlE;!Kj925!ETAsT*#d_ z?i9zBl0+86hd8db_cLWdu3|NZMPb_(QU1g!UxZ)dxU!55c8lZc$wUvma7#a`v=EjK z*{JL}j%&*im;GVCohz|T z(}Osaz`3iZZYnQOx8sebJiqJFuYCP&_%ed&O@!c97xHTgW3%QjBM$KiaR}qDNt6(| zsn7;)3sf8LTL?>2s9wc!J~z*n`!|VM4c&O_yB>Pr3!8ooLelH?&V}(j$j4p}eEVZJ z{@~nS(;exXzJ1d@pLp;~H(mSN=k+;%$2s@)6@5K?ot?e;^MCM$H{W>PIeoTYjJKk= z5j#S2{ECCjal@C^Shj_6OLSB(3|N&M`u6)D{rtz@x9`_{rGNeXx4rQ?HA$69{`}Ps zKL3SHq0-yj*HG!~AK&|p&wgRkIekw7F7)=#GGwqcKB&E1Dm@5WJ;N$xbyIyewLZma z{lVKm`{{S=|IA&5P|XiN^_~yj_^FQ-d_9kZ@4liN{{A06_s;jd{cbKbmdZ{|4~S91 zeDCL1HQf*6Ls?b-P(-Wmp{ljMgNJT5dN|K|#Na>pp8q%hncv?R`tWa`z47vEAGnTp zg{#jMwBY4nPb&#s=aaEyiSO1c#j&wzDa>MB$&0l}ht#5k6 zO%I*>iasnXZiH@o-*?VEr|$>{_bM8mvP*X*zv{x3j8I}dAa1Zm=m_7ShusKyI1l{Z zr>}YR^I!S^4aOp34Sw6deE3rg!Wst`H=bgO0y^ghVU9t#(zW+W+WS{PUgIFoIeKdV zntkYjublRZz7>Ld@TTv-R(72Gn;+8*vLz$MNQiMaGtZw2f?z@VFf9uOFv zfA81-?tL`4Uw~Z)Ah~n;Ry)Y}CP9`s!g|QFKxQ!_&^Q!T{~FM%1^VGI2RtMozy6_* zfArLI`c^qWcMA|4Xx;;w2hetd^B_&U4LGYp6K@q+H{j57(eX+L=X-*~a_?ae=V9QS zVsK8`QT-dhtaM<0qjBe3&im=)`^mY&=e%6CyeD52l@zEIgv=> zNe-I`e#>~3GOmRK_>5PQan8ZiI$DEn(f2_7_tbklsUP;ef0*9i=CZP$uii~oZ2=o= z6x5?&jUMX#Kt0>4XTebY5IIeN0rV}(xz2n5txszHDg{m5v z9_*A_g_--+kwqfV`c&(ylG{rz46?YcnxVXa?C(ftOD{vV>9Q%VGw7%ueH1p+H?+A+ zBynF^wV`4}GtTO&>x`u3OCw6$8k?4**RL!T5_EtxsywFil$=n$n!{siicTr#nZ@Ty>5-w1^LnO9{-X(J0JlfVLSZow9#+JV>n{#dredIWWA;vblofq5LT$AV`W6&ygMvtHN=uHEx$Cq-@j3-+lyV9AtY@ ze6*qW{U^u8yV7bNJq#e{X|&=p+R0(4l{m~!1~LspLKKJZmOvE73P`qNWl5+?9F=^i zR4g+wY#}tK7~Jh<{7=U6jt@2^9Oa!ATFdnC6mG9l_{EThRT`wyN-+vGmNzi1H%t-o zntYMtnispDJsIzu6&p46Q4v#l)HxutYw=gAf?|t;+h%Smvlqi6!$e~*z>HxGg@hD$ z^7*|Fe~N(t5(=AAW&9y^eU@q?B1vf^tV`o)0e_L%uZjo7e_y012-*{n!V5eFdGK9U z0*mKzQ$iIk*_0qk3kj;`Y$?!T3W1;$U}6&B2GVkS|-isso);Pjnv5mXnUTjOXsQN$chaiyLzODO~QyG zQ7zWSVg%1JePGNThL|N>YMNlZuK2e60%xHr}97?Gg z*+Gybnx({0sV^rkrOaOkr!516{L#%O=g;li+RisXD29b^^h{hS=S9 zZ0Mk@Y6$3${U=pB4vz7gUu0##+ifexg#Bs}f{O$NA=7tremZ387S5@-D_ zbTwq{!)^E^vUb+gjb{`u&>BCREsLVhHj@RosKa7B(4-pv20|svWB0|?tuNi~i}7t7 zvn(5hU9#Ffp~7>%4YQF7u-GmtFM`lz)S+po*pSk(vP*Sg|FQY^`{GizDtf~7WU&dh z3+1-fSQ@CKnSz{K8XRNE_%s-iN*6hXbB;AGd8_8eT*L}gDbPA{<8F#YMzO}H^HPG# zi;jRD?N1LyyMPNex`hp|3IBIpEWv@_8As+xHZPqGdxvhTMdjvb37SESlu0CuOjIdO zm82G%Sx$#8IB{i0k3vw`ywRiJ6*e4V8v6VKiIqf&G#zA-q}544Zcqwj<1S`eu!z(b zD8NyQJb)E}PlAj;(%P%{n&Big(;H4~xGg77$2&o2WvZW`f9~o`<4;)oP>Zw(ap5}} zLhHLvtSLdWB|}ku(zKm1jm4z95+-AeEgU_GHB*ekv8G;fdUR@fgt_50n$HwVTvcnw z%Y3ZRCyL3hcT662a3Pa-Jkyx`e1n|_-Y=d2!_RYhoQfu(DtN*f#_!Q>9S+uu%b!p< z-?SLdc^k~$bAKJdFs3U2aCl>_;=0E79}l;O&x+L*(*-y>YbW16PKo;%hGc9*kajxmzSL-uQldzLTA=4Cp$P=PIml%mXjTg zWjWc2Be0z8OqJziKYn@HnPJNUfA=!;qmV5NK2AJ`&!1_#kywGtZyImGKeteEF8`<7 z=Qo=K2T8jDnD zh4=$AXl|l8@+!@nC+#~km{wN4{3PmR4bhCJi}f(axU75aaZ>qKu_KtLOxZ!@Wyi-H zV_}-|k43?@ALs9!8JL=FN%*Tc2aV#!q}0}$RFXBxY;QSh5?(#2!jE*|AciRje@SOe zVmB`MZa1Ry7zCYuz?wu6S(9{6S=m{WbON^lBAi}h|FN9i0J1)392zxo=m%15Lxo*3mEe*ePv3kwVB)l_1H=VXK|(*sO|SE`xGU|Ytiakdr=qxsSr@o+ z;&WT0NDowElH978fTi~A>mn7G^7I6AVN~-m)?&;1qPrQONlaz3PC<{H;Bdwu|7r((+%*p-iL{ zXQN(z0s6pT#A%VEU~-u^*Ll1r<-N^?xI*4wk@l-UJOj3&_EL@{CmB7SSzq}vEmNRo zftdkSxh6KxZxbZm4HR;b1Oa8@PdeC5C$)xf7ogI#0jrT7Qo{L{tDBvvJjCcHy`&C& z8gK^YvOsk~>2{Jg zIdrg7*cp_%el~>KJy-r9jvT*cARL1XJdLlJ6;cmg1(+C;SjFxFjsutq-OG}7NN}hO zMpZ!pBKYtK3%b(GqJV&aN~F_nT}12F5p&zomC#UQI+6DZ@lzfFG@Jh;ivptJ^{@(m z?Vanlt_gByA*@r!{+H?0a}7CWy*NpoS^~kI1Z<@I1sfV9)9yfT8XJa7j}OCa9I!Gs zWjbKEP&wf4t;y?pC`-X;T0F}~;E|3c{ZlHK)3~H?qCJ}ZhZXBc8nx!7dAaNaO=!yA z3Yz_n7U;&lZGzZI${Wx)>AWTgm$#mSYFVB}C1Ei#`NG1AOy`Bw7qXUEBOyhm*NVo@ z8wt!di3ip*HqpSS-E5V#FRdMzY~L<2c%RjV{7Wy7i5E`2<@#5{MsJ}!0F#FU@tPI4_=$rNv3@s(pM%xBtV>lU!q?|g;x z?J`%YM!P!gJXMCRF4_e#O25WQEG$&)g6C}Uq{W9Fxe_uPk!;mpmKmZ550q>+1UjD8 zHm~0S%d%^{1O!XS{p;Lg$biKWGkGCp=)2sZ&knLKM4!#RX7s_1 z!JEc2W5=~}^LT1~xR6+uMxHEO0eP%upiO|(>=Gv7EIThOxQ)pq64t3=h{>iCXHt1% z<~wZ2&DO9WmrD3H;4JRx0xWzkT7rmR%*`mU1*NTpp8yKV&DDSgPf{bb&R+=}C+j#O zMpWZEZmvF>Ieu>J|4%r$jhSI_WSVD2pq$4uGZxL;Iy2lv(#+7b6pPQ%|EpaL)kRo* zwjCWA1-KdNSv)heiDx(RLa&QvXU#+in!G&);-Ua#+hkHu$fd! zW>P81q=Hf)lZuQj-nzsB^fW?D4p7$SjZ9J)Zc0pBn}C^h2_8XYQ_U9Rv3}-+x(Fx_ zw$kT0f#}-TuuO>s8eBU(-@>Fd^;qScQ0Pw!FL`0%6u44^-3iN7UYpPDB5FU#w0IM7 ze*1)p&G9h5LcuDO!>;ys+N=PY^Jg|M-8|;=FEDzAnNlR&ox8_f-Y{~5kSS+v50Xwl3PLZe=?5@=ufp) z#S_t*9Rb0?%8FMjE-Ss37Lr4K$tqW^At)^(jKl1LL7KtmSK(-F%U3;wZu~fFt6c3d z9Q;yWNv&=z?>i)=)xZ=Tf-J06DC$lM$1XrM!bSHexWErF8ncP|EB<3ll~z*i)&e6$s@EI?C0euiCzsvb;D&uJXQAwL(^+Oo!y|#huokhJh+pmvznZ#I zAc2T|4eoApf@dezDqoDuRGXLCQb8GHR4(|7LC&+7l2dd_QV-!i=d@LH&{8wqa8X%p zj7W-(tAhoQ5uIr%c>vY{GiS^H)NzQiDS8<@6M3Si9%n2j6IruvjPrdH`i)F$@In`% zdEL$GrTQ$xG?T@%xgu=taGkZjv9icIyQsEl*4Lobxp8f2N3FcBW+6&M@wk+PA?;vD zn`E^KD^@l1IVlsWN25w4IE`>oqneXQf1@KT*?}byzGjQF!ojVp8fIh}2=EqR2$JfF zs5%12md4fv79=*v*`*=xa!Y0=JLIYbX;}->BHwMQ9u0uv2+;h(bi`^nT00XW?*Nau z&CT!-WgW&s3s;i`b6) z2n_lz!2stoMc4E@M?RHrL`!YfXElkQU}D+K!j@zpt-bI(nw=L_jV7v~hPX}H!xfS% zXH$jFsRr7!NP(?&$QP(7ySl78s6W|J{W8ZWuPXY^mTE9xpwPO!oU{Z7#kMrmOQ*3| z_WbsTW9yWEyxC=DT1IxZXqS^6Yx;7s;|;T%>?bWR`zdX++i-}$#re2-weqL&PvBCO zQ*IVf9h+RLa@iROu|YR(4aIb^?7`{DO*CJ$#WN-coq<>mbOxeLcA={9GyK5bo-q96 zl<7b}E#{)d2;xahKY^W#?NPHVoY@o4>K|wJ^{v_6 z{JK?oll*ksxHaJ|<6ME<&wBTBlBBYf3tOYH(urT>KAb^f@Y~jX-I!RyUSJ{H1SIBn zLHk*z0ibVmwA}#gP!>5vbu>9dvD1b6qIhAZq?EG_z)ol9$!!1{1cf`WO*3gVwKC22 zn`T=0Hb4Z2D6NOWewlV-&o}vy6sljvAZF_g$F+Y8zI18HIlz0{7sQ071w}PU(l%Ue znQMO=B&ZbY+`Un)Z7s<4cIB`Ew#Ea~^FGVNLLJ`7>wG=KLCuY|Zh_n8m*|S@)mX z)5YOmHH&3Eo*GG{)t*@a*+o){mV@jV1P2bCjXHEFGEzq|Wi3aZ^fA&33jNH&J&p1A zkUmZ5XAb>oA@7|(pjLT&Xn`O1@=|0m!y|J_SF0Aaj<*F)tOb1RmR`8JNMCk-BHA7v z?BxFzdcj4GuJ&k2VSu$#klHN2n8U;NU|Cm*H^>TON~cs}))(=}V8m>Wo!^PhKe}BE zKHKFn&Q}jpgp32ylx3bMXyGB#h=us7e0M2ZD`@-anp*o6vR&-(r zfzKOC{3#~CsLjmvHd-zuT5e5uUB#S+R``o+IMoavVkUv)j_Nmj+%Mgupq&E_8gMr3 zH$-uGbPaa1fTEQgqEu2RNtEu;U0q4(SrLAc{4w$jnR9sz7V9_|rtCCEOza2r0GXdk zmc{{g?x}$T)%vnDBD<|1ji3H34HGJ!m$Ia;%+lz(A|~;(+NbFTT0jl>*M44s5+JYS z6#xO~YF;TD;E8q9v;Yd5y;{9Ge+jS$yE0joRZz`pUg4hxl3xELB-VO#+FrqR*$<+a!+tD;4k)OLd1fd^Uin;1c-@pvV#7K^Xqgylih*cG)K_bF z&WXv;o1QEUw1_N(?<`HYAx-$s(u5$=_z7JT7pScyji1nQKV|`0ez*c;KT-jxAEW@! z(?9^_5xpuS6c+Gctkt=Vuz=z z4$YA;xW=KGP4W!Q1447;(d;r|uAmrb2JacFz^|CrLNv>u(TZjZp&u|}yF&dYm0QuQ z6>$#DHez845z$P86|hchLXA_P_Em0(bSa^b*TXAKJ0djK(KAuod;&b$KXqql9>~zV zIzuz0>hlQ|wbdX8RILU&ZxExQ8PQ{CcG$&?NRe8XE_&%mG52JsT_e;M9BQ%TkqexH zY+r*oKWz>umaPv=hVJ+AO7}y5`+24Np}#A61$CjnT+;1<4kQ8X-ASOqBeE&X1v@^U zCq&58Cm?0~)2a+Z)eJ)`G7R-*7%BwPlg~&ZRLQ6guJmJGy(V*wk(Mg&=;ao@_>w-y zo6T8Y`l+;5BhnliC1)KMaFl5{JQK-BUdK1YAyBCipZMwv@!}Ik#b*w7kj?WN6NkD1 zqJjK?ZDW6=YXrCf#)zmS{L942Pe8Qs)E?3pi$EI2SbIrhK*Ibq?&>@MGM>wY2Lcs_ zK^zGv0kW7800L0)Ax1R7lP*Kk0wX{J7nw7Qd|RPG|J0X_cqO9(?o;w#xxLyyi4X_r zvEk}e(1jJ9pEPocjRG>0LguE4Z+OD;sm6qs8=iVdqjRD8hNoWA=waxC;fc!`)y=FU z>ZA@U^Aq@;XVsyho=XRo=^1q31D-dBc_AFrv^Bny9#3m@tB;Lo15X3ld{~`fY*mIa zuHf_~#0#Yx=J3=Bp4!nV2Eobe=un(@;eGwg!tE)zN}4Fo8f61n+WMNXhDbXt@I z)h{Ql; zAUlZ~P#GYL*m4B8l2^(Gcv46il|YJ~epa@@Q#Hd$e}?`Q8FskRJm5+6vx<2pLee~o zl2wj=jCTc@EC!a*50+yxC#x*>!^``$SqZeJiP({iYIio~J=uU&veEC&hEwwhv}j1g zJG?v%gW#uCK$^rWXbDKuECVgsNCft?a9XX%(9)Nor7@Yf)5TYB@>B!^`7pPd<*CT0 zk`kAQMOx+EU8cqNdo8{r)8b3juVc^**^!z1E0=X5os+JZHzeTlF0R2|gQa*D}plZqXr-pe|hH(}> z9{0;qEv0v(S}K0kN$pfiuy1H*<^aBC%O%qrO@}uJZQU%;DILBGSk1~M@n(&*jlufn zc|Tst&^e1WC+p*ZN!i)9jAoD6*f7KTGQK`l}j=kazzGWuT0<| zZM87iX{TIz3_(P`Anr2$X<5ppNgH`wHk3;t z2TZtKRX@XvmCtl{$SkXfP-V|HipPS){C`Q56h_ihcGgO12i77mTw2jtDiz9|9q6f1 zdWO@z*`+mVy@C;QG$32Kklp&3pRr8y0x;#)SL_@wqa9l$?K6? z7FV(lz4jrCn^%?~v=0~yptCH@p1En+hZXiAi^@l9y9V(UC9_4(u>e>Ck0Plyn5AN+ zB8}-8CWi*%o?&h%R`#6q>!%F=Fxqxnf*T74Q}+fWU4sKf8y>87g=BzMf?iYOYR0@v zx(dhH6OPDm#OlmNN3ySgtsU`lg$UOufvK1=WGzxk=h*%~!VwA~iAgw^g{|P`dP~7u z$s@0n5@MS?m@u=HSxdnPnxzmekUaCb6bK;+GiE^4Gmu`r&$+$HM##9@jrGnQ-Az0> z5^*h<1Q2HBz^-D@oAC{eQDeCVf|H;F_Lvogz;=*acZ&H8s_X)3_(PP1JIK&{JjAvY ze8^%?n*`KnXp{s`X(DS|&9KBS_=8{n>;L2t-IG{P&;USnp4*yLV z#bL_gVmk#y}&Etu1rK6lgSVD)A{mse9fq8C`rjx&Am zAa5y`Ra{3k(~dDC$rO0J@<)dBy)RuS>cnnoEX{+B-7f}oE{93tm#)K&>7A-jnp0Q0 zRu?JOx?OZLwXMfFyO83qT0(8*1ujT=k9e(gq0)@Yh`I3YIgHxKT^zcLM#Jy#<)e6@ zMJq012;lUE7+ji9FeENgjA6C9=t(~ehPjF9gP_4~tT90Z88qn)0h$^kogsU-#<**a z5`Q99__vUpk-Mc(%7wqGh}vjJw?@b8@yK2->=>25QGZ1{1aB^78y|^XN640kj>*{0 z2i4F_)FIr8WT^lLI};A8sz;=XSAv~UW_e_m@^Zo?;KCQ**zOk0!Wo({i=D@i>KGG8 zx_vo&G89U60*lPF@(JFfG0UY83D!KT#TT_8M^@DBT)2Y;<~3I_9uw-2;m;r+zMzh{ zrrYTyB9xQcDV+wN3@oaI@3!l>2PIm96=q{7TH-w$LvrOjy$@gjfhw}wHt(sCTGUm4TR&D4g--aJ06l=%QSy z49jGt)z0V6t;r&z_Cz!{ zt_~fm}a}=#O>1^Dw*351&Q{qatn8#&3{=l^6@(P91L5k&0C($QJivH zr06q-gC*hTwrr(eSbJKwc$px|sGn~BTY;GHtn{ERxy)&5CF zoegpJuPx#%_)dr{(1Tg!E-7v@UkjffnYOI_$h0N%w|WF3(^^m1HnZQB_Ot3<5`Js@ zk!j1yk4#%Ke{1^{Omaza+|qtz+LG{F+mB3JGJn(pADPyAz<-U0!xv zT$j^!ZW&ol_W8q1^;X0a-f~&+G0rV3KjAHx%pbLo8Rozxr&eoz!dtfFcT?rt3p9zA zik4DGTam_nw{oAuIA9lA8V>EZQzovAV?_$^_gl#dpIE@>!pVg~_2<(! zUmsO<&7-rj7x7%ap~lL&pKL^RbD^?g7n9&PauqjKeTGFouU-0cvh?TmOMgCT>CdNR zpS64qt(GaHiV3#zV6@aZsjzaRkJ+ltpUTb7NtG~)$@0{6PU`U#uRNj?@bM)I;VNfZ3W9-JaiKrEOha;3SG>fctR7femI(5R+qhp=52i1`6O65pLQSQvnZc-cRsf!pY~3CdksiCpLT6P=Y85aoXp^~ML*_^h2thW z3APR4t~0lqG>ge{vdeI`5V~;`wa7WvAB|)E)kR`cWphpA17h6>a_SuW7f^By!9z6z zYiH4AQ#Y_GXf|amlWhuG4;CqF6xzNJ{b*CjdCyykVyfxo#vXxBh}=u#iFc}U!3 z3!6YKt`9mdqEHCfY(YfQxegqJW7#=K>dvE4wo5`Iz=90(LbK}%2;D8L?y42pwK8z* z6d39|(jGf6Q8=N1rCeEb>zVPw^pahi=NM!&mT&?IB~9o69|#H-P^M3m*iF11?S!$J zoDEn>m&0mZtV`c%iHeLcN{p2BlIrCY&_GI1GJqn;Fj_KUXTzn=&@e@wpiK?JP*EFW zsP;-l7>qZjW2!= zdbFpPR?O7zMvmL!lWq;3cAH#W4egmgZlZD9X~0&`hLVN9Q5s}}wO(g$49E7B7;6+_ z4~>kzXq5J7`0RSS#JY)2z&=SJ55zFrGGe-dU_mh4UfFl!sNC2NiHtZiRM2|EqG(~T z$f%dJ%`Tb87dO&wSB-P^AFh%%Dd~xu0gCSdMgm7so81r?@%i~(`K-91 zqqrR1)%Xm10v%v7?MZmu%{eWRXCS505*NOyF^%1 zvjn~j!4{Y$n?*t^42B^yjwcXCneFBeY%Ir#{7lLvdQQ()*ea&o?VGd-X8#J8-C6l$ zwKKX{QJ59ctn1>_3-<5f4OUxpJDRK34MYIqUwN0fC80JRR~{zi8*1I6 za`w#T4;2*z*+`Z9KwP;V`%u;{d^b^gxCv4j%P$ru(4jV-^^JK3XLawyTNeJJIrGXk zcpm1yvlxnaP?QJsYoR%0p}kt|#@f??-GjXbYWDZo(u-1^P5aBPq<5rN*+s&xIV_ekD7#P)1TX&|hg3jjju&L3Kg9jh6Wk zAjn+3D$X)Lydf#PRkU6G-B@F}*nf$J4S#{i8aq2%n)D+B_8Y{|M|EJmh}RLqC`u}7 zYEsx=qhr*PWlZ9?ijC1UNhT{(NpPGNOwa;Sq9neKEP?|LLcu!+`#|HXW@lepV!vMz zec;jodiVkwHJ_Dl{(9S{)qSFO9xA@HFAjkA`3FNYtpEc(9E)_BlD^a5GE=znMgRN@ zmmFw3k^1ZZ^2pyFGxlfEfyR^TgpnT1lWJAh2GMA!YvV5-sKvM24CqN;Y77|KK|)$i z^bA8}aS}$?lMc*?xxZ?U&ct-4uYLE5Gr?eI`sg=Lq`$Dc4*J}_4}w-MaHjdMrLi|Ne=`xmtDZ_DxxP z58!`{v#09fNI_`!{9Lk{R?OAnd|rJ$*!_`jZJ=>r8JnS z-+rX>u5(W_BpmQ9Jjk@pntR`!2TniF{;Avh51jtkrO&Jb;Lg_0QtRLfG1Fp(fPPg{ zRa>G1NkoId#au0-8SwlY+$npB?M}QVMkQIc;Z)$Y+NJvpZ@I^Jo?xsr7?;x7=1_Y z&~GIW3qZt5-G4^<^hpDK-`nn(9R7uEryV%`J0qX|P@7i`JkEahH(M9-bX1>w>CbZ??z5|0aAwASD(G{haPH>NA zdPqy6LuHU0HRrU*ZeaT?NGE`}py)u{HgT4L_@jP-xO9)8?KvwC!g6X|zy+T0-AMB- zNXq>p<>f>rAL{jVgkj4ihSTCG!mVYw<-(Vkl@u2S@Bqb?naW9 z(h*6HV!8&lja5tKK(>+XE>HC2mR1X;Dm~eyY%E)`^sz=GKd7L{AeZ;x>om<*2?O*} zlSl~@rs>cw>JnVEjea4nfZ+X#iXOkS=JXMTdk8WR6%q`Ena5| zB2AmF5r9njF2V1KkYwr8P~Ue=qFh>Om_93W>(XQ`&iG700u%M~?W?RcsK zf;+K#%~C3qOeF9?ox)u^u)bjI3Lc#=h>bQYSZyf?AgzzAUsSj*Uk(nEl_O|EQ-#3E zmpdw7PGMw2Ly4BzR1P@#a!<*Zi*w~z5;T!Tn%oy9c|)j%N4RCQJ{ExDzHScTU|~%8bXvBTmkb)>rsoY6+s(5qnYG zLdD1}oPk-0j&{QMcTp#f*MN|@NwN0Dr{Rj?l#`w(yXNecIIsz1f&;OMp1)7Vq8`XQ z=>ddfmfgT6Z(z=KbW6pMHZ2Vrt;Td{Wk;7ukC~pl`SLpl5e$XO$|$-dLHKOi@S0k5 zaT2|{vdJvTVq?exx@oo<>_I0K*yebN4m?YEAc6HGndXDPz}pddvU62#cD7wy-8F2b4$V7qxgOXZBAanjmax}e|8ZAHA!+=@9c(reex)1&P z4=>t*?0waxm+w&(!lCVmTJ94H(L$&WWWht`r}A=YhdIJekk#FH~PhqrXr%Grf=PTdJ(|dL{w8S zs={coX=;45{x#e%Ns-s2xCtcHM=sEI&=8#Rfg(!D=W=m`fnAIGbS}L5`j{tnE7Bjy zN|Y2wWI9jpp_^uQRDWePTp!<)*4W2|Qbd^a29@thI-qK-@i?aQ{NnVQd9Lp!NxdVX z)}xN7Tu-75I|fBa7ZapIAN$aAv_3Jc^vRr3P=}KuXrl;l5Pk`}7+6`9A3ep?Rx}S+ z5T62C!rp=UfGvqf{r}8$NuNiHdhB4z#E!az!Ub4g-f(U8u_RY@f`@HH@R;wi$Fo|Y zYRw-IX~zp*jOE%P)-I2L6qrf9iF)KJby$|=qH=9V)WyDt$iYq8lv#h}*-R+y9bI*{ zorKv?7>v=tq8IXo`q;ahRt;C3O`F0d0ez5?TZH`JS{pcqqyE5qM>ZCYqNx~uHx%HJ z9;_5XETwQx!J(*d%dqs0`a{bG3~M4QM65Te6w8w-qaC&^<`w!@uJSI3Li)NW66B!= z#_>kikG=wJFXr0LF3hxcRMmD2W1@H|jW%p(*w%~k4(|8H)tE_H~-o;s9} z07vwl>7+9Vg)-z!U*KLcfVtj?4g;wnHbf*?{xN^jL=ChNX-(0aYPN^N(EuHAu^~0V zvnz!+v&h_GgN6_xs|MHSab#v>Qb_M+Hb9TcB6_gP8bFIp2Zmnr8T6>Mo83Y_oWcig zvbJT-F1nU!p4MVXoMPw)wq!On*p2kmq!z|m3*Agm9X?OKh16?pG`2tssee8d(UaeV zh>f3dg;M2WZ)mrjNn!fF*F|7c*UP0>U+wsN@2DO*>01=}xeFR#jSq{IvGB#u{ zG8?A7nksHeGBFC8?VblU+FH5vxY@{XRvDfd8`?ZtPo~F{ZNp<*lacz~!p@=5(eW*> z+%`GBlRx$P*5sn0sbp(?YWTu2UdTE=Ho7<2Tu-);la!%t)Ah;ZmD}q>6P9($_|A#Z z`gEO425M-!zO_(DADS;zj+>Yq-#W8}>|4j{Q_0x)bh3SDcRd*zONO>g5A&oJaQoI> zg-U(P(3mo8866tlnM~F%8k*cXmCTGy5056(+o^r~(C}C?JmpHNl4SkRbTV2Wnwm~d ze%^7(_%_u~gGcIPQ^~~8t0tGkV17A z4Nq?;_k>_>9a7WY{I`WlZ+(1fc>F|zOwtV`{g2_PsTm>CD%&cWP)i zRZdahQxxcPFkB*OUm@)XhC|4=&J2%j8y%V+9v|c5_xM?Rb=IJ+9f4Lpw>h{O&@fYxB(B#Jyg{tH%Qg+v;_) zT&pa+CGK@UuSe;1=g=gbYtT)7&+wG$ct07Av8GJcr|Od;rZz44qQH29nyNz;WAzI` zF1a`FomREqBSUp;oPnPjr%Ux@a{MAS_(R}kcx-BB+ct=&J~o}~ni-!S;>#QP@@yOK z#Pye=Tk1gEnrP}Is)gZJPer8DAKvc7wGd}fO2WH~gKuJ~}F(rx_!JnygNy)V3b%)N!Q6E>gBEFE(* z)=ea)&hTWQ)A8L*#gk7;_ST0cMVKF@%u}bfkI#%kuGXBf@v#$rr#?CEJ4v3elIQp_ zhC(#GWnu=_Fggu~@Ysbfj87OT)Dy7`f&HV86e_hQEV`aB3e(AE;9NAkb$UA)-@8~w z)sxToc`~kV2XUIw(dahAeQfFMtR$B3vk1{?+>@I&hQvVzBJj)Np3=?yDa%gO78{-T+ zxiA^trtvc3hd7}-sAe0GAEcCq8VD5bh$i<)@ir(9kB=xQI){HmAo$++OkC~9tyt@ zE?l34>A?Y@80%LU21MCKd=YbV0zzK_@m)X+jKgAF_B`&c_(Y+yc6baV4~NfF6ZI{_ z+lEbt_)|Vt7nXV#$qm)QSHERuauS9O+ibLw%0ENibs27a-liPiBF7r3BjaOeCnBk& zzHM85i=@qEpDa{P4ZVjwPpfN7^?Y+3b;x9r@BAG=c-qWZeGlD|&N4JL1v8o2yL0pS zD2mC%jH-EnOnm_j;_IY6L>i*Vp=QhY7_1v5MB2dvuZx0=+?y$9!(&@eX{HQq-zURb z38Jat-$DD47R9$whHiKZ<^S-HqDn1CTx!tHp*>JO0|@p^tZJ^^LdIwC<&{G-)7!@< zho|?xa%+8JdV82IkXNRGJ%{{XApf9gi&Hbmgvn{uJUYB{*gEcLNc8$B`HtH=KGTp@ zn;Cx4KRrHi!f1VWeKau%yobEkUlUcHrwJ*+xi=Zp1PTPF$w|R5KK2djbHFJ3S<1fP zcOq+;wJm{WV1c{^zz8Yekk z|AwftvPmLR3F&`Ey4P2&vn0Knq#hx~5JbZJN$9k0@^Tk19YQ|OALcpk;o%-0V1pof zXr?hULNm9FjypnokZez}1_tsosGIkqWE=;WSN*Xl%`*=H^J@3@;S0Bmu?sKtNix2b zjB27|>?GVw!b;EP^95c}iydy%>Aw}jj)1PZ$xIOX!^M`MWD$g0;yaP6(^$7zYT4icY4o#0wzEaOl9I}4d ziR2o7B`dtTrqErKJknK91C0Sfd|@r+ByuY72ozO5n%UHVl~-V zTrj#w{rcoKr%E5>%c|^)lv)4byL>oR>(HUe;VBA*hWkm|TFF#El~!MfEGoVEI;O-$ zusG4mdwD6H^0EStxA8c5;>pi`&U2qPw0R3k!G+t0cZ`hg92=k5H90jsv-_ewdw+*~ zUr>sgWvL&M%|v+A7|a4q-1R=q(H_~!u@y1_%xrYEebv_N5PZzosgbKil)J|nL)&*77W%~|1_$clq)+mv)M+&&#T3z zz-K6SM9AAZ3m)R*n*7JyM0kvEPnlxaFvu_uGOJ5iJ-_jK82pJ~@LD~H<#R5p5+Bb4 z?oX8}B+tKxH@M$NHlPDEk_&~-`#$-L-}v`mJ`L-9KAGGbi?{tFx!D$|3~Xlg428jt Lq^(ZLz*PAEB!|}j literal 0 HcmV?d00001 From f7b957ccee0232cdc7ad6d315b626be1c3461f72 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 5 Sep 2018 11:11:46 -0400 Subject: [PATCH 0508/1048] Code cleaning --- eosio.system/src/voting.cpp | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 52be4cdd..5438e37a 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -140,28 +140,12 @@ namespace eosiosystem { delta_total_votepay_share += additional_shares_delta; if( delta_total_votepay_share < 0 && _gstate2.total_producer_votepay_share < -delta_total_votepay_share ) { - // Some amount of over subtracting is acceptable because of floating point errors. - // If it is too much though, the caller of this function is passing in delta values that are too negative. - { - double delta_total_votepay_share_magnitude = -delta_total_votepay_share; // must be positive - double relative_error = (delta_total_votepay_share_magnitude - _gstate2.total_producer_votepay_share) - / delta_total_votepay_share_magnitude; // must be positive and no greater than 1.0 - eosio_assert( relative_error < relative_tolerance, "subtracting too much from total_producer_votepay_share" ); - } _gstate2.total_producer_votepay_share = 0.0; } else { _gstate2.total_producer_votepay_share += delta_total_votepay_share; } if( shares_rate_delta < 0 && _gstate3.total_vpay_share_change_rate < -shares_rate_delta ) { - // Some amount of over subtracting is acceptable because of floating point errors. - // If it is too much though, the caller of this function is passing in delta values that are too negative. - { - double shares_rate_delta_magnitude = -shares_rate_delta; // must be positive - double relative_error = (shares_rate_delta_magnitude - _gstate3.total_vpay_share_change_rate) - / shares_rate_delta_magnitude; // must be positive and no greater than 1.0 - eosio_assert( relative_error < relative_tolerance, "subtracting too much from total_vpay_share_change_rate" ); - } _gstate3.total_vpay_share_change_rate = 0.0; } else { _gstate3.total_vpay_share_change_rate += shares_rate_delta; From 342d22a8db00a0f5fcf16236a1a875dbdad96448 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 5 Sep 2018 11:13:17 -0400 Subject: [PATCH 0509/1048] Add wasmsdk version to test_contracts old system contract --- tests/test_contracts/eosio.system.old/Readme.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_contracts/eosio.system.old/Readme.txt b/tests/test_contracts/eosio.system.old/Readme.txt index fd0bee79..b85d6da8 100644 --- a/tests/test_contracts/eosio.system.old/Readme.txt +++ b/tests/test_contracts/eosio.system.old/Readme.txt @@ -1,2 +1,3 @@ Compiled with eosio.contracts tag: v1.2.1 +eosio.wasmsdk 2c106a018f2e69d34325ef2376cf085426068e93 From e8754348bd6edf10c631bfbf5613537bf20fd5d6 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 5 Sep 2018 14:29:21 -0400 Subject: [PATCH 0510/1048] further code cleanup --- eosio.system/src/voting.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 5438e37a..e4ffb1d8 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -130,8 +130,6 @@ namespace eosiosystem { double additional_shares_delta, double shares_rate_delta ) { - static const double relative_tolerance = 1e-10; - double delta_total_votepay_share = 0.0; if( ct > _gstate3.last_vpay_state_update ) { delta_total_votepay_share = _gstate3.total_vpay_share_change_rate From c5035c8a93c695859fd909ba4ff565a12787f25c Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 5 Sep 2018 14:33:31 -0400 Subject: [PATCH 0511/1048] add more detail to READMEs for old versions of contracts --- tests/test_contracts/eosio.msig.old/Readme.txt | 5 ++--- tests/test_contracts/eosio.system.old/Readme.txt | 4 ++-- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/tests/test_contracts/eosio.msig.old/Readme.txt b/tests/test_contracts/eosio.msig.old/Readme.txt index 526cf983..c229cbe6 100644 --- a/tests/test_contracts/eosio.msig.old/Readme.txt +++ b/tests/test_contracts/eosio.msig.old/Readme.txt @@ -1,4 +1,3 @@ Compiled with -eosio.contracts ee6415b0d3f9cff3bafebf98b2e06b80545dfa36 -eosio.wasmsdk 0d4befeee7abbef1db775b2e8833f7db8fca7ad2 -eos 2ad412773d6ccc72045dae760ae3d81cf229c8ee +eosio.contracts: ee6415b0d3f9cff3bafebf98b2e06b80545dfa36 +eosio.wasmsdk: 0d4befeee7abbef1db775b2e8833f7db8fca7ad2 (v1.1.1), CORE_SYMBOL_NAME = "SYS" diff --git a/tests/test_contracts/eosio.system.old/Readme.txt b/tests/test_contracts/eosio.system.old/Readme.txt index b85d6da8..a9aa16fb 100644 --- a/tests/test_contracts/eosio.system.old/Readme.txt +++ b/tests/test_contracts/eosio.system.old/Readme.txt @@ -1,3 +1,3 @@ Compiled with -eosio.contracts tag: v1.2.1 -eosio.wasmsdk 2c106a018f2e69d34325ef2376cf085426068e93 +eosio.contracts: bf28f8bbf9ee753966c95c586906e82d72f9dfac (v1.2.1) +eosio.wasmsdk: 2c106a018f2e69d34325ef2376cf085426068e93, CORE_SYMBOL_NAME = "SYS" From 70861ef03972d74cff41532831eebd8f53872b2d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 5 Sep 2018 16:47:03 -0400 Subject: [PATCH 0512/1048] do not allow revision to be updated beyond what the code can support --- eosio.system/src/eosio.system.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 4e5876aa..e01327f5 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -141,8 +141,10 @@ namespace eosiosystem { void system_contract::updtrevision( uint8_t revision ) { require_auth( _self ); + eosio_assert( _gstate2.revision < 255, "can not increment revision" ); // prevent wrap around eosio_assert( revision == _gstate2.revision + 1, "can only increment revision by one" ); - eosio_assert( _gstate2.revision < 255, "can not increment revision" ); + eosio_assert( revision <= 1, // set upper bound to greatest revision supported in the code + "specified revision is not yet supported by the code" ); _gstate2.revision = revision; } From a04bb40a6a25f0845a2710afa05a6a43c9eecdf2 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 5 Sep 2018 18:30:19 -0400 Subject: [PATCH 0513/1048] bumped the version to 1.3.0 and changed wasmsdk to cdt --- CMakeLists.txt | 14 +++++++------- README.md | 4 ++-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6a14bb21..97e94340 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.2.0) +project(eosio_contracts VERSION 1.3.0) set(EOSIO_DEPENDENCY "1.2") -set(EOSIO_WASMSDK_DEPENDENCY "1.1") +set(EOSIO_CDT_DEPENDENCY "1.2") if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(TEST_BUILD_TYPE "Debug") @@ -15,18 +15,18 @@ if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) set(EOSIO_ROOT "/usr/local/eosio") endif() -if(EOSIO_WASMSDK_ROOT STREQUAL "" OR NOT EOSIO_WASMSDK_ROOT) - set(EOSIO_WASMSDK_ROOT "/usr/local/eosio.wasmsdk") +if(EOSIO_CDT_ROOT STREQUAL "" OR NOT EOSIO__ROOT) + set(EOSIO_CDT_ROOT "/usr/local/eosio.cdt") endif() -list(APPEND CMAKE_MODULE_PATH ${EOSIO_WASMSDK_ROOT}/lib/cmake) +list(APPEND CMAKE_MODULE_PATH ${EOSIO_CDT_ROOT}/lib/cmake) include(EosioWasmToolchain) ### Check the version of wasmsdk -string(FIND "${EOSIO_WASMSDK_VERSION}" "${EOSIO_WASMSDK_DEPENDENCY}" output) +string(FIND "${EOSIO_CDT_VERSION}" "${EOSIO_CDT_DEPENDENCY}" output) if (NOT "${output}" EQUAL 0) - message(FATAL_ERROR "Incorrect EOSIO.WasmSDK version, please use version ${EOSIO_WASMSDK_DEPENDENCY}.x") + message(FATAL_ERROR "Incorrect EOSIO.CDT version, please use version ${EOSIO_CDT_DEPENDENCY}.x") endif() include_directories(AFTER ${BOOST_ROOT}/include) diff --git a/README.md b/README.md index b27fdc4b..f32834cc 100644 --- a/README.md +++ b/README.md @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.1.2](https://github.com/eosio/eos/tree/v1.1.2) -* [eosio.wasmsdk v1.1.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.1.0) +* [eosio v1.2.0](https://github.com/eosio/eos/tree/v1.2.0) +* [eosio.cdt v1.2.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.1.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From 27e2a01a4e658a98a1ab4469ebfab59dca00c2a8 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 5 Sep 2018 20:33:56 -0400 Subject: [PATCH 0514/1048] add abihash table to system contract ABI --- eosio.system/abi/eosio.system.abi | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index d4baf192..8bddf7e6 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -638,6 +638,12 @@ "index_type": "i64", "key_names" : ["newname"], "key_types" : ["account_name"] + },{ + "name": "abihash", + "type": "abi_hash", + "index_type": "i64", + "key_names": ["owner"], + "key_types": ["account_name"] } ], "ricardian_clauses": [], From 62e710c65bec8afac238d67dc473f46b6a139d72 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 5 Sep 2018 20:52:07 -0400 Subject: [PATCH 0515/1048] update version in README as well; also fix links to dependencies --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f32834cc..2c7e7e16 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.2.0 +## Version : 1.3.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.2.0](https://github.com/eosio/eos/tree/v1.2.0) -* [eosio.cdt v1.2.0](https://github.com/eosio/eosio.wasmsdk/tree/v1.1.0) +* [eosio v1.2.x](https://github.com/EOSIO/eos/releases/tag/v1.2.4) +* [eosio.cdt v1.2.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.2.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From 75f0a5976ee6d0da061d286114113b90dff48bef Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 5 Sep 2018 20:53:27 -0400 Subject: [PATCH 0516/1048] further cleanup on renaming eosio.wasmsdk to eosio.cdt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 97e94340..eb45f222 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ endif() list(APPEND CMAKE_MODULE_PATH ${EOSIO_CDT_ROOT}/lib/cmake) include(EosioWasmToolchain) -### Check the version of wasmsdk +### Check the version of eosio.cdt string(FIND "${EOSIO_CDT_VERSION}" "${EOSIO_CDT_DEPENDENCY}" output) if (NOT "${output}" EQUAL 0) From b87eaf6537a57e3f2ebb6cce36200ce34a457c1b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 6 Sep 2018 19:01:50 -0400 Subject: [PATCH 0517/1048] Revert formula change, add REX symbol assert --- eosio.system/src/eosio.system.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 51934a2e..64c7cc3e 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -306,6 +306,7 @@ namespace eosiosystem { rex_balance_table rbalance(_self,_self); auto bitr = rbalance.find( from ); eosio_assert( bitr != rbalance.end(), "user must first lendrex" ); + eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); const auto S0 = itr->total_lendable.amount; @@ -346,7 +347,7 @@ namespace eosiosystem { const double F0 = double(conin); const double I = double(in); - auto out = int64_t((I*F0) / (T0+I)); + auto out = int64_t((I*T0) / (I+F0)); if( out < 0 ) out = 0; @@ -430,8 +431,6 @@ namespace eosiosystem { auto unrent = [&]( int64_t rented_tokens ) { rextable.modify( rexi, 0, [&]( auto& rt ) { - int64_t unlent = rt.total_lendable.amount - rt.total_lent.amount; - int64_t rent_earned = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); rt.total_lent.amount = rt.total_lendable.amount - rt.total_unlent.amount; }); }; From 259e9bfa2ac8e0bfde441e1eb1771f27e70648d5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 6 Sep 2018 19:02:34 -0400 Subject: [PATCH 0518/1048] REX testing --- tests/eosio.system_tester.hpp | 4 +- tests/eosio.system_tests.cpp | 86 ++++++++++++++++++++++++++++++++++- 2 files changed, 86 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 672a1efe..bed6aa32 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -323,8 +323,8 @@ class eosio_system_tester : public TESTER { } asset get_rex_balance( const account_name& act ) const { - vector data = get_row_by_account( N(eosio), N(eosio), N(rexbal), act ); - return data.empty() ? asset(0, symbol(N(REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); + return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); } fc::variant get_rex_pool() const { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 1dcb7f3c..d93ecf37 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3306,8 +3306,90 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { + + const int64_t ratio = 10000; + cross_15_percent_threshold(); + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); + } + + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("30.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("970.0000"), get_balance(alice) ); + BOOST_REQUIRE_EQUAL( ratio * asset::from_string("30.0000 REX").get_amount(), get_rex_balance(alice).get_amount() ); + auto rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), rex_pool["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( get_rex_balance(alice), rex_pool["total_rex"].as() ); + + BOOST_REQUIRE_EQUAL( success(), lendrex( bob, core_from_string("75.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("925.0000"), get_balance(bob) ); + BOOST_REQUIRE_EQUAL( ratio * asset::from_string("75.0000 REX").get_amount(), get_rex_balance(bob).get_amount() ); + rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( core_from_string("105.0000"), rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("105.0000"), rex_pool["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first lendrex"), unlendrex( carol, asset::from_string("5.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset symbol must be (4, REX)"), unlendrex( bob, core_from_string("55.0000") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), unlendrex( bob, asset::from_string("750000.0030 REX") ) ); + + auto init_total_rex = rex_pool["total_rex"].as().get_amount(); + auto init_total_lendable = rex_pool["total_lendable"].as().get_amount(); + BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, asset::from_string("550000.6800 REX") ) ); + BOOST_REQUIRE_EQUAL( asset::from_string("199999.3200 REX"), get_rex_balance(bob) ); + rex_pool = get_rex_pool(); + auto total_rex = rex_pool["total_rex"].as().get_amount(); + auto total_lendable = rex_pool["total_lendable"].as().get_amount(); + + BOOST_REQUIRE_EQUAL( init_total_rex / init_total_lendable, total_rex / total_lendable ); + BOOST_REQUIRE_EQUAL( total_lendable, rex_pool["total_unlent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { + + const int64_t ratio = 10000; + cross_15_percent_threshold(); + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); + } + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rent( bob, carol, core_from_string("5.0000"), true ) ); + + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); + auto rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( ratio * rex_pool["total_lendable"].as().get_amount(), rex_pool["total_rex"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, core_from_string("5.0000"), true ) ); + rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( core_from_string("70.0000"), rex_pool["total_lendable"].as() ); // 65 + 5 + // BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); + +} FC_LOG_AND_RETHROW() + + /* BOOST_FIXTURE_TEST_CASE( lend_unlendrex, eosio_system_tester ) try { - /* transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); @@ -3325,7 +3407,6 @@ BOOST_FIXTURE_TEST_CASE( lend_unlendrex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), unlendrex( N(alice1111111), rex_balance/2 ) ); BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); - */ } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( rent_bandwidth, eosio_system_tester ) try { @@ -3343,6 +3424,7 @@ BOOST_FIXTURE_TEST_CASE( rent_bandwidth, eosio_system_tester ) try { auto loan = get_last_cpu_loan(); //std::cout << loan << std::endl; } FC_LOG_AND_RETHROW() +*/ BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); From 7d7fb80017fc6ec13b2f96da395451a472ff7205 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 7 Sep 2018 16:39:29 -0400 Subject: [PATCH 0519/1048] REX testing - bug fix --- eosio.system/src/eosio.system.cpp | 7 ++++--- tests/eosio.system_tests.cpp | 18 +++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 64c7cc3e..76ecc464 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -343,8 +343,8 @@ namespace eosiosystem { * @param conout - the output connector balance */ int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { - const double T0 = double(conout); const double F0 = double(conin); + const double T0 = double(conout); const double I = double(in); auto out = int64_t((I*T0) / (I+F0)); @@ -393,8 +393,9 @@ namespace eosiosystem { rextable.modify( itr, 0, [&]( auto& rt ) { rt.total_lendable.amount += payment.amount; int64_t unlent = rt.total_lendable.amount - rt.total_lent.amount; - rented_tokens = bancor_convert( unlent, rt.total_rent.amount, payment.amount ); - rt.total_lent.amount += rented_tokens; + rented_tokens = bancor_convert( rt.total_rent.amount, unlent, payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount = unlent; rt.loan_num++; }); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d93ecf37..78b216ec 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3364,6 +3364,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { + auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; const int64_t ratio = 10000; cross_15_percent_threshold(); const asset net = core_from_string("80.0000"); @@ -3377,14 +3378,21 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { } BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rent( bob, carol, core_from_string("5.0000"), true ) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); auto rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( ratio * rex_pool["total_lendable"].as().get_amount(), rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, core_from_string("5.0000"), true ) ); + asset init_tot_unlent = rex_pool["total_unlent"].as(); + asset init_tot_lendable = rex_pool["total_lendable"].as(); + asset init_tot_rent = rex_pool["total_rent"].as(); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); + asset fee = core_from_string("7.0000"); + BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( core_from_string("70.0000"), rex_pool["total_lendable"].as() ); // 65 + 5 - // BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 7 + BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 7 + int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount() + fee.get_amount(), fee.get_amount() ); + BOOST_REQUIRE_EQUAL( expected_total_lent, rex_pool["total_lent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); } FC_LOG_AND_RETHROW() From ff29a9e25eb13c21a48659cf19b42335d8fa498f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 7 Sep 2018 16:40:44 -0400 Subject: [PATCH 0520/1048] Code cleanup --- tests/eosio.system_tests.cpp | 37 ------------------------------------ 1 file changed, 37 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 78b216ec..7cc461b3 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3396,43 +3396,6 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() - /* -BOOST_FIXTURE_TEST_CASE( lend_unlendrex, eosio_system_tester ) try { - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( success(), lendrex( N(alice1111111), core_from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); - - //BOOST_REQUIRE_EQUAL( eosio::chain::asset::from_string("900.0000 REX"), get_rex_balance( "alice1111111" ) ); - asset init_rex_balance = get_rex_balance( "alice1111111" ); - - BOOST_REQUIRE_EQUAL( success(), lendrex( N(alice1111111), core_from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("400.0000"), get_balance( "alice1111111" ) ); - asset rex_balance = get_rex_balance( "alice1111111" ); - - BOOST_REQUIRE_EQUAL( init_rex_balance * 2, rex_balance ); - - BOOST_REQUIRE_EQUAL( success(), unlendrex( N(alice1111111), rex_balance/2 ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( rent_bandwidth, eosio_system_tester ) try { - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( success(), lendrex( N(alice1111111), core_from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); - - asset init_rex_balance = get_rex_balance( "alice1111111" ); - - transfer( "eosio", "bob111111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), rent( N(bob111111111), N(bob111111111), core_from_string("10.0000"), true ) ); - - auto loan = get_last_cpu_loan(); - //std::cout << loan << std::endl; -} FC_LOG_AND_RETHROW() -*/ BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); From 3f4e1189d34f7f8eab1c351efaedb5f66fd4ae64 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 7 Sep 2018 17:19:01 -0400 Subject: [PATCH 0521/1048] REX testing - 2 --- tests/eosio.system_tests.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7cc461b3..cb0226c3 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3367,18 +3367,20 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; const int64_t ratio = 10000; cross_15_percent_threshold(); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const asset init_balance = core_from_string("1000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; for (const auto& a: accounts) { create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + transfer( config::system_account_name, a, init_balance, config::system_account_name ); BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); } BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rent( bob, carol, core_from_string("5.0000"), true ) ); BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); + BOOST_REQUIRE_EQUAL( init_balance - core_from_string("65.0000"), get_balance(alice) ); auto rex_pool = get_rex_pool(); asset init_tot_unlent = rex_pool["total_unlent"].as(); asset init_tot_lendable = rex_pool["total_lendable"].as(); @@ -3387,6 +3389,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); asset fee = core_from_string("7.0000"); BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); + BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 7 BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 7 From 32ca974c1928ba2af439fda56c0c8f626cca1c05 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 10 Sep 2018 13:52:46 -0400 Subject: [PATCH 0522/1048] Change Bancor formula input to initial balances --- eosio.system/src/eosio.system.cpp | 25 ++++++++++++------------- tests/eosio.system_tests.cpp | 2 +- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 76ecc464..260a0420 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -325,7 +325,7 @@ namespace eosiosystem { }); rbalance.modify( bitr, 0, [&]( auto& rb ) { - rb.rex_balance.amount -= rex.amount; + rb.rex_balance.amount -= rex.amount; }); @@ -391,11 +391,10 @@ namespace eosiosystem { int64_t rented_tokens = 0; rextable.modify( itr, 0, [&]( auto& rt ) { + rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += payment.amount; rt.total_lendable.amount += payment.amount; - int64_t unlent = rt.total_lendable.amount - rt.total_lent.amount; - rented_tokens = bancor_convert( rt.total_rent.amount, unlent, payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount = unlent; rt.loan_num++; }); @@ -403,20 +402,20 @@ namespace eosiosystem { rex_cpu_loan_table cpu_loans(_self,_self); cpu_loans.emplace( from, [&]( auto& c ) { - c.receiver = receiver; + c.receiver = receiver; c.total_staked = asset( rented_tokens, CORE_SYMBOL ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); - c.loan_num = itr->loan_num; + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; }); update_resource_limits( receiver, rented_tokens, 0 ); } else { rex_net_loan_table net_loans(_self,_self); net_loans.emplace( from, [&]( auto& c ) { - c.receiver = receiver; + c.receiver = receiver; c.total_staked = asset( rented_tokens, CORE_SYMBOL ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); - c.loan_num = itr->loan_num; + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; }); update_resource_limits( receiver, 0, rented_tokens ); } @@ -437,7 +436,7 @@ namespace eosiosystem { }; rex_cpu_loan_table cpu_loans(_self,_self); - for( uint32_t i = 0; i < max; ++i ) { + for( uint16_t i = 0; i < max; ++i ) { auto itr = cpu_loans.begin(); if( itr == cpu_loans.end() ) break; if( itr->expiration.elapsed.count() > current_time() ) break; @@ -448,7 +447,7 @@ namespace eosiosystem { } rex_net_loan_table net_loans(_self,_self); - for( uint32_t i = 0; i < max; ++i ) { + for( uint16_t i = 0; i < max; ++i ) { auto itr = net_loans.begin(); if( itr == net_loans.end() ) break; if( itr->expiration.elapsed.count() > current_time() ) break; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index cb0226c3..a98a9a98 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3393,7 +3393,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 7 BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 7 - int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount() + fee.get_amount(), fee.get_amount() ); + int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); BOOST_REQUIRE_EQUAL( expected_total_lent, rex_pool["total_lent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); From 1579e49f80deecc8fe0d7a0f513aebb3651478ee Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 10 Sep 2018 15:57:41 -0400 Subject: [PATCH 0523/1048] Revert wrong change --- eosio.system/src/eosio.system.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 260a0420..76c7734b 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -431,6 +431,7 @@ namespace eosiosystem { auto unrent = [&]( int64_t rented_tokens ) { rextable.modify( rexi, 0, [&]( auto& rt ) { + bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); rt.total_lent.amount = rt.total_lendable.amount - rt.total_unlent.amount; }); }; From b3254255415c533ff8fa3652cf400aec8f3ff864 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 11 Sep 2018 13:52:26 -0400 Subject: [PATCH 0524/1048] Create unlendrex request queue --- .../include/eosio.system/eosio.system.hpp | 21 ++- eosio.system/src/eosio.system.cpp | 153 ++++++++++-------- tests/eosio.system_tester.hpp | 2 +- 3 files changed, 107 insertions(+), 69 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 0da4a0e7..d30d4bcf 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -184,6 +184,7 @@ namespace eosiosystem { auto primary_key()const { return owner; } }; + typedef eosio::multi_index< N(rexbal), rex_balance > rex_balance_table; struct rex_loan { @@ -199,6 +200,18 @@ namespace eosiosystem { typedef eosio::multi_index< N(cpuloan), rex_loan> rex_cpu_loan_table; typedef eosio::multi_index< N(cpunet), rex_loan> rex_net_loan_table; + struct rex_request { + account_name owner; + asset rex_requested; + eosio::time_point request_time; + + auto primary_key()const { return owner; } + uint64_t by_request_time()const { return static_cast( -request_time.elapsed.count() ); } + }; + + typedef eosio::multi_index< N(rexqueue), rex_request, + indexed_by>> rex_request_table; + class system_contract : public native { private: voters_table _voters; @@ -211,6 +224,8 @@ namespace eosiosystem { eosio_global_state2 _gstate2; eosio_global_state3 _gstate3; rammarket _rammarket; + rex_pool_table _rextable; + rex_balance_table _rexbalance; public: system_contract( account_name s ); @@ -240,15 +255,13 @@ namespace eosiosystem { /** * Converts REX stake back into SYS tokens at current exchange rate */ - void unlendrex( account_name from, asset rex ); + void unlendrex( account_name from, asset rex ); /** * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ void rent( account_name from, account_name receiver, asset payment, bool cpu ); - void runrex( uint16_t max ); - /** * Decreases the total tokens delegated by from to receiver and/or @@ -323,6 +336,8 @@ namespace eosiosystem { static time_point current_time_point(); static block_timestamp current_block_time(); void update_ram_supply(); + void runrex( uint16_t max ); + bool close_unlendrex_request( const rex_balance_table::const_iterator& bal_itr, const asset& rex ); //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 76c7734b..92cf0d03 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -18,7 +18,9 @@ namespace eosiosystem { _global(_self,_self), _global2(_self,_self), _global3(_self,_self), - _rammarket(_self,_self) + _rammarket(_self,_self), + _rextable(_self,_self), + _rexbalance(_self,_self) { //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); @@ -243,48 +245,44 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), amount, "buy REX" } ); - rex_pool_table rextable(_self,_self); - asset rex_received( 0, S(4,REX) ); - auto itr = rextable.begin(); - if( itr == rextable.end() ) { - rextable.emplace( _self, [&]( auto& rp ){ - rex_received.amount = amount.amount * 10000; + auto itr = _rextable.begin(); + if( itr == _rextable.end() ) { + _rextable.emplace( _self, [&]( auto& rp ){ + rex_received.amount = amount.amount * 10000; - rp.total_lendable = amount; - rp.total_lent = asset( 0, CORE_SYMBOL ); - rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available - rp.total_rex = rex_received; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + rp.total_lendable = amount; + rp.total_lent = asset( 0, CORE_SYMBOL ); + rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available + rp.total_rex = rex_received; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; }); } else { const auto S0 = itr->total_lendable.amount; const auto S1 = S0 + amount.amount; const auto R0 = itr->total_rex.amount; - const auto R1 = (uint128_t(S1) * R0) / S0; rex_received.amount = R1 - R0; - rextable.modify( itr, 0, [&]( auto& rp ) { - rp.total_lendable.amount = S1; - rp.total_rex.amount = R1; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); + _rextable.modify( itr, 0, [&]( auto& rp ) { + rp.total_lendable.amount = S1; + rp.total_rex.amount = R1; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); }); } - rex_balance_table rbalance(_self,_self); - auto bitr = rbalance.find( from ); - if( bitr == rbalance.end() ) { - rbalance.emplace( from, [&]( auto& rb ) { + auto bitr = _rexbalance.find( from ); + if( bitr == _rexbalance.end() ) { + _rexbalance.emplace( from, [&]( auto& rb ) { rb.owner = from; rb.rex_balance = rex_received; }); } else { - rbalance.modify( bitr, 0, [&]( auto& rb ) { + _rexbalance.modify( bitr, 0, [&]( auto& rb ) { rb.rex_balance.amount += rex_received.amount; }); } @@ -294,44 +292,28 @@ namespace eosiosystem { /** * Converts REX stake back into SYS tokens at current exchange rate */ - void system_contract::unlendrex( account_name from, asset rex ) { + void system_contract::unlendrex( account_name from, asset rex ) { runrex(2); require_auth( from ); - rex_pool_table rextable(_self,_self); - auto itr = rextable.begin(); - eosio_assert( itr != rextable.end(), "rex system not initialized yet" ); + auto itr = _rextable.begin(); + eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); - rex_balance_table rbalance(_self,_self); - auto bitr = rbalance.find( from ); - eosio_assert( bitr != rbalance.end(), "user must first lendrex" ); + // rex_balance_table rbalance(_self,_self); + auto bitr = _rexbalance.find( from ); + eosio_assert( bitr != _rexbalance.end(), "user must first lendrex" ); eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); - const auto S0 = itr->total_lendable.amount; - const auto R0 = itr->total_rex.amount; - const auto R1 = R0 - rex.amount; - const auto S1 = (uint128_t(R1) * S0) / R0; - - asset proceeds(S0-S1, CORE_SYMBOL); - - rextable.modify( itr, 0, [&]( auto& rt ) { - rt.total_rex.amount = R1; - rt.total_lendable.amount = S1; - rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; - eosio_assert( rt.total_lendable.amount >= rt.total_lent.amount, "unable to unlendrex until loans expire" );// XXX > or >= - eosio_assert( rt.total_unlent.amount >= 0, "programmer error, this should never go negative" ); - }); - - rbalance.modify( bitr, 0, [&]( auto& rb ) { - rb.rex_balance.amount -= rex.amount; - }); - - - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, - { N(eosio.rex), from, proceeds, "sell REX" } ); - + if( !close_unlendrex_request( bitr, rex ) ) { + rex_request_table rex_requests(_self, _self); + rex_requests.emplace( from, [&]( auto& req ) { + req.owner = from; + req.rex_requested = rex; + req.request_time = current_time_point(); + }); + } } /** @@ -362,9 +344,9 @@ namespace eosiosystem { auto tot_itr = totals_tbl.find( receiver ); eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); totals_tbl.modify( tot_itr, 0, [&]( auto& tot ) { - tot.cpu_weight.amount += delta_cpu; - tot.net_weight.amount += delta_net; - }); + tot.cpu_weight.amount += delta_cpu; + tot.net_weight.amount += delta_net; + }); eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); @@ -385,12 +367,11 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), payment, string("rent ") + (cpu ? "CPU" : "NET") } ); - rex_pool_table rextable(_self,_self); - auto itr = rextable.begin(); - eosio_assert( itr != rextable.end(), "rex system not initialized yet" ); + auto itr = _rextable.begin(); + eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); int64_t rented_tokens = 0; - rextable.modify( itr, 0, [&]( auto& rt ) { + _rextable.modify( itr, 0, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); rt.total_lent.amount += rented_tokens; rt.total_unlent.amount += payment.amount; @@ -425,12 +406,11 @@ namespace eosiosystem { * Perform maitenance operations on expired rex */ void system_contract::runrex( uint16_t max ) { - rex_pool_table rextable(_self,_self); - auto rexi = rextable.begin(); - eosio_assert( rexi != rextable.end(), "rex system not initialized yet" ); + auto rexi = _rextable.begin(); + eosio_assert( rexi != _rextable.end(), "rex system not initialized yet" ); auto unrent = [&]( int64_t rented_tokens ) { - rextable.modify( rexi, 0, [&]( auto& rt ) { + _rextable.modify( rexi, 0, [&]( auto& rt ) { bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); rt.total_lent.amount = rt.total_lendable.amount - rt.total_unlent.amount; }); @@ -457,6 +437,49 @@ namespace eosiosystem { unrent( itr->total_staked.amount ); net_loans.erase( itr ); } + + rex_request_table rex_requests(_self, _self); + auto idx = rex_requests.get_index(); + auto reqitr = idx.begin(); + for( uint16_t i = 0; i < max; ++i ) { + if( reqitr == idx.end() ) break; + auto bitr = _rexbalance.find( reqitr->owner ); + if( bitr == _rexbalance.end() ) { + idx.erase( reqitr++ ); + continue; + } + if( close_unlendrex_request( bitr, reqitr->rex_requested ) ) { + idx.erase( reqitr++ ); + } else { + ++reqitr; + } + } + + } + + bool system_contract::close_unlendrex_request( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + auto rexitr = _rextable.begin(); + const auto S0 = rexitr->total_lendable.amount; + const auto R0 = rexitr->total_rex.amount; + const auto R1 = R0 - rex.amount; + const auto S1 = (uint128_t(R1) * S0) / R0; + asset proceeds(S0-S1, CORE_SYMBOL); + bool success = false; + if( proceeds <= rexitr->total_unlent ) { + _rextable.modify( rexitr, 0, [&]( auto& rt ) { + rt.total_rex.amount = R1; + rt.total_lendable.amount = S1; + rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; + }); + _rexbalance.modify( bitr, 0, [&]( auto& rb ) { + rb.rex_balance.amount -= rex.amount; + }); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, + { N(eosio.rex), bitr->owner, proceeds, "sell REX" } ); + success = true; + } + return success; } void native::setabi( account_name acnt, const bytes& abi ) { @@ -482,7 +505,7 @@ EOSIO_ABI( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(updtrevision)(bidname) - (lendrex)(unlendrex)(rent)(runrex) + (lendrex)(unlendrex)(rent) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index bed6aa32..ebbe4bc4 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -275,7 +275,7 @@ class eosio_system_tester : public TESTER { action_result unlendrex( const account_name& from, const asset& rex ) { return push_action( name(from), N(unlendrex), mvo() ("from", from) - ("rex", rex) + ("rex", rex) ); } From a3f67fa7315d7c160ec0805b037ccf583e43d080 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 11 Sep 2018 15:58:08 -0400 Subject: [PATCH 0525/1048] Add cnclrexorder system contract action --- eosio.system/abi/eosio.system.abi | 24 +++++++++++++++ .../include/eosio.system/eosio.system.hpp | 13 ++++---- eosio.system/src/eosio.system.cpp | 30 ++++++++++++------- 3 files changed, 50 insertions(+), 17 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 0b990ab8..93f39ecd 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -212,6 +212,12 @@ {"name":"from", "type":"account_name"}, {"name":"rex", "type":"asset"} ] + },{ + "name": "cnclrexorder", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"} + ] },{ "name": "rex_balance", "base": "", @@ -239,6 +245,14 @@ {"name":"total_stake", "type":"asset"}, {"name":"loan_num", "type":"uint64"} ] + },{ + "name": "rex_order", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"rex_requested", "type":"asset"}, + {"name":"order_time", "type":"time_point"} + ] },{ "name": "rent", "base": "", @@ -565,6 +579,10 @@ "name": "unlendrex", "type": "unlendrex", "ricardian_contract": "" + },{ + "name": "cnclrexorder", + "type": "cnclrexorder", + "ricardian_contract": "" },{ "name": "rent", "type": "rent", @@ -694,6 +712,12 @@ "index_type": "i64", "key_names" : ["owner"], "key_types" : ["uint64"] + },{ + "name": "rexqueue", + "type": "rex_order", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] },{ "name": "cpuloan", "type": "rex_loan", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index d30d4bcf..fd1ad1bc 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -200,17 +200,17 @@ namespace eosiosystem { typedef eosio::multi_index< N(cpuloan), rex_loan> rex_cpu_loan_table; typedef eosio::multi_index< N(cpunet), rex_loan> rex_net_loan_table; - struct rex_request { + struct rex_order { account_name owner; asset rex_requested; - eosio::time_point request_time; + eosio::time_point order_time; auto primary_key()const { return owner; } - uint64_t by_request_time()const { return static_cast( -request_time.elapsed.count() ); } + uint64_t by_time()const { return static_cast( -order_time.elapsed.count() ); } }; - typedef eosio::multi_index< N(rexqueue), rex_request, - indexed_by>> rex_request_table; + typedef eosio::multi_index< N(rexqueue), rex_order, + indexed_by>> rex_order_table; class system_contract : public native { private: @@ -256,6 +256,7 @@ namespace eosiosystem { * Converts REX stake back into SYS tokens at current exchange rate */ void unlendrex( account_name from, asset rex ); + void cnclrexorder( account_name from ); /** * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, @@ -337,7 +338,7 @@ namespace eosiosystem { static block_timestamp current_block_time(); void update_ram_supply(); void runrex( uint16_t max ); - bool close_unlendrex_request( const rex_balance_table::const_iterator& bal_itr, const asset& rex ); + bool close_rex_order( const rex_balance_table::const_iterator& bal_itr, const asset& rex ); //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 92cf0d03..19239bf5 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -306,16 +306,24 @@ namespace eosiosystem { eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); - if( !close_unlendrex_request( bitr, rex ) ) { - rex_request_table rex_requests(_self, _self); - rex_requests.emplace( from, [&]( auto& req ) { - req.owner = from; - req.rex_requested = rex; - req.request_time = current_time_point(); + if( !close_rex_order( bitr, rex ) ) { + rex_order_table rexorders(_self, _self); + rexorders.emplace( from, [&]( auto& ordr ) { + ordr.owner = from; + ordr.rex_requested = rex; + ordr.order_time = current_time_point(); }); } } + void system_contract::cnclrexorder( account_name from ) { + require_auth( from ); + rex_order_table rexorders(_self, _self); + auto itr = rexorders.find( from ); + eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); + rexorders.erase( itr ); + } + /** * Given two connector balances (conin, and conout), and an incoming amount of * in, this function will modify conin and conout and return the delta out. @@ -438,8 +446,8 @@ namespace eosiosystem { net_loans.erase( itr ); } - rex_request_table rex_requests(_self, _self); - auto idx = rex_requests.get_index(); + rex_order_table rexorders(_self, _self); + auto idx = rexorders.get_index(); auto reqitr = idx.begin(); for( uint16_t i = 0; i < max; ++i ) { if( reqitr == idx.end() ) break; @@ -448,7 +456,7 @@ namespace eosiosystem { idx.erase( reqitr++ ); continue; } - if( close_unlendrex_request( bitr, reqitr->rex_requested ) ) { + if( close_rex_order( bitr, reqitr->rex_requested ) ) { idx.erase( reqitr++ ); } else { ++reqitr; @@ -457,7 +465,7 @@ namespace eosiosystem { } - bool system_contract::close_unlendrex_request( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + bool system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; @@ -505,7 +513,7 @@ EOSIO_ABI( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(updtrevision)(bidname) - (lendrex)(unlendrex)(rent) + (lendrex)(unlendrex)(cnclrexorder)(rent) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp From e40aa61dec1d00c5ae92540fb480968804add0d6 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Sep 2018 10:48:02 -0400 Subject: [PATCH 0526/1048] Remove transfer from rex order queue processing, add claimrex --- eosio.system/abi/eosio.system.abi | 8 ++- .../include/eosio.system/eosio.system.hpp | 12 ++-- eosio.system/src/eosio.system.cpp | 58 ++++++++++++------- tests/eosio.system_tester.hpp | 4 ++ tests/eosio.system_tests.cpp | 18 ++++++ 5 files changed, 74 insertions(+), 26 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 93f39ecd..a2b5c0f8 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -216,7 +216,13 @@ "name": "cnclrexorder", "base": "", "fields": [ - {"name":"from", "type":"account_name"} + {"name":"owner", "type":"account_name"} + ] + },{ + "name": "claimrex", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} ] },{ "name": "rex_balance", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index fd1ad1bc..f4c2125c 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -203,10 +203,13 @@ namespace eosiosystem { struct rex_order { account_name owner; asset rex_requested; + asset proceeds; eosio::time_point order_time; - + bool is_open = true; + + void close() { is_open = false; } auto primary_key()const { return owner; } - uint64_t by_time()const { return static_cast( -order_time.elapsed.count() ); } + uint64_t by_time()const { return is_open? -order_time.elapsed.count(): order_time.elapsed.count(); } }; typedef eosio::multi_index< N(rexqueue), rex_order, @@ -256,7 +259,8 @@ namespace eosiosystem { * Converts REX stake back into SYS tokens at current exchange rate */ void unlendrex( account_name from, asset rex ); - void cnclrexorder( account_name from ); + void cnclrexorder( account_name owner ); + void claimrex( account_name owner ); /** * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, @@ -338,7 +342,7 @@ namespace eosiosystem { static block_timestamp current_block_time(); void update_ram_supply(); void runrex( uint16_t max ); - bool close_rex_order( const rex_balance_table::const_iterator& bal_itr, const asset& rex ); + std::pair close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 19239bf5..c7bc6c5e 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -300,30 +300,45 @@ namespace eosiosystem { auto itr = _rextable.begin(); eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); - // rex_balance_table rbalance(_self,_self); auto bitr = _rexbalance.find( from ); eosio_assert( bitr != _rexbalance.end(), "user must first lendrex" ); eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); - if( !close_rex_order( bitr, rex ) ) { + auto result = close_rex_order( bitr, rex ); + if( result.first ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, + { N(eosio.rex), from, result.second, "sell REX" } ); + } else { rex_order_table rexorders(_self, _self); rexorders.emplace( from, [&]( auto& ordr ) { ordr.owner = from; ordr.rex_requested = rex; - ordr.order_time = current_time_point(); + ordr.order_time = current_time_point(); }); } } - void system_contract::cnclrexorder( account_name from ) { - require_auth( from ); + void system_contract::cnclrexorder( account_name owner ) { + require_auth( owner ); rex_order_table rexorders(_self, _self); - auto itr = rexorders.find( from ); + auto itr = rexorders.find( owner ); eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); rexorders.erase( itr ); } + void system_contract::claimrex( account_name owner ) { + runrex(2); + require_auth( owner ); + rex_order_table rexorders(_self, _self); + auto itr = rexorders.find( owner ); + eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); + eosio_assert( !itr->is_open, "rex order hasn't been closed" ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, + { N(eosio.rex), itr->owner, itr->proceeds, "sell REX" } ); + rexorders.erase( itr ); + } + /** * Given two connector balances (conin, and conout), and an incoming amount of * in, this function will modify conin and conout and return the delta out. @@ -448,24 +463,28 @@ namespace eosiosystem { rex_order_table rexorders(_self, _self); auto idx = rexorders.get_index(); - auto reqitr = idx.begin(); + auto oitr = idx.begin(); for( uint16_t i = 0; i < max; ++i ) { - if( reqitr == idx.end() ) break; - auto bitr = _rexbalance.find( reqitr->owner ); + if( oitr == idx.end() || !oitr->is_open ) break; + auto bitr = _rexbalance.find( oitr->owner ); if( bitr == _rexbalance.end() ) { - idx.erase( reqitr++ ); + idx.erase( oitr++ ); continue; } - if( close_rex_order( bitr, reqitr->rex_requested ) ) { - idx.erase( reqitr++ ); - } else { - ++reqitr; + auto result = close_rex_order( bitr, oitr->rex_requested ); + auto next = oitr; + if( result.first ) { + idx.modify( oitr, 0, [&]( auto& rt ) { + rt.proceeds.amount = result.second.amount; + rt.close(); + }); } + oitr = ++next; } } - bool system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; @@ -477,17 +496,14 @@ namespace eosiosystem { _rextable.modify( rexitr, 0, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; - rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; + rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; }); _rexbalance.modify( bitr, 0, [&]( auto& rb ) { rb.rex_balance.amount -= rex.amount; }); - - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, - { N(eosio.rex), bitr->owner, proceeds, "sell REX" } ); success = true; } - return success; + return std::make_pair(success, proceeds); } void native::setabi( account_name acnt, const bytes& abi ) { @@ -513,7 +529,7 @@ EOSIO_ABI( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(rmvproducer)(updtrevision)(bidname) - (lendrex)(unlendrex)(cnclrexorder)(rent) + (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rent) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index ebbe4bc4..9616fc09 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -279,6 +279,10 @@ class eosio_system_tester : public TESTER { ); } + action_result cancelrexorder( const account_name& owner ) { + return push_action( name(owner), N(cnclrexorder), mvo()("owner", owner) ); + } + action_result rent( const account_name& from, const account_name& receiver, const asset& payment, bool cpu ) { return push_action( name(from), N(rent), mvo() ("from", from) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index a98a9a98..7737566f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3378,7 +3378,9 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); } + // bob tries to rent rex BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rent( bob, carol, core_from_string("5.0000"), true ) ); + // alice lends rex BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); BOOST_REQUIRE_EQUAL( init_balance - core_from_string("65.0000"), get_balance(alice) ); auto rex_pool = get_rex_pool(); @@ -3387,6 +3389,8 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { asset init_tot_rent = rex_pool["total_rent"].as(); BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); + // bob rents cpu for carol asset fee = core_from_string("7.0000"); BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); @@ -3396,6 +3400,20 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); BOOST_REQUIRE_EQUAL( expected_total_lent, rex_pool["total_lent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); + // alice tries to unlendrex, order gets scheduled then she scheduled cancels order + BOOST_REQUIRE_EQUAL( wasm_assert_msg("no unlendrex is scheduled"), cancelrexorder( alice ) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); + + produce_block( fc::days(20) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + produce_block( fc::days(10) ); + // alice is finally able to unlendrex, she gains the fee paid by bob + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(alice) ); + BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); } FC_LOG_AND_RETHROW() From 3959d0057b42df15a6741a4e8796d9f885371349 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Sep 2018 18:43:30 -0400 Subject: [PATCH 0527/1048] Fix bug in rent rex - testing --- eosio.system/abi/eosio.system.abi | 8 +++- eosio.system/src/eosio.system.cpp | 10 ++--- tests/eosio.system_tester.hpp | 4 ++ tests/eosio.system_tests.cpp | 67 ++++++++++++++++++++++++++++--- 4 files changed, 77 insertions(+), 12 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index a2b5c0f8..de45915e 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -257,7 +257,9 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"rex_requested", "type":"asset"}, - {"name":"order_time", "type":"time_point"} + {"name":"proceeds", "type":"asset"}, + {"name":"order_time", "type":"time_point"}, + {"name":"is_open", "type":"bool"} ] },{ "name": "rent", @@ -589,6 +591,10 @@ "name": "cnclrexorder", "type": "cnclrexorder", "ricardian_contract": "" + },{ + "name": "claimrex", + "type": "claimrex", + "ricardian_contract": "" },{ "name": "rent", "type": "rent", diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index c7bc6c5e..0295c313 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -319,7 +319,7 @@ namespace eosiosystem { } } - void system_contract::cnclrexorder( account_name owner ) { + void system_contract::cnclrexorder( account_name owner ) { require_auth( owner ); rex_order_table rexorders(_self, _self); auto itr = rexorders.find( owner ); @@ -328,8 +328,8 @@ namespace eosiosystem { } void system_contract::claimrex( account_name owner ) { - runrex(2); require_auth( owner ); + runrex(2); rex_order_table rexorders(_self, _self); auto itr = rexorders.find( owner ); eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); @@ -395,10 +395,8 @@ namespace eosiosystem { int64_t rented_tokens = 0; _rextable.modify( itr, 0, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += payment.amount; - rt.total_lendable.amount += payment.amount; + rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); + rt.total_lent.amount += rented_tokens; rt.loan_num++; }); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 9616fc09..1bf7085b 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -283,6 +283,10 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(cnclrexorder), mvo()("owner", owner) ); } + action_result claimrex( const account_name& owner ) { + return push_action( name(owner), N(claimrex), mvo()("owner", owner) ); + } + action_result rent( const account_name& from, const account_name& receiver, const asset& payment, bool cpu ) { return push_action( name(from), N(rent), mvo() ("from", from) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7737566f..70d8984e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3395,12 +3395,12 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 7 + BOOST_REQUIRE_EQUAL( init_tot_lendable /* + fee */, rex_pool["total_lendable"].as() ); // 65 + 7 BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 7 int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); BOOST_REQUIRE_EQUAL( expected_total_lent, rex_pool["total_lent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); - // alice tries to unlendrex, order gets scheduled then she scheduled cancels order + // alice tries to unlendrex, order gets scheduled then she cancels order BOOST_REQUIRE_EQUAL( wasm_assert_msg("no unlendrex is scheduled"), cancelrexorder( alice ) ); BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); @@ -3411,9 +3411,66 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); produce_block( fc::days(10) ); // alice is finally able to unlendrex, she gains the fee paid by bob - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(alice) ); - BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); + BOOST_REQUIRE_EQUAL( init_balance, get_balance(alice) ); + + rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( init_tot_rent, rex_pool["total_rent"].as() ); + +} FC_LOG_AND_RETHROW() + + +BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { + + auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; + const int64_t ratio = 10000; + cross_15_percent_threshold(); + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const asset init_balance = core_from_string("5000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, init_balance, config::system_account_name ); + BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); + } + + // alice, bob, carol and emily lend rex + asset rex_purchace[] = { core_from_string("67.0000"), + core_from_string("45.0000"), + core_from_string("38.0000"), + core_from_string("1.0000") }; + for (uint16_t i = 0; i < 4; ++i) { + BOOST_REQUIRE_EQUAL( success(), lendrex( accounts[i], rex_purchace[i] ) ); + BOOST_REQUIRE_EQUAL( init_balance - rex_purchace[i], get_balance(accounts[i]) ); + } + auto rex_pool = get_rex_pool(); + asset init_tot_unlent = rex_pool["total_unlent"].as(); + asset init_tot_lendable = rex_pool["total_lendable"].as(); + asset init_tot_rent = rex_pool["total_rent"].as(); + auto init_alice_rex = get_rex_balance(alice); + auto init_bob_rex = get_rex_balance(bob); + auto init_carol_rex = get_rex_balance(carol); + auto init_emily_rex = get_rex_balance(emily); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), init_alice_rex + init_bob_rex + init_carol_rex + init_emily_rex ); + + // frank rents rex + const auto fee = core_from_string("1000.0000"); + BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, fee, true ) ); + + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, init_alice_rex ) ); + BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, init_carol_rex ) ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, init_bob_rex ) ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( emily, init_emily_rex ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance(emily).get_amount() ); } FC_LOG_AND_RETHROW() From 2089233b7969d4712cb59cedb1c54c2b0a35dd8b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 13 Sep 2018 18:46:05 -0400 Subject: [PATCH 0528/1048] More REX testing, bug fixes --- .../include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/eosio.system.cpp | 23 +++++---- tests/eosio.system_tester.hpp | 5 ++ tests/eosio.system_tests.cpp | 51 ++++++++++++++++--- 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index f4c2125c..5020180d 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -209,7 +209,7 @@ namespace eosiosystem { void close() { is_open = false; } auto primary_key()const { return owner; } - uint64_t by_time()const { return is_open? -order_time.elapsed.count(): order_time.elapsed.count(); } + uint64_t by_time()const { return is_open? order_time.elapsed.count(): -order_time.elapsed.count(); } }; typedef eosio::multi_index< N(rexqueue), rex_order, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 0295c313..1ce308d2 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -311,6 +311,7 @@ namespace eosiosystem { { N(eosio.rex), from, result.second, "sell REX" } ); } else { rex_order_table rexorders(_self, _self); + eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); rexorders.emplace( from, [&]( auto& ordr ) { ordr.owner = from; ordr.rex_requested = rex; @@ -324,6 +325,7 @@ namespace eosiosystem { rex_order_table rexorders(_self, _self); auto itr = rexorders.find( owner ); eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); + eosio_assert( itr->is_open, "rex order has been closed and cannot be canceled" ); rexorders.erase( itr ); } @@ -333,7 +335,7 @@ namespace eosiosystem { rex_order_table rexorders(_self, _self); auto itr = rexorders.find( owner ); eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); - eosio_assert( !itr->is_open, "rex order hasn't been closed" ); + eosio_assert( !itr->is_open, "rex order has not been closed" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, { N(eosio.rex), itr->owner, itr->proceeds, "sell REX" } ); rexorders.erase( itr ); @@ -432,8 +434,10 @@ namespace eosiosystem { auto unrent = [&]( int64_t rented_tokens ) { _rextable.modify( rexi, 0, [&]( auto& rt ) { - bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); - rt.total_lent.amount = rt.total_lendable.amount - rt.total_unlent.amount; + auto fee = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); + rt.total_lent.amount -= rented_tokens; + rt.total_unlent.amount += fee; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); }; @@ -471,25 +475,26 @@ namespace eosiosystem { } auto result = close_rex_order( bitr, oitr->rex_requested ); auto next = oitr; + ++next; if( result.first ) { idx.modify( oitr, 0, [&]( auto& rt ) { rt.proceeds.amount = result.second.amount; rt.close(); }); } - oitr = ++next; + oitr = next; } } std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex) { auto rexitr = _rextable.begin(); - const auto S0 = rexitr->total_lendable.amount; - const auto R0 = rexitr->total_rex.amount; - const auto R1 = R0 - rex.amount; - const auto S1 = (uint128_t(R1) * S0) / R0; + const auto S0 = rexitr->total_lendable.amount; + const auto R0 = rexitr->total_rex.amount; + const auto R1 = R0 - rex.amount; + const auto S1 = (uint128_t(R1) * S0) / R0; asset proceeds(S0-S1, CORE_SYMBOL); - bool success = false; + bool success = false; if( proceeds <= rexitr->total_unlent ) { _rextable.modify( rexitr, 0, [&]( auto& rt ) { rt.total_rex.amount = R1; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 1bf7085b..f30f7a60 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -335,6 +335,11 @@ class eosio_system_tester : public TESTER { return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); } + fc::variant get_rex_order( const account_name& act ) { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); + return abi_ser.binary_to_variant( "rex_order", data, abi_serializer_max_time ); + } + fc::variant get_rex_pool() const { vector data; const auto& db = control->db(); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 70d8984e..aa28eefd 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3411,9 +3411,9 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); produce_block( fc::days(10) ); // alice is finally able to unlendrex, she gains the fee paid by bob - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( init_balance, get_balance(alice) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); + // BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); @@ -3429,7 +3429,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { cross_15_percent_threshold(); const asset net = core_from_string("80.0000"); const asset cpu = core_from_string("80.0000"); - const asset init_balance = core_from_string("5000.0000"); + const asset init_balance = core_from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; for (const auto& a: accounts) { @@ -3463,15 +3463,54 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { const auto fee = core_from_string("1000.0000"); BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, fee, true ) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, init_alice_rex ) ); + // alice, bob, carol and emily try to unlend rex + // emily's order is successfuly processed while others' orders are queued + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, init_alice_rex ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("an unlendrex request has already been scheduled"), + unlendrex( alice, init_alice_rex ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), + claimrex( alice ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, init_carol_rex ) ); + + BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, init_carol_rex ) ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, init_bob_rex ) ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); + + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( emily, init_emily_rex ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(emily).get_amount() ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); + + produce_block( fc::hours(29*24 + 23) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); + produce_block( fc::hours(2) ); + + // some action is needed to trigger loan and rex queue processing + BOOST_REQUIRE_EQUAL( success(), lendrex( frank, core_from_string("0.0001") ) ); + // 2 rex orders are processed (alice and carol) + BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(alice)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance(carol).get_amount() ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); + // bob's order is still in the queue and can be canceled + BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( bob ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has been closed and cannot be canceled"), + cancelrexorder( carol ) ); + BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); + } FC_LOG_AND_RETHROW() From 581183e52b254f052956b2f151df4978a3258b98 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 14 Sep 2018 10:18:23 -0400 Subject: [PATCH 0529/1048] fix eosio.msig ABI definition for approvals_info struct #75 --- eosio.msig/abi/eosio.msig.abi | 1 + 1 file changed, 1 insertion(+) diff --git a/eosio.msig/abi/eosio.msig.abi b/eosio.msig/abi/eosio.msig.abi index 4fe2325c..473198dc 100644 --- a/eosio.msig/abi/eosio.msig.abi +++ b/eosio.msig/abi/eosio.msig.abi @@ -125,6 +125,7 @@ "name": "approvals_info", "base": "", "fields": [ + {"name": "version", "type": "uint8"}, {"name": "proposal_name", "type": "name"}, {"name": "requested_approvals", "type": "approval[]"}, {"name": "provided_approvals", "type": "approval[]"} From 9ebd1c092a72f40b9ecd4322b24db3d578f5b844 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 17 Sep 2018 09:36:18 -0400 Subject: [PATCH 0530/1048] Add rent to rex pool upon loan creation and not expiry --- eosio.system/src/eosio.system.cpp | 6 ++- tests/eosio.system_tests.cpp | 62 +++++++++++++++++-------------- 2 files changed, 39 insertions(+), 29 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 1ce308d2..ddfdf1cc 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -398,7 +398,9 @@ namespace eosiosystem { int64_t rented_tokens = 0; _rextable.modify( itr, 0, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); - rt.total_lent.amount += rented_tokens; + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; rt.loan_num++; }); @@ -436,7 +438,7 @@ namespace eosiosystem { _rextable.modify( rexi, 0, [&]( auto& rt ) { auto fee = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); rt.total_lent.amount -= rented_tokens; - rt.total_unlent.amount += fee; + // rt.total_unlent.amount += fee; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); }; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index aa28eefd..4754b0a0 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3384,26 +3384,26 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); BOOST_REQUIRE_EQUAL( init_balance - core_from_string("65.0000"), get_balance(alice) ); auto rex_pool = get_rex_pool(); - asset init_tot_unlent = rex_pool["total_unlent"].as(); - asset init_tot_lendable = rex_pool["total_lendable"].as(); - asset init_tot_rent = rex_pool["total_rent"].as(); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + const asset init_tot_unlent = rex_pool["total_unlent"].as(); + const asset init_tot_lendable = rex_pool["total_lendable"].as(); + const asset init_tot_rent = rex_pool["total_rent"].as(); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); + BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); // bob rents cpu for carol - asset fee = core_from_string("7.0000"); - BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); + const asset fee = core_from_string("17.0000"); + BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable /* + fee */, rex_pool["total_lendable"].as() ); // 65 + 7 - BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 7 + BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 17 + BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); BOOST_REQUIRE_EQUAL( expected_total_lent, rex_pool["total_lent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); // alice tries to unlendrex, order gets scheduled then she cancels order - BOOST_REQUIRE_EQUAL( wasm_assert_msg("no unlendrex is scheduled"), cancelrexorder( alice ) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no unlendrex is scheduled") ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); produce_block( fc::days(20) ); @@ -3413,11 +3413,14 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { // alice is finally able to unlendrex, she gains the fee paid by bob BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - // BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); + BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( init_tot_rent, rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_unlent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); + // The following test is not always true, need to be replaced + // BOOST_REQUIRE_EQUAL( init_tot_rent, rex_pool["total_rent"].as() ); } FC_LOG_AND_RETHROW() @@ -3439,14 +3442,22 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { } // alice, bob, carol and emily lend rex - asset rex_purchace[] = { core_from_string("67.0000"), - core_from_string("45.0000"), - core_from_string("38.0000"), + asset rex_purchace[] = { core_from_string("270.0000"), + core_from_string("350.0000"), + core_from_string("400.0000"), core_from_string("1.0000") }; for (uint16_t i = 0; i < 4; ++i) { + std::cout << i << std::endl; BOOST_REQUIRE_EQUAL( success(), lendrex( accounts[i], rex_purchace[i] ) ); BOOST_REQUIRE_EQUAL( init_balance - rex_purchace[i], get_balance(accounts[i]) ); + int64_t amount = (5 + i) * 50 * 10000; + asset fee( amount, symbol(SY(4, SYS)) ); + BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, fee, i%2 == 0 ) ); + auto init_rex_balance = get_rex_balance(accounts[i]); + BOOST_REQUIRE_EQUAL( success(), unlendrex( accounts[i], get_rex_balance(accounts[i]) ) ); + BOOST_REQUIRE_EQUAL( init_rex_balance, get_rex_balance(accounts[i]) ); } + return; auto rex_pool = get_rex_pool(); asset init_tot_unlent = rex_pool["total_unlent"].as(); asset init_tot_lendable = rex_pool["total_lendable"].as(); @@ -3455,13 +3466,13 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); auto init_emily_rex = get_rex_balance(emily); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); + // BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + // BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), init_alice_rex + init_bob_rex + init_carol_rex + init_emily_rex ); // frank rents rex - const auto fee = core_from_string("1000.0000"); - BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, fee, true ) ); + // const auto fee = core_from_string("2000.0000"); + // BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, fee, true ) ); // alice, bob, carol and emily try to unlend rex // emily's order is successfuly processed while others' orders are queued @@ -3474,19 +3485,16 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); + // BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_rex_pool()["total_unlent"].as() ); BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, init_carol_rex ) ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); + // BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, init_bob_rex ) ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( emily, init_emily_rex ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(emily).get_amount() ); - - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); - + return; produce_block( fc::hours(29*24 + 23) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); produce_block( fc::hours(2) ); From 40eecfac2a1d936ff423dc488865973e8baf26d1 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 18 Sep 2018 14:03:23 -0400 Subject: [PATCH 0531/1048] bump version to 1.3.1 --- CMakeLists.txt | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index eb45f222..578a5a46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.3.0) +project(eosio_contracts VERSION 1.3.1) set(EOSIO_DEPENDENCY "1.2") set(EOSIO_CDT_DEPENDENCY "1.2") diff --git a/README.md b/README.md index 2c7e7e16..6412a30b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.3.0 +## Version : 1.3.1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.2.x](https://github.com/EOSIO/eos/releases/tag/v1.2.4) -* [eosio.cdt v1.2.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.2.0) +* [eosio v1.2.x](https://github.com/EOSIO/eos/releases/tag/v1.2.5) +* [eosio.cdt v1.2.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.2.1) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From 51b9908f407294fc0234f26f113699f6ddae6dc8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 18 Sep 2018 14:30:27 -0400 Subject: [PATCH 0532/1048] Fix REX unit test --- eosio.system/src/eosio.system.cpp | 1 - tests/eosio.system_tests.cpp | 139 +++++++++++++++--------------- 2 files changed, 69 insertions(+), 71 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index ddfdf1cc..fca97f31 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -438,7 +438,6 @@ namespace eosiosystem { _rextable.modify( rexi, 0, [&]( auto& rt ) { auto fee = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); rt.total_lent.amount -= rented_tokens; - // rt.total_unlent.amount += fee; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); }; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 4754b0a0..d34be48d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3441,84 +3441,83 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); } - // alice, bob, carol and emily lend rex - asset rex_purchace[] = { core_from_string("270.0000"), - core_from_string("350.0000"), - core_from_string("400.0000"), - core_from_string("1.0000") }; - for (uint16_t i = 0; i < 4; ++i) { - std::cout << i << std::endl; - BOOST_REQUIRE_EQUAL( success(), lendrex( accounts[i], rex_purchace[i] ) ); - BOOST_REQUIRE_EQUAL( init_balance - rex_purchace[i], get_balance(accounts[i]) ); - int64_t amount = (5 + i) * 50 * 10000; - asset fee( amount, symbol(SY(4, SYS)) ); - BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, fee, i%2 == 0 ) ); - auto init_rex_balance = get_rex_balance(accounts[i]); - BOOST_REQUIRE_EQUAL( success(), unlendrex( accounts[i], get_rex_balance(accounts[i]) ) ); - BOOST_REQUIRE_EQUAL( init_rex_balance, get_rex_balance(accounts[i]) ); - } - return; - auto rex_pool = get_rex_pool(); - asset init_tot_unlent = rex_pool["total_unlent"].as(); - asset init_tot_lendable = rex_pool["total_lendable"].as(); - asset init_tot_rent = rex_pool["total_rent"].as(); - auto init_alice_rex = get_rex_balance(alice); - auto init_bob_rex = get_rex_balance(bob); - auto init_carol_rex = get_rex_balance(carol); - auto init_emily_rex = get_rex_balance(emily); - // BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); - // BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), init_alice_rex + init_bob_rex + init_carol_rex + init_emily_rex ); - - // frank rents rex - // const auto fee = core_from_string("2000.0000"); - // BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, fee, true ) ); - - // alice, bob, carol and emily try to unlend rex - // emily's order is successfuly processed while others' orders are queued - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, init_alice_rex ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("an unlendrex request has already been scheduled"), - unlendrex( alice, init_alice_rex ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), - claimrex( alice ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); - - // BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_rex_pool()["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, init_carol_rex ) ); - // BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, init_bob_rex ) ); + auto purchase1 = core_from_string("880.0000"); + auto purchase2 = core_from_string("471.0000"); + auto purchase3 = core_from_string("469.0000"); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, purchase1) ); + BOOST_REQUIRE_EQUAL( success(), lendrex( bob, purchase2) ); + BOOST_REQUIRE_EQUAL( success(), lendrex( carol, purchase3) ); + + BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_balance(alice) ); + BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_balance(bob) ); + BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_balance(carol) ); + + auto init_alice_rex = get_rex_balance(alice); + auto init_bob_rex = get_rex_balance(bob); + auto init_carol_rex = get_rex_balance(carol); + + BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, core_from_string("1100.0000"), true ) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); + init_alice_rex = get_rex_balance(alice); + BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, get_rex_balance(bob) ) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, get_rex_balance(carol) ) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); - - BOOST_REQUIRE_EQUAL( success(), unlendrex( emily, init_emily_rex ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(emily).get_amount() ); - return; - produce_block( fc::hours(29*24 + 23) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); - produce_block( fc::hours(2) ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); + BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); - // some action is needed to trigger loan and rex queue processing - BOOST_REQUIRE_EQUAL( success(), lendrex( frank, core_from_string("0.0001") ) ); - // 2 rex orders are processed (alice and carol) - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); + // now bob's, carol's and alice's unlendrex requests have been queued + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(carol).get_amount() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); - // bob's order is still in the queue and can be canceled + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( bob ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(bob)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); + + // wait for 30 days minus 1 hour + produce_block( fc::hours(29*24 + 23) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( bob ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( carol ) ); + + // wait for 2 more hours, by now frank's loan has expired and there is enough balance in + // total_unlent to close some unlendrex orders. only two are processed, bob's and carol's + // alices's order is still open + // an action is needed to trigger queue processing + produce_block( fc::hours(2) ); + BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, core_from_string("0.0001"), true ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("an unlendrex request has already been scheduled"), + unlendrex( alice, init_alice_rex ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), + claimrex( alice ) ); + + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has been closed and cannot be canceled"), - cancelrexorder( carol ) ); - BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); + BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), + claimrex( alice ) ); + + BOOST_REQUIRE_EQUAL( success(), lendrex( emily, core_from_string("100.0000")) ); + BOOST_REQUIRE_EQUAL( success(), claimrex( alice ) ); + } FC_LOG_AND_RETHROW() From 3b63ee3a0d6515bd580acc426d666bdcd1c14672 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 18 Sep 2018 17:49:17 -0400 Subject: [PATCH 0533/1048] bump up eos dependency link in README to latest eos tag with compatible minor version --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6412a30b..02cecc92 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.2.x](https://github.com/EOSIO/eos/releases/tag/v1.2.5) +* [eosio v1.2.x](https://github.com/EOSIO/eos/releases/tag/v1.2.6) * [eosio.cdt v1.2.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.2.1) To build the contracts and the unit tests: From c18a5e53e75eecf11158d2aff3e8980120e8667a Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 18 Sep 2018 17:54:05 -0400 Subject: [PATCH 0534/1048] Test REX resource limit update --- tests/eosio.system_tests.cpp | 110 +++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d34be48d..b575be25 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3365,15 +3365,26 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; + auto get_net_limit = [&](account_name a) -> int64_t { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return net; + }; + auto get_cpu_limit = [&](account_name a) -> int64_t { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return cpu; + }; + const int64_t ratio = 10000; cross_15_percent_threshold(); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset init_net = core_from_string("70.0000"); + const asset init_cpu = core_from_string("90.0000"); const asset init_balance = core_from_string("1000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, init_net, init_cpu ); transfer( config::system_account_name, a, init_balance, config::system_account_name ); BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); } @@ -3390,37 +3401,65 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); - // bob rents cpu for carol - const asset fee = core_from_string("17.0000"); - BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); - BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 17 - BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 - int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); - BOOST_REQUIRE_EQUAL( expected_total_lent, rex_pool["total_lent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); - // alice tries to unlendrex, order gets scheduled then she cancels order - BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no unlendrex is scheduled") ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); - - produce_block( fc::days(20) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - produce_block( fc::days(10) ); - // alice is finally able to unlendrex, she gains the fee paid by bob - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_unlent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); - // The following test is not always true, need to be replaced - // BOOST_REQUIRE_EQUAL( init_tot_rent, rex_pool["total_rent"].as() ); + { + // bob rents cpu for carol + const asset fee = core_from_string("17.0000"); + BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); + BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); + rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 17 + BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 + int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); + BOOST_REQUIRE_EQUAL( expected_total_lent, + rex_pool["total_lent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), + rex_pool["total_lendable"].as() ); + + // test that carol's resource limits have been updated properly + BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu.get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net.get_amount() ); + + // alice tries to unlendrex, order gets scheduled then she cancels order + BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no unlendrex is scheduled") ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); + + produce_block( fc::days(20) ); + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + produce_block( fc::days(10) ); + // alice is finally able to unlendrex, she gains the fee paid by bob + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); + BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); + // test that carol's resource limits have been updated properly when loan expires + BOOST_REQUIRE_EQUAL( 0, get_cpu_limit( carol ) - init_cpu.get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net.get_amount() ); + + rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_unlent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); + // The following test is not always true, need to be replaced + // BOOST_REQUIRE_EQUAL( init_tot_rent, rex_pool["total_rent"].as() ); + } + + { + // the following fails with "divide by zero" error message!! + // need to fix the corner case where rex system has been initialized but + // balances are zero + BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("110.0000") ) ); + rex_pool = get_rex_pool(); + const asset fee = core_from_string("132.4560"); + int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), + rex_pool["total_unlent"].as().get_amount(), + fee.get_amount() ); + BOOST_REQUIRE_EQUAL( success(), rent( emily, emily, fee, false ) ); + BOOST_REQUIRE_EQUAL( expected_net, get_net_limit( emily ) - init_net.get_amount() ); + } } FC_LOG_AND_RETHROW() @@ -3441,7 +3480,6 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); } - auto purchase1 = core_from_string("880.0000"); auto purchase2 = core_from_string("471.0000"); auto purchase3 = core_from_string("469.0000"); From 6453e70e7dc567834534ac53743983fe2e08fe0e Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 24 Sep 2018 13:34:14 -0400 Subject: [PATCH 0535/1048] Update CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 578a5a46..2d060420 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,7 +15,7 @@ if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) set(EOSIO_ROOT "/usr/local/eosio") endif() -if(EOSIO_CDT_ROOT STREQUAL "" OR NOT EOSIO__ROOT) +if(EOSIO_CDT_ROOT STREQUAL "" OR NOT EOSIO_CDT_ROOT) set(EOSIO_CDT_ROOT "/usr/local/eosio.cdt") endif() From d9aa86ff93fe8e004a9b08757941579cb751a84c Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 25 Sep 2018 14:33:53 -0400 Subject: [PATCH 0536/1048] add setparams action to bios contract --- eosio.bios/abi/eosio.bios.abi | 32 ++++++++++++++++++++ eosio.bios/include/eosio.bios/eosio.bios.hpp | 11 +++++-- eosio.bios/src/eosio.bios.cpp | 2 +- 3 files changed, 41 insertions(+), 4 deletions(-) diff --git a/eosio.bios/abi/eosio.bios.abi b/eosio.bios/abi/eosio.bios.abi index 26aabc01..64ef98be 100644 --- a/eosio.bios/abi/eosio.bios.abi +++ b/eosio.bios/abi/eosio.bios.abi @@ -53,6 +53,28 @@ {"name":"accounts", "type":"permission_level_weight[]"}, {"name":"waits", "type":"wait_weight[]"} ] + },{ + "name": "blockchain_parameters", + "base": "", + "fields": [ + {"name":"max_block_net_usage", "type":"uint64"}, + {"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":"uint32"}, + {"name":"max_inline_action_depth", "type":"uint16"}, + {"name":"max_authority_depth", "type":"uint16"} + ] },{ "name": "newaccount", "base": "", @@ -167,6 +189,12 @@ "fields": [ {"name":"schedule", "type":"producer_key[]"} ] + },{ + "name": "setparams", + "base": "", + "fields": [ + {"name":"params", "type":"blockchain_parameters"} + ] },{ "name": "require_auth", "base": "", @@ -226,6 +254,10 @@ "name": "setprods", "type": "set_producers", "ricardian_contract": "" + },{ + "name": "setparams", + "type": "setparams", + "ricardian_contract": "" },{ "name": "reqauth", "type": "require_auth", diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 391d8ea1..2cfe5688 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -13,7 +13,7 @@ namespace eosio { EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; - typedef eosio::multi_index< N(abihash), abi_hash> abi_hash_table; + typedef eosio::multi_index< N(abihash), abi_hash> abi_hash_table; class bios : public contract { public: @@ -45,6 +45,11 @@ namespace eosio { set_proposed_producers(buffer, size); } + void setparams( const eosio::blockchain_parameters& params ) { + require_auth( _self ); + set_blockchain_parameters( params ); + } + void reqauth( action_name from ) { require_auth( from ); } @@ -55,11 +60,11 @@ namespace eosio { if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { row.owner = acnt; - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } else { table.modify( itr, 0, [&]( auto& row ) { - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } } diff --git a/eosio.bios/src/eosio.bios.cpp b/eosio.bios/src/eosio.bios.cpp index 8d7b4732..04ce20e6 100644 --- a/eosio.bios/src/eosio.bios.cpp +++ b/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,3 @@ #include -EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(reqauth)(setabi) ) +EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi) ) From ec5a1b3d36c3421cb07f8e2b2fb905a2ce948e4d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 25 Sep 2018 17:20:35 -0400 Subject: [PATCH 0537/1048] Small changes, refactoring --- .../include/eosio.system/eosio.system.hpp | 7 +-- eosio.system/src/delegate_bandwidth.cpp | 45 ++++++++++--------- eosio.system/src/eosio.system.cpp | 24 +++++----- tests/eosio.system_tests.cpp | 1 + 4 files changed, 43 insertions(+), 34 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 5020180d..a6905c26 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -172,7 +172,7 @@ namespace eosiosystem { asset total_lendable; /// total EOS that have been lent (total_unlent + total_lent) asset total_rex; /// total number of REX shares allocated to contributors to total_lendable uint64_t loan_num = 0; /// increments with each new loan - auto primary_key()const { return 0; } + uint64_t primary_key()const { return 0; } }; typedef eosio::multi_index< N(rexpool), rex_pool > rex_pool_table; @@ -182,7 +182,7 @@ namespace eosiosystem { asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote asset rex_balance; /// the amount of REX owned by owner - auto primary_key()const { return owner; } + uint64_t primary_key()const { return owner; } }; typedef eosio::multi_index< N(rexbal), rex_balance > rex_balance_table; @@ -194,7 +194,7 @@ namespace eosiosystem { eosio::time_point expiration; - auto primary_key()const { return loan_num; } + uint64_t primary_key()const { return loan_num; } }; typedef eosio::multi_index< N(cpuloan), rex_loan> rex_cpu_loan_table; @@ -348,6 +348,7 @@ namespace eosiosystem { void changebw( account_name from, account_name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); void update_resource_limits( account_name receiver, int64_t delta_cpu, int64_t delta_net ); + void update_voting_power( const account_name& voter, const asset& total_update ); //defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 667a2c12..db1c589d 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -363,27 +363,32 @@ namespace eosiosystem { } // update voting power - { - asset total_update = stake_net_delta + stake_cpu_delta; - auto from_voter = _voters.find(from); - if( from_voter == _voters.end() ) { - from_voter = _voters.emplace( from, [&]( auto& v ) { - v.owner = from; - v.staked = total_update.amount; - }); - } else { - _voters.modify( from_voter, 0, [&]( auto& v ) { - v.staked += total_update.amount; - }); - } - eosio_assert( 0 <= from_voter->staked, "stake for voting cannot be negative"); - if( from == N(b1) ) { - validate_b1_vesting( from_voter->staked ); - } + update_voting_power( from, stake_net_delta + stake_cpu_delta ); - if( from_voter->producers.size() || from_voter->proxy ) { - update_votes( from, from_voter->proxy, from_voter->producers, false ); - } + } + + void system_contract::update_voting_power( const account_name& voter, const asset& total_update ) + { + auto voter_itr = _voters.find( voter ); + if( voter_itr == _voters.end() ) { + voter_itr = _voters.emplace( voter, [&]( auto& v ) { + v.owner = voter; + v.staked = total_update.amount; + }); + } else { + _voters.modify( voter_itr, 0, [&]( auto& v ) { + v.staked += total_update.amount; + }); + } + + eosio_assert( 0 <= voter_itr->staked, "stake for voting cannot be negative"); + + if( voter == N(b1) ) { + validate_b1_vesting( voter_itr->staked ); + } + + if( voter_itr->producers.size() || voter_itr->proxy ) { + update_votes( voter, voter_itr->proxy, voter_itr->producers, false ); } } diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index fca97f31..5214e73e 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -277,13 +277,15 @@ namespace eosiosystem { auto bitr = _rexbalance.find( from ); if( bitr == _rexbalance.end() ) { _rexbalance.emplace( from, [&]( auto& rb ) { - rb.owner = from; + rb.owner = from; + rb.vote_stake = amount; rb.rex_balance = rex_received; + }); - } - else { + } else { _rexbalance.modify( bitr, 0, [&]( auto& rb ) { - rb.rex_balance.amount += rex_received.amount; + rb.vote_stake.amount += amount.amount; + rb.rex_balance.amount += rex_received.amount; }); } runrex(2); @@ -310,7 +312,7 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, { N(eosio.rex), from, result.second, "sell REX" } ); } else { - rex_order_table rexorders(_self, _self); + rex_order_table rexorders( _self, _self ); eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); rexorders.emplace( from, [&]( auto& ordr ) { ordr.owner = from; @@ -322,7 +324,7 @@ namespace eosiosystem { void system_contract::cnclrexorder( account_name owner ) { require_auth( owner ); - rex_order_table rexorders(_self, _self); + rex_order_table rexorders( _self, _self ); auto itr = rexorders.find( owner ); eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); eosio_assert( itr->is_open, "rex order has been closed and cannot be canceled" ); @@ -488,15 +490,15 @@ namespace eosiosystem { } - std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex) { + std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; - asset proceeds(S0-S1, CORE_SYMBOL); - bool success = false; - if( proceeds <= rexitr->total_unlent ) { + const asset proceeds( S0 - S1, CORE_SYMBOL ); + bool success = false; + if( proceeds.amount <= rexitr->total_unlent.amount ) { _rextable.modify( rexitr, 0, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; @@ -507,7 +509,7 @@ namespace eosiosystem { }); success = true; } - return std::make_pair(success, proceeds); + return std::make_pair( success, proceeds ); } void native::setabi( account_name acnt, const bytes& abi ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b575be25..5dab641d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3447,6 +3447,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { } { + // TODO: // the following fails with "divide by zero" error message!! // need to fix the corner case where rex system has been initialized but // balances are zero From 501e5a500762ca9e8e32014507eebc0c7164bc65 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 25 Sep 2018 21:51:36 -0400 Subject: [PATCH 0538/1048] Update voting power in lendrex and unlendrex --- eosio.system/src/eosio.system.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 5214e73e..072b1fac 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -280,7 +280,6 @@ namespace eosiosystem { rb.owner = from; rb.vote_stake = amount; rb.rex_balance = rex_received; - }); } else { _rexbalance.modify( bitr, 0, [&]( auto& rb ) { @@ -288,6 +287,9 @@ namespace eosiosystem { rb.rex_balance.amount += rex_received.amount; }); } + + update_voting_power( from, amount ); + runrex(2); } @@ -504,7 +506,11 @@ namespace eosiosystem { rt.total_lendable.amount = S1; rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; }); + asset unstake_quant( 0, CORE_SYMBOL ); + unstake_quant.amount = -( rex.amount * bitr->vote_stake.amount ) / bitr->rex_balance.amount; + update_voting_power( bitr->owner, unstake_quant ); _rexbalance.modify( bitr, 0, [&]( auto& rb ) { + rb.vote_stake.amount += unstake_quant.amount; rb.rex_balance.amount -= rex.amount; }); success = true; From 73d142f29f41ba9e10b5c16065cbe1fd1f96429b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 26 Sep 2018 20:30:37 -0400 Subject: [PATCH 0539/1048] Changes to update_voting_power in unlendrex, testing --- eosio.system/abi/eosio.system.abi | 1 + .../include/eosio.system/eosio.system.hpp | 3 +- eosio.system/src/delegate_bandwidth.cpp | 1 - eosio.system/src/eosio.system.cpp | 30 ++++++++++--------- tests/eosio.system_tester.hpp | 5 ++++ tests/eosio.system_tests.cpp | 17 +++++++++-- 6 files changed, 38 insertions(+), 19 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index de45915e..53676bbe 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -258,6 +258,7 @@ {"name":"owner", "type":"account_name"}, {"name":"rex_requested", "type":"asset"}, {"name":"proceeds", "type":"asset"}, + {"name":"unstake_quant", "type":"asset"}, {"name":"order_time", "type":"time_point"}, {"name":"is_open", "type":"bool"} ] diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index a6905c26..4278a5f4 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -204,6 +204,7 @@ namespace eosiosystem { account_name owner; asset rex_requested; asset proceeds; + asset unstake_quant; eosio::time_point order_time; bool is_open = true; @@ -342,7 +343,7 @@ namespace eosiosystem { static block_timestamp current_block_time(); void update_ram_supply(); void runrex( uint16_t max ); - std::pair close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index db1c589d..e2852620 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -362,7 +362,6 @@ namespace eosiosystem { } } - // update voting power update_voting_power( from, stake_net_delta + stake_cpu_delta ); } diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 072b1fac..449e0b85 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -310,15 +310,17 @@ namespace eosiosystem { eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); auto result = close_rex_order( bitr, rex ); - if( result.first ) { + if( std::get<0>( result ) ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, - { N(eosio.rex), from, result.second, "sell REX" } ); + { N(eosio.rex), from, std::get<1>(result), "sell REX" } ); + update_voting_power( from, asset( -( std::get<2>( result ).amount ), CORE_SYMBOL ) ); } else { rex_order_table rexorders( _self, _self ); eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); rexorders.emplace( from, [&]( auto& ordr ) { ordr.owner = from; ordr.rex_requested = rex; + ordr.unstake_quant = std::get<2>( result ); ordr.order_time = current_time_point(); }); } @@ -341,7 +343,8 @@ namespace eosiosystem { eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); eosio_assert( !itr->is_open, "rex order has not been closed" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, - { N(eosio.rex), itr->owner, itr->proceeds, "sell REX" } ); + { N(eosio.rex), itr->owner, itr->proceeds, "claim REX proceeds" } ); + update_voting_power( owner, asset( -( itr->unstake_quant.amount ), CORE_SYMBOL ) ); rexorders.erase( itr ); } @@ -446,7 +449,7 @@ namespace eosiosystem { }); }; - rex_cpu_loan_table cpu_loans(_self,_self); + rex_cpu_loan_table cpu_loans( _self, _self ); for( uint16_t i = 0; i < max; ++i ) { auto itr = cpu_loans.begin(); if( itr == cpu_loans.end() ) break; @@ -457,7 +460,7 @@ namespace eosiosystem { cpu_loans.erase( itr ); } - rex_net_loan_table net_loans(_self,_self); + rex_net_loan_table net_loans( _self, _self ); for( uint16_t i = 0; i < max; ++i ) { auto itr = net_loans.begin(); if( itr == net_loans.end() ) break; @@ -468,7 +471,7 @@ namespace eosiosystem { net_loans.erase( itr ); } - rex_order_table rexorders(_self, _self); + rex_order_table rexorders( _self, _self ); auto idx = rexorders.get_index(); auto oitr = idx.begin(); for( uint16_t i = 0; i < max; ++i ) { @@ -481,9 +484,9 @@ namespace eosiosystem { auto result = close_rex_order( bitr, oitr->rex_requested ); auto next = oitr; ++next; - if( result.first ) { + if( std::get<0>( result ) ) { idx.modify( oitr, 0, [&]( auto& rt ) { - rt.proceeds.amount = result.second.amount; + rt.proceeds.amount = std::get<1>( result ).amount; rt.close(); }); } @@ -492,13 +495,15 @@ namespace eosiosystem { } - std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + std::tuple system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; const asset proceeds( S0 - S1, CORE_SYMBOL ); + asset unstake_quant( 0, CORE_SYMBOL ); + unstake_quant.amount = ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount; bool success = false; if( proceeds.amount <= rexitr->total_unlent.amount ) { _rextable.modify( rexitr, 0, [&]( auto& rt ) { @@ -506,16 +511,13 @@ namespace eosiosystem { rt.total_lendable.amount = S1; rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; }); - asset unstake_quant( 0, CORE_SYMBOL ); - unstake_quant.amount = -( rex.amount * bitr->vote_stake.amount ) / bitr->rex_balance.amount; - update_voting_power( bitr->owner, unstake_quant ); _rexbalance.modify( bitr, 0, [&]( auto& rb ) { - rb.vote_stake.amount += unstake_quant.amount; + rb.vote_stake.amount -= unstake_quant.amount; rb.rex_balance.amount -= rex.amount; }); success = true; } - return std::make_pair( success, proceeds ); + return std::make_tuple( success, proceeds, unstake_quant ); } void native::setabi( account_name acnt, const bytes& abi ) { diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index f30f7a60..a22be914 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -335,6 +335,11 @@ class eosio_system_tester : public TESTER { return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); } + asset get_rex_vote_stake( const account_name& act ) const { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); + return data.empty() ? core_from_string("0.0000") : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["vote_stake"].as(); + } + fc::variant get_rex_order( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); return abi_ser.binary_to_variant( "rex_order", data, abi_serializer_max_time ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 5dab641d..7aad6033 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3480,7 +3480,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { transfer( config::system_account_name, a, init_balance, config::system_account_name ); BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); } - + auto purchase1 = core_from_string("880.0000"); auto purchase2 = core_from_string("471.0000"); auto purchase3 = core_from_string("469.0000"); @@ -3489,6 +3489,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), lendrex( carol, purchase3) ); BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_balance(alice) ); + BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() ); BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_balance(bob) ); BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_balance(carol) ); @@ -3498,7 +3499,13 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, core_from_string("1100.0000"), true ) ); BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); + + BOOST_REQUIRE_EQUAL( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ); + BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_rex_vote_stake( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_voter_info(alice)["staked"].as() ); + init_alice_rex = get_rex_balance(alice); + BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, get_rex_balance(bob) ) ); BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, get_rex_balance(carol) ) ); BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); @@ -3543,14 +3550,18 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( purchase2, get_rex_order(bob)["unstake_quant"].as() ); BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); + BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); - + BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_voter_info( bob )["staked"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_voter_info( carol )["staked"].as() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); From 856e038ed7dae2dc4d4aab93875c582c14f95be1 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 27 Sep 2018 11:21:41 -0400 Subject: [PATCH 0540/1048] Small changes to REX --- eosio.system/abi/eosio.system.abi | 4 +-- .../include/eosio.system/eosio.system.hpp | 10 +++---- eosio.system/src/eosio.system.cpp | 26 +++++++++---------- tests/eosio.system_tests.cpp | 18 ++++++------- 4 files changed, 29 insertions(+), 29 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 53676bbe..6e39049c 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -257,8 +257,8 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"rex_requested", "type":"asset"}, - {"name":"proceeds", "type":"asset"}, - {"name":"unstake_quant", "type":"asset"}, + {"name":"proceeds", "type":"int64"}, + {"name":"unstake_quant", "type":"int64"}, {"name":"order_time", "type":"time_point"}, {"name":"is_open", "type":"bool"} ] diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 4278a5f4..2348efc8 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -203,14 +203,14 @@ namespace eosiosystem { struct rex_order { account_name owner; asset rex_requested; - asset proceeds; - asset unstake_quant; + int64_t proceeds; + int64_t unstake_quant; eosio::time_point order_time; bool is_open = true; void close() { is_open = false; } - auto primary_key()const { return owner; } - uint64_t by_time()const { return is_open? order_time.elapsed.count(): -order_time.elapsed.count(); } + auto primary_key()const { return owner; } + uint64_t by_time()const { return is_open ? order_time.elapsed.count() : -order_time.elapsed.count(); } }; typedef eosio::multi_index< N(rexqueue), rex_order, @@ -343,7 +343,7 @@ namespace eosiosystem { static block_timestamp current_block_time(); void update_ram_supply(); void runrex( uint16_t max ); - std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); //defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 449e0b85..cd727e9b 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -310,17 +310,17 @@ namespace eosiosystem { eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); auto result = close_rex_order( bitr, rex ); - if( std::get<0>( result ) ) { + if( std::get<0>(result) ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, - { N(eosio.rex), from, std::get<1>(result), "sell REX" } ); - update_voting_power( from, asset( -( std::get<2>( result ).amount ), CORE_SYMBOL ) ); + { N(eosio.rex), from, asset( std::get<1>(result), CORE_SYMBOL ), "sell REX" } ); + update_voting_power( from, asset( -(std::get<2>(result)), CORE_SYMBOL ) ); } else { rex_order_table rexorders( _self, _self ); eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); rexorders.emplace( from, [&]( auto& ordr ) { ordr.owner = from; ordr.rex_requested = rex; - ordr.unstake_quant = std::get<2>( result ); + ordr.unstake_quant = std::get<2>(result); ordr.order_time = current_time_point(); }); } @@ -343,8 +343,8 @@ namespace eosiosystem { eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); eosio_assert( !itr->is_open, "rex order has not been closed" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, - { N(eosio.rex), itr->owner, itr->proceeds, "claim REX proceeds" } ); - update_voting_power( owner, asset( -( itr->unstake_quant.amount ), CORE_SYMBOL ) ); + { N(eosio.rex), itr->owner, asset(itr->proceeds, CORE_SYMBOL), "claim REX proceeds" } ); + update_voting_power( owner, asset( -( itr->unstake_quant ), CORE_SYMBOL ) ); rexorders.erase( itr ); } @@ -477,6 +477,7 @@ namespace eosiosystem { for( uint16_t i = 0; i < max; ++i ) { if( oitr == idx.end() || !oitr->is_open ) break; auto bitr = _rexbalance.find( oitr->owner ); + // TODO: change the logic below if( bitr == _rexbalance.end() ) { idx.erase( oitr++ ); continue; @@ -486,7 +487,7 @@ namespace eosiosystem { ++next; if( std::get<0>( result ) ) { idx.modify( oitr, 0, [&]( auto& rt ) { - rt.proceeds.amount = std::get<1>( result ).amount; + rt.proceeds = std::get<1>( result ); rt.close(); }); } @@ -495,24 +496,23 @@ namespace eosiosystem { } - std::tuple system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + std::tuple system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; - const asset proceeds( S0 - S1, CORE_SYMBOL ); - asset unstake_quant( 0, CORE_SYMBOL ); - unstake_quant.amount = ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount; + const int64_t proceeds = S0 - S1; // asset( S0 - S1, CORE_SYMBOL ); + const int64_t unstake_quant = ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount; bool success = false; - if( proceeds.amount <= rexitr->total_unlent.amount ) { + if( proceeds <= rexitr->total_unlent.amount ) { _rextable.modify( rexitr, 0, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; }); _rexbalance.modify( bitr, 0, [&]( auto& rb ) { - rb.vote_stake.amount -= unstake_quant.amount; + rb.vote_stake.amount -= unstake_quant; rb.rex_balance.amount -= rex.amount; }); success = true; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7aad6033..deafae9a 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3517,13 +3517,13 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { // now bob's, carol's and alice's unlendrex requests have been queued BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(bob)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(bob)["proceeds"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as() ); // wait for 30 days minus 1 hour produce_block( fc::hours(29*24 + 23) ); @@ -3543,18 +3543,18 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { unlendrex( alice, init_alice_rex ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( purchase2, get_rex_order(bob)["unstake_quant"].as() ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as() ); + BOOST_REQUIRE_EQUAL( purchase2.get_amount(), get_rex_order(bob)["unstake_quant"].as() ); BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); + BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as() ); BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); From d71f51f4e18ce0c75009f877c5cd9c4dd6698012 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 27 Sep 2018 15:59:57 -0400 Subject: [PATCH 0541/1048] Move REX functions from eosio.system.cpp to new file rex.cpp --- .../include/eosio.system/eosio.system.hpp | 14 +- eosio.system/src/eosio.system.cpp | 287 +---------------- eosio.system/src/rex.cpp | 293 ++++++++++++++++++ 3 files changed, 301 insertions(+), 293 deletions(-) create mode 100644 eosio.system/src/rex.cpp diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 3032f0bb..59bc3336 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -211,8 +211,8 @@ namespace eosiosystem { struct rex_order { account_name owner; asset rex_requested; - int64_t proceeds; - int64_t unstake_quant; + int64_t proceeds = 0; + int64_t unstake_quant = 0; eosio::time_point order_time; bool is_open = true; @@ -348,27 +348,25 @@ namespace eosiosystem { private: // Implementation details: - //defined in eosio.system.cpp + // defined in eosio.system.cpp static eosio_global_state get_default_parameters(); static time_point current_time_point(); static block_timestamp current_block_time(); void update_ram_supply(); + // defined in rex.cpp void runrex( uint16_t max ); std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); - //defined in delegate_bandwidth.cpp + // defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); void update_resource_limits( account_name receiver, int64_t delta_cpu, int64_t delta_net ); void update_voting_power( const account_name& voter, const asset& total_update ); - //defined in voting.hpp + // defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); void update_votes( const account_name voter, const account_name proxy, const std::vector& producers, bool voting ); - - // defined in voting.cpp void propagate_weight_change( const voter_info& voter ); - double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, time_point ct, double shares_rate, bool reset_to_zero = false ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 8dd7ee41..9025a23b 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -6,7 +6,7 @@ #include "delegate_bandwidth.cpp" #include "voting.cpp" #include "exchange_state.cpp" - +#include "rex.cpp" namespace eosiosystem { @@ -274,290 +274,6 @@ namespace eosiosystem { set_resource_limits( newact, 0, 0, 0 ); } - /** - * Transfers SYS tokens from user balance and credits converts them to REX stake. - */ - void system_contract::lendrex( account_name from, asset amount ) { - require_auth( from ); - - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio.rex), amount, "buy REX" } ); - - asset rex_received( 0, S(4,REX) ); - - auto itr = _rextable.begin(); - if( itr == _rextable.end() ) { - _rextable.emplace( _self, [&]( auto& rp ){ - rex_received.amount = amount.amount * 10000; - - rp.total_lendable = amount; - rp.total_lent = asset( 0, CORE_SYMBOL ); - rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available - rp.total_rex = rex_received; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - }); - } else { - const auto S0 = itr->total_lendable.amount; - const auto S1 = S0 + amount.amount; - const auto R0 = itr->total_rex.amount; - const auto R1 = (uint128_t(S1) * R0) / S0; - - rex_received.amount = R1 - R0; - - _rextable.modify( itr, 0, [&]( auto& rp ) { - rp.total_lendable.amount = S1; - rp.total_rex.amount = R1; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); - }); - } - - auto bitr = _rexbalance.find( from ); - if( bitr == _rexbalance.end() ) { - _rexbalance.emplace( from, [&]( auto& rb ) { - rb.owner = from; - rb.vote_stake = amount; - rb.rex_balance = rex_received; - }); - } else { - _rexbalance.modify( bitr, 0, [&]( auto& rb ) { - rb.vote_stake.amount += amount.amount; - rb.rex_balance.amount += rex_received.amount; - }); - } - - update_voting_power( from, amount ); - - runrex(2); - } - - /** - * Converts REX stake back into SYS tokens at current exchange rate - */ - void system_contract::unlendrex( account_name from, asset rex ) { - runrex(2); - - require_auth( from ); - - auto itr = _rextable.begin(); - eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); - - auto bitr = _rexbalance.find( from ); - eosio_assert( bitr != _rexbalance.end(), "user must first lendrex" ); - eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); - eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); - - auto result = close_rex_order( bitr, rex ); - if( std::get<0>(result) ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, - { N(eosio.rex), from, asset( std::get<1>(result), CORE_SYMBOL ), "sell REX" } ); - update_voting_power( from, asset( -(std::get<2>(result)), CORE_SYMBOL ) ); - } else { - rex_order_table rexorders( _self, _self ); - eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); - rexorders.emplace( from, [&]( auto& ordr ) { - ordr.owner = from; - ordr.rex_requested = rex; - ordr.unstake_quant = std::get<2>(result); - ordr.order_time = current_time_point(); - }); - } - } - - void system_contract::cnclrexorder( account_name owner ) { - require_auth( owner ); - rex_order_table rexorders( _self, _self ); - auto itr = rexorders.find( owner ); - eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); - eosio_assert( itr->is_open, "rex order has been closed and cannot be canceled" ); - rexorders.erase( itr ); - } - - void system_contract::claimrex( account_name owner ) { - require_auth( owner ); - runrex(2); - rex_order_table rexorders(_self, _self); - auto itr = rexorders.find( owner ); - eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); - eosio_assert( !itr->is_open, "rex order has not been closed" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, - { N(eosio.rex), itr->owner, asset(itr->proceeds, CORE_SYMBOL), "claim REX proceeds" } ); - update_voting_power( owner, asset( -( itr->unstake_quant ), CORE_SYMBOL ) ); - rexorders.erase( itr ); - } - - /** - * Given two connector balances (conin, and conout), and an incoming amount of - * in, this function will modify conin and conout and return the delta out. - * - * @param in - same units as conin - * @param conin - the input connector balance - * @param conout - the output connector balance - */ - int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { - const double F0 = double(conin); - const double T0 = double(conout); - const double I = double(in); - - auto out = int64_t((I*T0) / (I+F0)); - - if( out < 0 ) out = 0; - - conin += in; - conout -= out; - - return out; - } - - void system_contract::update_resource_limits( account_name receiver, int64_t delta_cpu, int64_t delta_net ) { - user_resources_table totals_tbl( _self, receiver ); - auto tot_itr = totals_tbl.find( receiver ); - eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); - totals_tbl.modify( tot_itr, 0, [&]( auto& tot ) { - tot.cpu_weight.amount += delta_cpu; - tot.net_weight.amount += delta_net; - }); - eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); - eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); - - int64_t ram_bytes, net, cpu; - get_resource_limits( receiver, &ram_bytes, &net, &cpu ); - set_resource_limits( receiver, ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - } - - /** - * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, - * after 30 days the rented SYS delegation of CPU or NET will expire. - */ - void system_contract::rent( account_name from, account_name receiver, asset payment, bool cpu ) { - require_auth( from ); - - runrex(2); - - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio.rex), payment, string("rent ") + (cpu ? "CPU" : "NET") } ); - - auto itr = _rextable.begin(); - eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); - - int64_t rented_tokens = 0; - _rextable.modify( itr, 0, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - rt.loan_num++; - }); - - if( cpu ) { - rex_cpu_loan_table cpu_loans(_self,_self); - - cpu_loans.emplace( from, [&]( auto& c ) { - c.receiver = receiver; - c.total_staked = asset( rented_tokens, CORE_SYMBOL ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); - c.loan_num = itr->loan_num; - }); - update_resource_limits( receiver, rented_tokens, 0 ); - } else { - rex_net_loan_table net_loans(_self,_self); - - net_loans.emplace( from, [&]( auto& c ) { - c.receiver = receiver; - c.total_staked = asset( rented_tokens, CORE_SYMBOL ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); - c.loan_num = itr->loan_num; - }); - update_resource_limits( receiver, 0, rented_tokens ); - } - } - - /** - * Perform maitenance operations on expired rex - */ - void system_contract::runrex( uint16_t max ) { - auto rexi = _rextable.begin(); - eosio_assert( rexi != _rextable.end(), "rex system not initialized yet" ); - - auto unrent = [&]( int64_t rented_tokens ) { - _rextable.modify( rexi, 0, [&]( auto& rt ) { - auto fee = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); - rt.total_lent.amount -= rented_tokens; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - }); - }; - - rex_cpu_loan_table cpu_loans( _self, _self ); - for( uint16_t i = 0; i < max; ++i ) { - auto itr = cpu_loans.begin(); - if( itr == cpu_loans.end() ) break; - if( itr->expiration.elapsed.count() > current_time() ) break; - - update_resource_limits( itr->receiver, -itr->total_staked.amount, 0 ); - unrent( itr->total_staked.amount ); - cpu_loans.erase( itr ); - } - - rex_net_loan_table net_loans( _self, _self ); - for( uint16_t i = 0; i < max; ++i ) { - auto itr = net_loans.begin(); - if( itr == net_loans.end() ) break; - if( itr->expiration.elapsed.count() > current_time() ) break; - - update_resource_limits( itr->receiver, 0, -itr->total_staked.amount ); - unrent( itr->total_staked.amount ); - net_loans.erase( itr ); - } - - rex_order_table rexorders( _self, _self ); - auto idx = rexorders.get_index(); - auto oitr = idx.begin(); - for( uint16_t i = 0; i < max; ++i ) { - if( oitr == idx.end() || !oitr->is_open ) break; - auto bitr = _rexbalance.find( oitr->owner ); - // TODO: change the logic below - if( bitr == _rexbalance.end() ) { - idx.erase( oitr++ ); - continue; - } - auto result = close_rex_order( bitr, oitr->rex_requested ); - auto next = oitr; - ++next; - if( std::get<0>( result ) ) { - idx.modify( oitr, 0, [&]( auto& rt ) { - rt.proceeds = std::get<1>( result ); - rt.close(); - }); - } - oitr = next; - } - - } - - std::tuple system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { - auto rexitr = _rextable.begin(); - const auto S0 = rexitr->total_lendable.amount; - const auto R0 = rexitr->total_rex.amount; - const auto R1 = R0 - rex.amount; - const auto S1 = (uint128_t(R1) * S0) / R0; - const int64_t proceeds = S0 - S1; // asset( S0 - S1, CORE_SYMBOL ); - const int64_t unstake_quant = ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount; - bool success = false; - if( proceeds <= rexitr->total_unlent.amount ) { - _rextable.modify( rexitr, 0, [&]( auto& rt ) { - rt.total_rex.amount = R1; - rt.total_lendable.amount = S1; - rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; - }); - _rexbalance.modify( bitr, 0, [&]( auto& rb ) { - rb.vote_stake.amount -= unstake_quant; - rb.rex_balance.amount -= rex.amount; - }); - success = true; - } - return std::make_tuple( success, proceeds, unstake_quant ); - } - void native::setabi( account_name acnt, const bytes& abi ) { eosio::multi_index< N(abihash), abi_hash> table(_self,_self); auto itr = table.find( acnt ); @@ -581,6 +297,7 @@ EOSIO_ABI( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) + // rex.cpp (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rent) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp new file mode 100644 index 00000000..c49a0e4c --- /dev/null +++ b/eosio.system/src/rex.cpp @@ -0,0 +1,293 @@ +/** + * @copyright defined in eos/LICENSE.txt + */ + +#include + +namespace eosiosystem { + + /** + * Transfers SYS tokens from user balance and credits converts them to REX stake. + */ + void system_contract::lendrex( account_name from, asset amount ) { + require_auth( from ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio.rex), amount, "buy REX" } ); + + asset rex_received( 0, S(4,REX) ); + + auto itr = _rextable.begin(); + if( itr == _rextable.end() ) { + _rextable.emplace( _self, [&]( auto& rp ){ + rex_received.amount = amount.amount * 10000; + + rp.total_lendable = amount; + rp.total_lent = asset( 0, CORE_SYMBOL ); + rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available + rp.total_rex = rex_received; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + }); + } else { + const auto S0 = itr->total_lendable.amount; + const auto S1 = S0 + amount.amount; + const auto R0 = itr->total_rex.amount; + const auto R1 = (uint128_t(S1) * R0) / S0; + + rex_received.amount = R1 - R0; + + _rextable.modify( itr, 0, [&]( auto& rp ) { + rp.total_lendable.amount = S1; + rp.total_rex.amount = R1; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); + }); + } + + auto bitr = _rexbalance.find( from ); + if( bitr == _rexbalance.end() ) { + _rexbalance.emplace( from, [&]( auto& rb ) { + rb.owner = from; + rb.vote_stake = amount; + rb.rex_balance = rex_received; + }); + } else { + _rexbalance.modify( bitr, 0, [&]( auto& rb ) { + rb.vote_stake.amount += amount.amount; + rb.rex_balance.amount += rex_received.amount; + }); + } + + update_voting_power( from, amount ); + + runrex(2); + } + + /** + * Converts REX stake back into SYS tokens at current exchange rate + */ + void system_contract::unlendrex( account_name from, asset rex ) { + runrex(2); + + require_auth( from ); + + auto itr = _rextable.begin(); + eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); + + auto bitr = _rexbalance.find( from ); + eosio_assert( bitr != _rexbalance.end(), "user must first lendrex" ); + eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); + eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); + + auto result = close_rex_order( bitr, rex ); + if( std::get<0>(result) ) { + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, + { N(eosio.rex), from, asset( std::get<1>(result), CORE_SYMBOL ), "sell REX" } ); + update_voting_power( from, asset( -(std::get<2>(result)), CORE_SYMBOL ) ); + } else { + rex_order_table rexorders( _self, _self ); + eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); + rexorders.emplace( from, [&]( auto& ordr ) { + ordr.owner = from; + ordr.rex_requested = rex; + ordr.unstake_quant = std::get<2>(result); + ordr.order_time = current_time_point(); + }); + } + } + + void system_contract::cnclrexorder( account_name owner ) { + require_auth( owner ); + rex_order_table rexorders( _self, _self ); + auto itr = rexorders.find( owner ); + eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); + eosio_assert( itr->is_open, "rex order has been closed and cannot be canceled" ); + rexorders.erase( itr ); + } + + void system_contract::claimrex( account_name owner ) { + require_auth( owner ); + runrex(2); + rex_order_table rexorders(_self, _self); + auto itr = rexorders.find( owner ); + eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); + eosio_assert( !itr->is_open, "rex order has not been closed" ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, + { N(eosio.rex), itr->owner, asset(itr->proceeds, CORE_SYMBOL), "claim REX proceeds" } ); + update_voting_power( owner, asset( -( itr->unstake_quant ), CORE_SYMBOL ) ); + rexorders.erase( itr ); + } + + /** + * Given two connector balances (conin, and conout), and an incoming amount of + * in, this function will modify conin and conout and return the delta out. + * + * @param in - same units as conin + * @param conin - the input connector balance + * @param conout - the output connector balance + */ + int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { + const double F0 = double(conin); + const double T0 = double(conout); + const double I = double(in); + + auto out = int64_t((I*T0) / (I+F0)); + + if( out < 0 ) out = 0; + + conin += in; + conout -= out; + + return out; + } + + void system_contract::update_resource_limits( account_name receiver, int64_t delta_cpu, int64_t delta_net ) { + user_resources_table totals_tbl( _self, receiver ); + auto tot_itr = totals_tbl.find( receiver ); + eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); + totals_tbl.modify( tot_itr, 0, [&]( auto& tot ) { + tot.cpu_weight.amount += delta_cpu; + tot.net_weight.amount += delta_net; + }); + eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); + eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); + + int64_t ram_bytes, net, cpu; + get_resource_limits( receiver, &ram_bytes, &net, &cpu ); + set_resource_limits( receiver, ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + } + + /** + * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, + * after 30 days the rented SYS delegation of CPU or NET will expire. + */ + void system_contract::rent( account_name from, account_name receiver, asset payment, bool cpu ) { + require_auth( from ); + + runrex(2); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio.rex), payment, string("rent ") + (cpu ? "CPU" : "NET") } ); + + auto itr = _rextable.begin(); + eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); + + int64_t rented_tokens = 0; + _rextable.modify( itr, 0, [&]( auto& rt ) { + rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + rt.loan_num++; + }); + + if( cpu ) { + rex_cpu_loan_table cpu_loans(_self,_self); + + cpu_loans.emplace( from, [&]( auto& c ) { + c.receiver = receiver; + c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; + }); + update_resource_limits( receiver, rented_tokens, 0 ); + } else { + rex_net_loan_table net_loans(_self,_self); + + net_loans.emplace( from, [&]( auto& c ) { + c.receiver = receiver; + c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; + }); + update_resource_limits( receiver, 0, rented_tokens ); + } + } + + /** + * Perform maitenance operations on expired rex + */ + void system_contract::runrex( uint16_t max ) { + auto rexi = _rextable.begin(); + eosio_assert( rexi != _rextable.end(), "rex system not initialized yet" ); + + auto unrent = [&]( int64_t rented_tokens ) { + _rextable.modify( rexi, 0, [&]( auto& rt ) { + auto fee = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); + rt.total_lent.amount -= rented_tokens; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + }); + }; + + rex_cpu_loan_table cpu_loans( _self, _self ); + for( uint16_t i = 0; i < max; ++i ) { + auto itr = cpu_loans.begin(); + if( itr == cpu_loans.end() ) break; + if( itr->expiration.elapsed.count() > current_time() ) break; + + update_resource_limits( itr->receiver, -itr->total_staked.amount, 0 ); + unrent( itr->total_staked.amount ); + cpu_loans.erase( itr ); + } + + rex_net_loan_table net_loans( _self, _self ); + for( uint16_t i = 0; i < max; ++i ) { + auto itr = net_loans.begin(); + if( itr == net_loans.end() ) break; + if( itr->expiration.elapsed.count() > current_time() ) break; + + update_resource_limits( itr->receiver, 0, -itr->total_staked.amount ); + unrent( itr->total_staked.amount ); + net_loans.erase( itr ); + } + + rex_order_table rexorders( _self, _self ); + auto idx = rexorders.get_index(); + auto oitr = idx.begin(); + for( uint16_t i = 0; i < max; ++i ) { + if( oitr == idx.end() || !oitr->is_open ) break; + auto bitr = _rexbalance.find( oitr->owner ); + // TODO: change the logic below + if( bitr == _rexbalance.end() ) { + idx.erase( oitr++ ); + continue; + } + auto result = close_rex_order( bitr, oitr->rex_requested ); + auto next = oitr; + ++next; + if( std::get<0>( result ) ) { + idx.modify( oitr, 0, [&]( auto& rt ) { + rt.proceeds = std::get<1>( result ); + rt.close(); + }); + } + oitr = next; + } + + } + + std::tuple system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + auto rexitr = _rextable.begin(); + const auto S0 = rexitr->total_lendable.amount; + const auto R0 = rexitr->total_rex.amount; + const auto R1 = R0 - rex.amount; + const auto S1 = (uint128_t(R1) * S0) / R0; + const int64_t proceeds = S0 - S1; // asset( S0 - S1, CORE_SYMBOL ); + const int64_t unstake_quant = ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount; + bool success = false; + if( proceeds <= rexitr->total_unlent.amount ) { + _rextable.modify( rexitr, 0, [&]( auto& rt ) { + rt.total_rex.amount = R1; + rt.total_lendable.amount = S1; + rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; + }); + _rexbalance.modify( bitr, 0, [&]( auto& rb ) { + rb.vote_stake.amount -= unstake_quant; + rb.rex_balance.amount -= rex.amount; + }); + success = true; + } + return std::make_tuple( success, proceeds, unstake_quant ); + } + +}; /// namespace eosiosystem From a5d9e5a173a9dd2b8dab6f31a6d5bc22699c306c Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 28 Sep 2018 15:52:55 -0400 Subject: [PATCH 0542/1048] Update CMakeLists.txt --- CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2d060420..802360ad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,12 +15,7 @@ if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) set(EOSIO_ROOT "/usr/local/eosio") endif() -if(EOSIO_CDT_ROOT STREQUAL "" OR NOT EOSIO_CDT_ROOT) - set(EOSIO_CDT_ROOT "/usr/local/eosio.cdt") -endif() - -list(APPEND CMAKE_MODULE_PATH ${EOSIO_CDT_ROOT}/lib/cmake) -include(EosioWasmToolchain) +find_package(eosio.cdt) ### Check the version of eosio.cdt string(FIND "${EOSIO_CDT_VERSION}" "${EOSIO_CDT_DEPENDENCY}" output) From 75806ba468e3d2992f69b234bfb74eca1747dc04 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 28 Sep 2018 17:34:04 -0400 Subject: [PATCH 0543/1048] improvements to dependency versions checking --- CMakeLists.txt | 37 +++++++++------ CheckVersion.txt | 90 ++++++++++++++++++++++++++++++++++++ UnitTestsExternalProject.txt | 5 +- tests/CMakeLists.txt | 29 ++++++++++-- 4 files changed, 138 insertions(+), 23 deletions(-) create mode 100644 CheckVersion.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 802360ad..b81cb4a1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,28 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts VERSION 1.3.1) -set(EOSIO_DEPENDENCY "1.2") -set(EOSIO_CDT_DEPENDENCY "1.2") +set(EOSIO_CDT_VERSION_MIN "1.2") # REMINDER: Change this to 1.3 before release +set(EOSIO_CDT_VERSION_SOFT_MAX "1.3") +#set(EOSIO_CDT_VERSION_HARD_MAX "") + +include(CheckVersion.txt) + +find_package(eosio.cdt) + +### Check the version of eosio.cdt +set(VERSION_MATCH_ERROR_MSG "") +EOSIO_CHECK_VERSION(VERSION_OUTPUT "${EOSIO_CDT_VERSION}" + "${EOSIO_CDT_VERSION_MIN}" + "${EOSIO_CDT_VERSION_SOFT_MAX}" + "${EOSIO_CDT_VERSION_HARD_MAX}" + VERSION_MATCH_ERROR_MSG) +if(VERSION_OUTPUT STREQUAL "MATCH") + message(STATUS "Using eosio.cdt version ${EOSIO_CDT_VERSION}") +elseif(VERSION_OUTPUT STREQUAL "WARN") + message(WARNING "Using eosio.cdt version ${EOSIO_CDT_VERSION} even though it exceeds the maximum supported version of ${EOSIO_CDT_VERSION_SOFT_MAX}; continuing with configuration, however build may fail.\nIt is recommended to use eosio.cdt version ${EOSIO_CDT_VERSION_SOFT_MAX}.x") +else() # INVALID OR MISMATCH + message(FATAL_ERROR "Found eosio.cdt version ${EOSIO_CDT_VERSION} but it does not satisfy version requirements: ${VERSION_MATCH_ERROR_MSG}\nPlease use eosio.cdt version ${EOSIO_CDT_VERSION_SOFT_MAX}.x") +endif(VERSION_OUTPUT STREQUAL "MATCH") if(CMAKE_BUILD_TYPE STREQUAL "Debug") set(TEST_BUILD_TYPE "Debug") @@ -11,20 +31,7 @@ else() set(TEST_BUILD_TYPE ${CMAKE_BUILD_TYPE}) endif() -if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) - set(EOSIO_ROOT "/usr/local/eosio") -endif() - -find_package(eosio.cdt) - -### Check the version of eosio.cdt -string(FIND "${EOSIO_CDT_VERSION}" "${EOSIO_CDT_DEPENDENCY}" output) - -if (NOT "${output}" EQUAL 0) - message(FATAL_ERROR "Incorrect EOSIO.CDT version, please use version ${EOSIO_CDT_DEPENDENCY}.x") -endif() -include_directories(AFTER ${BOOST_ROOT}/include) add_subdirectory(eosio.bios) add_subdirectory(eosio.msig) add_subdirectory(eosio.sudo) diff --git a/CheckVersion.txt b/CheckVersion.txt new file mode 100644 index 00000000..ffd28561 --- /dev/null +++ b/CheckVersion.txt @@ -0,0 +1,90 @@ +function(EXTRACT_MAJOR_MINOR_FROM_VERSION version success major minor) + string(REGEX REPLACE "^([0-9]+)\\..+$" "\\1" _major "${version}") + if("${_major}" STREQUAL "${version}") + set(${success} FALSE PARENT_SCOPE) + return() + endif() + + string(REGEX REPLACE "^[0-9]+\\.([0-9]+)(\\..*)?$" "\\1" _minor "${version}") + if("${_minor}" STREQUAL "${version}") + set(success FALSE PARENT_SCOPE) + return() + endif() + + set(${major} ${_major} PARENT_SCOPE) + set(${minor} ${_minor} PARENT_SCOPE) + set(${success} TRUE PARENT_SCOPE) +endfunction(EXTRACT_MAJOR_MINOR_FROM_VERSION) + +function(EOSIO_CHECK_VERSION output version hard_min soft_max hard_max) # optional 6th argument for error message + set(${output} "INVALID" PARENT_SCOPE) + + EXTRACT_MAJOR_MINOR_FROM_VERSION("${version}" success major minor) + if(NOT success) + if(${ARGC} GREATER 5) + set(${ARGV5} "version '${version}' is invalid" PARENT_SCOPE) + endif() + return() + endif() + + EXTRACT_MAJOR_MINOR_FROM_VERSION("${hard_min}" success hard_min_major hard_min_minor) + if(NOT success) + if(${ARGC} GREATER 5) + set(${ARGV5} "hard minimum version '${hard_min}' is invalid" PARENT_SCOPE) + endif() + return() + endif() + + if( "${major}.${minor}" VERSION_LESS "${hard_min_major}.${hard_min_minor}" ) + set(${output} "MISMATCH" PARENT_SCOPE) + if(${ARGC} GREATER 5) + set(${ARGV5} "version '${version}' does not meet hard minimum version requirement of ${hard_min_major}.${hard_min_minor}" PARENT_SCOPE) + endif() + return() + endif() + + if(NOT hard_max STREQUAL "") + EXTRACT_MAJOR_MINOR_FROM_VERSION("${hard_max}" success hard_max_major hard_max_minor) + if(NOT success) + if(${ARGC} GREATER 5) + set(${ARGV5} "hard maximum version '${hard_max}' is invalid" PARENT_SCOPE) + endif() + return() + endif() + + if( "${major}.${minor}" VERSION_GREATER "${hard_max_major}.${hard_max_minor}" ) + set(${output} "MISMATCH" PARENT_SCOPE) + if(${ARGC} GREATER 5) + set(${ARGV5} "version '${version}' does not meet hard maximum version requirement of ${hard_max_major}.${hard_max_minor}" PARENT_SCOPE) + endif() + return() + endif() + endif() + + EXTRACT_MAJOR_MINOR_FROM_VERSION("${soft_max}" success soft_max_major soft_max_minor) + if(NOT success) + set(${output} "MISMATCH" PARENT_SCOPE) + if(${ARGC} GREATER 5) + set(${ARGV5} "soft maximum version '${soft_max}' is invalid" PARENT_SCOPE) + endif() + return() + endif() + + if( ${major} GREATER ${soft_max_major} ) + set(${output} "MISMATCH" PARENT_SCOPE) + if(${ARGC} GREATER 5) + set(${ARGV5} "version '${version}' must have the same major version as the soft maximum version (${soft_max_major})" PARENT_SCOPE) + endif() + return() + endif() + + if( "${major}.${minor}" VERSION_GREATER "${soft_max_major}.${soft_max_minor}" ) + set(${output} "WARN" PARENT_SCOPE) + if(${ARGC} GREATER 5) + set(${ARGV5} "version '${version}' matches requirements but is greater than the soft maximum version of ${soft_max_major}.${soft_max_minor}" PARENT_SCOPE) + endif() + return() + endif() + + set(${output} "MATCH" PARENT_SCOPE) +endfunction(EOSIO_CHECK_VERSION) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index b7f9af50..3da9f16f 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -3,9 +3,8 @@ find_package(Git REQUIRED) include(GNUInstallDirs) ExternalProject_Add( - contracts_unit_tests - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} -DEOSIO_DEPENDENCY=${EOSIO_DEPENDENCY} - + contracts_unit_tests + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 12b6d8f1..7e6132cf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,13 +1,32 @@ cmake_minimum_required( VERSION 3.5 ) +set(EOSIO_VERSION_MIN "1.2") +set(EOSIO_VERSION_SOFT_MAX "1.2") +#set(EOSIO_VERSION_HARD_MAX "") + +include(../CheckVersion.txt) + +if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) + set(EOSIO_ROOT "/usr/local/eosio") +endif() + list(APPEND CMAKE_MODULE_PATH ${EOSIO_ROOT}/lib/cmake) include(EosioTester) -### check the version of EOSIO -string(FIND "${EOSIO_VERSION}" "${EOSIO_DEPENDENCY}" output) -if (NOT "${output}" EQUAL 0) - message(FATAL_ERROR "Incorrect EOSIO version, please use version ${EOSIO_DEPENDENCY}.x") -endif() +### Check the version of eosio +set(VERSION_MATCH_ERROR_MSG "") +EOSIO_CHECK_VERSION(VERSION_OUTPUT "${EOSIO_VERSION}" + "${EOSIO_VERSION_MIN}" + "${EOSIO_VERSION_SOFT_MAX}" + "${EOSIO_VERSION_HARD_MAX}" + VERSION_MATCH_ERROR_MSG) +if(VERSION_OUTPUT STREQUAL "MATCH") + message(STATUS "Using eosio version ${EOSIO_VERSION}") +elseif(VERSION_OUTPUT STREQUAL "WARN") + message(WARNING "Using eosio version ${EOSIO_VERSION} even though it exceeds the maximum supported version of ${EOSIO_VERSION_SOFT_MAX}; continuing with configuration, however build may fail.\nIt is recommended to use eosio version ${EOSIO_VERSION_SOFT_MAX}.x") +else() # INVALID OR MISMATCH + message(FATAL_ERROR "Found eosio version ${EOSIO_VERSION} but it does not satisfy version requirements: ${VERSION_MATCH_ERROR_MSG}\nPlease use eosio version ${EOSIO_VERSION_SOFT_MAX}.x") +endif(VERSION_OUTPUT STREQUAL "MATCH") enable_testing() From 76a7e4b359d106232aa6d2bb68aee828f6d190f2 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 28 Sep 2018 17:34:13 -0400 Subject: [PATCH 0544/1048] added init action and started work on tests --- eosio.system/abi/eosio.system.abi | 10 +++ .../include/eosio.system/eosio.system.hpp | 16 ++++- eosio.system/src/delegate_bandwidth.cpp | 4 +- eosio.system/src/eosio.system.cpp | 42 ++++++------ eosio.system/src/producer_pay.cpp | 2 +- tests/eosio.msig_tests.cpp | 45 ++++++------- tests/eosio.system_tester.hpp | 65 ++++++++++--------- tests/test_symbol.hpp | 11 ++++ 8 files changed, 115 insertions(+), 80 deletions(-) create mode 100644 tests/test_symbol.hpp diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 9855e669..c7b6e3cd 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -24,6 +24,12 @@ {"name":"actor", "type":"account_name"}, {"name":"permission", "type":"permission_name"} ] + },{ + "name": "init", + "base": "", + "fields": [ + {"name":"core", "type":"symbol"} + ] },{ "name": "abi_hash", "base": "", @@ -465,6 +471,10 @@ "name": "newaccount", "type": "newaccount", "ricardian_contract": "" + },{ + "name": "init", + "type": "init", + "ricardian_contract": "" },{ "name": "setcode", "type": "setcode", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index f44559e8..dbba1923 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -171,8 +171,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr uint64_t system_token_symbol = CORE_SYMBOL; - + class system_contract : public native { private: voters_table _voters; @@ -189,8 +188,21 @@ namespace eosiosystem { public: system_contract( account_name s ); ~system_contract(); + + inline uint64_t get_core_symbol() { + auto get_sym = [&]() { + auto itr = _rammarket.find(S(4,RAMCORE)); + eosio_assert(itr != _rammarket.end(), "rammarket must exist"); + uint64_t sym = 0; + _rammarket.modify(itr, 0, [&]( auto& m ) { sym = m.quote.balance.symbol; } ); + return sym; + }; + static uint64_t sym = get_sym(); + return sym; + } // Actions: + void init( symbol_type core ); void onblock( block_timestamp timestamp, account_name producer ); // const block_header& header ); /// only parse first 3 fields of block header diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index edede0e5..7250b4f0 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -90,7 +90,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); auto tmp = *itr; - auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); + auto eosout = tmp.convert( asset(bytes,S(0,RAM)), get_core_symbol() ); buyram( payer, receiver, eosout ); } @@ -177,7 +177,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); + tokens_out = es.convert( asset(bytes,S(0,RAM)), get_core_symbol()); }); eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 5de82a65..8424a4a8 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -24,24 +24,6 @@ namespace eosiosystem { _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; - - auto itr = _rammarket.find(S(4,RAMCORE)); - - if( itr == _rammarket.end() ) { - auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; - if( system_token_supply > 0 ) { - itr = _rammarket.emplace( _self, [&]( auto& m ) { - m.supply.amount = 100000000000000ll; - m.supply.symbol = S(4,RAMCORE); - m.base.balance.amount = int64_t(_gstate.free_ram()); - m.base.balance.symbol = S(0,RAM); - m.quote.balance.amount = system_token_supply / 1000; - m.quote.balance.symbol = CORE_SYMBOL; - }); - } - } else { - //print( "ram market already created" ); - } } eosio_global_state system_contract::get_default_parameters() { @@ -190,12 +172,12 @@ namespace eosiosystem { auto it = refunds_table.find( current->high_bidder ); if ( it != refunds_table.end() ) { refunds_table.modify( it, 0, [&](auto& r) { - r.amount += asset( current->high_bid, system_token_symbol ); + r.amount += asset( current->high_bid, get_core_symbol() ); }); } else { refunds_table.emplace( bidder, [&](auto& r) { r.bidder = current->high_bidder; - r.amount = asset( current->high_bid, system_token_symbol ); + r.amount = asset( current->high_bid, get_core_symbol() ); }); } @@ -286,7 +268,23 @@ namespace eosiosystem { }); } } - + + void system_contract::init( symbol_type core ) { + auto itr = _rammarket.find(S(4,RAMCORE)); + if ( itr == _rammarket.end() ) { + auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(core).name()).amount; + if( system_token_supply > 0 ) { + _rammarket.emplace( S(4,RAMCORE), [&]( auto& m ) { + m.supply.amount = 100000000000000ll; + m.supply.symbol = S(4,RAMCORE); + m.base.balance.amount = int64_t(_gstate.free_ram()); + m.base.balance.symbol = S(0,RAM); + m.quote.balance.amount = system_token_supply / 1000; + m.quote.balance.symbol = core; + }); + } + } + } } /// eosio.system @@ -294,7 +292,7 @@ EOSIO_ABI( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp - (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) + (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index e71693d1..1c48e0db 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -84,7 +84,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); + const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(get_core_symbol()).name() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 9bf3fc16..766f1ef8 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -7,6 +7,7 @@ #include #include "contracts.hpp" +#include "test_symbol.hpp" using namespace eosio::testing; using namespace eosio; @@ -18,7 +19,6 @@ using mvo = fc::mutable_variant_object; class eosio_msig_tester : public tester { public: - eosio_msig_tester() { create_accounts( { N(eosio.msig), N(eosio.stake), N(eosio.ram), N(eosio.ramfee), N(alice), N(bob), N(carol) } ); produce_block(); @@ -40,7 +40,7 @@ class eosio_msig_tester : public tester { } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, - asset net = core_from_string("10.0000"), asset cpu = core_from_string("10.0000") ) { + asset net = core_sym::from_string("10.0000"), asset cpu = core_sym::from_string("10.0000") ) { signed_transaction trx; set_transaction_headers(trx); @@ -113,14 +113,14 @@ class eosio_msig_tester : public tester { // the balance is implied to be 0 if either the table or row does not exist if (tbl) { - const auto *obj = db.find(boost::make_tuple(tbl->id, symbol(CORE_SYMBOL).to_symbol_code())); + const auto *obj = db.find(boost::make_tuple(tbl->id, symbol(CORE_SYM).to_symbol_code())); if (obj) { // balance is the first field in the serialization fc::datastream ds(obj->value.data(), obj->value.size()); fc::raw::unpack(ds, result); } } - return asset( result, symbol(CORE_SYMBOL) ); + return asset( result, symbol(CORE_SYM) ); } transaction_trace_ptr push_action( const account_name& signer, const action_name& name, const variant_object& data, bool auth = true ) { @@ -406,21 +406,22 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) set_code( N(eosio.token), contracts::token_wasm() ); set_abi( N(eosio.token), contracts::token_abi().data() ); - create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); - issue(config::system_account_name, core_from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), + create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); + issue(config::system_account_name, core_sym::from_string("1000000000.0000")); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); - + base_tester::push_action(config::system_account_name, N(init), + config::system_account_name, mutable_variant_object() + ("core", CORE_SYM_STR)); produce_blocks(); + create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); + create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); + create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); - create_account_with_resources( N(alice1111111), N(eosio), core_from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), N(eosio), core_from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), N(eosio), core_from_string("1.0000"), false ); - - BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, @@ -496,7 +497,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) // can't create account because system contract was replace by the test_api contract - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_from_string("1.0000"), false ), + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), eosio_assert_message_exception, eosio_assert_message_is("Unknown Test") ); @@ -518,20 +519,20 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester set_code( N(eosio.token), contracts::token_wasm() ); set_abi( N(eosio.token), contracts::token_abi().data() ); - create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); - issue(config::system_account_name, core_from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance( "eosio" ) ); + create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); + issue(config::system_account_name, core_sym::from_string("1000000000.0000")); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( "eosio" ) ); set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); produce_blocks(); - create_account_with_resources( N(alice1111111), N(eosio), core_from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), N(eosio), core_from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), N(eosio), core_from_string("1.0000"), false ); + create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); + create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); + create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); - BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, @@ -619,7 +620,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester // can't create account because system contract was replace by the test_api contract - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_from_string("1.0000"), false ), + BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), eosio_assert_message_exception, eosio_assert_message_is("Unknown Test") ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index f7d9342d..3db3e9ab 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -7,6 +7,7 @@ #include #include #include "contracts.hpp" +#include "test_symbol.hpp" #include #include @@ -25,14 +26,14 @@ using mvo = fc::mutable_variant_object; #endif #endif + namespace eosio_system { class eosio_system_tester : public TESTER { public: - eosio_system_tester() : eosio_system_tester([](TESTER& ) {}){} - + template eosio_system_tester(Lambda setup) { setup(*this); @@ -53,12 +54,14 @@ class eosio_system_tester : public TESTER { token_abi_ser.set_abi(abi, abi_serializer_max_time); } - create_currency( N(eosio.token), config::system_account_name, core_from_string("10000000000.0000") ); - issue(config::system_account_name, core_from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance( "eosio" ) ); + create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); + issue(config::system_account_name, core_sym::from_string("1000000000.0000")); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( "eosio" ) ); set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); - + base_tester::push_action(config::system_account_name, N(init), + config::system_account_name, mutable_variant_object() + ("core", CORE_SYM_STR)); { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; @@ -68,11 +71,11 @@ class eosio_system_tester : public TESTER { produce_blocks(); - create_account_with_resources( N(alice1111111), config::system_account_name, core_from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), config::system_account_name, core_from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), config::system_account_name, core_from_string("1.0000"), false ); + create_account_with_resources( N(alice1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); + create_account_with_resources( N(bob111111111), config::system_account_name, core_sym::from_string("0.4500"), false ); + create_account_with_resources( N(carol1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); - BOOST_REQUIRE_EQUAL( core_from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); } @@ -107,8 +110,8 @@ class eosio_system_tester : public TESTER { mvo() ("from", creator) ("receiver", a) - ("stake_net_quantity", core_from_string("10.0000") ) - ("stake_cpu_quantity", core_from_string("10.0000") ) + ("stake_net_quantity", core_sym::from_string("10.0000") ) + ("stake_cpu_quantity", core_sym::from_string("10.0000") ) ("transfer", 0 ) ) ); @@ -119,7 +122,7 @@ class eosio_system_tester : public TESTER { } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, - asset net = core_from_string("10.0000"), asset cpu = core_from_string("10.0000") ) { + asset net = core_sym::from_string("10.0000"), asset cpu = core_from_string("10.0000") ) { signed_transaction trx; set_transaction_headers(trx); @@ -165,9 +168,9 @@ class eosio_system_tester : public TESTER { account_name creator(config::system_account_name); signed_transaction trx; set_transaction_headers(trx); - asset cpu = core_from_string("80.0000"); - asset net = core_from_string("80.0000"); - asset ram = core_from_string("1.0000"); + asset cpu = core_sym::from_string("80.0000"); + asset net = core_sym::from_string("80.0000"); + asset ram = core_sym::from_string("1.0000"); for (const auto& a: accounts) { authority owner_auth( get_public_key( a, "owner" ) ); @@ -319,8 +322,8 @@ class eosio_system_tester : public TESTER { } asset get_balance( const account_name& act ) { - vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYMBOL).to_symbol_code().value ); - return data.empty() ? asset(0, symbol(CORE_SYMBOL)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); + vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYM).to_symbol_code().value ); + return data.empty() ? asset(0, symbol(CORE_SYM)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } fc::variant get_total_stake( const account_name& act ) { @@ -373,7 +376,7 @@ class eosio_system_tester : public TESTER { } double stake2votes( const string& s ) { - return stake2votes( core_from_string(s) ); + return stake2votes( core_sym::from_string(s) ); } fc::variant get_stats( const string& symbolname ) { @@ -384,7 +387,7 @@ class eosio_system_tester : public TESTER { } asset get_token_supply() { - return get_stats("4," CORE_SYMBOL_NAME)["supply"].as(); + return get_stats("4," CORE_SYM_NAME)["supply"].as(); } uint64_t microseconds_since_epoch_of_iso_string( const fc::variant& v ) { @@ -416,7 +419,7 @@ class eosio_system_tester : public TESTER { abi_serializer msig_abi_ser; { create_account_with_resources( N(eosio.msig), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( "eosio", "eosio.msig", core_from_string("5000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "eosio", "eosio.msig", core_sym::from_string("5000.0000") ) ); produce_block(); auto trace = base_tester::push_action(config::system_account_name, N(setpriv), @@ -439,8 +442,8 @@ class eosio_system_tester : public TESTER { vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain - transfer( "eosio", "alice1111111", core_from_string("650000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("300000000.0000"), core_from_string("300000000.0000") ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("650000000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_from_string("300000000.0000") ) ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers std::vector producer_names; @@ -472,9 +475,9 @@ class eosio_system_tester : public TESTER { //vote for producers { - transfer( config::system_account_name, "alice1111111", core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake( "alice1111111", core_from_string("30000000.0000"), core_from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), buyram( "alice1111111", "alice1111111", core_from_string("30000000.0000") ) ); + transfer( config::system_account_name, "alice1111111", core_sym::from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake( "alice1111111", core_sym::from_string("30000000.0000"), core_from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("30000000.0000") ) ); BOOST_REQUIRE_EQUAL(success(), push_action(N(alice1111111), N(voteproducer), mvo() ("voter", "alice1111111") ("proxy", name(0).to_string()) @@ -503,8 +506,8 @@ class eosio_system_tester : public TESTER { mvo() ("from", name{config::system_account_name}) ("receiver", "producer1111") - ("stake_net_quantity", core_from_string("150000000.0000") ) - ("stake_cpu_quantity", core_from_string("0.0000") ) + ("stake_net_quantity", core_sym::from_string("150000000.0000") ) + ("stake_cpu_quantity", core_sym::from_string("0.0000") ) ("transfer", 1 ) ) ); @@ -521,8 +524,8 @@ class eosio_system_tester : public TESTER { mvo() ("from", "producer1111") ("receiver", "producer1111") - ("unstake_net_quantity", core_from_string("150000000.0000") ) - ("unstake_cpu_quantity", core_from_string("0.0000") ) + ("unstake_net_quantity", core_sym::from_string("150000000.0000") ) + ("unstake_cpu_quantity", core_sym::from_string("0.0000") ) ) ); @@ -563,7 +566,7 @@ inline fc::mutable_variant_object proxy( account_name acct ) { } inline uint64_t M( const string& eos_str ) { - return core_from_string( eos_str ).get_amount(); + return core_sym::from_string( eos_str ).get_amount(); } } diff --git a/tests/test_symbol.hpp b/tests/test_symbol.hpp new file mode 100644 index 00000000..21cff898 --- /dev/null +++ b/tests/test_symbol.hpp @@ -0,0 +1,11 @@ +#pragma once +#define CORE_SYM SY(4, TST) +#define CORE_SYM_NAME "TST" +#define CORE_SYM_STR "4,TST" + +struct core_sym { + static inline eosio::chain::asset from_string(const std::string& s) { + return eosio::chain::asset::from_string(s + " " CORE_SYM_NAME); + } +}; + From a2e3ae20f1d7825ff60891ced4056a556551fbc1 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 28 Sep 2018 17:53:56 -0400 Subject: [PATCH 0545/1048] Add REX loan auto-renew option --- eosio.system/abi/eosio.system.abi | 20 ++- .../include/eosio.system/eosio.system.hpp | 18 ++- eosio.system/src/rex.cpp | 129 +++++++++++++++--- tests/eosio.system_tester.hpp | 3 +- 4 files changed, 138 insertions(+), 32 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 46de19ca..9f7c3aae 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -254,9 +254,14 @@ "name": "rex_loan", "base": "", "fields": [ - {"name":"receiver", "type":"account_name"}, - {"name":"total_stake", "type":"asset"}, - {"name":"loan_num", "type":"uint64"} + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"loan_payment", "type":"asset"}, + {"name":"total_stake", "type":"asset"}, + {"name":"loan_num", "type":"uint64"}, + {"name":"expiration", "type":"time_point"}, + {"name":"auto_renew", "type":"bool"}, + {"name":"balance", "type":"asset"} ] },{ "name": "rex_order", @@ -273,10 +278,11 @@ "name": "rent", "base": "", "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"payment", "type":"asset"}, - {"name":"cpu", "type":"bool"} + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"payment", "type":"asset"}, + {"name":"cpu", "type":"bool"}, + {"name":"auto_renew", "type":"bool"} ] },{ "name": "user_resources", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 59bc3336..5d676316 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -196,17 +196,25 @@ namespace eosiosystem { typedef eosio::multi_index< N(rexbal), rex_balance > rex_balance_table; struct rex_loan { + account_name from; account_name receiver; + asset loan_payment; asset total_staked; uint64_t loan_num; - eosio::time_point expiration; + + bool auto_renew = false; + asset balance; - uint64_t primary_key()const { return loan_num; } + uint64_t primary_key()const { return loan_num; } + uint64_t by_expr()const { return expiration.elapsed.count(); } }; - typedef eosio::multi_index< N(cpuloan), rex_loan> rex_cpu_loan_table; - typedef eosio::multi_index< N(cpunet), rex_loan> rex_net_loan_table; + typedef eosio::multi_index< N(cpuloan), rex_loan, + indexed_by>> rex_cpu_loan_table; + + typedef eosio::multi_index< N(netloan), rex_loan, + indexed_by>> rex_net_loan_table; struct rex_order { account_name owner; @@ -275,7 +283,7 @@ namespace eosiosystem { * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ - void rent( account_name from, account_name receiver, asset payment, bool cpu ); + void rent( account_name from, account_name receiver, asset payment, bool cpu, bool auto_renew ); /** * Decreases the total tokens delegated by from to receiver and/or diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index c49a0e4c..b23c8a2d 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -161,7 +161,7 @@ namespace eosiosystem { * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ - void system_contract::rent( account_name from, account_name receiver, asset payment, bool cpu ) { + void system_contract::rent( account_name from, account_name receiver, asset payment, bool cpu, bool auto_renew ) { require_auth( from ); runrex(2); @@ -185,20 +185,30 @@ namespace eosiosystem { rex_cpu_loan_table cpu_loans(_self,_self); cpu_loans.emplace( from, [&]( auto& c ) { + c.from = from; c.receiver = receiver; + c.loan_payment = payment; c.total_staked = asset( rented_tokens, CORE_SYMBOL ); c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); c.loan_num = itr->loan_num; + + c.auto_renew = auto_renew; + c.balance = asset( 0, CORE_SYMBOL ); }); update_resource_limits( receiver, rented_tokens, 0 ); } else { rex_net_loan_table net_loans(_self,_self); net_loans.emplace( from, [&]( auto& c ) { + c.from = from; c.receiver = receiver; + c.loan_payment = payment; c.total_staked = asset( rented_tokens, CORE_SYMBOL ); c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); c.loan_num = itr->loan_num; + + c.auto_renew = auto_renew; + c.balance = asset( 0, CORE_SYMBOL ); }); update_resource_limits( receiver, 0, rented_tokens ); } @@ -219,26 +229,107 @@ namespace eosiosystem { }); }; - rex_cpu_loan_table cpu_loans( _self, _self ); - for( uint16_t i = 0; i < max; ++i ) { - auto itr = cpu_loans.begin(); - if( itr == cpu_loans.end() ) break; - if( itr->expiration.elapsed.count() > current_time() ) break; - - update_resource_limits( itr->receiver, -itr->total_staked.amount, 0 ); - unrent( itr->total_staked.amount ); - cpu_loans.erase( itr ); + // TODO: refactor and remove code duplication + { + rex_cpu_loan_table cpu_loans( _self, _self ); + auto cpu_idx = cpu_loans.get_index(); + bool delete_loan = false; + for( uint16_t i = 0; i < max; ++i ) { + auto itr = cpu_idx.begin(); + if( itr == cpu_idx.end() ) break; + if( itr->expiration.elapsed.count() > current_time() ) break; + + // update rex totals to account for closing the loan + unrent( itr->total_staked.amount ); + + int64_t delta_stake = 0; + if( itr->auto_renew && itr->loan_payment <= itr->balance ) { + + int64_t rented_tokens = 0; + _rextable.modify( rexi, 0, [&]( auto& rt ) { + rented_tokens = bancor_convert( rt.total_rent.amount, + rt.total_unlent.amount, + itr->loan_payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += itr->loan_payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + }); + + { + auto prim_itr = cpu_loans.find( itr->loan_num ); + cpu_loans.modify ( prim_itr, 0, [&]( auto loan ) { + delta_stake = rented_tokens - loan.total_staked.amount; + loan.total_staked.amount = rented_tokens; + loan.expiration += eosio::days(30); + loan.balance -= itr->loan_payment; + }); + } + + } else { + delete_loan = true; + delta_stake = -( itr->total_staked.amount ); + if( itr->auto_renew ) { + // refund "from" account + } + } + + if( delta_stake != 0 ) + update_resource_limits( itr->receiver, delta_stake, 0 ); + if( delete_loan ) + cpu_idx.erase( itr ); + } } - rex_net_loan_table net_loans( _self, _self ); - for( uint16_t i = 0; i < max; ++i ) { - auto itr = net_loans.begin(); - if( itr == net_loans.end() ) break; - if( itr->expiration.elapsed.count() > current_time() ) break; - - update_resource_limits( itr->receiver, 0, -itr->total_staked.amount ); - unrent( itr->total_staked.amount ); - net_loans.erase( itr ); + // TODO: refactor and remove code duplication + { + rex_net_loan_table net_loans( _self, _self ); + auto net_idx = net_loans.get_index(); + bool delete_loan = false; + for( uint16_t i = 0; i < max; ++i ) { + auto itr = net_idx.begin(); + if( itr == net_idx.end() ) break; + if( itr->expiration.elapsed.count() > current_time() ) break; + + // update rex totals to account for closing the loan + unrent( itr->total_staked.amount ); + + int64_t delta_stake = 0; + if( itr->auto_renew && itr->loan_payment <= itr->balance ) { + + int64_t rented_tokens = 0; + _rextable.modify( rexi, 0, [&]( auto& rt ) { + rented_tokens = bancor_convert( rt.total_rent.amount, + rt.total_unlent.amount, + itr->loan_payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += itr->loan_payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + }); + + { + auto prim_itr = net_loans.find( itr->loan_num ); + net_loans.modify ( prim_itr, 0, [&]( auto loan ) { + delta_stake = rented_tokens - loan.total_staked.amount; + loan.total_staked.amount = rented_tokens; + loan.expiration += eosio::days(30); + loan.balance -= itr->loan_payment; + }); + } + + } else { + delete_loan = true; + delta_stake = -( itr->total_staked.amount ); + if( itr->auto_renew && itr->balance.amount > 0 ) { + // refund "from" account + } + } + + if( delta_stake != 0 ) + update_resource_limits( itr->receiver, 0, delta_stake ); + + if( delete_loan ) + net_idx.erase( itr ); + } } rex_order_table rexorders( _self, _self ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index a22be914..cdff5338 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -287,12 +287,13 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(claimrex), mvo()("owner", owner) ); } - action_result rent( const account_name& from, const account_name& receiver, const asset& payment, bool cpu ) { + action_result rent( const account_name& from, const account_name& receiver, const asset& payment, bool cpu, bool auto_renew = false ) { return push_action( name(from), N(rent), mvo() ("from", from) ("receiver", receiver) ("payment", payment) ("cpu", cpu) + ("auto_renew", auto_renew) ); } From 5056f94e913762a08caa1790a2221226fd12ed82 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 28 Sep 2018 18:27:05 -0400 Subject: [PATCH 0546/1048] Add fundrexloan action --- eosio.system/abi/eosio.system.abi | 13 ++++++++ .../include/eosio.system/eosio.system.hpp | 2 ++ eosio.system/src/rex.cpp | 30 +++++++++++++++++++ 3 files changed, 45 insertions(+) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 9f7c3aae..448f29ef 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -284,6 +284,15 @@ {"name":"cpu", "type":"bool"}, {"name":"auto_renew", "type":"bool"} ] + },{ + "name": "fundrexloan", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"loan_num", "type":"uint64"}, + {"name":"payment", "type":"asset"}, + {"name":"cpu", "type":"bool"} + ] },{ "name": "user_resources", "base": "", @@ -620,6 +629,10 @@ "name": "rent", "type": "rent", "ricardian_contract": "" + },{ + "name": "fundrexloan", + "type": "fundrexloan", + "ricardian_contract": "" },{ "name": "regproducer", "type": "regproducer", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 5d676316..082c2255 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -284,6 +284,8 @@ namespace eosiosystem { * after 30 days the rented SYS delegation of CPU or NET will expire. */ void rent( account_name from, account_name receiver, asset payment, bool cpu, bool auto_renew ); + + void fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ); /** * Decreases the total tokens delegated by from to receiver and/or diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index b23c8a2d..6ae79f83 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -214,6 +214,36 @@ namespace eosiosystem { } } + void system_contract::fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ) { + + require_auth( from ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio.rex), payment, string("fund ") + (cpu ? "CPU loan" : "NET loan") } ); + // TODO: refactor and remove code duplication + if( cpu ) { + rex_cpu_loan_table cpu_loans( _self, _self ); + auto itr = cpu_loans.find( loan_num ); + eosio_assert( itr != cpu_loans.end(), "loan not found" ); + eosio_assert( itr->from, "actor has to be loan creator" ); + eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); + eosio_assert( itr->expiration < current_time_point(), "loan has already expired" ); + cpu_loans.modify( itr, 0, [&]( auto& loan ) { + loan.balance.amount += payment.amount; + }); + } else { + rex_net_loan_table net_loans( _self, _self ); + auto itr = net_loans.find( loan_num ); + eosio_assert( itr != net_loans.end(), "loan not found" ); + eosio_assert( itr->from, "actor has to be loan creator" ); + eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); + eosio_assert( itr->expiration < current_time_point(), "loan has already expired" ); + net_loans.modify( itr, 0, [&]( auto& loan ) { + loan.balance.amount += payment.amount; + }); + } + } + /** * Perform maitenance operations on expired rex */ From 74f507242b605e5bf621a9401951fd885f1808a7 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 28 Sep 2018 19:51:06 -0400 Subject: [PATCH 0547/1048] update system contract to not use default symbol type in asset constructor --- .../include/eosio.system/eosio.system.hpp | 12 ++-- eosio.system/src/delegate_bandwidth.cpp | 63 ++++++++++--------- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/producer_pay.cpp | 15 +++-- 4 files changed, 47 insertions(+), 45 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index dbba1923..00233794 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -171,7 +171,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - + class system_contract : public native { private: voters_table _voters; @@ -188,16 +188,16 @@ namespace eosiosystem { public: system_contract( account_name s ); ~system_contract(); - - inline uint64_t get_core_symbol() { - auto get_sym = [&]() { + + inline symbol_type get_core_symbol() { + auto get_sym = [&]() -> symbol_type { auto itr = _rammarket.find(S(4,RAMCORE)); eosio_assert(itr != _rammarket.end(), "rammarket must exist"); uint64_t sym = 0; _rammarket.modify(itr, 0, [&]( auto& m ) { sym = m.quote.balance.symbol; } ); - return sym; + return {sym}; }; - static uint64_t sym = get_sym(); + static auto sym = get_sym(); return sym; } diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 7250b4f0..7a8d0a57 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -200,7 +200,7 @@ namespace eosiosystem { // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount if( fee > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, - { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); + { account, N(eosio.ramfee), asset(fee, get_core_symbol()), std::string("sell ram fee") } ); } } @@ -216,7 +216,7 @@ namespace eosiosystem { const asset stake_net_delta, const asset stake_cpu_delta, bool transfer ) { require_auth( from ); - eosio_assert( stake_net_delta != asset(0) || stake_cpu_delta != asset(0), "should stake non-zero amount" ); + eosio_assert( stake_net_delta.amount != 0 || stake_cpu_delta.amount != 0, "should stake non-zero amount" ); eosio_assert( std::abs( (stake_net_delta + stake_cpu_delta).amount ) >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), "net and cpu deltas cannot be opposite signs" ); @@ -244,9 +244,9 @@ namespace eosiosystem { dbo.cpu_weight += stake_cpu_delta; }); } - eosio_assert( asset(0) <= itr->net_weight, "insufficient staked net bandwidth" ); - eosio_assert( asset(0) <= itr->cpu_weight, "insufficient staked cpu bandwidth" ); - if ( itr->net_weight == asset(0) && itr->cpu_weight == asset(0) ) { + eosio_assert( 0 <= itr->net_weight.amount, "insufficient staked net bandwidth" ); + eosio_assert( 0 <= itr->cpu_weight.amount, "insufficient staked cpu bandwidth" ); + if ( itr->net_weight.amount == 0 && itr->cpu_weight.amount == 0 ) { del_tbl.erase( itr ); } } // itr can be invalid, should go out of scope @@ -267,15 +267,15 @@ namespace eosiosystem { tot.cpu_weight += stake_cpu_delta; }); } - eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); - eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); + eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); + eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); int64_t ram_bytes, net, cpu; get_resource_limits( receiver, &ram_bytes, &net, &cpu ); set_resource_limits( receiver, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) && tot_itr->ram_bytes == 0 ) { + if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); } } // tot_itr can be invalid, should go out of scope @@ -299,44 +299,44 @@ namespace eosiosystem { if( is_delegating_to_self || is_undelegating ) { if ( req != refunds_tbl.end() ) { //need to update refund refunds_tbl.modify( req, 0, [&]( refund_request& r ) { - if ( net_balance < asset(0) || cpu_balance < asset(0) ) { + if ( net_balance.amount < 0 || cpu_balance.amount < 0 ) { r.request_time = now(); } r.net_amount -= net_balance; - if ( r.net_amount < asset(0) ) { + if ( r.net_amount.amount < 0 ) { net_balance = -r.net_amount; - r.net_amount = asset(0); + r.net_amount.amount = 0; } else { - net_balance = asset(0); + net_balance.amount = 0; } r.cpu_amount -= cpu_balance; - if ( r.cpu_amount < asset(0) ){ + if ( r.cpu_amount.amount < 0 ){ cpu_balance = -r.cpu_amount; - r.cpu_amount = asset(0); + r.cpu_amount.amount = 0; } else { - cpu_balance = asset(0); + cpu_balance.amount = 0; } }); - eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen - eosio_assert( asset(0) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen + eosio_assert( 0 <= req->net_amount.amount, "negative net refund amount" ); //should never happen + eosio_assert( 0 <= req->cpu_amount.amount, "negative cpu refund amount" ); //should never happen - if ( req->net_amount == asset(0) && req->cpu_amount == asset(0) ) { + if ( req->net_amount.amount == 0 && req->cpu_amount.amount == 0 ) { refunds_tbl.erase( req ); need_deferred_trx = false; } else { need_deferred_trx = true; } - } else if ( net_balance < asset(0) || cpu_balance < asset(0) ) { //need to create refund + } else if ( net_balance.amount < 0 || cpu_balance.amount < 0 ) { //need to create refund refunds_tbl.emplace( from, [&]( refund_request& r ) { r.owner = from; - if ( net_balance < asset(0) ) { + if ( net_balance.amount < 0 ) { r.net_amount = -net_balance; - net_balance = asset(0); + net_balance.amount = 0; } // else r.net_amount = 0 by default constructor - if ( cpu_balance < asset(0) ) { + if ( cpu_balance.amount < 0 ) { r.cpu_amount = -cpu_balance; - cpu_balance = asset(0); + cpu_balance.amount = 0; } // else r.cpu_amount = 0 by default constructor r.request_time = now(); }); @@ -355,7 +355,7 @@ namespace eosiosystem { } auto transfer_amount = net_balance + cpu_balance; - if ( asset(0) < transfer_amount ) { + if ( 0 < transfer_amount.amount ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {source_stake_from, N(active)}, { source_stake_from, N(eosio.stake), asset(transfer_amount), std::string("stake bandwidth") } ); } @@ -390,19 +390,22 @@ namespace eosiosystem { asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ) { - eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); - eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); - eosio_assert( stake_net_quantity + stake_cpu_quantity > asset(0), "must stake a positive amount" ); + asset zero_asset( 0, get_core_symbol() ); + eosio_assert( stake_cpu_quantity >= zero_asset, "must stake a positive amount" ); + eosio_assert( stake_net_quantity >= zero_asset, "must stake a positive amount" ); + eosio_assert( stake_net_quantity.amount + stake_cpu_quantity.amount > 0, "must stake a positive amount" ); eosio_assert( !transfer || from != receiver, "cannot use transfer flag if delegating to self" ); + changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); } // delegatebw void system_contract::undelegatebw( account_name from, account_name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ) { - eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); - eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); - eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); + asset zero_asset( 0, get_core_symbol() ); + eosio_assert( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); + eosio_assert( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); + eosio_assert( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 8424a4a8..ba6914d7 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -268,7 +268,7 @@ namespace eosiosystem { }); } } - + void system_contract::init( symbol_type core ) { auto itr = _rammarket.find(S(4,RAMCORE)); if ( itr == _rammarket.end() ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 1c48e0db..ee5c1443 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -16,7 +16,6 @@ namespace eosiosystem { const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); const int64_t useconds_per_year = seconds_per_year*1000000ll; - void system_contract::onblock( block_timestamp timestamp, account_name producer ) { using namespace eosio; @@ -84,7 +83,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(get_core_symbol()).name() ); + const asset token_supply = token( N(eosio.token)).get_supply( get_core_symbol().name() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { @@ -96,16 +95,16 @@ namespace eosiosystem { auto to_per_vote_pay = to_producers - to_per_block_pay; INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - { N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings") } ); + { N(eosio), asset(new_tokens, get_core_symbol()), std::string("issue tokens for producer pay and savings") } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.saving), asset(to_savings), "unallocated inflation" } ); + { N(eosio), N(eosio.saving), asset(to_savings, get_core_symbol()), "unallocated inflation" } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.bpay), asset(to_per_block_pay), "fund per-block bucket" } ); + { N(eosio), N(eosio.bpay), asset(to_per_block_pay, get_core_symbol()), "fund per-block bucket" } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.vpay), asset(to_per_vote_pay), "fund per-vote bucket" } ); + { N(eosio), N(eosio.vpay), asset(to_per_vote_pay, get_core_symbol()), "fund per-vote bucket" } ); _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; @@ -176,11 +175,11 @@ namespace eosiosystem { if( producer_per_block_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.bpay),N(active)},{owner,N(active)}}, - { N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } ); + { N(eosio.bpay), owner, asset(producer_per_block_pay, get_core_symbol()), std::string("producer block pay") } ); } if( producer_per_vote_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.vpay),N(active)},{owner,N(active)}}, - { N(eosio.vpay), owner, asset(producer_per_vote_pay), std::string("producer vote pay") } ); + { N(eosio.vpay), owner, asset(producer_per_vote_pay, get_core_symbol()), std::string("producer vote pay") } ); } } From c0abc6b4ef31e5483661e4e0f106ff997627dcfa Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sat, 29 Sep 2018 18:37:13 -0400 Subject: [PATCH 0548/1048] Separate REX rent into rentcpu and rentnet --- eosio.system/abi/eosio.system.abi | 20 ++++- .../include/eosio.system/eosio.system.hpp | 3 +- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/rex.cpp | 88 ++++++++++++------- tests/eosio.system_tester.hpp | 20 +++-- tests/eosio.system_tests.cpp | 10 +-- 6 files changed, 94 insertions(+), 49 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 448f29ef..15bb6da4 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -275,13 +275,21 @@ {"name":"is_open", "type":"bool"} ] },{ - "name": "rent", + "name": "rentcpu", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"receiver", "type":"account_name"}, + {"name":"payment", "type":"asset"}, + {"name":"auto_renew", "type":"bool"} + ] + },{ + "name": "rentnet", "base": "", "fields": [ {"name":"from", "type":"account_name"}, {"name":"receiver", "type":"account_name"}, {"name":"payment", "type":"asset"}, - {"name":"cpu", "type":"bool"}, {"name":"auto_renew", "type":"bool"} ] },{ @@ -626,8 +634,12 @@ "type": "claimrex", "ricardian_contract": "" },{ - "name": "rent", - "type": "rent", + "name": "rentcpu", + "type": "rentcpu", + "ricardian_contract": "" + },{ + "name": "rentnet", + "type": "rentnet", "ricardian_contract": "" },{ "name": "fundrexloan", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 082c2255..2fa50abf 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -283,7 +283,8 @@ namespace eosiosystem { * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ - void rent( account_name from, account_name receiver, asset payment, bool cpu, bool auto_renew ); + void rentcpu( account_name from, account_name receiver, asset payment, bool auto_renew ); + void rentnet( account_name from, account_name receiver, asset payment, bool auto_renew ); void fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 9025a23b..0d3ac9ef 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -298,7 +298,7 @@ EOSIO_ABI( eosiosystem::system_contract, // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rent) + (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 6ae79f83..5f39d32c 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -161,13 +161,14 @@ namespace eosiosystem { * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ - void system_contract::rent( account_name from, account_name receiver, asset payment, bool cpu, bool auto_renew ) { + void system_contract::rentcpu( account_name from, account_name receiver, asset payment, bool auto_renew ) { + require_auth( from ); runrex(2); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio.rex), payment, string("rent ") + (cpu ? "CPU" : "NET") } ); + { from, N(eosio.rex), payment, string("rent CPU") } ); auto itr = _rextable.begin(); eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); @@ -181,38 +182,61 @@ namespace eosiosystem { rt.loan_num++; }); - if( cpu ) { - rex_cpu_loan_table cpu_loans(_self,_self); - - cpu_loans.emplace( from, [&]( auto& c ) { - c.from = from; - c.receiver = receiver; - c.loan_payment = payment; - c.total_staked = asset( rented_tokens, CORE_SYMBOL ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); - c.loan_num = itr->loan_num; - - c.auto_renew = auto_renew; - c.balance = asset( 0, CORE_SYMBOL ); - }); - update_resource_limits( receiver, rented_tokens, 0 ); - } else { - rex_net_loan_table net_loans(_self,_self); + rex_cpu_loan_table cpu_loans(_self,_self); + + cpu_loans.emplace( from, [&]( auto& c ) { + c.from = from; + c.receiver = receiver; + c.loan_payment = payment; + c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; - net_loans.emplace( from, [&]( auto& c ) { - c.from = from; - c.receiver = receiver; - c.loan_payment = payment; - c.total_staked = asset( rented_tokens, CORE_SYMBOL ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); - c.loan_num = itr->loan_num; - - c.auto_renew = auto_renew; - c.balance = asset( 0, CORE_SYMBOL ); - }); - update_resource_limits( receiver, 0, rented_tokens ); - } + c.auto_renew = auto_renew; + c.balance = asset( 0, CORE_SYMBOL ); + }); + + update_resource_limits( receiver, rented_tokens, 0 ); } + + void system_contract::rentnet( account_name from, account_name receiver, asset payment, bool auto_renew ) { + + require_auth( from ); + + runrex(2); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio.rex), payment, string("rent NET") } ); + + auto itr = _rextable.begin(); + eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); + + int64_t rented_tokens = 0; + _rextable.modify( itr, 0, [&]( auto& rt ) { + rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + rt.loan_num++; + }); + + rex_net_loan_table net_loans(_self,_self); + + net_loans.emplace( from, [&]( auto& c ) { + c.from = from; + c.receiver = receiver; + c.loan_payment = payment; + c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.loan_num = itr->loan_num; + + c.auto_renew = auto_renew; + c.balance = asset( 0, CORE_SYMBOL ); + }); + + update_resource_limits( receiver, 0, rented_tokens ); + } + void system_contract::fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ) { diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index cdff5338..9e026420 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -287,12 +287,20 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(claimrex), mvo()("owner", owner) ); } - action_result rent( const account_name& from, const account_name& receiver, const asset& payment, bool cpu, bool auto_renew = false ) { - return push_action( name(from), N(rent), mvo() - ("from", from) - ("receiver", receiver) - ("payment", payment) - ("cpu", cpu) + action_result rentcpu( const account_name& from, const account_name& receiver, const asset& payment, bool auto_renew = false ) { + return push_action( name(from), N(rentcpu), mvo() + ("from", from) + ("receiver", receiver) + ("payment", payment) + ("auto_renew", auto_renew) + ); + } + + action_result rentnet( const account_name& from, const account_name& receiver, const asset& payment, bool auto_renew = false ) { + return push_action( name(from), N(rentnet), mvo() + ("from", from) + ("receiver", receiver) + ("payment", payment) ("auto_renew", auto_renew) ); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index de3dbcd6..a734a518 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3454,7 +3454,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { } // bob tries to rent rex - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rent( bob, carol, core_from_string("5.0000"), true ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_from_string("5.0000") ) ); // alice lends rex BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); BOOST_REQUIRE_EQUAL( init_balance - core_from_string("65.0000"), get_balance(alice) ); @@ -3469,7 +3469,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { { // bob rents cpu for carol const asset fee = core_from_string("17.0000"); - BOOST_REQUIRE_EQUAL( success(), rent( bob, carol, fee, true ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 17 @@ -3522,7 +3522,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), rex_pool["total_unlent"].as().get_amount(), fee.get_amount() ); - BOOST_REQUIRE_EQUAL( success(), rent( emily, emily, fee, false ) ); + BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, fee ) ); BOOST_REQUIRE_EQUAL( expected_net, get_net_limit( emily ) - init_net.get_amount() ); } @@ -3561,7 +3561,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); - BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, core_from_string("1100.0000"), true ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_from_string("1100.0000") ) ); BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); BOOST_REQUIRE_EQUAL( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ); @@ -3601,7 +3601,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { // alices's order is still open // an action is needed to trigger queue processing produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), rent( frank, frank, core_from_string("0.0001"), true ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_from_string("0.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("an unlendrex request has already been scheduled"), unlendrex( alice, init_alice_rex ) ); From dd2dd92f28dc6061c40a0ae077d91b59f7e77b7e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sat, 29 Sep 2018 19:29:46 -0400 Subject: [PATCH 0549/1048] REX loan balance refund --- eosio.system/abi/eosio.system.abi | 17 ++++++++ .../include/eosio.system/eosio.system.hpp | 12 ++++++ eosio.system/src/rex.cpp | 43 +++++++++++++++++-- 3 files changed, 69 insertions(+), 3 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 15bb6da4..00e3af20 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -263,6 +263,13 @@ {"name":"auto_renew", "type":"bool"}, {"name":"balance", "type":"asset"} ] + },{ + "name": "loan_refund", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"}, + {"name":"balance", "type":"asset"} + ] },{ "name": "rex_order", "base": "", @@ -301,6 +308,12 @@ {"name":"payment", "type":"asset"}, {"name":"cpu", "type":"bool"} ] + },{ + "name": "claimrefund", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] },{ "name": "user_resources", "base": "", @@ -645,6 +658,10 @@ "name": "fundrexloan", "type": "fundrexloan", "ricardian_contract": "" + },{ + "name": "claimrefund", + "type": "claimrefund", + "ricardian_contract": "" },{ "name": "regproducer", "type": "regproducer", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 2fa50abf..cfb640a5 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -216,6 +216,15 @@ namespace eosiosystem { typedef eosio::multi_index< N(netloan), rex_loan, indexed_by>> rex_net_loan_table; + struct loan_refund { + account_name owner; + asset balance; + + uint64_t primary_key()const { return owner; } + }; + + typedef eosio::multi_index< N(loanrefunds), loan_refund > loan_refund_table; + struct rex_order { account_name owner; asset rex_requested; @@ -284,10 +293,13 @@ namespace eosiosystem { * after 30 days the rented SYS delegation of CPU or NET will expire. */ void rentcpu( account_name from, account_name receiver, asset payment, bool auto_renew ); + void rentnet( account_name from, account_name receiver, asset payment, bool auto_renew ); void fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ); + void claimrefund( account_name owner ); + /** * Decreases the total tokens delegated by from to receiver and/or * frees the memory associated with the delegation if there is nothing diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 5f39d32c..68093996 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -268,6 +268,19 @@ namespace eosiosystem { } } + void system_contract::claimrefund( account_name owner ) { + + require_auth( owner ); + + loan_refund_table loan_refunds( _self, _self ); + auto itr = loan_refunds.find( owner ); + eosio_assert( itr != loan_refunds.end(), "no refund to be claimed" ); + if( itr->balance.amount > 0 ) + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, + { N(eosio.rex), owner, itr->balance, "claim REX loan refund" } ); + loan_refunds.erase( itr ); + } + /** * Perform maitenance operations on expired rex */ @@ -322,8 +335,20 @@ namespace eosiosystem { } else { delete_loan = true; delta_stake = -( itr->total_staked.amount ); - if( itr->auto_renew ) { - // refund "from" account + // refund "from" account if the closed loan balance is positive + if( itr->auto_renew && itr->balance.amount > 0 ) { + loan_refund_table loan_refunds( _self, _self ); + auto ref_itr = loan_refunds.find( itr->from ); + if( ref_itr == loan_refunds.end() ) { + loan_refunds.emplace( itr->from, [&]( auto& ref ) { + ref.owner = itr->from; + ref.balance = itr->balance; + }); + } else { + loan_refunds.modify( ref_itr, itr->from, [&]( auto& ref ) { + ref.balance.amount += itr->balance.amount; + }); + } } } @@ -373,8 +398,20 @@ namespace eosiosystem { } else { delete_loan = true; delta_stake = -( itr->total_staked.amount ); + // refund "from" account if the closed loan balance is positive if( itr->auto_renew && itr->balance.amount > 0 ) { - // refund "from" account + loan_refund_table loan_refunds( _self, _self ); + auto ref_itr = loan_refunds.find( itr->from ); + if( ref_itr == loan_refunds.end() ) { + loan_refunds.emplace( itr->from, [&]( auto& ref ) { + ref.owner = itr->from; + ref.balance = itr->balance; + }); + } else { + loan_refunds.modify( ref_itr, itr->from, [&]( auto& ref ) { + ref.balance.amount += itr->balance.amount; + }); + } } } From 618b99a3c03f1a70e24f0f3c36e3b0420e90a06d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sat, 29 Sep 2018 19:33:40 -0400 Subject: [PATCH 0550/1048] Update system EOSIO_ABI --- eosio.system/src/eosio.system.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 0d3ac9ef..304183a8 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -298,7 +298,7 @@ EOSIO_ABI( eosiosystem::system_contract, // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet) + (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundrexloan)(claimrefund) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp From a9c37a7829acf277c1fa7a1af52b2b736a29acc0 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 1 Oct 2018 05:01:31 -0400 Subject: [PATCH 0551/1048] remove use of S macro and only use symbol class --- eosio.system/include/eosio.system/eosio.system.hpp | 2 +- .../include/eosio.system/exchange_state.hpp | 4 ++-- eosio.system/src/delegate_bandwidth.cpp | 12 ++++++------ eosio.system/src/eosio.system.cpp | 14 +++++++------- eosio.system/src/exchange_state.cpp | 2 +- eosio.system/src/producer_pay.cpp | 2 +- eosio.token/include/eosio.token/eosio.token.hpp | 12 ++++++------ eosio.token/src/eosio.token.cpp | 4 ++-- 8 files changed, 26 insertions(+), 26 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index f44559e8..9cfa8a6d 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -171,7 +171,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr uint64_t system_token_symbol = CORE_SYMBOL; + static constexpr symbol system_token_symbol = symbol(4, "SYS"); class system_contract : public native { private: diff --git a/eosio.system/include/eosio.system/exchange_state.hpp b/eosio.system/include/eosio.system/exchange_state.hpp index 3705a9b8..4056026e 100644 --- a/eosio.system/include/eosio.system/exchange_state.hpp +++ b/eosio.system/include/eosio.system/exchange_state.hpp @@ -4,7 +4,7 @@ namespace eosiosystem { using eosio::asset; - using eosio::symbol_type; + using eosio::symbol; typedef double real_type; @@ -30,7 +30,7 @@ namespace eosiosystem { asset convert_to_exchange( connector& c, asset in ); asset convert_from_exchange( connector& c, asset in ); - asset convert( asset from, symbol_type to ); + asset convert( asset from, symbol to ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) }; diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index edede0e5..7a94c5d2 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -88,9 +88,9 @@ namespace eosiosystem { */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - auto itr = _rammarket.find(S(4,RAMCORE)); + auto itr = _rammarket.find(symbol(4, "RAMCORE")); auto tmp = *itr; - auto eosout = tmp.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL ); + auto eosout = tmp.convert( asset(bytes,symbol(0, "RAM")), symbol(4, "SYS") ); buyram( payer, receiver, eosout ); } @@ -131,9 +131,9 @@ namespace eosiosystem { int64_t bytes_out; - const auto& market = _rammarket.get(S(4,RAMCORE), "ram market does not exist"); + const auto& market = _rammarket.get(symbol(4, "RAMCORE"), "ram market does not exist"); _rammarket.modify( market, 0, [&]( auto& es ) { - bytes_out = es.convert( quant_after_fee, S(0,RAM) ).amount; + bytes_out = es.convert( quant_after_fee, symbol(0, "RAM") ).amount; }); eosio_assert( bytes_out > 0, "must reserve a positive amount" ); @@ -174,10 +174,10 @@ namespace eosiosystem { eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; - auto itr = _rammarket.find(S(4,RAMCORE)); + auto itr = _rammarket.find(symbol(4, "RAMCORE")); _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(bytes,S(0,RAM)), CORE_SYMBOL); + tokens_out = es.convert( asset(bytes,symbol(0, "RAM")), symbol(4, "SYS")); }); eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 5de82a65..bea2c4ed 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -25,18 +25,18 @@ namespace eosiosystem { _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; - auto itr = _rammarket.find(S(4,RAMCORE)); + auto itr = _rammarket.find(symbol(4, "RAMCORE")); if( itr == _rammarket.end() ) { - auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(system_token_symbol).name()).amount; + auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol(system_token_symbol)).amount; if( system_token_supply > 0 ) { itr = _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; - m.supply.symbol = S(4,RAMCORE); + m.supply.symbol = symbol(4, "RAMCORE"); m.base.balance.amount = int64_t(_gstate.free_ram()); - m.base.balance.symbol = S(0,RAM); + m.base.balance.symbol = symbol(0, "RAM"); m.quote.balance.amount = system_token_supply / 1000; - m.quote.balance.symbol = CORE_SYMBOL; + m.quote.balance.symbol = symbol(4, "SYS"); }); } } else { @@ -74,7 +74,7 @@ namespace eosiosystem { eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size); - auto itr = _rammarket.find(S(4,RAMCORE)); + auto itr = _rammarket.find(symbol(4, "RAMCORE")); /** * Increase the amount of ram for sale based upon the change in max ram size. @@ -91,7 +91,7 @@ namespace eosiosystem { if( cbt <= _gstate2.last_ram_increase ) return; - auto itr = _rammarket.find(S(4,RAMCORE)); + auto itr = _rammarket.find(symbol(4, "RAMCORE")); auto new_ram = (cbt.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; _gstate.max_ram_size += new_ram; diff --git a/eosio.system/src/exchange_state.cpp b/eosio.system/src/exchange_state.cpp index b0116903..2612c884 100644 --- a/eosio.system/src/exchange_state.cpp +++ b/eosio.system/src/exchange_state.cpp @@ -43,7 +43,7 @@ namespace eosiosystem { return asset( out, c.balance.symbol ); } - asset exchange_state::convert( asset from, symbol_type to ) { + asset exchange_state::convert( asset from, symbol to ) { auto sell_symbol = from.symbol; auto ex_symbol = supply.symbol; auto base_symbol = base.balance.symbol; diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index e71693d1..7a2156fd 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -84,7 +84,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token( N(eosio.token)).get_supply(symbol_type(system_token_symbol).name() ); + const asset token_supply = token( N(eosio.token)).get_supply(symbol(system_token_symbol)); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 512e877a..9871b97c 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -33,13 +33,13 @@ namespace eosio { asset quantity, string memo ); - void open( account_name owner, symbol_type symbol, account_name payer ); + void open( account_name owner, symbol symbol, account_name payer ); - void close( account_name owner, symbol_type symbol ); + void close( account_name owner, symbol symbol ); - inline asset get_supply( symbol_name sym )const; + inline asset get_supply( symbol sym )const; - inline asset get_balance( account_name owner, symbol_name sym )const; + inline asset get_balance( account_name owner, symbol sym )const; private: struct account { @@ -71,14 +71,14 @@ namespace eosio { }; }; - asset token::get_supply( symbol_name sym )const + asset token::get_supply( symbol sym )const { stats statstable( _self, sym ); const auto& st = statstable.get( sym ); return st.supply; } - asset token::get_balance( account_name owner, symbol_name sym )const + asset token::get_balance( account_name owner, symbol sym )const { accounts accountstable( _self, owner ); const auto& ac = accountstable.get( sym ); diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index 74831f48..eb22c0a5 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -136,7 +136,7 @@ void token::add_balance( account_name owner, asset value, account_name ram_payer } } -void token::open( account_name owner, symbol_type symbol, account_name ram_payer ) +void token::open( account_name owner, symbol symbol, account_name ram_payer ) { require_auth( ram_payer ); accounts acnts( _self, owner ); @@ -148,7 +148,7 @@ void token::open( account_name owner, symbol_type symbol, account_name ram_payer } } -void token::close( account_name owner, symbol_type symbol ) +void token::close( account_name owner, symbol symbol ) { require_auth( owner ); accounts acnts( _self, owner ); From f8890031afc6777db60dd913d4f4da0694fb965b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 1 Oct 2018 16:35:15 -0400 Subject: [PATCH 0552/1048] REX loan testing, fixes --- eosio.system/abi/eosio.system.abi | 6 ++++ eosio.system/src/rex.cpp | 37 +++++++++---------- tests/eosio.system_tester.hpp | 13 +++++++ tests/eosio.system_tests.cpp | 59 +++++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 00e3af20..e554bc0c 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -809,6 +809,12 @@ "index_type": "i64", "key_names" : ["loan_num"], "key_types" : ["uint64"] + },{ + "name": "loanrefunds", + "type": "loan_refund", + "index_type": "i64", + "key_names" : ["owner"], + "key_types" : ["uint64"] },{ "name": "rammarket", "type": "exchange_state", diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 68093996..de1ae3ae 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -251,7 +251,7 @@ namespace eosiosystem { eosio_assert( itr != cpu_loans.end(), "loan not found" ); eosio_assert( itr->from, "actor has to be loan creator" ); eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); - eosio_assert( itr->expiration < current_time_point(), "loan has already expired" ); + eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); cpu_loans.modify( itr, 0, [&]( auto& loan ) { loan.balance.amount += payment.amount; }); @@ -261,7 +261,7 @@ namespace eosiosystem { eosio_assert( itr != net_loans.end(), "loan not found" ); eosio_assert( itr->from, "actor has to be loan creator" ); eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); - eosio_assert( itr->expiration < current_time_point(), "loan has already expired" ); + eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); net_loans.modify( itr, 0, [&]( auto& loan ) { loan.balance.amount += payment.amount; }); @@ -322,16 +322,13 @@ namespace eosiosystem { rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); - { - auto prim_itr = cpu_loans.find( itr->loan_num ); - cpu_loans.modify ( prim_itr, 0, [&]( auto loan ) { - delta_stake = rented_tokens - loan.total_staked.amount; - loan.total_staked.amount = rented_tokens; - loan.expiration += eosio::days(30); - loan.balance -= itr->loan_payment; - }); - } - + cpu_idx.modify ( itr, 0, [&]( auto& loan ) { + delta_stake = rented_tokens - loan.total_staked.amount; + loan.total_staked.amount = rented_tokens; + loan.expiration += eosio::days(30); + loan.balance.amount -= loan.loan_payment.amount; + }); + } else { delete_loan = true; delta_stake = -( itr->total_staked.amount ); @@ -354,6 +351,7 @@ namespace eosiosystem { if( delta_stake != 0 ) update_resource_limits( itr->receiver, delta_stake, 0 ); + if( delete_loan ) cpu_idx.erase( itr ); } @@ -385,15 +383,12 @@ namespace eosiosystem { rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); - { - auto prim_itr = net_loans.find( itr->loan_num ); - net_loans.modify ( prim_itr, 0, [&]( auto loan ) { - delta_stake = rented_tokens - loan.total_staked.amount; - loan.total_staked.amount = rented_tokens; - loan.expiration += eosio::days(30); - loan.balance -= itr->loan_payment; - }); - } + net_idx.modify ( itr, 0, [&]( auto& loan ) { + delta_stake = rented_tokens - loan.total_staked.amount; + loan.total_staked.amount = rented_tokens; + loan.expiration += eosio::days(30); + loan.balance -= itr->loan_payment; + }); } else { delete_loan = true; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 9e026420..1d87e43a 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -305,6 +305,19 @@ class eosio_system_tester : public TESTER { ); } + action_result fundrexloan( const account_name& from, const uint64_t loan_num, const asset& payment, bool cpu ) { + return push_action( name(from), N(fundrexloan), mvo() + ("from", from) + ("loan_num", loan_num) + ("payment", payment) + ("cpu", cpu) + ); + } + + action_result claimrefund( const account_name& owner ) { + return push_action( name(owner), N(claimrefund), mvo()("owner", owner) ); + } + fc::variant get_last_loan(bool cpu) { vector data; const auto& db = control->db(); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index a734a518..23fe6bcc 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3635,6 +3635,65 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { + + auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; + const int64_t ratio = 10000; + cross_15_percent_threshold(); + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const asset init_balance = core_from_string("10000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, init_balance, config::system_account_name ); + BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); + } + + const asset payment = core_from_string("30.0000"); + asset cur_frank_balance = get_balance( frank ); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("500.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, payment, true ) ); + auto loan_info = get_last_cpu_loan(); + auto old_frank_balance = cur_frank_balance; + cur_frank_balance = get_balance( frank ); + BOOST_REQUIRE_EQUAL( old_frank_balance, payment + cur_frank_balance ); + BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); + BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + BOOST_REQUIRE_EQUAL( 0, loan_info["balance"].as().get_amount() ); + + const asset fund = core_from_string("35.0000"); + BOOST_REQUIRE_EQUAL( success(), fundrexloan( frank, 1, fund, true ) ); + old_frank_balance = cur_frank_balance; + cur_frank_balance = get_balance( frank ); + loan_info = get_last_cpu_loan(); + BOOST_REQUIRE_EQUAL( old_frank_balance, fund + cur_frank_balance ); + BOOST_REQUIRE_EQUAL( fund, loan_info["balance"].as() ); + BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + + produce_block( fc::hours(30*24 + 1) ); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); + + loan_info = get_last_cpu_loan(); + BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); + BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + BOOST_REQUIRE_EQUAL( fund - payment, loan_info["balance"].as() ); + + produce_block( fc::hours(30*24) ); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), claimrefund( frank ) ); + old_frank_balance = cur_frank_balance; + cur_frank_balance = get_balance( frank ); + BOOST_REQUIRE_EQUAL( fund - payment, cur_frank_balance - old_frank_balance ); + BOOST_REQUIRE (old_frank_balance < cur_frank_balance ); + + BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); set_code( config::system_account_name, contracts::bios_wasm() ); From 28aefb942b8e69c8b8b171d72a1951a910ff7160 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 1 Oct 2018 17:26:12 -0400 Subject: [PATCH 0553/1048] fix bugs in init action; cleanup get_core_symbol --- .../include/eosio.system/eosio.system.hpp | 15 ++---- eosio.system/src/delegate_bandwidth.cpp | 13 +++-- eosio.system/src/eosio.system.cpp | 48 +++++++++++++------ eosio.system/src/producer_pay.cpp | 14 +++--- 4 files changed, 53 insertions(+), 37 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 00233794..01a0606b 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -189,17 +189,9 @@ namespace eosiosystem { system_contract( account_name s ); ~system_contract(); - inline symbol_type get_core_symbol() { - auto get_sym = [&]() -> symbol_type { - auto itr = _rammarket.find(S(4,RAMCORE)); - eosio_assert(itr != _rammarket.end(), "rammarket must exist"); - uint64_t sym = 0; - _rammarket.modify(itr, 0, [&]( auto& m ) { sym = m.quote.balance.symbol; } ); - return {sym}; - }; - static auto sym = get_sym(); - return sym; - } + static symbol_type get_core_symbol( const rammarket& rm ); + static symbol_type get_core_symbol(); + symbol_type core_symbol()const; // Actions: void init( symbol_type core ); @@ -293,6 +285,7 @@ namespace eosiosystem { static eosio_global_state get_default_parameters(); static time_point current_time_point(); static block_timestamp current_block_time(); + void update_ram_supply(); //defined in delegate_bandwidth.cpp diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 7a8d0a57..563a8380 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -90,7 +90,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); auto tmp = *itr; - auto eosout = tmp.convert( asset(bytes,S(0,RAM)), get_core_symbol() ); + auto eosout = tmp.convert( asset(bytes,S(0,RAM)), core_symbol() ); buyram( payer, receiver, eosout ); } @@ -109,6 +109,7 @@ namespace eosiosystem { require_auth( payer ); update_ram_supply(); + eosio_assert( quant.symbol == core_symbol(), "must buy ram with core token" ); eosio_assert( quant.amount > 0, "must purchase a positive amount" ); auto fee = quant; @@ -146,6 +147,8 @@ namespace eosiosystem { if( res_itr == userres.end() ) { res_itr = userres.emplace( receiver, [&]( auto& res ) { res.owner = receiver; + res.net_weight = asset( 0, core_symbol() ); + res.cpu_weight = asset( 0, core_symbol() ); res.ram_bytes = bytes_out; }); } else { @@ -177,7 +180,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(bytes,S(0,RAM)), get_core_symbol()); + tokens_out = es.convert( asset(bytes,S(0,RAM)), core_symbol()); }); eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); @@ -200,7 +203,7 @@ namespace eosiosystem { // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount if( fee > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, - { account, N(eosio.ramfee), asset(fee, get_core_symbol()), std::string("sell ram fee") } ); + { account, N(eosio.ramfee), asset(fee, core_symbol()), std::string("sell ram fee") } ); } } @@ -390,7 +393,7 @@ namespace eosiosystem { asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ) { - asset zero_asset( 0, get_core_symbol() ); + asset zero_asset( 0, core_symbol() ); eosio_assert( stake_cpu_quantity >= zero_asset, "must stake a positive amount" ); eosio_assert( stake_net_quantity >= zero_asset, "must stake a positive amount" ); eosio_assert( stake_net_quantity.amount + stake_cpu_quantity.amount > 0, "must stake a positive amount" ); @@ -402,7 +405,7 @@ namespace eosiosystem { void system_contract::undelegatebw( account_name from, account_name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ) { - asset zero_asset( 0, get_core_symbol() ); + asset zero_asset( 0, core_symbol() ); eosio_assert( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); eosio_assert( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); eosio_assert( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index ba6914d7..daae0278 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -42,6 +42,24 @@ namespace eosiosystem { return cbt; } + symbol_type system_contract::get_core_symbol( const rammarket& rm ) { + auto itr = rm.find(S(4,RAMCORE)); + eosio_assert(itr != rm.end(), "system contract must first be initialized"); + return itr->quote.balance.symbol; + } + + symbol_type system_contract::get_core_symbol() { + rammarket rm(N(eosio),N(eosio)); + const static auto sym = get_core_symbol( rm ); + return sym; + } + + + symbol_type system_contract::core_symbol()const { + const static auto sym = get_core_symbol( _rammarket ); + return sym; + } + system_contract::~system_contract() { _global.set( _gstate, _self ); _global2.set( _gstate2, _self ); @@ -172,12 +190,12 @@ namespace eosiosystem { auto it = refunds_table.find( current->high_bidder ); if ( it != refunds_table.end() ) { refunds_table.modify( it, 0, [&](auto& r) { - r.amount += asset( current->high_bid, get_core_symbol() ); + r.amount += asset( current->high_bid, core_symbol() ); }); } else { refunds_table.emplace( bidder, [&](auto& r) { r.bidder = current->high_bidder; - r.amount = asset( current->high_bid, get_core_symbol() ); + r.amount = asset( current->high_bid, core_symbol() ); }); } @@ -249,6 +267,8 @@ namespace eosiosystem { userres.emplace( newact, [&]( auto& res ) { res.owner = newact; + res.net_weight = asset( 0, system_contract::get_core_symbol() ); + res.cpu_weight = asset( 0, system_contract::get_core_symbol() ); }); set_resource_limits( newact, 0, 0, 0 ); @@ -271,18 +291,18 @@ namespace eosiosystem { void system_contract::init( symbol_type core ) { auto itr = _rammarket.find(S(4,RAMCORE)); - if ( itr == _rammarket.end() ) { - auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(core).name()).amount; - if( system_token_supply > 0 ) { - _rammarket.emplace( S(4,RAMCORE), [&]( auto& m ) { - m.supply.amount = 100000000000000ll; - m.supply.symbol = S(4,RAMCORE); - m.base.balance.amount = int64_t(_gstate.free_ram()); - m.base.balance.symbol = S(0,RAM); - m.quote.balance.amount = system_token_supply / 1000; - m.quote.balance.symbol = core; - }); - } + eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); + + auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(core).name()).amount; + if( system_token_supply > 0 ) { + _rammarket.emplace( _self, [&]( auto& m ) { + m.supply.amount = 100000000000000ll; + m.supply.symbol = S(4,RAMCORE); + m.base.balance.amount = int64_t(_gstate.free_ram()); + m.base.balance.symbol = S(0,RAM); + m.quote.balance.amount = system_token_supply / 1000; + m.quote.balance.symbol = core; + }); } } } /// eosio.system diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index ee5c1443..c1e7675e 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -83,7 +83,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token( N(eosio.token)).get_supply( get_core_symbol().name() ); + const asset token_supply = token( N(eosio.token)).get_supply( core_symbol().name() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { @@ -95,16 +95,16 @@ namespace eosiosystem { auto to_per_vote_pay = to_producers - to_per_block_pay; INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - { N(eosio), asset(new_tokens, get_core_symbol()), std::string("issue tokens for producer pay and savings") } ); + { N(eosio), asset(new_tokens, core_symbol()), std::string("issue tokens for producer pay and savings") } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.saving), asset(to_savings, get_core_symbol()), "unallocated inflation" } ); + { N(eosio), N(eosio.saving), asset(to_savings, core_symbol()), "unallocated inflation" } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.bpay), asset(to_per_block_pay, get_core_symbol()), "fund per-block bucket" } ); + { N(eosio), N(eosio.bpay), asset(to_per_block_pay, core_symbol()), "fund per-block bucket" } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.vpay), asset(to_per_vote_pay, get_core_symbol()), "fund per-vote bucket" } ); + { N(eosio), N(eosio.vpay), asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" } ); _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; @@ -175,11 +175,11 @@ namespace eosiosystem { if( producer_per_block_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.bpay),N(active)},{owner,N(active)}}, - { N(eosio.bpay), owner, asset(producer_per_block_pay, get_core_symbol()), std::string("producer block pay") } ); + { N(eosio.bpay), owner, asset(producer_per_block_pay, core_symbol()), std::string("producer block pay") } ); } if( producer_per_vote_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.vpay),N(active)},{owner,N(active)}}, - { N(eosio.vpay), owner, asset(producer_per_vote_pay, get_core_symbol()), std::string("producer vote pay") } ); + { N(eosio.vpay), owner, asset(producer_per_vote_pay, core_symbol()), std::string("producer vote pay") } ); } } From 00bfdfbb198b22c96e4832d42fdbef5f39ce5689 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 1 Oct 2018 17:30:03 -0400 Subject: [PATCH 0554/1048] replace all core_from_string with core_sym::from_string --- tests/eosio.system_tester.hpp | 8 +- tests/eosio.system_tests.cpp | 1052 ++++++++++++++++----------------- 2 files changed, 530 insertions(+), 530 deletions(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 3db3e9ab..c96353b2 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -33,7 +33,7 @@ class eosio_system_tester : public TESTER { public: eosio_system_tester() : eosio_system_tester([](TESTER& ) {}){} - + template eosio_system_tester(Lambda setup) { setup(*this); @@ -122,7 +122,7 @@ class eosio_system_tester : public TESTER { } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, - asset net = core_sym::from_string("10.0000"), asset cpu = core_from_string("10.0000") ) { + asset net = core_sym::from_string("10.0000"), asset cpu = core_sym::from_string("10.0000") ) { signed_transaction trx; set_transaction_headers(trx); @@ -443,7 +443,7 @@ class eosio_system_tester : public TESTER { vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain transfer( "eosio", "alice1111111", core_sym::from_string("650000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_from_string("300000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers std::vector producer_names; @@ -476,7 +476,7 @@ class eosio_system_tester : public TESTER { //vote for producers { transfer( config::system_account_name, "alice1111111", core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake( "alice1111111", core_sym::from_string("30000000.0000"), core_from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(success(), stake( "alice1111111", core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000") ) ); BOOST_REQUIRE_EQUAL(success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("30000000.0000") ) ); BOOST_REQUIRE_EQUAL(success(), push_action(N(alice1111111), N(voteproducer), mvo() ("voter", "alice1111111") diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 743e853a..df7a9a4e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -22,20 +22,20 @@ BOOST_AUTO_TEST_SUITE(eosio_system_tests) BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "alice1111111" ); auto init_bytes = total["ram_bytes"].as_uint64(); const asset initial_ram_balance = get_balance(N(eosio.ram)); const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("800.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( initial_ram_balance + core_from_string("199.0000"), get_balance(N(eosio.ram)) ); - BOOST_REQUIRE_EQUAL( initial_ramfee_balance + core_from_string("1.0000"), get_balance(N(eosio.ramfee)) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("800.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( initial_ram_balance + core_sym::from_string("199.0000"), get_balance(N(eosio.ram)) ); + BOOST_REQUIRE_EQUAL( initial_ramfee_balance + core_sym::from_string("1.0000"), get_balance(N(eosio.ramfee)) ); total = get_total_stake( "alice1111111" ); auto bytes = total["ram_bytes"].as_uint64(); @@ -45,19 +45,19 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, 0 < bought_bytes ); BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("998.0049"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("998.0049"), get_balance( "alice1111111" ) ); total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - transfer( "eosio", "alice1111111", core_from_string("100000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( core_from_string("100000998.0049"), get_balance( "alice1111111" ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("100000000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("100000998.0049"), get_balance( "alice1111111" ) ); // alice buys ram for 10000000.0000, 0.5% = 50000.0000 go to ramfee // after fee 9950000.0000 go to bought bytes // when selling back bought bytes, pay 0.5% fee and get back 99.5% of 9950000.0000 = 9900250.0000 // expected account after that is 90000998.0049 + 9900250.0000 = 99901248.0049 with a difference // of order 0.0001 due to rounding errors - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("90000998.0049"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("90000998.0049"), get_balance( "alice1111111" ) ); total = get_total_stake( "alice1111111" ); bytes = total["ram_bytes"].as_uint64(); @@ -72,18 +72,18 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { wdump((init_bytes)(bought_bytes)(bytes) ); BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - BOOST_REQUIRE_EQUAL( core_from_string("99901248.0048"), get_balance( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99900688.0048"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("99901248.0048"), get_balance( "alice1111111" ) ); + + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("30.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("99900688.0048"), get_balance( "alice1111111" ) ); auto newtotal = get_total_stake( "alice1111111" ); @@ -92,21 +92,21 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { wdump((newbytes)(bytes)(bought_bytes) ); BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99901242.4187"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("99901242.4187"), get_balance( "alice1111111" ) ); newtotal = get_total_stake( "alice1111111" ); auto startbytes = newtotal["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("300000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("49301242.4187"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("300000.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("49301242.4187"), get_balance( "alice1111111" ) ); auto finaltotal = get_total_stake( "alice1111111" ); auto endbytes = finaltotal["ram_bytes"].as_uint64(); @@ -116,7 +116,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_from_string("99396507.4158"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("99396507.4158"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() @@ -126,128 +126,128 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake, eosio_system_tester ) try { produce_blocks( 10 ); produce_block( fc::hours(3*24) ); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); const auto init_eosio_stake_balance = get_balance( N(eosio.stake) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_from_string("300.0000"), get_balance( N(eosio.stake) ) ); - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_sym::from_string("300.0000"), get_balance( N(eosio.stake) ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); produce_block( fc::hours(3*24-1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_from_string("300.0000"), get_balance( N(eosio.stake) ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_sym::from_string("300.0000"), get_balance( N(eosio.stake) ) ); //after 3 days funds should be released produce_block( fc::hours(1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( init_eosio_stake_balance, get_balance( N(eosio.stake) ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); total = get_total_stake("bob111111111"); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000").get_amount(), total["net_weight"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000").get_amount(), total["cpu_weight"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000").get_amount(), total["net_weight"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000").get_amount(), total["cpu_weight"].as().get_amount() ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000")), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); auto bytes = total["ram_bytes"].as_uint64(); BOOST_REQUIRE_EQUAL( true, 0 < bytes ); //unstake from bob111111111 - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); total = get_total_stake("bob111111111"); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); produce_block( fc::hours(3*24-1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); //after 3 days funds should be released produce_block( fc::hours(1) ); produce_blocks(1); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("0.0000") ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000") ), get_voter_info( "alice1111111" ) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "eosio", core_from_string("1000.0000"), config::system_account_name ); - issue( "eosio.stake", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + issue( "eosio", core_sym::from_string("1000.0000"), config::system_account_name ); + issue( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //eosio stakes for alice with transfer flag - transfer( "eosio", "bob111111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //check that alice has both bandwidth and voting power auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000")), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //alice stakes for herself - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //now alice's stake should be equal to transfered from eosio + own stake total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("600.0000")), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("410.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("600.0000")), get_voter_info( "alice1111111" ) ); //alice can unstake everything (including what was transfered) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("400.0000"), core_from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("400.0000"), core_sym::from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); produce_block( fc::hours(3*24-1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); //after 3 days funds should be released produce_block( fc::hours(1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("1300.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1300.0000"), get_balance( "alice1111111" ) ); //stake should be equal to what was staked in constructor, voting power should be 0 total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("0.0000")), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try { cross_15_percent_threshold(); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot use transfer flag if delegating to self"), - stake_with_transfer( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) + stake_with_transfer( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() @@ -255,72 +255,72 @@ BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "eosio", core_from_string("1000.0000"), config::system_account_name ); - issue( "eosio.stake", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + issue( "eosio", core_sym::from_string("1000.0000"), config::system_account_name ); + issue( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //eosio stakes for alice with transfer flag - transfer( "eosio", "bob111111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //check that alice has both bandwidth and voting power auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000")), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //alice stakes for herself - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //now alice's stake should be equal to transfered from eosio + own stake total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("600.0000")), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("410.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("600.0000")), get_voter_info( "alice1111111" ) ); //alice can unstake everything (including what was transfered) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("400.0000"), core_from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("400.0000"), core_sym::from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); produce_block( fc::hours(3*24-1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); //after 3 days funds should be released produce_block( fc::hours(1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("1300.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1300.0000"), get_balance( "alice1111111" ) ); //stake should be equal to what was staked in constructor, voting power should be 0 total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("0.0000")), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("2000.0000"), core_from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("10.0000"), core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("2000.0000"), core_sym::from_string("1000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), push_action( N(alice1111111), N(delegatebw), mvo() ("from", "alice1111111") ("receiver", "bob111111111") - ("stake_net_quantity", core_from_string("10.0000")) - ("stake_cpu_quantity", core_from_string("10.0000")) + ("stake_net_quantity", core_sym::from_string("10.0000")) + ("stake_cpu_quantity", core_sym::from_string("10.0000")) ("transfer", 0 ) ,false ) @@ -330,8 +330,8 @@ BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { push_action(N(alice1111111), N(undelegatebw), mvo() ("from", "alice1111111") ("receiver", "bob111111111") - ("unstake_net_quantity", core_from_string("200.0000")) - ("unstake_cpu_quantity", core_from_string("100.0000")) + ("unstake_net_quantity", core_sym::from_string("200.0000")) + ("unstake_cpu_quantity", core_sym::from_string("100.0000")) ("transfer", 0 ) ,false ) @@ -341,22 +341,22 @@ BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_from_string("-0.0001"), core_from_string("0.0000") ) + stake( "alice1111111", core_sym::from_string("-0.0001"), core_sym::from_string("0.0000") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_from_string("0.0000"), core_from_string("-0.0001") ) + stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("-0.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_from_string("00.0000"), core_from_string("00.0000") ) + stake( "alice1111111", core_sym::from_string("00.0000"), core_sym::from_string("00.0000") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_from_string("0.0000"), core_from_string("00.0000") ) + stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("00.0000") ) ); @@ -365,28 +365,28 @@ BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0001"), core_from_string("100.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0001"), core_sym::from_string("100.0001") ) ); auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0001"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0001"), total["net_weight"].as()); auto vinfo = get_voter_info("alice1111111" ); wdump((vinfo)); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0002") ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0002") ), get_voter_info( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_from_string("-1.0000"), core_from_string("0.0000") ) + unstake( "alice1111111", "bob111111111", core_sym::from_string("-1.0000"), core_sym::from_string("0.0000") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_from_string("0.0000"), core_from_string("-1.0000") ) + unstake( "alice1111111", "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("-1.0000") ) ); //unstake all zeros BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_from_string("0.0000"), core_from_string("0.0000") ) + unstake( "alice1111111", "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("0.0000") ) ); @@ -396,87 +396,87 @@ BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( unstake_more_than_at_stake, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); //trying to unstake more net bandwith than at stake BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111", core_from_string("200.0001"), core_from_string("0.0000") ) + unstake( "alice1111111", core_sym::from_string("200.0001"), core_sym::from_string("0.0000") ) ); //trying to unstake more cpu bandwith than at stake BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111", core_from_string("0.0000"), core_from_string("100.0001") ) + unstake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("100.0001") ) ); //check that nothing has changed total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake ( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake ( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); //all voting power goes to alice1111111 - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); //but not to bob111111111 BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); //bob111111111 should not be able to unstake what was staked by alice1111111 BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "bob111111111", core_from_string("0.0000"), core_from_string("10.0000") ) + unstake( "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "bob111111111", core_from_string("10.0000"), core_from_string("0.0000") ) + unstake( "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("0.0000") ) ); - issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", "bob111111111", core_from_string("20.0000"), core_from_string("10.0000") ) ); + issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", "bob111111111", core_sym::from_string("20.0000"), core_sym::from_string("10.0000") ) ); total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("970.0000"), get_balance( "carol1111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("30.0000") ), get_voter_info( "carol1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_balance( "carol1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("30.0000") ), get_voter_info( "carol1111111" ) ); //alice1111111 should not be able to unstake money staked by carol1111111 BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111", "bob111111111", core_from_string("2001.0000"), core_from_string("1.0000") ) + unstake( "alice1111111", "bob111111111", core_sym::from_string("2001.0000"), core_sym::from_string("1.0000") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111", "bob111111111", core_from_string("1.0000"), core_from_string("101.0000") ) + unstake( "alice1111111", "bob111111111", core_sym::from_string("1.0000"), core_sym::from_string("101.0000") ) ); total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["cpu_weight"].as()); //balance should not change after unsuccessfull attempts to unstake - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); //voting power too - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("30.0000") ), get_voter_info( "carol1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("30.0000") ), get_voter_info( "carol1111111" ) ); BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); } FC_LOG_AND_RETHROW() @@ -484,209 +484,209 @@ BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( stake_unstake_separate, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance( "alice1111111" ) ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); //everything at once - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("10.0000"), core_from_string("20.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("10.0000"), core_sym::from_string("20.0000") ) ); auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); //cpu - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("100.0000"), core_from_string("0.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("0.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); //net - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("0.0000"), core_from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("200.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["cpu_weight"].as()); //unstake cpu - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("100.0000"), core_from_string("0.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("0.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("230.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["cpu_weight"].as()); //unstake net - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("0.0000"), core_from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("200.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("30.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( adding_stake_partial_unstake, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("450.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("550.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("450.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("550.0000"), get_balance( "alice1111111" ) ); //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("150.0000"), core_from_string("75.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("150.0000"), core_sym::from_string("75.0000") ) ); total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("85.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("225.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("225.0000") ), get_voter_info( "alice1111111" ) ); //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("150.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("150.0000") ), get_voter_info( "alice1111111" ) ); //combined amount should be available only in 3 days produce_block( fc::days(2) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("550.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("550.0000"), get_balance( "alice1111111" ) ); produce_block( fc::days(1) ); produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_from_string("850.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("850.0000"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("50.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("400.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("600.0000"), get_balance( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("400.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("250.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("600.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("250.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); auto refund = get_refund_request( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string( "50.0000"), refund["cpu_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); //XXX auto request_time = refund["request_time"].as_int64(); //alice delegates to bob, should pull from liquid balance not refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("50.0000"), core_from_string("50.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("350.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("350.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); refund = get_refund_request( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string( "50.0000"), refund["cpu_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); //stake less than pending refund, entire amount should be taken from refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("85.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); refund = get_refund_request( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("50.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string("25.0000"), refund["cpu_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("50.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("25.0000"), refund["cpu_amount"].as() ); //request time should stay the same //BOOST_REQUIRE_EQUAL( request_time, refund["request_time"].as_int64() ); //balance should stay the same - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); //stake exactly pending refund amount - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("50.0000"), core_from_string("25.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); //pending refund should be removed refund = get_refund_request( "alice1111111" ); BOOST_TEST_REQUIRE( refund.is_null() ); //balance should stay the same - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); //create pending refund again - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("10.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("500.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); refund = get_refund_request( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); //stake more than pending refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("300.0000"), core_from_string("200.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300.0000"), core_sym::from_string("200.0000") ) ); total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("700.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("700.0000") ), get_voter_info( "alice1111111" ) ); refund = get_refund_request( "alice1111111" ); BOOST_TEST_REQUIRE( refund.is_null() ); //200 core tokens should be taken from alice's account - BOOST_REQUIRE_EQUAL( core_from_string("300.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_balance( "alice1111111" ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); //unstake - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto refund = get_refund_request( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); //auto orig_request_time = refund["request_time"].as_int64(); //stake to another user - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_from_string("110.0000"), total["cpu_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); + BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); //stake should be taken from alices' balance, and refund request should stay the same - BOOST_REQUIRE_EQUAL( core_from_string("400.0000"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("400.0000"), get_balance( "alice1111111" ) ); refund = get_refund_request( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), refund["cpu_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); //BOOST_REQUIRE_EQUAL( orig_request_time, refund["request_time"].as_int64() ); } FC_LOG_AND_RETHROW() // Tests for voting BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try { - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); //fc::variant params = producer_parameters_example(1); auto key = fc::crypto::public_key( std::string("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ); @@ -758,7 +758,7 @@ BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() ("producer", "alice1111111") @@ -772,61 +772,61 @@ BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_t BOOST_REQUIRE_EQUAL( 0, prod["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); - issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); - issue( "carol1111111", core_from_string("3000.0000"), config::system_account_name ); + issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + issue( "carol1111111", core_sym::from_string("3000.0000"), config::system_account_name ); //bob111111111 makes stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("11.0000"), core_from_string("0.1111") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("1988.8889"), get_balance( "bob111111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("11.1111") ), get_voter_info( "bob111111111" ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("11.0000"), core_sym::from_string("0.1111") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1988.8889"), get_balance( "bob111111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("11.1111") ), get_voter_info( "bob111111111" ) ); //bob111111111 votes for alice1111111 BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(alice1111111) } ) ); //check that producer parameters stay the same after voting prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("11.1111")) == prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("11.1111")) == prod["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( "alice1111111", prod["owner"].as_string() ); BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); //carol1111111 makes stake - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("22.0000"), core_from_string("0.2222") ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("22.2222") ), get_voter_info( "carol1111111" ) ); - BOOST_REQUIRE_EQUAL( core_from_string("2977.7778"), get_balance( "carol1111111" ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("22.2222") ), get_voter_info( "carol1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("2977.7778"), get_balance( "carol1111111" ) ); //carol1111111 votes for alice1111111 BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); //new stake votes be added to alice1111111's total_votes prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("33.3333")) == prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("33.3333")) == prod["total_votes"].as_double() ); //bob111111111 increases his stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("33.0000"), core_from_string("0.3333") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("33.0000"), core_sym::from_string("0.3333") ) ); //alice1111111 stake with transfer to bob111111111 - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_from_string("22.0000"), core_from_string("0.2222") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); //should increase alice1111111's total_votes prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("88.8888")) == prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("88.8888")) == prod["total_votes"].as_double() ); //carol1111111 unstakes part of the stake - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_from_string("2.0000"), core_from_string("0.0002")/*"2.0000 EOS", "0.0002 EOS"*/ ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_sym::from_string("2.0000"), core_sym::from_string("0.0002")/*"2.0000 EOS", "0.0002 EOS"*/ ) ); //should decrease alice1111111's total_votes prod = get_producer_info( "alice1111111" ); wdump((prod)); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("86.8886")) == prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("86.8886")) == prod["total_votes"].as_double() ); //bob111111111 revokes his vote BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector() ) ); //should decrease alice1111111's total_votes prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.2220")) == prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.2220")) == prod["total_votes"].as_double() ); //but eos should still be at stake - BOOST_REQUIRE_EQUAL( core_from_string("1955.5556"), get_balance( "bob111111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1955.5556"), get_balance( "bob111111111" ) ); //carol1111111 unstakes rest of eos - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_from_string("20.0000"), core_from_string("0.2220") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_sym::from_string("20.0000"), core_sym::from_string("0.2220") ) ); //should decrease alice1111111's total_votes to zero prod = get_producer_info( "alice1111111" ); BOOST_TEST_REQUIRE( 0.0 == prod["total_votes"].as_double() ); @@ -834,22 +834,22 @@ BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_t //carol1111111 should receive funds in 3 days produce_block( fc::days(3) ); produce_block(); - BOOST_REQUIRE_EQUAL( core_from_string("3000.0000"), get_balance( "carol1111111" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("3000.0000"), get_balance( "carol1111111" ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("13.0000"), core_from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("13.5791") ), get_voter_info( "bob111111111" ) ); + issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); //bob111111111 should not be able to vote for alice1111111 who is not a producer BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer is not registered" ), vote( N(bob111111111), { N(alice1111111) } ) ); //alice1111111 registers as a producer - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() ("producer", "alice1111111") @@ -875,9 +875,9 @@ BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * bo BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try { - issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("13.0000"), core_from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("13.5791") ), get_voter_info( "bob111111111" ) ); + issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); //bob111111111 should not be able to vote for alice1111111 who is not a producer BOOST_REQUIRE_EQUAL( wasm_assert_msg( "attempt to vote for too many producers" ), @@ -887,12 +887,12 @@ BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try { - issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("50.0000"), core_from_string("50.0000") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("100.0000") ), get_voter_info( "bob111111111" ) ); + issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("100.0000") ), get_voter_info( "bob111111111" ) ); //alice1111111 becomes a producer - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() ("producer", "alice1111111") @@ -913,7 +913,7 @@ BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); vector key = fc::raw::pack( get_public_key( N(alice1111111), "active" ) ); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() @@ -925,15 +925,15 @@ BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit ); //bob111111111 makes stake - issue( "bob111111111", core_from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("13.0000"), core_from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("13.5791") ), get_voter_info( "bob111111111" ) ); + issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); //bob111111111 votes for alice1111111 BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), { N(alice1111111) } ) ); auto prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")) == prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")) == prod["total_votes"].as_double() ); //unregister producer BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(unregprod), mvo() @@ -946,7 +946,7 @@ BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit //check parameters just in case //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")), prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); //regtister the same producer again params = producer_parameters_example(2); @@ -959,7 +959,7 @@ BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit ); prod = get_producer_info( "alice1111111" ); //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")), prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); //change parameters params = producer_parameters_example(3); @@ -972,7 +972,7 @@ BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit ); prod = get_producer_info( "alice1111111" ); //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_from_string("13.5791")), prod["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); //check parameters just in case //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); @@ -1002,33 +1002,33 @@ BOOST_FIXTURE_TEST_CASE( vote_for_two_producers, eosio_system_tester, * boost::u ); //carol1111111 votes for alice1111111 and bob111111111 - issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("15.0005"), core_from_string("5.0000") ) ); + issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("15.0005"), core_sym::from_string("5.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111), N(bob111111111) } ) ); auto alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == alice_info["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == alice_info["total_votes"].as_double() ); auto bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == bob_info["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == bob_info["total_votes"].as_double() ); //carol1111111 votes for alice1111111 (but revokes vote for bob111111111) BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("20.0005")) == alice_info["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == alice_info["total_votes"].as_double() ); bob_info = get_producer_info( "bob111111111" ); BOOST_TEST_REQUIRE( 0 == bob_info["total_votes"].as_double() ); //alice1111111 votes for herself and bob111111111 - issue( "alice1111111", core_from_string("2.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("1.0000"), core_from_string("1.0000") ) ); + issue( "alice1111111", core_sym::from_string("2.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("1.0000"), core_sym::from_string("1.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(alice1111111), N(bob111111111) } ) ); alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("22.0005")) == alice_info["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("22.0005")) == alice_info["total_votes"].as_double() ); bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("2.0000")) == bob_info["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("2.0000")) == bob_info["total_votes"].as_double() ); } FC_LOG_AND_RETHROW() @@ -1051,8 +1051,8 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes REQUIRE_MATCHING_OBJECT( voter( "alice1111111" ), get_voter_info( "alice1111111" ) ); //stake and then register as a proxy - issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("200.0002"), core_from_string("100.0001") ) ); + issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("200.0002"), core_sym::from_string("100.0001") ) ); BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() ("proxy", "bob111111111") ("isproxy", true) @@ -1065,7 +1065,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", false) ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_from_string("300.0003") ), get_voter_info( "bob111111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("300.0003") ), get_voter_info( "bob111111111" ) ); //register as a proxy and then stake BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() @@ -1073,8 +1073,8 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", true) ) ); - issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("246.0002"), core_from_string("531.0001") ) ); + issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("246.0002"), core_sym::from_string("531.0001") ) ); //check that both proxy flag and stake a correct REQUIRE_MATCHING_OBJECT( proxy( "carol1111111" )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); @@ -1084,7 +1084,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", false) ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_from_string("777.0003") ), get_voter_info( "carol1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("777.0003") ), get_voter_info( "carol1111111" ) ); } FC_LOG_AND_RETHROW() @@ -1097,25 +1097,25 @@ BOOST_FIXTURE_TEST_CASE( proxy_stake_unstake_keeps_proxy_flag, eosio_system_test ("isproxy", true) ) ); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); //stake - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("100.0000"), core_from_string("50.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); //check that account is still a proxy REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); //stake more - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("30.0000"), core_from_string("20.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0000"), core_sym::from_string("20.0000") ) ); //check that account is still a proxy REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("65.0000"), core_from_string("35.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); //unstake the rest - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("65.0000"), core_from_string("35.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 0 ), get_voter_info( "alice1111111" ) ); } FC_LOG_AND_RETHROW() @@ -1137,22 +1137,22 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * ); //accumulate proxied votes - issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), vector(), N(alice1111111) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); //vote for producers BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_TEST_REQUIRE( 0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); //vote for another producers BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer3) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); //unregister proxy BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -1160,7 +1160,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * ("isproxy", false) ) ); - //REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); + //REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer1" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); @@ -1171,22 +1171,22 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * ("isproxy", true) ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); //stake increase by proxy itself affects producers - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("30.0001"), core_from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( stake2votes(core_from_string("200.0005")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); + BOOST_REQUIRE_EQUAL( stake2votes(core_sym::from_string("200.0005")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( stake2votes(core_from_string("200.0005")), get_producer_info( "defproducer3" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( stake2votes(core_sym::from_string("200.0005")), get_producer_info( "defproducer3" )["total_votes"].as_double() ); //stake decrease by proxy itself affects producers - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_from_string("10.0001"), core_from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("180.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("10.0001"), core_sym::from_string("10.0001") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("180.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("180.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("180.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); } FC_LOG_AND_RETHROW() @@ -1197,13 +1197,13 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t const double secs_per_year = 52 * 7 * 24 * 3600; - const asset large_asset = core_from_string("80.0000"); - create_account_with_resources( N(defproducera), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerb), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerc), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + const asset large_asset = core_sym::from_string("80.0000"); + create_account_with_resources( N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(defproducerb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(defproducerc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvotera), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); produce_block(fc::hours(24)); @@ -1211,8 +1211,8 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t BOOST_REQUIRE_EQUAL("defproducera", prod["owner"].as_string()); BOOST_REQUIRE_EQUAL(0, prod["total_votes"].as_double()); - transfer( config::system_account_name, "producvotera", core_from_string("400000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_from_string("100000000.0000"), core_from_string("100000000.0000"))); + transfer( config::system_account_name, "producvotera", core_sym::from_string("400000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera) })); // defproducera is the only active producer @@ -1392,13 +1392,13 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const double usecs_per_year = secs_per_year * 1000000; const double cont_rate = 4.879/100.; - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); } // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers @@ -1767,13 +1767,13 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); } // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers @@ -1926,20 +1926,20 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::u cross_15_percent_threshold(); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); } const auto vota = accounts[0]; const auto votb = accounts[1]; const auto proda = accounts[2]; const auto prodb = accounts[3]; - BOOST_REQUIRE_EQUAL( success(), stake( vota, core_from_string("100.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( votb, core_from_string("100.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( vota, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( votb, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( success(), regproducer( proda ) ); BOOST_REQUIRE_EQUAL( success(), regproducer( prodb ) ); @@ -1994,12 +1994,12 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ cross_15_percent_threshold(); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); } const auto alice = accounts[0]; const auto bob = accounts[1]; @@ -2015,15 +2015,15 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), regproducer( emily, 1) ); // bob chooses alice as proxy - BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0002"), core_from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, core_from_string("150.0000"), core_from_string("150.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( bob, core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( alice, core_sym::from_string("150.0000"), core_sym::from_string("150.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_voter_info(alice)["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_voter_info(alice)["proxied_vote_weight"].as_double() ); // alice (proxy) votes for carol BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); double total_votes = get_producer_info(carol)["total_votes"].as_double(); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == total_votes ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("450.0003")) == total_votes ); BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); uint64_t last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); @@ -2033,7 +2033,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); auto cur_info2 = get_producer_info2(carol); double expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( stake2votes(core_from_string("450.0003")) == get_producer_info(carol)["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("450.0003")) == get_producer_info(carol)["total_votes"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); last_update_time = microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ); @@ -2042,8 +2042,8 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ produce_block( fc::hours(40) ); // bob unstakes - BOOST_REQUIRE_EQUAL( success(), unstake( bob, core_from_string("10.0002"), core_from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( success(), unstake( bob, core_sym::from_string("10.0002"), core_sym::from_string("10.0001") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); cur_info2 = get_producer_info2(carol); expected_votepay_share += double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; @@ -2059,7 +2059,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_ // bob votes for carol BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); cur_info2 = get_producer_info2(carol); expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); @@ -2142,12 +2142,12 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost cross_15_percent_threshold(); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); + create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); } const auto alice = accounts[0]; const auto bob = accounts[1]; @@ -2159,8 +2159,8 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost produce_block( fc::hours(24) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, core_from_string("100.0000"), core_from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( bob, core_from_string("100.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( alice, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( bob, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); @@ -2209,13 +2209,13 @@ BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); } // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers @@ -2258,7 +2258,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducera)) ); BOOST_REQUIRE( microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducera))["last_claim_time"] ) < microseconds_since_epoch_of_iso_string( get_producer_info2(N(defproducera))["last_votepay_share_update"] ) ); - create_account_with_resources( N(defproducer1), config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + create_account_with_resources( N(defproducer1), config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducer1)) ); BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducer1))["last_claim_time"] ) ); BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducer1))["last_claim_time"].as_string(), @@ -2272,13 +2272,13 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition2, eosio_system_tester, * boost::unit_ set_code( config::system_account_name, contracts::util::system_wasm_old() ); set_abi( config::system_account_name, contracts::util::system_abi_old().data() ); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); } // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers @@ -2317,7 +2317,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition2, eosio_system_tester, * boost::unit_ produce_blocks(2); produce_block( fc::hours(24 + 1) ); - + BOOST_REQUIRE_EQUAL( success(), push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); BOOST_TEST_REQUIRE( get_producer_info(producer_names[0])["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); @@ -2325,7 +2325,7 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition2, eosio_system_tester, * boost::unit_ produce_block( fc::hours(5) ); BOOST_REQUIRE_EQUAL( success(), regproducer(producer_names[1]) ); - BOOST_TEST_REQUIRE( get_producer_info(producer_names[0])["total_votes"].as_double() + get_producer_info(producer_names[1])["total_votes"].as_double() == + BOOST_TEST_REQUIRE( get_producer_info(producer_names[0])["total_votes"].as_double() + get_producer_info(producer_names[1])["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); } FC_LOG_AND_RETHROW() @@ -2439,10 +2439,10 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { - const asset large_asset = core_from_string("80.0000"); - create_account_with_resources( N(producvotera), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterc), config::system_account_name, core_from_string("1.0000"), false, large_asset, large_asset ); + const asset large_asset = core_sym::from_string("80.0000"); + create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvoterc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers std::vector producer_names; @@ -2462,11 +2462,11 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.back() )["total_votes"].as()); - transfer(config::system_account_name, "producvotera", core_from_string("200000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_from_string("70000000.0000"), core_from_string("70000000.0000") )); + transfer(config::system_account_name, "producvotera", core_sym::from_string("200000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("70000000.0000"), core_sym::from_string("70000000.0000") )); BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); BOOST_CHECK_EQUAL( wasm_assert_msg( "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ), - unstake( "producvotera", core_from_string("50.0000"), core_from_string("50.0000") ) ); + unstake( "producvotera", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); // give a chance for everyone to produce blocks { @@ -2499,10 +2499,10 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { } // stake across 15% boundary - transfer(config::system_account_name, "producvoterb", core_from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterb", core_from_string("4000000.0000"), core_from_string("4000000.0000"))); - transfer(config::system_account_name, "producvoterc", core_from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterc", core_from_string("2000000.0000"), core_from_string("2000000.0000"))); + transfer(config::system_account_name, "producvoterb", core_sym::from_string("100000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvoterb", core_sym::from_string("4000000.0000"), core_sym::from_string("4000000.0000"))); + transfer(config::system_account_name, "producvoterc", core_sym::from_string("100000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvoterc", core_sym::from_string("2000000.0000"), core_sym::from_string("2000000.0000"))); BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterc), vector(producer_names.begin(), producer_names.end()))); @@ -2529,7 +2529,7 @@ BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { BOOST_REQUIRE(0 < get_balance(producer_names.front()).get_amount()); } - BOOST_CHECK_EQUAL( success(), unstake( "producvotera", core_from_string("50.0000"), core_from_string("50.0000") ) ); + BOOST_CHECK_EQUAL( success(), unstake( "producvotera", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); } FC_LOG_AND_RETHROW() @@ -2550,11 +2550,11 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); //alice1111111 makes stake and votes - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("30.0001"), core_from_string("20.0001") ) ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( success(), push_action( N(donald111111), N(regproxy), mvo() @@ -2565,50 +2565,50 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system REQUIRE_MATCHING_OBJECT( proxy( "donald111111" ), get_voter_info( "donald111111" ) ); //bob111111111 chooses alice1111111 as a proxy - issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("150.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); //carol1111111 chooses alice1111111 as a proxy - issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("30.0001"), core_from_string("20.0001") ) ); + issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("200.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("250.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("250.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("250.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("250.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); //proxied voter carol1111111 increases stake - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("50.0000"), core_from_string("70.0000") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("320.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("370.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("370.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("50.0000"), core_sym::from_string("70.0000") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("320.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("370.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("370.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); //proxied voter bob111111111 decreases stake - BOOST_REQUIRE_EQUAL( success(), unstake( "bob111111111", core_from_string("50.0001"), core_from_string("50.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("220.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("270.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("270.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( success(), unstake( "bob111111111", core_sym::from_string("50.0001"), core_sym::from_string("50.0001") ) ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("220.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("270.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("270.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); //proxied voter carol1111111 chooses another proxy BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "donald111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0001")), get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("170.0002")), get_voter_info( "donald111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0001")), get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("170.0002")), get_voter_info( "donald111111" )["proxied_vote_weight"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); //bob111111111 switches to direct voting and votes for one of the same producers, but not for another one BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); BOOST_TEST_REQUIRE( 0.0 == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("50.0002")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); + BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); BOOST_TEST_REQUIRE( 0.0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); } FC_LOG_AND_RETHROW() @@ -2628,8 +2628,8 @@ BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) tr //bob111111111 chooses alice1111111 as a proxy - issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot vote for producers and proxy at same time"), vote( N(bob111111111), { N(carol1111111) }, "alice1111111" ) ); @@ -2638,8 +2638,8 @@ BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) tr BOOST_FIXTURE_TEST_CASE( select_invalid_proxy, eosio_system_tester ) try { //accumulate proxied votes - issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); //selecting account not registered as a proxy BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), @@ -2659,16 +2659,16 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys ("isproxy", 1) ) ); - issue( "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_from_string("5.0000"), core_from_string("5.0000") ) ); + issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("5.0000"), core_sym::from_string("5.0000") ) ); edump((get_voter_info("alice1111111"))); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //bob111111111 stakes and selects alice1111111 as a proxy - issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes( core_from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //double regestering should fail without affecting total votes and stake BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), @@ -2677,7 +2677,7 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys ("isproxy", 1) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //uregister BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -2685,7 +2685,7 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys ("isproxy", 0) ) ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //double unregistering should not affect proxied_votes and stake BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), @@ -2694,7 +2694,7 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys ("isproxy", 0) ) ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_from_string("150.0003")))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); } FC_LOG_AND_RETHROW() @@ -2715,14 +2715,14 @@ BOOST_FIXTURE_TEST_CASE( proxy_cannot_use_another_proxy, eosio_system_tester ) t ); //proxy should not be able to use a proxy - issue( "bob111111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account registered as a proxy is not allowed to use a proxy" ), vote( N(bob111111111), vector(), "alice1111111" ) ); //voter that uses a proxy should not be allowed to become a proxy - issue( "carol1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_from_string("100.0002"), core_from_string("50.0001") ) ); + issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account that uses a proxy is not allowed to become a proxy" ), push_action( N(carol1111111), N(regproxy), mvo() @@ -2764,8 +2764,8 @@ BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_teste BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); //stake more than 15% of total EOS supply to activate chain - transfer( "eosio", "alice1111111", core_from_string("600000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_from_string("300000000.0000"), core_from_string("300000000.0000") ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("600000000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); //vote for producers BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1) } ) ); produce_blocks(250); @@ -2778,9 +2778,9 @@ BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_teste //REQUIRE_EQUAL_OBJECTS(prod1_config, config); // elect 2 producers - issue( "bob111111111", core_from_string("80000.0000"), config::system_account_name ); + issue( "bob111111111", core_sym::from_string("80000.0000"), config::system_account_name ); ilog("stake"); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_from_string("40000.0000"), core_from_string("40000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("40000.0000"), core_sym::from_string("40000.0000") ) ); ilog("start vote"); BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); ilog("."); @@ -2826,10 +2826,10 @@ BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_teste BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { create_accounts_with_resources( { N(dan), N(sam) } ); - transfer( config::system_account_name, "dan", core_from_string( "10000.0000" ) ); - transfer( config::system_account_name, "sam", core_from_string( "10000.0000" ) ); - stake_with_transfer( config::system_account_name, "sam", core_from_string( "80000000.0000" ), core_from_string( "80000000.0000" ) ); - stake_with_transfer( config::system_account_name, "dan", core_from_string( "80000000.0000" ), core_from_string( "80000000.0000" ) ); + transfer( config::system_account_name, "dan", core_sym::from_string( "10000.0000" ) ); + transfer( config::system_account_name, "sam", core_sym::from_string( "10000.0000" ) ); + stake_with_transfer( config::system_account_name, "sam", core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); + stake_with_transfer( config::system_account_name, "dan", core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); regproducer( config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), vote( N(sam), { config::system_account_name } ) ); @@ -2841,9 +2841,9 @@ BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(fail) }, N(dan) ), // dan shouldn't be able to create fail eosio_assert_message_exception, eosio_assert_message_is( "no active bid for name" ) ); - bidname( "dan", "nofail", core_from_string( "1.0000" ) ); - BOOST_REQUIRE_EQUAL( "assertion failure with message: must increase bid by 10%", bidname( "sam", "nofail", core_from_string( "1.0000" ) )); // didn't increase bid by 10% - BOOST_REQUIRE_EQUAL( success(), bidname( "sam", "nofail", core_from_string( "2.0000" ) )); // didn't increase bid by 10% + bidname( "dan", "nofail", core_sym::from_string( "1.0000" ) ); + BOOST_REQUIRE_EQUAL( "assertion failure with message: must increase bid by 10%", bidname( "sam", "nofail", core_sym::from_string( "1.0000" ) )); // didn't increase bid by 10% + BOOST_REQUIRE_EQUAL( success(), bidname( "sam", "nofail", core_sym::from_string( "2.0000" ) )); // didn't increase bid by 10% produce_block( fc::days(1) ); produce_block(); @@ -2852,7 +2852,7 @@ BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { //wlog( "verify sam can create nofail" ); create_accounts_with_resources( { N(nofail) }, N(sam) ); // sam should be able to do this, he won the bid //wlog( "verify nofail can create test.nofail" ); - transfer( "eosio", "nofail", core_from_string( "1000.0000" ) ); + transfer( "eosio", "nofail", core_sym::from_string( "1000.0000" ) ); create_accounts_with_resources( { N(test.nofail) }, N(nofail) ); // only nofail can create test.nofail //wlog( "verify dan cannot create test.fail" ); BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(test.fail) }, N(dan) ), // dan shouldn't be able to do this @@ -2865,16 +2865,16 @@ BOOST_FIXTURE_TEST_CASE( bid_invalid_names, eosio_system_tester ) try { create_accounts_with_resources( { N(dan) } ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "you can only bid on top-level suffix" ), - bidname( "dan", "abcdefg.12345", core_from_string( "1.0000" ) ) ); + bidname( "dan", "abcdefg.12345", core_sym::from_string( "1.0000" ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "the empty name is not a valid account name to bid on" ), - bidname( "dan", "", core_from_string( "1.0000" ) ) ); + bidname( "dan", "", core_sym::from_string( "1.0000" ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "13 character names are not valid account names to bid on" ), - bidname( "dan", "abcdefgh12345", core_from_string( "1.0000" ) ) ); + bidname( "dan", "abcdefgh12345", core_sym::from_string( "1.0000" ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "accounts with 12 character names and no dots can be created without bidding required" ), - bidname( "dan", "abcdefg12345", core_from_string( "1.0000" ) ) ); + bidname( "dan", "abcdefg12345", core_sym::from_string( "1.0000" ) ) ); } FC_LOG_AND_RETHROW() @@ -2885,61 +2885,61 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { std::vector accounts = { N(alice), N(bob), N(carl), N(david), N(eve) }; create_accounts_with_resources( accounts ); for ( const auto& a: accounts ) { - transfer( config::system_account_name, a, core_from_string( "10000.0000" ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance(a) ); + transfer( config::system_account_name, a, core_sym::from_string( "10000.0000" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance(a) ); } create_accounts_with_resources( { N(producer) } ); BOOST_REQUIRE_EQUAL( success(), regproducer( N(producer) ) ); produce_block(); // stake but but not enough to go live - stake_with_transfer( config::system_account_name, "bob", core_from_string( "35000000.0000" ), core_from_string( "35000000.0000" ) ); - stake_with_transfer( config::system_account_name, "carl", core_from_string( "35000000.0000" ), core_from_string( "35000000.0000" ) ); + stake_with_transfer( config::system_account_name, "bob", core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); + stake_with_transfer( config::system_account_name, "carl", core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob), { N(producer) } ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carl), { N(producer) } ) ); // start bids - bidname( "bob", "prefa", core_from_string("1.0003") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.9997" ), get_balance("bob") ); - bidname( "bob", "prefb", core_from_string("1.0000") ); - bidname( "bob", "prefc", core_from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9996.9997" ), get_balance("bob") ); + bidname( "bob", "prefa", core_sym::from_string("1.0003") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.9997" ), get_balance("bob") ); + bidname( "bob", "prefb", core_sym::from_string("1.0000") ); + bidname( "bob", "prefc", core_sym::from_string("1.0000") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9996.9997" ), get_balance("bob") ); - bidname( "carl", "prefd", core_from_string("1.0000") ); - bidname( "carl", "prefe", core_from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.0000" ), get_balance("carl") ); + bidname( "carl", "prefd", core_sym::from_string("1.0000") ); + bidname( "carl", "prefe", core_sym::from_string("1.0000") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0000" ), get_balance("carl") ); BOOST_REQUIRE_EQUAL( error("assertion failure with message: account is already highest bidder"), - bidname( "bob", "prefb", core_from_string("1.1001") ) ); + bidname( "bob", "prefb", core_sym::from_string("1.1001") ) ); BOOST_REQUIRE_EQUAL( error("assertion failure with message: must increase bid by 10%"), - bidname( "alice", "prefb", core_from_string("1.0999") ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9996.9997" ), get_balance("bob") ); - BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance("alice") ); + bidname( "alice", "prefb", core_sym::from_string("1.0999") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9996.9997" ), get_balance("bob") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance("alice") ); // alice outbids bob on prefb { const asset initial_names_balance = get_balance(N(eosio.names)); BOOST_REQUIRE_EQUAL( success(), - bidname( "alice", "prefb", core_from_string("1.1001") ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9997.9997" ), get_balance("bob") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.8999" ), get_balance("alice") ); - BOOST_REQUIRE_EQUAL( initial_names_balance + core_from_string("0.1001"), get_balance(N(eosio.names)) ); + bidname( "alice", "prefb", core_sym::from_string("1.1001") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9997.9997" ), get_balance("bob") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.8999" ), get_balance("alice") ); + BOOST_REQUIRE_EQUAL( initial_names_balance + core_sym::from_string("0.1001"), get_balance(N(eosio.names)) ); } // david outbids carl on prefd { - BOOST_REQUIRE_EQUAL( core_from_string( "9998.0000" ), get_balance("carl") ); - BOOST_REQUIRE_EQUAL( core_from_string( "10000.0000" ), get_balance("david") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0000" ), get_balance("carl") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance("david") ); BOOST_REQUIRE_EQUAL( success(), - bidname( "david", "prefd", core_from_string("1.9900") ) ); - BOOST_REQUIRE_EQUAL( core_from_string( "9999.0000" ), get_balance("carl") ); - BOOST_REQUIRE_EQUAL( core_from_string( "9998.0100" ), get_balance("david") ); + bidname( "david", "prefd", core_sym::from_string("1.9900") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9999.0000" ), get_balance("carl") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0100" ), get_balance("david") ); } // eve outbids carl on prefe { BOOST_REQUIRE_EQUAL( success(), - bidname( "eve", "prefe", core_from_string("1.7200") ) ); + bidname( "eve", "prefe", core_sym::from_string("1.7200") ) ); } produce_block( fc::days(14) ); @@ -2950,7 +2950,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { fc::exception, fc_assert_exception_message_is( not_closed_message ) ); // stake enough to go above the 15% threshold - stake_with_transfer( config::system_account_name, "alice", core_from_string( "10000000.0000" ), core_from_string( "10000000.0000" ) ); + stake_with_transfer( config::system_account_name, "alice", core_sym::from_string( "10000000.0000" ), core_sym::from_string( "10000000.0000" ) ); BOOST_REQUIRE_EQUAL(0, get_producer_info("producer")["unpaid_blocks"].as()); BOOST_REQUIRE_EQUAL( success(), vote( N(alice), { N(producer) } ) ); @@ -2979,7 +2979,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { fc::exception, fc_assert_exception_message_is( "no active bid for name" ) ); // changing highest bid pushes auction closing time by 24 hours BOOST_REQUIRE_EQUAL( success(), - bidname( "eve", "prefb", core_from_string("2.1880") ) ); + bidname( "eve", "prefb", core_sym::from_string("2.1880") ) ); produce_block( fc::hours(22) ); produce_blocks(2); @@ -2988,7 +2988,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { fc::exception, fc_assert_exception_message_is( not_closed_message ) ); // but changing a bid that is not the highest does not push closing time BOOST_REQUIRE_EQUAL( success(), - bidname( "carl", "prefe", core_from_string("2.0980") ) ); + bidname( "carl", "prefe", core_sym::from_string("2.0980") ) ); produce_block( fc::hours(2) ); produce_blocks(2); // bid for prefb has closed, only highest bidder can claim @@ -3007,7 +3007,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { // prefe can now create *.prefe BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(xyz.prefe), N(carl) ), fc::exception, fc_assert_exception_message_is("only suffix may create this account") ); - transfer( config::system_account_name, N(prefe), core_from_string("10000.0000") ); + transfer( config::system_account_name, N(prefe), core_sym::from_string("10000.0000") ); create_account_with_resources( N(xyz.prefe), N(prefe) ); // other auctions haven't closed @@ -3019,11 +3019,11 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( namebid_pending_winner, eosio_system_tester ) try { cross_15_percent_threshold(); produce_block( fc::hours(14*24) ); //wait 14 day for name auction activation - transfer( config::system_account_name, N(alice1111111), core_from_string("10000.0000") ); - transfer( config::system_account_name, N(bob111111111), core_from_string("10000.0000") ); + transfer( config::system_account_name, N(alice1111111), core_sym::from_string("10000.0000") ); + transfer( config::system_account_name, N(bob111111111), core_sym::from_string("10000.0000") ); - BOOST_REQUIRE_EQUAL( success(), bidname( "alice1111111", "prefa", core_from_string( "50.0000" ) )); - BOOST_REQUIRE_EQUAL( success(), bidname( "bob111111111", "prefb", core_from_string( "30.0000" ) )); + BOOST_REQUIRE_EQUAL( success(), bidname( "alice1111111", "prefa", core_sym::from_string( "50.0000" ) )); + BOOST_REQUIRE_EQUAL( success(), bidname( "bob111111111", "prefb", core_sym::from_string( "30.0000" ) )); produce_block( fc::hours(100) ); //should close "perfa" produce_block( fc::hours(100) ); //should close "perfb" @@ -3033,11 +3033,11 @@ BOOST_FIXTURE_TEST_CASE( namebid_pending_winner, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); + const asset net = core_sym::from_string("80.0000"); + const asset cpu = core_sym::from_string("80.0000"); std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - create_account_with_resources(v, config::system_account_name, core_from_string("1.0000"), false, net, cpu); + create_account_with_resources(v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu); } // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers @@ -3059,8 +3059,8 @@ BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { } for (const auto& v: voters) { - transfer( config::system_account_name, v, core_from_string("200000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_from_string("30000000.0000"), core_from_string("30000000.0000")) ); + transfer( config::system_account_name, v, core_sym::from_string("200000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); } { @@ -3091,7 +3091,7 @@ BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { produce_block(fc::hours(7)); const uint32_t voted_out_index = 20; const uint32_t new_prod_index = 23; - BOOST_REQUIRE_EQUAL(success(), stake("producvoterd", core_from_string("40000000.0000"), core_from_string("40000000.0000"))); + BOOST_REQUIRE_EQUAL(success(), stake("producvoterd", core_sym::from_string("40000000.0000"), core_sym::from_string("40000000.0000"))); BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), { producer_names[new_prod_index] })); BOOST_REQUIRE_EQUAL(0, get_producer_info(producer_names[new_prod_index])["unpaid_blocks"].as()); produce_blocks(4 * 12 * 21); @@ -3201,35 +3201,35 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { - const asset net = core_from_string("8.0000"); - const asset cpu = core_from_string("8.0000"); + const asset net = core_sym::from_string("8.0000"); + const asset cpu = core_sym::from_string("8.0000"); std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; for (const auto& a: accounts) { - create_account_with_resources(a, config::system_account_name, core_from_string("1.0000"), false, net, cpu); + create_account_with_resources(a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu); } { const auto name_a = accounts[0]; - transfer( config::system_account_name, name_a, core_from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance(name_a) ); + transfer( config::system_account_name, name_a, core_sym::from_string("1000.0000") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance(name_a) ); const uint64_t init_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), buyram( name_a, name_a, core_from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance(name_a) ); + BOOST_REQUIRE_EQUAL( success(), buyram( name_a, name_a, core_sym::from_string("300.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance(name_a) ); const uint64_t bought_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64() - init_bytes_a; // after buying and selling balance should be 700 + 300 * 0.995 * 0.995 = 997.0075 (actually 997.0074 due to rounding fees up) BOOST_REQUIRE_EQUAL( success(), sellram(name_a, bought_bytes_a ) ); - BOOST_REQUIRE_EQUAL( core_from_string("997.0074"), get_balance(name_a) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("997.0074"), get_balance(name_a) ); } { const auto name_b = accounts[1]; - transfer( config::system_account_name, name_b, core_from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_from_string("1000.0000"), get_balance(name_b) ); + transfer( config::system_account_name, name_b, core_sym::from_string("1000.0000") ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance(name_b) ); const uint64_t init_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64(); // name_b buys ram at current price - BOOST_REQUIRE_EQUAL( success(), buyram( name_b, name_b, core_from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("700.0000"), get_balance(name_b) ); + BOOST_REQUIRE_EQUAL( success(), buyram( name_b, name_b, core_sym::from_string("300.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance(name_b) ); const uint64_t bought_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64() - init_bytes_b; // increase max_ram_size, ram bought by name_b loses part of its value @@ -3241,8 +3241,8 @@ BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { push_action(config::system_account_name, N(setram), mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); BOOST_REQUIRE_EQUAL( success(), sellram(name_b, bought_bytes_b ) ); - BOOST_REQUIRE( core_from_string("900.0000") < get_balance(name_b) ); - BOOST_REQUIRE( core_from_string("950.0000") > get_balance(name_b) ); + BOOST_REQUIRE( core_sym::from_string("900.0000") < get_balance(name_b) ); + BOOST_REQUIRE( core_sym::from_string("950.0000") > get_balance(name_b) ); } } FC_LOG_AND_RETHROW() @@ -3254,8 +3254,8 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); produce_blocks(20); BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - transfer( config::system_account_name, "alice1111111", core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + transfer( config::system_account_name, "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); produce_blocks(3); BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); uint16_t rate = 1000; @@ -3268,7 +3268,7 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { // But with additional blocks, it should start accumulating at the new rate. uint64_t cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); produce_blocks(10); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * rate, get_global_state()["max_ram_size"].as_uint64() ); cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); produce_blocks(5); @@ -3296,13 +3296,13 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); const asset initial_ram_balance = get_balance(N(eosio.ram)); const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("1000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol().to_symbol_code() ).empty() ); @@ -3344,13 +3344,13 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { */ //check that stake/unstake keeps the gift - transfer( "eosio", "alice1111111", core_from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_from_string("200.0000"), core_from_string("100.0000") ) ); + transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); + BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); int64_t ram_bytes_after_stake; rlm.get_account_limits( N(alice1111111), ram_bytes_after_stake, net_weight, cpu_weight ); BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_stake ); - BOOST_REQUIRE_EQUAL( success(), unstake( "eosio", "alice1111111", core_from_string("20.0000"), core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( "eosio", "alice1111111", core_sym::from_string("20.0000"), core_sym::from_string("10.0000") ) ); int64_t ram_bytes_after_unstake; rlm.get_account_limits( N(alice1111111), ram_bytes_after_unstake, net_weight, cpu_weight ); BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_unstake ); @@ -3358,7 +3358,7 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { uint64_t ram_gift = 1400; int64_t ram_bytes; - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_from_string("1000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); auto userres = get_total_stake( N(alice1111111) ); BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); From 89b419b9b038ad1805035b279f8533863300dc06 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 1 Oct 2018 18:26:10 -0400 Subject: [PATCH 0555/1048] fix eosio.msig tests; cleanup symbol macros --- tests/eosio.msig_tests.cpp | 10 ++++++---- tests/test_symbol.hpp | 11 ++++++++--- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 766f1ef8..609a2715 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -413,9 +413,9 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); - base_tester::push_action(config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("core", CORE_SYM_STR)); + base_tester::push_action( config::system_account_name, N(init), + config::system_account_name, mutable_variant_object() + ("core", CORE_SYM_STR) ); produce_blocks(); create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); @@ -525,7 +525,9 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); - + base_tester::push_action( config::system_account_name, N(init), + config::system_account_name, mutable_variant_object() + ("core", CORE_SYM_STR) ); produce_blocks(); create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); diff --git a/tests/test_symbol.hpp b/tests/test_symbol.hpp index 21cff898..598ea434 100644 --- a/tests/test_symbol.hpp +++ b/tests/test_symbol.hpp @@ -1,11 +1,16 @@ #pragma once -#define CORE_SYM SY(4, TST) + #define CORE_SYM_NAME "TST" -#define CORE_SYM_STR "4,TST" +#define CORE_SYM_PRECISION 4 + +#define _STRINGIZE1(x) #x +#define _STRINGIZE2(x) _STRINGIZE1(x) + +#define CORE_SYM_STR ( _STRINGIZE2(CORE_SYM_PRECISION) "," CORE_SYM_NAME ) +#define CORE_SYM ( ::eosio::chain::string_to_symbol_c( CORE_SYM_PRECISION, CORE_SYM_NAME ) ) struct core_sym { static inline eosio::chain::asset from_string(const std::string& s) { return eosio::chain::asset::from_string(s + " " CORE_SYM_NAME); } }; - From 815fab69a07cca243b06d764df4ffa49ca020727 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 1 Oct 2018 20:15:11 -0400 Subject: [PATCH 0556/1048] additional bug fixes in system contract related to core symbol; fix remaining eosio.system tests --- eosio.system/src/delegate_bandwidth.cpp | 8 ++- eosio.system/src/eosio.system.cpp | 2 +- tests/eosio.system_tester.hpp | 80 ++++++++++++++++------ tests/eosio.system_tests.cpp | 88 +++++++++++++++---------- 4 files changed, 120 insertions(+), 58 deletions(-) diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 563a8380..a5ceb6a1 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -336,11 +336,15 @@ namespace eosiosystem { if ( net_balance.amount < 0 ) { r.net_amount = -net_balance; net_balance.amount = 0; - } // else r.net_amount = 0 by default constructor + } else { + r.net_amount = asset( 0, core_symbol() ); + } if ( cpu_balance.amount < 0 ) { r.cpu_amount = -cpu_balance; cpu_balance.amount = 0; - } // else r.cpu_amount = 0 by default constructor + } else { + r.cpu_amount = asset( 0, core_symbol() ); + } r.request_time = now(); }); need_deferred_trx = true; diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index daae0278..e0651b65 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -164,7 +164,7 @@ namespace eosiosystem { eosio_assert( (newname & 0xFull) == 0, "13 character names are not valid account names to bid on" ); eosio_assert( (newname & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); eosio_assert( !is_account( newname ), "account already exists" ); - eosio_assert( bid.symbol == asset().symbol, "asset must be system token" ); + eosio_assert( bid.symbol == core_symbol(), "asset must be system token" ); eosio_assert( bid.amount > 0, "insufficient bid" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {bidder,N(active)}, diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index c96353b2..6589a73d 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -31,13 +31,8 @@ namespace eosio_system { class eosio_system_tester : public TESTER { public: - eosio_system_tester() - : eosio_system_tester([](TESTER& ) {}){} - - template - eosio_system_tester(Lambda setup) { - setup(*this); + void basic_setup() { produce_blocks( 2 ); create_accounts({ N(eosio.token), N(eosio.ram), N(eosio.ramfee), N(eosio.stake), @@ -53,24 +48,36 @@ class eosio_system_tester : public TESTER { BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); token_abi_ser.set_abi(abi, abi_serializer_max_time); } + } + + void create_core_token( symbol core_symbol = symbol{CORE_SYM} ) { + FC_ASSERT( core_symbol.precision() != 4, "create_core_token assumes precision of core token is 4" ); + create_currency( N(eosio.token), config::system_account_name, asset(100000000000000, core_symbol) ); + issue(config::system_account_name, asset(10000000000000, core_symbol) ); + BOOST_REQUIRE_EQUAL( asset(10000000000000, core_symbol), get_balance( "eosio", core_symbol ) ); + } - create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); - issue(config::system_account_name, core_sym::from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( "eosio" ) ); + void deploy_contract( bool call_init = true ) { set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); - base_tester::push_action(config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("core", CORE_SYM_STR)); + if( call_init ) { + base_tester::push_action(config::system_account_name, N(init), + config::system_account_name, mutable_variant_object() + ("core", CORE_SYM_STR)); + } + { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); abi_ser.set_abi(abi, abi_serializer_max_time); } + } + void remaining_setup() { produce_blocks(); + // Assumes previous setup steps were done with core token symbol set to CORE_SYM create_account_with_resources( N(alice1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); create_account_with_resources( N(bob111111111), config::system_account_name, core_sym::from_string("0.4500"), false ); create_account_with_resources( N(carol1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); @@ -78,6 +85,39 @@ class eosio_system_tester : public TESTER { BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); } + enum class setup_level { + none, + minimal, + core_token, + deploy_contract, + full + }; + + eosio_system_tester( setup_level l = setup_level::full ) { + if( l == setup_level::none ) return; + + basic_setup(); + if( l == setup_level::minimal ) return; + + create_core_token(); + if( l == setup_level::core_token ) return; + + deploy_contract(); + if( l == setup_level::deploy_contract ) return; + + remaining_setup(); + } + + template + eosio_system_tester(Lambda setup) { + setup(*this); + + basic_setup(); + create_core_token(); + deploy_contract(); + remaining_setup(); + } + void create_accounts_with_resources( vector accounts, account_name creator = config::system_account_name ) { for( auto a : accounts ) { @@ -164,13 +204,15 @@ class eosio_system_tester : public TESTER { return push_transaction( trx ); } - transaction_trace_ptr setup_producer_accounts( const std::vector& accounts ) { + transaction_trace_ptr setup_producer_accounts( const std::vector& accounts, + asset ram = core_sym::from_string("1.0000"), + asset cpu = core_sym::from_string("80.0000"), + asset net = core_sym::from_string("80.0000") + ) + { account_name creator(config::system_account_name); signed_transaction trx; set_transaction_headers(trx); - asset cpu = core_sym::from_string("80.0000"); - asset net = core_sym::from_string("80.0000"); - asset ram = core_sym::from_string("1.0000"); for (const auto& a: accounts) { authority owner_auth( get_public_key( a, "owner" ) ); @@ -321,9 +363,9 @@ class eosio_system_tester : public TESTER { return time_point_sec( control->head_block_time() ).sec_since_epoch(); } - asset get_balance( const account_name& act ) { - vector data = get_row_by_account( N(eosio.token), act, N(accounts), symbol(CORE_SYM).to_symbol_code().value ); - return data.empty() ? asset(0, symbol(CORE_SYM)) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); + asset get_balance( const account_name& act, symbol balance_symbol = symbol{CORE_SYM} ) { + vector data = get_row_by_account( N(eosio.token), act, N(accounts), balance_symbol.to_symbol_code().value ); + return data.empty() ? asset(0, balance_symbol) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } fc::variant get_total_stake( const account_name& act ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index df7a9a4e..7a879ea1 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2267,18 +2267,33 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE(votepay_transition2, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { +BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) try { + eosio_system_tester t(eosio_system_tester::setup_level::minimal); - set_code( config::system_account_name, contracts::util::system_wasm_old() ); - set_abi( config::system_account_name, contracts::util::system_abi_old().data() ); + std::string old_contract_core_symbol_name = "SYS"; // Set to core symbol used in contracts::util::system_wasm_old() + symbol old_contract_core_symbol{::eosio::chain::string_to_symbol_c( 4, old_contract_core_symbol_name.c_str() )}; - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); + auto old_core_from_string = [&]( const std::string& s ) { + return eosio::chain::asset::from_string(s + " " + old_contract_core_symbol_name); + }; + + t.create_core_token( old_contract_core_symbol ); + t.set_code( config::system_account_name, contracts::util::system_wasm_old() ); + t.set_abi( config::system_account_name, contracts::util::system_abi_old().data() ); + { + const auto& accnt = t.control->db().get( config::system_account_name ); + abi_def abi; + BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); + t.abi_ser.set_abi(abi, eosio_system_tester::abi_serializer_max_time); + } + + const asset net = old_core_from_string("80.0000"); + const asset cpu = old_core_from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); + t.create_account_with_resources( v, config::system_account_name, old_core_from_string("1.0000"), false, net, cpu ); + t.transfer( config::system_account_name, v, old_core_from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(t.success(), t.stake(v, old_core_from_string("30000000.0000"), old_core_from_string("30000000.0000")) ); } // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers @@ -2291,42 +2306,43 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition2, eosio_system_tester, * boost::unit_ producer_names.emplace_back(root + std::string(1, c)); } } - setup_producer_accounts(producer_names); + t.setup_producer_accounts( producer_names, old_core_from_string("1.0000"), + old_core_from_string("80.0000"), old_core_from_string("80.0000") ); for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); + BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(p) ); + BOOST_TEST_REQUIRE(0 == t.get_producer_info(p)["total_votes"].as_double()); } } - BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); - produce_block( fc::hours(20) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); - produce_block( fc::hours(30) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.end())) ); - BOOST_REQUIRE_EQUAL( success(), push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); - BOOST_REQUIRE_EQUAL( success(), push_action(producer_names[1], N(claimrewards), mvo()("owner", producer_names[1])) ); - auto* tbl = control->db().find( boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); + BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); + t.produce_block( fc::hours(20) ); + BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); + t.produce_block( fc::hours(30) ); + BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvoterc), vector(producer_names.begin(), producer_names.end())) ); + BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); + BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[1], N(claimrewards), mvo()("owner", producer_names[1])) ); + auto* tbl = t.control->db().find( + boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); BOOST_REQUIRE( !tbl ); - produce_block( fc::hours(2*24) ); + t.produce_block( fc::hours(2*24) ); - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); + t.deploy_contract( false ); - produce_blocks(2); - produce_block( fc::hours(24 + 1) ); + t.produce_blocks(2); + t.produce_block( fc::hours(24 + 1) ); - BOOST_REQUIRE_EQUAL( success(), push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( get_producer_info(producer_names[0])["total_votes"].as_double() == get_global_state3()["total_vpay_share_change_rate"].as_double() ); + BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); + BOOST_TEST_REQUIRE( 0 == t.get_global_state2()["total_producer_votepay_share"].as_double() ); + BOOST_TEST_REQUIRE( t.get_producer_info(producer_names[0])["total_votes"].as_double() == t.get_global_state3()["total_vpay_share_change_rate"].as_double() ); - produce_block( fc::hours(5) ); + t.produce_block( fc::hours(5) ); - BOOST_REQUIRE_EQUAL( success(), regproducer(producer_names[1]) ); - BOOST_TEST_REQUIRE( get_producer_info(producer_names[0])["total_votes"].as_double() + get_producer_info(producer_names[1])["total_votes"].as_double() == - get_global_state3()["total_vpay_share_change_rate"].as_double() ); + BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(producer_names[1]) ); + BOOST_TEST_REQUIRE( t.get_producer_info(producer_names[0])["total_votes"].as_double() + t.get_producer_info(producer_names[1])["total_votes"].as_double() == + t.get_global_state3()["total_vpay_share_change_rate"].as_double() ); } FC_LOG_AND_RETHROW() @@ -3304,14 +3320,14 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol().to_symbol_code() ).empty() ); + BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol{CORE_SYM}.to_symbol_code() ).empty() ); //remove row base_tester::push_action( N(eosio.token), N(close), N(alice1111111), mvo() ( "owner", "alice1111111" ) - ( "symbol", symbol() ) + ( "symbol", symbol{CORE_SYM} ) ); - BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol().to_symbol_code() ).empty() ); + BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol{CORE_SYM}.to_symbol_code() ).empty() ); auto rlm = control->get_resource_limits_manager(); auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); From ca9ce1e974f2efe12756a20fcf1f0e24d86e076b Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 2 Oct 2018 11:40:35 -0400 Subject: [PATCH 0557/1048] use _n suffix rather than N macro --- eosio.bios/include/eosio.bios/eosio.bios.hpp | 2 +- eosio.msig/include/eosio.msig/eosio.msig.hpp | 8 +-- .../include/eosio.system/eosio.system.hpp | 34 ++++++++----- .../include/eosio.system/exchange_state.hpp | 4 +- eosio.system/src/delegate_bandwidth.cpp | 51 ++++++++++++------- eosio.system/src/eosio.system.cpp | 29 ++++++----- eosio.system/src/producer_pay.cpp | 42 +++++++++------ eosio.system/src/voting.cpp | 2 +- .../include/eosio.token/eosio.token.hpp | 4 +- eosio.token/src/eosio.token.cpp | 4 +- 10 files changed, 112 insertions(+), 68 deletions(-) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 2cfe5688..44f1dc80 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -13,7 +13,7 @@ namespace eosio { EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; - typedef eosio::multi_index< N(abihash), abi_hash> abi_hash_table; + typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; class bios : public contract { public: diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index adfad2b8..f3c74d22 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -22,7 +22,7 @@ namespace eosio { auto primary_key()const { return proposal_name.value; } }; - typedef eosio::multi_index proposals; + typedef eosio::multi_index< "proposal"_n, proposal > proposals; struct old_approvals_info { name proposal_name; @@ -31,7 +31,7 @@ namespace eosio { auto primary_key()const { return proposal_name.value; } }; - typedef eosio::multi_index old_approvals; + typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals; struct approval { permission_level level; @@ -49,7 +49,7 @@ namespace eosio { auto primary_key()const { return proposal_name.value; } }; - typedef eosio::multi_index approvals; + typedef eosio::multi_index< "approvals2"_n, approvals_info > approvals; struct invalidation { account_name account; @@ -58,7 +58,7 @@ namespace eosio { auto primary_key() const { return account; } }; - typedef eosio::multi_index invalidations; + typedef eosio::multi_index< "invals"_n, invalidation > invalidations; }; } /// namespace eosio diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 01a0606b..62850d6b 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -39,11 +39,11 @@ namespace eosiosystem { auto primary_key() const { return bidder; } }; - typedef eosio::multi_index< N(namebids), name_bid, - indexed_by > - > name_bid_table; + typedef eosio::multi_index< "namebids"_n, name_bid, + indexed_by<"highbid"_n, const_mem_fun > + > name_bid_table; - typedef eosio::multi_index< N(bidrefunds), bid_refund> bid_refund_table; + typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; struct eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } @@ -157,17 +157,17 @@ namespace eosiosystem { EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(reserved1)(reserved2)(reserved3) ) }; - typedef eosio::multi_index< N(voters), voter_info> voters_table; + typedef eosio::multi_index< "voters"_n, voter_info > voters_table; - typedef eosio::multi_index< N(producers), producer_info, - indexed_by > - > producers_table; - typedef eosio::multi_index< N(producers2), producer_info2 > producers_table2; + typedef eosio::multi_index< "producers"_n, producer_info, + indexed_by<"prototalvote"_n, const_mem_fun > + > producers_table; + typedef eosio::multi_index< "producers2"_n, producer_info2 > producers_table2; - typedef eosio::singleton global_state_singleton; - typedef eosio::singleton global_state2_singleton; - typedef eosio::singleton global_state3_singleton; + typedef eosio::singleton< "global"_n, eosio_global_state > global_state_singleton; + typedef eosio::singleton< "global2"_n, eosio_global_state2 > global_state2_singleton; + typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; @@ -186,6 +186,16 @@ namespace eosiosystem { rammarket _rammarket; public: + static constexpr eosio::name active_permission{"active"_n}; + static constexpr eosio::name token_account{"eosio.token"_n}; + static constexpr eosio::name ram_account{"eosio.ram"_n}; + static constexpr eosio::name ramfee_account{"eosio.ramfee"_n}; + static constexpr eosio::name stake_account{"eosio.stake"_n}; + static constexpr eosio::name bpay_account{"eosio.bpay"_n}; + static constexpr eosio::name vpay_account{"eosio.vpay"_n}; + static constexpr eosio::name names_account{"eosio.names"_n}; + static constexpr eosio::name saving_account{"eosio.saving"_n}; + system_contract( account_name s ); ~system_contract(); diff --git a/eosio.system/include/eosio.system/exchange_state.hpp b/eosio.system/include/eosio.system/exchange_state.hpp index 3705a9b8..b680d09e 100644 --- a/eosio.system/include/eosio.system/exchange_state.hpp +++ b/eosio.system/include/eosio.system/exchange_state.hpp @@ -28,13 +28,13 @@ namespace eosiosystem { uint64_t primary_key()const { return supply.symbol; } - asset convert_to_exchange( connector& c, asset in ); + asset convert_to_exchange( connector& c, asset in ); asset convert_from_exchange( connector& c, asset in ); asset convert( asset from, symbol_type to ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) }; - typedef eosio::multi_index rammarket; + typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; } /// namespace eosiosystem diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index a5ceb6a1..e206d438 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -77,9 +77,9 @@ namespace eosiosystem { * These tables are designed to be constructed in the scope of the relevant user, this * facilitates simpler API for per-user queries */ - typedef eosio::multi_index< N(userres), user_resources> user_resources_table; - typedef eosio::multi_index< N(delband), delegated_bandwidth> del_bandwidth_table; - typedef eosio::multi_index< N(refunds), refund_request> refunds_table; + typedef eosio::multi_index< "userres"_n, user_resources > user_resources_table; + typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; + typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; @@ -122,12 +122,16 @@ namespace eosiosystem { // quant_after_fee.amount should be > 0 if quant.amount > 1. // If quant.amount == 1, then quant_after_fee.amount == 0 and the next inline transfer will fail causing the buyram action to fail. - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{payer,N(active)},{N(eosio.ram),N(active)}}, - { payer, N(eosio.ram), quant_after_fee, std::string("buy ram") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {payer, active_permission}, {ram_account, active_permission} }, + { payer, ram_account, quant_after_fee, std::string("buy ram") } + ); if( fee.amount > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, - { payer, N(eosio.ramfee), fee, std::string("ram fee") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {payer, active_permission} }, + { payer, ramfee_account, fee, std::string("ram fee") } + ); } int64_t bytes_out; @@ -196,14 +200,18 @@ namespace eosiosystem { }); set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.ram),N(active)},{account,N(active)}}, - { N(eosio.ram), account, asset(tokens_out), std::string("sell ram") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {ram_account, active_permission}, {account, active_permission} }, + { ram_account, account, asset(tokens_out), std::string("sell ram") } + ); auto fee = ( tokens_out.amount + 199 ) / 200; /// .5% fee (round up) // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount if( fee > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, - { account, N(eosio.ramfee), asset(fee, core_symbol()), std::string("sell ram fee") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {account, active_permission} }, + { account, ramfee_account, asset(fee, core_symbol()), std::string("sell ram fee") } + ); } } @@ -284,7 +292,7 @@ namespace eosiosystem { } // tot_itr can be invalid, should go out of scope // create refund or update from existing refund - if ( N(eosio.stake) != source_stake_from ) { //for eosio both transfer and refund make no sense + if ( stake_account != source_stake_from ) { //for eosio both transfer and refund make no sense refunds_table refunds_tbl( _self, from ); auto req = refunds_tbl.find( from ); @@ -353,7 +361,10 @@ namespace eosiosystem { if ( need_deferred_trx ) { eosio::transaction out; - out.actions.emplace_back( permission_level{ from, N(active) }, _self, N(refund), from ); + out.actions.emplace_back( permission_level{from, active_permission}, + _self, "refund"_n, + from + ); out.delay_sec = refund_delay; cancel_deferred( from ); // TODO: Remove this line when replacing deferred trxs is fixed out.send( from, from, true ); @@ -363,8 +374,10 @@ namespace eosiosystem { auto transfer_amount = net_balance + cpu_balance; if ( 0 < transfer_amount.amount ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {source_stake_from, N(active)}, - { source_stake_from, N(eosio.stake), asset(transfer_amount), std::string("stake bandwidth") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {source_stake_from, active_permission} }, + { source_stake_from, stake_account, asset(transfer_amount), std::string("stake bandwidth") } + ); } } @@ -383,7 +396,7 @@ namespace eosiosystem { }); } eosio_assert( 0 <= from_voter->staked, "stake for voting cannot be negative"); - if( from == N(b1) ) { + if( from == "b1"_n ) { validate_b1_vesting( from_voter->staked ); } @@ -431,8 +444,10 @@ namespace eosiosystem { // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many // consecutive missed blocks. - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.stake),N(active)},{req->owner,N(active)}}, - { N(eosio.stake), req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {stake_account, active_permission}, {req->owner, active_permission} }, + { stake_account, req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } + ); refunds_tbl.erase( req ); } diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index e0651b65..cbb49954 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -49,7 +49,7 @@ namespace eosiosystem { } symbol_type system_contract::get_core_symbol() { - rammarket rm(N(eosio),N(eosio)); + rammarket rm("eosio"_n, "eosio"_n); const static auto sym = get_core_symbol( rm ); return sym; } @@ -119,7 +119,7 @@ namespace eosiosystem { } void system_contract::setparams( const eosio::blockchain_parameters& params ) { - require_auth( N(eosio) ); + require_auth( _self ); (eosio::blockchain_parameters&)(_gstate) = params; eosio_assert( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); set_blockchain_parameters( params ); @@ -131,7 +131,7 @@ namespace eosiosystem { } void system_contract::setalimits( account_name account, int64_t ram, int64_t net, int64_t cpu ) { - require_auth( N(eosio) ); + require_auth( _self ); user_resources_table userres( _self, account ); auto ritr = userres.find( account ); eosio_assert( ritr == userres.end(), "only supports unlimited accounts" ); @@ -167,8 +167,10 @@ namespace eosiosystem { eosio_assert( bid.symbol == core_symbol(), "asset must be system token" ); eosio_assert( bid.amount > 0, "insufficient bid" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {bidder,N(active)}, - { bidder, N(eosio.names), bid, std::string("bid name ")+(name{newname}).to_string() } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {bidder, active_permission} }, + { bidder, names_account, bid, std::string("bid name ")+(name{newname}).to_string() } + ); name_bid_table bids(_self,_self); print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); @@ -199,9 +201,11 @@ namespace eosiosystem { }); } - action a( {N(eosio),N(active)}, N(eosio), N(bidrefund), std::make_tuple( current->high_bidder, newname ) ); transaction t; - t.actions.push_back( std::move(a) ); + t.actions.emplace_back( permission_level{_self, active_permission}, + _self, "bidrefund"_n, + std::make_tuple( current->high_bidder, newname ) + ); t.delay_sec = 0; uint128_t deferred_id = (uint128_t(newname) << 64) | current->high_bidder; cancel_deferred( deferred_id ); @@ -219,9 +223,10 @@ namespace eosiosystem { bid_refund_table refunds_table(_self, newname); auto it = refunds_table.find( bidder ); eosio_assert( it != refunds_table.end(), "refund not found" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.names),N(active)},{bidder,N(active)}}, - { N(eosio.names), bidder, asset(it->amount), - std::string("refund bid on name ")+(name{newname}).to_string() } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {names_account, active_permission}, {bidder, active_permission} }, + { names_account, bidder, asset(it->amount), std::string("refund bid on name ")+(name{newname}).to_string() } + ); refunds_table.erase( it ); } @@ -275,7 +280,7 @@ namespace eosiosystem { } void native::setabi( account_name acnt, const bytes& abi ) { - eosio::multi_index< N(abihash), abi_hash> table(_self,_self); + eosio::multi_index< "abihash"_n, abi_hash > table(_self,_self); auto itr = table.find( acnt ); if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { @@ -293,7 +298,7 @@ namespace eosiosystem { auto itr = _rammarket.find(S(4,RAMCORE)); eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); - auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol_type(core).name()).amount; + auto system_token_supply = eosio::token(token_account).get_supply(eosio::symbol_type(core).name()).amount; if( system_token_supply > 0 ) { _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index c1e7675e..6be5ed0a 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -19,7 +19,7 @@ namespace eosiosystem { void system_contract::onblock( block_timestamp timestamp, account_name producer ) { using namespace eosio; - require_auth(N(eosio)); + require_auth(_self); // _gstate2.last_block_num is not used anywhere in the system contract code anymore. // Although this field is deprecated, we will continue updating it for now until the last_block_num field @@ -52,7 +52,7 @@ namespace eosiosystem { if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { name_bid_table bids(_self,_self); - auto idx = bids.get_index(); + auto idx = bids.get_index<"highbid"_n>(); auto highest = idx.lower_bound( std::numeric_limits::max()/2 ); if( highest != idx.end() && highest->high_bid > 0 && @@ -83,7 +83,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token( N(eosio.token)).get_supply( core_symbol().name() ); + const asset token_supply = token(token_account).get_supply( core_symbol().name() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { @@ -94,17 +94,25 @@ namespace eosiosystem { auto to_per_block_pay = to_producers / 4; auto to_per_vote_pay = to_producers - to_per_block_pay; - INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - { N(eosio), asset(new_tokens, core_symbol()), std::string("issue tokens for producer pay and savings") } ); + INLINE_ACTION_SENDER(eosio::token, issue)( + token_account, { {_self, active_permission} }, + { _self, asset(new_tokens, core_symbol()), std::string("issue tokens for producer pay and savings") } + ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.saving), asset(to_savings, core_symbol()), "unallocated inflation" } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {_self, active_permission} }, + { _self, saving_account, asset(to_savings, core_symbol()), "unallocated inflation" } + ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.bpay), asset(to_per_block_pay, core_symbol()), "fund per-block bucket" } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {_self, active_permission} }, + { _self, bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" } + ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.vpay), asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {_self, active_permission} }, + { _self, vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" } + ); _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; @@ -174,12 +182,16 @@ namespace eosiosystem { }); if( producer_per_block_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.bpay),N(active)},{owner,N(active)}}, - { N(eosio.bpay), owner, asset(producer_per_block_pay, core_symbol()), std::string("producer block pay") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {bpay_account, active_permission}, {owner, active_permission} }, + { bpay_account, owner, asset(producer_per_block_pay, core_symbol()), std::string("producer block pay") } + ); } if( producer_per_vote_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.vpay),N(active)},{owner,N(active)}}, - { N(eosio.vpay), owner, asset(producer_per_vote_pay, core_symbol()), std::string("producer vote pay") } ); + INLINE_ACTION_SENDER(eosio::token, transfer)( + token_account, { {vpay_account, active_permission}, {owner, active_permission} }, + { vpay_account, owner, asset(producer_per_vote_pay, core_symbol()), std::string("producer vote pay") } + ); } } diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index e4ffb1d8..435bc9fd 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -91,7 +91,7 @@ namespace eosiosystem { void system_contract::update_elected_producers( block_timestamp block_time ) { _gstate.last_producer_schedule_update = block_time; - auto idx = _producers.get_index(); + auto idx = _producers.get_index<"prototalvote"_n>(); std::vector< std::pair > top_producers; top_producers.reserve(21); diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 512e877a..bea78a64 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -56,8 +56,8 @@ namespace eosio { uint64_t primary_key()const { return supply.symbol.name(); } }; - typedef eosio::multi_index accounts; - typedef eosio::multi_index stats; + typedef eosio::multi_index< "accounts"_n, account > accounts; + typedef eosio::multi_index< "stat"_n, currency_stats > stats; void sub_balance( account_name owner, asset value ); void add_balance( account_name owner, asset value, account_name ram_payer ); diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index 74831f48..de3a876a 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -55,7 +55,9 @@ void token::issue( account_name to, asset quantity, string memo ) add_balance( st.issuer, quantity, st.issuer ); if( to != st.issuer ) { - SEND_INLINE_ACTION( *this, transfer, {st.issuer,N(active)}, {st.issuer, to, quantity, memo} ); + SEND_INLINE_ACTION( *this, transfer, { {st.issuer, "active"_n} }, + { st.issuer, to, quantity, memo } + ); } } From 7e429e702594c1d96504a7ba43445536de71542b Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 2 Oct 2018 11:53:58 -0400 Subject: [PATCH 0558/1048] add versioning and require_auth to system contract init action --- eosio.system/abi/eosio.system.abi | 1 + eosio.system/include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/eosio.system.cpp | 5 ++++- tests/eosio.msig_tests.cpp | 8 ++++++-- tests/eosio.system_tester.hpp | 4 +++- 5 files changed, 15 insertions(+), 5 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index c7b6e3cd..d9610336 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -28,6 +28,7 @@ "name": "init", "base": "", "fields": [ + {"name":"version", "type": "varuint32"}, {"name":"core", "type":"symbol"} ] },{ diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 62850d6b..d23efc71 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -204,7 +204,7 @@ namespace eosiosystem { symbol_type core_symbol()const; // Actions: - void init( symbol_type core ); + void init( unsigned_int version, symbol_type core ); void onblock( block_timestamp timestamp, account_name producer ); // const block_header& header ); /// only parse first 3 fields of block header diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index cbb49954..fb33da68 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -294,7 +294,10 @@ namespace eosiosystem { } } - void system_contract::init( symbol_type core ) { + void system_contract::init( unsigned_int version, symbol_type core ) { + require_auth( _self ); + eosio_assert( version.value == 0, "unsupported version for init action" ); + auto itr = _rammarket.find(S(4,RAMCORE)); eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 609a2715..a5e3a830 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -415,7 +415,9 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) set_abi( config::system_account_name, contracts::system_abi().data() ); base_tester::push_action( config::system_account_name, N(init), config::system_account_name, mutable_variant_object() - ("core", CORE_SYM_STR) ); + ("version", 0) + ("core", CORE_SYM_STR) + ); produce_blocks(); create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); @@ -527,7 +529,9 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester set_abi( config::system_account_name, contracts::system_abi().data() ); base_tester::push_action( config::system_account_name, N(init), config::system_account_name, mutable_variant_object() - ("core", CORE_SYM_STR) ); + ("version", 0) + ("core", CORE_SYM_STR) + ); produce_blocks(); create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 6589a73d..1d26caef 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -63,7 +63,9 @@ class eosio_system_tester : public TESTER { if( call_init ) { base_tester::push_action(config::system_account_name, N(init), config::system_account_name, mutable_variant_object() - ("core", CORE_SYM_STR)); + ("version", 0) + ("core", CORE_SYM_STR) + ); } { From aedf2cda7bf68e0f9d582b655dcad5a36b879fda Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 2 Oct 2018 17:11:28 -0400 Subject: [PATCH 0559/1048] fixes for new symbol types --- .../include/eosio.system/eosio.system.hpp | 5 +- .../include/eosio.system/exchange_state.hpp | 4 +- eosio.system/src/delegate_bandwidth.cpp | 72 +++++++++---------- eosio.system/src/eosio.system.cpp | 12 ++-- eosio.system/src/exchange_state.cpp | 2 +- eosio.system/src/producer_pay.cpp | 12 ++-- .../include/eosio.token/eosio.token.hpp | 22 +++--- eosio.token/src/eosio.token.cpp | 34 ++++----- 8 files changed, 83 insertions(+), 80 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 9cfa8a6d..41d5af64 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -171,7 +171,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr symbol system_token_symbol = symbol(4, "SYS"); + static constexpr symbol system_token_symbol = symbol(4, "SYS"_s); class system_contract : public native { private: @@ -190,6 +190,9 @@ namespace eosiosystem { system_contract( account_name s ); ~system_contract(); + static constexpr symbol ramcore_symbol = symbol(4, "RAMCORE"_s); + static constexpr symbol ram_symbol = symbol(0, "RAM"_s); + // Actions: void onblock( block_timestamp timestamp, account_name producer ); // const block_header& header ); /// only parse first 3 fields of block header diff --git a/eosio.system/include/eosio.system/exchange_state.hpp b/eosio.system/include/eosio.system/exchange_state.hpp index 4056026e..26c866cf 100644 --- a/eosio.system/include/eosio.system/exchange_state.hpp +++ b/eosio.system/include/eosio.system/exchange_state.hpp @@ -26,11 +26,11 @@ namespace eosiosystem { connector base; connector quote; - uint64_t primary_key()const { return supply.symbol; } + uint64_t primary_key()const { return supply.symbol.code().raw(); } asset convert_to_exchange( connector& c, asset in ); asset convert_from_exchange( connector& c, asset in ); - asset convert( asset from, symbol to ); + asset convert( asset from, const symbol& to ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) }; diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 7a94c5d2..82f60293 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -88,9 +88,9 @@ namespace eosiosystem { */ void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { - auto itr = _rammarket.find(symbol(4, "RAMCORE")); + auto itr = _rammarket.find(ramcore_symbol.raw()); auto tmp = *itr; - auto eosout = tmp.convert( asset(bytes,symbol(0, "RAM")), symbol(4, "SYS") ); + auto eosout = tmp.convert( asset(bytes, ram_symbol), symbol(4, "SYS"_s) ); buyram( payer, receiver, eosout ); } @@ -131,9 +131,9 @@ namespace eosiosystem { int64_t bytes_out; - const auto& market = _rammarket.get(symbol(4, "RAMCORE"), "ram market does not exist"); + const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); _rammarket.modify( market, 0, [&]( auto& es ) { - bytes_out = es.convert( quant_after_fee, symbol(0, "RAM") ).amount; + bytes_out = es.convert( quant_after_fee, ram_symbol ).amount; }); eosio_assert( bytes_out > 0, "must reserve a positive amount" ); @@ -174,10 +174,10 @@ namespace eosiosystem { eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; - auto itr = _rammarket.find(symbol(4, "RAMCORE")); + auto itr = _rammarket.find(ramcore_symbol.raw()); _rammarket.modify( itr, 0, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(bytes,symbol(0, "RAM")), symbol(4, "SYS")); + tokens_out = es.convert( asset(bytes,ram_symbol), symbol(4, "SYS"_s)); }); eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); @@ -200,7 +200,7 @@ namespace eosiosystem { // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount if( fee > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, - { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); + { account, N(eosio.ramfee), asset(fee, symbol(4, "SYS"_s)), std::string("sell ram fee") } ); } } @@ -216,7 +216,7 @@ namespace eosiosystem { const asset stake_net_delta, const asset stake_cpu_delta, bool transfer ) { require_auth( from ); - eosio_assert( stake_net_delta != asset(0) || stake_cpu_delta != asset(0), "should stake non-zero amount" ); + eosio_assert( stake_net_delta != asset(0, symbol(4, "SYS"_s)) || stake_cpu_delta != asset(0, symbol(4, "SYS"_s)), "should stake non-zero amount" ); eosio_assert( std::abs( (stake_net_delta + stake_cpu_delta).amount ) >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), "net and cpu deltas cannot be opposite signs" ); @@ -244,9 +244,9 @@ namespace eosiosystem { dbo.cpu_weight += stake_cpu_delta; }); } - eosio_assert( asset(0) <= itr->net_weight, "insufficient staked net bandwidth" ); - eosio_assert( asset(0) <= itr->cpu_weight, "insufficient staked cpu bandwidth" ); - if ( itr->net_weight == asset(0) && itr->cpu_weight == asset(0) ) { + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= itr->net_weight, "insufficient staked net bandwidth" ); + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= itr->cpu_weight, "insufficient staked cpu bandwidth" ); + if ( itr->net_weight == asset(0, symbol(4, "SYS"_s)) && itr->cpu_weight == asset(0, symbol(4, "SYS"_s)) ) { del_tbl.erase( itr ); } } // itr can be invalid, should go out of scope @@ -267,15 +267,15 @@ namespace eosiosystem { tot.cpu_weight += stake_cpu_delta; }); } - eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); - eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); int64_t ram_bytes, net, cpu; get_resource_limits( receiver, &ram_bytes, &net, &cpu ); set_resource_limits( receiver, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - if ( tot_itr->net_weight == asset(0) && tot_itr->cpu_weight == asset(0) && tot_itr->ram_bytes == 0 ) { + if ( tot_itr->net_weight == asset(0, symbol(4, "SYS"_s)) && tot_itr->cpu_weight == asset(0, symbol(4, "SYS"_s)) && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); } } // tot_itr can be invalid, should go out of scope @@ -299,44 +299,44 @@ namespace eosiosystem { if( is_delegating_to_self || is_undelegating ) { if ( req != refunds_tbl.end() ) { //need to update refund refunds_tbl.modify( req, 0, [&]( refund_request& r ) { - if ( net_balance < asset(0) || cpu_balance < asset(0) ) { + if ( net_balance < asset(0, symbol(4, "SYS"_s)) || cpu_balance < asset(0, symbol(4, "SYS"_s)) ) { r.request_time = now(); } r.net_amount -= net_balance; - if ( r.net_amount < asset(0) ) { + if ( r.net_amount < asset(0, symbol(4, "SYS"_s)) ) { net_balance = -r.net_amount; - r.net_amount = asset(0); + r.net_amount = asset(0, symbol(4, "SYS"_s)); } else { - net_balance = asset(0); + net_balance = asset(0, symbol(4, "SYS"_s)); } r.cpu_amount -= cpu_balance; - if ( r.cpu_amount < asset(0) ){ + if ( r.cpu_amount < asset(0, symbol(4, "SYS"_s)) ){ cpu_balance = -r.cpu_amount; - r.cpu_amount = asset(0); + r.cpu_amount = asset(0, symbol(4, "SYS"_s)); } else { - cpu_balance = asset(0); + cpu_balance = asset(0, symbol(4, "SYS"_s)); } }); - eosio_assert( asset(0) <= req->net_amount, "negative net refund amount" ); //should never happen - eosio_assert( asset(0) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= req->net_amount, "negative net refund amount" ); //should never happen + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= req->cpu_amount, "negative cpu refund amount" ); //should never happen - if ( req->net_amount == asset(0) && req->cpu_amount == asset(0) ) { + if ( req->net_amount == asset(0, symbol(4, "SYS"_s)) && req->cpu_amount == asset(0, symbol(4, "SYS"_s)) ) { refunds_tbl.erase( req ); need_deferred_trx = false; } else { need_deferred_trx = true; } - } else if ( net_balance < asset(0) || cpu_balance < asset(0) ) { //need to create refund + } else if ( net_balance < asset(0, symbol(4, "SYS"_s)) || cpu_balance < asset(0, symbol(4, "SYS"_s)) ) { //need to create refund refunds_tbl.emplace( from, [&]( refund_request& r ) { r.owner = from; - if ( net_balance < asset(0) ) { + if ( net_balance < asset(0, symbol(4, "SYS"_s)) ) { r.net_amount = -net_balance; - net_balance = asset(0); + net_balance = asset(0, symbol(4, "SYS"_s)); } // else r.net_amount = 0 by default constructor - if ( cpu_balance < asset(0) ) { + if ( cpu_balance < asset(0, symbol(4, "SYS"_s)) ) { r.cpu_amount = -cpu_balance; - cpu_balance = asset(0); + cpu_balance = asset(0, symbol(4, "SYS"_s)); } // else r.cpu_amount = 0 by default constructor r.request_time = now(); }); @@ -355,7 +355,7 @@ namespace eosiosystem { } auto transfer_amount = net_balance + cpu_balance; - if ( asset(0) < transfer_amount ) { + if ( asset(0, symbol(4, "SYS"_s)) < transfer_amount ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {source_stake_from, N(active)}, { source_stake_from, N(eosio.stake), asset(transfer_amount), std::string("stake bandwidth") } ); } @@ -390,9 +390,9 @@ namespace eosiosystem { asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ) { - eosio_assert( stake_cpu_quantity >= asset(0), "must stake a positive amount" ); - eosio_assert( stake_net_quantity >= asset(0), "must stake a positive amount" ); - eosio_assert( stake_net_quantity + stake_cpu_quantity > asset(0), "must stake a positive amount" ); + eosio_assert( stake_cpu_quantity >= asset(0, symbol(4, "SYS"_s)), "must stake a positive amount" ); + eosio_assert( stake_net_quantity >= asset(0, symbol(4, "SYS"_s)), "must stake a positive amount" ); + eosio_assert( stake_net_quantity + stake_cpu_quantity > asset(0, symbol(4, "SYS"_s)), "must stake a positive amount" ); eosio_assert( !transfer || from != receiver, "cannot use transfer flag if delegating to self" ); changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); } // delegatebw @@ -400,9 +400,9 @@ namespace eosiosystem { void system_contract::undelegatebw( account_name from, account_name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ) { - eosio_assert( asset() <= unstake_cpu_quantity, "must unstake a positive amount" ); - eosio_assert( asset() <= unstake_net_quantity, "must unstake a positive amount" ); - eosio_assert( asset() < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= unstake_cpu_quantity, "must unstake a positive amount" ); + eosio_assert( asset(0, symbol(4, "SYS"_s)) <= unstake_net_quantity, "must unstake a positive amount" ); + eosio_assert( asset(0, symbol(4, "SYS"_s)) < unstake_cpu_quantity + unstake_net_quantity, "must unstake a positive amount" ); eosio_assert( _gstate.total_activated_stake >= min_activated_stake, "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index bea2c4ed..1459c228 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -25,18 +25,18 @@ namespace eosiosystem { _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; - auto itr = _rammarket.find(symbol(4, "RAMCORE")); + auto itr = _rammarket.find(ramcore_symbol.raw()); if( itr == _rammarket.end() ) { auto system_token_supply = eosio::token(N(eosio.token)).get_supply(eosio::symbol(system_token_symbol)).amount; if( system_token_supply > 0 ) { itr = _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; - m.supply.symbol = symbol(4, "RAMCORE"); + m.supply.symbol = ramcore_symbol; m.base.balance.amount = int64_t(_gstate.free_ram()); - m.base.balance.symbol = symbol(0, "RAM"); + m.base.balance.symbol = ram_symbol; m.quote.balance.amount = system_token_supply / 1000; - m.quote.balance.symbol = symbol(4, "SYS"); + m.quote.balance.symbol = symbol(4, "SYS"_s); }); } } else { @@ -74,7 +74,7 @@ namespace eosiosystem { eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size); - auto itr = _rammarket.find(symbol(4, "RAMCORE")); + auto itr = _rammarket.find(ramcore_symbol.raw()); /** * Increase the amount of ram for sale based upon the change in max ram size. @@ -91,7 +91,7 @@ namespace eosiosystem { if( cbt <= _gstate2.last_ram_increase ) return; - auto itr = _rammarket.find(symbol(4, "RAMCORE")); + auto itr = _rammarket.find(ramcore_symbol.raw()); auto new_ram = (cbt.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; _gstate.max_ram_size += new_ram; diff --git a/eosio.system/src/exchange_state.cpp b/eosio.system/src/exchange_state.cpp index 2612c884..28b43de7 100644 --- a/eosio.system/src/exchange_state.cpp +++ b/eosio.system/src/exchange_state.cpp @@ -43,7 +43,7 @@ namespace eosiosystem { return asset( out, c.balance.symbol ); } - asset exchange_state::convert( asset from, symbol to ) { + asset exchange_state::convert( asset from, const symbol& to ) { auto sell_symbol = from.symbol; auto ex_symbol = supply.symbol; auto base_symbol = base.balance.symbol; diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 7a2156fd..b0ecf1b2 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -96,16 +96,16 @@ namespace eosiosystem { auto to_per_vote_pay = to_producers - to_per_block_pay; INLINE_ACTION_SENDER(eosio::token, issue)( N(eosio.token), {{N(eosio),N(active)}}, - { N(eosio), asset(new_tokens), std::string("issue tokens for producer pay and savings") } ); + { N(eosio), asset(new_tokens, symbol(4,"SYS"_s)), std::string("issue tokens for producer pay and savings") } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.saving), asset(to_savings), "unallocated inflation" } ); + { N(eosio), N(eosio.saving), asset(to_savings, symbol(4, "SYS"_s)), "unallocated inflation" } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.bpay), asset(to_per_block_pay), "fund per-block bucket" } ); + { N(eosio), N(eosio.bpay), asset(to_per_block_pay, symbol(4, "SYS"_s)), "fund per-block bucket" } ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio),N(active)}, - { N(eosio), N(eosio.vpay), asset(to_per_vote_pay), "fund per-vote bucket" } ); + { N(eosio), N(eosio.vpay), asset(to_per_vote_pay, symbol(4, "SYS"_s)), "fund per-vote bucket" } ); _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; @@ -176,11 +176,11 @@ namespace eosiosystem { if( producer_per_block_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.bpay),N(active)},{owner,N(active)}}, - { N(eosio.bpay), owner, asset(producer_per_block_pay), std::string("producer block pay") } ); + { N(eosio.bpay), owner, asset(producer_per_block_pay, symbol(4, "SYS"_s)), std::string("producer block pay") } ); } if( producer_per_vote_pay > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {{N(eosio.vpay),N(active)},{owner,N(active)}}, - { N(eosio.vpay), owner, asset(producer_per_vote_pay), std::string("producer vote pay") } ); + { N(eosio.vpay), owner, asset(producer_per_vote_pay, symbol(4, "SYS"_s)), std::string("producer vote pay") } ); } } diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 9871b97c..d145abc9 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -33,19 +33,19 @@ namespace eosio { asset quantity, string memo ); - void open( account_name owner, symbol symbol, account_name payer ); + void open( account_name owner, const symbol& symbol, account_name payer ); - void close( account_name owner, symbol symbol ); + void close( account_name owner, const symbol& symbol ); - inline asset get_supply( symbol sym )const; + inline asset get_supply( const symbol& sym )const; - inline asset get_balance( account_name owner, symbol sym )const; + inline asset get_balance( account_name owner, const symbol& sym )const; private: struct account { asset balance; - uint64_t primary_key()const { return balance.symbol.name(); } + uint64_t primary_key()const { return balance.symbol.raw(); } }; struct currency_stats { @@ -53,7 +53,7 @@ namespace eosio { asset max_supply; account_name issuer; - uint64_t primary_key()const { return supply.symbol.name(); } + uint64_t primary_key()const { return supply.symbol.raw(); } }; typedef eosio::multi_index accounts; @@ -71,17 +71,17 @@ namespace eosio { }; }; - asset token::get_supply( symbol sym )const + asset token::get_supply( const symbol& sym )const { - stats statstable( _self, sym ); - const auto& st = statstable.get( sym ); + stats statstable( _self, sym.raw() ); + const auto& st = statstable.get( sym.raw() ); return st.supply; } - asset token::get_balance( account_name owner, symbol sym )const + asset token::get_balance( account_name owner, const symbol& sym )const { accounts accountstable( _self, owner ); - const auto& ac = accountstable.get( sym ); + const auto& ac = accountstable.get( sym.raw() ); return ac.balance; } diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index eb22c0a5..968726c7 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -17,8 +17,8 @@ void token::create( account_name issuer, eosio_assert( maximum_supply.is_valid(), "invalid supply"); eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); - stats statstable( _self, sym.name() ); - auto existing = statstable.find( sym.name() ); + stats statstable( _self, sym.code().raw() ); + auto existing = statstable.find( sym.code().raw() ); eosio_assert( existing == statstable.end(), "token with symbol already exists" ); statstable.emplace( _self, [&]( auto& s ) { @@ -35,9 +35,9 @@ void token::issue( account_name to, asset quantity, string memo ) eosio_assert( sym.is_valid(), "invalid symbol name" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); - auto sym_name = sym.name(); - stats statstable( _self, sym_name ); - auto existing = statstable.find( sym_name ); + auto sym_name = sym.code(); + stats statstable( _self, sym_name.raw() ); + auto existing = statstable.find( sym_name.raw() ); eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); const auto& st = *existing; @@ -65,9 +65,9 @@ void token::retire( asset quantity, string memo ) eosio_assert( sym.is_valid(), "invalid symbol name" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); - auto sym_name = sym.name(); - stats statstable( _self, sym_name ); - auto existing = statstable.find( sym_name ); + auto sym_name = sym.code(); + stats statstable( _self, sym_name.raw() ); + auto existing = statstable.find( sym_name.raw() ); eosio_assert( existing != statstable.end(), "token with symbol does not exist" ); const auto& st = *existing; @@ -92,9 +92,9 @@ void token::transfer( account_name from, eosio_assert( from != to, "cannot transfer to self" ); require_auth( from ); eosio_assert( is_account( to ), "to account does not exist"); - auto sym = quantity.symbol.name(); - stats statstable( _self, sym ); - const auto& st = statstable.get( sym ); + auto sym = quantity.symbol.code(); + stats statstable( _self, sym.raw() ); + const auto& st = statstable.get( sym.raw() ); require_recipient( from ); require_recipient( to ); @@ -113,7 +113,7 @@ void token::transfer( account_name from, void token::sub_balance( account_name owner, asset value ) { accounts from_acnts( _self, owner ); - const auto& from = from_acnts.get( value.symbol.name(), "no balance object found" ); + const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" ); eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); from_acnts.modify( from, owner, [&]( auto& a ) { @@ -124,7 +124,7 @@ void token::sub_balance( account_name owner, asset value ) { void token::add_balance( account_name owner, asset value, account_name ram_payer ) { accounts to_acnts( _self, owner ); - auto to = to_acnts.find( value.symbol.name() ); + auto to = to_acnts.find( value.symbol.code().raw() ); if( to == to_acnts.end() ) { to_acnts.emplace( ram_payer, [&]( auto& a ){ a.balance = value; @@ -136,11 +136,11 @@ void token::add_balance( account_name owner, asset value, account_name ram_payer } } -void token::open( account_name owner, symbol symbol, account_name ram_payer ) +void token::open( account_name owner, const symbol& symbol, account_name ram_payer ) { require_auth( ram_payer ); accounts acnts( _self, owner ); - auto it = acnts.find( symbol.name() ); + auto it = acnts.find( symbol.code().raw() ); if( it == acnts.end() ) { acnts.emplace( ram_payer, [&]( auto& a ){ a.balance = asset{0, symbol}; @@ -148,11 +148,11 @@ void token::open( account_name owner, symbol symbol, account_name ram_payer ) } } -void token::close( account_name owner, symbol symbol ) +void token::close( account_name owner, const symbol& symbol ) { require_auth( owner ); accounts acnts( _self, owner ); - auto it = acnts.find( symbol.name() ); + auto it = acnts.find( symbol.code().raw() ); eosio_assert( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); eosio_assert( it->balance.amount == 0, "Cannot close because the balance is not zero." ); acnts.erase( it ); From ae8b5329453a63e16b24975bd8a69a9bcbfc42c4 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 2 Oct 2018 18:32:05 -0400 Subject: [PATCH 0560/1048] correct eosiosystem::authority struct #86 --- eosio.system/include/eosio.system/native.hpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index 476da787..b8edd22c 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -28,21 +28,29 @@ namespace eosiosystem { }; struct key_weight { - public_key key; - weight_type weight; + eosio::public_key key; + weight_type weight; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( key_weight, (key)(weight) ) }; + struct wait_weight { + uint32_t wait_sec; + weight_type weight; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) + }; + struct authority { - uint32_t threshold; - uint32_t delay_sec; + uint32_t threshold = 0; std::vector keys; std::vector accounts; + std::vector waits; // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( authority, (threshold)(delay_sec)(keys)(accounts) ) + EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) }; struct block_header { From b2392282d0bddad54b87509216c57cdae545fc63 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 2 Oct 2018 18:32:27 -0400 Subject: [PATCH 0561/1048] cleanup eosio.system.abi #78 --- eosio.system/abi/eosio.system.abi | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 9855e669..6980ea72 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -236,7 +236,6 @@ "name": "blockchain_parameters", "base": "", "fields": [ - {"name":"max_block_net_usage", "type":"uint64"}, {"name":"target_block_net_usage_pct", "type":"uint32"}, {"name":"max_transaction_net_usage", "type":"uint32"}, @@ -257,6 +256,7 @@ ] },{ "name": "eosio_global_state2", + "base": "", "fields": [ {"name":"new_ram_per_block", "type":"uint16"}, {"name":"last_ram_increase", "type":"block_timestamp_type"}, @@ -266,6 +266,7 @@ ] },{ "name": "eosio_global_state3", + "base": "", "fields": [ {"name":"last_vpay_state_update", "type":"time_point"}, {"name":"total_vpay_share_change_rate", "type":"float64"} From 2901a8a6d25aedd06bd266854562f09dbddd544e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 2 Oct 2018 19:12:14 -0400 Subject: [PATCH 0562/1048] REX loan testing - 2 --- eosio.system/abi/eosio.system.abi | 2 +- tests/eosio.system_tester.hpp | 14 ++++ tests/eosio.system_tests.cpp | 102 +++++++++++++++++++++++------- 3 files changed, 93 insertions(+), 25 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index e554bc0c..423de9e4 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -257,7 +257,7 @@ {"name":"from", "type":"account_name"}, {"name":"receiver", "type":"account_name"}, {"name":"loan_payment", "type":"asset"}, - {"name":"total_stake", "type":"asset"}, + {"name":"total_staked", "type":"asset"}, {"name":"loan_num", "type":"uint64"}, {"name":"expiration", "type":"time_point"}, {"name":"auto_renew", "type":"bool"}, diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 1d87e43a..a20e92d6 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -352,6 +352,20 @@ class eosio_system_tester : public TESTER { return get_last_loan( false ); } + fc::variant get_loan_info( const uint64_t& loan_num, bool cpu ) const { + name table_name = cpu ? N(cpuloan) : N(netloan); + vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, loan_num ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer_max_time ); + } + + fc::variant get_cpu_loan( const uint64_t loan_num ) const { + return get_loan_info( loan_num, true ); + } + + fc::variant get_net_loan( const uint64_t loan_num ) const { + return get_loan_info( loan_num, false ); + } + asset get_rex_balance( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 23fe6bcc..0ab8b396 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3638,8 +3638,18 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; + auto get_net_limit = [&](account_name a) -> int64_t { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return net; + }; + auto get_cpu_limit = [&](account_name a) -> int64_t { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return cpu; + }; + const int64_t ratio = 10000; - cross_15_percent_threshold(); const asset net = core_from_string("80.0000"); const asset cpu = core_from_string("80.0000"); const asset init_balance = core_from_string("10000.0000"); @@ -3651,43 +3661,87 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); } - const asset payment = core_from_string("30.0000"); - asset cur_frank_balance = get_balance( frank ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("500.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, payment, true ) ); - auto loan_info = get_last_cpu_loan(); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("500.0000") ) ); + + auto rex_pool = get_rex_pool(); + const asset payment = core_from_string("30.0000"); + asset cur_frank_balance = get_balance( frank ); + int64_t expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount(), + rex_pool["total_unlent"].as().get_amount(), + payment.get_amount() ); + const int64_t init_stake = get_cpu_limit( frank ); + + // frank rents cpu for bob + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, payment, true ) ); // loan_num = 1 + BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment, false ) ); // loan_num = 2 + BOOST_REQUIRE_EQUAL( 2, get_last_cpu_loan()["loan_num"].as_uint64() ); + + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, emily, payment, false ) ); // loan_num = 3 + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, alice, payment, false ) ); // loan_num = 4 + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, frank, payment, false ) ); // loan_num = 5 + BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); + + auto loan_info = get_cpu_loan(1); auto old_frank_balance = cur_frank_balance; - cur_frank_balance = get_balance( frank ); - BOOST_REQUIRE_EQUAL( old_frank_balance, payment + cur_frank_balance ); - BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); - BOOST_REQUIRE_EQUAL( 0, loan_info["balance"].as().get_amount() ); - + cur_frank_balance = get_balance( frank ); + BOOST_REQUIRE_EQUAL( old_frank_balance, payment + cur_frank_balance ); + BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); + BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + BOOST_REQUIRE_EQUAL( 0, loan_info["balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); + + // frank funds his loan enough to be renewed once const asset fund = core_from_string("35.0000"); BOOST_REQUIRE_EQUAL( success(), fundrexloan( frank, 1, fund, true ) ); old_frank_balance = cur_frank_balance; cur_frank_balance = get_balance( frank ); - loan_info = get_last_cpu_loan(); + loan_info = get_cpu_loan(1); BOOST_REQUIRE_EQUAL( old_frank_balance, fund + cur_frank_balance ); BOOST_REQUIRE_EQUAL( fund, loan_info["balance"].as() ); BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + // wait for 30 days, frank's loan will be renewed at the current price produce_block( fc::hours(30*24 + 1) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("10.0000") ) ); + rex_pool = get_rex_pool(); + { + int64_t unlent_tokens = bancor_convert( rex_pool["total_unlent"].as().get_amount(), + rex_pool["total_rent"].as().get_amount(), + expected_stake ); + + expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount() - unlent_tokens, + rex_pool["total_unlent"].as().get_amount() + expected_stake, + payment.get_amount() ); + } + + BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, asset::from_string("1.0000 REX") ) ); BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); - - loan_info = get_last_cpu_loan(); - BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); - BOOST_REQUIRE_EQUAL( fund - payment, loan_info["balance"].as() ); - + + loan_info = get_cpu_loan(1); + BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + BOOST_REQUIRE_EQUAL( fund - payment, loan_info["balance"].as() ); + BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); + + // check that loans have been processed in order + BOOST_REQUIRE_EQUAL( false, get_cpu_loan(1).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_cpu_loan(2).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_net_loan(3).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_net_loan(4).is_null() ); + BOOST_REQUIRE_EQUAL( false, get_net_loan(5).is_null() ); + BOOST_REQUIRE_EQUAL( 1, get_last_cpu_loan()["loan_num"].as_uint64() ); + BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); + + // wait for another month, frank's loan doesn't have enough funds and will be closed produce_block( fc::hours(30*24) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), claimrefund( frank ) ); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); + BOOST_REQUIRE_EQUAL( init_stake, get_cpu_limit( bob ) ); + BOOST_REQUIRE_EQUAL( success(), claimrefund( frank ) ); old_frank_balance = cur_frank_balance; cur_frank_balance = get_balance( frank ); - BOOST_REQUIRE_EQUAL( fund - payment, cur_frank_balance - old_frank_balance ); - BOOST_REQUIRE (old_frank_balance < cur_frank_balance ); + BOOST_REQUIRE_EQUAL( fund - payment, cur_frank_balance - old_frank_balance ); + BOOST_REQUIRE ( old_frank_balance < cur_frank_balance ); BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); From fc3423f23abe9945501288915057ba0f50ab24d8 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 2 Oct 2018 21:23:58 -0400 Subject: [PATCH 0563/1048] use new definition of symbol and symbol_code --- eosio.system/include/eosio.system/eosio.system.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index bb1f1038..fce1728f 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -16,6 +16,8 @@ namespace eosiosystem { using eosio::asset; + using eosio::symbol; + using eosio::symbol_code; using eosio::indexed_by; using eosio::const_mem_fun; using eosio::block_timestamp; @@ -195,8 +197,8 @@ namespace eosiosystem { static constexpr eosio::name vpay_account{"eosio.vpay"_n}; static constexpr eosio::name names_account{"eosio.names"_n}; static constexpr eosio::name saving_account{"eosio.saving"_n}; - static constexpr symbol ramcore_symbol = symbol(4, "RAMCORE"_s); - static constexpr symbol ram_symbol = symbol(0, "RAM"_s); + static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); + static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); system_contract( account_name s ); ~system_contract(); From 44376ffd2dfb297db01d50d2d0bd8ede50bb9a32 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 3 Oct 2018 10:18:32 -0400 Subject: [PATCH 0564/1048] REX code refactoring --- eosio.system/src/rex.cpp | 153 ++++++++++++++------------------------- 1 file changed, 55 insertions(+), 98 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index de1ae3ae..2c6b65f8 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -288,76 +288,75 @@ namespace eosiosystem { auto rexi = _rextable.begin(); eosio_assert( rexi != _rextable.end(), "rex system not initialized yet" ); - auto unrent = [&]( int64_t rented_tokens ) { + auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { + _rextable.modify( rexi, 0, [&]( auto& rt ) { - auto fee = bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, rented_tokens ); - rt.total_lent.amount -= rented_tokens; + bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, itr->total_staked.amount ); + rt.total_lent.amount -= itr->total_staked.amount; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); + + bool delete_loan = false; + int64_t delta_stake = 0; + if( itr->auto_renew && itr->loan_payment <= itr->balance ) { + + int64_t rented_tokens = 0; + _rextable.modify( rexi, 0, [&]( auto& rt ) { + rented_tokens = bancor_convert( rt.total_rent.amount, + rt.total_unlent.amount, + itr->loan_payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += itr->loan_payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + }); + + idx.modify ( itr, 0, [&]( auto& loan ) { + delta_stake = rented_tokens - loan.total_staked.amount; + loan.total_staked.amount = rented_tokens; + loan.expiration += eosio::days(30); + loan.balance.amount -= loan.loan_payment.amount; + }); + + } else { + delete_loan = true; + delta_stake = -( itr->total_staked.amount ); + // refund "from" account if the closed loan balance is positive + if( itr->auto_renew && itr->balance.amount > 0 ) { + loan_refund_table loan_refunds( _self, _self ); + auto ref_itr = loan_refunds.find( itr->from ); + if( ref_itr == loan_refunds.end() ) { + loan_refunds.emplace( itr->from, [&]( auto& ref ) { + ref.owner = itr->from; + ref.balance = itr->balance; + }); + } else { + loan_refunds.modify( ref_itr, itr->from, [&]( auto& ref ) { + ref.balance.amount += itr->balance.amount; + }); + } + } + } + + return std::make_pair( delete_loan, delta_stake ); }; - // TODO: refactor and remove code duplication { rex_cpu_loan_table cpu_loans( _self, _self ); auto cpu_idx = cpu_loans.get_index(); - bool delete_loan = false; for( uint16_t i = 0; i < max; ++i ) { auto itr = cpu_idx.begin(); if( itr == cpu_idx.end() ) break; if( itr->expiration.elapsed.count() > current_time() ) break; - - // update rex totals to account for closing the loan - unrent( itr->total_staked.amount ); - - int64_t delta_stake = 0; - if( itr->auto_renew && itr->loan_payment <= itr->balance ) { - - int64_t rented_tokens = 0; - _rextable.modify( rexi, 0, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, - rt.total_unlent.amount, - itr->loan_payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += itr->loan_payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - }); - - cpu_idx.modify ( itr, 0, [&]( auto& loan ) { - delta_stake = rented_tokens - loan.total_staked.amount; - loan.total_staked.amount = rented_tokens; - loan.expiration += eosio::days(30); - loan.balance.amount -= loan.loan_payment.amount; - }); - } else { - delete_loan = true; - delta_stake = -( itr->total_staked.amount ); - // refund "from" account if the closed loan balance is positive - if( itr->auto_renew && itr->balance.amount > 0 ) { - loan_refund_table loan_refunds( _self, _self ); - auto ref_itr = loan_refunds.find( itr->from ); - if( ref_itr == loan_refunds.end() ) { - loan_refunds.emplace( itr->from, [&]( auto& ref ) { - ref.owner = itr->from; - ref.balance = itr->balance; - }); - } else { - loan_refunds.modify( ref_itr, itr->from, [&]( auto& ref ) { - ref.balance.amount += itr->balance.amount; - }); - } - } - } - - if( delta_stake != 0 ) - update_resource_limits( itr->receiver, delta_stake, 0 ); + auto result = process_expired_loan( cpu_idx, itr ); + if( result.second != 0 ) + update_resource_limits( itr->receiver, result.second, 0 ); - if( delete_loan ) + if( result.first ) cpu_idx.erase( itr ); } } - // TODO: refactor and remove code duplication { rex_net_loan_table net_loans( _self, _self ); auto net_idx = net_loans.get_index(); @@ -367,53 +366,11 @@ namespace eosiosystem { if( itr == net_idx.end() ) break; if( itr->expiration.elapsed.count() > current_time() ) break; - // update rex totals to account for closing the loan - unrent( itr->total_staked.amount ); - - int64_t delta_stake = 0; - if( itr->auto_renew && itr->loan_payment <= itr->balance ) { - - int64_t rented_tokens = 0; - _rextable.modify( rexi, 0, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, - rt.total_unlent.amount, - itr->loan_payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += itr->loan_payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - }); - - net_idx.modify ( itr, 0, [&]( auto& loan ) { - delta_stake = rented_tokens - loan.total_staked.amount; - loan.total_staked.amount = rented_tokens; - loan.expiration += eosio::days(30); - loan.balance -= itr->loan_payment; - }); - - } else { - delete_loan = true; - delta_stake = -( itr->total_staked.amount ); - // refund "from" account if the closed loan balance is positive - if( itr->auto_renew && itr->balance.amount > 0 ) { - loan_refund_table loan_refunds( _self, _self ); - auto ref_itr = loan_refunds.find( itr->from ); - if( ref_itr == loan_refunds.end() ) { - loan_refunds.emplace( itr->from, [&]( auto& ref ) { - ref.owner = itr->from; - ref.balance = itr->balance; - }); - } else { - loan_refunds.modify( ref_itr, itr->from, [&]( auto& ref ) { - ref.balance.amount += itr->balance.amount; - }); - } - } - } - - if( delta_stake != 0 ) - update_resource_limits( itr->receiver, 0, delta_stake ); + auto result = process_expired_loan( net_idx, itr ); + if( result.second != 0 ) + update_resource_limits( itr->receiver, 0, result.second ); - if( delete_loan ) + if( result.first ) net_idx.erase( itr ); } } From 3cf9b051c68e6e9ab7347c22d7943df82ea350dc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 3 Oct 2018 11:41:15 -0400 Subject: [PATCH 0565/1048] Small REX changes --- .../include/eosio.system/eosio.system.hpp | 9 ++- eosio.system/src/rex.cpp | 67 +++++++++---------- 2 files changed, 40 insertions(+), 36 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index cfb640a5..ff1794eb 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -208,13 +208,18 @@ namespace eosiosystem { uint64_t primary_key()const { return loan_num; } uint64_t by_expr()const { return expiration.elapsed.count(); } + uint64_t by_owner()const { return from; } }; typedef eosio::multi_index< N(cpuloan), rex_loan, - indexed_by>> rex_cpu_loan_table; + indexed_by>, + indexed_by> + > rex_cpu_loan_table; typedef eosio::multi_index< N(netloan), rex_loan, - indexed_by>> rex_net_loan_table; + indexed_by>, + indexed_by> + > rex_net_loan_table; struct loan_refund { account_name owner; diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 2c6b65f8..c73670ae 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -23,8 +23,8 @@ namespace eosiosystem { rex_received.amount = amount.amount * 10000; rp.total_lendable = amount; - rp.total_lent = asset( 0, CORE_SYMBOL ); - rp.total_rent = asset( 1000000, CORE_SYMBOL ); /// base amount prevents renting profitably until at least a minimum number of CORE_SYMBOL are made available + rp.total_lent = asset( 0, system_token_symbol ); + rp.total_rent = asset( 1000000, system_token_symbol ); /// base amount prevents renting profitably until at least a minimum number of system_token_symbol are made available rp.total_rex = rex_received; rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; }); @@ -82,8 +82,8 @@ namespace eosiosystem { auto result = close_rex_order( bitr, rex ); if( std::get<0>(result) ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, - { N(eosio.rex), from, asset( std::get<1>(result), CORE_SYMBOL ), "sell REX" } ); - update_voting_power( from, asset( -(std::get<2>(result)), CORE_SYMBOL ) ); + { N(eosio.rex), from, asset( std::get<1>(result), system_token_symbol ), "sell REX" } ); + update_voting_power( from, asset( -(std::get<2>(result)), system_token_symbol ) ); } else { rex_order_table rexorders( _self, _self ); eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); @@ -113,8 +113,8 @@ namespace eosiosystem { eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); eosio_assert( !itr->is_open, "rex order has not been closed" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, - { N(eosio.rex), itr->owner, asset(itr->proceeds, CORE_SYMBOL), "claim REX proceeds" } ); - update_voting_power( owner, asset( -( itr->unstake_quant ), CORE_SYMBOL ) ); + { N(eosio.rex), itr->owner, asset(itr->proceeds, system_token_symbol), "claim REX proceeds" } ); + update_voting_power( owner, asset( -( itr->unstake_quant ), system_token_symbol ) ); rexorders.erase( itr ); } @@ -188,12 +188,12 @@ namespace eosiosystem { c.from = from; c.receiver = receiver; c.loan_payment = payment; - c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.total_staked = asset( rented_tokens, system_token_symbol ); c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); c.loan_num = itr->loan_num; c.auto_renew = auto_renew; - c.balance = asset( 0, CORE_SYMBOL ); + c.balance = asset( 0, system_token_symbol ); }); update_resource_limits( receiver, rented_tokens, 0 ); @@ -226,18 +226,17 @@ namespace eosiosystem { c.from = from; c.receiver = receiver; c.loan_payment = payment; - c.total_staked = asset( rented_tokens, CORE_SYMBOL ); + c.total_staked = asset( rented_tokens, system_token_symbol ); c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); c.loan_num = itr->loan_num; c.auto_renew = auto_renew; - c.balance = asset( 0, CORE_SYMBOL ); + c.balance = asset( 0, system_token_symbol ); }); update_resource_limits( receiver, 0, rented_tokens ); } - void system_contract::fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ) { require_auth( from ); @@ -299,7 +298,6 @@ namespace eosiosystem { bool delete_loan = false; int64_t delta_stake = 0; if( itr->auto_renew && itr->loan_payment <= itr->balance ) { - int64_t rented_tokens = 0; _rextable.modify( rexi, 0, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, @@ -360,7 +358,6 @@ namespace eosiosystem { { rex_net_loan_table net_loans( _self, _self ); auto net_idx = net_loans.get_index(); - bool delete_loan = false; for( uint16_t i = 0; i < max; ++i ) { auto itr = net_idx.begin(); if( itr == net_idx.end() ) break; @@ -375,27 +372,29 @@ namespace eosiosystem { } } - rex_order_table rexorders( _self, _self ); - auto idx = rexorders.get_index(); - auto oitr = idx.begin(); - for( uint16_t i = 0; i < max; ++i ) { - if( oitr == idx.end() || !oitr->is_open ) break; - auto bitr = _rexbalance.find( oitr->owner ); - // TODO: change the logic below - if( bitr == _rexbalance.end() ) { - idx.erase( oitr++ ); - continue; - } - auto result = close_rex_order( bitr, oitr->rex_requested ); - auto next = oitr; - ++next; - if( std::get<0>( result ) ) { - idx.modify( oitr, 0, [&]( auto& rt ) { - rt.proceeds = std::get<1>( result ); - rt.close(); - }); + { + rex_order_table rex_orders( _self, _self ); + auto idx = rex_orders.get_index(); + auto oitr = idx.begin(); + for( uint16_t i = 0; i < max; ++i ) { + if( oitr == idx.end() || !oitr->is_open ) break; + auto bitr = _rexbalance.find( oitr->owner ); + // TODO: change the logic below + if( bitr == _rexbalance.end() ) { + idx.erase( oitr++ ); + continue; + } + auto result = close_rex_order( bitr, oitr->rex_requested ); + auto next = oitr; + ++next; + if( std::get<0>( result ) ) { + idx.modify( oitr, 0, [&]( auto& rt ) { + rt.proceeds = std::get<1>( result ); + rt.close(); + }); + } + oitr = next; } - oitr = next; } } @@ -406,7 +405,7 @@ namespace eosiosystem { const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; - const int64_t proceeds = S0 - S1; // asset( S0 - S1, CORE_SYMBOL ); + const int64_t proceeds = S0 - S1; // asset( S0 - S1, system_token_symbol ); const int64_t unstake_quant = ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount; bool success = false; if( proceeds <= rexitr->total_unlent.amount ) { From cb7f5fe2321934c307a57a714a484cc73aa2c610 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 3 Oct 2018 17:54:43 -0400 Subject: [PATCH 0566/1048] Transfer ramfee proceeds to rex --- .../include/eosio.system/eosio.system.hpp | 1 + eosio.system/src/delegate_bandwidth.cpp | 6 ++- eosio.system/src/rex.cpp | 51 ++++++++++++------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index ff1794eb..a0ef28a8 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -384,6 +384,7 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + void deposit_rex( const account_name& from, const asset& amount ); // defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 11d4bd82..0023de7b 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -127,8 +127,9 @@ namespace eosiosystem { if( fee.amount > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {payer,N(active)}, { payer, N(eosio.ramfee), fee, std::string("ram fee") } ); + deposit_rex( N(eosio.ramfee), fee ); } - + int64_t bytes_out; const auto& market = _rammarket.get(S(4,RAMCORE), "ram market does not exist"); @@ -200,7 +201,8 @@ namespace eosiosystem { // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount if( fee > 0 ) { INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {account,N(active)}, - { account, N(eosio.ramfee), asset(fee), std::string("sell ram fee") } ); + { account, N(eosio.ramfee), asset(fee, system_token_symbol), std::string("sell ram fee") } ); + deposit_rex( N(eosio.ramfee), asset(fee, system_token_symbol) ); } } diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index c73670ae..c47319b8 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -1,17 +1,19 @@ /** - * @copyright defined in eos/LICENSE.txt + * @copyright defined in eos/LICENSE.txt */ #include namespace eosiosystem { - + /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ void system_contract::lendrex( account_name from, asset amount ) { + require_auth( from ); + eosio_assert( amount.symbol == system_token_symbol, "asset must be system token" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), amount, "buy REX" } ); @@ -22,11 +24,11 @@ namespace eosiosystem { _rextable.emplace( _self, [&]( auto& rp ){ rex_received.amount = amount.amount * 10000; - rp.total_lendable = amount; - rp.total_lent = asset( 0, system_token_symbol ); - rp.total_rent = asset( 1000000, system_token_symbol ); /// base amount prevents renting profitably until at least a minimum number of system_token_symbol are made available - rp.total_rex = rex_received; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + rp.total_lendable = amount; + rp.total_lent = asset( 0, system_token_symbol ); + rp.total_rent = asset( 1000000, system_token_symbol ); /// base amount prevents renting profitably until at least a minimum number of system_token_symbol are made available + rp.total_rex = rex_received; + rp.total_unlent = rp.total_lendable - rp.total_lent; }); } else { const auto S0 = itr->total_lendable.amount; @@ -149,8 +151,8 @@ namespace eosiosystem { tot.cpu_weight.amount += delta_cpu; tot.net_weight.amount += delta_net; }); - eosio_assert( asset(0) <= tot_itr->net_weight, "insufficient staked total net bandwidth" ); - eosio_assert( asset(0) <= tot_itr->cpu_weight, "insufficient staked total cpu bandwidth" ); + eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); + eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); int64_t ram_bytes, net, cpu; get_resource_limits( receiver, &ram_bytes, &net, &cpu ); @@ -167,6 +169,7 @@ namespace eosiosystem { runrex(2); + eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), payment, string("rent CPU") } ); @@ -189,7 +192,7 @@ namespace eosiosystem { c.receiver = receiver; c.loan_payment = payment; c.total_staked = asset( rented_tokens, system_token_symbol ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.expiration = current_time_point() + eosio::days(30); c.loan_num = itr->loan_num; c.auto_renew = auto_renew; @@ -205,6 +208,7 @@ namespace eosiosystem { runrex(2); + eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), payment, string("rent NET") } ); @@ -227,7 +231,7 @@ namespace eosiosystem { c.receiver = receiver; c.loan_payment = payment; c.total_staked = asset( rented_tokens, system_token_symbol ); - c.expiration = eosio::time_point( eosio::microseconds(current_time() + eosio::days(30).count()) ); + c.expiration = current_time_point() + eosio::days(30); c.loan_num = itr->loan_num; c.auto_renew = auto_renew; @@ -241,6 +245,7 @@ namespace eosiosystem { require_auth( from ); + eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), payment, string("fund ") + (cpu ? "CPU loan" : "NET loan") } ); // TODO: refactor and remove code duplication @@ -248,7 +253,7 @@ namespace eosiosystem { rex_cpu_loan_table cpu_loans( _self, _self ); auto itr = cpu_loans.find( loan_num ); eosio_assert( itr != cpu_loans.end(), "loan not found" ); - eosio_assert( itr->from, "actor has to be loan creator" ); + eosio_assert( itr->from == from, "actor has to be loan creator" ); eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); cpu_loans.modify( itr, 0, [&]( auto& loan ) { @@ -258,7 +263,7 @@ namespace eosiosystem { rex_net_loan_table net_loans( _self, _self ); auto itr = net_loans.find( loan_num ); eosio_assert( itr != net_loans.end(), "loan not found" ); - eosio_assert( itr->from, "actor has to be loan creator" ); + eosio_assert( itr->from == from, "actor has to be loan creator" ); eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); net_loans.modify( itr, 0, [&]( auto& loan ) { @@ -288,7 +293,6 @@ namespace eosiosystem { eosio_assert( rexi != _rextable.end(), "rex system not initialized yet" ); auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { - _rextable.modify( rexi, 0, [&]( auto& rt ) { bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, itr->total_staked.amount ); rt.total_lent.amount -= itr->total_staked.amount; @@ -343,8 +347,7 @@ namespace eosiosystem { auto cpu_idx = cpu_loans.get_index(); for( uint16_t i = 0; i < max; ++i ) { auto itr = cpu_idx.begin(); - if( itr == cpu_idx.end() ) break; - if( itr->expiration.elapsed.count() > current_time() ) break; + if( itr == cpu_idx.end() || itr->expiration > current_time_point() ) break; auto result = process_expired_loan( cpu_idx, itr ); if( result.second != 0 ) @@ -360,8 +363,7 @@ namespace eosiosystem { auto net_idx = net_loans.get_index(); for( uint16_t i = 0; i < max; ++i ) { auto itr = net_idx.begin(); - if( itr == net_idx.end() ) break; - if( itr->expiration.elapsed.count() > current_time() ) break; + if( itr == net_idx.end() || itr->expiration > current_time_point() ) break; auto result = process_expired_loan( net_idx, itr ); if( result.second != 0 ) @@ -423,4 +425,17 @@ namespace eosiosystem { return std::make_tuple( success, proceeds, unstake_quant ); } + void system_contract::deposit_rex( const account_name& from, const asset& amount ) { + auto itr = _rextable.begin(); + if( itr != _rextable.end() ) { + _rextable.modify( itr, 0, [&]( auto& rp ) { + rp.total_unlent.amount += amount.amount; + rp.total_lendable.amount += rp.total_unlent.amount + rp.total_lent.amount; + }); + + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { from, N(active) }, + { from, N(eosio.rex), amount, std::string("ram fee") } ); + } + } + }; /// namespace eosiosystem From 79cc91ae77dddb1308f321649d0f537700447255 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 3 Oct 2018 18:20:15 -0400 Subject: [PATCH 0567/1048] Transfer namebid proceeds to rex --- eosio.system/abi/eosio.system.abi | 13 +++++++------ eosio.system/include/eosio.system/eosio.system.hpp | 1 + eosio.system/src/producer_pay.cpp | 6 ++++++ eosio.system/src/rex.cpp | 8 ++++++++ 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 423de9e4..68415ab1 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -243,12 +243,13 @@ "name": "rex_pool", "base": "", "fields": [ - {"name":"total_lent", "type":"asset"}, - {"name":"total_unlent", "type":"asset"}, - {"name":"total_rent", "type":"asset"}, - {"name":"total_lendable", "type":"asset"}, - {"name":"total_rex", "type":"asset"}, - {"name":"loan_num", "type":"uint64"} + {"name":"total_lent", "type":"asset"}, + {"name":"total_unlent", "type":"asset"}, + {"name":"total_rent", "type":"asset"}, + {"name":"total_lendable", "type":"asset"}, + {"name":"total_rex", "type":"asset"}, + {"name":"namebid_proceeds", "type":"asset"}, + {"name":"loan_num", "type":"uint64"} ] },{ "name": "rex_loan", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index a0ef28a8..04bfa2d2 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -179,6 +179,7 @@ namespace eosiosystem { asset total_rent; /// fees received in exchange for lent (connector) asset total_lendable; /// total EOS that have been lent (total_unlent + total_lent) asset total_rex; /// total number of REX shares allocated to contributors to total_lendable + asset namebid_proceeds; uint64_t loan_num = 0; /// increments with each new loan uint64_t primary_key()const { return 0; } }; diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index e71693d1..8b8b9620 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -62,6 +62,12 @@ namespace eosiosystem { (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) ) { _gstate.last_name_close = timestamp; + auto rex_itr = _rextable.begin(); + if( rex_itr != _rextable.end() ) { + _rextable.modify( rex_itr, 0, [&]( auto& rp ) { + rp.namebid_proceeds.amount += highest->high_bid; + }); + } idx.modify( highest, 0, [&]( auto& b ){ b.high_bid = -b.high_bid; }); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index c47319b8..d2950947 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -342,6 +342,14 @@ namespace eosiosystem { return std::make_pair( delete_loan, delta_stake ); }; + // transfer from eosio.names to eosio.rex + if( rexi->namebid_proceeds.amount > 0 ) { + deposit_rex( N(eosio.names), rexi->namebid_proceeds ); + _rextable.modify( rexi, 0, [&]( auto& rt ) { + rt.namebid_proceeds.amount = 0; + }); + } + { rex_cpu_loan_table cpu_loans( _self, _self ); auto cpu_idx = cpu_loans.get_index(); From c5bd51578e117600a2b06b01ccefcbdd3d1d1412 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 3 Oct 2018 18:39:36 -0400 Subject: [PATCH 0568/1048] cleanup unneeded (bios) structs from system contract ABI --- eosio.system/abi/eosio.system.abi | 38 ------------------------------- 1 file changed, 38 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 6980ea72..8d3401d8 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -16,7 +16,6 @@ "new_type_name": "weight_type", "type": "uint16" }], - "____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.", "structs": [{ "name": "permission_level", "base": "", @@ -398,31 +397,6 @@ {"name":"net_weight", "type":"int64"}, {"name":"cpu_weight", "type":"int64"} ] - },{ - "name": "set_global_limits", - "base": "", - "fields": [ - {"name":"cpu_usec_per_period", "type":"int64"} - ] - },{ - "name": "producer_key", - "base": "", - "fields": [ - {"name":"producer_name", "type":"account_name"}, - {"name":"block_signing_key", "type":"public_key"} - ] - },{ - "name": "set_producers", - "base": "", - "fields": [ - {"name":"schedule", "type":"producer_key[]"} - ] - },{ - "name": "require_auth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"} - ] },{ "name": "setparams", "base": "", @@ -574,18 +548,6 @@ "name": "setalimits", "type": "set_account_limits", "ricardian_contract": "" - },{ - "name": "setglimits", - "type": "set_global_limits", - "ricardian_contract": "" - },{ - "name": "setprods", - "type": "set_producers", - "ricardian_contract": "" - },{ - "name": "reqauth", - "type": "require_auth", - "ricardian_contract": "" },{ "name": "setparams", "type": "setparams", From fbae061e450aa3917f8b63c1d11b8cb37076f7a3 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 3 Oct 2018 19:25:09 -0400 Subject: [PATCH 0569/1048] Test ramfee to rex transfer --- eosio.system/src/rex.cpp | 4 ++-- tests/eosio.system_tests.cpp | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index d2950947..dce63eb1 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -438,11 +438,11 @@ namespace eosiosystem { if( itr != _rextable.end() ) { _rextable.modify( itr, 0, [&]( auto& rp ) { rp.total_unlent.amount += amount.amount; - rp.total_lendable.amount += rp.total_unlent.amount + rp.total_lent.amount; + rp.total_lendable.amount += amount.amount; }); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { from, N(active) }, - { from, N(eosio.rex), amount, std::string("ram fee") } ); + { from, N(eosio.rex), amount, std::string("transfer from ") + name{from}.to_string() + " REX"} ); } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0ab8b396..192130b4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3748,6 +3748,38 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( ramfee_to_rex, eosio_system_tester ) try { + + const int64_t ratio = 10000; + const asset net = core_from_string("80.0000"); + const asset cpu = core_from_string("80.0000"); + const asset init_balance = core_from_string("10000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, init_balance, config::system_account_name ); + BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); + } + + asset cur_ramfee_balance = get_balance( N(eosio.ramfee) ); + BOOST_REQUIRE_EQUAL( success(), buyram( alice, alice, core_from_string("20.0000") ) ); + BOOST_REQUIRE_EQUAL( get_balance( N(eosio.ramfee) ), core_from_string("0.1000") + cur_ramfee_balance ); + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("350.0000") ) ); + cur_ramfee_balance = get_balance( N(eosio.ramfee) ); + asset cur_rex_balance = get_balance( N(eosio.rex) ); + BOOST_REQUIRE_EQUAL( core_from_string("350.0000"), cur_rex_balance ); + BOOST_REQUIRE_EQUAL( success(), buyram( bob, carol, core_from_string("70.0000") ) ); + BOOST_REQUIRE_EQUAL( cur_ramfee_balance, get_balance( N(eosio.ramfee) ) ); + BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_from_string("0.3500") ); + cur_rex_balance = get_balance( N(eosio.rex) ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_lent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); set_code( config::system_account_name, contracts::bios_wasm() ); From afa122e4872bd88fd4dcfa2ad7de41caae284a13 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 3 Oct 2018 21:28:40 -0400 Subject: [PATCH 0570/1048] initial work on updating contracts to use new eosio::name from CDT --- eosio.bios/include/eosio.bios/eosio.bios.hpp | 2 +- eosio.msig/include/eosio.msig/eosio.msig.hpp | 8 ++++---- eosio.sudo/include/eosio.sudo/eosio.sudo.hpp | 2 +- eosio.system/include/eosio.system/eosio.system.hpp | 3 ++- eosio.system/src/eosio.system.cpp | 6 +++--- eosio.token/include/eosio.token/eosio.token.hpp | 2 +- 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 44f1dc80..9ec9779e 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -17,7 +17,7 @@ namespace eosio { class bios : public contract { public: - bios( action_name self ):contract(self){} + bios( name self ):contract(self){} void setpriv( account_name account, uint8_t ispriv ) { require_auth( _self ); diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index f3c74d22..b003a804 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -6,7 +6,7 @@ namespace eosio { class multisig : public contract { public: - multisig( account_name self ):contract(self){} + multisig( name self ):contract(self){} void propose(); void approve( account_name proposer, name proposal_name, permission_level level ); @@ -20,7 +20,7 @@ namespace eosio { name proposal_name; vector packed_transaction; - auto primary_key()const { return proposal_name.value; } + auto primary_key()const { return proposal_name.raw(); } }; typedef eosio::multi_index< "proposal"_n, proposal > proposals; @@ -29,7 +29,7 @@ namespace eosio { vector requested_approvals; vector provided_approvals; - auto primary_key()const { return proposal_name.value; } + auto primary_key()const { return proposal_name.raw(); } }; typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals; @@ -47,7 +47,7 @@ namespace eosio { vector requested_approvals; vector provided_approvals; - auto primary_key()const { return proposal_name.value; } + auto primary_key()const { return proposal_name.raw(); } }; typedef eosio::multi_index< "approvals2"_n, approvals_info > approvals; diff --git a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp index a9656212..4ed435ff 100644 --- a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp +++ b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp @@ -6,7 +6,7 @@ namespace eosio { class sudo : public contract { public: - sudo( account_name self ):contract(self){} + sudo( name self ):contract(self){} void exec(); diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index fce1728f..9f1ed55a 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -15,6 +15,7 @@ namespace eosiosystem { + using eosio::name; using eosio::asset; using eosio::symbol; using eosio::symbol_code; @@ -200,7 +201,7 @@ namespace eosiosystem { static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); - system_contract( account_name s ); + system_contract( name s ); ~system_contract(); static symbol get_core_symbol( const rammarket& rm ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 717696b9..271d8c7c 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -10,7 +10,7 @@ namespace eosiosystem { - system_contract::system_contract( account_name s ) + system_contract::system_contract( name s ) :native(s), _voters(_self,_self), _producers(_self,_self), @@ -158,7 +158,7 @@ namespace eosiosystem { void system_contract::bidname( account_name bidder, account_name newname, asset bid ) { require_auth( bidder ); - eosio_assert( eosio::name_suffix(newname) == newname, "you can only bid on top-level suffix" ); + eosio_assert( name(newname).suffix() == name(newname), "you can only bid on top-level suffix" ); eosio_assert( newname != 0, "the empty name is not a valid account name to bid on" ); eosio_assert( (newname & 0xFull) == 0, "13 character names are not valid account names to bid on" ); @@ -254,7 +254,7 @@ namespace eosiosystem { tmp >>= 5; } if( has_dot ) { // or is less than 12 characters - auto suffix = eosio::name_suffix(newact); + auto suffix = name(newact).suffix().raw(); if( suffix == newact ) { name_bid_table bids(_self,_self); auto current = bids.find( newact ); diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index d1bd4b2a..5934b8c1 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -19,7 +19,7 @@ namespace eosio { class token : public contract { public: - token( account_name self ):contract(self){} + token( name self ):contract(self){} void create( account_name issuer, asset maximum_supply); From 80db78ace6a89263171dfc8c6576ef5393d70fe1 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 4 Oct 2018 11:35:57 -0400 Subject: [PATCH 0571/1048] Test namebids to rex transfer --- tests/eosio.system_tests.cpp | 34 ++++++++++++++++++++++++++++++---- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 192130b4..0716c954 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3748,7 +3748,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( ramfee_to_rex, eosio_system_tester ) try { +BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { const int64_t ratio = 10000; const asset net = core_from_string("80.0000"); @@ -3772,10 +3772,36 @@ BOOST_FIXTURE_TEST_CASE( ramfee_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( bob, carol, core_from_string("70.0000") ) ); BOOST_REQUIRE_EQUAL( cur_ramfee_balance, get_balance( N(eosio.ramfee) ) ); BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_from_string("0.3500") ); + cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_lent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); + auto cur_rex_pool = get_rex_pool(); + + BOOST_REQUIRE_EQUAL( cur_rex_balance, cur_rex_pool["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["total_lent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, cur_rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); + + // required for closing namebids + cross_15_percent_threshold(); + produce_block( fc::days(14) ); + + cur_rex_balance = get_balance( N(eosio.rex) ); + BOOST_REQUIRE_EQUAL( success(), bidname( carol, N(rndmbid), core_from_string("23.7000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("23.7000"), get_balance( N(eosio.names) ) ); + BOOST_REQUIRE_EQUAL( success(), bidname( alice, N(rndmbid), core_from_string("29.3500") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_balance( N(eosio.names) )); + + produce_block( fc::hours(24) ); + produce_blocks( 10 ); + + BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); + BOOST_REQUIRE_EQUAL( success(), lendrex( frank, core_from_string("5.0000") ) ); + BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_from_string("34.3500") ); + BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); + + cur_rex_balance = get_balance( N(eosio.rex) ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_unlent"].as() ); } FC_LOG_AND_RETHROW() From 1c802287fd7ae2ea8c259f2d4e8236b47450b80a Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 4 Oct 2018 16:29:57 -0400 Subject: [PATCH 0572/1048] Add voting condition to lendrex, fix unit tests --- eosio.system/src/rex.cpp | 13 +++- tests/eosio.system_tester.hpp | 20 +++++ tests/eosio.system_tests.cpp | 141 ++++++++++++++-------------------- 3 files changed, 87 insertions(+), 87 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index dce63eb1..2a9d4e10 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -14,6 +14,13 @@ namespace eosiosystem { require_auth( from ); eosio_assert( amount.symbol == system_token_symbol, "asset must be system token" ); + + { + auto vitr = _voters.find( from ); + eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), + "must vote for proxy or at least 21 producers before buying REX" ); + } + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, { from, N(eosio.rex), amount, "buy REX" } ); @@ -148,8 +155,8 @@ namespace eosiosystem { auto tot_itr = totals_tbl.find( receiver ); eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); totals_tbl.modify( tot_itr, 0, [&]( auto& tot ) { - tot.cpu_weight.amount += delta_cpu; - tot.net_weight.amount += delta_net; + tot.cpu_weight.amount += delta_cpu; + tot.net_weight.amount += delta_net; }); eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); @@ -311,14 +318,12 @@ namespace eosiosystem { rt.total_unlent.amount += itr->loan_payment.amount; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); - idx.modify ( itr, 0, [&]( auto& loan ) { delta_stake = rented_tokens - loan.total_staked.amount; loan.total_staked.amount = rented_tokens; loan.expiration += eosio::days(30); loan.balance.amount -= loan.loan_payment.amount; }); - } else { delete_loan = true; delta_stake = -( itr->total_staked.amount ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index a20e92d6..471c5433 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -402,6 +402,26 @@ class eosio_system_tester : public TESTER { return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer_max_time ); } + void setup_rex_accounts( const std::vector& accounts, + const asset& init_balance, + const asset& net = core_from_string("80.0000"), + const asset& cpu = core_from_string("80.0000") ) { + // const asset net = core_from_string("80.0000"); + // const asset cpu = core_from_string("80.0000"); + const asset nstake = core_from_string("10.0000"); + const asset cstake = core_from_string("10.0000"); + create_account_with_resources( N(proxyaccount), config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + BOOST_REQUIRE_EQUAL( success(), push_action( N(proxyaccount), N(regproxy), mvo()("proxy", "proxyaccount")("isproxy", true) ) ); + for (const auto& a: accounts) { + create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); + transfer( config::system_account_name, a, init_balance + nstake + cstake, config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( a, a, nstake, cstake) ); + BOOST_REQUIRE_EQUAL( success(), vote( a, { }, N(proxyaccount) ) ); + BOOST_REQUIRE_EQUAL( init_balance, get_balance(a) ); + BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); + } + } + action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { return push_action( name(bidder), N(bidname), mvo() ("bidder", bidder) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0716c954..7f951e64 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3373,17 +3373,11 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { - const int64_t ratio = 10000; - cross_15_percent_threshold(); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - } + const int64_t ratio = 10000; + const asset init_balance = core_from_string("1000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + setup_rex_accounts( accounts, init_balance ); BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("30.0000") ) ); BOOST_REQUIRE_EQUAL( core_from_string("970.0000"), get_balance(alice) ); @@ -3439,19 +3433,17 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); return cpu; }; - - const int64_t ratio = 10000; - cross_15_percent_threshold(); - const asset init_net = core_from_string("70.0000"); - const asset init_cpu = core_from_string("90.0000"); - const asset init_balance = core_from_string("1000.0000"); + + const int64_t ratio = 10000; + const asset init_balance = core_from_string("10000.0000"); + const asset init_net = core_from_string("70.0000"); + const asset init_cpu = core_from_string("90.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, init_net, init_cpu ); - transfer( config::system_account_name, a, init_balance, config::system_account_name ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - } + setup_rex_accounts( accounts, init_balance, init_net, init_cpu ); + + const int64_t init_cpu_limit = get_cpu_limit( alice ); + const int64_t init_net_limit = get_net_limit( alice ); // bob tries to rent rex BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_from_string("5.0000") ) ); @@ -3459,9 +3451,10 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); BOOST_REQUIRE_EQUAL( init_balance - core_from_string("65.0000"), get_balance(alice) ); auto rex_pool = get_rex_pool(); - const asset init_tot_unlent = rex_pool["total_unlent"].as(); - const asset init_tot_lendable = rex_pool["total_lendable"].as(); - const asset init_tot_rent = rex_pool["total_rent"].as(); + const asset init_tot_unlent = rex_pool["total_unlent"].as(); + const asset init_tot_lendable = rex_pool["total_lendable"].as(); + const asset init_tot_rent = rex_pool["total_rent"].as(); + const int64_t init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); @@ -3481,8 +3474,8 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { rex_pool["total_lendable"].as() ); // test that carol's resource limits have been updated properly - BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu.get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net.get_amount() ); + BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); + BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); // alice tries to unlendrex, order gets scheduled then she cancels order BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no unlendrex is scheduled") ); @@ -3499,8 +3492,8 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); // test that carol's resource limits have been updated properly when loan expires - BOOST_REQUIRE_EQUAL( 0, get_cpu_limit( carol ) - init_cpu.get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net.get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_cpu_limit( carol ) - init_cpu_limit ); + BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); @@ -3532,28 +3525,23 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; - const int64_t ratio = 10000; - cross_15_percent_threshold(); - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const asset init_balance = core_from_string("10000.0000"); + + const int64_t ratio = 10000; + const asset init_balance = core_from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, init_balance, config::system_account_name ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - } + setup_rex_accounts( accounts, init_balance ); - auto purchase1 = core_from_string("880.0000"); - auto purchase2 = core_from_string("471.0000"); - auto purchase3 = core_from_string("469.0000"); + const auto purchase1 = core_from_string("880.0000"); + const auto purchase2 = core_from_string("471.0000"); + const auto purchase3 = core_from_string("469.0000"); + const auto init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( success(), lendrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), lendrex( bob, purchase2) ); BOOST_REQUIRE_EQUAL( success(), lendrex( carol, purchase3) ); BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_balance(alice) ); - BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() ); + BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_balance(bob) ); BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_balance(carol) ); @@ -3566,7 +3554,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ); BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_rex_vote_stake( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_voter_info(alice)["staked"].as() ); + BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_voter_info(alice)["staked"].as() - init_stake ); init_alice_rex = get_rex_balance(alice); @@ -3602,7 +3590,6 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { // an action is needed to trigger queue processing produce_block( fc::hours(2) ); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("an unlendrex request has already been scheduled"), unlendrex( alice, init_alice_rex ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); @@ -3616,21 +3603,21 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as() ); BOOST_REQUIRE_EQUAL( purchase2.get_amount(), get_rex_order(bob)["unstake_quant"].as() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as() ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as() ); - BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); - BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_voter_info( bob )["staked"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_voter_info( carol )["staked"].as() ); + BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); + BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); + BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); + BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( emily, core_from_string("100.0000")) ); - BOOST_REQUIRE_EQUAL( success(), claimrex( alice ) ); + BOOST_REQUIRE_EQUAL( success(), lendrex( emily, core_from_string("100.0000")) ); + BOOST_REQUIRE_EQUAL( success(), claimrex( alice ) ); } FC_LOG_AND_RETHROW() @@ -3649,17 +3636,11 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { return cpu; }; - const int64_t ratio = 10000; - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const asset init_balance = core_from_string("10000.0000"); + const int64_t ratio = 10000; + const asset init_balance = core_from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, init_balance, config::system_account_name ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - } + setup_rex_accounts( accounts, init_balance ); BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("500.0000") ) ); @@ -3750,17 +3731,11 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { - const int64_t ratio = 10000; - const asset net = core_from_string("80.0000"); - const asset cpu = core_from_string("80.0000"); - const asset init_balance = core_from_string("10000.0000"); + const int64_t ratio = 10000; + const asset init_balance = core_from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, init_balance, config::system_account_name ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - } + setup_rex_accounts( accounts, init_balance ); asset cur_ramfee_balance = get_balance( N(eosio.ramfee) ); BOOST_REQUIRE_EQUAL( success(), buyram( alice, alice, core_from_string("20.0000") ) ); @@ -3786,22 +3761,22 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { produce_block( fc::days(14) ); cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( success(), bidname( carol, N(rndmbid), core_from_string("23.7000") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("23.7000"), get_balance( N(eosio.names) ) ); - BOOST_REQUIRE_EQUAL( success(), bidname( alice, N(rndmbid), core_from_string("29.3500") ) ); - BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_balance( N(eosio.names) )); + BOOST_REQUIRE_EQUAL( success(), bidname( carol, N(rndmbid), core_from_string("23.7000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("23.7000"), get_balance( N(eosio.names) ) ); + BOOST_REQUIRE_EQUAL( success(), bidname( alice, N(rndmbid), core_from_string("29.3500") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_balance( N(eosio.names) )); produce_block( fc::hours(24) ); produce_blocks( 10 ); - BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); - BOOST_REQUIRE_EQUAL( success(), lendrex( frank, core_from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_from_string("34.3500") ); - BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); + BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); + BOOST_REQUIRE_EQUAL( success(), lendrex( frank, core_from_string("5.0000") ) ); + BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_from_string("34.3500") ); + BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_unlent"].as() ); } FC_LOG_AND_RETHROW() From 31f087096c962bce64b04b174119522b48aeb705 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 4 Oct 2018 16:31:20 -0400 Subject: [PATCH 0573/1048] Code cleaning --- tests/eosio.system_tester.hpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 471c5433..3ab607e2 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -406,8 +406,6 @@ class eosio_system_tester : public TESTER { const asset& init_balance, const asset& net = core_from_string("80.0000"), const asset& cpu = core_from_string("80.0000") ) { - // const asset net = core_from_string("80.0000"); - // const asset cpu = core_from_string("80.0000"); const asset nstake = core_from_string("10.0000"); const asset cstake = core_from_string("10.0000"); create_account_with_resources( N(proxyaccount), config::system_account_name, core_from_string("1.0000"), false, net, cpu ); From 15b8ee3efde7496a490e0d4eb8bf9477896e771b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 4 Oct 2018 17:08:27 -0400 Subject: [PATCH 0574/1048] REX code cleaning --- .../include/eosio.system/eosio.system.hpp | 3 + eosio.system/src/rex.cpp | 105 +++++++----------- 2 files changed, 44 insertions(+), 64 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 04bfa2d2..d813016d 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -386,6 +386,9 @@ namespace eosiosystem { void runrex( uint16_t max ); std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); void deposit_rex( const account_name& from, const asset& amount ); + template + int64_t rentrex( T& table, account_name from, account_name receiver, asset payment, bool auto_renew, + const std::string& memo ); // defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 2a9d4e10..d53a9e7f 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -76,6 +76,7 @@ namespace eosiosystem { * Converts REX stake back into SYS tokens at current exchange rate */ void system_contract::unlendrex( account_name from, asset rex ) { + runrex(2); require_auth( from ); @@ -174,38 +175,8 @@ namespace eosiosystem { require_auth( from ); - runrex(2); - - eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio.rex), payment, string("rent CPU") } ); - - auto itr = _rextable.begin(); - eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); - - int64_t rented_tokens = 0; - _rextable.modify( itr, 0, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - rt.loan_num++; - }); - - rex_cpu_loan_table cpu_loans(_self,_self); - - cpu_loans.emplace( from, [&]( auto& c ) { - c.from = from; - c.receiver = receiver; - c.loan_payment = payment; - c.total_staked = asset( rented_tokens, system_token_symbol ); - c.expiration = current_time_point() + eosio::days(30); - c.loan_num = itr->loan_num; - - c.auto_renew = auto_renew; - c.balance = asset( 0, system_token_symbol ); - }); - + rex_cpu_loan_table cpu_loans( _self, _self ); + int64_t rented_tokens = rentrex( cpu_loans, from, receiver, payment, auto_renew, "rent CPU" ); update_resource_limits( receiver, rented_tokens, 0 ); } @@ -213,38 +184,8 @@ namespace eosiosystem { require_auth( from ); - runrex(2); - - eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio.rex), payment, string("rent NET") } ); - - auto itr = _rextable.begin(); - eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); - - int64_t rented_tokens = 0; - _rextable.modify( itr, 0, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - rt.loan_num++; - }); - - rex_net_loan_table net_loans(_self,_self); - - net_loans.emplace( from, [&]( auto& c ) { - c.from = from; - c.receiver = receiver; - c.loan_payment = payment; - c.total_staked = asset( rented_tokens, system_token_symbol ); - c.expiration = current_time_point() + eosio::days(30); - c.loan_num = itr->loan_num; - - c.auto_renew = auto_renew; - c.balance = asset( 0, system_token_symbol ); - }); - + rex_net_loan_table net_loans( _self, _self ); + int64_t rented_tokens = rentrex( net_loans, from, receiver, payment, auto_renew, "rent NET" ); update_resource_limits( receiver, 0, rented_tokens ); } @@ -414,6 +355,42 @@ namespace eosiosystem { } + template + int64_t system_contract::rentrex( T& table, account_name from, account_name receiver, + asset payment, bool auto_renew, const std::string& memo ) { + runrex(2); + + eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, + { from, N(eosio.rex), payment, memo } ); + + auto itr = _rextable.begin(); + eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); + + int64_t rented_tokens = 0; + _rextable.modify( itr, 0, [&]( auto& rt ) { + rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + rt.loan_num++; + }); + + table.emplace( from, [&]( auto& c ) { + c.from = from; + c.receiver = receiver; + c.loan_payment = payment; + c.total_staked = asset( rented_tokens, system_token_symbol ); + c.expiration = current_time_point() + eosio::days(30); + c.loan_num = itr->loan_num; + + c.auto_renew = auto_renew; + c.balance = asset( 0, system_token_symbol ); + }); + + return rented_tokens; + } + std::tuple system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; From 4c6bde9a92af782f2b6b73c6f308b93260938491 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 4 Oct 2018 19:14:50 -0400 Subject: [PATCH 0575/1048] Created updaterex system contract action --- eosio.system/abi/eosio.system.abi | 10 ++++++ .../include/eosio.system/eosio.system.hpp | 2 ++ eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/rex.cpp | 33 +++++++++++++++---- tests/eosio.system_tests.cpp | 6 ++-- 5 files changed, 42 insertions(+), 11 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 68415ab1..e8b5a3bf 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -231,6 +231,12 @@ "fields": [ {"name":"owner", "type":"account_name"} ] + },{ + "name": "updaterex", + "base": "", + "fields": [ + {"name":"owner", "type":"account_name"} + ] },{ "name": "rex_balance", "base": "", @@ -647,6 +653,10 @@ "name": "claimrex", "type": "claimrex", "ricardian_contract": "" + },{ + "name": "updaterex", + "type": "updaterex", + "ricardian_contract": "" },{ "name": "rentcpu", "type": "rentcpu", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index d813016d..9c46bd27 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -305,6 +305,8 @@ namespace eosiosystem { void fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ); void claimrefund( account_name owner ); + + void updaterex( account_name owner ); /** * Decreases the total tokens delegated by from to receiver and/or diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 304183a8..ccc27add 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -298,7 +298,7 @@ EOSIO_ABI( eosiosystem::system_contract, // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundrexloan)(claimrefund) + (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundrexloan)(claimrefund)(updaterex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index d53a9e7f..c8bcc1c3 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -233,6 +233,29 @@ namespace eosiosystem { loan_refunds.erase( itr ); } + void system_contract::updaterex( account_name owner ) { + + require_auth( owner ); + + auto itr = _rexbalance.find( owner ); + eosio_assert( itr != _rexbalance.end() && itr->rex_balance.amount > 0, "account has no REX balance"); + const asset init_stake = itr->vote_stake; + + runrex(2); + + auto rexp_itr = _rextable.begin(); + const asset& total_rex = rexp_itr->total_rex; + const asset& total_lendable = rexp_itr->total_lendable; + + asset current_stake( 0, system_token_symbol ); + current_stake.amount = ( uint128_t(itr->rex_balance.amount) * total_lendable.amount ) / total_rex.amount; + _rexbalance.modify( itr, 0, [&]( auto& rb ) { + rb.vote_stake = current_stake; + }); + + update_voting_power( owner, current_stake - init_stake ); + } + /** * Perform maitenance operations on expired rex */ @@ -296,6 +319,7 @@ namespace eosiosystem { }); } + // process cpu loans { rex_cpu_loan_table cpu_loans( _self, _self ); auto cpu_idx = cpu_loans.get_index(); @@ -312,6 +336,7 @@ namespace eosiosystem { } } + // process net loans { rex_net_loan_table net_loans( _self, _self ); auto net_idx = net_loans.get_index(); @@ -328,18 +353,14 @@ namespace eosiosystem { } } + // process unlendrex orders { rex_order_table rex_orders( _self, _self ); auto idx = rex_orders.get_index(); auto oitr = idx.begin(); for( uint16_t i = 0; i < max; ++i ) { if( oitr == idx.end() || !oitr->is_open ) break; - auto bitr = _rexbalance.find( oitr->owner ); - // TODO: change the logic below - if( bitr == _rexbalance.end() ) { - idx.erase( oitr++ ); - continue; - } + auto bitr = _rexbalance.find( oitr->owner ); // bitr != _rexbalance.end() auto result = close_rex_order( bitr, oitr->rex_requested ); auto next = oitr; ++next; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7f951e64..0f131a14 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3492,15 +3492,13 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); // test that carol's resource limits have been updated properly when loan expires - BOOST_REQUIRE_EQUAL( 0, get_cpu_limit( carol ) - init_cpu_limit ); - BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); + BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); + BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_unlent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); - // The following test is not always true, need to be replaced - // BOOST_REQUIRE_EQUAL( init_tot_rent, rex_pool["total_rent"].as() ); } { From cf02262fe88596230a2d9a28dfbe4c783f9f956f Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 4 Oct 2018 20:36:49 -0400 Subject: [PATCH 0576/1048] progress on updating contracts to reflect changes in CDT --- eosio.bios/include/eosio.bios/eosio.bios.hpp | 22 ++-- eosio.msig/include/eosio.msig/eosio.msig.hpp | 20 ++-- eosio.msig/src/eosio.msig.cpp | 73 ++++++------ eosio.sudo/src/eosio.sudo.cpp | 6 +- .../include/eosio.system/eosio.system.hpp | 82 +++++++------- eosio.system/include/eosio.system/native.hpp | 48 ++++---- eosio.system/src/delegate_bandwidth.cpp | 106 +++++++++--------- eosio.system/src/eosio.system.cpp | 92 +++++++-------- eosio.system/src/producer_pay.cpp | 18 +-- eosio.system/src/voting.cpp | 58 +++++----- .../include/eosio.token/eosio.token.hpp | 42 +++---- eosio.token/src/eosio.token.cpp | 36 +++--- tests/eosio.system_tests.cpp | 24 ++-- 13 files changed, 316 insertions(+), 311 deletions(-) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 9ec9779e..99540a98 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -6,9 +6,9 @@ namespace eosio { struct abi_hash { - account_name owner; + name owner; checksum256 hash; - auto primary_key()const { return owner; } + uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; @@ -19,14 +19,14 @@ namespace eosio { public: bios( name self ):contract(self){} - void setpriv( account_name account, uint8_t ispriv ) { + void setpriv( name account, uint8_t ispriv ) { require_auth( _self ); - set_privileged( account, ispriv ); + set_privileged( account.value, ispriv ); } - void setalimits( account_name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { + void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { require_auth( _self ); - set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); + set_resource_limits( account.value, ram_bytes, net_weight, cpu_weight ); } void setglimits( uint64_t ram, uint64_t net, uint64_t cpu ) { @@ -50,20 +50,20 @@ namespace eosio { set_blockchain_parameters( params ); } - void reqauth( action_name from ) { + void reqauth( name from ) { require_auth( from ); } - void setabi( account_name acnt, const bytes& abi ) { - abi_hash_table table(_self, _self); - auto itr = table.find( acnt ); + void setabi( name acnt, const bytes& abi ) { + abi_hash_table table(_self, _self.value); + auto itr = table.find( acnt.value ); if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { row.owner = acnt; sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } else { - table.modify( itr, 0, [&]( auto& row ) { + table.modify( itr, same_payer, [&]( auto& row ) { sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index b003a804..fde80e43 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -9,18 +9,18 @@ namespace eosio { multisig( name self ):contract(self){} void propose(); - void approve( account_name proposer, name proposal_name, permission_level level ); - void unapprove( account_name proposer, name proposal_name, permission_level level ); - void cancel( account_name proposer, name proposal_name, account_name canceler ); - void exec( account_name proposer, name proposal_name, account_name executer ); - void invalidate( account_name account ); + void approve( name proposer, name proposal_name, permission_level level ); + void unapprove( name proposer, name proposal_name, permission_level level ); + void cancel( name proposer, name proposal_name, name canceler ); + void exec( name proposer, name proposal_name, name executer ); + void invalidate( name account ); private: struct proposal { name proposal_name; vector packed_transaction; - auto primary_key()const { return proposal_name.raw(); } + uint64_t primary_key()const { return proposal_name.value; } }; typedef eosio::multi_index< "proposal"_n, proposal > proposals; @@ -29,7 +29,7 @@ namespace eosio { vector requested_approvals; vector provided_approvals; - auto primary_key()const { return proposal_name.raw(); } + uint64_t primary_key()const { return proposal_name.value; } }; typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals; @@ -47,15 +47,15 @@ namespace eosio { vector requested_approvals; vector provided_approvals; - auto primary_key()const { return proposal_name.raw(); } + uint64_t primary_key()const { return proposal_name.value; } }; typedef eosio::multi_index< "approvals2"_n, approvals_info > approvals; struct invalidation { - account_name account; + name account; time_point last_invalidation_time; - auto primary_key() const { return account; } + uint64_t primary_key() const { return account.value; } }; typedef eosio::multi_index< "invals"_n, invalidation > invalidations; diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index 5a8c1af2..45e6d2fd 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -15,7 +15,7 @@ because parsing data in the dispatcher uses too much CPU in case if proposed tra If we use dispatcher the function signature should be: -void multisig::propose( account_name proposer, +void multisig::propose( name proposer, name proposal_name, vector requested, transaction trx) @@ -27,7 +27,7 @@ void multisig::propose() { char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); read_action_data( buffer, size ); - account_name proposer; + name proposer; name proposal_name; vector requested; transaction_header trx_header; @@ -42,8 +42,8 @@ void multisig::propose() { eosio_assert( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); //eosio_assert( trx_header.actions.size() > 0, "transaction must have at least one action" ); - proposals proptable( _self, proposer ); - eosio_assert( proptable.find( proposal_name ) == proptable.end(), "proposal with the same name exists" ); + proposals proptable( _self, proposer.value ); + eosio_assert( proptable.find( proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); bytes packed_requested = pack(requested); auto res = ::check_transaction_authorization( buffer+trx_pos, size-trx_pos, @@ -57,7 +57,7 @@ void multisig::propose() { prop.packed_transaction = bytes( buffer+trx_pos, buffer+size ); }); - approvals apptable( _self, proposer ); + approvals apptable( _self, proposer.value ); apptable.emplace( proposer, [&]( auto& a ) { a.proposal_name = proposal_name; a.requested_approvals.reserve( requested.size() ); @@ -67,11 +67,11 @@ void multisig::propose() { }); } -void multisig::approve( account_name proposer, name proposal_name, permission_level level ) { +void multisig::approve( name proposer, name proposal_name, permission_level level ) { require_auth( level ); - approvals apptable( _self, proposer ); - auto apps_it = apptable.find( proposal_name ); + approvals apptable( _self, proposer.value ); + auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { auto itr = std::find_if( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), [&](const approval& a) { return a.level == level; } ); eosio_assert( itr != apps_it->requested_approvals.end(), "approval is not on the list of requested approvals" ); @@ -81,8 +81,8 @@ void multisig::approve( account_name proposer, name proposal_name, permission_le a.requested_approvals.erase( itr ); }); } else { - old_approvals old_apptable( _self, proposer ); - auto& apps = old_apptable.get( proposal_name, "proposal not found" ); + old_approvals old_apptable( _self, proposer.value ); + auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level ); eosio_assert( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" ); @@ -94,11 +94,11 @@ void multisig::approve( account_name proposer, name proposal_name, permission_le } } -void multisig::unapprove( account_name proposer, name proposal_name, permission_level level ) { +void multisig::unapprove( name proposer, name proposal_name, permission_level level ) { require_auth( level ); - approvals apptable( _self, proposer ); - auto apps_it = apptable.find( proposal_name ); + approvals apptable( _self, proposer.value ); + auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { auto itr = std::find_if( apps_it->provided_approvals.begin(), apps_it->provided_approvals.end(), [&](const approval& a) { return a.level == level; } ); eosio_assert( itr != apps_it->provided_approvals.end(), "no approval previously granted" ); @@ -107,8 +107,8 @@ void multisig::unapprove( account_name proposer, name proposal_name, permission_ a.provided_approvals.erase( itr ); }); } else { - old_approvals old_apptable( _self, proposer ); - auto& apps = old_apptable.get( proposal_name, "proposal not found" ); + old_approvals old_apptable( _self, proposer.value ); + auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); eosio_assert( itr != apps.provided_approvals.end(), "no approval previously granted" ); old_apptable.modify( apps, proposer, [&]( auto& a ) { @@ -118,11 +118,11 @@ void multisig::unapprove( account_name proposer, name proposal_name, permission_ } } -void multisig::cancel( account_name proposer, name proposal_name, account_name canceler ) { +void multisig::cancel( name proposer, name proposal_name, name canceler ) { require_auth( canceler ); - proposals proptable( _self, proposer ); - auto& prop = proptable.get( proposal_name, "proposal not found" ); + proposals proptable( _self, proposer.value ); + auto& prop = proptable.get( proposal_name.value, "proposal not found" ); if( canceler != proposer ) { eosio_assert( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(current_time_point()), "cannot cancel until expiration" ); @@ -130,46 +130,46 @@ void multisig::cancel( account_name proposer, name proposal_name, account_name c proptable.erase(prop); //remove from new table - approvals apptable( _self, proposer ); - auto apps_it = apptable.find( proposal_name ); + approvals apptable( _self, proposer.value ); + auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { apptable.erase(apps_it); } else { - old_approvals old_apptable( _self, proposer ); - auto apps_it = old_apptable.find( proposal_name ); + old_approvals old_apptable( _self, proposer.value ); + auto apps_it = old_apptable.find( proposal_name.value ); eosio_assert( apps_it != old_apptable.end(), "proposal not found" ); old_apptable.erase(apps_it); } } -void multisig::exec( account_name proposer, name proposal_name, account_name executer ) { +void multisig::exec( name proposer, name proposal_name, name executer ) { require_auth( executer ); - proposals proptable( _self, proposer ); - auto& prop = proptable.get( proposal_name, "proposal not found" ); + proposals proptable( _self, proposer.value ); + auto& prop = proptable.get( proposal_name.value, "proposal not found" ); transaction_header trx_header; datastream ds( prop.packed_transaction.data(), prop.packed_transaction.size() ); ds >> trx_header; eosio_assert( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); - approvals apptable( _self, proposer ); - auto apps_it = apptable.find( proposal_name ); + approvals apptable( _self, proposer.value ); + auto apps_it = apptable.find( proposal_name.value ); vector approvals; - invalidations inv_table( _self, _self ); + invalidations inv_table( _self, _self.value ); if ( apps_it != apptable.end() ) { approvals.reserve( apps_it->provided_approvals.size() ); for ( auto& p : apps_it->provided_approvals ) { - auto it = inv_table.find( p.level.actor ); + auto it = inv_table.find( p.level.actor.value ); if ( it == inv_table.end() || it->last_invalidation_time < p.time ) { approvals.push_back(p.level); } } apptable.erase(apps_it); } else { - old_approvals old_apptable( _self, proposer ); - auto& apps = old_apptable.get( proposal_name, "proposal not found" ); + old_approvals old_apptable( _self, proposer.value ); + auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); for ( auto& level : apps.provided_approvals ) { - auto it = inv_table.find( level.actor ); + auto it = inv_table.find( level.actor.value ); if ( it == inv_table.end() ) { approvals.push_back( level ); } @@ -183,15 +183,16 @@ void multisig::exec( account_name proposer, name proposal_name, account_name exe ); eosio_assert( res > 0, "transaction authorization failed" ); - send_deferred( (uint128_t(proposer) << 64) | proposal_name, executer, prop.packed_transaction.data(), prop.packed_transaction.size() ); + send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer.value, + prop.packed_transaction.data(), prop.packed_transaction.size() ); proptable.erase(prop); } -void multisig::invalidate( account_name account ) { +void multisig::invalidate( name account ) { require_auth( account ); - invalidations inv_table( _self, _self ); - auto it = inv_table.find( account ); + invalidations inv_table( _self, _self.value ); + auto it = inv_table.find( account.value ); if ( it == inv_table.end() ) { inv_table.emplace( account, [&](auto& i) { i.account = account; diff --git a/eosio.sudo/src/eosio.sudo.cpp b/eosio.sudo/src/eosio.sudo.cpp index c64ffa75..c426f2cc 100644 --- a/eosio.sudo/src/eosio.sudo.cpp +++ b/eosio.sudo/src/eosio.sudo.cpp @@ -9,7 +9,7 @@ because parsing data in the dispatcher uses too much CPU if the included transac If we use dispatcher the function signature should be: -void sudo::exec( account_name executer, +void sudo::exec( name executer, transaction trx ) */ @@ -21,7 +21,7 @@ void sudo::exec() { char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); read_action_data( buffer, size ); - account_name executer; + name executer; datastream ds( buffer, size ); ds >> executer; @@ -29,7 +29,7 @@ void sudo::exec() { require_auth( executer ); size_t trx_pos = ds.tellp(); - send_deferred( (uint128_t(executer) << 64) | current_time(), executer, buffer+trx_pos, size-trx_pos ); + send_deferred( (uint128_t(executer.value) << 64) | current_time(), executer.value, buffer+trx_pos, size-trx_pos ); } } /// namespace eosio diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 9f1ed55a..11059f72 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -26,20 +26,20 @@ namespace eosiosystem { using eosio::microseconds; struct name_bid { - account_name newname; - account_name high_bidder; - int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed - time_point last_bid_time; + name newname; + name high_bidder; + int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed + time_point last_bid_time; - auto primary_key()const { return newname; } + uint64_t primary_key()const { return newname.value; } uint64_t by_high_bid()const { return static_cast(-high_bid); } }; struct bid_refund { - account_name bidder; + name bidder; asset amount; - auto primary_key() const { return bidder; } + uint64_t primary_key()const { return bidder.value; } }; typedef eosio::multi_index< "namebids"_n, name_bid, @@ -99,7 +99,7 @@ namespace eosiosystem { }; struct producer_info { - account_name owner; + name owner; double total_votes = 0; eosio::public_key producer_key; /// a packed public key object bool is_active = true; @@ -108,7 +108,7 @@ namespace eosiosystem { time_point last_claim_time; uint16_t location = 0; - uint64_t primary_key()const { return owner; } + uint64_t primary_key()const { return owner.value; } double by_votes()const { return is_active ? -total_votes : total_votes; } bool active()const { return is_active; } void deactivate() { producer_key = public_key(); is_active = false; } @@ -119,21 +119,21 @@ namespace eosiosystem { }; struct producer_info2 { - account_name owner; + name owner; double votepay_share = 0; time_point last_votepay_share_update; - uint64_t primary_key()const { return owner; } + uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) }; struct voter_info { - account_name owner = 0; /// the voter - account_name proxy = 0; /// the proxy set by the voter, if any - std::vector producers; /// the producers approved by this voter if no proxy set - int64_t staked = 0; + name owner; /// the voter + name proxy; /// the proxy set by the voter, if any + std::vector producers; /// the producers approved by this voter if no proxy set + int64_t staked = 0; /** * Every time a vote is cast we must first "undo" the last vote weight, before casting the @@ -141,20 +141,20 @@ namespace eosiosystem { * * stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) */ - double last_vote_weight = 0; /// the vote weight cast the last time the vote was updated + double last_vote_weight = 0; /// the vote weight cast the last time the vote was updated /** * Total vote weight delegated to this voter. */ - double proxied_vote_weight= 0; /// the total vote weight delegated to this voter as a proxy - bool is_proxy = 0; /// whether the voter is a proxy for others + double proxied_vote_weight= 0; /// the total vote weight delegated to this voter as a proxy + bool is_proxy = 0; /// whether the voter is a proxy for others - uint32_t reserved1 = 0; - time reserved2 = 0; - eosio::asset reserved3; + uint32_t reserved1 = 0; + uint32_t reserved2 = 0; + eosio::asset reserved3; - uint64_t primary_key()const { return owner; } + uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(reserved1)(reserved2)(reserved3) ) @@ -210,10 +210,10 @@ namespace eosiosystem { // Actions: void init( unsigned_int version, symbol core ); - void onblock( block_timestamp timestamp, account_name producer ); + void onblock( block_timestamp timestamp, name producer ); // const block_header& header ); /// only parse first 3 fields of block header - void setalimits( account_name act, int64_t ram, int64_t net, int64_t cpu ); + void setalimits( name act, int64_t ram, int64_t net, int64_t cpu ); // functions defined in delegate_bandwidth.cpp /** @@ -221,7 +221,7 @@ namespace eosiosystem { * If transfer == true, then 'receiver' can unstake to their account * Else 'from' can unstake at any time. */ - void delegatebw( account_name from, account_name receiver, + void delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); @@ -241,7 +241,7 @@ namespace eosiosystem { * The 'from' account loses voting power as a result of this call and * all producer tallies are updated. */ - void undelegatebw( account_name from, account_name receiver, + void undelegatebw( name from, name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ); @@ -250,48 +250,48 @@ namespace eosiosystem { * tokens provided. An inline transfer from receiver to system contract of * tokens will be executed. */ - void buyram( account_name buyer, account_name receiver, asset tokens ); - void buyrambytes( account_name buyer, account_name receiver, uint32_t bytes ); + void buyram( name buyer, name receiver, asset tokens ); + void buyrambytes( name buyer, name receiver, uint32_t bytes ); /** * Reduces quota my bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. */ - void sellram( account_name receiver, int64_t bytes ); + void sellram( name receiver, int64_t bytes ); /** * This action is called after the delegation-period to claim all pending * unstaked tokens belonging to owner */ - void refund( account_name owner ); + void refund( name owner ); // functions defined in voting.cpp - void regproducer( const account_name producer, const public_key& producer_key, const std::string& url, uint16_t location ); + void regproducer( const name producer, const public_key& producer_key, const std::string& url, uint16_t location ); - void unregprod( const account_name producer ); + void unregprod( const name producer ); void setram( uint64_t max_ram_size ); void setramrate( uint16_t bytes_per_block ); - void voteproducer( const account_name voter, const account_name proxy, const std::vector& producers ); + void voteproducer( const name voter, const name proxy, const std::vector& producers ); - void regproxy( const account_name proxy, bool isproxy ); + void regproxy( const name proxy, bool isproxy ); void setparams( const eosio::blockchain_parameters& params ); // functions defined in producer_pay.cpp - void claimrewards( const account_name& owner ); + void claimrewards( const name owner ); - void setpriv( account_name account, uint8_t ispriv ); + void setpriv( name account, uint8_t ispriv ); - void rmvproducer( account_name producer ); + void rmvproducer( name producer ); void updtrevision( uint8_t revision ); - void bidname( account_name bidder, account_name newname, asset bid ); + void bidname( name bidder, name newname, asset bid ); - void bidrefund( account_name bidder, account_name newname ); + void bidrefund( name bidder, name newname ); private: // Implementation details: @@ -304,12 +304,12 @@ namespace eosiosystem { void update_ram_supply(); //defined in delegate_bandwidth.cpp - void changebw( account_name from, account_name receiver, + void changebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); //defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); - void update_votes( const account_name voter, const account_name proxy, const std::vector& producers, bool voting ); + void update_votes( const name voter, const name proxy, const std::vector& producers, bool voting ); // defined in voting.cpp void propagate_weight_change( const voter_info& voter ); diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index 476da787..5dd3d3eb 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -14,6 +14,7 @@ #include namespace eosiosystem { + using eosio::name; using eosio::permission_level; using eosio::public_key; @@ -21,7 +22,7 @@ namespace eosiosystem { struct permission_level_weight { permission_level permission; - weight_type weight; + uint16_t weight; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) @@ -29,7 +30,7 @@ namespace eosiosystem { struct key_weight { public_key key; - weight_type weight; + uint16_t weight; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( key_weight, (key)(weight) ) @@ -47,9 +48,9 @@ namespace eosiosystem { struct block_header { uint32_t timestamp; - account_name producer; + name producer; uint16_t confirmed = 0; - block_id_type previous; + checksum256 previous; checksum256 transaction_mroot; checksum256 action_mroot; uint32_t schedule_version = 0; @@ -62,9 +63,9 @@ namespace eosiosystem { struct abi_hash { - account_name owner; + name owner; checksum256 hash; - auto primary_key()const { return owner; } + uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; @@ -89,33 +90,34 @@ namespace eosiosystem { * therefore, this method will execute an inline buyram from receiver for newacnt in * an amount equal to the current new account creation fee. */ - void newaccount( account_name creator, - account_name newact + void newaccount( name creator, + name newact /* no need to parse authorites const authority& owner, const authority& active*/ ); - void updateauth( /*account_name account, - permission_name permission, - permission_name parent, - const authority& data*/ ) {} + void updateauth( /* name account, + name permission, + name parent, + const authority& data */ ) {} - void deleteauth( /*account_name account, permission_name permission*/ ) {} + void deleteauth( /* name account, + name permission */ ) {} - void linkauth( /*account_name account, - account_name code, - action_name type, - permission_name requirement*/ ) {} + void linkauth( /* name account, + name code, + name type, + name requirement */ ) {} - void unlinkauth( /*account_name account, - account_name code, - action_name type*/ ) {} + void unlinkauth( /* name account, + name code, + name type*/ ) {} - void canceldelay( /*permission_level canceling_auth, transaction_id_type trx_id*/ ) {} + void canceldelay( /* permission_level canceling_auth, checksum256 trx_id */ ) {} - void onerror( /*const bytes&*/ ) {} + void onerror( /* const bytes& */ ) {} - void setabi( account_name acnt, const bytes& abi ); + void setabi( name acnt, const bytes& abi ); }; } diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 2ba6460b..4f59fdbb 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -25,20 +25,20 @@ namespace eosiosystem { using eosio::bytes; using eosio::print; using eosio::permission_level; + using eosio::time_point_sec; using std::map; using std::pair; - static constexpr time refund_delay = 3*24*3600; - static constexpr time refund_expiration_time = 3600; - static constexpr int64_t ram_gift_bytes = 1400; + static constexpr uint32_t refund_delay_sec = 3*24*3600; + static constexpr int64_t ram_gift_bytes = 1400; struct user_resources { - account_name owner; + name owner; asset net_weight; asset cpu_weight; int64_t ram_bytes = 0; - uint64_t primary_key()const { return owner; } + uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(ram_bytes) ) @@ -49,12 +49,12 @@ namespace eosiosystem { * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. */ struct delegated_bandwidth { - account_name from; - account_name to; + name from; + name to; asset net_weight; asset cpu_weight; - uint64_t primary_key()const { return to; } + uint64_t primary_key()const { return to.value; } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) ) @@ -62,12 +62,12 @@ namespace eosiosystem { }; struct refund_request { - account_name owner; - time request_time; - eosio::asset net_amount; - eosio::asset cpu_amount; + name owner; + time_point_sec request_time; + eosio::asset net_amount; + eosio::asset cpu_amount; - uint64_t primary_key()const { return owner; } + uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(net_amount)(cpu_amount) ) @@ -86,7 +86,7 @@ namespace eosiosystem { /** * This action will buy an exact amount of ram and bill the payer the current market price. */ - void system_contract::buyrambytes( account_name payer, account_name receiver, uint32_t bytes ) { + void system_contract::buyrambytes( name payer, name receiver, uint32_t bytes ) { auto itr = _rammarket.find(ramcore_symbol.raw()); auto tmp = *itr; @@ -104,7 +104,7 @@ namespace eosiosystem { * RAM is a scarce resource whose supply is defined by global properties max_ram_size. RAM is * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. */ - void system_contract::buyram( account_name payer, account_name receiver, asset quant ) + void system_contract::buyram( name payer, name receiver, asset quant ) { require_auth( payer ); update_ram_supply(); @@ -137,7 +137,7 @@ namespace eosiosystem { int64_t bytes_out; const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); - _rammarket.modify( market, 0, [&]( auto& es ) { + _rammarket.modify( market, same_payer, [&]( auto& es ) { bytes_out = es.convert( quant_after_fee, ram_symbol ).amount; }); @@ -146,8 +146,8 @@ namespace eosiosystem { _gstate.total_ram_bytes_reserved += uint64_t(bytes_out); _gstate.total_ram_stake += quant_after_fee.amount; - user_resources_table userres( _self, receiver ); - auto res_itr = userres.find( receiver ); + user_resources_table userres( _self, receiver.value ); + auto res_itr = userres.find( receiver.value ); if( res_itr == userres.end() ) { res_itr = userres.emplace( receiver, [&]( auto& res ) { res.owner = receiver; @@ -160,7 +160,7 @@ namespace eosiosystem { res.ram_bytes += bytes_out; }); } - set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); } /** @@ -169,20 +169,20 @@ namespace eosiosystem { * tomorrow. Overall this will result in the market balancing the supply and demand * for RAM over time. */ - void system_contract::sellram( account_name account, int64_t bytes ) { + void system_contract::sellram( name account, int64_t bytes ) { require_auth( account ); update_ram_supply(); eosio_assert( bytes > 0, "cannot sell negative byte" ); - user_resources_table userres( _self, account ); - auto res_itr = userres.find( account ); + user_resources_table userres( _self, account.value ); + auto res_itr = userres.find( account.value ); eosio_assert( res_itr != userres.end(), "no resource row" ); eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; auto itr = _rammarket.find(ramcore_symbol.raw()); - _rammarket.modify( itr, 0, [&]( auto& es ) { + _rammarket.modify( itr, same_payer, [&]( auto& es ) { /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases tokens_out = es.convert( asset(bytes, ram_symbol), core_symbol()); }); @@ -198,7 +198,7 @@ namespace eosiosystem { userres.modify( res_itr, account, [&]( auto& res ) { res.ram_bytes -= bytes; }); - set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {ram_account, active_permission}, {account, active_permission} }, @@ -223,7 +223,7 @@ namespace eosiosystem { eosio_assert( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } - void system_contract::changebw( account_name from, account_name receiver, + void system_contract::changebw( name from, name receiver, const asset stake_net_delta, const asset stake_cpu_delta, bool transfer ) { require_auth( from ); @@ -232,15 +232,15 @@ namespace eosiosystem { >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), "net and cpu deltas cannot be opposite signs" ); - account_name source_stake_from = from; + name source_stake_from = from; if ( transfer ) { from = receiver; } // update stake delegated from "from" to "receiver" { - del_bandwidth_table del_tbl( _self, from); - auto itr = del_tbl.find( receiver ); + del_bandwidth_table del_tbl( _self, from.value ); + auto itr = del_tbl.find( receiver.value ); if( itr == del_tbl.end() ) { itr = del_tbl.emplace( from, [&]( auto& dbo ){ dbo.from = from; @@ -250,7 +250,7 @@ namespace eosiosystem { }); } else { - del_tbl.modify( itr, 0, [&]( auto& dbo ){ + del_tbl.modify( itr, same_payer, [&]( auto& dbo ){ dbo.net_weight += stake_net_delta; dbo.cpu_weight += stake_cpu_delta; }); @@ -264,8 +264,8 @@ namespace eosiosystem { // update totals of "receiver" { - user_resources_table totals_tbl( _self, receiver ); - auto tot_itr = totals_tbl.find( receiver ); + user_resources_table totals_tbl( _self, receiver.value ); + auto tot_itr = totals_tbl.find( receiver.value ); if( tot_itr == totals_tbl.end() ) { tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { tot.owner = receiver; @@ -273,7 +273,7 @@ namespace eosiosystem { tot.cpu_weight = stake_cpu_delta; }); } else { - totals_tbl.modify( tot_itr, from == receiver ? from : 0, [&]( auto& tot ) { + totals_tbl.modify( tot_itr, from == receiver ? from : same_payer, [&]( auto& tot ) { tot.net_weight += stake_net_delta; tot.cpu_weight += stake_cpu_delta; }); @@ -282,9 +282,9 @@ namespace eosiosystem { eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); int64_t ram_bytes, net, cpu; - get_resource_limits( receiver, &ram_bytes, &net, &cpu ); + get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); - set_resource_limits( receiver, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + set_resource_limits( receiver.value, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); @@ -293,8 +293,8 @@ namespace eosiosystem { // create refund or update from existing refund if ( stake_account != source_stake_from ) { //for eosio both transfer and refund make no sense - refunds_table refunds_tbl( _self, from ); - auto req = refunds_tbl.find( from ); + refunds_table refunds_tbl( _self, from.value ); + auto req = refunds_tbl.find( from.value ); //create/update/delete refund auto net_balance = stake_net_delta; @@ -309,9 +309,9 @@ namespace eosiosystem { if( is_delegating_to_self || is_undelegating ) { if ( req != refunds_tbl.end() ) { //need to update refund - refunds_tbl.modify( req, 0, [&]( refund_request& r ) { + refunds_tbl.modify( req, same_payer, [&]( refund_request& r ) { if ( net_balance.amount < 0 || cpu_balance.amount < 0 ) { - r.request_time = now(); + r.request_time = current_time_point(); } r.net_amount -= net_balance; if ( r.net_amount.amount < 0 ) { @@ -353,7 +353,7 @@ namespace eosiosystem { } else { r.cpu_amount = asset( 0, core_symbol() ); } - r.request_time = now(); + r.request_time = current_time_point(); }); need_deferred_trx = true; } // else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl @@ -365,11 +365,11 @@ namespace eosiosystem { _self, "refund"_n, from ); - out.delay_sec = refund_delay; - cancel_deferred( from ); // TODO: Remove this line when replacing deferred trxs is fixed - out.send( from, from, true ); + out.delay_sec = refund_delay_sec; + cancel_deferred( from.value ); // TODO: Remove this line when replacing deferred trxs is fixed + out.send( from.value, from, true ); } else { - cancel_deferred( from ); + cancel_deferred( from.value ); } auto transfer_amount = net_balance + cpu_balance; @@ -384,14 +384,14 @@ namespace eosiosystem { // update voting power { asset total_update = stake_net_delta + stake_cpu_delta; - auto from_voter = _voters.find(from); + auto from_voter = _voters.find( from.value ); if( from_voter == _voters.end() ) { from_voter = _voters.emplace( from, [&]( auto& v ) { v.owner = from; v.staked = total_update.amount; }); } else { - _voters.modify( from_voter, 0, [&]( auto& v ) { + _voters.modify( from_voter, same_payer, [&]( auto& v ) { v.staked += total_update.amount; }); } @@ -406,7 +406,7 @@ namespace eosiosystem { } } - void system_contract::delegatebw( account_name from, account_name receiver, + void system_contract::delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ) { @@ -419,7 +419,7 @@ namespace eosiosystem { changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); } // delegatebw - void system_contract::undelegatebw( account_name from, account_name receiver, + void system_contract::undelegatebw( name from, name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ) { asset zero_asset( 0, core_symbol() ); @@ -433,16 +433,14 @@ namespace eosiosystem { } // undelegatebw - void system_contract::refund( const account_name owner ) { + void system_contract::refund( const name owner ) { require_auth( owner ); - refunds_table refunds_tbl( _self, owner ); - auto req = refunds_tbl.find( owner ); + refunds_table refunds_tbl( _self, owner.value ); + auto req = refunds_tbl.find( owner.value ); eosio_assert( req != refunds_tbl.end(), "refund request not found" ); - eosio_assert( req->request_time + refund_delay <= now(), "refund is not available yet" ); - // Until now() becomes NOW, the fact that now() is the timestamp of the previous block could in theory - // allow people to get their tokens earlier than the 3 day delay if the unstake happened immediately after many - // consecutive missed blocks. + eosio_assert( req->request_time + seconds(refund_delay_sec) <= current_time_point(), + "refund is not available yet" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {stake_account, active_permission}, {req->owner, active_permission} }, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 271d8c7c..689055af 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -12,13 +12,13 @@ namespace eosiosystem { system_contract::system_contract( name s ) :native(s), - _voters(_self,_self), - _producers(_self,_self), - _producers2(_self,_self), - _global(_self,_self), - _global2(_self,_self), - _global3(_self,_self), - _rammarket(_self,_self) + _voters(_self, _self.value), + _producers(_self, _self.value), + _producers2(_self, _self.value), + _global(_self, _self.value), + _global2(_self, _self.value), + _global3(_self, _self.value), + _rammarket(_self, _self.value) { //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); @@ -49,7 +49,7 @@ namespace eosiosystem { } symbol system_contract::get_core_symbol() { - rammarket rm("eosio"_n, "eosio"_n); + rammarket rm("eosio"_n, "eosio"_n.value); const static auto sym = get_core_symbol( rm ); return sym; } @@ -79,7 +79,7 @@ namespace eosiosystem { /** * Increase the amount of ram for sale based upon the change in max ram size. */ - _rammarket.modify( itr, 0, [&]( auto& m ) { + _rammarket.modify( itr, same_payer, [&]( auto& m ) { m.base.balance.amount += delta; }); @@ -98,7 +98,7 @@ namespace eosiosystem { /** * Increase the amount of ram for sale based upon the change in max ram size. */ - _rammarket.modify( itr, 0, [&]( auto& m ) { + _rammarket.modify( itr, same_payer, [&]( auto& m ) { m.base.balance.amount += new_ram; }); _gstate2.last_ram_increase = cbt; @@ -125,24 +125,24 @@ namespace eosiosystem { set_blockchain_parameters( params ); } - void system_contract::setpriv( account_name account, uint8_t ispriv ) { + void system_contract::setpriv( name account, uint8_t ispriv ) { require_auth( _self ); - set_privileged( account, ispriv ); + set_privileged( account.value, ispriv ); } - void system_contract::setalimits( account_name account, int64_t ram, int64_t net, int64_t cpu ) { + void system_contract::setalimits( name account, int64_t ram, int64_t net, int64_t cpu ) { require_auth( _self ); - user_resources_table userres( _self, account ); - auto ritr = userres.find( account ); + user_resources_table userres( _self, account.value ); + auto ritr = userres.find( account.value ); eosio_assert( ritr == userres.end(), "only supports unlimited accounts" ); - set_resource_limits(account, ram, net, cpu); + set_resource_limits( account.value, ram, net, cpu ); } - void system_contract::rmvproducer( account_name producer ) { + void system_contract::rmvproducer( name producer ) { require_auth( _self ); - auto prod = _producers.find( producer ); + auto prod = _producers.find( producer.value ); eosio_assert( prod != _producers.end(), "producer not found" ); - _producers.modify( prod, 0, [&](auto& p) { + _producers.modify( prod, same_payer, [&](auto& p) { p.deactivate(); }); } @@ -156,25 +156,25 @@ namespace eosiosystem { _gstate2.revision = revision; } - void system_contract::bidname( account_name bidder, account_name newname, asset bid ) { + void system_contract::bidname( name bidder, name newname, asset bid ) { require_auth( bidder ); - eosio_assert( name(newname).suffix() == name(newname), "you can only bid on top-level suffix" ); + eosio_assert( newname.suffix() == newname, "you can only bid on top-level suffix" ); - eosio_assert( newname != 0, "the empty name is not a valid account name to bid on" ); - eosio_assert( (newname & 0xFull) == 0, "13 character names are not valid account names to bid on" ); - eosio_assert( (newname & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); + eosio_assert( (bool)newname, "the empty name is not a valid account name to bid on" ); + eosio_assert( (newname.value & 0xFull) == 0, "13 character names are not valid account names to bid on" ); + eosio_assert( (newname.value & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); eosio_assert( !is_account( newname ), "account already exists" ); eosio_assert( bid.symbol == core_symbol(), "asset must be system token" ); eosio_assert( bid.amount > 0, "insufficient bid" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {bidder, active_permission} }, - { bidder, names_account, bid, std::string("bid name ")+(name{newname}).to_string() } + { bidder, names_account, bid, std::string("bid name ")+ newname.to_string() } ); - name_bid_table bids(_self,_self); + name_bid_table bids(_self, _self.value); print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); - auto current = bids.find( newname ); + auto current = bids.find( newname.value ); if( current == bids.end() ) { bids.emplace( bidder, [&]( auto& b ) { b.newname = newname; @@ -187,11 +187,11 @@ namespace eosiosystem { eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); eosio_assert( current->high_bidder != bidder, "account is already highest bidder" ); - bid_refund_table refunds_table(_self, newname); + bid_refund_table refunds_table(_self, newname.value); - auto it = refunds_table.find( current->high_bidder ); + auto it = refunds_table.find( current->high_bidder.value ); if ( it != refunds_table.end() ) { - refunds_table.modify( it, 0, [&](auto& r) { + refunds_table.modify( it, same_payer, [&](auto& r) { r.amount += asset( current->high_bid, core_symbol() ); }); } else { @@ -207,7 +207,7 @@ namespace eosiosystem { std::make_tuple( current->high_bidder, newname ) ); t.delay_sec = 0; - uint128_t deferred_id = (uint128_t(newname) << 64) | current->high_bidder; + uint128_t deferred_id = (uint128_t(newname.value) << 64) | current->high_bidder.value; cancel_deferred( deferred_id ); t.send( deferred_id, bidder ); @@ -219,9 +219,9 @@ namespace eosiosystem { } } - void system_contract::bidrefund( account_name bidder, account_name newname ) { - bid_refund_table refunds_table(_self, newname); - auto it = refunds_table.find( bidder ); + void system_contract::bidrefund( name bidder, name newname ) { + bid_refund_table refunds_table(_self, newname.value); + auto it = refunds_table.find( bidder.value ); eosio_assert( it != refunds_table.end(), "refund not found" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {names_account, active_permission}, {bidder, active_permission} }, @@ -239,14 +239,14 @@ namespace eosiosystem { * who can create accounts with the creator's name as a suffix. * */ - void native::newaccount( account_name creator, - account_name newact + void native::newaccount( name creator, + name newact /* no need to parse authorites const authority& owner, const authority& active*/ ) { if( creator != _self ) { - auto tmp = newact >> 4; + uint64_t tmp = newact.value >> 4; bool has_dot = false; for( uint32_t i = 0; i < 12; ++i ) { @@ -254,10 +254,10 @@ namespace eosiosystem { tmp >>= 5; } if( has_dot ) { // or is less than 12 characters - auto suffix = name(newact).suffix().raw(); + auto suffix = newact.suffix(); if( suffix == newact ) { - name_bid_table bids(_self,_self); - auto current = bids.find( newact ); + name_bid_table bids(_self, _self.value); + auto current = bids.find( newact.value ); eosio_assert( current != bids.end(), "no active bid for name" ); eosio_assert( current->high_bidder == creator, "only highest bidder can claim" ); eosio_assert( current->high_bid < 0, "auction for name is not closed yet" ); @@ -268,7 +268,7 @@ namespace eosiosystem { } } - user_resources_table userres( _self, newact); + user_resources_table userres( _self, newact.value); userres.emplace( newact, [&]( auto& res ) { res.owner = newact; @@ -276,19 +276,19 @@ namespace eosiosystem { res.cpu_weight = asset( 0, system_contract::get_core_symbol() ); }); - set_resource_limits( newact, 0, 0, 0 ); + set_resource_limits( newact.value, 0, 0, 0 ); } - void native::setabi( account_name acnt, const bytes& abi ) { - eosio::multi_index< "abihash"_n, abi_hash > table(_self,_self); - auto itr = table.find( acnt ); + void native::setabi( name acnt, const bytes& abi ) { + eosio::multi_index< "abihash"_n, abi_hash > table(_self, _self.value); + auto itr = table.find( acnt.value ); if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { row.owner= acnt; sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } else { - table.modify( itr, 0, [&]( auto& row ) { + table.modify( itr, same_payer, [&]( auto& row ) { sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index b42f4dca..d88c557e 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -16,7 +16,7 @@ namespace eosiosystem { const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); const int64_t useconds_per_year = seconds_per_year*1000000ll; - void system_contract::onblock( block_timestamp timestamp, account_name producer ) { + void system_contract::onblock( block_timestamp timestamp, name producer ) { using namespace eosio; require_auth(_self); @@ -38,10 +38,10 @@ namespace eosiosystem { * At startup the initial producer may not be one that is registered / elected * and therefore there may be no producer object for them. */ - auto prod = _producers.find(producer); + auto prod = _producers.find( producer.value ); if ( prod != _producers.end() ) { _gstate.total_unpaid_blocks++; - _producers.modify( prod, 0, [&](auto& p ) { + _producers.modify( prod, same_payer, [&](auto& p ) { p.unpaid_blocks++; }); } @@ -51,7 +51,7 @@ namespace eosiosystem { update_elected_producers( timestamp ); if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { - name_bid_table bids(_self,_self); + name_bid_table bids(_self, _self.value); auto idx = bids.get_index<"highbid"_n>(); auto highest = idx.lower_bound( std::numeric_limits::max()/2 ); if( highest != idx.end() && @@ -61,7 +61,7 @@ namespace eosiosystem { (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) ) { _gstate.last_name_close = timestamp; - idx.modify( highest, 0, [&]( auto& b ){ + idx.modify( highest, same_payer, [&]( auto& b ){ b.high_bid = -b.high_bid; }); } @@ -70,10 +70,10 @@ namespace eosiosystem { } using namespace eosio; - void system_contract::claimrewards( const account_name& owner ) { + void system_contract::claimrewards( const name owner ) { require_auth( owner ); - const auto& prod = _producers.get( owner ); + const auto& prod = _producers.get( owner.value ); eosio_assert( prod.active(), "producer does not have an active key" ); eosio_assert( _gstate.total_activated_stake >= min_activated_stake, @@ -119,7 +119,7 @@ namespace eosiosystem { _gstate.last_pervote_bucket_fill = ct; } - auto prod2 = _producers2.find( owner ); + auto prod2 = _producers2.find( owner.value ); /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and /// time duration the vote weight has been held into one metric. @@ -176,7 +176,7 @@ namespace eosiosystem { update_total_votepay_share( ct, -new_votepay_share, (updated_after_threshold ? prod.total_votes : 0.0) ); - _producers.modify( prod, 0, [&](auto& p) { + _producers.modify( prod, same_payer, [&](auto& p) { p.last_claim_time = ct; p.unpaid_blocks = 0; }); diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 435bc9fd..8e914b98 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -34,12 +34,12 @@ namespace eosiosystem { * @pre authority of producer to register * */ - void system_contract::regproducer( const account_name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { + void system_contract::regproducer( const name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { eosio_assert( url.size() < 512, "url too long" ); eosio_assert( producer_key != eosio::public_key(), "public key should not be the default value" ); require_auth( producer ); - auto prod = _producers.find( producer ); + auto prod = _producers.find( producer.value ); const auto ct = current_time_point(); if ( prod != _producers.end() ) { @@ -52,7 +52,7 @@ namespace eosiosystem { info.last_claim_time = ct; }); - auto prod2 = _producers2.find( producer ); + auto prod2 = _producers2.find( producer.value ); if ( prod2 == _producers2.end() ) { _producers2.emplace( producer, [&]( producer_info2& info ){ info.owner = producer; @@ -79,11 +79,11 @@ namespace eosiosystem { } - void system_contract::unregprod( const account_name producer ) { + void system_contract::unregprod( const name producer ) { require_auth( producer ); - const auto& prod = _producers.get( producer, "producer not found" ); - _producers.modify( prod, 0, [&]( producer_info& info ){ + const auto& prod = _producers.get( producer.value, "producer not found" ); + _producers.modify( prod, same_payer, [&]( producer_info& info ){ info.deactivate(); }); } @@ -165,7 +165,7 @@ namespace eosiosystem { } double new_votepay_share = prod_itr->votepay_share + delta_votepay_share; - _producers2.modify( prod_itr, 0, [&](auto& p) { + _producers2.modify( prod_itr, same_payer, [&](auto& p) { if( reset_to_zero ) p.votepay_share = 0.0; else @@ -193,12 +193,12 @@ namespace eosiosystem { * * If voting for a proxy, the producer votes will not change until the proxy updates their own vote. */ - void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector& producers ) { + void system_contract::voteproducer( const name voter_name, const name proxy, const std::vector& producers ) { require_auth( voter_name ); update_votes( voter_name, proxy, producers, true ); } - void system_contract::update_votes( const account_name voter_name, const account_name proxy, const std::vector& producers, bool voting ) { + void system_contract::update_votes( const name voter_name, const name proxy, const std::vector& producers, bool voting ) { //validate input if ( proxy ) { eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" ); @@ -211,7 +211,7 @@ namespace eosiosystem { } } - auto voter = _voters.find(voter_name); + auto voter = _voters.find( voter_name.value ); eosio_assert( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object eosio_assert( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" ); @@ -232,12 +232,12 @@ namespace eosiosystem { new_vote_weight += voter->proxied_vote_weight; } - boost::container::flat_map > producer_deltas; + boost::container::flat_map > producer_deltas; if ( voter->last_vote_weight > 0 ) { if( voter->proxy ) { - auto old_proxy = _voters.find( voter->proxy ); + auto old_proxy = _voters.find( voter->proxy.value ); eosio_assert( old_proxy != _voters.end(), "old proxy not found" ); //data corruption - _voters.modify( old_proxy, 0, [&]( auto& vp ) { + _voters.modify( old_proxy, same_payer, [&]( auto& vp ) { vp.proxied_vote_weight -= voter->last_vote_weight; }); propagate_weight_change( *old_proxy ); @@ -251,11 +251,11 @@ namespace eosiosystem { } if( proxy ) { - auto new_proxy = _voters.find( proxy ); + auto new_proxy = _voters.find( proxy.value ); eosio_assert( new_proxy != _voters.end(), "invalid proxy specified" ); //if ( !voting ) { data corruption } else { wrong vote } eosio_assert( !voting || new_proxy->is_proxy, "proxy not found" ); if ( new_vote_weight >= 0 ) { - _voters.modify( new_proxy, 0, [&]( auto& vp ) { + _voters.modify( new_proxy, same_payer, [&]( auto& vp ) { vp.proxied_vote_weight += new_vote_weight; }); propagate_weight_change( *new_proxy ); @@ -274,11 +274,11 @@ namespace eosiosystem { double delta_change_rate = 0.0; double total_inactive_vpay_share = 0.0; for( const auto& pd : producer_deltas ) { - auto pitr = _producers.find( pd.first ); + auto pitr = _producers.find( pd.first.value ); if( pitr != _producers.end() ) { eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); double init_total_votes = pitr->total_votes; - _producers.modify( pitr, 0, [&]( auto& p ) { + _producers.modify( pitr, same_payer, [&]( auto& p ) { p.total_votes += pd.second.first; if ( p.total_votes < 0 ) { // floating point arithmetics can give small negative numbers p.total_votes = 0; @@ -286,7 +286,7 @@ namespace eosiosystem { _gstate.total_producer_vote_weight += pd.second.first; //eosio_assert( p.total_votes >= 0, "something bad happened" ); }); - auto prod2 = _producers2.find( pd.first ); + auto prod2 = _producers2.find( pd.first.value ); if( prod2 != _producers2.end() ) { const auto last_claim_plus_3days = pitr->last_claim_time + microseconds(3 * useconds_per_day); bool crossed_threshold = (last_claim_plus_3days <= ct); @@ -313,7 +313,7 @@ namespace eosiosystem { update_total_votepay_share( ct, -total_inactive_vpay_share, delta_change_rate ); - _voters.modify( voter, 0, [&]( auto& av ) { + _voters.modify( voter, same_payer, [&]( auto& av ) { av.last_vote_weight = new_vote_weight; av.producers = producers; av.proxy = proxy; @@ -329,14 +329,14 @@ namespace eosiosystem { * @pre proxy must have something staked (existing row in voters table) * @pre new state must be different than current state */ - void system_contract::regproxy( const account_name proxy, bool isproxy ) { + void system_contract::regproxy( const name proxy, bool isproxy ) { require_auth( proxy ); - auto pitr = _voters.find(proxy); + auto pitr = _voters.find( proxy.value ); if ( pitr != _voters.end() ) { eosio_assert( isproxy != pitr->is_proxy, "action has no effect" ); eosio_assert( !isproxy || !pitr->proxy, "account that uses a proxy is not allowed to become a proxy" ); - _voters.modify( pitr, 0, [&]( auto& p ) { + _voters.modify( pitr, same_payer, [&]( auto& p ) { p.is_proxy = isproxy; }); propagate_weight_change( *pitr ); @@ -349,7 +349,7 @@ namespace eosiosystem { } void system_contract::propagate_weight_change( const voter_info& voter ) { - eosio_assert( voter.proxy == 0 || !voter.is_proxy, "account registered as a proxy is not allowed to use a proxy" ); + eosio_assert( !voter.proxy || !voter.is_proxy, "account registered as a proxy is not allowed to use a proxy" ); double new_weight = stake2vote( voter.staked ); if ( voter.is_proxy ) { new_weight += voter.proxied_vote_weight; @@ -358,8 +358,8 @@ namespace eosiosystem { /// don't propagate small changes (1 ~= epsilon) if ( fabs( new_weight - voter.last_vote_weight ) > 1 ) { if ( voter.proxy ) { - auto& proxy = _voters.get( voter.proxy, "proxy not found" ); //data corruption - _voters.modify( proxy, 0, [&]( auto& p ) { + auto& proxy = _voters.get( voter.proxy.value, "proxy not found" ); //data corruption + _voters.modify( proxy, same_payer, [&]( auto& p ) { p.proxied_vote_weight += new_weight - voter.last_vote_weight; } ); @@ -370,13 +370,13 @@ namespace eosiosystem { double delta_change_rate = 0; double total_inactive_vpay_share = 0; for ( auto acnt : voter.producers ) { - auto& prod = _producers.get( acnt, "producer not found" ); //data corruption + auto& prod = _producers.get( acnt.value, "producer not found" ); //data corruption const double init_total_votes = prod.total_votes; - _producers.modify( prod, 0, [&]( auto& p ) { + _producers.modify( prod, same_payer, [&]( auto& p ) { p.total_votes += delta; _gstate.total_producer_vote_weight += delta; }); - auto prod2 = _producers2.find( acnt ); + auto prod2 = _producers2.find( acnt.value ); if ( prod2 != _producers2.end() ) { const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); bool crossed_threshold = (last_claim_plus_3days <= ct); @@ -401,7 +401,7 @@ namespace eosiosystem { update_total_votepay_share( ct, -total_inactive_vpay_share, delta_change_rate ); } } - _voters.modify( voter, 0, [&]( auto& v ) { + _voters.modify( voter, same_payer, [&]( auto& v ) { v.last_vote_weight = new_weight; } ); diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 5934b8c1..2ca6636c 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -21,25 +21,25 @@ namespace eosio { public: token( name self ):contract(self){} - void create( account_name issuer, - asset maximum_supply); + void create( name issuer, + asset maximum_supply); - void issue( account_name to, asset quantity, string memo ); + void issue( name to, asset quantity, string memo ); void retire( asset quantity, string memo ); - void transfer( account_name from, - account_name to, - asset quantity, - string memo ); + void transfer( name from, + name to, + asset quantity, + string memo ); - void open( account_name owner, const symbol& symbol, account_name payer ); + void open( name owner, const symbol& symbol, name payer ); - void close( account_name owner, const symbol& symbol ); + void close( name owner, const symbol& symbol ); inline asset get_supply( const symbol& sym )const; - inline asset get_balance( account_name owner, symbol sym )const; + inline asset get_balance( name owner, symbol sym )const; private: struct account { @@ -49,9 +49,9 @@ namespace eosio { }; struct currency_stats { - asset supply; - asset max_supply; - account_name issuer; + asset supply; + asset max_supply; + name issuer; uint64_t primary_key()const { return supply.symbol.raw(); } }; @@ -59,15 +59,15 @@ namespace eosio { typedef eosio::multi_index< "accounts"_n, account > accounts; typedef eosio::multi_index< "stat"_n, currency_stats > stats; - void sub_balance( account_name owner, asset value ); - void add_balance( account_name owner, asset value, account_name ram_payer ); + void sub_balance( name owner, asset value ); + void add_balance( name owner, asset value, name ram_payer ); public: struct transfer_args { - account_name from; - account_name to; - asset quantity; - string memo; + name from; + name to; + asset quantity; + string memo; }; }; @@ -78,9 +78,9 @@ namespace eosio { return st.supply; } - asset token::get_balance( account_name owner, symbol sym )const + asset token::get_balance( name owner, symbol sym )const { - accounts accountstable( _self, owner ); + accounts accountstable( _self, owner.value ); const auto& ac = accountstable.get( sym.raw() ); eosio::print(sym); eosio::print(sym.raw()); diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index ea0fb017..d1bd2136 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -7,8 +7,8 @@ namespace eosio { -void token::create( account_name issuer, - asset maximum_supply ) +void token::create( name issuer, + asset maximum_supply ) { require_auth( _self ); @@ -29,7 +29,7 @@ void token::create( account_name issuer, } -void token::issue( account_name to, asset quantity, string memo ) +void token::issue( name to, asset quantity, string memo ) { auto sym = quantity.symbol; eosio_assert( sym.is_valid(), "invalid symbol name" ); @@ -47,7 +47,7 @@ void token::issue( account_name to, asset quantity, string memo ) eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); - statstable.modify( st, 0, [&]( auto& s ) { + statstable.modify( st, same_payer, [&]( auto& s ) { s.supply += quantity; }); @@ -77,17 +77,17 @@ void token::retire( asset quantity, string memo ) eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); - statstable.modify( st, 0, [&]( auto& s ) { + statstable.modify( st, same_payer, [&]( auto& s ) { s.supply -= quantity; }); sub_balance( st.issuer, quantity ); } -void token::transfer( account_name from, - account_name to, - asset quantity, - string memo ) +void token::transfer( name from, + name to, + asset quantity, + string memo ) { eosio_assert( from != to, "cannot transfer to self" ); require_auth( from ); @@ -110,8 +110,8 @@ void token::transfer( account_name from, add_balance( to, quantity, payer ); } -void token::sub_balance( account_name owner, asset value ) { - accounts from_acnts( _self, owner ); +void token::sub_balance( name owner, asset value ) { + accounts from_acnts( _self, owner.value ); const auto& from = from_acnts.get( value.symbol.raw(), "no balance object found" ); eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); @@ -121,25 +121,25 @@ void token::sub_balance( account_name owner, asset value ) { }); } -void token::add_balance( account_name owner, asset value, account_name ram_payer ) +void token::add_balance( name owner, asset value, name ram_payer ) { - accounts to_acnts( _self, owner ); + accounts to_acnts( _self, owner.value ); auto to = to_acnts.find( value.symbol.code().raw() ); if( to == to_acnts.end() ) { to_acnts.emplace( ram_payer, [&]( auto& a ){ a.balance = value; }); } else { - to_acnts.modify( to, 0, [&]( auto& a ) { + to_acnts.modify( to, same_payer, [&]( auto& a ) { a.balance += value; }); } } -void token::open( account_name owner, const symbol& symbol, account_name ram_payer ) +void token::open( name owner, const symbol& symbol, name ram_payer ) { require_auth( ram_payer ); - accounts acnts( _self, owner ); + accounts acnts( _self, owner.value ); auto it = acnts.find( symbol.code().raw() ); if( it == acnts.end() ) { acnts.emplace( ram_payer, [&]( auto& a ){ @@ -148,10 +148,10 @@ void token::open( account_name owner, const symbol& symbol, account_name ram_pay } } -void token::close( account_name owner, const symbol& symbol ) +void token::close( name owner, const symbol& symbol ) { require_auth( owner ); - accounts acnts( _self, owner ); + accounts acnts( _self, owner.value ); auto it = acnts.find( symbol.code().raw() ); eosio_assert( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); eosio_assert( it->balance.amount == 0, "Cannot close because the balance is not zero." ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7a879ea1..7b87fe5d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2238,22 +2238,26 @@ BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_t } BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); - auto* tbl = control->db().find( boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); + auto* tbl = control->db().find( + boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); BOOST_REQUIRE( tbl ); BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info2("defproducera")["last_votepay_share_update"] ) ); - control->db().remove( *tbl ); - tbl = control->db().find( boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); + // const_cast hack for now + const_cast(control->db()).remove( *tbl ); + tbl = control->db().find( + boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); BOOST_REQUIRE( !tbl ); BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); - tbl = control->db().find( boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); + tbl = control->db().find( + boost::make_tuple( config::system_account_name, + config::system_account_name, + N(producers2) ) ); BOOST_REQUIRE( !tbl ); BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducera)) ); BOOST_REQUIRE( microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducera))["last_claim_time"] ) < microseconds_since_epoch_of_iso_string( get_producer_info2(N(defproducera))["last_votepay_share_update"] ) ); From 8084dd8a09a6e7273bc184dc1a7fbe055f0a7086 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 4 Oct 2018 21:17:44 -0400 Subject: [PATCH 0577/1048] cleanup dependency on now removed eosiolib/types.hpp --- eosio.bios/include/eosio.bios/eosio.bios.hpp | 2 +- eosio.msig/include/eosio.msig/eosio.msig.hpp | 18 +++++++++--------- eosio.msig/src/eosio.msig.cpp | 12 ++++++------ eosio.system/include/eosio.system/native.hpp | 7 ++----- eosio.system/src/delegate_bandwidth.cpp | 1 - eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/voting.cpp | 3 +-- 7 files changed, 20 insertions(+), 25 deletions(-) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 99540a98..f05d34e2 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -54,7 +54,7 @@ namespace eosio { require_auth( from ); } - void setabi( name acnt, const bytes& abi ) { + void setabi( name acnt, const std::vector& abi ) { abi_hash_table table(_self, _self.value); auto itr = table.find( acnt.value ); if( itr == table.end() ) { diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index fde80e43..1a5b9f8e 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -17,17 +17,17 @@ namespace eosio { private: struct proposal { - name proposal_name; - vector packed_transaction; + name proposal_name; + std::vector packed_transaction; uint64_t primary_key()const { return proposal_name.value; } }; typedef eosio::multi_index< "proposal"_n, proposal > proposals; struct old_approvals_info { - name proposal_name; - vector requested_approvals; - vector provided_approvals; + name proposal_name; + std::vector requested_approvals; + std::vector provided_approvals; uint64_t primary_key()const { return proposal_name.value; } }; @@ -39,13 +39,13 @@ namespace eosio { }; struct approvals_info { - uint8_t version = 1; - name proposal_name; + uint8_t version = 1; + name proposal_name; //requested approval doesn't need to cointain time, but we want requested approval //to be of exact the same size ad provided approval, in this case approve/unapprove //doesn't change serialized data size. So, we use the same type. - vector requested_approvals; - vector provided_approvals; + std::vector requested_approvals; + std::vector provided_approvals; uint64_t primary_key()const { return proposal_name.value; } }; diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index 45e6d2fd..dd9da508 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -17,7 +17,7 @@ If we use dispatcher the function signature should be: void multisig::propose( name proposer, name proposal_name, - vector requested, + std::vector requested, transaction trx) */ @@ -29,7 +29,7 @@ void multisig::propose() { name proposer; name proposal_name; - vector requested; + std::vector requested; transaction_header trx_header; datastream ds( buffer, size ); @@ -45,7 +45,7 @@ void multisig::propose() { proposals proptable( _self, proposer.value ); eosio_assert( proptable.find( proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); - bytes packed_requested = pack(requested); + auto packed_requested = pack(requested); auto res = ::check_transaction_authorization( buffer+trx_pos, size-trx_pos, (const char*)0, 0, packed_requested.data(), packed_requested.size() @@ -54,7 +54,7 @@ void multisig::propose() { proptable.emplace( proposer, [&]( auto& prop ) { prop.proposal_name = proposal_name; - prop.packed_transaction = bytes( buffer+trx_pos, buffer+size ); + prop.packed_transaction = std::vector( buffer+trx_pos, buffer+size ); }); approvals apptable( _self, proposer.value ); @@ -154,7 +154,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { approvals apptable( _self, proposer.value ); auto apps_it = apptable.find( proposal_name.value ); - vector approvals; + std::vector approvals; invalidations inv_table( _self, _self.value ); if ( apps_it != apptable.end() ) { approvals.reserve( apps_it->provided_approvals.size() ); @@ -176,7 +176,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { } old_apptable.erase(apps); } - bytes packed_provided_approvals = pack(approvals); + auto packed_provided_approvals = pack(approvals); auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), (const char*)0, 0, packed_provided_approvals.data(), packed_provided_approvals.size() diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index 5dd3d3eb..41cf349a 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -18,8 +17,6 @@ namespace eosiosystem { using eosio::permission_level; using eosio::public_key; - typedef std::vector bytes; - struct permission_level_weight { permission_level permission; uint16_t weight; @@ -116,8 +113,8 @@ namespace eosiosystem { void canceldelay( /* permission_level canceling_auth, checksum256 trx_id */ ) {} - void onerror( /* const bytes& */ ) {} + void onerror( /* const std::vector& */ ) {} - void setabi( name acnt, const bytes& abi ); + void setabi( name acnt, const std::vector& abi ); }; } diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 4f59fdbb..6df4346d 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -22,7 +22,6 @@ namespace eosiosystem { using eosio::asset; using eosio::indexed_by; using eosio::const_mem_fun; - using eosio::bytes; using eosio::print; using eosio::permission_level; using eosio::time_point_sec; diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 689055af..07bd1d92 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -279,7 +279,7 @@ namespace eosiosystem { set_resource_limits( newact.value, 0, 0, 0 ); } - void native::setabi( name acnt, const bytes& abi ) { + void native::setabi( name acnt, const std::vector& abi ) { eosio::multi_index< "abihash"_n, abi_hash > table(_self, _self.value); auto itr = table.find( acnt.value ); if( itr == table.end() ) { diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 8e914b98..2ad09981 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -21,7 +21,6 @@ namespace eosiosystem { using eosio::indexed_by; using eosio::const_mem_fun; - using eosio::bytes; using eosio::print; using eosio::singleton; using eosio::transaction; @@ -113,7 +112,7 @@ namespace eosiosystem { for( const auto& item : top_producers ) producers.push_back(item.first); - bytes packed_schedule = pack(producers); + auto packed_schedule = pack(producers); if( set_proposed_producers( packed_schedule.data(), packed_schedule.size() ) >= 0 ) { _gstate.last_producer_schedule_size = static_cast( top_producers.size() ); From f4d4f800b61f05f2c6f2dfe3fa53f59bb2d21cd4 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 4 Oct 2018 21:32:46 -0400 Subject: [PATCH 0578/1048] update bios and system contract to use capi_checksum256 (for now) --- eosio.bios/include/eosio.bios/eosio.bios.hpp | 4 ++-- eosio.system/include/eosio.system/native.hpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index f05d34e2..e5c17789 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -6,8 +6,8 @@ namespace eosio { struct abi_hash { - name owner; - checksum256 hash; + name owner; + capi_checksum256 hash; uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index e4fb76a9..84041cd6 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -55,9 +55,9 @@ namespace eosiosystem { uint32_t timestamp; name producer; uint16_t confirmed = 0; - checksum256 previous; - checksum256 transaction_mroot; - checksum256 action_mroot; + capi_checksum256 previous; + capi_checksum256 transaction_mroot; + capi_checksum256 action_mroot; uint32_t schedule_version = 0; eosio::optional new_producers; @@ -68,8 +68,8 @@ namespace eosiosystem { struct abi_hash { - name owner; - checksum256 hash; + name owner; + capi_checksum256 hash; uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) From cacce4303f738d3cf80094fc2f3690e1cf2a618c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 5 Oct 2018 10:43:03 -0400 Subject: [PATCH 0579/1048] Test updaterex --- .../include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/rex.cpp | 2 +- tests/eosio.system_tester.hpp | 4 +++ tests/eosio.system_tests.cpp | 26 ++++++++++++++++++- 4 files changed, 31 insertions(+), 3 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 9c46bd27..f72dbefe 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -389,7 +389,7 @@ namespace eosiosystem { std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); void deposit_rex( const account_name& from, const asset& amount ); template - int64_t rentrex( T& table, account_name from, account_name receiver, asset payment, bool auto_renew, + int64_t rentrex( T& table, account_name from, account_name receiver, const asset& payment, bool auto_renew, const std::string& memo ); // defined in delegate_bandwidth.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index c8bcc1c3..d662963a 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -378,7 +378,7 @@ namespace eosiosystem { template int64_t system_contract::rentrex( T& table, account_name from, account_name receiver, - asset payment, bool auto_renew, const std::string& memo ) { + const asset& payment, bool auto_renew, const std::string& memo ) { runrex(2); eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 3ab607e2..9c8770db 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -318,6 +318,10 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(claimrefund), mvo()("owner", owner) ); } + action_result updaterex( const account_name& owner ) { + return push_action( name(owner), N(updaterex), mvo()("owner", owner) ); + } + fc::variant get_last_loan(bool cpu) { vector data; const auto& db = control->db(); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0f131a14..64e6bcd2 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3765,7 +3765,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_balance( N(eosio.names) )); produce_block( fc::hours(24) ); - produce_blocks( 10 ); + produce_blocks( 2 ); BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); BOOST_REQUIRE_EQUAL( success(), lendrex( frank, core_from_string("5.0000") ) ); @@ -3779,6 +3779,30 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester ) try { + + auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; + + const int64_t ratio = 10000; + const asset init_balance = core_from_string("10000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + setup_rex_accounts( accounts, init_balance ); + + const int64_t init_stake = get_voter_info( alice )["staked"].as(); + + BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("250.0000") ) ); + BOOST_REQUIRE_EQUAL( core_from_string("250.0000"), get_rex_vote_stake(alice) ); + BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); + + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, core_from_string("50.0000"), false ) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); + BOOST_REQUIRE_EQUAL( core_from_string("300.0000"), get_rex_vote_stake(alice) ); + BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); set_code( config::system_account_name, contracts::bios_wasm() ); From 7c0078eb838c728ab11ebc115ae4f7126cbd5139 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 5 Oct 2018 11:20:19 -0400 Subject: [PATCH 0580/1048] REX code refactoring --- eosio.system/abi/eosio.system.abi | 25 ++++++--- .../include/eosio.system/eosio.system.hpp | 6 ++- eosio.system/src/eosio.system.cpp | 3 +- eosio.system/src/rex.cpp | 52 +++++++++---------- tests/eosio.system_tester.hpp | 13 +++-- tests/eosio.system_tests.cpp | 4 +- 6 files changed, 64 insertions(+), 39 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index e8b5a3bf..f89dd048 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -307,13 +307,20 @@ {"name":"auto_renew", "type":"bool"} ] },{ - "name": "fundrexloan", + "name": "fundcpuloan", "base": "", "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"loan_num", "type":"uint64"}, - {"name":"payment", "type":"asset"}, - {"name":"cpu", "type":"bool"} + {"name":"from", "type":"account_name"}, + {"name":"loan_num", "type":"uint64"}, + {"name":"payment", "type":"asset"} + ] + },{ + "name": "fundnetloan", + "base": "", + "fields": [ + {"name":"from", "type":"account_name"}, + {"name":"loan_num", "type":"uint64"}, + {"name":"payment", "type":"asset"} ] },{ "name": "claimrefund", @@ -666,8 +673,12 @@ "type": "rentnet", "ricardian_contract": "" },{ - "name": "fundrexloan", - "type": "fundrexloan", + "name": "fundcpuloan", + "type": "fundcpuloan", + "ricardian_contract": "" + },{ + "name": "fundnetloan", + "type": "fundnetloan", "ricardian_contract": "" },{ "name": "claimrefund", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index f72dbefe..67862f45 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -302,7 +302,9 @@ namespace eosiosystem { void rentnet( account_name from, account_name receiver, asset payment, bool auto_renew ); - void fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ); + void fundcpuloan( account_name from, uint64_t loan_num, asset payment ); + + void fundnetloan( account_name from, uint64_t loan_num, asset payment ); void claimrefund( account_name owner ); @@ -391,6 +393,8 @@ namespace eosiosystem { template int64_t rentrex( T& table, account_name from, account_name receiver, const asset& payment, bool auto_renew, const std::string& memo ); + template + void fundrexloan( T& table, account_name from, uint64_t loan_num, const asset& payment, const std::string& memo ); // defined in delegate_bandwidth.cpp void changebw( account_name from, account_name receiver, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index ccc27add..20ad7651 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -298,7 +298,8 @@ EOSIO_ABI( eosiosystem::system_contract, // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundrexloan)(claimrefund)(updaterex) + (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) + (claimrefund)(updaterex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index d662963a..501319e7 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -189,35 +189,20 @@ namespace eosiosystem { update_resource_limits( receiver, 0, rented_tokens ); } - void system_contract::fundrexloan( account_name from, uint64_t loan_num, asset payment, bool cpu ) { + void system_contract::fundcpuloan( account_name from, uint64_t loan_num, asset payment ) { require_auth( from ); - eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {from,N(active)}, - { from, N(eosio.rex), payment, string("fund ") + (cpu ? "CPU loan" : "NET loan") } ); - // TODO: refactor and remove code duplication - if( cpu ) { - rex_cpu_loan_table cpu_loans( _self, _self ); - auto itr = cpu_loans.find( loan_num ); - eosio_assert( itr != cpu_loans.end(), "loan not found" ); - eosio_assert( itr->from == from, "actor has to be loan creator" ); - eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); - eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); - cpu_loans.modify( itr, 0, [&]( auto& loan ) { - loan.balance.amount += payment.amount; - }); - } else { - rex_net_loan_table net_loans( _self, _self ); - auto itr = net_loans.find( loan_num ); - eosio_assert( itr != net_loans.end(), "loan not found" ); - eosio_assert( itr->from == from, "actor has to be loan creator" ); - eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); - eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); - net_loans.modify( itr, 0, [&]( auto& loan ) { - loan.balance.amount += payment.amount; - }); - } + rex_cpu_loan_table cpu_loans( _self, _self ); + fundrexloan( cpu_loans, from, loan_num, payment, "fund CPU loan" ); + } + + void system_contract::fundnetloan( account_name from, uint64_t loan_num, asset payment ) { + + require_auth( from ); + + rex_net_loan_table net_loans( _self, _self ); + fundrexloan( net_loans, from, loan_num, payment, "fund NET loan" ); } void system_contract::claimrefund( account_name owner ) { @@ -449,4 +434,19 @@ namespace eosiosystem { } } + template + void system_contract::fundrexloan( T& table, account_name from, uint64_t loan_num, const asset& payment, const std::string& memo ) { + eosio_assert( payment.symbol == system_token_symbol, "asset must be system token" ); + INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { from, N(active) }, + { from, N(eosio.rex), payment, memo } ); + auto itr = table.find( loan_num ); + eosio_assert( itr != table.end(), "loan not found" ); + eosio_assert( itr->from == from, "actor has to be loan creator" ); + eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); + eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); + table.modify( itr, 0, [&]( auto& loan ) { + loan.balance.amount += payment.amount; + }); + } + }; /// namespace eosiosystem diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 9c8770db..de6c8d8b 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -305,12 +305,19 @@ class eosio_system_tester : public TESTER { ); } - action_result fundrexloan( const account_name& from, const uint64_t loan_num, const asset& payment, bool cpu ) { - return push_action( name(from), N(fundrexloan), mvo() + action_result fundcpuloan( const account_name& from, const uint64_t loan_num, const asset& payment ) { + return push_action( name(from), N(fundcpuloan), mvo() + ("from", from) + ("loan_num", loan_num) + ("payment", payment) + ); + } + + action_result fundnetloan( const account_name& from, const uint64_t loan_num, const asset& payment ) { + return push_action( name(from), N(fundnetloan), mvo() ("from", from) ("loan_num", loan_num) ("payment", payment) - ("cpu", cpu) ); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 64e6bcd2..61eeb099 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3672,7 +3672,9 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { // frank funds his loan enough to be renewed once const asset fund = core_from_string("35.0000"); - BOOST_REQUIRE_EQUAL( success(), fundrexloan( frank, 1, fund, true ) ); + BOOST_REQUIRE_EQUAL( fundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); + BOOST_REQUIRE_EQUAL( fundcpuloan( alice, 1, fund ), wasm_assert_msg("actor has to be loan creator") ); + BOOST_REQUIRE_EQUAL( success(), fundcpuloan( frank, 1, fund ) ); old_frank_balance = cur_frank_balance; cur_frank_balance = get_balance( frank ); loan_info = get_cpu_loan(1); From 54882bfd21218a21905d786ddf5f16a6125f83de Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 5 Oct 2018 13:50:19 -0400 Subject: [PATCH 0581/1048] bug fixes in eosio.token and eosio.system related to symbol_code --- .../include/eosio.system/exchange_state.hpp | 2 +- eosio.system/src/eosio.system.cpp | 10 ++++++---- eosio.system/src/producer_pay.cpp | 2 +- .../include/eosio.token/eosio.token.hpp | 20 +++++++++---------- eosio.token/src/eosio.token.cpp | 14 ++++++------- 5 files changed, 24 insertions(+), 24 deletions(-) diff --git a/eosio.system/include/eosio.system/exchange_state.hpp b/eosio.system/include/eosio.system/exchange_state.hpp index f6e29502..2f1e416d 100644 --- a/eosio.system/include/eosio.system/exchange_state.hpp +++ b/eosio.system/include/eosio.system/exchange_state.hpp @@ -26,7 +26,7 @@ namespace eosiosystem { connector base; connector quote; - uint64_t primary_key()const { return supply.symbol.code().raw(); } + uint64_t primary_key()const { return supply.symbol.raw(); } asset convert_to_exchange( connector& c, asset in ); asset convert_from_exchange( connector& c, asset in ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 07bd1d92..fac1c939 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -43,7 +43,7 @@ namespace eosiosystem { } symbol system_contract::get_core_symbol( const rammarket& rm ) { - auto itr = rm.find(ram_symbol.raw()); + auto itr = rm.find(ramcore_symbol.raw()); eosio_assert(itr != rm.end(), "system contract must first be initialized"); return itr->quote.balance.symbol; } @@ -301,14 +301,16 @@ namespace eosiosystem { auto itr = _rammarket.find(ramcore_symbol.raw()); eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); - auto system_token_supply = eosio::token(token_account).get_supply(core).amount; - if( system_token_supply > 0 ) { + auto system_token_supply = eosio::token(token_account).get_supply( core.code() ); + eosio_assert( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); + + if( system_token_supply.amount > 0 ) { _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; m.supply.symbol = ramcore_symbol; m.base.balance.amount = int64_t(_gstate.free_ram()); m.base.balance.symbol = ram_symbol; - m.quote.balance.amount = system_token_supply / 1000; + m.quote.balance.amount = system_token_supply.amount / 1000; m.quote.balance.symbol = core; }); } diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index d88c557e..40935f24 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -83,7 +83,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token(token_account).get_supply( core_symbol() ); + const asset token_supply = token(token_account).get_supply( core_symbol().code() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 2ca6636c..b6061b1b 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -37,15 +37,15 @@ namespace eosio { void close( name owner, const symbol& symbol ); - inline asset get_supply( const symbol& sym )const; + inline asset get_supply( symbol_code sym_code )const; - inline asset get_balance( name owner, symbol sym )const; + inline asset get_balance( name owner, symbol_code sym_code )const; private: struct account { asset balance; - uint64_t primary_key()const { return balance.symbol.raw(); } + uint64_t primary_key()const { return balance.symbol.code().raw(); } }; struct currency_stats { @@ -53,7 +53,7 @@ namespace eosio { asset max_supply; name issuer; - uint64_t primary_key()const { return supply.symbol.raw(); } + uint64_t primary_key()const { return supply.symbol.code().raw(); } }; typedef eosio::multi_index< "accounts"_n, account > accounts; @@ -71,19 +71,17 @@ namespace eosio { }; }; - asset token::get_supply( const symbol& sym )const + asset token::get_supply( symbol_code sym_code )const { - stats statstable( _self, sym.raw() ); - const auto& st = statstable.get( sym.raw() ); + stats statstable( _self, sym_code.raw() ); + const auto& st = statstable.get( sym_code.raw() ); return st.supply; } - asset token::get_balance( name owner, symbol sym )const + asset token::get_balance( name owner, symbol_code sym_code )const { accounts accountstable( _self, owner.value ); - const auto& ac = accountstable.get( sym.raw() ); - eosio::print(sym); - eosio::print(sym.raw()); + const auto& ac = accountstable.get( sym_code.raw() ); return ac.balance; } diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index d1bd2136..22dd4aeb 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -17,8 +17,8 @@ void token::create( name issuer, eosio_assert( maximum_supply.is_valid(), "invalid supply"); eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); - stats statstable( _self, sym.raw() ); - auto existing = statstable.find( sym.raw() ); + stats statstable( _self, sym.code().raw() ); + auto existing = statstable.find( sym.code().raw() ); eosio_assert( existing == statstable.end(), "token with symbol already exists" ); statstable.emplace( _self, [&]( auto& s ) { @@ -35,8 +35,8 @@ void token::issue( name to, asset quantity, string memo ) eosio_assert( sym.is_valid(), "invalid symbol name" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); - stats statstable( _self, sym.raw() ); - auto existing = statstable.find( sym.raw() ); + stats statstable( _self, sym.code().raw() ); + auto existing = statstable.find( sym.code().raw() ); eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); const auto& st = *existing; @@ -66,8 +66,8 @@ void token::retire( asset quantity, string memo ) eosio_assert( sym.is_valid(), "invalid symbol name" ); eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); - stats statstable( _self, sym.raw() ); - auto existing = statstable.find( sym.raw() ); + stats statstable( _self, sym.code().raw() ); + auto existing = statstable.find( sym.code().raw() ); eosio_assert( existing != statstable.end(), "token with symbol does not exist" ); const auto& st = *existing; @@ -113,7 +113,7 @@ void token::transfer( name from, void token::sub_balance( name owner, asset value ) { accounts from_acnts( _self, owner.value ); - const auto& from = from_acnts.get( value.symbol.raw(), "no balance object found" ); + const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" ); eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); from_acnts.modify( from, owner, [&]( auto& a ) { From d75e6804e5e2960da781848dc9ecad9a946a0248 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 5 Oct 2018 15:58:23 -0400 Subject: [PATCH 0582/1048] Modify REX order queueing logic --- eosio.system/abi/eosio.system.abi | 4 +- .../include/eosio.system/eosio.system.hpp | 7 ++- eosio.system/src/rex.cpp | 52 +++++++++++++------ tests/eosio.system_tests.cpp | 16 +++--- 4 files changed, 49 insertions(+), 30 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index f89dd048..5724ac06 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -283,8 +283,8 @@ "fields": [ {"name":"owner", "type":"account_name"}, {"name":"rex_requested", "type":"asset"}, - {"name":"proceeds", "type":"int64"}, - {"name":"unstake_quant", "type":"int64"}, + {"name":"proceeds", "type":"asset"}, + {"name":"unstake_quant", "type":"asset"}, {"name":"order_time", "type":"time_point"}, {"name":"is_open", "type":"bool"} ] diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 67862f45..df6ea680 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -169,7 +169,6 @@ namespace eosiosystem { typedef eosio::singleton global_state2_singleton; typedef eosio::singleton global_state3_singleton; - // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; static constexpr uint64_t system_token_symbol = CORE_SYMBOL; @@ -179,7 +178,7 @@ namespace eosiosystem { asset total_rent; /// fees received in exchange for lent (connector) asset total_lendable; /// total EOS that have been lent (total_unlent + total_lent) asset total_rex; /// total number of REX shares allocated to contributors to total_lendable - asset namebid_proceeds; + asset namebid_proceeds; /// EOS to be transferred from namebids to REX pool uint64_t loan_num = 0; /// increments with each new loan uint64_t primary_key()const { return 0; } }; @@ -234,8 +233,8 @@ namespace eosiosystem { struct rex_order { account_name owner; asset rex_requested; - int64_t proceeds = 0; - int64_t unstake_quant = 0; + asset proceeds; + asset unstake_quant; eosio::time_point order_time; bool is_open = true; diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 501319e7..f30317b9 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -91,23 +91,39 @@ namespace eosiosystem { auto result = close_rex_order( bitr, rex ); if( std::get<0>(result) ) { + /// unlendrex has been processed successfuly, transfer tokens and update voting power INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, { N(eosio.rex), from, asset( std::get<1>(result), system_token_symbol ), "sell REX" } ); update_voting_power( from, asset( -(std::get<2>(result)), system_token_symbol ) ); } else { - rex_order_table rexorders( _self, _self ); - eosio_assert( rexorders.find( from ) == rexorders.end(), "an unlendrex request has already been scheduled"); - rexorders.emplace( from, [&]( auto& ordr ) { - ordr.owner = from; - ordr.rex_requested = rex; - ordr.unstake_quant = std::get<2>(result); - ordr.order_time = current_time_point(); - }); + /** + * REX order couldn't be filled and is added to queue. + * If account already has an open order, requested rex is added to existing order. + * If account has a closed order, action fails and account must claimrex first in order + * to delete closed order from queue. + */ + rex_order_table rex_orders( _self, _self ); + auto oitr = rex_orders.find( from ); + if( oitr == rex_orders.end() ) { + rex_orders.emplace( from, [&]( auto& ordr ) { + ordr.owner = from; + ordr.rex_requested = rex; + ordr.order_time = current_time_point(); + }); + } else { + eosio_assert( oitr->is_open, "user has a closed rex order in queue, must claimrex first"); + rex_orders.modify( oitr, 0, [&]( auto& ordr ) { + ordr.rex_requested.amount += rex.amount; + eosio_assert( bitr->rex_balance >= ordr.rex_requested, "insufficient funds for current and scheduled orders"); + }); + } } } void system_contract::cnclrexorder( account_name owner ) { + require_auth( owner ); + rex_order_table rexorders( _self, _self ); auto itr = rexorders.find( owner ); eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); @@ -116,15 +132,18 @@ namespace eosiosystem { } void system_contract::claimrex( account_name owner ) { + require_auth( owner ); + runrex(2); - rex_order_table rexorders(_self, _self); + + rex_order_table rexorders( _self, _self ); auto itr = rexorders.find( owner ); eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); eosio_assert( !itr->is_open, "rex order has not been closed" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, - { N(eosio.rex), itr->owner, asset(itr->proceeds, system_token_symbol), "claim REX proceeds" } ); - update_voting_power( owner, asset( -( itr->unstake_quant ), system_token_symbol ) ); + { N(eosio.rex), itr->owner, itr->proceeds, "claim REX proceeds" } ); + update_voting_power( owner, -( itr->unstake_quant ) ); rexorders.erase( itr ); } @@ -296,7 +315,7 @@ namespace eosiosystem { return std::make_pair( delete_loan, delta_stake ); }; - // transfer from eosio.names to eosio.rex + /// transfer from eosio.names to eosio.rex if( rexi->namebid_proceeds.amount > 0 ) { deposit_rex( N(eosio.names), rexi->namebid_proceeds ); _rextable.modify( rexi, 0, [&]( auto& rt ) { @@ -304,7 +323,7 @@ namespace eosiosystem { }); } - // process cpu loans + /// process cpu loans { rex_cpu_loan_table cpu_loans( _self, _self ); auto cpu_idx = cpu_loans.get_index(); @@ -321,7 +340,7 @@ namespace eosiosystem { } } - // process net loans + /// process net loans { rex_net_loan_table net_loans( _self, _self ); auto net_idx = net_loans.get_index(); @@ -338,7 +357,7 @@ namespace eosiosystem { } } - // process unlendrex orders + /// process unlendrex orders { rex_order_table rex_orders( _self, _self ); auto idx = rex_orders.get_index(); @@ -351,7 +370,8 @@ namespace eosiosystem { ++next; if( std::get<0>( result ) ) { idx.modify( oitr, 0, [&]( auto& rt ) { - rt.proceeds = std::get<1>( result ); + rt.proceeds.amount = std::get<1>( result ); + rt.unstake_quant.amount = std::get<2>( result ); rt.close(); }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 61eeb099..4ce8925d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3567,13 +3567,13 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { // now bob's, carol's and alice's unlendrex requests have been queued BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(bob)["proceeds"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(bob)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); // wait for 30 days minus 1 hour produce_block( fc::hours(29*24 + 23) ); @@ -3588,22 +3588,22 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { // an action is needed to trigger queue processing produce_block( fc::hours(2) ); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("an unlendrex request has already been scheduled"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds for current and scheduled orders"), unlendrex( alice, init_alice_rex ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as() ); - BOOST_REQUIRE_EQUAL( purchase2.get_amount(), get_rex_order(bob)["unstake_quant"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( purchase2.get_amount(), get_rex_order(bob)["unstake_quant"].as().get_amount() ); BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); From bcce2517540302bb6809d19f8a77236ee0f47cec Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 5 Oct 2018 17:07:48 -0400 Subject: [PATCH 0583/1048] Rename lendrex and unlendrex to buyrex and sellrex --- eosio.system/abi/eosio.system.abi | 12 +-- .../include/eosio.system/eosio.system.hpp | 4 +- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/rex.cpp | 20 ++--- tests/eosio.system_tester.hpp | 14 +-- tests/eosio.system_tests.cpp | 86 +++++++++---------- 6 files changed, 69 insertions(+), 69 deletions(-) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi index 5724ac06..8051ffa3 100644 --- a/eosio.system/abi/eosio.system.abi +++ b/eosio.system/abi/eosio.system.abi @@ -206,14 +206,14 @@ {"name":"cpu_weight", "type":"asset"} ] },{ - "name": "lendrex", + "name": "buyrex", "base": "", "fields": [ {"name":"from", "type":"account_name"}, {"name":"amount", "type":"asset"} ] },{ - "name": "unlendrex", + "name": "sellrex", "base": "", "fields": [ {"name":"from", "type":"account_name"}, @@ -645,12 +645,12 @@ "type": "refund", "ricardian_contract": "" },{ - "name": "lendrex", - "type": "lendrex", + "name": "buyrex", + "type": "buyrex", "ricardian_contract": "" },{ - "name": "unlendrex", - "type": "unlendrex", + "name": "sellrex", + "type": "sellrex", "ricardian_contract": "" },{ "name": "cnclrexorder", diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index df6ea680..afa3dc70 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -284,12 +284,12 @@ namespace eosiosystem { /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ - void lendrex( account_name from, asset amount ); + void buyrex( account_name from, asset amount ); /** * Converts REX stake back into SYS tokens at current exchange rate */ - void unlendrex( account_name from, asset rex ); + void sellrex( account_name from, asset rex ); void cnclrexorder( account_name owner ); void claimrex( account_name owner ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 20ad7651..2273ff59 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -298,7 +298,7 @@ EOSIO_ABI( eosiosystem::system_contract, // eosio.system.cpp (setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (lendrex)(unlendrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) + (buyrex)(sellrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) (claimrefund)(updaterex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index f30317b9..bad22a34 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -9,7 +9,7 @@ namespace eosiosystem { /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ - void system_contract::lendrex( account_name from, asset amount ) { + void system_contract::buyrex( account_name from, asset amount ) { require_auth( from ); @@ -75,7 +75,7 @@ namespace eosiosystem { /** * Converts REX stake back into SYS tokens at current exchange rate */ - void system_contract::unlendrex( account_name from, asset rex ) { + void system_contract::sellrex( account_name from, asset rex ) { runrex(2); @@ -85,13 +85,13 @@ namespace eosiosystem { eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); auto bitr = _rexbalance.find( from ); - eosio_assert( bitr != _rexbalance.end(), "user must first lendrex" ); + eosio_assert( bitr != _rexbalance.end(), "user must first buyrex" ); eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); auto result = close_rex_order( bitr, rex ); if( std::get<0>(result) ) { - /// unlendrex has been processed successfuly, transfer tokens and update voting power + /// sellrex has been processed successfuly, transfer tokens and update voting power INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), { N(eosio.rex), N(active) }, { N(eosio.rex), from, asset( std::get<1>(result), system_token_symbol ), "sell REX" } ); update_voting_power( from, asset( -(std::get<2>(result)), system_token_symbol ) ); @@ -126,8 +126,8 @@ namespace eosiosystem { rex_order_table rexorders( _self, _self ); auto itr = rexorders.find( owner ); - eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); - eosio_assert( itr->is_open, "rex order has been closed and cannot be canceled" ); + eosio_assert( itr != rexorders.end(), "no sellrex order is scheduled" ); + eosio_assert( itr->is_open, "sellrex order has been closed and cannot be canceled" ); rexorders.erase( itr ); } @@ -139,8 +139,8 @@ namespace eosiosystem { rex_order_table rexorders( _self, _self ); auto itr = rexorders.find( owner ); - eosio_assert( itr != rexorders.end(), "no unlendrex is scheduled" ); - eosio_assert( !itr->is_open, "rex order has not been closed" ); + eosio_assert( itr != rexorders.end(), "no sellrex order is scheduled" ); + eosio_assert( !itr->is_open, "sellrex order has not been closed" ); INLINE_ACTION_SENDER(eosio::token, transfer)( N(eosio.token), {N(eosio.rex),N(active)}, { N(eosio.rex), itr->owner, itr->proceeds, "claim REX proceeds" } ); update_voting_power( owner, -( itr->unstake_quant ) ); @@ -295,7 +295,7 @@ namespace eosiosystem { } else { delete_loan = true; delta_stake = -( itr->total_staked.amount ); - // refund "from" account if the closed loan balance is positive + /// refund "from" account if the closed loan balance is positive if( itr->auto_renew && itr->balance.amount > 0 ) { loan_refund_table loan_refunds( _self, _self ); auto ref_itr = loan_refunds.find( itr->from ); @@ -357,7 +357,7 @@ namespace eosiosystem { } } - /// process unlendrex orders + /// process sellrex orders { rex_order_table rex_orders( _self, _self ); auto idx = rex_orders.get_index(); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index de6c8d8b..deb5535a 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -265,17 +265,17 @@ class eosio_system_tester : public TESTER { return unstake( acnt, acnt, net, cpu ); } - action_result lendrex( const account_name& from, const asset& amount ) { - return push_action( name(from), N(lendrex), mvo() - ("from", from) + action_result buyrex( const account_name& from, const asset& amount ) { + return push_action( name(from), N(buyrex), mvo() + ("from", from) ("amount", amount) ); } - action_result unlendrex( const account_name& from, const asset& rex ) { - return push_action( name(from), N(unlendrex), mvo() - ("from", from) - ("rex", rex) + action_result sellrex( const account_name& from, const asset& rex ) { + return push_action( name(from), N(sellrex), mvo() + ("from", from) + ("rex", rex) ); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 4ce8925d..96a89b22 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3371,7 +3371,7 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { +BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; const asset init_balance = core_from_string("1000.0000"); @@ -3379,7 +3379,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("30.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("30.0000") ) ); BOOST_REQUIRE_EQUAL( core_from_string("970.0000"), get_balance(alice) ); BOOST_REQUIRE_EQUAL( ratio * asset::from_string("30.0000 REX").get_amount(), get_rex_balance(alice).get_amount() ); auto rex_pool = get_rex_pool(); @@ -3389,7 +3389,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); BOOST_REQUIRE_EQUAL( get_rex_balance(alice), rex_pool["total_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), lendrex( bob, core_from_string("75.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_from_string("75.0000") ) ); BOOST_REQUIRE_EQUAL( core_from_string("925.0000"), get_balance(bob) ); BOOST_REQUIRE_EQUAL( ratio * asset::from_string("75.0000 REX").get_amount(), get_rex_balance(bob).get_amount() ); rex_pool = get_rex_pool(); @@ -3399,28 +3399,28 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first lendrex"), unlendrex( carol, asset::from_string("5.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset symbol must be (4, REX)"), unlendrex( bob, core_from_string("55.0000") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), unlendrex( bob, asset::from_string("750000.0030 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first buyrex"), sellrex( carol, asset::from_string("5.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset symbol must be (4, REX)"), sellrex( bob, core_from_string("55.0000") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); auto init_total_rex = rex_pool["total_rex"].as().get_amount(); auto init_total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, asset::from_string("550000.6800 REX") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset::from_string("550000.6800 REX") ) ); BOOST_REQUIRE_EQUAL( asset::from_string("199999.3200 REX"), get_rex_balance(bob) ); rex_pool = get_rex_pool(); auto total_rex = rex_pool["total_rex"].as().get_amount(); auto total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( init_total_rex / init_total_lendable, total_rex / total_lendable ); - BOOST_REQUIRE_EQUAL( total_lendable, rex_pool["total_unlent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( init_total_rex / init_total_lendable, total_rex / total_lendable ); + BOOST_REQUIRE_EQUAL( total_lendable, rex_pool["total_unlent"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( core_from_string("0.0000"), rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( core_from_string("100.0000"), rex_pool["total_rent"].as() ); BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { +BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; auto get_net_limit = [&](account_name a) -> int64_t { @@ -3448,7 +3448,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { // bob tries to rent rex BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_from_string("5.0000") ) ); // alice lends rex - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("65.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("65.0000") ) ); BOOST_REQUIRE_EQUAL( init_balance - core_from_string("65.0000"), get_balance(alice) ); auto rex_pool = get_rex_pool(); const asset init_tot_unlent = rex_pool["total_unlent"].as(); @@ -3477,18 +3477,18 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); - // alice tries to unlendrex, order gets scheduled then she cancels order - BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no unlendrex is scheduled") ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + // alice tries to sellrex, order gets scheduled then she cancels order + BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no sellrex order is scheduled") ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); produce_block( fc::days(20) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); produce_block( fc::days(10) ); - // alice is finally able to unlendrex, she gains the fee paid by bob - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + // alice is finally able to sellrex, she gains the fee paid by bob + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); // test that carol's resource limits have been updated properly when loan expires @@ -3507,7 +3507,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { // need to fix the corner case where rex system has been initialized but // balances are zero BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("110.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("110.0000") ) ); rex_pool = get_rex_pool(); const asset fee = core_from_string("132.4560"); int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), @@ -3520,7 +3520,7 @@ BOOST_FIXTURE_TEST_CASE( lend_rent_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { +BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; @@ -3534,9 +3534,9 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { const auto purchase2 = core_from_string("471.0000"); const auto purchase3 = core_from_string("469.0000"); const auto init_stake = get_voter_info(alice)["staked"].as(); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, purchase1) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( bob, purchase2) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( carol, purchase3) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( carol, purchase3) ); BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_balance(alice) ); BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); @@ -3548,7 +3548,7 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { auto init_carol_rex = get_rex_balance(carol); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_from_string("1100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); BOOST_REQUIRE_EQUAL( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ); BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_rex_vote_stake( alice ).get_amount() ); @@ -3556,15 +3556,15 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { init_alice_rex = get_rex_balance(alice); - BOOST_REQUIRE_EQUAL( success(), unlendrex( bob, get_rex_balance(bob) ) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( carol, get_rex_balance(carol) ) ); - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, get_rex_balance(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); - // now bob's, carol's and alice's unlendrex requests have been queued + // now bob's, carol's and alice's sellrex orders have been queued BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); @@ -3578,22 +3578,22 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { // wait for 30 days minus 1 hour produce_block( fc::hours(29*24 + 23) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( alice ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( bob ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), claimrex( carol ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( alice ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( bob ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( carol ) ); // wait for 2 more hours, by now frank's loan has expired and there is enough balance in - // total_unlent to close some unlendrex orders. only two are processed, bob's and carol's + // total_unlent to close some sellrex orders. only two are processed, bob's and carol's // alices's order is still open // an action is needed to trigger queue processing produce_block( fc::hours(2) ); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_from_string("0.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds for current and scheduled orders"), - unlendrex( alice, init_alice_rex ) ); + sellrex( alice, init_alice_rex ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( alice ) ); BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); @@ -3611,10 +3611,10 @@ BOOST_FIXTURE_TEST_CASE( lend_unlend_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex order has not been closed"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( alice ) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( emily, core_from_string("100.0000")) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_from_string("100.0000")) ); BOOST_REQUIRE_EQUAL( success(), claimrex( alice ) ); } FC_LOG_AND_RETHROW() @@ -3640,7 +3640,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("500.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("500.0000") ) ); auto rex_pool = get_rex_pool(); const asset payment = core_from_string("30.0000"); @@ -3695,7 +3695,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { payment.get_amount() ); } - BOOST_REQUIRE_EQUAL( success(), unlendrex( alice, asset::from_string("1.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); loan_info = get_cpu_loan(1); @@ -3715,7 +3715,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { // wait for another month, frank's loan doesn't have enough funds and will be closed produce_block( fc::hours(30*24) ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); BOOST_REQUIRE_EQUAL( init_stake, get_cpu_limit( bob ) ); BOOST_REQUIRE_EQUAL( success(), claimrefund( frank ) ); @@ -3740,7 +3740,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { asset cur_ramfee_balance = get_balance( N(eosio.ramfee) ); BOOST_REQUIRE_EQUAL( success(), buyram( alice, alice, core_from_string("20.0000") ) ); BOOST_REQUIRE_EQUAL( get_balance( N(eosio.ramfee) ), core_from_string("0.1000") + cur_ramfee_balance ); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("350.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("350.0000") ) ); cur_ramfee_balance = get_balance( N(eosio.ramfee) ); asset cur_rex_balance = get_balance( N(eosio.rex) ); BOOST_REQUIRE_EQUAL( core_from_string("350.0000"), cur_rex_balance ); @@ -3770,7 +3770,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { produce_blocks( 2 ); BOOST_REQUIRE_EQUAL( core_from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); - BOOST_REQUIRE_EQUAL( success(), lendrex( frank, core_from_string("5.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_from_string("5.0000") ) ); BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_from_string("34.3500") ); BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); @@ -3793,7 +3793,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester ) try { const int64_t init_stake = get_voter_info( alice )["staked"].as(); - BOOST_REQUIRE_EQUAL( success(), lendrex( alice, core_from_string("250.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("250.0000") ) ); BOOST_REQUIRE_EQUAL( core_from_string("250.0000"), get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); From 0c723285acb3046ffafb871945f741e402c2c7b8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 5 Oct 2018 18:07:38 -0400 Subject: [PATCH 0584/1048] Maintain voting condition while voter holds REX --- eosio.system/src/voting.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index e4ffb1d8..9ef0c3a8 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -195,6 +195,10 @@ namespace eosiosystem { */ void system_contract::voteproducer( const account_name voter_name, const account_name proxy, const std::vector& producers ) { require_auth( voter_name ); + auto rex_itr = _rexbalance.find( voter_name ); + if( rex_itr != _rexbalance.end() && rex_itr->rex_balance.amount > 0 ) { + eosio_assert( proxy || producers.size() >= 21, "voter holding REX must vote for a proxy or at least 21 producers"); + } update_votes( voter_name, proxy, producers, true ); } From 1de126f0e4c1fac7688bab90d877f25e3e316b6a Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 5 Oct 2018 18:45:39 -0400 Subject: [PATCH 0585/1048] Fix rex pool corner case --- eosio.system/src/rex.cpp | 16 ++++++++++++++-- tests/eosio.system_tests.cpp | 7 ++----- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index bad22a34..2bc8e512 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -15,6 +15,8 @@ namespace eosiosystem { eosio_assert( amount.symbol == system_token_symbol, "asset must be system token" ); + const int64_t rex_ratio = 10000; + const int64_t init_rent = 1000000; { auto vitr = _voters.find( from ); eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), @@ -29,14 +31,24 @@ namespace eosiosystem { auto itr = _rextable.begin(); if( itr == _rextable.end() ) { _rextable.emplace( _self, [&]( auto& rp ){ - rex_received.amount = amount.amount * 10000; + rex_received.amount = amount.amount * rex_ratio; rp.total_lendable = amount; rp.total_lent = asset( 0, system_token_symbol ); - rp.total_rent = asset( 1000000, system_token_symbol ); /// base amount prevents renting profitably until at least a minimum number of system_token_symbol are made available + rp.total_rent = asset( init_rent, system_token_symbol ); /// base amount prevents renting profitably until at least a minimum number of system_token_symbol are made available rp.total_rex = rex_received; rp.total_unlent = rp.total_lendable - rp.total_lent; }); + } else if( itr->total_lendable.amount == 0 ) { /// should be a rare corner case + _rextable.modify( itr, 0, [&]( auto& rp ) { + rex_received.amount = amount.amount * rex_ratio; + + rp.total_lendable.amount = amount.amount; + rp.total_lent.amount = 0; + rp.total_rex.amount = rex_received.amount; + rp.total_unlent.amount = amount.amount; + rp.total_rent.amount = std::min( init_rent, rp.total_rent.amount ); + }); } else { const auto S0 = itr->total_lendable.amount; const auto S1 = S0 + amount.amount; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 96a89b22..d0af0338 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3502,10 +3502,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { } { - // TODO: - // the following fails with "divide by zero" error message!! - // need to fix the corner case where rex system has been initialized but - // balances are zero + const int64_t init_net_limit = get_net_limit( emily ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_from_string("110.0000") ) ); rex_pool = get_rex_pool(); @@ -3514,7 +3511,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_pool["total_unlent"].as().get_amount(), fee.get_amount() ); BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, fee ) ); - BOOST_REQUIRE_EQUAL( expected_net, get_net_limit( emily ) - init_net.get_amount() ); + BOOST_REQUIRE_EQUAL( expected_net, get_net_limit( emily ) - init_net_limit ); } } FC_LOG_AND_RETHROW() From c79122a1bea3c2ccdda9846ce186f3aa5d13c18d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 5 Oct 2018 19:24:17 -0400 Subject: [PATCH 0586/1048] Add REX actions description --- .../include/eosio.system/eosio.system.hpp | 32 +++++++++++++++---- 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index afa3dc70..09ab8b87 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -287,26 +287,46 @@ namespace eosiosystem { void buyrex( account_name from, asset amount ); /** - * Converts REX stake back into SYS tokens at current exchange rate + * Converts REX stake back into SYS tokens at current exchange rate. If order cannot be + * processed, it gets queued untill it can be there is enough REX to fill order. */ void sellrex( account_name from, asset rex ); + + /** + * Cancels queued sellrex order. + */ void cnclrexorder( account_name owner ); + + /** + * Transfers processed sellrex order that had been queued proceeds to owner account. Fails if + * order hasn't been filled. + */ void claimrex( account_name owner ); /** - * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, - * after 30 days the rented SYS delegation of CPU or NET will expire. + * Use payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, + * after 30 days the rented SYS delegation of CPU or NET will expire unless auto_renew == true. + * If auto_renew == true, loan creator can fund that specific loan. Upon expiration, if loan has enough funds, it + * gets renewed at current market price, otherwise, the loan is closed and remaining balance if refunded to loan + * creator. User claims the refund in a separate action. */ void rentcpu( account_name from, account_name receiver, asset payment, bool auto_renew ); - void rentnet( account_name from, account_name receiver, asset payment, bool auto_renew ); - - void fundcpuloan( account_name from, uint64_t loan_num, asset payment ); + /** + * Loan initiator funds a given CPU or NET loan. Loan must've been set as autorenew. + */ + void fundcpuloan( account_name from, uint64_t loan_num, asset payment ); void fundnetloan( account_name from, uint64_t loan_num, asset payment ); + /** + * Transfers remaining balance of closed auto-renew loans to owner account. + */ void claimrefund( account_name owner ); + /** + * Updates REX vote stake of owner to its current value. + */ void updaterex( account_name owner ); /** From 0a1eb09825b5af6a5450e28d3c52ca8968fa2b01 Mon Sep 17 00:00:00 2001 From: Greg Lee Date: Sat, 6 Oct 2018 11:12:49 -0400 Subject: [PATCH 0587/1048] Spelling correction --- eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 09ab8b87..bc418a68 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -288,7 +288,7 @@ namespace eosiosystem { /** * Converts REX stake back into SYS tokens at current exchange rate. If order cannot be - * processed, it gets queued untill it can be there is enough REX to fill order. + * processed, it gets queued until it can be there is enough REX to fill order. */ void sellrex( account_name from, asset rex ); From 245c775cdb5bc010a59ad14711b8f2877b060d44 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 8 Oct 2018 00:01:20 -0400 Subject: [PATCH 0588/1048] changes for ignore type and abi generation --- eosio.bios/CMakeLists.txt | 4 +- eosio.bios/include/eosio.bios/eosio.bios.hpp | 15 ++-- eosio.bios/src/eosio.bios.cpp | 2 +- eosio.msig/CMakeLists.txt | 4 +- eosio.msig/include/eosio.msig/eosio.msig.hpp | 26 +++++-- eosio.msig/src/eosio.msig.cpp | 55 +++++++------- eosio.sudo/CMakeLists.txt | 5 +- eosio.sudo/abi/eosio.sudo.abi | 73 ------------------- eosio.sudo/include/eosio.sudo/eosio.sudo.hpp | 9 ++- eosio.sudo/src/eosio.sudo.cpp | 14 +--- .../include/eosio.system/eosio.system.hpp | 3 +- eosio.system/src/eosio.system.cpp | 7 +- .../include/eosio.token/eosio.token.hpp | 1 + eosio.token/src/eosio.token.cpp | 2 +- 14 files changed, 80 insertions(+), 140 deletions(-) delete mode 100644 eosio.sudo/abi/eosio.sudo.abi diff --git a/eosio.bios/CMakeLists.txt b/eosio.bios/CMakeLists.txt index 9f8841b0..265d8655 100644 --- a/eosio.bios/CMakeLists.txt +++ b/eosio.bios/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(eosio.bios.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) +add_eosio_cdt_executable(bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) target_include_directories(eosio.bios.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -7,4 +7,4 @@ set_target_properties(eosio.bios.wasm PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.bios.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) +#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.bios.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index e5c17789..9a628ac0 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -5,7 +5,7 @@ namespace eosio { - struct abi_hash { + struct [[eosio::contract("bios"), eosio::table]] abi_hash { name owner; capi_checksum256 hash; uint64_t primary_key()const { return owner.value; } @@ -15,25 +15,29 @@ namespace eosio { typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; - class bios : public contract { + class [[eosio::contract]] bios : public contract { public: - bios( name self ):contract(self){} + bios( name self, datastream ds ):contract(self,ds){} + [[eosio::action]] void setpriv( name account, uint8_t ispriv ) { require_auth( _self ); set_privileged( account.value, ispriv ); } + [[eosio::action]] void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { require_auth( _self ); set_resource_limits( account.value, ram_bytes, net_weight, cpu_weight ); } + [[eosio::action]] void setglimits( uint64_t ram, uint64_t net, uint64_t cpu ) { (void)ram; (void)net; (void)cpu; require_auth( _self ); } + [[eosio::action]] void setprods( std::vector schedule ) { (void)schedule; // schedule argument just forces the deserialization of the action data into vector (necessary check) require_auth( _self ); @@ -45,15 +49,18 @@ namespace eosio { set_proposed_producers(buffer, size); } + [[eosio::action]] void setparams( const eosio::blockchain_parameters& params ) { require_auth( _self ); set_blockchain_parameters( params ); } + [[eosio::action]] void reqauth( name from ) { require_auth( from ); } + [[eosio::action]] void setabi( name acnt, const std::vector& abi ) { abi_hash_table table(_self, _self.value); auto itr = table.find( acnt.value ); @@ -68,8 +75,6 @@ namespace eosio { }); } } - - private: }; } /// namespace eosio diff --git a/eosio.bios/src/eosio.bios.cpp b/eosio.bios/src/eosio.bios.cpp index 04ce20e6..01e85c02 100644 --- a/eosio.bios/src/eosio.bios.cpp +++ b/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,3 @@ #include -EOSIO_ABI( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi) ) +EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi) ) diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index 1741e7c9..1005c622 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,6 +1,6 @@ -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) +#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) -add_executable(eosio.msig.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) +add_eosio_cdt_executable(multisig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index 1a5b9f8e..b61676e8 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -1,36 +1,46 @@ #pragma once #include +#include #include namespace eosio { - class multisig : public contract { + class [[eosio::contract]] multisig : public contract { public: - multisig( name self ):contract(self){} - - void propose(); + multisig( name self, datastream ds ):contract(self, ds){} + + [[eosio::action]] + void propose(ignore proposer, ignore proposal_name, + ignore> requested, ignore trx); + [[eosio::action]] void approve( name proposer, name proposal_name, permission_level level ); + [[eosio::action]] void unapprove( name proposer, name proposal_name, permission_level level ); + [[eosio::action]] void cancel( name proposer, name proposal_name, name canceler ); + [[eosio::action]] void exec( name proposer, name proposal_name, name executer ); + [[eosio::action]] void invalidate( name account ); private: - struct proposal { + struct [[eosio::table]] proposal { name proposal_name; std::vector packed_transaction; uint64_t primary_key()const { return proposal_name.value; } }; + typedef eosio::multi_index< "proposal"_n, proposal > proposals; - struct old_approvals_info { + struct [[eosio::table]] old_approvals_info { name proposal_name; std::vector requested_approvals; std::vector provided_approvals; uint64_t primary_key()const { return proposal_name.value; } }; + typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals22; typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals; struct approval { @@ -38,7 +48,7 @@ namespace eosio { time_point time; }; - struct approvals_info { + struct [[eosio::table]] approvals_info { uint8_t version = 1; name proposal_name; //requested approval doesn't need to cointain time, but we want requested approval @@ -51,7 +61,7 @@ namespace eosio { }; typedef eosio::multi_index< "approvals2"_n, approvals_info > approvals; - struct invalidation { + struct [[eosio::table]] invalidation { name account; time_point last_invalidation_time; diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index dd9da508..d1e6d086 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -21,47 +21,48 @@ void multisig::propose( name proposer, transaction trx) */ -void multisig::propose() { +void multisig::propose(ignore proposer, ignore proposal_name, + ignore> requested, ignore trx) { constexpr size_t max_stack_buffer_size = 512; - size_t size = action_data_size(); - char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); - read_action_data( buffer, size ); - name proposer; - name proposal_name; - std::vector requested; - transaction_header trx_header; + name _proposer; + name _proposal_name; + std::vector _requested; + transaction_header _trx_header; - datastream ds( buffer, size ); - ds >> proposer >> proposal_name >> requested; + _ds >> _proposer >> _proposal_name >> _requested; - size_t trx_pos = ds.tellp(); - ds >> trx_header; + const char* trx_pos = _ds.pos(); + size_t size = _ds.remaining(); + _ds >> _trx_header; - require_auth( proposer ); - eosio_assert( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); + require_auth( _proposer ); + eosio_assert( _trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); //eosio_assert( trx_header.actions.size() > 0, "transaction must have at least one action" ); - proposals proptable( _self, proposer.value ); - eosio_assert( proptable.find( proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); + proposals proptable( _self, _proposer.value ); + eosio_assert( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); - auto packed_requested = pack(requested); - auto res = ::check_transaction_authorization( buffer+trx_pos, size-trx_pos, + auto packed_requested = pack(_requested); + auto res = ::check_transaction_authorization( trx_pos, size, (const char*)0, 0, packed_requested.data(), packed_requested.size() ); eosio_assert( res > 0, "transaction authorization failed" ); - proptable.emplace( proposer, [&]( auto& prop ) { - prop.proposal_name = proposal_name; - prop.packed_transaction = std::vector( buffer+trx_pos, buffer+size ); + std::vector pkd_trans; + pkd_trans.resize(size); + memcpy((char*)pkd_trans.data(), trx_pos, size); + proptable.emplace( _proposer, [&]( auto& prop ) { + prop.proposal_name = _proposal_name; + prop.packed_transaction = pkd_trans; }); - approvals apptable( _self, proposer.value ); - apptable.emplace( proposer, [&]( auto& a ) { - a.proposal_name = proposal_name; - a.requested_approvals.reserve( requested.size() ); - for ( auto& level : requested ) { + approvals apptable( _self, _proposer.value ); + apptable.emplace( _proposer, [&]( auto& a ) { + a.proposal_name = _proposal_name; + a.requested_approvals.reserve( _requested.size() ); + for ( auto& level : _requested ) { a.requested_approvals.push_back( approval{ level, time_point{ microseconds{0} } } ); } }); @@ -207,4 +208,4 @@ void multisig::invalidate( name account ) { } /// namespace eosio -EOSIO_ABI( eosio::multisig, (propose)(approve)(unapprove)(cancel)(exec)(invalidate) ) +EOSIO_DISPATCH( eosio::multisig, (propose)(approve)(unapprove)(cancel)(exec)(invalidate) ) diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt index b02d424e..6fb6d45c 100644 --- a/eosio.sudo/CMakeLists.txt +++ b/eosio.sudo/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(eosio.sudo.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) +add_eosio_cdt_executable(sudo eosio.sudo ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) target_include_directories(eosio.sudo.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -6,6 +6,3 @@ target_include_directories(eosio.sudo.wasm set_target_properties(eosio.sudo.wasm PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.sudo.abi" "${CMAKE__CURRENT_BINARY_DIR}" COPYONLY) -#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.sudo/abi/eosio.sudo.abi b/eosio.sudo/abi/eosio.sudo.abi deleted file mode 100644 index 6f74921b..00000000 --- a/eosio.sudo/abi/eosio.sudo.abi +++ /dev/null @@ -1,73 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - }], - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name": "actor", "type": "account_name"}, - {"name": "permission", "type": "permission_name"} - ] - },{ - "name": "action", - "base": "", - "fields": [ - {"name": "account", "type": "account_name"}, - {"name": "name", "type": "action_name"}, - {"name": "authorization", "type": "permission_level[]"}, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction_header", - "base": "", - "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": "extension", - "base": "", - "fields": [ - {"name": "type", "type" : "uint16" }, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction", - "base": "transaction_header", - "fields": [ - {"name": "context_free_actions", "type": "action[]"}, - {"name": "actions", "type": "action[]"}, - {"name": "transaction_extensions", "type": "extension[]"} - ] - },{ - "name": "exec", - "base": "", - "fields": [ - {"name":"executer", "type":"account_name"}, - {"name":"trx", "type":"transaction"} - ] - } - ], - "actions": [{ - "name": "exec", - "type": "exec", - "ricardian_contract": "" - } - ], - "tables": [], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp index 4ed435ff..a699ae58 100644 --- a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp +++ b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp @@ -1,14 +1,17 @@ #pragma once #include +#include +#include namespace eosio { - class sudo : public contract { + class [[eosio::contract]] sudo : public contract { public: - sudo( name self ):contract(self){} + sudo( name self, datastream ds ):contract(self, ds){} - void exec(); + [[eosio::action]] + void exec(ignore executer, ignore trx); }; diff --git a/eosio.sudo/src/eosio.sudo.cpp b/eosio.sudo/src/eosio.sudo.cpp index c426f2cc..aea8db54 100644 --- a/eosio.sudo/src/eosio.sudo.cpp +++ b/eosio.sudo/src/eosio.sudo.cpp @@ -1,5 +1,4 @@ #include -#include namespace eosio { @@ -13,25 +12,20 @@ void sudo::exec( name executer, transaction trx ) */ -void sudo::exec() { +void sudo::exec(ignore, ignore) { require_auth( _self ); constexpr size_t max_stack_buffer_size = 512; - size_t size = action_data_size(); - char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); - read_action_data( buffer, size ); name executer; - datastream ds( buffer, size ); - ds >> executer; + _ds >> executer; require_auth( executer ); - size_t trx_pos = ds.tellp(); - send_deferred( (uint128_t(executer.value) << 64) | current_time(), executer.value, buffer+trx_pos, size-trx_pos ); + send_deferred( (uint128_t(executer.value) << 64) | current_time(), executer.value, _ds.pos(), _ds.remaining() ); } } /// namespace eosio -EOSIO_ABI( eosio::sudo, (exec) ) +EOSIO_DISPATCH( eosio::sudo, (exec) ) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 11059f72..52d7577e 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -24,6 +24,7 @@ namespace eosiosystem { using eosio::block_timestamp; using eosio::time_point; using eosio::microseconds; + using eosio::datastream; struct name_bid { name newname; @@ -201,7 +202,7 @@ namespace eosiosystem { static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); - system_contract( name s ); + system_contract( name s, datastream ds ); ~system_contract(); static symbol get_core_symbol( const rammarket& rm ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index fac1c939..7dfc5adf 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -10,8 +10,8 @@ namespace eosiosystem { - system_contract::system_contract( name s ) - :native(s), + system_contract::system_contract( name s, datastream ds ) + :native(s,ds), _voters(_self, _self.value), _producers(_self, _self.value), _producers2(_self, _self.value), @@ -20,6 +20,7 @@ namespace eosiosystem { _global3(_self, _self.value), _rammarket(_self, _self.value) { + //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; @@ -318,7 +319,7 @@ namespace eosiosystem { } /// eosio.system -EOSIO_ABI( eosiosystem::system_contract, +EOSIO_DISPATCH( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index b6061b1b..43d024ab 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -20,6 +20,7 @@ namespace eosio { class token : public contract { public: token( name self ):contract(self){} + token( name self, datastream ds ):contract(self,ds){} void create( name issuer, asset maximum_supply); diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index 22dd4aeb..9e35fa58 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -160,4 +160,4 @@ void token::close( name owner, const symbol& symbol ) } /// namespace eosio -EOSIO_ABI( eosio::token, (create)(issue)(transfer)(open)(close)(retire) ) +EOSIO_DISPATCH( eosio::token, (create)(issue)(transfer)(open)(close)(retire) ) From cc2201c32ca1306878941cc60865fbcd05eb4b91 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 8 Oct 2018 12:44:17 -0400 Subject: [PATCH 0589/1048] added support for ignore types, new datastream constructor and support for abi generation --- eosio.bios/CMakeLists.txt | 2 - eosio.bios/abi/eosio.bios.abi | 276 -------- eosio.bios/include/eosio.bios/eosio.bios.hpp | 4 +- eosio.msig/CMakeLists.txt | 4 - eosio.msig/abi/eosio.msig.abi | 191 ------ eosio.msig/include/eosio.msig/eosio.msig.hpp | 1 - eosio.system/CMakeLists.txt | 7 +- eosio.system/abi/eosio.system.abi | 649 ------------------ .../include/eosio.system/eosio.system.hpp | 42 +- .../include/eosio.system/exchange_state.hpp | 2 +- eosio.system/include/eosio.system/native.hpp | 51 +- eosio.system/src/delegate_bandwidth.cpp | 6 +- eosio.system/src/eosio.system.cpp | 9 +- eosio.token/CMakeLists.txt | 5 +- eosio.token/abi/eosio.token.abi | 112 --- .../include/eosio.token/eosio.token.hpp | 16 +- tests/eosio.msig_tests.cpp | 4 +- tests/eosio.system_tester.hpp | 16 +- tests/eosio.system_tests.cpp | 4 +- 19 files changed, 98 insertions(+), 1303 deletions(-) delete mode 100644 eosio.bios/abi/eosio.bios.abi delete mode 100644 eosio.msig/abi/eosio.msig.abi delete mode 100644 eosio.system/abi/eosio.system.abi delete mode 100644 eosio.token/abi/eosio.token.abi diff --git a/eosio.bios/CMakeLists.txt b/eosio.bios/CMakeLists.txt index 265d8655..618751ec 100644 --- a/eosio.bios/CMakeLists.txt +++ b/eosio.bios/CMakeLists.txt @@ -6,5 +6,3 @@ target_include_directories(eosio.bios.wasm set_target_properties(eosio.bios.wasm PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.bios.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) diff --git a/eosio.bios/abi/eosio.bios.abi b/eosio.bios/abi/eosio.bios.abi deleted file mode 100644 index 64ef98be..00000000 --- a/eosio.bios/abi/eosio.bios.abi +++ /dev/null @@ -1,276 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - },{ - "new_type_name": "transaction_id_type", - "type": "checksum256" - },{ - "new_type_name": "weight_type", - "type": "uint16" - }], - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name":"actor", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "key_weight", - "base": "", - "fields": [ - {"name":"key", "type":"public_key"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "permission_level_weight", - "base": "", - "fields": [ - {"name":"permission", "type":"permission_level"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "wait_weight", - "base": "", - "fields": [ - {"name":"wait_sec", "type":"uint32"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "authority", - "base": "", - "fields": [ - {"name":"threshold", "type":"uint32"}, - {"name":"keys", "type":"key_weight[]"}, - {"name":"accounts", "type":"permission_level_weight[]"}, - {"name":"waits", "type":"wait_weight[]"} - ] - },{ - "name": "blockchain_parameters", - "base": "", - "fields": [ - {"name":"max_block_net_usage", "type":"uint64"}, - {"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":"uint32"}, - {"name":"max_inline_action_depth", "type":"uint16"}, - {"name":"max_authority_depth", "type":"uint16"} - ] - },{ - "name": "newaccount", - "base": "", - "fields": [ - {"name":"creator", "type":"account_name"}, - {"name":"name", "type":"account_name"}, - {"name":"owner", "type":"authority"}, - {"name":"active", "type":"authority"} - ] - },{ - "name": "setcode", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"vmtype", "type":"uint8"}, - {"name":"vmversion", "type":"uint8"}, - {"name":"code", "type":"bytes"} - ] - },{ - "name": "setabi", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"abi", "type":"bytes"} - ] - },{ - "name": "abi_hash", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"hash", "type":"checksum256"} - ] - },{ - "name": "updateauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"}, - {"name":"parent", "type":"permission_name"}, - {"name":"auth", "type":"authority"} - ] - },{ - "name": "deleteauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "linkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"}, - {"name":"requirement", "type":"permission_name"} - ] - },{ - "name": "unlinkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"} - ] - },{ - "name": "canceldelay", - "base": "", - "fields": [ - {"name":"canceling_auth", "type":"permission_level"}, - {"name":"trx_id", "type":"transaction_id_type"} - ] - },{ - "name": "onerror", - "base": "", - "fields": [ - {"name":"sender_id", "type":"uint128"}, - {"name":"sent_trx", "type":"bytes"} - ] - },{ - "name": "set_account_limits", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"ram_bytes", "type":"int64"}, - {"name":"net_weight", "type":"int64"}, - {"name":"cpu_weight", "type":"int64"} - ] - },{ - "name": "setpriv", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"is_priv", "type":"int8"} - ] - },{ - "name": "set_global_limits", - "base": "", - "fields": [ - {"name":"cpu_usec_per_period", "type":"int64"} - ] - },{ - "name": "producer_key", - "base": "", - "fields": [ - {"name":"producer_name", "type":"account_name"}, - {"name":"block_signing_key", "type":"public_key"} - ] - },{ - "name": "set_producers", - "base": "", - "fields": [ - {"name":"schedule", "type":"producer_key[]"} - ] - },{ - "name": "setparams", - "base": "", - "fields": [ - {"name":"params", "type":"blockchain_parameters"} - ] - },{ - "name": "require_auth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"} - ] - }], - "actions": [{ - "name": "newaccount", - "type": "newaccount", - "ricardian_contract": "" - },{ - "name": "setcode", - "type": "setcode", - "ricardian_contract": "" - },{ - "name": "setabi", - "type": "setabi", - "ricardian_contract": "" - },{ - "name": "updateauth", - "type": "updateauth", - "ricardian_contract": "" - },{ - "name": "deleteauth", - "type": "deleteauth", - "ricardian_contract": "" - },{ - "name": "linkauth", - "type": "linkauth", - "ricardian_contract": "" - },{ - "name": "unlinkauth", - "type": "unlinkauth", - "ricardian_contract": "" - },{ - "name": "canceldelay", - "type": "canceldelay", - "ricardian_contract": "" - },{ - "name": "onerror", - "type": "onerror", - "ricardian_contract": "" - },{ - "name": "setalimits", - "type": "set_account_limits", - "ricardian_contract": "" - },{ - "name": "setglimits", - "type": "set_global_limits", - "ricardian_contract": "" - },{ - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "" - },{ - "name": "setprods", - "type": "set_producers", - "ricardian_contract": "" - },{ - "name": "setparams", - "type": "setparams", - "ricardian_contract": "" - },{ - "name": "reqauth", - "type": "require_auth", - "ricardian_contract": "" - } - ], - "tables": [{ - "name": "abihash", - "type": "abi_hash", - "index_type": "i64", - "key_names": ["owner"], - "key_types": ["account_name"] - }], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 9a628ac0..0c46e2f4 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -20,9 +20,9 @@ namespace eosio { bios( name self, datastream ds ):contract(self,ds){} [[eosio::action]] - void setpriv( name account, uint8_t ispriv ) { + void setpriv( name account, uint8_t is_priv ) { require_auth( _self ); - set_privileged( account.value, ispriv ); + set_privileged( account.value, is_priv ); } [[eosio::action]] diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index 1005c622..6864e111 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,5 +1,3 @@ -#configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.msig.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) - add_eosio_cdt_executable(multisig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm PUBLIC @@ -8,5 +6,3 @@ target_include_directories(eosio.msig.wasm set_target_properties(eosio.msig.wasm PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.msig/abi/eosio.msig.abi b/eosio.msig/abi/eosio.msig.abi deleted file mode 100644 index 473198dc..00000000 --- a/eosio.msig/abi/eosio.msig.abi +++ /dev/null @@ -1,191 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - }], - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name": "actor", "type": "account_name"}, - {"name": "permission", "type": "permission_name"} - ] - },{ - "name": "action", - "base": "", - "fields": [ - {"name": "account", "type": "account_name"}, - {"name": "name", "type": "action_name"}, - {"name": "authorization", "type": "permission_level[]"}, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction_header", - "base": "", - "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": "extension", - "base": "", - "fields": [ - {"name": "type", "type" : "uint16" }, - {"name": "data", "type": "bytes"} - ] - },{ - "name": "transaction", - "base": "transaction_header", - "fields": [ - {"name": "context_free_actions", "type": "action[]"}, - {"name": "actions", "type": "action[]"}, - {"name": "transaction_extensions", "type": "extension[]"} - ] - },{ - "name": "propose", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"requested", "type":"permission_level[]"}, - {"name":"trx", "type":"transaction"} - ] - },{ - "name": "approve", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"level", "type":"permission_level"} - ] - },{ - "name": "unapprove", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"level", "type":"permission_level"} - ] - },{ - "name": "cancel", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"canceler", "type":"account_name"} - ] - },{ - "name": "exec", - "base": "", - "fields": [ - {"name":"proposer", "type":"account_name"}, - {"name":"proposal_name", "type":"name"}, - {"name":"executer", "type":"account_name"} - ] - },{ - "name": "invalidate", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - ] - },{ - "name": "proposal", - "base": "", - "fields": [ - {"name": "proposal_name", "type": "name"}, - {"name": "packed_transaction", "type": "bytes"} - ] - },{ - "name": "old_approvals_info", - "base": "", - "fields": [ - {"name": "proposal_name", "type": "name"}, - {"name": "requested_approvals", "type": "permission_level[]"}, - {"name": "provided_approvals", "type": "permission_level[]"} - ] - },{ - "name": "approval", - "base": "", - "fields": [ - {"name": "level", "type": "permission_level"}, - {"name": "time", "type": "time_point"} - ] - },{ - "name": "approvals_info", - "base": "", - "fields": [ - {"name": "version", "type": "uint8"}, - {"name": "proposal_name", "type": "name"}, - {"name": "requested_approvals", "type": "approval[]"}, - {"name": "provided_approvals", "type": "approval[]"} - ] - },{ - "name": "invalidation", - "base": "", - "fields": [ - {"name": "account", "type": "account_name"}, - {"name": "last_invalidation_time", "type": "time_point"} - ] - } - ], - "actions": [{ - "name": "propose", - "type": "propose", - "ricardian_contract": "" - },{ - "name": "approve", - "type": "approve", - "ricardian_contract": "" - },{ - "name": "unapprove", - "type": "unapprove", - "ricardian_contract": "" - },{ - "name": "cancel", - "type": "cancel", - "ricardian_contract": "" - },{ - "name": "exec", - "type": "exec", - "ricardian_contract": "" - },{ - "name": "invalidate", - "type": "invalidate", - "ricardian_contract": "" - } - - ], - "tables": [{ - "name": "proposal", - "type": "proposal", - "index_type": "i64", - "key_names" : ["proposal_name"], - "key_types" : ["name"] - },{ - "name": "approvals", - "type": "old_approvals_info", - "index_type": "i64", - "key_names" : ["proposal_name"], - "key_types" : ["name"] - },{ - "name": "approvals2", - "type": "approvals_info", - "index_type": "i64", - "key_names" : ["proposal_name"], - "key_types" : ["name"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index b61676e8..689759d1 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -40,7 +40,6 @@ namespace eosio { uint64_t primary_key()const { return proposal_name.value; } }; - typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals22; typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals; struct approval { diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index 8b47085e..594d135f 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -1,4 +1,5 @@ -add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) +add_eosio_cdt_executable(system_contract eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) +#add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) target_include_directories(eosio.system.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include @@ -7,7 +8,3 @@ target_include_directories(eosio.system.wasm set_target_properties(eosio.system.wasm PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.system.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) - -#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.system/abi/eosio.system.abi b/eosio.system/abi/eosio.system.abi deleted file mode 100644 index 35b6244a..00000000 --- a/eosio.system/abi/eosio.system.abi +++ /dev/null @@ -1,649 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - },{ - "new_type_name": "transaction_id_type", - "type": "checksum256" - },{ - "new_type_name": "weight_type", - "type": "uint16" - }], - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name":"actor", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "init", - "base": "", - "fields": [ - {"name":"version", "type": "varuint32"}, - {"name":"core", "type":"symbol"} - ] - },{ - "name": "abi_hash", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"hash", "type":"checksum256"} - ] - },{ - "name": "key_weight", - "base": "", - "fields": [ - {"name":"key", "type":"public_key"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "bidname", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"newname", "type":"account_name"}, - {"name":"bid", "type":"asset"} - ] - },{ - "name": "bidrefund", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"newname", "type":"account_name"} - ] - },{ - "name": "permission_level_weight", - "base": "", - "fields": [ - {"name":"permission", "type":"permission_level"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "wait_weight", - "base": "", - "fields": [ - {"name":"wait_sec", "type":"uint32"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "authority", - "base": "", - "fields": [ - {"name":"threshold", "type":"uint32"}, - {"name":"keys", "type":"key_weight[]"}, - {"name":"accounts", "type":"permission_level_weight[]"}, - {"name":"waits", "type":"wait_weight[]"} - ] - },{ - "name": "newaccount", - "base": "", - "fields": [ - {"name":"creator", "type":"account_name"}, - {"name":"name", "type":"account_name"}, - {"name":"owner", "type":"authority"}, - {"name":"active", "type":"authority"} - ] - },{ - "name": "setcode", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"vmtype", "type":"uint8"}, - {"name":"vmversion", "type":"uint8"}, - {"name":"code", "type":"bytes"} - ] - },{ - "name": "setabi", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"abi", "type":"bytes"} - ] - },{ - "name": "updateauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"}, - {"name":"parent", "type":"permission_name"}, - {"name":"auth", "type":"authority"} - ] - },{ - "name": "deleteauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "linkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"}, - {"name":"requirement", "type":"permission_name"} - ] - },{ - "name": "unlinkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"} - ] - },{ - "name": "canceldelay", - "base": "", - "fields": [ - {"name":"canceling_auth", "type":"permission_level"}, - {"name":"trx_id", "type":"transaction_id_type"} - ] - },{ - "name": "onerror", - "base": "", - "fields": [ - {"name":"sender_id", "type":"uint128"}, - {"name":"sent_trx", "type":"bytes"} - ] - },{ - "name": "buyrambytes", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"bytes", "type":"uint32"} - ] - },{ - "name": "sellram", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"bytes", "type":"uint64"} - ] - },{ - "name": "buyram", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"quant", "type":"asset"} - ] - },{ - "name": "delegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"stake_net_quantity", "type":"asset"}, - {"name":"stake_cpu_quantity", "type":"asset"}, - {"name":"transfer", "type":"bool"} - ] - },{ - "name": "undelegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"unstake_net_quantity", "type":"asset"}, - {"name":"unstake_cpu_quantity", "type":"asset"} - ] - },{ - "name": "refund", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "delegated_bandwidth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"} - ] - },{ - "name": "user_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "total_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "refund_request", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"request_time", "type":"time_point_sec"}, - {"name":"net_amount", "type":"asset"}, - {"name":"cpu_amount", "type":"asset"} - ] - },{ - "name": "blockchain_parameters", - "base": "", - "fields": [ - {"name":"max_block_net_usage", "type":"uint64"}, - {"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":"uint32"}, - {"name":"max_inline_action_depth", "type":"uint16"}, - {"name":"max_authority_depth", "type":"uint16"} - ] - },{ - "name": "eosio_global_state2", - "base": "", - "fields": [ - {"name":"new_ram_per_block", "type":"uint16"}, - {"name":"last_ram_increase", "type":"block_timestamp_type"}, - {"name":"last_block_num", "type":"block_timestamp_type"}, - {"name":"total_producer_votepay_share", "type":"float64"}, - {"name":"revision", "type":"uint8"} - ] - },{ - "name": "eosio_global_state3", - "base": "", - "fields": [ - {"name":"last_vpay_state_update", "type":"time_point"}, - {"name":"total_vpay_share_change_rate", "type":"float64"} - ] - },{ - "name": "eosio_global_state", - "base": "blockchain_parameters", - "fields": [ - {"name":"max_ram_size", "type":"uint64"}, - {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"int64"}, - {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, - {"name":"last_pervote_bucket_fill", "type":"time_point"}, - {"name":"pervote_bucket", "type":"int64"}, - {"name":"perblock_bucket", "type":"int64"}, - {"name":"total_unpaid_blocks", "type":"uint32"}, - {"name":"total_activated_stake", "type":"int64"}, - {"name":"thresh_activated_stake_time", "type":"time_point"}, - {"name":"last_producer_schedule_size", "type":"uint16"}, - {"name":"total_producer_vote_weight", "type":"float64"}, - {"name":"last_name_close", "type":"block_timestamp_type"} - ] - },{ - "name": "producer_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"total_votes", "type":"float64"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"is_active", "type":"bool"}, - {"name":"url", "type":"string"}, - {"name":"unpaid_blocks", "type":"uint32"}, - {"name":"last_claim_time", "type":"time_point"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "producer_info2", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"votepay_share", "type":"float64"}, - {"name":"last_votepay_share_update", "type":"time_point"} - ] - },{ - "name": "regproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"url", "type":"string"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "unregprod", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "setram", - "base": "", - "fields": [ - {"name":"max_ram_size", "type":"uint64"} - ] - },{ - "name": "setramrate", - "base": "", - "fields": [ - {"name":"bytes_per_block", "type":"uint16"} - ] - },{ - "name": "regproxy", - "base": "", - "fields": [ - {"name":"proxy", "type":"account_name"}, - {"name":"isproxy", "type":"bool"} - ] - },{ - "name": "voteproducer", - "base": "", - "fields": [ - {"name":"voter", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"} - ] - },{ - "name": "voter_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"}, - {"name":"staked", "type":"int64"}, - {"name":"last_vote_weight", "type":"float64"}, - {"name":"proxied_vote_weight", "type":"float64"}, - {"name":"is_proxy", "type":"bool"} - ] - },{ - "name": "claimrewards", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "setpriv", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"is_priv", "type":"int8"} - ] - },{ - "name": "rmvproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "updtrevision", - "base": "", - "fields": [ - {"name":"revision", "type":"uint8"} - ] - },{ - "name": "set_account_limits", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"ram_bytes", "type":"int64"}, - {"name":"net_weight", "type":"int64"}, - {"name":"cpu_weight", "type":"int64"} - ] - },{ - "name": "setparams", - "base": "", - "fields": [ - {"name":"params", "type":"blockchain_parameters"} - ] - },{ - "name": "connector", - "base": "", - "fields": [ - {"name":"balance", "type":"asset"}, - {"name":"weight", "type":"float64"} - ] - },{ - "name": "exchange_state", - "base": "", - "fields": [ - {"name":"supply", "type":"asset"}, - {"name":"base", "type":"connector"}, - {"name":"quote", "type":"connector"} - ] - }, { - "name": "name_bid", - "base": "", - "fields": [ - {"name":"newname", "type":"account_name"}, - {"name":"high_bidder", "type":"account_name"}, - {"name":"high_bid", "type":"int64"}, - {"name":"last_bid_time", "type":"time_point"} - ] - }, { - "name": "bid_refund", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"amount", "type":"asset"} - ] - } - ], - "actions": [{ - "name": "newaccount", - "type": "newaccount", - "ricardian_contract": "" - },{ - "name": "init", - "type": "init", - "ricardian_contract": "" - },{ - "name": "setcode", - "type": "setcode", - "ricardian_contract": "" - },{ - "name": "setabi", - "type": "setabi", - "ricardian_contract": "" - },{ - "name": "updateauth", - "type": "updateauth", - "ricardian_contract": "" - },{ - "name": "deleteauth", - "type": "deleteauth", - "ricardian_contract": "" - },{ - "name": "linkauth", - "type": "linkauth", - "ricardian_contract": "" - },{ - "name": "unlinkauth", - "type": "unlinkauth", - "ricardian_contract": "" - },{ - "name": "canceldelay", - "type": "canceldelay", - "ricardian_contract": "" - },{ - "name": "onerror", - "type": "onerror", - "ricardian_contract": "" - },{ - "name": "buyrambytes", - "type": "buyrambytes", - "ricardian_contract": "" - },{ - "name": "buyram", - "type": "buyram", - "ricardian_contract": "" - },{ - "name": "sellram", - "type": "sellram", - "ricardian_contract": "" - },{ - "name": "delegatebw", - "type": "delegatebw", - "ricardian_contract": "" - },{ - "name": "undelegatebw", - "type": "undelegatebw", - "ricardian_contract": "" - },{ - "name": "refund", - "type": "refund", - "ricardian_contract": "" - },{ - "name": "regproducer", - "type": "regproducer", - "ricardian_contract": "" - },{ - "name": "setram", - "type": "setram", - "ricardian_contract": "" - },{ - "name": "setramrate", - "type": "setramrate", - "ricardian_contract": "Sets the number of new bytes of ram to create per block and resyncs bancor base connector balance" - },{ - "name": "bidname", - "type": "bidname", - "ricardian_contract": "" - },{ - "name": "bidrefund", - "type": "bidrefund", - "ricardian_contract": "" - },{ - "name": "unregprod", - "type": "unregprod", - "ricardian_contract": "" - },{ - "name": "regproxy", - "type": "regproxy", - "ricardian_contract": "" - },{ - "name": "voteproducer", - "type": "voteproducer", - "ricardian_contract": "" - },{ - "name": "claimrewards", - "type": "claimrewards", - "ricardian_contract": "" - },{ - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "" - },{ - "name": "rmvproducer", - "type": "rmvproducer", - "ricardian_contract": "" - },{ - "name": "updtrevision", - "type": "updtrevision", - "ricardian_contract": "" - },{ - "name": "setalimits", - "type": "set_account_limits", - "ricardian_contract": "" - },{ - "name": "setparams", - "type": "setparams", - "ricardian_contract": "" - }], - "tables": [{ - "name": "producers", - "type": "producer_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "producers2", - "type": "producer_info2", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "global", - "type": "eosio_global_state", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "global2", - "type": "eosio_global_state2", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "global3", - "type": "eosio_global_state3", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "voters", - "type": "voter_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["account_name"] - },{ - "name": "userres", - "type": "user_resources", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "delband", - "type": "delegated_bandwidth", - "index_type": "i64", - "key_names" : ["to"], - "key_types" : ["uint64"] - },{ - "name": "rammarket", - "type": "exchange_state", - "index_type": "i64", - "key_names" : ["supply"], - "key_types" : ["uint64"] - },{ - "name": "refunds", - "type": "refund_request", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "namebids", - "type": "name_bid", - "index_type": "i64", - "key_names" : ["newname"], - "key_types" : ["account_name"] - },{ - "name": "bidrefunds", - "type": "bid_refund", - "index_type": "i64", - "key_names" : ["bidder"], - "key_types" : ["account_name"] - },{ - "name": "abihash", - "type": "abi_hash", - "index_type": "i64", - "key_names": ["owner"], - "key_types": ["account_name"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 52d7577e..9e41f69b 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -26,7 +26,7 @@ namespace eosiosystem { using eosio::microseconds; using eosio::datastream; - struct name_bid { + struct [[eosio::table, eosio::contract("system_contract")]] name_bid { name newname; name high_bidder; int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed @@ -36,7 +36,7 @@ namespace eosiosystem { uint64_t by_high_bid()const { return static_cast(-high_bid); } }; - struct bid_refund { + struct [[eosio::table, eosio::contract("system_contract")]] bid_refund { name bidder; asset amount; @@ -49,7 +49,7 @@ namespace eosiosystem { typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; - struct eosio_global_state : eosio::blockchain_parameters { + struct [[eosio::table("global"), eosio::contract("system_contract")]] eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; @@ -78,7 +78,7 @@ namespace eosiosystem { /** * Defines new global state parameters added after version 1.0 */ - struct eosio_global_state2 { + struct [[eosio::table("global2"), eosio::contract("system_contract")]] eosio_global_state2 { eosio_global_state2(){} uint16_t new_ram_per_block = 0; @@ -91,7 +91,7 @@ namespace eosiosystem { (total_producer_votepay_share)(revision) ) }; - struct eosio_global_state3 { + struct [[eosio::table("global3"), eosio::contract("system_contract")]] eosio_global_state3 { eosio_global_state3() { } time_point last_vpay_state_update; double total_vpay_share_change_rate = 0; @@ -99,7 +99,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) }; - struct producer_info { + struct [[eosio::table, eosio::contract("system_contract")]] producer_info { name owner; double total_votes = 0; eosio::public_key producer_key; /// a packed public key object @@ -119,7 +119,7 @@ namespace eosiosystem { (unpaid_blocks)(last_claim_time)(location) ) }; - struct producer_info2 { + struct [[eosio::table, eosio::contract("system_contract")]] producer_info2 { name owner; double votepay_share = 0; time_point last_votepay_share_update; @@ -130,7 +130,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) }; - struct voter_info { + struct [[eosio::table, eosio::contract("system_contract")]] voter_info { name owner; /// the voter name proxy; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set @@ -176,7 +176,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - class system_contract : public native { + class [[eosio::contract]] system_contract : public native { private: voters_table _voters; producers_table _producers; @@ -210,10 +210,13 @@ namespace eosiosystem { symbol core_symbol()const; // Actions: + [[eosio::action]] void init( unsigned_int version, symbol core ); + [[eosio::action]] void onblock( block_timestamp timestamp, name producer ); // const block_header& header ); /// only parse first 3 fields of block header + [[eosio::action]] void setalimits( name act, int64_t ram, int64_t net, int64_t cpu ); // functions defined in delegate_bandwidth.cpp @@ -222,6 +225,7 @@ namespace eosiosystem { * If transfer == true, then 'receiver' can unstake to their account * Else 'from' can unstake at any time. */ + [[eosio::action]] void delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); @@ -242,6 +246,7 @@ namespace eosiosystem { * The 'from' account loses voting power as a result of this call and * all producer tallies are updated. */ + [[eosio::action]] void undelegatebw( name from, name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ); @@ -251,47 +256,64 @@ namespace eosiosystem { * tokens provided. An inline transfer from receiver to system contract of * tokens will be executed. */ + [[eosio::action]] void buyram( name buyer, name receiver, asset tokens ); + [[eosio::action]] void buyrambytes( name buyer, name receiver, uint32_t bytes ); /** * Reduces quota my bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. */ + [[eosio::action]] void sellram( name receiver, int64_t bytes ); /** * This action is called after the delegation-period to claim all pending * unstaked tokens belonging to owner */ + [[eosio::action]] void refund( name owner ); // functions defined in voting.cpp + [[eosio::action]] void regproducer( const name producer, const public_key& producer_key, const std::string& url, uint16_t location ); + [[eosio::action]] void unregprod( const name producer ); + [[eosio::action]] void setram( uint64_t max_ram_size ); + [[eosio::action]] void setramrate( uint16_t bytes_per_block ); + [[eosio::action]] void voteproducer( const name voter, const name proxy, const std::vector& producers ); + [[eosio::action]] void regproxy( const name proxy, bool isproxy ); + [[eosio::action]] void setparams( const eosio::blockchain_parameters& params ); // functions defined in producer_pay.cpp + [[eosio::action]] void claimrewards( const name owner ); - void setpriv( name account, uint8_t ispriv ); + [[eosio::action]] + void setpriv( name account, uint8_t is_priv ); + [[eosio::action]] void rmvproducer( name producer ); + [[eosio::action]] void updtrevision( uint8_t revision ); + [[eosio::action]] void bidname( name bidder, name newname, asset bid ); + [[eosio::action]] void bidrefund( name bidder, name newname ); private: diff --git a/eosio.system/include/eosio.system/exchange_state.hpp b/eosio.system/include/eosio.system/exchange_state.hpp index 2f1e416d..f443e08d 100644 --- a/eosio.system/include/eosio.system/exchange_state.hpp +++ b/eosio.system/include/eosio.system/exchange_state.hpp @@ -13,7 +13,7 @@ namespace eosiosystem { * bancor exchange is entirely contained within this struct. There are no external * side effects associated with using this API. */ - struct exchange_state { + struct [[eosio::table, eosio::contract("system_contract")]] exchange_state { asset supply; struct connector { diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index 84041cd6..e598ad94 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -11,11 +11,13 @@ #include #include #include +#include namespace eosiosystem { using eosio::name; using eosio::permission_level; using eosio::public_key; + using eosio::ignore; struct permission_level_weight { permission_level permission; @@ -67,7 +69,7 @@ namespace eosiosystem { }; - struct abi_hash { + struct [[eosio::table("abihash"), eosio::contract("system_contract")]] abi_hash { name owner; capi_checksum256 hash; uint64_t primary_key()const { return owner.value; } @@ -78,7 +80,7 @@ namespace eosiosystem { /* * Method parameters commented out to prevent generation of code that parses input data. */ - class native : public eosio::contract { + class [[eosio::contract("system_contract")]] native : public eosio::contract { public: using eosio::contract::contract; @@ -95,34 +97,41 @@ namespace eosiosystem { * therefore, this method will execute an inline buyram from receiver for newacnt in * an amount equal to the current new account creation fee. */ + [[eosio::action]] void newaccount( name creator, - name newact - /* no need to parse authorites - const authority& owner, - const authority& active*/ ); + name newact, + ignore owner, + ignore active); - void updateauth( /* name account, - name permission, - name parent, - const authority& data */ ) {} + [[eosio::action]] + void updateauth( ignore account, + ignore permission, + ignore parent, + ignore auth ) {} - void deleteauth( /* name account, - name permission */ ) {} + [[eosio::action]] + void deleteauth( ignore account, + ignore permission ) {} - void linkauth( /* name account, - name code, - name type, - name requirement */ ) {} + [[eosio::action]] + void linkauth( ignore account, + ignore code, + ignore type, + ignore requirement ) {} - void unlinkauth( /* name account, - name code, - name type*/ ) {} + [[eosio::action]] + void unlinkauth( ignore account, + ignore code, + ignore type ) {} - void canceldelay( /* permission_level canceling_auth, checksum256 trx_id */ ) {} + [[eosio::action]] + void canceldelay( ignore canceling_auth, ignore trx_id ) {} - void onerror( /* const std::vector& */ ) {} + [[eosio::action]] + void onerror( ignore sender_id, ignore> sent_trx ) {} + [[eosio::action]] void setabi( name acnt, const std::vector& abi ); }; } diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 6df4346d..2fcfb091 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -31,7 +31,7 @@ namespace eosiosystem { static constexpr uint32_t refund_delay_sec = 3*24*3600; static constexpr int64_t ram_gift_bytes = 1400; - struct user_resources { + struct [[eosio::table, eosio::contract("system_contract")]] user_resources { name owner; asset net_weight; asset cpu_weight; @@ -47,7 +47,7 @@ namespace eosiosystem { /** * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. */ - struct delegated_bandwidth { + struct [[eosio::table, eosio::contract("system_contract")]] delegated_bandwidth { name from; name to; asset net_weight; @@ -60,7 +60,7 @@ namespace eosiosystem { }; - struct refund_request { + struct [[eosio::table, eosio::contract("system_contract")]] refund_request { name owner; time_point_sec request_time; eosio::asset net_amount; diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 7dfc5adf..749787af 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -240,11 +240,10 @@ namespace eosiosystem { * who can create accounts with the creator's name as a suffix. * */ - void native::newaccount( name creator, - name newact - /* no need to parse authorites - const authority& owner, - const authority& active*/ ) { + void native::newaccount( name creator, + name newact, + ignore owner, + ignore active ) { if( creator != _self ) { uint64_t tmp = newact.value >> 4; diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt index 9ff728c3..7a16bc7e 100644 --- a/eosio.token/CMakeLists.txt +++ b/eosio.token/CMakeLists.txt @@ -1,4 +1,4 @@ -add_executable(eosio.token.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) +add_eosio_cdt_executable(token eosio.token ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) target_include_directories(eosio.token.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) @@ -6,6 +6,3 @@ target_include_directories(eosio.token.wasm set_target_properties(eosio.token.wasm PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/abi/eosio.token.abi" "${CMAKE_CURRENT_BINARY_DIR}" COPYONLY) -#install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/ DESTINATION ${WASM_ROOT}/eosio.wasmsdk/include) diff --git a/eosio.token/abi/eosio.token.abi b/eosio.token/abi/eosio.token.abi deleted file mode 100644 index 91f76404..00000000 --- a/eosio.token/abi/eosio.token.abi +++ /dev/null @@ -1,112 +0,0 @@ -{ - "version": "eosio::abi/1.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":"asset"}, - {"name":"memo", "type":"string"} - ] - },{ - "name": "create", - "base": "", - "fields": [ - {"name":"issuer", "type":"account_name"}, - {"name":"maximum_supply", "type":"asset"} - ] - },{ - "name": "issue", - "base": "", - "fields": [ - {"name":"to", "type":"account_name"}, - {"name":"quantity", "type":"asset"}, - {"name":"memo", "type":"string"} - ] - },{ - "name": "retire", - "base": "", - "fields": [ - {"name":"quantity", "type":"asset"}, - {"name":"memo", "type":"string"} - ] - },{ - "name": "open", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"symbol", "type":"symbol"}, - {"name":"ram_payer", "type":"account_name"} - ] - },{ - "name": "close", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"symbol", "type":"symbol"} - ] - },{ - "name": "account", - "base": "", - "fields": [ - {"name":"balance", "type":"asset"} - ] - },{ - "name": "currency_stats", - "base": "", - "fields": [ - {"name":"supply", "type":"asset"}, - {"name":"max_supply", "type":"asset"}, - {"name":"issuer", "type":"account_name"} - ] - } - ], - "actions": [{ - "name": "transfer", - "type": "transfer", - "ricardian_contract": "" - },{ - "name": "issue", - "type": "issue", - "ricardian_contract": "" - },{ - "name": "retire", - "type": "retire", - "ricardian_contract": "" - }, { - "name": "create", - "type": "create", - "ricardian_contract": "" - }, { - "name": "open", - "type": "open", - "ricardian_contract": "" - }, { - "name": "close", - "type": "close", - "ricardian_contract": "" - } - - ], - "tables": [{ - "name": "accounts", - "type": "account", - "index_type": "i64", - "key_names" : ["currency"], - "key_types" : ["uint64"] - },{ - "name": "stat", - "type": "currency_stats", - "index_type": "i64", - "key_names" : ["currency"], - "key_types" : ["uint64"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 43d024ab..4beabcab 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -17,25 +17,31 @@ namespace eosio { using std::string; - class token : public contract { + class [[eosio::contract]] token : public contract { public: token( name self ):contract(self){} token( name self, datastream ds ):contract(self,ds){} - + + [[eosio::action]] void create( name issuer, asset maximum_supply); + [[eosio::action]] void issue( name to, asset quantity, string memo ); + [[eosio::action]] void retire( asset quantity, string memo ); + [[eosio::action]] void transfer( name from, name to, asset quantity, string memo ); - void open( name owner, const symbol& symbol, name payer ); + [[eosio::action]] + void open( name owner, const symbol& symbol, name ram_payer ); + [[eosio::action]] void close( name owner, const symbol& symbol ); inline asset get_supply( symbol_code sym_code )const; @@ -43,13 +49,13 @@ namespace eosio { inline asset get_balance( name owner, symbol_code sym_code )const; private: - struct account { + struct [[eosio::table]] account { asset balance; uint64_t primary_key()const { return balance.symbol.code().raw(); } }; - struct currency_stats { + struct [[eosio::table]] currency_stats { asset supply; asset max_supply; name issuer; diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index a5e3a830..13c1120c 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -62,9 +62,9 @@ class eosio_msig_tester : public tester { trx.actions.emplace_back( get_action( N(eosio), N(buyram), vector{{creator,config::active_name}}, mvo() - ("payer", creator) + ("buyer", creator) ("receiver", a) - ("quant", ramfunds) ) + ("tokens", ramfunds) ) ); trx.actions.emplace_back( get_action( N(eosio), N(delegatebw), vector{{creator,config::active_name}}, diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 1d26caef..b95fa6c5 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -144,7 +144,7 @@ class eosio_system_tester : public TESTER { trx.actions.emplace_back( get_action( config::system_account_name, N(buyrambytes), vector{{creator,config::active_name}}, mvo() - ("payer", creator) + ("buyer", creator) ("receiver", a) ("bytes", ram_bytes) ) ); @@ -186,9 +186,9 @@ class eosio_system_tester : public TESTER { trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{{creator,config::active_name}}, mvo() - ("payer", creator) + ("buyer", creator) ("receiver", a) - ("quant", ramfunds) ) + ("tokens", ramfunds) ) ); trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, @@ -228,9 +228,9 @@ class eosio_system_tester : public TESTER { trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{ {creator, config::active_name} }, mvo() - ("payer", creator) + ("buyer", creator) ("receiver", a) - ("quant", ram) ) + ("tokens", ram) ) ); trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{ {creator, config::active_name} }, @@ -250,14 +250,14 @@ class eosio_system_tester : public TESTER { } action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { - return push_action( payer, N(buyram), mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); + return push_action( payer, N(buyram), mvo()( "buyer",payer)("receiver",receiver)("tokens",eosin) ); } action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { - return push_action( payer, N(buyrambytes), mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); + return push_action( payer, N(buyrambytes), mvo()( "buyer",payer)("receiver",receiver)("bytes",numbytes) ); } action_result sellram( const account_name& account, uint64_t numbytes ) { - return push_action( account, N(sellram), mvo()( "account", account)("bytes",numbytes) ); + return push_action( account, N(sellram), mvo()( "receiver", account)("bytes",numbytes) ); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7b87fe5d..f5744d53 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2387,7 +2387,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) ("ref_block_prefix", 3) - ("max_net_usage_words", 0) + ("net_usage_words", 0) ("max_cpu_usage_ms", 0) ("delay_sec", 0) ("actions", fc::variants({ @@ -3163,7 +3163,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { ("expiration", "2020-01-01T00:30") ("ref_block_num", 2) ("ref_block_prefix", 3) - ("max_net_usage_words", 0) + ("net_usage_words", 0) ("max_cpu_usage_ms", 0) ("delay_sec", 0) ("actions", fc::variants({ From d1938b6ab0f9c62ba8d6469489d8f2909f1cf8c1 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 8 Oct 2018 15:38:26 -0400 Subject: [PATCH 0590/1048] fixed tests --- eosio.system/include/eosio.system/native.hpp | 3 + tests/eosio.system_tests.cpp | 80 ++++++++++++++++++-- 2 files changed, 78 insertions(+), 5 deletions(-) diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index e598ad94..837394c2 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -133,5 +133,8 @@ namespace eosiosystem { [[eosio::action]] void setabi( name acnt, const std::vector& abi ); + + [[eosio::action]] + void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} }; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index f5744d53..0afac496 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1214,7 +1214,6 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t transfer( config::system_account_name, "producvotera", core_sym::from_string("400000000.0000"), config::system_account_name); BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera) })); - // defproducera is the only active producer // produce enough blocks so new schedule kicks in and defproducera produces some blocks { @@ -2290,12 +2289,47 @@ BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); t.abi_ser.set_abi(abi, eosio_system_tester::abi_serializer_max_time); } - const asset net = old_core_from_string("80.0000"); const asset cpu = old_core_from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - t.create_account_with_resources( v, config::system_account_name, old_core_from_string("1.0000"), false, net, cpu ); + { + signed_transaction trx; + t.set_transaction_headers(trx); + + authority owner_auth; + owner_auth = authority( t.get_public_key( account_name(v), "owner" ) ); + + trx.actions.emplace_back( vector{{config::system_account_name,config::active_name}}, + newaccount{ + .creator = config::system_account_name, + .name = account_name(v), + .owner = owner_auth, + .active = authority( t.get_public_key( account_name(v), "active" ) ) + }); + + trx.actions.emplace_back( t.get_action( config::system_account_name, N(buyram), vector{{config::system_account_name,config::active_name}}, + mvo() + ("payer", account_name(config::system_account_name).to_string()) + ("receiver", v) + ("quant", old_core_from_string("1.0000") ) ) + ); + + trx.actions.emplace_back( t.get_action( config::system_account_name, N(delegatebw), vector{{config::system_account_name,config::active_name}}, + mvo() + ("from", account_name(config::system_account_name).to_string()) + ("receiver", v) + ("stake_net_quantity", net ) + ("stake_cpu_quantity", cpu ) + ("transfer", 0 ) + ) + ); + + t.set_transaction_headers(trx); + trx.sign( t.get_private_key( config::system_account_name, "active" ), t.control->get_chain_id() ); + t.push_transaction( trx ); + } + t.transfer( config::system_account_name, v, old_core_from_string("100000000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL(t.success(), t.stake(v, old_core_from_string("30000000.0000"), old_core_from_string("30000000.0000")) ); } @@ -2310,8 +2344,44 @@ BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) producer_names.emplace_back(root + std::string(1, c)); } } - t.setup_producer_accounts( producer_names, old_core_from_string("1.0000"), - old_core_from_string("80.0000"), old_core_from_string("80.0000") ); + { + account_name creator(config::system_account_name); + signed_transaction trx; + t.set_transaction_headers(trx); + + for (const auto& a: producer_names) { + authority owner_auth( t.get_public_key( a, "owner" ) ); + trx.actions.emplace_back( vector{{creator,config::active_name}}, + newaccount{ + .creator = creator, + .name = a, + .owner = owner_auth, + .active = authority( t.get_public_key( a, "active" ) ) + }); + + trx.actions.emplace_back( t.get_action( config::system_account_name, N(buyram), vector{ {creator, config::active_name} }, + mvo() + ("payer", creator) + ("receiver", a) + ("quant", old_core_from_string("1.0000")) ) + ); + + trx.actions.emplace_back( t.get_action( config::system_account_name, N(delegatebw), vector{ {creator, config::active_name} }, + mvo() + ("from", creator) + ("receiver", a) + ("stake_net_quantity", old_core_from_string("80.0000")) + ("stake_cpu_quantity", old_core_from_string("80.0000") ) + ("transfer", 0 ) + ) + ); + } + + t.set_transaction_headers(trx); + trx.sign( t.get_private_key( creator, "active" ), t.control->get_chain_id() ); + t.push_transaction( trx ); + } + for (const auto& p: producer_names) { BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(p) ); BOOST_TEST_REQUIRE(0 == t.get_producer_info(p)["total_votes"].as_double()); From 44174209fe020b406a1d909c71b6c498f6e0f1df Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 9 Oct 2018 15:38:21 -0400 Subject: [PATCH 0591/1048] update to use code in constructor --- eosio.bios/CMakeLists.txt | 2 +- eosio.bios/include/eosio.bios/eosio.bios.hpp | 2 +- eosio.msig/CMakeLists.txt | 2 +- eosio.msig/include/eosio.msig/eosio.msig.hpp | 2 +- eosio.sudo/CMakeLists.txt | 2 +- eosio.sudo/include/eosio.sudo/eosio.sudo.hpp | 2 +- eosio.system/CMakeLists.txt | 2 +- eosio.system/include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/eosio.system.cpp | 6 +++--- eosio.system/src/producer_pay.cpp | 2 +- eosio.token/CMakeLists.txt | 2 +- eosio.token/include/eosio.token/eosio.token.hpp | 4 ++-- 12 files changed, 15 insertions(+), 15 deletions(-) diff --git a/eosio.bios/CMakeLists.txt b/eosio.bios/CMakeLists.txt index 618751ec..0dfccd8d 100644 --- a/eosio.bios/CMakeLists.txt +++ b/eosio.bios/CMakeLists.txt @@ -1,4 +1,4 @@ -add_eosio_cdt_executable(bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) +add_contract(bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) target_include_directories(eosio.bios.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 0c46e2f4..5d687408 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -17,7 +17,7 @@ namespace eosio { class [[eosio::contract]] bios : public contract { public: - bios( name self, datastream ds ):contract(self,ds){} + bios( name self, name code, datastream ds ):contract(self,code,ds){} [[eosio::action]] void setpriv( name account, uint8_t is_priv ) { diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index 6864e111..f80fb4cd 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,4 +1,4 @@ -add_eosio_cdt_executable(multisig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) +add_contract(multisig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index 689759d1..a4ba2235 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -7,7 +7,7 @@ namespace eosio { class [[eosio::contract]] multisig : public contract { public: - multisig( name self, datastream ds ):contract(self, ds){} + multisig( name self, name code, datastream ds ):contract(self,code,ds){} [[eosio::action]] void propose(ignore proposer, ignore proposal_name, diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt index 6fb6d45c..a5496d27 100644 --- a/eosio.sudo/CMakeLists.txt +++ b/eosio.sudo/CMakeLists.txt @@ -1,4 +1,4 @@ -add_eosio_cdt_executable(sudo eosio.sudo ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) +add_contract(sudo eosio.sudo ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) target_include_directories(eosio.sudo.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp index a699ae58..2b2904f9 100644 --- a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp +++ b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp @@ -8,7 +8,7 @@ namespace eosio { class [[eosio::contract]] sudo : public contract { public: - sudo( name self, datastream ds ):contract(self, ds){} + sudo( name self, name code, datastream ds ):contract(self,code,ds){} [[eosio::action]] void exec(ignore executer, ignore trx); diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index 594d135f..222da47e 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -1,4 +1,4 @@ -add_eosio_cdt_executable(system_contract eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) +add_contract(system_contract eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) #add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) target_include_directories(eosio.system.wasm PUBLIC diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 9e41f69b..afc0f827 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -202,7 +202,7 @@ namespace eosiosystem { static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); - system_contract( name s, datastream ds ); + system_contract( name s, name code, datastream ds ); ~system_contract(); static symbol get_core_symbol( const rammarket& rm ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 749787af..90091eaf 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -10,8 +10,8 @@ namespace eosiosystem { - system_contract::system_contract( name s, datastream ds ) - :native(s,ds), + system_contract::system_contract( name s, name code, datastream ds ) + :native(s,code,ds), _voters(_self, _self.value), _producers(_self, _self.value), _producers2(_self, _self.value), @@ -301,7 +301,7 @@ namespace eosiosystem { auto itr = _rammarket.find(ramcore_symbol.raw()); eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); - auto system_token_supply = eosio::token(token_account).get_supply( core.code() ); + auto system_token_supply = eosio::token(token_account, name()).get_supply( core.code() ); eosio_assert( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); if( system_token_supply.amount > 0 ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 40935f24..5c2214ee 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -83,7 +83,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token(token_account).get_supply( core_symbol().code() ); + const asset token_supply = token(token_account, name()).get_supply( core_symbol().code() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt index 7a16bc7e..e62fe29f 100644 --- a/eosio.token/CMakeLists.txt +++ b/eosio.token/CMakeLists.txt @@ -1,4 +1,4 @@ -add_eosio_cdt_executable(token eosio.token ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) +add_contract(token eosio.token ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) target_include_directories(eosio.token.wasm PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 4beabcab..bf6f303c 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -19,8 +19,8 @@ namespace eosio { class [[eosio::contract]] token : public contract { public: - token( name self ):contract(self){} - token( name self, datastream ds ):contract(self,ds){} + token( name self, name code ):contract(self,code){} + token( name self, name code, datastream ds ):contract(self,code,ds){} [[eosio::action]] void create( name issuer, From 54de5920db9686bc18b1580d67cd001806c6d596 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 9 Oct 2018 20:12:58 -0400 Subject: [PATCH 0592/1048] use better pattern for static helper function get_core_symbol so it can be useful to other contracts --- .../include/eosio.system/eosio.system.hpp | 16 +++++++++++++--- eosio.system/src/eosio.system.cpp | 13 ------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index afc0f827..5874df2c 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -205,9 +205,11 @@ namespace eosiosystem { system_contract( name s, name code, datastream ds ); ~system_contract(); - static symbol get_core_symbol( const rammarket& rm ); - static symbol get_core_symbol(); - symbol core_symbol()const; + static symbol get_core_symbol( name system_account = "eosio"_n ) { + rammarket rm(system_account, system_account.value); + const static auto sym = get_core_symbol( rm ); + return sym; + } // Actions: [[eosio::action]] @@ -319,11 +321,19 @@ namespace eosiosystem { private: // Implementation details: + static symbol get_core_symbol( const rammarket& rm ) { + auto itr = rm.find(ramcore_symbol.raw()); + eosio_assert(itr != rm.end(), "system contract must first be initialized"); + return itr->quote.balance.symbol; + } + //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); static time_point current_time_point(); static block_timestamp current_block_time(); + symbol core_symbol()const; + void update_ram_supply(); //defined in delegate_bandwidth.cpp diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 90091eaf..36dfdfa5 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -43,19 +43,6 @@ namespace eosiosystem { return cbt; } - symbol system_contract::get_core_symbol( const rammarket& rm ) { - auto itr = rm.find(ramcore_symbol.raw()); - eosio_assert(itr != rm.end(), "system contract must first be initialized"); - return itr->quote.balance.symbol; - } - - symbol system_contract::get_core_symbol() { - rammarket rm("eosio"_n, "eosio"_n.value); - const static auto sym = get_core_symbol( rm ); - return sym; - } - - symbol system_contract::core_symbol()const { const static auto sym = get_core_symbol( _rammarket ); return sym; From db527f39d9d0986b5d832a21ca9f63be82a0f3c1 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 9 Oct 2018 20:19:34 -0400 Subject: [PATCH 0593/1048] use better pattern for get_supply and get_balance methods from token contract --- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/producer_pay.cpp | 2 +- .../include/eosio.token/eosio.token.hpp | 30 ++++++++----------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 36dfdfa5..500fe0b4 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -288,7 +288,7 @@ namespace eosiosystem { auto itr = _rammarket.find(ramcore_symbol.raw()); eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); - auto system_token_supply = eosio::token(token_account, name()).get_supply( core.code() ); + auto system_token_supply = eosio::token::get_supply(token_account, core.code() ); eosio_assert( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); if( system_token_supply.amount > 0 ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 5c2214ee..0edc8291 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -83,7 +83,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token(token_account, name()).get_supply( core_symbol().code() ); + const asset token_supply = eosio::token::get_supply(token_account, core_symbol().code() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index bf6f303c..69d0d7bf 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -21,7 +21,7 @@ namespace eosio { public: token( name self, name code ):contract(self,code){} token( name self, name code, datastream ds ):contract(self,code,ds){} - + [[eosio::action]] void create( name issuer, asset maximum_supply); @@ -44,9 +44,19 @@ namespace eosio { [[eosio::action]] void close( name owner, const symbol& symbol ); - inline asset get_supply( symbol_code sym_code )const; + static asset get_supply( name token_contract_account, symbol_code sym_code ) + { + stats statstable( token_contract_account, sym_code.raw() ); + const auto& st = statstable.get( sym_code.raw() ); + return st.supply; + } - inline asset get_balance( name owner, symbol_code sym_code )const; + static asset get_balance( name token_contract_account, name owner, symbol_code sym_code ) + { + accounts accountstable( token_contract_account, owner.value ); + const auto& ac = accountstable.get( sym_code.raw() ); + return ac.balance; + } private: struct [[eosio::table]] account { @@ -78,18 +88,4 @@ namespace eosio { }; }; - asset token::get_supply( symbol_code sym_code )const - { - stats statstable( _self, sym_code.raw() ); - const auto& st = statstable.get( sym_code.raw() ); - return st.supply; - } - - asset token::get_balance( name owner, symbol_code sym_code )const - { - accounts accountstable( _self, owner.value ); - const auto& ac = accountstable.get( sym_code.raw() ); - return ac.balance; - } - } /// namespace eosio From 926e30f5c5d98611fe20ecc644f2963011d416c0 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 9 Oct 2018 20:25:23 -0400 Subject: [PATCH 0594/1048] reverted back some naming --- eosio.bios/include/eosio.bios/eosio.bios.hpp | 8 +- .../include/eosio.system/eosio.system.hpp | 11 ++- eosio.system/include/eosio.system/native.hpp | 5 +- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/producer_pay.cpp | 4 +- .../include/eosio.token/eosio.token.hpp | 3 +- tests/eosio.msig_tests.cpp | 4 +- tests/eosio.system_tester.hpp | 16 ++-- tests/eosio.system_tests.cpp | 78 +------------------ 9 files changed, 28 insertions(+), 103 deletions(-) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 5d687408..1581d9cf 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -61,12 +61,12 @@ namespace eosio { } [[eosio::action]] - void setabi( name acnt, const std::vector& abi ) { + void setabi( name account, const std::vector& abi ) { abi_hash_table table(_self, _self.value); - auto itr = table.find( acnt.value ); + auto itr = table.find( account.value ); if( itr == table.end() ) { - table.emplace( acnt, [&]( auto& row ) { - row.owner = acnt; + table.emplace( account, [&]( auto& row ) { + row.owner = account; sha256( const_cast(abi.data()), abi.size(), &row.hash ); }); } else { diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index afc0f827..7b74f92a 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -213,11 +213,10 @@ namespace eosiosystem { [[eosio::action]] void init( unsigned_int version, symbol core ); [[eosio::action]] - void onblock( block_timestamp timestamp, name producer ); - // const block_header& header ); /// only parse first 3 fields of block header + void onblock( block_timestamp timestamp, name producer, ignore header ); [[eosio::action]] - void setalimits( name act, int64_t ram, int64_t net, int64_t cpu ); + void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); // functions defined in delegate_bandwidth.cpp /** @@ -257,16 +256,16 @@ namespace eosiosystem { * tokens will be executed. */ [[eosio::action]] - void buyram( name buyer, name receiver, asset tokens ); + void buyram( name payer, name receiver, asset quant ); [[eosio::action]] - void buyrambytes( name buyer, name receiver, uint32_t bytes ); + void buyrambytes( name payer, name receiver, uint32_t bytes ); /** * Reduces quota my bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. */ [[eosio::action]] - void sellram( name receiver, int64_t bytes ); + void sellram( name account, int64_t bytes ); /** * This action is called after the delegation-period to claim all pending diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index 837394c2..262ed063 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include @@ -61,7 +60,7 @@ namespace eosiosystem { capi_checksum256 transaction_mroot; capi_checksum256 action_mroot; uint32_t schedule_version = 0; - eosio::optional new_producers; + std::optional new_producers; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE(block_header, (timestamp)(producer)(confirmed)(previous)(transaction_mroot)(action_mroot) @@ -132,7 +131,7 @@ namespace eosiosystem { void onerror( ignore sender_id, ignore> sent_trx ) {} [[eosio::action]] - void setabi( name acnt, const std::vector& abi ); + void setabi( name account, const std::vector& abi ); [[eosio::action]] void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 90091eaf..e8ddb1a5 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -301,7 +301,7 @@ namespace eosiosystem { auto itr = _rammarket.find(ramcore_symbol.raw()); eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); - auto system_token_supply = eosio::token(token_account, name()).get_supply( core.code() ); + auto system_token_supply = eosio::token(token_account, name(), {nullptr, 0}).get_supply( core.code() ); eosio_assert( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); if( system_token_supply.amount > 0 ) { diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 5c2214ee..f47c68ba 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -16,7 +16,7 @@ namespace eosiosystem { const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); const int64_t useconds_per_year = seconds_per_year*1000000ll; - void system_contract::onblock( block_timestamp timestamp, name producer ) { + void system_contract::onblock( block_timestamp timestamp, name producer, ignore ) { using namespace eosio; require_auth(_self); @@ -83,7 +83,7 @@ namespace eosiosystem { eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = token(token_account, name()).get_supply( core_symbol().code() ); + const asset token_supply = token(token_account, name(), {nullptr,0}).get_supply( core_symbol().code() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index bf6f303c..315ce630 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -19,8 +19,7 @@ namespace eosio { class [[eosio::contract]] token : public contract { public: - token( name self, name code ):contract(self,code){} - token( name self, name code, datastream ds ):contract(self,code,ds){} + using contract::contract; [[eosio::action]] void create( name issuer, diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 13c1120c..a5e3a830 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -62,9 +62,9 @@ class eosio_msig_tester : public tester { trx.actions.emplace_back( get_action( N(eosio), N(buyram), vector{{creator,config::active_name}}, mvo() - ("buyer", creator) + ("payer", creator) ("receiver", a) - ("tokens", ramfunds) ) + ("quant", ramfunds) ) ); trx.actions.emplace_back( get_action( N(eosio), N(delegatebw), vector{{creator,config::active_name}}, diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index b95fa6c5..1d26caef 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -144,7 +144,7 @@ class eosio_system_tester : public TESTER { trx.actions.emplace_back( get_action( config::system_account_name, N(buyrambytes), vector{{creator,config::active_name}}, mvo() - ("buyer", creator) + ("payer", creator) ("receiver", a) ("bytes", ram_bytes) ) ); @@ -186,9 +186,9 @@ class eosio_system_tester : public TESTER { trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{{creator,config::active_name}}, mvo() - ("buyer", creator) + ("payer", creator) ("receiver", a) - ("tokens", ramfunds) ) + ("quant", ramfunds) ) ); trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, @@ -228,9 +228,9 @@ class eosio_system_tester : public TESTER { trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{ {creator, config::active_name} }, mvo() - ("buyer", creator) + ("payer", creator) ("receiver", a) - ("tokens", ram) ) + ("quant", ram) ) ); trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{ {creator, config::active_name} }, @@ -250,14 +250,14 @@ class eosio_system_tester : public TESTER { } action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { - return push_action( payer, N(buyram), mvo()( "buyer",payer)("receiver",receiver)("tokens",eosin) ); + return push_action( payer, N(buyram), mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); } action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { - return push_action( payer, N(buyrambytes), mvo()( "buyer",payer)("receiver",receiver)("bytes",numbytes) ); + return push_action( payer, N(buyrambytes), mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); } action_result sellram( const account_name& account, uint64_t numbytes ) { - return push_action( account, N(sellram), mvo()( "receiver", account)("bytes",numbytes) ); + return push_action( account, N(sellram), mvo()( "account", account)("bytes",numbytes) ); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0afac496..c29742e3 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2293,43 +2293,7 @@ BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) const asset cpu = old_core_from_string("80.0000"); const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; for (const auto& v: voters) { - { - signed_transaction trx; - t.set_transaction_headers(trx); - - authority owner_auth; - owner_auth = authority( t.get_public_key( account_name(v), "owner" ) ); - - trx.actions.emplace_back( vector{{config::system_account_name,config::active_name}}, - newaccount{ - .creator = config::system_account_name, - .name = account_name(v), - .owner = owner_auth, - .active = authority( t.get_public_key( account_name(v), "active" ) ) - }); - - trx.actions.emplace_back( t.get_action( config::system_account_name, N(buyram), vector{{config::system_account_name,config::active_name}}, - mvo() - ("payer", account_name(config::system_account_name).to_string()) - ("receiver", v) - ("quant", old_core_from_string("1.0000") ) ) - ); - - trx.actions.emplace_back( t.get_action( config::system_account_name, N(delegatebw), vector{{config::system_account_name,config::active_name}}, - mvo() - ("from", account_name(config::system_account_name).to_string()) - ("receiver", v) - ("stake_net_quantity", net ) - ("stake_cpu_quantity", cpu ) - ("transfer", 0 ) - ) - ); - - t.set_transaction_headers(trx); - trx.sign( t.get_private_key( config::system_account_name, "active" ), t.control->get_chain_id() ); - t.push_transaction( trx ); - } - + t.create_account_with_resources( v, config::system_account_name, old_core_from_string("1.0000"), false, net, cpu ); t.transfer( config::system_account_name, v, old_core_from_string("100000000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL(t.success(), t.stake(v, old_core_from_string("30000000.0000"), old_core_from_string("30000000.0000")) ); } @@ -2344,44 +2308,8 @@ BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) producer_names.emplace_back(root + std::string(1, c)); } } - { - account_name creator(config::system_account_name); - signed_transaction trx; - t.set_transaction_headers(trx); - - for (const auto& a: producer_names) { - authority owner_auth( t.get_public_key( a, "owner" ) ); - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( t.get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( t.get_action( config::system_account_name, N(buyram), vector{ {creator, config::active_name} }, - mvo() - ("payer", creator) - ("receiver", a) - ("quant", old_core_from_string("1.0000")) ) - ); - - trx.actions.emplace_back( t.get_action( config::system_account_name, N(delegatebw), vector{ {creator, config::active_name} }, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", old_core_from_string("80.0000")) - ("stake_cpu_quantity", old_core_from_string("80.0000") ) - ("transfer", 0 ) - ) - ); - } - - t.set_transaction_headers(trx); - trx.sign( t.get_private_key( creator, "active" ), t.control->get_chain_id() ); - t.push_transaction( trx ); - } - + t.setup_producer_accounts( producer_names, old_core_from_string("1.0000"), + old_core_from_string("80.0000"), old_core_from_string("80.0000") ); for (const auto& p: producer_names) { BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(p) ); BOOST_TEST_REQUIRE(0 == t.get_producer_info(p)["total_votes"].as_double()); From f2f0f1a169958c8cb38900e5fd112d0f09a82616 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 9 Oct 2018 20:45:43 -0400 Subject: [PATCH 0595/1048] correct onblock ABI --- eosio.system/include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/producer_pay.cpp | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index d7cc8ebc..2b657a43 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -215,7 +215,7 @@ namespace eosiosystem { [[eosio::action]] void init( unsigned_int version, symbol core ); [[eosio::action]] - void onblock( block_timestamp timestamp, name producer, ignore header ); + void onblock( ignore header ); [[eosio::action]] void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 7d7f9648..287ab8b6 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -16,11 +16,15 @@ namespace eosiosystem { const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); const int64_t useconds_per_year = seconds_per_year*1000000ll; - void system_contract::onblock( block_timestamp timestamp, name producer, ignore ) { + void system_contract::onblock( ignore ) { using namespace eosio; require_auth(_self); + block_timestamp timestamp; + name producer; + _ds >> timestamp >> producer; + // _gstate2.last_block_num is not used anywhere in the system contract code anymore. // Although this field is deprecated, we will continue updating it for now until the last_block_num field // is eventually completely removed, at which point this line can be removed. From 0ae58b2ec779811e616bac93020393b9ca781203 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Oct 2018 10:24:12 -0400 Subject: [PATCH 0596/1048] rename eosio::contract attribute names for all contracts --- eosio.bios/CMakeLists.txt | 4 ++-- eosio.bios/include/eosio.bios/eosio.bios.hpp | 24 +++++++++---------- eosio.msig/CMakeLists.txt | 4 ++-- eosio.msig/include/eosio.msig/eosio.msig.hpp | 10 ++++---- eosio.msig/src/eosio.msig.cpp | 23 +++++------------- eosio.sudo/CMakeLists.txt | 4 ++-- eosio.sudo/include/eosio.sudo/eosio.sudo.hpp | 6 ++--- eosio.sudo/src/eosio.sudo.cpp | 15 +----------- eosio.system/CMakeLists.txt | 4 ++-- .../include/eosio.system/eosio.system.hpp | 18 +++++++------- .../include/eosio.system/exchange_state.hpp | 2 +- eosio.system/include/eosio.system/native.hpp | 6 ++--- eosio.system/src/delegate_bandwidth.cpp | 6 ++--- eosio.token/CMakeLists.txt | 4 ++-- .../include/eosio.token/eosio.token.hpp | 10 +------- 15 files changed, 54 insertions(+), 86 deletions(-) diff --git a/eosio.bios/CMakeLists.txt b/eosio.bios/CMakeLists.txt index 0dfccd8d..d4ed66f8 100644 --- a/eosio.bios/CMakeLists.txt +++ b/eosio.bios/CMakeLists.txt @@ -1,6 +1,6 @@ -add_contract(bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) +add_contract(eosio.bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) target_include_directories(eosio.bios.wasm - PUBLIC + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) set_target_properties(eosio.bios.wasm diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 1581d9cf..c1d5a2cc 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -5,19 +5,9 @@ namespace eosio { - struct [[eosio::contract("bios"), eosio::table]] abi_hash { - name owner; - capi_checksum256 hash; - uint64_t primary_key()const { return owner.value; } - - EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) - }; - - typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; - - class [[eosio::contract]] bios : public contract { + class [[eosio::contract("eosio.bios")]] bios : public contract { public: - bios( name self, name code, datastream ds ):contract(self,code,ds){} + using contract::contract; [[eosio::action]] void setpriv( name account, uint8_t is_priv ) { @@ -75,6 +65,16 @@ namespace eosio { }); } } + + struct [[eosio::table]] abi_hash { + name owner; + capi_checksum256 hash; + uint64_t primary_key()const { return owner.value; } + + EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) + }; + + typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; }; } /// namespace eosio diff --git a/eosio.msig/CMakeLists.txt b/eosio.msig/CMakeLists.txt index f80fb4cd..84614e87 100644 --- a/eosio.msig/CMakeLists.txt +++ b/eosio.msig/CMakeLists.txt @@ -1,6 +1,6 @@ -add_contract(multisig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) +add_contract(eosio.msig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) target_include_directories(eosio.msig.wasm - PUBLIC + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) set_target_properties(eosio.msig.wasm diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index a4ba2235..8ba22542 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -5,12 +5,12 @@ namespace eosio { - class [[eosio::contract]] multisig : public contract { + class [[eosio::contract("eosio.msig")]] multisig : public contract { public: - multisig( name self, name code, datastream ds ):contract(self,code,ds){} - + using contract::contract; + [[eosio::action]] - void propose(ignore proposer, ignore proposal_name, + void propose(ignore proposer, ignore proposal_name, ignore> requested, ignore trx); [[eosio::action]] void approve( name proposer, name proposal_name, permission_level level ); @@ -68,6 +68,6 @@ namespace eosio { }; typedef eosio::multi_index< "invals"_n, invalidation > invalidations; -}; + }; } /// namespace eosio diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index d1e6d086..0c88c56b 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -4,27 +4,16 @@ namespace eosio { -static time_point current_time_point() { +time_point current_time_point() { const static time_point ct{ microseconds{ static_cast( current_time() ) } }; return ct; } -/* -propose function manually parses input data (instead of taking parsed arguments from dispatcher) -because parsing data in the dispatcher uses too much CPU in case if proposed transaction is big - -If we use dispatcher the function signature should be: - -void multisig::propose( name proposer, - name proposal_name, - std::vector requested, - transaction trx) -*/ - -void multisig::propose(ignore proposer, ignore proposal_name, - ignore> requested, ignore trx) { - constexpr size_t max_stack_buffer_size = 512; - +void multisig::propose( ignore proposer, + ignore proposal_name, + ignore> requested, + ignore trx ) +{ name _proposer; name _proposal_name; std::vector _requested; diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt index a5496d27..c0014a53 100644 --- a/eosio.sudo/CMakeLists.txt +++ b/eosio.sudo/CMakeLists.txt @@ -1,6 +1,6 @@ -add_contract(sudo eosio.sudo ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) +add_contract(eosio.sudo eosio.sudo ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) target_include_directories(eosio.sudo.wasm - PUBLIC + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) set_target_properties(eosio.sudo.wasm diff --git a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp index 2b2904f9..670ae2a4 100644 --- a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp +++ b/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp @@ -6,12 +6,12 @@ namespace eosio { - class [[eosio::contract]] sudo : public contract { + class [[eosio::contract("eosio.sudo")]] sudo : public contract { public: - sudo( name self, name code, datastream ds ):contract(self,code,ds){} + using contract::contract; [[eosio::action]] - void exec(ignore executer, ignore trx); + void exec( ignore executer, ignore trx ); }; diff --git a/eosio.sudo/src/eosio.sudo.cpp b/eosio.sudo/src/eosio.sudo.cpp index aea8db54..9a0c9dfc 100644 --- a/eosio.sudo/src/eosio.sudo.cpp +++ b/eosio.sudo/src/eosio.sudo.cpp @@ -2,23 +2,10 @@ namespace eosio { -/* -exec function manually parses input data (instead of taking parsed arguments from dispatcher) -because parsing data in the dispatcher uses too much CPU if the included transaction is very big - -If we use dispatcher the function signature should be: - -void sudo::exec( name executer, - transaction trx ) -*/ - -void sudo::exec(ignore, ignore) { +void sudo::exec( ignore, ignore ) { require_auth( _self ); - constexpr size_t max_stack_buffer_size = 512; - name executer; - _ds >> executer; require_auth( executer ); diff --git a/eosio.system/CMakeLists.txt b/eosio.system/CMakeLists.txt index 222da47e..66a9e312 100644 --- a/eosio.system/CMakeLists.txt +++ b/eosio.system/CMakeLists.txt @@ -1,7 +1,7 @@ -add_contract(system_contract eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) +add_contract(eosio.system eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) #add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) target_include_directories(eosio.system.wasm - PUBLIC + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/../eosio.token/include) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 2b657a43..32ccdce7 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -26,7 +26,7 @@ namespace eosiosystem { using eosio::microseconds; using eosio::datastream; - struct [[eosio::table, eosio::contract("system_contract")]] name_bid { + struct [[eosio::table, eosio::contract("eosio.system")]] name_bid { name newname; name high_bidder; int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed @@ -36,7 +36,7 @@ namespace eosiosystem { uint64_t by_high_bid()const { return static_cast(-high_bid); } }; - struct [[eosio::table, eosio::contract("system_contract")]] bid_refund { + struct [[eosio::table, eosio::contract("eosio.system")]] bid_refund { name bidder; asset amount; @@ -49,7 +49,7 @@ namespace eosiosystem { typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; - struct [[eosio::table("global"), eosio::contract("system_contract")]] eosio_global_state : eosio::blockchain_parameters { + struct [[eosio::table("global"), eosio::contract("eosio.system")]] eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; @@ -78,7 +78,7 @@ namespace eosiosystem { /** * Defines new global state parameters added after version 1.0 */ - struct [[eosio::table("global2"), eosio::contract("system_contract")]] eosio_global_state2 { + struct [[eosio::table("global2"), eosio::contract("eosio.system")]] eosio_global_state2 { eosio_global_state2(){} uint16_t new_ram_per_block = 0; @@ -91,7 +91,7 @@ namespace eosiosystem { (total_producer_votepay_share)(revision) ) }; - struct [[eosio::table("global3"), eosio::contract("system_contract")]] eosio_global_state3 { + struct [[eosio::table("global3"), eosio::contract("eosio.system")]] eosio_global_state3 { eosio_global_state3() { } time_point last_vpay_state_update; double total_vpay_share_change_rate = 0; @@ -99,7 +99,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) }; - struct [[eosio::table, eosio::contract("system_contract")]] producer_info { + struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { name owner; double total_votes = 0; eosio::public_key producer_key; /// a packed public key object @@ -119,7 +119,7 @@ namespace eosiosystem { (unpaid_blocks)(last_claim_time)(location) ) }; - struct [[eosio::table, eosio::contract("system_contract")]] producer_info2 { + struct [[eosio::table, eosio::contract("eosio.system")]] producer_info2 { name owner; double votepay_share = 0; time_point last_votepay_share_update; @@ -130,7 +130,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) }; - struct [[eosio::table, eosio::contract("system_contract")]] voter_info { + struct [[eosio::table, eosio::contract("eosio.system")]] voter_info { name owner; /// the voter name proxy; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set @@ -176,7 +176,7 @@ namespace eosiosystem { // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - class [[eosio::contract]] system_contract : public native { + class [[eosio::contract("eosio.system")]] system_contract : public native { private: voters_table _voters; producers_table _producers; diff --git a/eosio.system/include/eosio.system/exchange_state.hpp b/eosio.system/include/eosio.system/exchange_state.hpp index f443e08d..aba1eefe 100644 --- a/eosio.system/include/eosio.system/exchange_state.hpp +++ b/eosio.system/include/eosio.system/exchange_state.hpp @@ -13,7 +13,7 @@ namespace eosiosystem { * bancor exchange is entirely contained within this struct. There are no external * side effects associated with using this API. */ - struct [[eosio::table, eosio::contract("system_contract")]] exchange_state { + struct [[eosio::table, eosio::contract("eosio.system")]] exchange_state { asset supply; struct connector { diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index 262ed063..61a23eee 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -60,7 +60,7 @@ namespace eosiosystem { capi_checksum256 transaction_mroot; capi_checksum256 action_mroot; uint32_t schedule_version = 0; - std::optional new_producers; + std::optional new_producers; // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE(block_header, (timestamp)(producer)(confirmed)(previous)(transaction_mroot)(action_mroot) @@ -68,7 +68,7 @@ namespace eosiosystem { }; - struct [[eosio::table("abihash"), eosio::contract("system_contract")]] abi_hash { + struct [[eosio::table("abihash"), eosio::contract("eosio.system")]] abi_hash { name owner; capi_checksum256 hash; uint64_t primary_key()const { return owner.value; } @@ -79,7 +79,7 @@ namespace eosiosystem { /* * Method parameters commented out to prevent generation of code that parses input data. */ - class [[eosio::contract("system_contract")]] native : public eosio::contract { + class [[eosio::contract("eosio.system")]] native : public eosio::contract { public: using eosio::contract::contract; diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 2fcfb091..dfe073a6 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -31,7 +31,7 @@ namespace eosiosystem { static constexpr uint32_t refund_delay_sec = 3*24*3600; static constexpr int64_t ram_gift_bytes = 1400; - struct [[eosio::table, eosio::contract("system_contract")]] user_resources { + struct [[eosio::table, eosio::contract("eosio.system")]] user_resources { name owner; asset net_weight; asset cpu_weight; @@ -47,7 +47,7 @@ namespace eosiosystem { /** * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. */ - struct [[eosio::table, eosio::contract("system_contract")]] delegated_bandwidth { + struct [[eosio::table, eosio::contract("eosio.system")]] delegated_bandwidth { name from; name to; asset net_weight; @@ -60,7 +60,7 @@ namespace eosiosystem { }; - struct [[eosio::table, eosio::contract("system_contract")]] refund_request { + struct [[eosio::table, eosio::contract("eosio.system")]] refund_request { name owner; time_point_sec request_time; eosio::asset net_amount; diff --git a/eosio.token/CMakeLists.txt b/eosio.token/CMakeLists.txt index e62fe29f..5582d04a 100644 --- a/eosio.token/CMakeLists.txt +++ b/eosio.token/CMakeLists.txt @@ -1,6 +1,6 @@ -add_contract(token eosio.token ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) +add_contract(eosio.token eosio.token ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) target_include_directories(eosio.token.wasm - PUBLIC + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) set_target_properties(eosio.token.wasm diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/eosio.token/include/eosio.token/eosio.token.hpp index 93add74b..53130bdb 100644 --- a/eosio.token/include/eosio.token/eosio.token.hpp +++ b/eosio.token/include/eosio.token/eosio.token.hpp @@ -17,7 +17,7 @@ namespace eosio { using std::string; - class [[eosio::contract]] token : public contract { + class [[eosio::contract("eosio.token")]] token : public contract { public: using contract::contract; @@ -77,14 +77,6 @@ namespace eosio { void sub_balance( name owner, asset value ); void add_balance( name owner, asset value, name ram_payer ); - - public: - struct transfer_args { - name from; - name to; - asset quantity; - string memo; - }; }; } /// namespace eosio From 011efd09d1bf2b9f3fe240ba415fe5e1b2ba25de Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Oct 2018 10:33:30 -0400 Subject: [PATCH 0597/1048] rename eosio.sudo to eosio.wrap --- CMakeLists.txt | 2 +- eosio.sudo/CMakeLists.txt | 8 -- eosio.wrap/CMakeLists.txt | 8 ++ {eosio.sudo => eosio.wrap}/README.md | 0 .../include/eosio.wrap/eosio.wrap.hpp | 2 +- .../src/eosio.wrap.cpp | 6 +- tests/contracts.hpp.in | 10 +-- ...io.sudo_tests.cpp => eosio.wrap_tests.cpp} | 74 +++++++++---------- 8 files changed, 55 insertions(+), 55 deletions(-) delete mode 100644 eosio.sudo/CMakeLists.txt create mode 100644 eosio.wrap/CMakeLists.txt rename {eosio.sudo => eosio.wrap}/README.md (100%) rename eosio.sudo/include/eosio.sudo/eosio.sudo.hpp => eosio.wrap/include/eosio.wrap/eosio.wrap.hpp (82%) rename eosio.sudo/src/eosio.sudo.cpp => eosio.wrap/src/eosio.wrap.cpp (66%) rename tests/{eosio.sudo_tests.cpp => eosio.wrap_tests.cpp} (87%) diff --git a/CMakeLists.txt b/CMakeLists.txt index b81cb4a1..68f75dbf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,7 +34,7 @@ endif() add_subdirectory(eosio.bios) add_subdirectory(eosio.msig) -add_subdirectory(eosio.sudo) +add_subdirectory(eosio.wrap) add_subdirectory(eosio.system) add_subdirectory(eosio.token) diff --git a/eosio.sudo/CMakeLists.txt b/eosio.sudo/CMakeLists.txt deleted file mode 100644 index c0014a53..00000000 --- a/eosio.sudo/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -add_contract(eosio.sudo eosio.sudo ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.sudo.cpp) -target_include_directories(eosio.sudo.wasm - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) - -set_target_properties(eosio.sudo.wasm - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/eosio.wrap/CMakeLists.txt b/eosio.wrap/CMakeLists.txt new file mode 100644 index 00000000..d67ef83a --- /dev/null +++ b/eosio.wrap/CMakeLists.txt @@ -0,0 +1,8 @@ +add_contract(eosio.wrap eosio.wrap ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.wrap.cpp) +target_include_directories(eosio.wrap.wasm + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set_target_properties(eosio.wrap.wasm + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/eosio.sudo/README.md b/eosio.wrap/README.md similarity index 100% rename from eosio.sudo/README.md rename to eosio.wrap/README.md diff --git a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp b/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp similarity index 82% rename from eosio.sudo/include/eosio.sudo/eosio.sudo.hpp rename to eosio.wrap/include/eosio.wrap/eosio.wrap.hpp index 670ae2a4..a01aa363 100644 --- a/eosio.sudo/include/eosio.sudo/eosio.sudo.hpp +++ b/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -6,7 +6,7 @@ namespace eosio { - class [[eosio::contract("eosio.sudo")]] sudo : public contract { + class [[eosio::contract("eosio.wrap")]] wrap : public contract { public: using contract::contract; diff --git a/eosio.sudo/src/eosio.sudo.cpp b/eosio.wrap/src/eosio.wrap.cpp similarity index 66% rename from eosio.sudo/src/eosio.sudo.cpp rename to eosio.wrap/src/eosio.wrap.cpp index 9a0c9dfc..d8a03446 100644 --- a/eosio.sudo/src/eosio.sudo.cpp +++ b/eosio.wrap/src/eosio.wrap.cpp @@ -1,8 +1,8 @@ -#include +#include namespace eosio { -void sudo::exec( ignore, ignore ) { +void wrap::exec( ignore, ignore ) { require_auth( _self ); name executer; @@ -15,4 +15,4 @@ void sudo::exec( ignore, ignore ) { } /// namespace eosio -EOSIO_DISPATCH( eosio::sudo, (exec) ) +EOSIO_DISPATCH( eosio::wrap, (exec) ) diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index cde28e1c..efe4950d 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -9,17 +9,17 @@ struct contracts { static std::vector system_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.abi"); } static std::vector token_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wasm"); } static std::string token_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.abi"); } + static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.abi"); } static std::vector msig_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wasm"); } static std::string msig_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wast"); } static std::vector msig_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.abi"); } - static std::vector sudo_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wasm"); } - static std::string sudo_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.wast"); } - static std::vector sudo_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.sudo/eosio.sudo.abi"); } + static std::vector wrap_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.wrap/eosio.wrap.wasm"); } + static std::string wrap_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.wrap/eosio.wrap.wast"); } + static std::vector wrap_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.wrap/eosio.wrap.abi"); } static std::vector bios_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.wasm"); } static std::string bios_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.wast"); } static std::vector bios_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.abi"); } - + struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } static std::vector exchange_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/exchange.wasm"); } diff --git a/tests/eosio.sudo_tests.cpp b/tests/eosio.wrap_tests.cpp similarity index 87% rename from tests/eosio.sudo_tests.cpp rename to tests/eosio.wrap_tests.cpp index 8de7a93f..b6f1424d 100644 --- a/tests/eosio.sudo_tests.cpp +++ b/tests/eosio.wrap_tests.cpp @@ -16,10 +16,10 @@ using namespace fc; using mvo = fc::mutable_variant_object; -class eosio_sudo_tester : public tester { +class eosio_wrap_tester : public tester { public: - eosio_sudo_tester() { + eosio_wrap_tester() { create_accounts( { N(eosio.msig), N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(alice), N(bob), N(carol) } ); produce_block(); @@ -41,7 +41,7 @@ class eosio_sudo_tester : public tester { trx.actions.emplace_back( vector{{config::system_account_name, config::active_name}}, newaccount{ .creator = config::system_account_name, - .name = N(eosio.sudo), + .name = N(eosio.wrap), .owner = auth, .active = auth, }); @@ -52,13 +52,13 @@ class eosio_sudo_tester : public tester { base_tester::push_action(config::system_account_name, N(setpriv), config::system_account_name, mutable_variant_object() - ("account", "eosio.sudo") + ("account", "eosio.wrap") ("is_priv", 1) ); auto system_private_key = get_private_key( config::system_account_name, "active" ); - set_code( N(eosio.sudo), contracts::sudo_wasm(), &system_private_key ); - set_abi( N(eosio.sudo), contracts::sudo_abi().data(), &system_private_key ); + set_code( N(eosio.wrap), contracts::wrap_wasm(), &system_private_key ); + set_abi( N(eosio.wrap), contracts::wrap_abi().data(), &system_private_key ); produce_blocks(); @@ -74,7 +74,7 @@ class eosio_sudo_tester : public tester { produce_blocks(); - const auto& accnt = control->db().get( N(eosio.sudo) ); + const auto& accnt = control->db().get( N(eosio.wrap) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); abi_ser.set_abi(abi, abi_serializer_max_time); @@ -109,25 +109,25 @@ class eosio_sudo_tester : public tester { ); } - transaction sudo_exec( account_name executer, const transaction& trx, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); + transaction wrap_exec( account_name executer, const transaction& trx, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); transaction reqauth( account_name from, const vector& auths, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); abi_serializer abi_ser; }; -transaction eosio_sudo_tester::sudo_exec( account_name executer, const transaction& trx, uint32_t expiration ) { +transaction eosio_wrap_tester::wrap_exec( account_name executer, const transaction& trx, uint32_t expiration ) { fc::variants v; v.push_back( fc::mutable_variant_object() ("actor", executer) ("permission", name{config::active_name}) ); v.push_back( fc::mutable_variant_object() - ("actor", "eosio.sudo") + ("actor", "eosio.wrap") ("permission", name{config::active_name}) ); auto act_obj = fc::mutable_variant_object() - ("account", "eosio.sudo") + ("account", "eosio.wrap") ("name", "exec") ("authorization", v) ("data", fc::mutable_variant_object()("executer", executer)("trx", trx) ); @@ -139,7 +139,7 @@ transaction eosio_sudo_tester::sudo_exec( account_name executer, const transacti return trx2; } -transaction eosio_sudo_tester::reqauth( account_name from, const vector& auths, uint32_t expiration ) { +transaction eosio_wrap_tester::reqauth( account_name from, const vector& auths, uint32_t expiration ) { fc::variants v; for ( auto& level : auths ) { v.push_back(fc::mutable_variant_object() @@ -160,30 +160,30 @@ transaction eosio_sudo_tester::reqauth( account_name from, const vectorapplied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); { - signed_transaction sudo_trx( sudo_exec( N(alice), trx ), {}, {} ); + signed_transaction wrap_trx( wrap_exec( N(alice), trx ), {}, {} ); /* - set_transaction_headers( sudo_trx ); - sudo_trx.actions.emplace_back( get_action( N(eosio.sudo), N(exec), - {{N(alice), config::active_name}, {N(eosio.sudo), config::active_name}}, + set_transaction_headers( wrap_trx ); + wrap_trx.actions.emplace_back( get_action( N(eosio.wrap), N(exec), + {{N(alice), config::active_name}, {N(eosio.wrap), config::active_name}}, mvo() ("executer", "alice") ("trx", trx) ) ); */ - sudo_trx.sign( get_private_key( N(alice), "active" ), control->get_chain_id() ); + wrap_trx.sign( get_private_key( N(alice), "active" ), control->get_chain_id() ); for( const auto& actor : {"prod1", "prod2", "prod3", "prod4"} ) { - sudo_trx.sign( get_private_key( actor, "active" ), control->get_chain_id() ); + wrap_trx.sign( get_private_key( actor, "active" ), control->get_chain_id() ); } - push_transaction( sudo_trx ); + push_transaction( wrap_trx ); } produce_block(); @@ -196,16 +196,16 @@ BOOST_FIXTURE_TEST_CASE( sudo_exec_direct, eosio_sudo_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( sudo_with_msig, eosio_sudo_tester ) try { +BOOST_FIXTURE_TEST_CASE( wrap_with_msig, eosio_wrap_tester ) try { auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto sudo_trx = sudo_exec( N(alice), trx ); + auto wrap_trx = wrap_exec( N(alice), trx ); propose( N(carol), N(first), { {N(alice), N(active)}, {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - sudo_trx ); + wrap_trx ); - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the sudo::exec action + approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action // More than 2/3 of block producers approve approve( N(carol), N(first), N(prod1) ); @@ -232,7 +232,7 @@ BOOST_FIXTURE_TEST_CASE( sudo_with_msig, eosio_sudo_tester ) try { BOOST_REQUIRE_EQUAL( 2, traces.size() ); BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio.sudo", name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( "eosio.wrap", name{traces[0]->action_traces[0].act.account} ); BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); @@ -243,16 +243,16 @@ BOOST_FIXTURE_TEST_CASE( sudo_with_msig, eosio_sudo_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( sudo_with_msig_unapprove, eosio_sudo_tester ) try { +BOOST_FIXTURE_TEST_CASE( wrap_with_msig_unapprove, eosio_wrap_tester ) try { auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto sudo_trx = sudo_exec( N(alice), trx ); + auto wrap_trx = wrap_exec( N(alice), trx ); propose( N(carol), N(first), { {N(alice), N(active)}, {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - sudo_trx ); + wrap_trx ); - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the sudo::exec action + approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action // 3 of the 4 needed producers approve approve( N(carol), N(first), N(prod1) ); @@ -267,7 +267,7 @@ BOOST_FIXTURE_TEST_CASE( sudo_with_msig_unapprove, eosio_sudo_tester ) try { produce_block(); - // The proposal should not have sufficient approvals to pass the authorization checks of eosio.sudo::exec. + // The proposal should not have sufficient approvals to pass the authorization checks of eosio.wrap::exec. BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() ("proposer", "carol") ("proposal_name", "first") @@ -278,18 +278,18 @@ BOOST_FIXTURE_TEST_CASE( sudo_with_msig_unapprove, eosio_sudo_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( sudo_with_msig_producers_change, eosio_sudo_tester ) try { +BOOST_FIXTURE_TEST_CASE( wrap_with_msig_producers_change, eosio_wrap_tester ) try { create_accounts( { N(newprod1) } ); auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto sudo_trx = sudo_exec( N(alice), trx, 36000 ); + auto wrap_trx = wrap_exec( N(alice), trx, 36000 ); propose( N(carol), N(first), { {N(alice), N(active)}, {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - sudo_trx ); + wrap_trx ); - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the sudo::exec action + approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action // 2 of the 4 needed producers approve approve( N(carol), N(first), N(prod1) ); @@ -309,7 +309,7 @@ BOOST_FIXTURE_TEST_CASE( sudo_with_msig_producers_change, eosio_sudo_tester ) tr produce_block(); - // The proposal has four of the five requested approvals but they are not sufficient to satisfy the authorization checks of eosio.sudo::exec. + // The proposal has four of the five requested approvals but they are not sufficient to satisfy the authorization checks of eosio.wrap::exec. BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() ("proposer", "carol") ("proposal_name", "first") @@ -346,7 +346,7 @@ BOOST_FIXTURE_TEST_CASE( sudo_with_msig_producers_change, eosio_sudo_tester ) tr BOOST_REQUIRE_EQUAL( 2, traces.size() ); BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio.sudo", name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( "eosio.wrap", name{traces[0]->action_traces[0].act.account} ); BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); From da16431b224fbf26264b9449e41db6dcb4e75bbe Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Oct 2018 10:37:53 -0400 Subject: [PATCH 0598/1048] rename sudo to wrap in README (and yes I know the binary action data in the examples still encode the name "sudo") --- eosio.wrap/README.md | 226 +++++++++++++++++++++---------------------- 1 file changed, 113 insertions(+), 113 deletions(-) diff --git a/eosio.wrap/README.md b/eosio.wrap/README.md index af1031e0..0bbdb1d8 100644 --- a/eosio.wrap/README.md +++ b/eosio.wrap/README.md @@ -1,32 +1,32 @@ -# eosio.sudo +# eosio.wrap ## 1. Actions: The naming convention is codeaccount::actionname followed by a list of parameters. -Execute a transaction while bypassing regular authorization checks (requires authorization of eosio.sudo which needs to be a privileged account). +Execute a transaction while bypassing regular authorization checks (requires authorization of eosio.wrap which needs to be a privileged account). -### eosio.sudo::exec executer trx +### eosio.wrap::exec executer trx - **executer** account executing the transaction - **trx** transaction to execute Deferred transaction RAM usage is billed to 'executer' -## 2. Installing the eosio.sudo contract +## 2. Installing the eosio.wrap contract -The eosio.sudo contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.sudo`. +The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. -First, the account `eosio.sudo` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.sudo` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.sudo` account. +First, the account `eosio.wrap` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.wrap` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.wrap` account. -The `eosio.sudo` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. +The `eosio.wrap` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. This guide will be using cleos to carry out the process. -### 2.1 Create the eosio.sudo account +### 2.1 Create the eosio.wrap account -#### 2.1.1 Generate the transaction to create the eosio.sudo account +#### 2.1.1 Generate the transaction to create the eosio.wrap account -The transaction to create the `eosio.sudo` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. +The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. @@ -34,9 +34,9 @@ Three unsigned transactions will be generated using cleos and then the actions w First, generate a transaction to capture the necessary actions involved in creating a new account: ``` -$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.sudo EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json -726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.sudo","bytes":51200}} -726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.sudo","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} +$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json +726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} +726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} $ cat generated_account_creation_trx.json { "expiration": "2018-06-29T17:11:36", @@ -88,7 +88,7 @@ Second, create a file (e.g. newaccount_payload.json) with the JSON payload for t $ cat newaccount_payload.json { "creator": "eosio", - "name": "eosio.sudo", + "name": "eosio.wrap", "owner": { "threshold": 1, "keys": [], @@ -139,9 +139,9 @@ $ cat generated_newaccount_trx.json } ``` -Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.sudo` account privileged: +Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: ``` -$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.sudo", "is_priv": 1}' -p eosio > generated_setpriv_trx.json +$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json $ cat generated_setpriv_trx.json { "expiration": "2018-06-29T17:11:36", @@ -168,9 +168,9 @@ $ cat generated_setpriv_trx.json } ``` -Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_sudo_account_trx.json) and edit the first three fields so it looks something like the following: +Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: ``` -$ cat create_sudo_account_trx.json +$ cat create_wrap_account_trx.json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -198,9 +198,9 @@ $ cat create_sudo_account_trx.json The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. -Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_sudo_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_sudo_account_trx.json. The final result is a create_sudo_account_trx.json file that looks like the following: +Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: ``` -$ cat create_sudo_account_trx.json +$ cat create_wrap_account_trx.json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -253,7 +253,7 @@ $ cat create_sudo_account_trx.json } ``` -The transaction in create_sudo_account_trx.json is now ready to be proposed. +The transaction in create_wrap_account_trx.json is now ready to be proposed. It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. @@ -287,32 +287,32 @@ $ cat producer_permissions.json ] ``` -#### 2.1.2 Propose the transaction to create the eosio.sudo account +#### 2.1.2 Propose the transaction to create the eosio.wrap account -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_sudo_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. -The lead block producer (`blkproducera`) should propose the transaction stored in create_sudo_account_trx.json: +The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: ``` -$ cleos multisig propose_trx createsudo producer_permissions.json create_sudo_account_trx.json blkproducera +$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createsudo","requested":[{"actor":"blkproducera","permis... +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.1.3 Review and approve the transaction to create the eosio.sudo account +#### 2.1.3 Review and approve the transaction to create the eosio.wrap account Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. The proposed transaction can be reviewed using the `cleos multisig review` command: ``` -$ cleos multisig review blkproducera createsudo > create_sudo_account_trx_to_review.json -$ head -n 30 create_sudo_account_trx_to_review.json +$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json +$ head -n 30 create_wrap_account_trx_to_review.json { - "proposal_name": "createsudo", + "proposal_name": "createwrap", "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", "transaction": { "expiration": "2018-07-06T12:00:00", @@ -332,7 +332,7 @@ $ head -n 30 create_sudo_account_trx_to_review.json ], "data": { "creator": "eosio", - "name": "eosio.sudo", + "name": "eosio.wrap", "owner": { "threshold": 1, "keys": [], @@ -345,37 +345,37 @@ $ head -n 30 create_sudo_account_trx_to_review.json The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: ``` -$ cleos multisig propose_trx -j -s -d createsudo '[]' create_sudo_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_sudo_trx_serialized.hex -$ cat expected_create_sudo_trx_serialized.hex +$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex +$ cat expected_create_wrap_trx_serialized.hex c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ cat create_sudo_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_sudo_trx_serialized.hex -$ cat proposed_create_sudo_trx_serialized.hex +$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex +$ cat proposed_create_wrap_trx_serialized.hex c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ diff expected_create_sudo_trx_serialized.hex proposed_create_sudo_trx_serialized.hex +$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex ``` When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: ``` -$ cleos multisig approve blkproducera createsudo '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createsudo","level":{"actor":"blkproducerb","permission"... +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.1.4 Execute the transaction to create the eosio.sudo account +#### 2.1.4 Execute the transaction to create the eosio.wrap account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). ``` -$ cleos multisig exec blkproducera createsudo blkproducera +$ cleos multisig exec blkproducera createwrap blkproducera executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createsudo","executer":"blkproducera"} +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} warning: transaction executed locally, but may not be confirmed by the network yet ``` -Anyone can now verify that the `eosio.sudo` was created: +Anyone can now verify that the `eosio.wrap` was created: ``` -$ cleos get account eosio.sudo +$ cleos get account eosio.wrap privileged: true permissions: owner 1: 1 eosio@active, @@ -401,19 +401,19 @@ producers: ``` -### 2.2 Deploy the eosio.sudo contract +### 2.2 Deploy the eosio.wrap contract -#### 2.2.1 Generate the transaction to deploy the eosio.sudo contract +#### 2.2.1 Generate the transaction to deploy the eosio.wrap contract -The transaction to deploy the contract to the `eosio.sudo` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. +The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. The easy way to generate this transaction is using cleos: ``` -$ cleos set contract -s -j -d eosio.sudo contracts/eosio.sudo/ > deploy_sudo_contract_trx.json -Reading WAST/WASM from contracts/eosio.sudo/eosio.sudo.wasm... +$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json +Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... Using already assembled WASM... Publishing contract... -$ cat deploy_sudo_contract_trx.json +$ cat deploy_wrap_contract_trx.json { "expiration": "2018-06-29T19:55:26", "ref_block_num": 18544, @@ -426,7 +426,7 @@ $ cat deploy_sudo_contract_trx.json "account": "eosio", "name": "setcode", "authorization": [{ - "actor": "eosio.sudo", + "actor": "eosio.wrap", "permission": "active" } ], @@ -435,7 +435,7 @@ $ cat deploy_sudo_contract_trx.json "account": "eosio", "name": "setabi", "authorization": [{ - "actor": "eosio.sudo", + "actor": "eosio.wrap", "permission": "active" } ], @@ -448,9 +448,9 @@ $ cat deploy_sudo_contract_trx.json } ``` -Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_sudo_contract_trx.json the first few lines of it may look something like the following: +Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: ``` -$ head -n 9 deploy_sudo_contract_trx.json +$ head -n 9 deploy_wrap_contract_trx.json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -464,32 +464,32 @@ $ head -n 9 deploy_sudo_contract_trx.json This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. -#### 2.2.2 Propose the transaction to deploy the eosio.sudo contract +#### 2.2.2 Propose the transaction to deploy the eosio.wrap contract -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_sudo_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. -The lead block producer (`blkproducera`) should propose the transaction stored in deploy_sudo_contract_trx.json: +The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: ``` -$ cleos multisig propose_trx deploysudo producer_permissions.json deploy_sudo_contract_trx.json blkproducera +$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploysudo","requested":[{"actor":"blkproducera","permis... +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.2.3 Review and approve the transaction to deploy the eosio.sudo contract +#### 2.2.3 Review and approve the transaction to deploy the eosio.wrap contract Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. The proposed transaction can be reviewed using the `cleos multisig review` command: ``` -$ cleos multisig review blkproducera deploysudo > deploy_sudo_contract_trx_to_review.json -$ cat deploy_sudo_contract_trx_to_review.json +$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json +$ cat deploy_wrap_contract_trx_to_review.json { - "proposal_name": "deploysudo", + "proposal_name": "deploywrap", "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", "transaction": { "expiration": "2018-07-06T12:00:00", @@ -503,12 +503,12 @@ $ cat deploy_sudo_contract_trx_to_review.json "account": "eosio", "name": "setcode", "authorization": [{ - "actor": "eosio.sudo", + "actor": "eosio.wrap", "permission": "active" } ], "data": { - "account": "eosio.sudo", + "account": "eosio.wrap", "vmtype": 0, "vmversion": 0, "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" @@ -518,12 +518,12 @@ $ cat deploy_sudo_contract_trx_to_review.json "account": "eosio", "name": "setabi", "authorization": [{ - "actor": "eosio.sudo", + "actor": "eosio.wrap", "permission": "active" } ], "data": { - "account": "eosio.sudo", + "account": "eosio.wrap", "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" }, "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" @@ -534,54 +534,54 @@ $ cat deploy_sudo_contract_trx_to_review.json } ``` -Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.sudo` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.sudo` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. +Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. -This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_sudo_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: +This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: ``` -$ cleos multisig propose_trx -j -s -d deploysudo '[]' deploy_sudo_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_sudo_trx_serialized.hex -$ cat expected_deploy_sudo_trx_serialized.hex | cut -c -50 +$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex +$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 c0593f5b00000000000000000000020000000000ea30550000 -$ cat deploy_sudo_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_sudo_trx_serialized.hex -$ cat proposed_deploy_sudo_trx_serialized.hex | cut -c -50 +$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex +$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 c0593f5b00000000000000000000020000000000ea30550000 -$ diff expected_deploy_sudo_trx_serialized.hex proposed_deploy_sudo_trx_serialized.hex +$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex ``` When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: ``` -$ cleos multisig approve blkproducera deploysudo '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploysudo","level":{"actor":"blkproducerb","permission"... +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.2.4 Execute the transaction to create the eosio.sudo account +#### 2.2.4 Execute the transaction to create the eosio.wrap account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). ``` -$ cleos multisig exec blkproducera deploysudo blkproducera +$ cleos multisig exec blkproducera deploywrap blkproducera executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploysudo","executer":"blkproducera"} +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} ``` -Anyone can now verify that the `eosio.sudo` contract was deployed correctly. +Anyone can now verify that the `eosio.wrap` contract was deployed correctly. ``` -$ cleos get code -a retrieved-eosio.sudo.abi eosio.sudo +$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c -saving abi to retrieved-eosio.sudo.abi -$ sha256sum contracts/eosio.sudo/eosio.sudo.wasm -1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.sudo/eosio.sudo.wasm +saving abi to retrieved-eosio.wrap.abi +$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm +1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm ``` -If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.sudo.abi, can then be compared to the original ABI of the contract (contracts/eosio.sudo/eosio.sudo.abi) to ensure they are semantically the same. +If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. -## 3. Using the eosio.sudo contract +## 3. Using the eosio.wrap contract ### 3.1 Example: Updating owner authority of an arbitrary account -This example will demonstrate how to use the deployed eosio.sudo contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos sudo exec` sub-command. However, the guide also demonstrates what to do if the `cleos sudo exec` sub-command is not available. +This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. @@ -677,15 +677,15 @@ $ cat update_alice_owner_trx.json } ``` -The next step is to generate the transaction containing the `eosio.sudo::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. +The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. ``` -$ cleos sudo exec -s -j -d blkproducera update_alice_owner_trx.json > sudo_update_alice_owner_trx.json +$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json ``` -Once again modify sudo_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. +Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. ``` -$ cat sudo_update_alice_owner_trx.json +$ cat wrap_update_alice_owner_trx.json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -695,13 +695,13 @@ $ cat sudo_update_alice_owner_trx.json "delay_sec": 0, "context_free_actions": [], "actions": [{ - "account": "eosio.sudo", + "account": "eosio.wrap", "name": "exec", "authorization": [{ "actor": "blkproducera", "permission": "active" },{ - "actor": "eosio.sudo", + "actor": "eosio.wrap", "permission": "active" } ], @@ -714,7 +714,7 @@ $ cat sudo_update_alice_owner_trx.json } ``` -If the `cleos sudo` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the sudo_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos sudo exec` sub-command method. +If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: ``` @@ -723,10 +723,10 @@ $ cat update_alice_owner_trx_serialized.hex 0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 ``` -Then generate the template for the transaction containing the `eosio.sudo::exec` action: +Then generate the template for the transaction containing the `eosio.wrap::exec` action: ``` -$ cleos push action -s -j -d eosio.sudo exec '{"executer": "blkproducera", "trx": ""}' > sudo_update_alice_owner_trx.json -$ cat sudo_update_alice_owner_trx.json +$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json +$ cat wrap_update_alice_owner_trx.json { "expiration": "2018-06-29T23:34:01", "ref_block_num": 23708, @@ -736,7 +736,7 @@ $ cat sudo_update_alice_owner_trx.json "delay_sec": 0, "context_free_actions": [], "actions": [{ - "account": "eosio.sudo", + "account": "eosio.wrap", "name": "exec", "authorization": [], "data": "60ae423ad15b613c" @@ -748,17 +748,17 @@ $ cat sudo_update_alice_owner_trx.json } ``` -Then modify the transaction in sudo_update_alice_owner_trx.json as follows: +Then modify the transaction in wrap_update_alice_owner_trx.json as follows: * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); - * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in sudo_update_alice_owner_trx.json. + * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. #### 3.1.2 Propose the transaction to change the owner permission of an account -The lead block producer (`blkproducera`) should propose the transaction stored in sudo_update_alice_owner_trx.json: +The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: ``` -$ cleos multisig propose_trx updatealice producer_permissions.json sudo_update_alice_owner_trx.json blkproducera +$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us # eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... warning: transaction executed locally, but may not be confirmed by the network yet @@ -768,8 +768,8 @@ warning: transaction executed locally, but may not be confirmed by the network y Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. ``` -$ cleos multisig review blkproducera updatealice > sudo_update_alice_owner_trx_to_review.json -$ cat sudo_update_alice_owner_trx_to_review.json +$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json +$ cat wrap_update_alice_owner_trx_to_review.json { "proposal_name": "updatealice", "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", @@ -782,13 +782,13 @@ $ cat sudo_update_alice_owner_trx_to_review.json "delay_sec": 0, "context_free_actions": [], "actions": [{ - "account": "eosio.sudo", + "account": "eosio.wrap", "name": "exec", "authorization": [{ "actor": "blkproducera", "permission": "active" },{ - "actor": "eosio.sudo", + "actor": "eosio.wrap", "permission": "active" } ], @@ -824,19 +824,19 @@ $ cat sudo_update_alice_owner_trx_to_review.json } ``` -The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.sudo::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. +The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.wrap::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. -Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.sudo` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. +Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. -Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file sudo_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: +Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: ``` -$ cleos multisig propose_trx -j -s -d updatealice '[]' sudo_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_sudo_update_alice_owner_trx_serialized.hex -$ cat expected_sudo_update_alice_owner_trx_serialized.hex +$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex +$ cat expected_wrap_update_alice_owner_trx_serialized.hex c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ cat sudo_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_sudo_update_alice_owner_trx_serialized.hex -$ cat proposed_sudo_update_alice_owner_trx_serialized.hex +$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex +$ cat proposed_wrap_update_alice_owner_trx_serialized.hex c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ diff expected_sudo_update_alice_owner_trx_serialized.hex proposed_sudo_update_alice_owner_trx_serialized.hex +$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex ``` When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: From 40d6cd0e5a525c5e862edfe1be04965965b4fa8f Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Oct 2018 10:42:50 -0400 Subject: [PATCH 0599/1048] make eosio.sudo to eosio.wrap rename change in main README as well --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 02cecc92..4e212217 100644 --- a/README.md +++ b/README.md @@ -2,13 +2,13 @@ ## Version : 1.3.1 -The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and sudo contracts. +The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. This repository contains examples of these privileged contracts that are useful when deploying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) - * [eosio.sudo](https://github.com/eosio/eosio.contracts/tree/master/eosio.sudo) + * [eosio.wrap](https://github.com/eosio/eosio.contracts/tree/master/eosio.wrap) The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) From e03c9313fa479f05b71b80a2dd2a49328902c7bb Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Oct 2018 18:50:05 -0400 Subject: [PATCH 0600/1048] ensure symbol actually exists in eosio.token::open #93 --- eosio.token/src/eosio.token.cpp | 9 ++++++++- tests/eosio.token_tests.cpp | 8 +++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/eosio.token/src/eosio.token.cpp b/eosio.token/src/eosio.token.cpp index 9e35fa58..b18a68af 100644 --- a/eosio.token/src/eosio.token.cpp +++ b/eosio.token/src/eosio.token.cpp @@ -139,8 +139,15 @@ void token::add_balance( name owner, asset value, name ram_payer ) void token::open( name owner, const symbol& symbol, name ram_payer ) { require_auth( ram_payer ); + + auto sym_code_raw = symbol.code().raw(); + + stats statstable( _self, sym_code_raw ); + const auto& st = statstable.get( sym_code_raw, "symbol does not exist" ); + eosio_assert( st.supply.symbol == symbol, "symbol precision mismatch" ); + accounts acnts( _self, owner.value ); - auto it = acnts.find( symbol.code().raw() ); + auto it = acnts.find( sym_code_raw ); if( it == acnts.end() ) { acnts.emplace( ram_payer, [&]( auto& a ){ a.balance = asset{0, symbol}; diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 7a3c0eb0..8d7d73ff 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -105,7 +105,7 @@ class eosio_token_tester : public tester { account_name ram_payer ) { return push_action( ram_payer, N(open), mvo() ( "owner", owner ) - ( "symbol", "0,CERO" ) + ( "symbol", symbolname ) ( "ram_payer", ram_payer ) ); } @@ -377,6 +377,12 @@ BOOST_FIXTURE_TEST_CASE( open_tests, eosio_token_tester ) try { ("balance", "200 CERO") ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "symbol does not exist" ), + open( N(carol), "0,INVALID", N(alice) ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "symbol precision mismatch" ), + open( N(carol), "1,CERO", N(alice) ) ); + } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( close_tests, eosio_token_tester ) try { From b24957c1dbb508f4f90e4b13bcd2f6d342e9b6d9 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Oct 2018 19:15:40 -0400 Subject: [PATCH 0601/1048] bump version to 1.4.0 and update dependencies --- CMakeLists.txt | 4 ++-- README.md | 6 +++--- tests/CMakeLists.txt | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 68f75dbf..3b5c69ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.3.1) +project(eosio_contracts VERSION 1.4.0) -set(EOSIO_CDT_VERSION_MIN "1.2") # REMINDER: Change this to 1.3 before release +set(EOSIO_CDT_VERSION_MIN "1.3") set(EOSIO_CDT_VERSION_SOFT_MAX "1.3") #set(EOSIO_CDT_VERSION_HARD_MAX "") diff --git a/README.md b/README.md index 4e212217..8ff86a9d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.3.1 +## Version : 1.4.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.2.x](https://github.com/EOSIO/eos/releases/tag/v1.2.6) -* [eosio.cdt v1.2.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.2.1) +* [eosio v1.3.x](https://github.com/EOSIO/eos/releases/tag/v1.3.2) +* [eosio.cdt v1.3.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.3.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7e6132cf..ef8603fb 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 3.5 ) -set(EOSIO_VERSION_MIN "1.2") -set(EOSIO_VERSION_SOFT_MAX "1.2") +set(EOSIO_VERSION_MIN "1.3") +set(EOSIO_VERSION_SOFT_MAX "1.3") #set(EOSIO_VERSION_HARD_MAX "") include(../CheckVersion.txt) From 38b09c11ae92c13c2e1b49b4cfa46ad13c2832a4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 11 Oct 2018 19:30:14 -0400 Subject: [PATCH 0602/1048] Add deposit and withdraw actions, remove inline transfers --- .../include/eosio.system/eosio.system.hpp | 36 ++++-- eosio.system/src/eosio.system.cpp | 1 + eosio.system/src/rex.cpp | 104 +++++++++++++----- 3 files changed, 102 insertions(+), 39 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 8e72fbfe..a3614d91 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -189,6 +189,15 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; + struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { + name owner; + asset balance; + + uint64_t primary_key()const { return owner.value; } + }; + + typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; + struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { name owner; asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote @@ -202,13 +211,11 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { name from; name receiver; - asset loan_payment; + asset payment; + asset balance; asset total_staked; uint64_t loan_num; - eosio::time_point expiration; - - bool auto_renew = false; - asset balance; + eosio::time_point expiration; uint64_t primary_key()const { return loan_num; } uint64_t by_expr()const { return expiration.elapsed.count(); } @@ -264,6 +271,7 @@ namespace eosiosystem { eosio_global_state3 _gstate3; rammarket _rammarket; rex_pool_table _rextable; + rex_fund_table _rexfunds; rex_balance_table _rexbalance; public: @@ -310,6 +318,12 @@ namespace eosiosystem { asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + [[eosio::action]] + void deposit( name owner, asset amount ); + + [[eosio::action]] + void withdraw( name owner, asset amount ); + /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ @@ -344,9 +358,9 @@ namespace eosiosystem { * creator. User claims the refund in a separate action. */ [[eosio::action]] - void rentcpu( name from, name receiver, asset payment, bool auto_renew ); + void rentcpu( name from, name receiver, asset loan_payment, asset loan_fund ); [[eosio::action]] - void rentnet( name from, name receiver, asset payment, bool auto_renew ); + void rentnet( name from, name receiver, asset loan_payment, asset loan_fund ); /** * Loan initiator funds a given CPU or NET loan. Loan must've been set as autorenew. @@ -478,10 +492,12 @@ namespace eosiosystem { std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); void deposit_rex( const name& from, const asset& amount ); template - int64_t rentrex( T& table, name from, name receiver, const asset& payment, bool auto_renew, - const std::string& memo ); + int64_t rentrex( T& table, name from, name receiver, const asset& loan_payment, const asset& loan_fund ); template - void fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment, const std::string& memo ); + void fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment ); + + void transfer_from_fund( name owner, const asset& amount ); + void transfer_to_fund( name owner, const asset& amount ); // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index df5b2e06..21f00c70 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -20,6 +20,7 @@ namespace eosiosystem { _global3(_self, _self.value), _rammarket(_self, _self.value), _rextable(_self, _self.value), + _rexfunds(_self, _self.value), _rexbalance(_self, _self.value) { diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 902769e5..065a6d70 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -5,7 +5,44 @@ #include namespace eosiosystem { - + + void system_contract::deposit( name owner, asset amount ) { + + require_auth( owner ); + + eosio_assert( amount.symbol == core_symbol(), "must deposit core token" ); + + INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { owner, active_permission }, + { owner, rex_account, amount, "deposit into REX fund" } ); + auto itr = _rexfunds.find( owner.value ); + if( itr == _rexfunds.end() ) { + _rexfunds.emplace( owner, [&]( auto& fund ) { + fund.owner = owner; + fund.balance = amount; + }); + } else { + _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { + fund.balance.amount += amount.amount; + }); + } + } + + void system_contract::withdraw( name owner, asset amount ) { + + require_auth( owner ); + + eosio_assert( amount.symbol == core_symbol(), "must withdraw core token" ); + + auto itr = _rexfunds.require_find( owner.value, "account has no REX funds" ); + eosio_assert( amount <= itr->balance, "insufficient funds"); + _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { + fund.balance.amount -= amount.amount; + }); + + INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, + { rex_account, owner, amount, "withdraw from REX fund" } ); + } + /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ @@ -23,8 +60,7 @@ namespace eosiosystem { "must vote for proxy or at least 21 producers before buying REX" ); } - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, {from,active_permission}, - { from, rex_account, amount, "buy REX" } ); + transfer_from_fund( from, amount ); asset rex_received( 0, rex_symbol ); @@ -105,8 +141,7 @@ namespace eosiosystem { auto result = close_rex_order( bitr, rex ); if( std::get<0>(result) ) { /// sellrex has been processed successfuly, transfer tokens and update voting power - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, - { rex_account, from, asset( std::get<1>(result), core_symbol() ), "sell REX" } ); + transfer_to_fund( from, asset( std::get<1>(result), core_symbol() ) ); update_voting_power( from, asset( -(std::get<2>(result)), core_symbol() ) ); } else { /** @@ -205,21 +240,21 @@ namespace eosiosystem { * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ - void system_contract::rentcpu( name from, name receiver, asset payment, bool auto_renew ) { + void system_contract::rentcpu( name from, name receiver, asset loan_payment, asset loan_fund ) { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); - int64_t rented_tokens = rentrex( cpu_loans, from, receiver, payment, auto_renew, "rent CPU" ); + int64_t rented_tokens = rentrex( cpu_loans, from, receiver, loan_payment, loan_fund ); update_resource_limits( receiver, rented_tokens, 0 ); } - void system_contract::rentnet( name from, name receiver, asset payment, bool auto_renew ) { + void system_contract::rentnet( name from, name receiver, asset loan_payment, asset loan_fund ) { require_auth( from ); rex_net_loan_table net_loans( _self, _self.value ); - int64_t rented_tokens = rentrex( net_loans, from, receiver, payment, auto_renew, "rent NET" ); + int64_t rented_tokens = rentrex( net_loans, from, receiver, loan_payment, loan_fund ); update_resource_limits( receiver, 0, rented_tokens ); } @@ -228,7 +263,7 @@ namespace eosiosystem { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); - fundrexloan( cpu_loans, from, loan_num, payment, "fund CPU loan" ); + fundrexloan( cpu_loans, from, loan_num, payment ); } void system_contract::fundnetloan( name from, uint64_t loan_num, asset payment ) { @@ -236,7 +271,7 @@ namespace eosiosystem { require_auth( from ); rex_net_loan_table net_loans( _self, _self.value ); - fundrexloan( net_loans, from, loan_num, payment, "fund NET loan" ); + fundrexloan( net_loans, from, loan_num, payment ); } void system_contract::claimrefund( name owner ) { @@ -291,27 +326,27 @@ namespace eosiosystem { bool delete_loan = false; int64_t delta_stake = 0; - if( itr->auto_renew && itr->loan_payment <= itr->balance ) { + if( itr->payment <= itr->balance ) { int64_t rented_tokens = 0; _rextable.modify( rexi, same_payer, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, - itr->loan_payment.amount ); + itr->payment.amount ); rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += itr->loan_payment.amount; + rt.total_unlent.amount += itr->payment.amount; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); idx.modify ( itr, same_payer, [&]( auto& loan ) { delta_stake = rented_tokens - loan.total_staked.amount; loan.total_staked.amount = rented_tokens; loan.expiration += eosio::days(30); - loan.balance.amount -= loan.loan_payment.amount; + loan.balance.amount -= loan.payment.amount; }); } else { delete_loan = true; delta_stake = -( itr->total_staked.amount ); /// refund "from" account if the closed loan balance is positive - if( itr->auto_renew && itr->balance.amount > 0 ) { + if( itr->balance.amount > 0 ) { loan_refund_table loan_refunds( _self, _self.value ); auto ref_itr = loan_refunds.find( itr->from.value ); if( ref_itr == loan_refunds.end() ) { @@ -397,13 +432,13 @@ namespace eosiosystem { } template - int64_t system_contract::rentrex( T& table, name from, name receiver, const asset& payment, - bool auto_renew, const std::string& memo ) { + int64_t system_contract::rentrex( T& table, name from, name receiver, const asset& payment, const asset& fund ) { + runrex(2); - eosio_assert( payment.symbol == core_symbol(), "asset must be system token" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { from, active_permission }, - { from, rex_account, payment, memo } ); + eosio_assert( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); + + transfer_from_fund( from, payment + fund ); auto itr = _rextable.begin(); eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); @@ -420,13 +455,11 @@ namespace eosiosystem { table.emplace( from, [&]( auto& c ) { c.from = from; c.receiver = receiver; - c.loan_payment = payment; + c.payment = payment; + c.balance = fund; c.total_staked = asset( rented_tokens, core_symbol() ); c.expiration = current_time_point() + eosio::days(30); c.loan_num = itr->loan_num; - - c.auto_renew = auto_renew; - c.balance = asset( 0, core_symbol() ); }); return rented_tokens; @@ -470,18 +503,31 @@ namespace eosiosystem { } template - void system_contract::fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment, const std::string& memo ) { + void system_contract::fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment ) { eosio_assert( payment.symbol == core_symbol(), "asset must be system token" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { from, active_permission }, - { from, rex_account, payment, memo } ); + transfer_from_fund( from, payment ); auto itr = table.find( loan_num ); eosio_assert( itr != table.end(), "loan not found" ); eosio_assert( itr->from == from, "actor has to be loan creator" ); - eosio_assert( itr->auto_renew, "loan must be set as auto-renew" ); eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); table.modify( itr, same_payer, [&]( auto& loan ) { loan.balance.amount += payment.amount; }); } + void system_contract::transfer_from_fund( name owner, const asset& amount ) { + auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); + eosio_assert( amount <= itr->balance, "insufficient funds"); + _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { + fund.balance.amount -= amount.amount; + }); + } + + void system_contract::transfer_to_fund( name owner, const asset& amount ) { + auto itr = _rexfunds.require_find( owner.value, "programmer error" ); + _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { + fund.balance.amount += amount.amount; + }); + } + }; /// namespace eosiosystem From 16f4eabdee996a279314390138da55168c8d4920 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 12 Oct 2018 18:54:15 -0400 Subject: [PATCH 0603/1048] Changes to REX account management --- .../include/eosio.system/eosio.system.hpp | 32 ++--- eosio.system/src/eosio.system.cpp | 3 +- eosio.system/src/rex.cpp | 116 +++++++----------- 3 files changed, 55 insertions(+), 96 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index a3614d91..18e35c67 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -232,15 +232,6 @@ namespace eosiosystem { indexed_by<"byowner"_n, const_mem_fun> > rex_net_loan_table; - struct [[eosio::table,eosio::contract("eosio.system")]] loan_refund { - name owner; - asset balance; - - uint64_t primary_key()const { return owner.value; } - }; - - typedef eosio::multi_index< "loanrefunds"_n, loan_refund > loan_refund_table; - struct [[eosio::table,eosio::contract("eosio.system")]] rex_order { name owner; asset rex_requested; @@ -257,6 +248,12 @@ namespace eosiosystem { typedef eosio::multi_index< "rexqueue"_n, rex_order, indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; + struct rex_order_output { + bool success; + asset proceeds; + asset unstake_quant; + }; + class [[eosio::contract("eosio.system")]] system_contract : public native { private: @@ -343,13 +340,6 @@ namespace eosiosystem { [[eosio::action]] void cnclrexorder( name owner ); - /** - * Transfers processed sellrex order that had been queued proceeds to owner account. Fails if - * order hasn't been filled. - */ - [[eosio::action]] - void claimrex( name owner ); - /** * Use payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire unless auto_renew == true. @@ -370,12 +360,6 @@ namespace eosiosystem { [[eosio::action]] void fundnetloan( name from, uint64_t loan_num, asset payment ); - /** - * Transfers remaining balance of closed auto-renew loans to owner account. - */ - [[eosio::action]] - void claimrefund( name owner ); - /** * Updates REX vote stake of owner to its current value. */ @@ -489,13 +473,13 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); - std::tuple close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + rex_order_output close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + void update_rex_account( name owner, asset proceeds, asset unstake_quant ); void deposit_rex( const name& from, const asset& amount ); template int64_t rentrex( T& table, name from, name receiver, const asset& loan_payment, const asset& loan_fund ); template void fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment ); - void transfer_from_fund( name owner, const asset& amount ); void transfer_to_fund( name owner, const asset& amount ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 21f00c70..736478a4 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -314,8 +314,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, // eosio.system.cpp (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (buyrex)(sellrex)(cnclrexorder)(claimrex)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) - (claimrefund)(updaterex) + (deposit)(withdraw)(buyrex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan)(updaterex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 065a6d70..e73a6aa0 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -25,6 +25,8 @@ namespace eosiosystem { fund.balance.amount += amount.amount; }); } + + update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } void system_contract::withdraw( name owner, asset amount ) { @@ -33,6 +35,8 @@ namespace eosiosystem { eosio_assert( amount.symbol == core_symbol(), "must withdraw core token" ); + update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); + auto itr = _rexfunds.require_find( owner.value, "account has no REX funds" ); eosio_assert( amount <= itr->balance, "insufficient funds"); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { @@ -116,9 +120,9 @@ namespace eosiosystem { }); } - update_voting_power( from, amount ); - runrex(2); + + update_rex_account( from, asset( 0, core_symbol() ), amount ); } /** @@ -133,22 +137,16 @@ namespace eosiosystem { auto itr = _rextable.begin(); eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); - auto bitr = _rexbalance.find( from.value ); - eosio_assert( bitr != _rexbalance.end(), "user must first buyrex" ); + auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); - auto result = close_rex_order( bitr, rex ); - if( std::get<0>(result) ) { - /// sellrex has been processed successfuly, transfer tokens and update voting power - transfer_to_fund( from, asset( std::get<1>(result), core_symbol() ) ); - update_voting_power( from, asset( -(std::get<2>(result)), core_symbol() ) ); - } else { + auto current_order = close_rex_order( bitr, rex ); + update_rex_account( from, current_order.proceeds, -current_order.unstake_quant ); + if( !current_order.success ) { /** * REX order couldn't be filled and is added to queue. * If account already has an open order, requested rex is added to existing order. - * If account has a closed order, action fails and account must claimrex first in order - * to delete closed order from queue. */ rex_order_table rex_orders( _self, _self.value ); auto oitr = rex_orders.find( from.value ); @@ -156,12 +154,12 @@ namespace eosiosystem { rex_orders.emplace( from, [&]( auto& ordr ) { ordr.owner = from; ordr.rex_requested = rex; + ordr.is_open = true; ordr.proceeds = asset( 0, core_symbol() ); ordr.unstake_quant = asset( 0, core_symbol() ); ordr.order_time = current_time_point(); }); } else { - eosio_assert( oitr->is_open, "user has a closed rex order in queue, must claimrex first"); rex_orders.modify( oitr, same_payer, [&]( auto& ordr ) { ordr.rex_requested.amount += rex.amount; eosio_assert( bitr->rex_balance >= ordr.rex_requested, "insufficient funds for current and scheduled orders"); @@ -175,28 +173,11 @@ namespace eosiosystem { require_auth( owner ); rex_order_table rexorders( _self, _self.value ); - auto itr = rexorders.find( owner.value ); - eosio_assert( itr != rexorders.end(), "no sellrex order is scheduled" ); + auto itr = rexorders.require_find( owner.value, "no sellrex order is scheduled" ); eosio_assert( itr->is_open, "sellrex order has been closed and cannot be canceled" ); rexorders.erase( itr ); } - void system_contract::claimrex( name owner ) { - - require_auth( owner ); - - runrex(2); - - rex_order_table rexorders( _self, _self.value ); - auto itr = rexorders.find( owner.value ); - eosio_assert( itr != rexorders.end(), "no sellrex order is scheduled" ); - eosio_assert( !itr->is_open, "sellrex order has not been closed" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, - { rex_account, itr->owner, itr->proceeds, "claim REX proceeds" } ); - update_voting_power( owner, -( itr->unstake_quant ) ); - rexorders.erase( itr ); - } - /** * Given two connector balances (conin, and conout), and an incoming amount of * in, this function will modify conin and conout and return the delta out. @@ -274,25 +255,12 @@ namespace eosiosystem { fundrexloan( net_loans, from, loan_num, payment ); } - void system_contract::claimrefund( name owner ) { - - require_auth( owner ); - - loan_refund_table loan_refunds( _self, _self.value ); - auto itr = loan_refunds.find( owner.value ); - eosio_assert( itr != loan_refunds.end(), "no refund to be claimed" ); - if( itr->balance.amount > 0 ) - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, - { rex_account, owner, itr->balance, "claim REX loan refund" } ); - loan_refunds.erase( itr ); - } - void system_contract::updaterex( name owner ) { require_auth( owner ); auto itr = _rexbalance.find( owner.value ); - eosio_assert( itr != _rexbalance.end() && itr->rex_balance.amount > 0, "account has no REX balance"); + eosio_assert( itr != _rexbalance.end() && itr->rex_balance.amount > 0, "account has no REX balance" ); const asset init_stake = itr->vote_stake; runrex(2); @@ -307,7 +275,8 @@ namespace eosiosystem { rb.vote_stake = current_stake; }); - update_voting_power( owner, current_stake - init_stake ); + asset delta_stake = current_stake - init_stake; + update_rex_account( owner, asset( 0, core_symbol() ), delta_stake ); } /** @@ -347,18 +316,7 @@ namespace eosiosystem { delta_stake = -( itr->total_staked.amount ); /// refund "from" account if the closed loan balance is positive if( itr->balance.amount > 0 ) { - loan_refund_table loan_refunds( _self, _self.value ); - auto ref_itr = loan_refunds.find( itr->from.value ); - if( ref_itr == loan_refunds.end() ) { - loan_refunds.emplace( itr->from, [&]( auto& ref ) { - ref.owner = itr->from; - ref.balance = itr->balance; - }); - } else { - loan_refunds.modify( ref_itr, itr->from, [&]( auto& ref ) { - ref.balance.amount += itr->balance.amount; - }); - } + transfer_to_fund( itr->from, itr->balance ); } } @@ -418,10 +376,10 @@ namespace eosiosystem { auto result = close_rex_order( bitr, oitr->rex_requested ); auto next = oitr; ++next; - if( std::get<0>( result ) ) { + if( result.success ) { idx.modify( oitr, same_payer, [&]( auto& rt ) { - rt.proceeds.amount = std::get<1>( result ); - rt.unstake_quant.amount = std::get<2>( result ); + rt.proceeds.amount = result.proceeds.amount; + rt.unstake_quant.amount = result.unstake_quant.amount; rt.close(); }); } @@ -438,6 +396,7 @@ namespace eosiosystem { eosio_assert( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); + update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( from, payment + fund ); auto itr = _rextable.begin(); @@ -465,28 +424,32 @@ namespace eosiosystem { return rented_tokens; } - std::tuple system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + rex_order_output system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; - const int64_t proceeds = S0 - S1; // asset( S0 - S1, core_symbol() ); - const int64_t unstake_quant = ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount; + asset proceeds( S0 - S1, core_symbol() ); + asset unstake_quant( ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount, + core_symbol() ); bool success = false; - if( proceeds <= rexitr->total_unlent.amount ) { + if( proceeds.amount <= rexitr->total_unlent.amount ) { _rextable.modify( rexitr, same_payer, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; }); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount -= unstake_quant; + rb.vote_stake.amount -= unstake_quant.amount; rb.rex_balance.amount -= rex.amount; }); success = true; + } else { + proceeds.amount = 0; + unstake_quant.amount = 0; } - return std::make_tuple( success, proceeds, unstake_quant ); + return { success, proceeds, unstake_quant }; } void system_contract::deposit_rex( const name& from, const asset& amount ) { @@ -504,10 +467,9 @@ namespace eosiosystem { template void system_contract::fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment ) { - eosio_assert( payment.symbol == core_symbol(), "asset must be system token" ); + eosio_assert( payment.symbol == core_symbol(), "must use core token" ); transfer_from_fund( from, payment ); - auto itr = table.find( loan_num ); - eosio_assert( itr != table.end(), "loan not found" ); + auto itr = table.require_find( loan_num, "loan not found" ); eosio_assert( itr->from == from, "actor has to be loan creator" ); eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); table.modify( itr, same_payer, [&]( auto& loan ) { @@ -530,4 +492,18 @@ namespace eosiosystem { }); } + void system_contract::update_rex_account( name owner, asset proceeds, asset delta_stake ) { + rex_order_table rex_orders( _self, _self.value ); + auto itr = rex_orders.find( owner.value ); + if( itr != rex_orders.end() && !itr->is_open ) { + proceeds.amount += itr->proceeds.amount; + delta_stake.amount -= itr->unstake_quant.amount; + rex_orders.erase( itr ); + } + if( proceeds.amount > 0 ) + transfer_to_fund( owner, proceeds ); + if( delta_stake.amount != 0 ) + update_voting_power( owner, delta_stake ); + } + }; /// namespace eosiosystem From 10ad847c17a58c4890911783c00cc39c05f27bc3 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 14 Oct 2018 21:56:07 -0400 Subject: [PATCH 0604/1048] More REX changes --- .../include/eosio.system/eosio.system.hpp | 14 ++- eosio.system/src/eosio.system.cpp | 7 +- eosio.system/src/rex.cpp | 115 +++++++++++------- tests/eosio.system_tester.hpp | 35 +++++- tests/eosio.system_tests.cpp | 24 ++-- 5 files changed, 132 insertions(+), 63 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 18e35c67..794dcc7b 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -270,6 +270,7 @@ namespace eosiosystem { rex_pool_table _rextable; rex_fund_table _rexfunds; rex_balance_table _rexbalance; + rex_order_table _rexorders; public: static constexpr eosio::name active_permission{"active"_n}; @@ -359,6 +360,10 @@ namespace eosiosystem { void fundcpuloan( name from, uint64_t loan_num, asset payment ); [[eosio::action]] void fundnetloan( name from, uint64_t loan_num, asset payment ); + [[eosio::action]] + void defcpuloan( name from, uint64_t loan_num, asset amount ); + [[eosio::action]] + void defnetloan( name from, uint64_t loan_num, asset amount ); /** * Updates REX vote stake of owner to its current value. @@ -366,6 +371,9 @@ namespace eosiosystem { [[eosio::action]] void updaterex( name owner ); + [[eosio::action]] + void rexexec( uint16_t max ); + /** * Decreases the total tokens delegated by from to receiver and/or * frees the memory associated with the delegation if there is nothing @@ -477,9 +485,11 @@ namespace eosiosystem { void update_rex_account( name owner, asset proceeds, asset unstake_quant ); void deposit_rex( const name& from, const asset& amount ); template - int64_t rentrex( T& table, name from, name receiver, const asset& loan_payment, const asset& loan_fund ); + int64_t rent_rex( T& table, name from, name receiver, const asset& loan_payment, const asset& loan_fund ); + template + void fund_rex_loan( T& table, name from, uint64_t loan_num, const asset& payment ); template - void fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment ); + void defund_rex_loan( T& table, name from, uint64_t loan_num, const asset& amount ); void transfer_from_fund( name owner, const asset& amount ); void transfer_to_fund( name owner, const asset& amount ); diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 736478a4..d6939361 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -21,9 +21,9 @@ namespace eosiosystem { _rammarket(_self, _self.value), _rextable(_self, _self.value), _rexfunds(_self, _self.value), - _rexbalance(_self, _self.value) + _rexbalance(_self, _self.value), + _rexorders(_self, _self.value) { - //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; @@ -314,7 +314,8 @@ EOSIO_DISPATCH( eosiosystem::system_contract, // eosio.system.cpp (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (deposit)(withdraw)(buyrex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan)(updaterex) + (deposit)(withdraw)(buyrex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) + (defcpuloan)(defnetloan)(updaterex)(rexexec) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index e73a6aa0..e1316534 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -148,10 +148,9 @@ namespace eosiosystem { * REX order couldn't be filled and is added to queue. * If account already has an open order, requested rex is added to existing order. */ - rex_order_table rex_orders( _self, _self.value ); - auto oitr = rex_orders.find( from.value ); - if( oitr == rex_orders.end() ) { - rex_orders.emplace( from, [&]( auto& ordr ) { + auto oitr = _rexorders.find( from.value ); + if( oitr == _rexorders.end() ) { + _rexorders.emplace( from, [&]( auto& ordr ) { ordr.owner = from; ordr.rex_requested = rex; ordr.is_open = true; @@ -160,7 +159,7 @@ namespace eosiosystem { ordr.order_time = current_time_point(); }); } else { - rex_orders.modify( oitr, same_payer, [&]( auto& ordr ) { + _rexorders.modify( oitr, same_payer, [&]( auto& ordr ) { ordr.rex_requested.amount += rex.amount; eosio_assert( bitr->rex_balance >= ordr.rex_requested, "insufficient funds for current and scheduled orders"); }); @@ -172,10 +171,9 @@ namespace eosiosystem { require_auth( owner ); - rex_order_table rexorders( _self, _self.value ); - auto itr = rexorders.require_find( owner.value, "no sellrex order is scheduled" ); + auto itr = _rexorders.require_find( owner.value, "no sellrex order is scheduled" ); eosio_assert( itr->is_open, "sellrex order has been closed and cannot be canceled" ); - rexorders.erase( itr ); + _rexorders.erase( itr ); } /** @@ -226,7 +224,7 @@ namespace eosiosystem { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); - int64_t rented_tokens = rentrex( cpu_loans, from, receiver, loan_payment, loan_fund ); + int64_t rented_tokens = rent_rex( cpu_loans, from, receiver, loan_payment, loan_fund ); update_resource_limits( receiver, rented_tokens, 0 ); } @@ -235,7 +233,7 @@ namespace eosiosystem { require_auth( from ); rex_net_loan_table net_loans( _self, _self.value ); - int64_t rented_tokens = rentrex( net_loans, from, receiver, loan_payment, loan_fund ); + int64_t rented_tokens = rent_rex( net_loans, from, receiver, loan_payment, loan_fund ); update_resource_limits( receiver, 0, rented_tokens ); } @@ -244,7 +242,7 @@ namespace eosiosystem { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); - fundrexloan( cpu_loans, from, loan_num, payment ); + fund_rex_loan( cpu_loans, from, loan_num, payment ); } void system_contract::fundnetloan( name from, uint64_t loan_num, asset payment ) { @@ -252,7 +250,23 @@ namespace eosiosystem { require_auth( from ); rex_net_loan_table net_loans( _self, _self.value ); - fundrexloan( net_loans, from, loan_num, payment ); + fund_rex_loan( net_loans, from, loan_num, payment ); + } + + void system_contract::defcpuloan( name from, uint64_t loan_num, asset amount ) { + + require_auth( from ); + + rex_cpu_loan_table cpu_loans( _self, _self.value ); + defund_rex_loan( cpu_loans, from, loan_num, amount ); + } + + void system_contract::defnetloan( name from, uint64_t loan_num, asset amount ) { + + require_auth( from ); + + rex_net_loan_table net_loans( _self, _self.value ); + defund_rex_loan( net_loans, from, loan_num, amount ); } void system_contract::updaterex( name owner ) { @@ -279,6 +293,13 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), delta_stake ); } + void system_contract::rexexec( uint16_t max ) { + + require_auth( _self ); + + runrex( max ); + } + /** * Perform maitenance operations on expired rex */ @@ -295,7 +316,7 @@ namespace eosiosystem { bool delete_loan = false; int64_t delta_stake = 0; - if( itr->payment <= itr->balance ) { + if( itr->payment <= itr->balance && _rexorders.begin() == _rexorders.end() ) { int64_t rented_tokens = 0; _rextable.modify( rexi, same_payer, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, @@ -331,6 +352,27 @@ namespace eosiosystem { }); } + /// process sellrex orders + { + auto idx = _rexorders.get_index<"bytime"_n>(); + auto oitr = idx.begin(); + for( uint16_t i = 0; i < max; ++i ) { + if( oitr == idx.end() || !oitr->is_open ) break; + auto bitr = _rexbalance.find( oitr->owner.value ); // bitr != _rexbalance.end() + auto result = close_rex_order( bitr, oitr->rex_requested ); + auto next = oitr; + ++next; + if( result.success ) { + idx.modify( oitr, same_payer, [&]( auto& rt ) { + rt.proceeds.amount = result.proceeds.amount; + rt.unstake_quant.amount = result.unstake_quant.amount; + rt.close(); + }); + } + oitr = next; + } + } + /// process cpu loans { rex_cpu_loan_table cpu_loans( _self, _self.value ); @@ -365,35 +407,14 @@ namespace eosiosystem { } } - /// process sellrex orders - { - rex_order_table rex_orders( _self, _self.value ); - auto idx = rex_orders.get_index<"bytime"_n>(); - auto oitr = idx.begin(); - for( uint16_t i = 0; i < max; ++i ) { - if( oitr == idx.end() || !oitr->is_open ) break; - auto bitr = _rexbalance.find( oitr->owner.value ); // bitr != _rexbalance.end() - auto result = close_rex_order( bitr, oitr->rex_requested ); - auto next = oitr; - ++next; - if( result.success ) { - idx.modify( oitr, same_payer, [&]( auto& rt ) { - rt.proceeds.amount = result.proceeds.amount; - rt.unstake_quant.amount = result.unstake_quant.amount; - rt.close(); - }); - } - oitr = next; - } - } - } template - int64_t system_contract::rentrex( T& table, name from, name receiver, const asset& payment, const asset& fund ) { + int64_t system_contract::rent_rex( T& table, name from, name receiver, const asset& payment, const asset& fund ) { runrex(2); + eosio_assert( _rexorders.begin() == _rexorders.end(), "rex loans are not currently available" ); eosio_assert( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); @@ -466,7 +487,7 @@ namespace eosiosystem { } template - void system_contract::fundrexloan( T& table, name from, uint64_t loan_num, const asset& payment ) { + void system_contract::fund_rex_loan( T& table, name from, uint64_t loan_num, const asset& payment ) { eosio_assert( payment.symbol == core_symbol(), "must use core token" ); transfer_from_fund( from, payment ); auto itr = table.require_find( loan_num, "loan not found" ); @@ -477,6 +498,19 @@ namespace eosiosystem { }); } + template + void system_contract::defund_rex_loan( T& table, name from, uint64_t loan_num, const asset& amount ) { + eosio_assert( amount.symbol == core_symbol(), "must use core token" ); + auto itr = table.require_find( loan_num, "loan not found" ); + eosio_assert( itr->from == from, "actor has to be loan creator" ); + eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); + eosio_assert( itr->balance >= amount, "insufficent loan balane" ); + table.modify( itr, same_payer, [&]( auto& loan ) { + loan.balance.amount -= amount.amount; + }); + transfer_to_fund( from, amount ); + } + void system_contract::transfer_from_fund( name owner, const asset& amount ) { auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); eosio_assert( amount <= itr->balance, "insufficient funds"); @@ -493,12 +527,11 @@ namespace eosiosystem { } void system_contract::update_rex_account( name owner, asset proceeds, asset delta_stake ) { - rex_order_table rex_orders( _self, _self.value ); - auto itr = rex_orders.find( owner.value ); - if( itr != rex_orders.end() && !itr->is_open ) { + auto itr = _rexorders.find( owner.value ); + if( itr != _rexorders.end() && !itr->is_open ) { proceeds.amount += itr->proceeds.amount; delta_stake.amount -= itr->unstake_quant.amount; - rex_orders.erase( itr ); + _rexorders.erase( itr ); } if( proceeds.amount > 0 ) transfer_to_fund( owner, proceeds ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 556ac3ac..0e6f4385 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -312,6 +312,20 @@ class eosio_system_tester : public TESTER { return unstake( acnt, acnt, net, cpu ); } + action_result deposit( const account_name& owner, const asset& amount ) { + return push_action( name(owner), N(deposit), mvo() + ("owner", owner) + ("amount", amount) + ); + } + + action_result withdraw( const account_name& owner, const asset& amount ) { + return push_action( name(owner), N(withdraw), mvo() + ("owner", owner) + ("amount", amount) + ); + } + action_result buyrex( const account_name& from, const asset& amount ) { return push_action( name(from), N(buyrex), mvo() ("from", from) @@ -330,10 +344,6 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(cnclrexorder), mvo()("owner", owner) ); } - action_result claimrex( const account_name& owner ) { - return push_action( name(owner), N(claimrex), mvo()("owner", owner) ); - } - action_result rentcpu( const account_name& from, const account_name& receiver, const asset& payment, bool auto_renew = false ) { return push_action( name(from), N(rentcpu), mvo() ("from", from) @@ -368,8 +378,21 @@ class eosio_system_tester : public TESTER { ); } - action_result claimrefund( const account_name& owner ) { - return push_action( name(owner), N(claimrefund), mvo()("owner", owner) ); + + action_result defundcpuloan( const account_name& from, const uint64_t loan_num, const asset& amount ) { + return push_action( name(from), N(defcpuloan), mvo() + ("from", from) + ("loan_num", loan_num) + ("amount", amount) + ); + } + + action_result defundnetloan( const account_name& from, const uint64_t loan_num, const asset& amount ) { + return push_action( name(from), N(defnetloan), mvo() + ("from", from) + ("loan_num", loan_num) + ("amount", amount) + ); } action_result updaterex( const account_name& owner ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index fd30b2b2..1f8fe041 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3591,10 +3591,12 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { // wait for 30 days minus 1 hour produce_block( fc::hours(29*24 + 23) ); + /* BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( alice ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( bob ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( carol ) ); - + */ + // wait for 2 more hours, by now frank's loan has expired and there is enough balance in // total_unlent to close some sellrex orders. only two are processed, bob's and carol's // alices's order is still open @@ -3606,8 +3608,8 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), - claimrex( alice ) ); + // BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), + // claimrex( alice ) ); BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); @@ -3617,17 +3619,17 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); - BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); + // BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); + // BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), - claimrex( alice ) ); + // BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), + // claimrex( alice ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_sym::from_string("100.0000")) ); - BOOST_REQUIRE_EQUAL( success(), claimrex( alice ) ); + // BOOST_REQUIRE_EQUAL( success(), claimrex( alice ) ); } FC_LOG_AND_RETHROW() @@ -3708,7 +3710,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { } BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); + // BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); loan_info = get_cpu_loan(1); BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); @@ -3730,13 +3732,13 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); BOOST_REQUIRE_EQUAL( init_stake, get_cpu_limit( bob ) ); - BOOST_REQUIRE_EQUAL( success(), claimrefund( frank ) ); + // BOOST_REQUIRE_EQUAL( success(), claimrefund( frank ) ); old_frank_balance = cur_frank_balance; cur_frank_balance = get_balance( frank ); BOOST_REQUIRE_EQUAL( fund - payment, cur_frank_balance - old_frank_balance ); BOOST_REQUIRE ( old_frank_balance < cur_frank_balance ); - BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); + // BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); } FC_LOG_AND_RETHROW() From a443db58c59265c0132109f2e94d07130d12582e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 15 Oct 2018 16:23:47 -0400 Subject: [PATCH 0605/1048] Fix REX unit tests --- .../include/eosio.system/eosio.system.hpp | 1 + eosio.system/src/rex.cpp | 49 +++++----- tests/eosio.system_tester.hpp | 33 ++++--- tests/eosio.system_tests.cpp | 91 +++++++++---------- 4 files changed, 90 insertions(+), 84 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 794dcc7b..a414790b 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -492,6 +492,7 @@ namespace eosiosystem { void defund_rex_loan( T& table, name from, uint64_t loan_num, const asset& amount ); void transfer_from_fund( name owner, const asset& amount ); void transfer_to_fund( name owner, const asset& amount ); + bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end(); } // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index e1316534..bb5dc9dd 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -273,8 +273,7 @@ namespace eosiosystem { require_auth( owner ); - auto itr = _rexbalance.find( owner.value ); - eosio_assert( itr != _rexbalance.end() && itr->rex_balance.amount > 0, "account has no REX balance" ); + auto itr = _rexbalance.require_find( owner.value, "account has no REX balance" ); const asset init_stake = itr->vote_stake; runrex(2); @@ -316,7 +315,7 @@ namespace eosiosystem { bool delete_loan = false; int64_t delta_stake = 0; - if( itr->payment <= itr->balance && _rexorders.begin() == _rexorders.end() ) { + if( itr->payment <= itr->balance && rex_loans_available() ) { int64_t rented_tokens = 0; _rextable.modify( rexi, same_payer, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, @@ -352,27 +351,6 @@ namespace eosiosystem { }); } - /// process sellrex orders - { - auto idx = _rexorders.get_index<"bytime"_n>(); - auto oitr = idx.begin(); - for( uint16_t i = 0; i < max; ++i ) { - if( oitr == idx.end() || !oitr->is_open ) break; - auto bitr = _rexbalance.find( oitr->owner.value ); // bitr != _rexbalance.end() - auto result = close_rex_order( bitr, oitr->rex_requested ); - auto next = oitr; - ++next; - if( result.success ) { - idx.modify( oitr, same_payer, [&]( auto& rt ) { - rt.proceeds.amount = result.proceeds.amount; - rt.unstake_quant.amount = result.unstake_quant.amount; - rt.close(); - }); - } - oitr = next; - } - } - /// process cpu loans { rex_cpu_loan_table cpu_loans( _self, _self.value ); @@ -407,6 +385,27 @@ namespace eosiosystem { } } + /// process sellrex orders + { + auto idx = _rexorders.get_index<"bytime"_n>(); + auto oitr = idx.begin(); + for( uint16_t i = 0; i < max; ++i ) { + if( oitr == idx.end() || !oitr->is_open ) break; + auto bitr = _rexbalance.find( oitr->owner.value ); // bitr != _rexbalance.end() + auto result = close_rex_order( bitr, oitr->rex_requested ); + auto next = oitr; + ++next; + if( result.success ) { + idx.modify( oitr, same_payer, [&]( auto& rt ) { + rt.proceeds.amount = result.proceeds.amount; + rt.unstake_quant.amount = result.unstake_quant.amount; + rt.close(); + }); + } + oitr = next; + } + } + } template @@ -414,7 +413,7 @@ namespace eosiosystem { runrex(2); - eosio_assert( _rexorders.begin() == _rexorders.end(), "rex loans are not currently available" ); + eosio_assert( rex_loans_available(), "rex loans are not currently available" ); eosio_assert( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 0e6f4385..91a09699 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -344,21 +344,21 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(cnclrexorder), mvo()("owner", owner) ); } - action_result rentcpu( const account_name& from, const account_name& receiver, const asset& payment, bool auto_renew = false ) { + action_result rentcpu( const account_name& from, const account_name& receiver, const asset& payment, const asset& fund = core_sym::from_string("0.0000") ) { return push_action( name(from), N(rentcpu), mvo() - ("from", from) - ("receiver", receiver) - ("payment", payment) - ("auto_renew", auto_renew) + ("from", from) + ("receiver", receiver) + ("loan_payment", payment) + ("loan_fund", fund) ); } - action_result rentnet( const account_name& from, const account_name& receiver, const asset& payment, bool auto_renew = false ) { + action_result rentnet( const account_name& from, const account_name& receiver, const asset& payment, const asset& fund = core_sym::from_string("0.0000") ) { return push_action( name(from), N(rentnet), mvo() - ("from", from) - ("receiver", receiver) - ("payment", payment) - ("auto_renew", auto_renew) + ("from", from) + ("receiver", receiver) + ("loan_payment", payment) + ("loan_fund", fund) ); } @@ -452,6 +452,11 @@ class eosio_system_tester : public TESTER { return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); } + asset get_rex_fund( const account_name& act ) const { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); + return data.empty() ? asset(0, symbol{CORE_SYM}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer_max_time)["balance"].as(); + } + asset get_rex_vote_stake( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); return data.empty() ? core_sym::from_string("0.0000") : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["vote_stake"].as(); @@ -486,7 +491,8 @@ class eosio_system_tester : public TESTER { void setup_rex_accounts( const std::vector& accounts, const asset& init_balance, const asset& net = core_sym::from_string("80.0000"), - const asset& cpu = core_sym::from_string("80.0000") ) { + const asset& cpu = core_sym::from_string("80.0000"), + bool deposit_into_rex = true ) { const asset nstake = core_sym::from_string("10.0000"); const asset cstake = core_sym::from_string("10.0000"); create_account_with_resources( N(proxyaccount), config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); @@ -498,6 +504,11 @@ class eosio_system_tester : public TESTER { BOOST_REQUIRE_EQUAL( success(), vote( a, { }, N(proxyaccount) ) ); BOOST_REQUIRE_EQUAL( init_balance, get_balance(a) ); BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); + if (deposit_into_rex) { + BOOST_REQUIRE_EQUAL( success(), deposit( a, init_balance ) ); + BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( a ) ); + BOOST_REQUIRE_EQUAL( 0, get_balance( a ).get_amount() ); + } } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 1f8fe041..1e60da5e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3396,9 +3396,9 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_balance(alice) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_rex_fund(alice) ); BOOST_REQUIRE_EQUAL( ratio * asset::from_string("30.0000 REX").get_amount(), get_rex_balance(alice).get_amount() ); auto rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_lendable"].as() ); @@ -3408,7 +3408,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( get_rex_balance(alice), rex_pool["total_rex"].as() ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("75.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("925.0000"), get_balance(bob) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("925.0000"), get_rex_fund(bob) ); BOOST_REQUIRE_EQUAL( ratio * asset::from_string("75.0000 REX").get_amount(), get_rex_balance(bob).get_amount() ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( core_sym::from_string("105.0000"), rex_pool["total_lendable"].as() ); @@ -3467,7 +3467,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_sym::from_string("5.0000") ) ); // alice lends rex BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("65.0000") ) ); - BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("65.0000"), get_balance(alice) ); + BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("65.0000"), get_rex_fund(alice) ); auto rex_pool = get_rex_pool(); const asset init_tot_unlent = rex_pool["total_unlent"].as(); const asset init_tot_lendable = rex_pool["total_lendable"].as(); @@ -3481,7 +3481,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { // bob rents cpu for carol const asset fee = core_sym::from_string("17.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); - BOOST_REQUIRE_EQUAL( init_balance - fee, get_balance(bob) ); + BOOST_REQUIRE_EQUAL( init_balance - fee, get_rex_fund(bob) ); rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 17 BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 @@ -3508,7 +3508,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { // alice is finally able to sellrex, she gains the fee paid by bob BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( init_balance + fee, get_balance(alice) ); + BOOST_REQUIRE_EQUAL( init_balance + fee, get_rex_fund(alice) ); // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); @@ -3553,10 +3553,10 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); BOOST_REQUIRE_EQUAL( success(), buyrex( carol, purchase3) ); - BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_balance(alice) ); + BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_rex_fund(alice) ); BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); - BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_balance(bob) ); - BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_balance(carol) ); + BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_rex_fund(bob) ); + BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_rex_fund(carol) ); auto init_alice_rex = get_rex_balance(alice); auto init_bob_rex = get_rex_balance(bob); @@ -3588,49 +3588,44 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); + // wait for 30 days minus 1 hour produce_block( fc::hours(29*24 + 23) ); - - /* - BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( alice ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( bob ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), claimrex( carol ) ); - */ + BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("0.0001") ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); // wait for 2 more hours, by now frank's loan has expired and there is enough balance in // total_unlent to close some sellrex orders. only two are processed, bob's and carol's // alices's order is still open // an action is needed to trigger queue processing produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds for current and scheduled orders"), - sellrex( alice, init_alice_rex ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are not currently available"), + rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); + + BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("0.0001") ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - // BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), - // claimrex( alice ) ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( purchase2.get_amount(), get_rex_order(bob)["unstake_quant"].as().get_amount() ); - + BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); - // BOOST_REQUIRE_EQUAL( success(), claimrex( bob ) ); - // BOOST_REQUIRE_EQUAL( success(), claimrex( carol ) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); + BOOST_REQUIRE_EQUAL( success(), updaterex( carol ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( carol ).get_amount() ); BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); - // BOOST_REQUIRE_EQUAL( wasm_assert_msg("sellrex order has not been closed"), - // claimrex( alice ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_sym::from_string("100.0000")) ); - // BOOST_REQUIRE_EQUAL( success(), claimrex( alice ) ); - } FC_LOG_AND_RETHROW() @@ -3652,34 +3647,34 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { const asset init_balance = core_sym::from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); + setup_rex_accounts( accounts, init_balance ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("500.0000") ) ); auto rex_pool = get_rex_pool(); const asset payment = core_sym::from_string("30.0000"); - asset cur_frank_balance = get_balance( frank ); + asset cur_frank_balance = get_rex_fund( frank ); int64_t expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount(), rex_pool["total_unlent"].as().get_amount(), payment.get_amount() ); const int64_t init_stake = get_cpu_limit( frank ); // frank rents cpu for bob - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, payment, true ) ); // loan_num = 1 - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment, false ) ); // loan_num = 2 + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, payment ) ); // loan_num = 1 + BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment ) ); // loan_num = 2 BOOST_REQUIRE_EQUAL( 2, get_last_cpu_loan()["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, emily, payment, false ) ); // loan_num = 3 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, alice, payment, false ) ); // loan_num = 4 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, frank, payment, false ) ); // loan_num = 5 + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, emily, payment ) ); // loan_num = 3 + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, alice, payment ) ); // loan_num = 4 + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, frank, payment ) ); // loan_num = 5 BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); auto loan_info = get_cpu_loan(1); auto old_frank_balance = cur_frank_balance; - cur_frank_balance = get_balance( frank ); + cur_frank_balance = get_rex_fund( frank ); BOOST_REQUIRE_EQUAL( old_frank_balance, payment + cur_frank_balance ); BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); BOOST_REQUIRE_EQUAL( 0, loan_info["balance"].as().get_amount() ); BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); @@ -3690,11 +3685,11 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( fundcpuloan( alice, 1, fund ), wasm_assert_msg("actor has to be loan creator") ); BOOST_REQUIRE_EQUAL( success(), fundcpuloan( frank, 1, fund ) ); old_frank_balance = cur_frank_balance; - cur_frank_balance = get_balance( frank ); + cur_frank_balance = get_rex_fund( frank ); loan_info = get_cpu_loan(1); BOOST_REQUIRE_EQUAL( old_frank_balance, fund + cur_frank_balance ); BOOST_REQUIRE_EQUAL( fund, loan_info["balance"].as() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); // wait for 30 days, frank's loan will be renewed at the current price produce_block( fc::hours(30*24 + 1) ); @@ -3710,10 +3705,9 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { } BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); - // BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); loan_info = get_cpu_loan(1); - BOOST_REQUIRE_EQUAL( payment, loan_info["loan_payment"].as() ); + BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); BOOST_REQUIRE_EQUAL( fund - payment, loan_info["balance"].as() ); BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); @@ -3732,14 +3726,11 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("10.0000") ) ); BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); BOOST_REQUIRE_EQUAL( init_stake, get_cpu_limit( bob ) ); - // BOOST_REQUIRE_EQUAL( success(), claimrefund( frank ) ); old_frank_balance = cur_frank_balance; - cur_frank_balance = get_balance( frank ); + cur_frank_balance = get_rex_fund( frank ); BOOST_REQUIRE_EQUAL( fund - payment, cur_frank_balance - old_frank_balance ); BOOST_REQUIRE ( old_frank_balance < cur_frank_balance ); - // BOOST_REQUIRE_EQUAL( claimrefund( frank ), wasm_assert_msg("no refund to be claimed") ); - } FC_LOG_AND_RETHROW() @@ -3749,11 +3740,14 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { const asset init_balance = core_sym::from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); + setup_rex_accounts( accounts, init_balance, core_sym::from_string("80.0000"), core_sym::from_string("80.0000"), false ); asset cur_ramfee_balance = get_balance( N(eosio.ramfee) ); BOOST_REQUIRE_EQUAL( success(), buyram( alice, alice, core_sym::from_string("20.0000") ) ); BOOST_REQUIRE_EQUAL( get_balance( N(eosio.ramfee) ), core_sym::from_string("0.1000") + cur_ramfee_balance ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit to REX fund first"), + buyrex( alice, core_sym::from_string("350.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), deposit( alice, core_sym::from_string("350.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("350.0000") ) ); cur_ramfee_balance = get_balance( N(eosio.ramfee) ); asset cur_rex_balance = get_balance( N(eosio.rex) ); @@ -3784,6 +3778,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { produce_blocks( 2 ); BOOST_REQUIRE_EQUAL( core_sym::from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); + BOOST_REQUIRE_EQUAL( success(), deposit( frank, core_sym::from_string("5.0000") ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("5.0000") ) ); BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("34.3500") ); BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); @@ -3811,7 +3806,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("250.0000"), get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, core_sym::from_string("50.0000"), false ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, core_sym::from_string("50.0000") ) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); From 0782bb49c93521e19ad1af78b4dabaae61998645 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 15 Oct 2018 19:06:09 -0400 Subject: [PATCH 0606/1048] REX voting tests --- tests/eosio.system_tests.cpp | 47 +++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 1e60da5e..7ce01760 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3659,7 +3659,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { payment.get_amount() ); const int64_t init_stake = get_cpu_limit( frank ); - // frank rents cpu for bob + // create 2 cpu and 3 net loans BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, payment ) ); // loan_num = 1 BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment ) ); // loan_num = 2 BOOST_REQUIRE_EQUAL( 2, get_last_cpu_loan()["loan_num"].as_uint64() ); @@ -3790,9 +3790,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester ) try { - - auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; +BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { const int64_t ratio = 10000; const asset init_balance = core_sym::from_string("10000.0000"); @@ -3811,6 +3809,47 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'z'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + + setup_producer_accounts(producer_names); + for ( const auto& p: producer_names ) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); + } + } + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX must vote for a proxy or at least 21 producers"), + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); + BOOST_REQUIRE_EQUAL( success(), + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + + BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) + == get_producer_info(producer_names[0])["total_votes"].as() ); + BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) + == get_producer_info(producer_names[20])["total_votes"].as() ); + + const asset init_rex = get_rex_balance( alice ); + const asset init_rex_stake = get_rex_vote_stake( alice ); + const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); + BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); + BOOST_REQUIRE_EQUAL( 3 * init_rex_stake.get_amount(), 4 * get_rex_vote_stake( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); + BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) + == get_producer_info(producer_names[0])["total_votes"].as() ); + + produce_block( fc::days(31) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); + } FC_LOG_AND_RETHROW() From c9f111d1c17a237dc555ba3cdfa9ac39e38d4c0c Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 16 Oct 2018 16:20:07 -0400 Subject: [PATCH 0607/1048] assert in init --- eosio.system/src/eosio.system.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 500fe0b4..eb99a208 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -291,16 +291,15 @@ namespace eosiosystem { auto system_token_supply = eosio::token::get_supply(token_account, core.code() ); eosio_assert( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); - if( system_token_supply.amount > 0 ) { - _rammarket.emplace( _self, [&]( auto& m ) { - m.supply.amount = 100000000000000ll; - m.supply.symbol = ramcore_symbol; - m.base.balance.amount = int64_t(_gstate.free_ram()); - m.base.balance.symbol = ram_symbol; - m.quote.balance.amount = system_token_supply.amount / 1000; - m.quote.balance.symbol = core; - }); - } + eosio_assert( system_token_supply.amount > 0, "system token supply must be greater than 0" ); + _rammarket.emplace( _self, [&]( auto& m ) { + m.supply.amount = 100000000000000ll; + m.supply.symbol = ramcore_symbol; + m.base.balance.amount = int64_t(_gstate.free_ram()); + m.base.balance.symbol = ram_symbol; + m.quote.balance.amount = system_token_supply.amount / 1000; + m.quote.balance.symbol = core; + }); } } /// eosio.system From 420eff453b2582cd01db72900439c4cc9e83c286 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 16 Oct 2018 17:35:58 -0400 Subject: [PATCH 0608/1048] REX funds testing --- .../include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/rex.cpp | 6 +-- tests/eosio.system_tests.cpp | 54 ++++++++++++++++++- 3 files changed, 57 insertions(+), 5 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index a414790b..6f20f378 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -372,7 +372,7 @@ namespace eosiosystem { void updaterex( name owner ); [[eosio::action]] - void rexexec( uint16_t max ); + void rexexec( name user, uint16_t max ); /** * Decreases the total tokens delegated by from to receiver and/or diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index bb5dc9dd..ff734696 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -292,9 +292,9 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), delta_stake ); } - void system_contract::rexexec( uint16_t max ) { + void system_contract::rexexec( name user, uint16_t max ) { - require_auth( _self ); + require_auth( user ); runrex( max ); } @@ -503,7 +503,7 @@ namespace eosiosystem { auto itr = table.require_find( loan_num, "loan not found" ); eosio_assert( itr->from == from, "actor has to be loan creator" ); eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); - eosio_assert( itr->balance >= amount, "insufficent loan balane" ); + eosio_assert( itr->balance >= amount, "insufficent loan balance" ); table.modify( itr, same_payer, [&]( auto& loan ) { loan.balance.amount -= amount.amount; }); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7ce01760..ccd2db34 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3691,6 +3691,26 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( fund, loan_info["balance"].as() ); BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); + // in the meantime, defund then fund the same amount and test the balances + { + const asset amount = core_sym::from_string("7.5000"); + BOOST_REQUIRE_EQUAL( defundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); + BOOST_REQUIRE_EQUAL( defundcpuloan( alice, 1, fund ), wasm_assert_msg("actor has to be loan creator") ); + BOOST_REQUIRE_EQUAL( defundcpuloan( frank, 1, core_sym::from_string("75.0000") ), wasm_assert_msg("insufficent loan balance") ); + old_frank_balance = cur_frank_balance; + asset old_loan_balance = get_cpu_loan(1)["balance"].as(); + BOOST_REQUIRE_EQUAL( defundcpuloan( frank, 1, amount ), success() ); + BOOST_REQUIRE_EQUAL( old_loan_balance, get_cpu_loan(1)["balance"].as() + amount ); + cur_frank_balance = get_rex_fund( frank ); + old_loan_balance = get_cpu_loan(1)["balance"].as(); + BOOST_REQUIRE_EQUAL( old_frank_balance + amount, cur_frank_balance ); + old_frank_balance = cur_frank_balance; + BOOST_REQUIRE_EQUAL( fundcpuloan( frank, 1, amount ), success() ); + BOOST_REQUIRE_EQUAL( old_loan_balance + amount, get_cpu_loan(1)["balance"].as() ); + cur_frank_balance = get_rex_fund( frank ); + BOOST_REQUIRE_EQUAL( old_frank_balance - amount, cur_frank_balance ); + } + // wait for 30 days, frank's loan will be renewed at the current price produce_block( fc::hours(30*24 + 1) ); rex_pool = get_rex_pool(); @@ -3704,7 +3724,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { payment.get_amount() ); } - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); loan_info = get_cpu_loan(1); BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); @@ -3853,6 +3873,38 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { + + const asset init_balance = core_sym::from_string("1000.0000"); + const asset init_net = core_sym::from_string("70.0000"); + const asset init_cpu = core_sym::from_string("90.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); + + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_rex_fund( alice ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("account has no REX funds"), withdraw( alice, core_sym::from_string("0.0001") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), deposit( alice, init_balance + init_balance ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit core token"), deposit( alice, asset::from_string("1.0000 RNDM") ) ); + + asset deposit_quant( init_balance.get_amount() / 5, init_balance.get_symbol() ); + BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); + BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant ); + BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant ); + BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); + BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant + deposit_quant ); + BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant - deposit_quant ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), withdraw( alice, get_rex_fund( alice ) + core_sym::from_string("0.0001")) ); + BOOST_REQUIRE_EQUAL( success(), withdraw( alice, deposit_quant ) ); + BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant ); + BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant ); + BOOST_REQUIRE_EQUAL( success(), withdraw( alice, get_rex_fund( alice ) ) ); + BOOST_REQUIRE_EQUAL( get_rex_fund( alice ).get_amount(), 0 ); + BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); set_code( config::system_account_name, contracts::bios_wasm() ); From 6abd3631de5cf6b627d98a04dae7fbbd8df06a2d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 17 Oct 2018 16:47:58 -0400 Subject: [PATCH 0609/1048] Change REX vote stake update --- .../include/eosio.system/eosio.system.hpp | 11 +-- eosio.system/src/delegate_bandwidth.cpp | 4 +- eosio.system/src/rex.cpp | 69 +++++++++++-------- tests/eosio.system_tests.cpp | 39 ++++++----- 4 files changed, 67 insertions(+), 56 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 6f20f378..34b4cfa4 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -236,7 +236,6 @@ namespace eosiosystem { name owner; asset rex_requested; asset proceeds; - asset unstake_quant; eosio::time_point order_time; bool is_open = true; @@ -248,12 +247,6 @@ namespace eosiosystem { typedef eosio::multi_index< "rexqueue"_n, rex_order, indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; - struct rex_order_output { - bool success; - asset proceeds; - asset unstake_quant; - }; - class [[eosio::contract("eosio.system")]] system_contract : public native { private: @@ -481,7 +474,7 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); - rex_order_output close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + std::pair close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); void update_rex_account( name owner, asset proceeds, asset unstake_quant ); void deposit_rex( const name& from, const asset& amount ); template @@ -498,7 +491,7 @@ namespace eosiosystem { void changebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); void update_resource_limits( name receiver, int64_t delta_cpu, int64_t delta_net ); - void update_voting_power( const name& voter, const asset& total_update ); + void update_voting_power( const name& voter, const asset& total_update, bool update_votes_flag = true ); // defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 420e0da3..610399f7 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -385,7 +385,7 @@ namespace eosiosystem { update_voting_power( from, stake_net_delta + stake_cpu_delta ); } - void system_contract::update_voting_power( const name& voter, const asset& total_update ) + void system_contract::update_voting_power( const name& voter, const asset& total_update, bool update_votes_flag ) { auto voter_itr = _voters.find( voter.value ); if( voter_itr == _voters.end() ) { @@ -405,7 +405,7 @@ namespace eosiosystem { validate_b1_vesting( voter_itr->staked ); } - if( voter_itr->producers.size() || voter_itr->proxy ) { + if( update_votes_flag && ( voter_itr->producers.size() || voter_itr->proxy ) ) { update_votes( voter, voter_itr->proxy, voter_itr->producers, false ); } } diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index ff734696..7e4824aa 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -13,7 +13,7 @@ namespace eosiosystem { eosio_assert( amount.symbol == core_symbol(), "must deposit core token" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { owner, active_permission }, - { owner, rex_account, amount, "deposit into REX fund" } ); + { owner, rex_account, amount, "deposit to REX fund" } ); auto itr = _rexfunds.find( owner.value ); if( itr == _rexfunds.end() ) { _rexfunds.emplace( owner, [&]( auto& fund ) { @@ -54,7 +54,7 @@ namespace eosiosystem { require_auth( from ); - eosio_assert( amount.symbol == core_symbol(), "asset must be system token" ); + eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); const int64_t rex_ratio = 10000; const int64_t init_rent = 1000000; @@ -70,6 +70,7 @@ namespace eosiosystem { auto itr = _rextable.begin(); if( itr == _rextable.end() ) { + /// eosio.token open action for eosio.rex account _rextable.emplace( _self, [&]( auto& rp ){ rex_received.amount = amount.amount * rex_ratio; @@ -107,22 +108,27 @@ namespace eosiosystem { } auto bitr = _rexbalance.find( from.value ); + asset init_rex_stake( 0, core_symbol() ); + asset current_rex_stake( 0, core_symbol() ); if( bitr == _rexbalance.end() ) { _rexbalance.emplace( from, [&]( auto& rb ) { rb.owner = from; rb.vote_stake = amount; rb.rex_balance = rex_received; }); + current_rex_stake.amount = amount.amount; } else { + init_rex_stake.amount = bitr->vote_stake.amount; _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount += amount.amount; rb.rex_balance.amount += rex_received.amount; + rb.vote_stake.amount = ( uint128_t(rb.rex_balance.amount) * itr->total_lendable.amount ) / itr->total_rex.amount; }); + current_rex_stake.amount = bitr->vote_stake.amount; } runrex(2); - update_rex_account( from, asset( 0, core_symbol() ), amount ); + update_rex_account( from, asset( 0, core_symbol() ), current_rex_stake - init_rex_stake ); } /** @@ -142,26 +148,25 @@ namespace eosiosystem { eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); auto current_order = close_rex_order( bitr, rex ); - update_rex_account( from, current_order.proceeds, -current_order.unstake_quant ); - if( !current_order.success ) { + update_rex_account( from, current_order.second, -current_order.second ); + if( !current_order.first ) { /** * REX order couldn't be filled and is added to queue. * If account already has an open order, requested rex is added to existing order. */ auto oitr = _rexorders.find( from.value ); if( oitr == _rexorders.end() ) { - _rexorders.emplace( from, [&]( auto& ordr ) { - ordr.owner = from; - ordr.rex_requested = rex; - ordr.is_open = true; - ordr.proceeds = asset( 0, core_symbol() ); - ordr.unstake_quant = asset( 0, core_symbol() ); - ordr.order_time = current_time_point(); + _rexorders.emplace( from, [&]( auto& order ) { + order.owner = from; + order.rex_requested = rex; + order.is_open = true; + order.proceeds = asset( 0, core_symbol() ); + order.order_time = current_time_point(); }); } else { - _rexorders.modify( oitr, same_payer, [&]( auto& ordr ) { - ordr.rex_requested.amount += rex.amount; - eosio_assert( bitr->rex_balance >= ordr.rex_requested, "insufficient funds for current and scheduled orders"); + _rexorders.modify( oitr, same_payer, [&]( auto& order ) { + order.rex_requested.amount += rex.amount; + eosio_assert( bitr->rex_balance >= order.rex_requested, "insufficient funds for current and scheduled orders"); }); } } @@ -303,6 +308,7 @@ namespace eosiosystem { * Perform maitenance operations on expired rex */ void system_contract::runrex( uint16_t max ) { + auto rexi = _rextable.begin(); eosio_assert( rexi != _rextable.end(), "rex system not initialized yet" ); @@ -395,11 +401,10 @@ namespace eosiosystem { auto result = close_rex_order( bitr, oitr->rex_requested ); auto next = oitr; ++next; - if( result.success ) { - idx.modify( oitr, same_payer, [&]( auto& rt ) { - rt.proceeds.amount = result.proceeds.amount; - rt.unstake_quant.amount = result.unstake_quant.amount; - rt.close(); + if( result.first ) { + idx.modify( oitr, same_payer, [&]( auto& order ) { + order.proceeds.amount = result.second.amount; + order.close(); }); } oitr = next; @@ -444,15 +449,22 @@ namespace eosiosystem { return rented_tokens; } - rex_order_output system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; asset proceeds( S0 - S1, core_symbol() ); - asset unstake_quant( ( uint128_t(rex.amount) * bitr->vote_stake.amount ) / bitr->rex_balance.amount, - core_symbol() ); + + /// update vote_stake to its current value whether sell order is processed or not + /// that is, value right before sell order is processed + int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; + update_voting_power( bitr->owner, asset( current_stake_value - bitr->vote_stake.amount, core_symbol() ), false ); + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + rb.vote_stake.amount = current_stake_value; + }); + bool success = false; if( proceeds.amount <= rexitr->total_unlent.amount ) { _rextable.modify( rexitr, same_payer, [&]( auto& rt ) { @@ -461,15 +473,14 @@ namespace eosiosystem { rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; }); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount -= unstake_quant.amount; + rb.vote_stake.amount -= proceeds.amount; rb.rex_balance.amount -= rex.amount; }); success = true; } else { - proceeds.amount = 0; - unstake_quant.amount = 0; + proceeds.amount = 0; } - return { success, proceeds, unstake_quant }; + return { success, proceeds }; } void system_contract::deposit_rex( const name& from, const asset& amount ) { @@ -529,7 +540,7 @@ namespace eosiosystem { auto itr = _rexorders.find( owner.value ); if( itr != _rexorders.end() && !itr->is_open ) { proceeds.amount += itr->proceeds.amount; - delta_stake.amount -= itr->unstake_quant.amount; + delta_stake.amount -= itr->proceeds.amount; _rexorders.erase( itr ); } if( proceeds.amount > 0 ) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index ccd2db34..119bf525 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3397,9 +3397,12 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_rex_fund(alice) ); - BOOST_REQUIRE_EQUAL( ratio * asset::from_string("30.0000 REX").get_amount(), get_rex_balance(alice).get_amount() ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("13.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("13.0000"), get_rex_vote_stake( alice ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("17.0000") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), get_rex_vote_stake( alice ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_rex_fund(alice) ); + BOOST_REQUIRE_EQUAL( get_rex_balance(alice).get_amount(), ratio * asset::from_string("30.0000 REX").get_amount() ); auto rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_unlent"].as() ); @@ -3563,11 +3566,14 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto init_carol_rex = get_rex_balance(carol); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_sym::from_string("1100.0000") ) ); + const auto init_rex_pool = get_rex_pool(); + const int64_t init_alice_rex_stake = ( init_alice_rex.get_amount() * init_rex_pool["total_lendable"].as().get_amount() ) + / init_rex_pool["total_rex"].as().get_amount(); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); BOOST_REQUIRE_EQUAL( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_rex_vote_stake( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( purchase1.get_amount() / 4, get_voter_info(alice)["staked"].as() - init_stake ); + BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ); init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); @@ -3604,16 +3610,15 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are not currently available"), rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("0.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( purchase2.get_amount(), get_rex_order(bob)["unstake_quant"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); @@ -3855,12 +3860,14 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); - const asset init_rex = get_rex_balance( alice ); - const asset init_rex_stake = get_rex_vote_stake( alice ); + const asset init_rex = get_rex_balance( alice ); + const auto current_rex_pool = get_rex_pool(); + const int64_t init_alice_rex_stake = ( init_rex.get_amount() * current_rex_pool["total_lendable"].as().get_amount() ) + / current_rex_pool["total_rex"].as().get_amount(); const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); - BOOST_REQUIRE_EQUAL( 3 * init_rex_stake.get_amount(), 4 * get_rex_vote_stake( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ); BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); From fe4187ae9938dbb51a859ade72b3e847235abeef Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 18 Oct 2018 11:06:08 -0400 Subject: [PATCH 0610/1048] Call token open action for eosio.rex in system init --- .../include/eosio.system/eosio.system.hpp | 40 +++++++------- eosio.system/src/eosio.system.cpp | 4 ++ eosio.system/src/rex.cpp | 54 ++++++++++--------- 3 files changed, 52 insertions(+), 46 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 34b4cfa4..14660c08 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -310,29 +310,29 @@ namespace eosiosystem { [[eosio::action]] - void deposit( name owner, asset amount ); + void deposit( const name& owner, const asset& amount ); [[eosio::action]] - void withdraw( name owner, asset amount ); + void withdraw( const name& owner, const asset& amount ); /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ [[eosio::action]] - void buyrex( name from, asset amount ); + void buyrex( const name& from, const asset& amount ); /** * Converts REX stake back into SYS tokens at current exchange rate. If order cannot be * processed, it gets queued until it can be there is enough REX to fill order. */ [[eosio::action]] - void sellrex( name from, asset rex ); + void sellrex( const name& from, const asset& rex ); /** * Cancels queued sellrex order. */ [[eosio::action]] - void cnclrexorder( name owner ); + void cnclrexorder( const name& owner ); /** * Use payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, @@ -342,30 +342,30 @@ namespace eosiosystem { * creator. User claims the refund in a separate action. */ [[eosio::action]] - void rentcpu( name from, name receiver, asset loan_payment, asset loan_fund ); + void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); [[eosio::action]] - void rentnet( name from, name receiver, asset loan_payment, asset loan_fund ); + void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** * Loan initiator funds a given CPU or NET loan. Loan must've been set as autorenew. */ [[eosio::action]] - void fundcpuloan( name from, uint64_t loan_num, asset payment ); + void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); [[eosio::action]] - void fundnetloan( name from, uint64_t loan_num, asset payment ); + void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); [[eosio::action]] - void defcpuloan( name from, uint64_t loan_num, asset amount ); + void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); [[eosio::action]] - void defnetloan( name from, uint64_t loan_num, asset amount ); + void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); /** * Updates REX vote stake of owner to its current value. */ [[eosio::action]] - void updaterex( name owner ); + void updaterex( const name& owner ); [[eosio::action]] - void rexexec( name user, uint16_t max ); + void rexexec( const name& user, uint16_t max ); /** * Decreases the total tokens delegated by from to receiver and/or @@ -474,23 +474,23 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); + void update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ); std::pair close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); - void update_rex_account( name owner, asset proceeds, asset unstake_quant ); + void update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant ); void deposit_rex( const name& from, const asset& amount ); template - int64_t rent_rex( T& table, name from, name receiver, const asset& loan_payment, const asset& loan_fund ); + int64_t rent_rex( T& table, const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); template - void fund_rex_loan( T& table, name from, uint64_t loan_num, const asset& payment ); + void fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ); template - void defund_rex_loan( T& table, name from, uint64_t loan_num, const asset& amount ); - void transfer_from_fund( name owner, const asset& amount ); - void transfer_to_fund( name owner, const asset& amount ); + void defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ); + void transfer_from_fund( const name& owner, const asset& amount ); + void transfer_to_fund( const name& owner, const asset& amount ); bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end(); } // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); - void update_resource_limits( name receiver, int64_t delta_cpu, int64_t delta_net ); void update_voting_power( const name& voter, const asset& total_update, bool update_votes_flag = true ); // defined in voting.hpp diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index d6939361..f34fa0a5 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -304,6 +304,10 @@ namespace eosiosystem { m.quote.balance.symbol = core; }); } + + INLINE_ACTION_SENDER(eosio::token, open)( token_account, { _self, active_permission }, + { rex_account, core, _self } ); + } } /// eosio.system diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 7e4824aa..3a7da7bc 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -6,7 +6,7 @@ namespace eosiosystem { - void system_contract::deposit( name owner, asset amount ) { + void system_contract::deposit( const name& owner, const asset& amount ) { require_auth( owner ); @@ -29,7 +29,7 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } - void system_contract::withdraw( name owner, asset amount ) { + void system_contract::withdraw( const name& owner, const asset& amount ) { require_auth( owner ); @@ -50,7 +50,7 @@ namespace eosiosystem { /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ - void system_contract::buyrex( name from, asset amount ) { + void system_contract::buyrex( const name& from, const asset& amount ) { require_auth( from ); @@ -70,8 +70,8 @@ namespace eosiosystem { auto itr = _rextable.begin(); if( itr == _rextable.end() ) { - /// eosio.token open action for eosio.rex account - _rextable.emplace( _self, [&]( auto& rp ){ + /// initialize REX pool + _rextable.emplace( _self, [&]( auto& rp ) { rex_received.amount = amount.amount * rex_ratio; rp.total_lendable = amount; @@ -134,7 +134,7 @@ namespace eosiosystem { /** * Converts REX stake back into SYS tokens at current exchange rate */ - void system_contract::sellrex( name from, asset rex ) { + void system_contract::sellrex( const name& from, const asset& rex ) { runrex(2); @@ -172,7 +172,7 @@ namespace eosiosystem { } } - void system_contract::cnclrexorder( name owner ) { + void system_contract::cnclrexorder( const name& owner ) { require_auth( owner ); @@ -204,7 +204,7 @@ namespace eosiosystem { return out; } - void system_contract::update_resource_limits( name receiver, int64_t delta_cpu, int64_t delta_net ) { + void system_contract::update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ) { user_resources_table totals_tbl( _self, receiver.value ); auto tot_itr = totals_tbl.find( receiver.value ); eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); @@ -224,7 +224,7 @@ namespace eosiosystem { * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ - void system_contract::rentcpu( name from, name receiver, asset loan_payment, asset loan_fund ) { + void system_contract::rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { require_auth( from ); @@ -233,7 +233,7 @@ namespace eosiosystem { update_resource_limits( receiver, rented_tokens, 0 ); } - void system_contract::rentnet( name from, name receiver, asset loan_payment, asset loan_fund ) { + void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { require_auth( from ); @@ -242,7 +242,7 @@ namespace eosiosystem { update_resource_limits( receiver, 0, rented_tokens ); } - void system_contract::fundcpuloan( name from, uint64_t loan_num, asset payment ) { + void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) { require_auth( from ); @@ -250,7 +250,7 @@ namespace eosiosystem { fund_rex_loan( cpu_loans, from, loan_num, payment ); } - void system_contract::fundnetloan( name from, uint64_t loan_num, asset payment ) { + void system_contract::fundnetloan( const name& from, uint64_t loan_num, const asset& payment ) { require_auth( from ); @@ -258,7 +258,7 @@ namespace eosiosystem { fund_rex_loan( net_loans, from, loan_num, payment ); } - void system_contract::defcpuloan( name from, uint64_t loan_num, asset amount ) { + void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) { require_auth( from ); @@ -266,7 +266,7 @@ namespace eosiosystem { defund_rex_loan( cpu_loans, from, loan_num, amount ); } - void system_contract::defnetloan( name from, uint64_t loan_num, asset amount ) { + void system_contract::defnetloan( const name& from, uint64_t loan_num, const asset& amount ) { require_auth( from ); @@ -274,7 +274,7 @@ namespace eosiosystem { defund_rex_loan( net_loans, from, loan_num, amount ); } - void system_contract::updaterex( name owner ) { + void system_contract::updaterex( const name& owner ) { require_auth( owner ); @@ -297,7 +297,7 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), delta_stake ); } - void system_contract::rexexec( name user, uint16_t max ) { + void system_contract::rexexec( const name& user, uint16_t max ) { require_auth( user ); @@ -414,7 +414,7 @@ namespace eosiosystem { } template - int64_t system_contract::rent_rex( T& table, name from, name receiver, const asset& payment, const asset& fund ) { + int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) { runrex(2); @@ -497,7 +497,7 @@ namespace eosiosystem { } template - void system_contract::fund_rex_loan( T& table, name from, uint64_t loan_num, const asset& payment ) { + void system_contract::fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ) { eosio_assert( payment.symbol == core_symbol(), "must use core token" ); transfer_from_fund( from, payment ); auto itr = table.require_find( loan_num, "loan not found" ); @@ -509,7 +509,7 @@ namespace eosiosystem { } template - void system_contract::defund_rex_loan( T& table, name from, uint64_t loan_num, const asset& amount ) { + void system_contract::defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ) { eosio_assert( amount.symbol == core_symbol(), "must use core token" ); auto itr = table.require_find( loan_num, "loan not found" ); eosio_assert( itr->from == from, "actor has to be loan creator" ); @@ -521,7 +521,7 @@ namespace eosiosystem { transfer_to_fund( from, amount ); } - void system_contract::transfer_from_fund( name owner, const asset& amount ) { + void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); eosio_assert( amount <= itr->balance, "insufficient funds"); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { @@ -529,24 +529,26 @@ namespace eosiosystem { }); } - void system_contract::transfer_to_fund( name owner, const asset& amount ) { + void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { auto itr = _rexfunds.require_find( owner.value, "programmer error" ); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { fund.balance.amount += amount.amount; }); } - void system_contract::update_rex_account( name owner, asset proceeds, asset delta_stake ) { + void system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake ) { + asset to_fund( proceeds ); + asset to_stake( delta_stake ); auto itr = _rexorders.find( owner.value ); if( itr != _rexorders.end() && !itr->is_open ) { - proceeds.amount += itr->proceeds.amount; - delta_stake.amount -= itr->proceeds.amount; + to_fund.amount += itr->proceeds.amount; + to_stake.amount-= itr->proceeds.amount; _rexorders.erase( itr ); } if( proceeds.amount > 0 ) - transfer_to_fund( owner, proceeds ); + transfer_to_fund( owner, to_fund ); if( delta_stake.amount != 0 ) - update_voting_power( owner, delta_stake ); + update_voting_power( owner, to_stake ); } }; /// namespace eosiosystem From d987222aed5cd7a51132e0c1c1098be2eac1bcc3 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 18 Oct 2018 11:16:53 -0400 Subject: [PATCH 0611/1048] Code cleaning --- eosio.system/src/rex.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 3a7da7bc..95957de0 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -34,14 +34,8 @@ namespace eosiosystem { require_auth( owner ); eosio_assert( amount.symbol == core_symbol(), "must withdraw core token" ); - update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - - auto itr = _rexfunds.require_find( owner.value, "account has no REX funds" ); - eosio_assert( amount <= itr->balance, "insufficient funds"); - _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { - fund.balance.amount -= amount.amount; - }); + transfer_from_fund( owner, amount ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, { rex_account, owner, amount, "withdraw from REX fund" } ); From 0cc435511bcd941608ba08c96957277a0d07c9d9 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 18 Oct 2018 11:22:55 -0400 Subject: [PATCH 0612/1048] Fix unit test --- tests/eosio.system_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 119bf525..ee67f589 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3889,10 +3889,10 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1]; setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_rex_fund( alice ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("account has no REX funds"), withdraw( alice, core_sym::from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), deposit( alice, init_balance + init_balance ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit core token"), deposit( alice, asset::from_string("1.0000 RNDM") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_rex_fund( alice ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit to REX fund first"), withdraw( alice, core_sym::from_string("0.0001") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), deposit( alice, init_balance + init_balance ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit core token"), deposit( alice, asset::from_string("1.0000 RNDM") ) ); asset deposit_quant( init_balance.get_amount() / 5, init_balance.get_symbol() ); BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); From 5a2a5ff5b61a4a69d2ca337d2e8d38971b953f26 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 18 Oct 2018 14:28:35 -0400 Subject: [PATCH 0613/1048] Create closerex action --- .../include/eosio.system/eosio.system.hpp | 3 ++ eosio.system/src/rex.cpp | 47 +++++++++++++++++-- 2 files changed, 47 insertions(+), 3 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 14660c08..d8fe1cb1 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -367,6 +367,9 @@ namespace eosiosystem { [[eosio::action]] void rexexec( const name& user, uint16_t max ); + [[eosio::action]] + void closerex( const name& user ); + /** * Decreases the total tokens delegated by from to receiver and/or * frees the memory associated with the delegation if there is nothing diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 95957de0..b1587892 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -298,8 +298,49 @@ namespace eosiosystem { runrex( max ); } + void system_contract::closerex( const name& user ) { + + require_auth( user ); + + runrex(2); + + update_rex_account( user, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); + + /// check for any outstanding cpu loans + { + rex_cpu_loan_table cpu_loans( _self, _self.value ); + auto cpu_idx = cpu_loans.get_index<"byowner"_n>(); + eosio_assert( cpu_idx.find( user.value ) == cpu_idx.end(), "account has outstanding CPU loan" ); + } + + /// check for any outstanding net loans + { + rex_net_loan_table net_loans( _self, _self.value ); + auto net_idx = net_loans.get_index<"byowner"_n>(); + eosio_assert( net_idx.find( user.value ) == net_idx.end(), "account has outstanding NET loan" ); + } + + /// check for remaining rex balance + { + auto rex_itr = _rexbalance.find( user.value ); + if( rex_itr != _rexbalance.end() ) { + eosio_assert( rex_itr->rex_balance.amount == 0, "account has remaining REX, must sell first"); + _rexbalance.erase( rex_itr ); + } + } + + /// check for remaining rex fund balance + { + auto fund_itr =_rexfunds.find( user.value ); + if( fund_itr != _rexfunds.end() ) { + eosio_assert( fund_itr->balance.amount == 0, "account has remaining funds, must withdraw first"); + _rexfunds.erase( fund_itr ); + } + } + } + /** - * Perform maitenance operations on expired rex + * Perform maintenance operations on expired rex */ void system_contract::runrex( uint16_t max ) { @@ -539,9 +580,9 @@ namespace eosiosystem { to_stake.amount-= itr->proceeds.amount; _rexorders.erase( itr ); } - if( proceeds.amount > 0 ) + if( to_fund.amount > 0 ) transfer_to_fund( owner, to_fund ); - if( delta_stake.amount != 0 ) + if( to_stake.amount != 0 ) update_voting_power( owner, to_stake ); } From b9532fab5e2ba489e283ca66dca2f1471116a940 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 18 Oct 2018 18:43:48 -0400 Subject: [PATCH 0614/1048] closerex testing - incomplete --- .../include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/rex.cpp | 23 +++---- tests/eosio.system_tester.hpp | 20 +++++- tests/eosio.system_tests.cpp | 65 ++++++++++++++++++- 5 files changed, 96 insertions(+), 16 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index d8fe1cb1..e8f831a3 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -368,7 +368,7 @@ namespace eosiosystem { void rexexec( const name& user, uint16_t max ); [[eosio::action]] - void closerex( const name& user ); + void closerex( const name& owner ); /** * Decreases the total tokens delegated by from to receiver and/or diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index f34fa0a5..bd1370a9 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -319,7 +319,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp (deposit)(withdraw)(buyrex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) - (defcpuloan)(defnetloan)(updaterex)(rexexec) + (defcpuloan)(defnetloan)(updaterex)(rexexec)(closerex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index b1587892..55bb4515 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -298,31 +298,32 @@ namespace eosiosystem { runrex( max ); } - void system_contract::closerex( const name& user ) { - - require_auth( user ); + void system_contract::closerex( const name& owner ) { + + require_auth( owner ); - runrex(2); + if( _rextable.begin() != _rextable.end() ) + runrex(2); - update_rex_account( user, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); + update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); /// check for any outstanding cpu loans { rex_cpu_loan_table cpu_loans( _self, _self.value ); auto cpu_idx = cpu_loans.get_index<"byowner"_n>(); - eosio_assert( cpu_idx.find( user.value ) == cpu_idx.end(), "account has outstanding CPU loan" ); + eosio_assert( cpu_idx.find( owner.value ) == cpu_idx.end(), "account has outstanding CPU loan" ); } /// check for any outstanding net loans { rex_net_loan_table net_loans( _self, _self.value ); auto net_idx = net_loans.get_index<"byowner"_n>(); - eosio_assert( net_idx.find( user.value ) == net_idx.end(), "account has outstanding NET loan" ); + eosio_assert( net_idx.find( owner.value ) == net_idx.end(), "account has outstanding NET loan" ); } /// check for remaining rex balance { - auto rex_itr = _rexbalance.find( user.value ); + auto rex_itr = _rexbalance.find( owner.value ); if( rex_itr != _rexbalance.end() ) { eosio_assert( rex_itr->rex_balance.amount == 0, "account has remaining REX, must sell first"); _rexbalance.erase( rex_itr ); @@ -331,7 +332,7 @@ namespace eosiosystem { /// check for remaining rex fund balance { - auto fund_itr =_rexfunds.find( user.value ); + auto fund_itr =_rexfunds.find( owner.value ); if( fund_itr != _rexfunds.end() ) { eosio_assert( fund_itr->balance.amount == 0, "account has remaining funds, must withdraw first"); _rexfunds.erase( fund_itr ); @@ -576,8 +577,8 @@ namespace eosiosystem { asset to_stake( delta_stake ); auto itr = _rexorders.find( owner.value ); if( itr != _rexorders.end() && !itr->is_open ) { - to_fund.amount += itr->proceeds.amount; - to_stake.amount-= itr->proceeds.amount; + to_fund.amount += itr->proceeds.amount; + to_stake.amount -= itr->proceeds.amount; _rexorders.erase( itr ); } if( to_fund.amount > 0 ) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 91a09699..dfe15dd3 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -399,6 +399,14 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(updaterex), mvo()("owner", owner) ); } + action_result rexexec( const account_name& user, uint16_t max ) { + return push_action( name(user), N(rexexec), mvo()("user", user)("max", max) ); + } + + action_result closerex( const account_name& owner ) { + return push_action( name(owner), N(closerex), mvo()("owner", owner) ); + } + fc::variant get_last_loan(bool cpu) { vector data; const auto& db = control->db(); @@ -452,11 +460,21 @@ class eosio_system_tester : public TESTER { return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); } + fc::variant get_rex_balance_obj( const account_name& act ) const { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time); + } + asset get_rex_fund( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); return data.empty() ? asset(0, symbol{CORE_SYM}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer_max_time)["balance"].as(); } + fc::variant get_rex_fund_obj( const account_name& act ) const { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_fund", data, abi_serializer_max_time ); + } + asset get_rex_vote_stake( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); return data.empty() ? core_sym::from_string("0.0000") : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["vote_stake"].as(); @@ -465,7 +483,7 @@ class eosio_system_tester : public TESTER { fc::variant get_rex_order( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); return abi_ser.binary_to_variant( "rex_order", data, abi_serializer_max_time ); - } + } fc::variant get_rex_pool() const { vector data; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index ee67f589..74358b7f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3817,8 +3817,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); + const asset init_balance = core_sym::from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); @@ -3912,6 +3911,68 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { + + const asset init_balance = core_sym::from_string("200.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; + setup_rex_accounts( accounts, init_balance ); + + BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( alice ).is_null() ); + BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( alice ) ); + BOOST_REQUIRE_EQUAL( closerex( alice ), wasm_assert_msg("account has remaining funds, must withdraw first") ); + BOOST_REQUIRE_EQUAL( success(), withdraw( alice, init_balance ) ); + BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( alice).is_null() ); + BOOST_REQUIRE_EQUAL( success(), deposit( alice, init_balance ) ); + BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( alice).is_null() ); + + BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); + BOOST_REQUIRE_EQUAL( false, get_rex_balance_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); + BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX, must sell first") ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); + BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining funds, must withdraw first") ); + BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); + BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); + + BOOST_REQUIRE_EQUAL( success(), deposit( bob, init_balance ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); + + BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, emily, init_balance ) ); + + produce_block( fc::days(20) ); + + BOOST_REQUIRE_EQUAL( closerex( carol ), wasm_assert_msg("account has outstanding CPU loan") ); + + produce_block( fc::days(10) ); + + BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( carol ).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( carol ).is_null() ); + + BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, init_balance ) ); + BOOST_REQUIRE_EQUAL( closerex( emily ), wasm_assert_msg("account has outstanding NET loan") ); + + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); + BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX, must sell first") ); + + produce_block( fc::days(30) ); + + // BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining funds, must withdraw first") ); + // BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); + // BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); + // BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); + // BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); + // BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); set_code( config::system_account_name, contracts::bios_wasm() ); From 2e44cad4ce5ea143f5af44a3bf85380669f16860 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 21 Oct 2018 19:59:42 -0400 Subject: [PATCH 0615/1048] closerex testing - 2 --- .../include/eosio.system/eosio.system.hpp | 9 +++- eosio.system/src/rex.cpp | 50 ++++++++++--------- tests/eosio.system_tests.cpp | 13 ++--- 3 files changed, 41 insertions(+), 31 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index e8f831a3..67d3c73c 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -236,6 +236,7 @@ namespace eosiosystem { name owner; asset rex_requested; asset proceeds; + asset stake_change; eosio::time_point order_time; bool is_open = true; @@ -247,6 +248,12 @@ namespace eosiosystem { typedef eosio::multi_index< "rexqueue"_n, rex_order, indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; + struct rex_order_outcome { + bool success; + asset proceeds; + asset stake_change; + }; + class [[eosio::contract("eosio.system")]] system_contract : public native { private: @@ -478,7 +485,7 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); void update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ); - std::pair close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + rex_order_outcome close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); void update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant ); void deposit_rex( const name& from, const asset& amount ); template diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 55bb4515..7d0fbb4f 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -142,8 +142,8 @@ namespace eosiosystem { eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); auto current_order = close_rex_order( bitr, rex ); - update_rex_account( from, current_order.second, -current_order.second ); - if( !current_order.first ) { + update_rex_account( from, current_order.proceeds, current_order.stake_change ); + if( !current_order.success ) { /** * REX order couldn't be filled and is added to queue. * If account already has an open order, requested rex is added to existing order. @@ -155,6 +155,7 @@ namespace eosiosystem { order.rex_requested = rex; order.is_open = true; order.proceeds = asset( 0, core_symbol() ); + order.stake_change = asset( 0, core_symbol() ); order.order_time = current_time_point(); }); } else { @@ -271,18 +272,21 @@ namespace eosiosystem { void system_contract::updaterex( const name& owner ) { require_auth( owner ); - - auto itr = _rexbalance.require_find( owner.value, "account has no REX balance" ); - const asset init_stake = itr->vote_stake; runrex(2); - auto rexp_itr = _rextable.begin(); - const asset& total_rex = rexp_itr->total_rex; - const asset& total_lendable = rexp_itr->total_lendable; + auto itr = _rexbalance.require_find( owner.value, "account has no REX balance" ); + const asset init_stake = itr->vote_stake; + auto rexp_itr = _rextable.begin(); + const int64_t total_rex = rexp_itr->total_rex.amount; + const int64_t total_lendable = rexp_itr->total_lendable.amount; + const int64_t rex_balance = itr->rex_balance.amount; + asset current_stake( 0, core_symbol() ); - current_stake.amount = ( uint128_t(itr->rex_balance.amount) * total_lendable.amount ) / total_rex.amount; + if ( total_rex > 0 ) { + current_stake.amount = ( uint128_t(rex_balance) * total_lendable ) / total_rex; + } _rexbalance.modify( itr, same_payer, [&]( auto& rb ) { rb.vote_stake = current_stake; }); @@ -437,9 +441,10 @@ namespace eosiosystem { auto result = close_rex_order( bitr, oitr->rex_requested ); auto next = oitr; ++next; - if( result.first ) { + if( result.success ) { idx.modify( oitr, same_payer, [&]( auto& order ) { - order.proceeds.amount = result.second.amount; + order.proceeds.amount = result.proceeds.amount; + order.stake_change.amount = result.stake_change.amount; order.close(); }); } @@ -485,38 +490,35 @@ namespace eosiosystem { return rented_tokens; } - std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + // std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + rex_order_outcome system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rextable.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; asset proceeds( S0 - S1, core_symbol() ); - - /// update vote_stake to its current value whether sell order is processed or not - /// that is, value right before sell order is processed - int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; - update_voting_power( bitr->owner, asset( current_stake_value - bitr->vote_stake.amount, core_symbol() ), false ); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount = current_stake_value; - }); - + asset stake_change( 0, core_symbol() ); + bool success = false; if( proceeds.amount <= rexitr->total_unlent.amount ) { + const int64_t init_vote_stake_amount = bitr->vote_stake.amount; + const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; _rextable.modify( rexitr, same_payer, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; }); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount -= proceeds.amount; + rb.vote_stake.amount = current_stake_value - proceeds.amount; rb.rex_balance.amount -= rex.amount; }); + stake_change.amount = bitr->vote_stake.amount - init_vote_stake_amount; success = true; } else { proceeds.amount = 0; } - return { success, proceeds }; + return { success, proceeds, stake_change }; } void system_contract::deposit_rex( const name& from, const asset& amount ) { @@ -578,7 +580,7 @@ namespace eosiosystem { auto itr = _rexorders.find( owner.value ); if( itr != _rexorders.end() && !itr->is_open ) { to_fund.amount += itr->proceeds.amount; - to_stake.amount -= itr->proceeds.amount; + to_stake.amount += itr->stake_change.amount; _rexorders.erase( itr ); } if( to_fund.amount > 0 ) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 74358b7f..e3f9c7c7 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3963,12 +3963,13 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { produce_block( fc::days(30) ); - // BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining funds, must withdraw first") ); - // BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); - // BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); - // BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); - // BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); - // BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining funds, must withdraw first") ); + BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); + BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); + BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); + BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); } FC_LOG_AND_RETHROW() From dbb9169bc134f1a69a90b3714205c2e959126b84 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 22 Oct 2018 10:43:30 -0400 Subject: [PATCH 0616/1048] Fix REX rent corner case, refactoring --- .../include/eosio.system/eosio.system.hpp | 6 ++- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/producer_pay.cpp | 5 +- eosio.system/src/rex.cpp | 46 +++++++++---------- tests/eosio.system_tests.cpp | 9 +++- 5 files changed, 36 insertions(+), 32 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 67d3c73c..53d9fe77 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -267,7 +267,7 @@ namespace eosiosystem { eosio_global_state2 _gstate2; eosio_global_state3 _gstate3; rammarket _rammarket; - rex_pool_table _rextable; + rex_pool_table _rexpool; rex_fund_table _rexfunds; rex_balance_table _rexbalance; rex_order_table _rexorders; @@ -496,7 +496,9 @@ namespace eosiosystem { void defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ); void transfer_from_fund( const name& owner, const asset& amount ); void transfer_to_fund( const name& owner, const asset& amount ); - bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end(); } + bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end() && rex_available(); } + bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } + bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index bd1370a9..2c3fa512 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -19,7 +19,7 @@ namespace eosiosystem { _global2(_self, _self.value), _global3(_self, _self.value), _rammarket(_self, _self.value), - _rextable(_self, _self.value), + _rexpool(_self, _self.value), _rexfunds(_self, _self.value), _rexbalance(_self, _self.value), _rexorders(_self, _self.value) diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 6ab733f3..09586861 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -65,9 +65,8 @@ namespace eosiosystem { (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) ) { _gstate.last_name_close = timestamp; - auto rex_itr = _rextable.begin(); - if( rex_itr != _rextable.end() ) { - _rextable.modify( rex_itr, same_payer, [&]( auto& rp ) { + if( rex_available() ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.namebid_proceeds.amount += highest->high_bid; }); } diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 7d0fbb4f..1553248f 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -62,10 +62,10 @@ namespace eosiosystem { asset rex_received( 0, rex_symbol ); - auto itr = _rextable.begin(); - if( itr == _rextable.end() ) { + auto itr = _rexpool.begin(); + if( !rex_system_initialized() ) { /// initialize REX pool - _rextable.emplace( _self, [&]( auto& rp ) { + _rexpool.emplace( _self, [&]( auto& rp ) { rex_received.amount = amount.amount * rex_ratio; rp.total_lendable = amount; @@ -75,8 +75,8 @@ namespace eosiosystem { rp.total_unlent = rp.total_lendable - rp.total_lent; rp.namebid_proceeds = asset( 0, core_symbol() ); }); - } else if( itr->total_lendable.amount == 0 ) { /// should be a rare corner case - _rextable.modify( itr, same_payer, [&]( auto& rp ) { + } else if( !rex_available() ) { /// should be a rare corner case + _rexpool.modify( itr, same_payer, [&]( auto& rp ) { rex_received.amount = amount.amount * rex_ratio; rp.total_lendable.amount = amount.amount; @@ -93,7 +93,7 @@ namespace eosiosystem { rex_received.amount = R1 - R0; - _rextable.modify( itr, same_payer, [&]( auto& rp ) { + _rexpool.modify( itr, same_payer, [&]( auto& rp ) { rp.total_lendable.amount = S1; rp.total_rex.amount = R1; rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; @@ -134,8 +134,7 @@ namespace eosiosystem { require_auth( from ); - auto itr = _rextable.begin(); - eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); + eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); @@ -278,7 +277,7 @@ namespace eosiosystem { auto itr = _rexbalance.require_find( owner.value, "account has no REX balance" ); const asset init_stake = itr->vote_stake; - auto rexp_itr = _rextable.begin(); + auto rexp_itr = _rexpool.begin(); const int64_t total_rex = rexp_itr->total_rex.amount; const int64_t total_lendable = rexp_itr->total_lendable.amount; const int64_t rex_balance = itr->rex_balance.amount; @@ -306,7 +305,7 @@ namespace eosiosystem { require_auth( owner ); - if( _rextable.begin() != _rextable.end() ) + if( rex_system_initialized() ) runrex(2); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); @@ -349,11 +348,12 @@ namespace eosiosystem { */ void system_contract::runrex( uint16_t max ) { - auto rexi = _rextable.begin(); - eosio_assert( rexi != _rextable.end(), "rex system not initialized yet" ); + eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); + + auto rexi = _rexpool.begin(); auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { - _rextable.modify( rexi, same_payer, [&]( auto& rt ) { + _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, itr->total_staked.amount ); rt.total_lent.amount -= itr->total_staked.amount; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; @@ -363,7 +363,7 @@ namespace eosiosystem { int64_t delta_stake = 0; if( itr->payment <= itr->balance && rex_loans_available() ) { int64_t rented_tokens = 0; - _rextable.modify( rexi, same_payer, [&]( auto& rt ) { + _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, itr->payment.amount ); @@ -392,7 +392,7 @@ namespace eosiosystem { /// transfer from eosio.names to eosio.rex if( rexi->namebid_proceeds.amount > 0 ) { deposit_rex( names_account, rexi->namebid_proceeds ); - _rextable.modify( rexi, same_payer, [&]( auto& rt ) { + _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { rt.namebid_proceeds.amount = 0; }); } @@ -465,11 +465,11 @@ namespace eosiosystem { update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( from, payment + fund ); - auto itr = _rextable.begin(); - eosio_assert( itr != _rextable.end(), "rex system not initialized yet" ); + auto itr = _rexpool.begin(); + eosio_assert( itr != _rexpool.end(), "rex system not initialized yet" ); int64_t rented_tokens = 0; - _rextable.modify( itr, same_payer, [&]( auto& rt ) { + _rexpool.modify( itr, same_payer, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); rt.total_lent.amount += rented_tokens; rt.total_unlent.amount += payment.amount; @@ -490,9 +490,8 @@ namespace eosiosystem { return rented_tokens; } - // std::pair system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { rex_order_outcome system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { - auto rexitr = _rextable.begin(); + auto rexitr = _rexpool.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; const auto R1 = R0 - rex.amount; @@ -504,7 +503,7 @@ namespace eosiosystem { if( proceeds.amount <= rexitr->total_unlent.amount ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; - _rextable.modify( rexitr, same_payer, [&]( auto& rt ) { + _rexpool.modify( rexitr, same_payer, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; @@ -522,9 +521,8 @@ namespace eosiosystem { } void system_contract::deposit_rex( const name& from, const asset& amount ) { - auto itr = _rextable.begin(); - if( itr != _rextable.end() ) { - _rextable.modify( itr, same_payer, [&]( auto& rp ) { + if( rex_available() ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.total_unlent.amount += amount.amount; rp.total_lendable.amount += amount.amount; }); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index e3f9c7c7..00a43255 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3914,8 +3914,8 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { const asset init_balance = core_sym::from_string("200.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( alice ).is_null() ); @@ -3971,6 +3971,11 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_rex"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are not currently available"), + rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); + } FC_LOG_AND_RETHROW() From ebb1156b4d555e70bcfb9bbf86dcc9d76f34f692 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 22 Oct 2018 14:32:51 -0400 Subject: [PATCH 0617/1048] Update REX comments --- .../include/eosio.system/eosio.system.hpp | 46 ++++++++++++++----- eosio.system/src/rex.cpp | 21 +++++++-- 2 files changed, 51 insertions(+), 16 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 53d9fe77..2d040ff2 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -315,38 +315,51 @@ namespace eosiosystem { void delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); - + /** + * Deposits core tokens to user REX fund. All proceeds and expenses related to REX are added to + * or taken out of this fund. Inline token transfer from user balance is executed. + */ [[eosio::action]] void deposit( const name& owner, const asset& amount ); + /** + * Withdraws core tokens from user REX fund. Inline token transfer to user balance is executed. + */ [[eosio::action]] void withdraw( const name& owner, const asset& amount ); /** - * Transfers SYS tokens from user balance and credits converts them to REX stake. + * Transfers core tokens from user REX fund and converts them to REX stake. + * User votes are updated following this action. */ [[eosio::action]] void buyrex( const name& from, const asset& amount ); /** - * Converts REX stake back into SYS tokens at current exchange rate. If order cannot be - * processed, it gets queued until it can be there is enough REX to fill order. + * Converts REX stake back into core tokens at current exchange rate. If order cannot be + * processed, it gets queued until there is enough in REX pool to fill order. + * If successful, user votes are updated. */ [[eosio::action]] void sellrex( const name& from, const asset& rex ); /** - * Cancels queued sellrex order. + * Cancels queued sellrex order. Order cannot be cancelled once it's been filled. */ [[eosio::action]] void cnclrexorder( const name& owner ); /** - * Use payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, - * after 30 days the rented SYS delegation of CPU or NET will expire unless auto_renew == true. - * If auto_renew == true, loan creator can fund that specific loan. Upon expiration, if loan has enough funds, it - * gets renewed at current market price, otherwise, the loan is closed and remaining balance if refunded to loan - * creator. User claims the refund in a separate action. + * Use payment to rent as many SYS tokens as possible and stake them for either CPU or NET for the + * benefit of receiver, after 30 days the rented SYS delegation of CPU or NET will expire unless loan + * balance is larger than or equal to payment. + * + * If loan has enough balance, it gets renewed at current market price, otherwise, the is is closed + * and remaining balance is refunded to loan owner. + * + * Owner can fund or defund a loan at any time before its expiration. + * + * All loan expenses and refunds come out of or are added to owner's REX fund. */ [[eosio::action]] void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); @@ -354,12 +367,15 @@ namespace eosiosystem { void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Loan initiator funds a given CPU or NET loan. Loan must've been set as autorenew. + * Loan owner funds a given CPU or NET loan. */ [[eosio::action]] void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); [[eosio::action]] void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); + /** + * Loan owner defunds a given CPU or NET loan. + */ [[eosio::action]] void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); [[eosio::action]] @@ -371,9 +387,17 @@ namespace eosiosystem { [[eosio::action]] void updaterex( const name& owner ); + /** + * Processes max CPU loans, max NET loans, and max queued sellrex orders. + * Action does not execute anything related to a specific user. + */ [[eosio::action]] void rexexec( const name& user, uint16_t max ); + /** + * Deletes owner records from REX tables and frees used RAM. Owner must have no outstanding loans, + * REX balance, or remaining REX fund balance. + */ [[eosio::action]] void closerex( const name& owner ); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 1553248f..d0b48ffd 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -125,9 +125,6 @@ namespace eosiosystem { update_rex_account( from, asset( 0, core_symbol() ), current_rex_stake - init_rex_stake ); } - /** - * Converts REX stake back into SYS tokens at current exchange rate - */ void system_contract::sellrex( const name& from, const asset& rex ) { runrex(2); @@ -490,6 +487,13 @@ namespace eosiosystem { return rented_tokens; } + /** + * close_rex_order processes an incoming of already scheduled sellrex order. If REX pool has enough core + * tokens (not frozen in loans), order can be filled. In this case, REX pool totals, user rex_balance + * and user vote_stake are updated. However, user voting power is not updated inside this function. The + * function returns success flag, order proceeds, and vote stake change. These are used later to finish + * order processing, which includes transfering proceeds and updating user vote weight. + */ rex_order_outcome system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rexpool.begin(); const auto S0 = rexitr->total_lendable.amount; @@ -497,9 +501,9 @@ namespace eosiosystem { const auto R1 = R0 - rex.amount; const auto S1 = (uint128_t(R1) * S0) / R0; asset proceeds( S0 - S1, core_symbol() ); - asset stake_change( 0, core_symbol() ); - + asset stake_change( 0, core_symbol() ); bool success = false; + if( proceeds.amount <= rexitr->total_unlent.amount ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; @@ -572,6 +576,13 @@ namespace eosiosystem { }); } + /** + * update_rex_account checks if user has a scheduled sellrex order that has been closed, completes its processing, + * and deletes it. + * Processing entails transfering proceeds to user REX fund and updating user vote weight. + * Additional proceeds and stake change can be passed. + * This function is called only by actions pushed by owner, unlike close_rex_order. + */ void system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake ) { asset to_fund( proceeds ); asset to_stake( delta_stake ); From 038e15b162603698677003a17e8d577356d51742 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 25 Oct 2018 14:16:51 -0400 Subject: [PATCH 0618/1048] Small change to clearly isolate transfering from system accounts to REX --- .../include/eosio.system/eosio.system.hpp | 7 ++-- eosio.system/src/delegate_bandwidth.cpp | 4 +-- eosio.system/src/producer_pay.cpp | 6 +--- eosio.system/src/rex.cpp | 34 ++++++++++++------- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 2d040ff2..5ee4aee2 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -354,8 +354,8 @@ namespace eosiosystem { * benefit of receiver, after 30 days the rented SYS delegation of CPU or NET will expire unless loan * balance is larger than or equal to payment. * - * If loan has enough balance, it gets renewed at current market price, otherwise, the is is closed - * and remaining balance is refunded to loan owner. + * If loan has enough balance, it gets renewed at current market price, otherwise, it is closed and + * remaining balance is refunded to loan owner. * * Owner can fund or defund a loan at any time before its expiration. * @@ -511,7 +511,8 @@ namespace eosiosystem { void update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ); rex_order_outcome close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); void update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant ); - void deposit_rex( const name& from, const asset& amount ); + void channel_to_rex( const name& from, const asset& amount ); + void channel_namebid_to_rex( const int64_t highest_bid ); template int64_t rent_rex( T& table, const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); template diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 610399f7..14885562 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -131,7 +131,7 @@ namespace eosiosystem { token_account, { {payer, active_permission} }, { payer, ramfee_account, fee, std::string("ram fee") } ); - deposit_rex( ramfee_account, fee ); + channel_to_rex( ramfee_account, fee ); } int64_t bytes_out; @@ -212,7 +212,7 @@ namespace eosiosystem { token_account, { {account, active_permission} }, { account, ramfee_account, asset(fee, core_symbol()), std::string("sell ram fee") } ); - deposit_rex( ramfee_account, asset(fee, core_symbol() )); + channel_to_rex( ramfee_account, asset(fee, core_symbol() )); } } diff --git a/eosio.system/src/producer_pay.cpp b/eosio.system/src/producer_pay.cpp index 09586861..70dd093b 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/eosio.system/src/producer_pay.cpp @@ -65,11 +65,7 @@ namespace eosiosystem { (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) ) { _gstate.last_name_close = timestamp; - if( rex_available() ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { - rp.namebid_proceeds.amount += highest->high_bid; - }); - } + channel_namebid_to_rex( highest->high_bid ); idx.modify( highest, same_payer, [&]( auto& b ){ b.high_bid = -b.high_bid; }); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index d0b48ffd..ba8653c7 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -388,7 +388,7 @@ namespace eosiosystem { /// transfer from eosio.names to eosio.rex if( rexi->namebid_proceeds.amount > 0 ) { - deposit_rex( names_account, rexi->namebid_proceeds ); + channel_to_rex( names_account, rexi->namebid_proceeds ); _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { rt.namebid_proceeds.amount = 0; }); @@ -524,18 +524,6 @@ namespace eosiosystem { return { success, proceeds, stake_change }; } - void system_contract::deposit_rex( const name& from, const asset& amount ) { - if( rex_available() ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { - rp.total_unlent.amount += amount.amount; - rp.total_lendable.amount += amount.amount; - }); - - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { from, active_permission }, - { from, rex_account, amount, std::string("transfer from ") + name{from}.to_string() + " REX"} ); - } - } - template void system_contract::fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ) { eosio_assert( payment.symbol == core_symbol(), "must use core token" ); @@ -598,4 +586,24 @@ namespace eosiosystem { update_voting_power( owner, to_stake ); } + void system_contract::channel_to_rex( const name& from, const asset& amount ) { + if( rex_available() ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { + rp.total_unlent.amount += amount.amount; + rp.total_lendable.amount += amount.amount; + }); + + INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { from, active_permission }, + { from, rex_account, amount, std::string("transfer from ") + name{from}.to_string() + " REX"} ); + } + } + + void system_contract::channel_namebid_to_rex( const int64_t highest_bid ) { + if( rex_available() ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { + rp.namebid_proceeds.amount += highest_bid; + }); + } + } + }; /// namespace eosiosystem From ae8030914dc908c66c67bf386dff747dd959901b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 29 Oct 2018 10:04:43 -0400 Subject: [PATCH 0619/1048] Small change in REX order queue --- eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 5ee4aee2..96cc79ce 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -242,7 +242,7 @@ namespace eosiosystem { void close() { is_open = false; } uint64_t primary_key()const { return owner.value; } - uint64_t by_time()const { return is_open ? order_time.elapsed.count() : -order_time.elapsed.count(); } + uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } }; typedef eosio::multi_index< "rexqueue"_n, rex_order, From 4e24ee2d2ef687b624f5de6fa1da8d4f5be87c66 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 5 Nov 2018 19:11:35 -0500 Subject: [PATCH 0620/1048] use CMake find_package for eosio dependency; upgrade eosio dependency minimum version to 1.4 --- CMakeLists.txt | 2 - CheckVersion.txt | 90 ------------------------------------ UnitTestsExternalProject.txt | 6 ++- tests/CMakeLists.txt | 13 ++---- 4 files changed, 8 insertions(+), 103 deletions(-) delete mode 100644 CheckVersion.txt diff --git a/CMakeLists.txt b/CMakeLists.txt index 3b5c69ca..c26001e7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,8 +5,6 @@ set(EOSIO_CDT_VERSION_MIN "1.3") set(EOSIO_CDT_VERSION_SOFT_MAX "1.3") #set(EOSIO_CDT_VERSION_HARD_MAX "") -include(CheckVersion.txt) - find_package(eosio.cdt) ### Check the version of eosio.cdt diff --git a/CheckVersion.txt b/CheckVersion.txt deleted file mode 100644 index ffd28561..00000000 --- a/CheckVersion.txt +++ /dev/null @@ -1,90 +0,0 @@ -function(EXTRACT_MAJOR_MINOR_FROM_VERSION version success major minor) - string(REGEX REPLACE "^([0-9]+)\\..+$" "\\1" _major "${version}") - if("${_major}" STREQUAL "${version}") - set(${success} FALSE PARENT_SCOPE) - return() - endif() - - string(REGEX REPLACE "^[0-9]+\\.([0-9]+)(\\..*)?$" "\\1" _minor "${version}") - if("${_minor}" STREQUAL "${version}") - set(success FALSE PARENT_SCOPE) - return() - endif() - - set(${major} ${_major} PARENT_SCOPE) - set(${minor} ${_minor} PARENT_SCOPE) - set(${success} TRUE PARENT_SCOPE) -endfunction(EXTRACT_MAJOR_MINOR_FROM_VERSION) - -function(EOSIO_CHECK_VERSION output version hard_min soft_max hard_max) # optional 6th argument for error message - set(${output} "INVALID" PARENT_SCOPE) - - EXTRACT_MAJOR_MINOR_FROM_VERSION("${version}" success major minor) - if(NOT success) - if(${ARGC} GREATER 5) - set(${ARGV5} "version '${version}' is invalid" PARENT_SCOPE) - endif() - return() - endif() - - EXTRACT_MAJOR_MINOR_FROM_VERSION("${hard_min}" success hard_min_major hard_min_minor) - if(NOT success) - if(${ARGC} GREATER 5) - set(${ARGV5} "hard minimum version '${hard_min}' is invalid" PARENT_SCOPE) - endif() - return() - endif() - - if( "${major}.${minor}" VERSION_LESS "${hard_min_major}.${hard_min_minor}" ) - set(${output} "MISMATCH" PARENT_SCOPE) - if(${ARGC} GREATER 5) - set(${ARGV5} "version '${version}' does not meet hard minimum version requirement of ${hard_min_major}.${hard_min_minor}" PARENT_SCOPE) - endif() - return() - endif() - - if(NOT hard_max STREQUAL "") - EXTRACT_MAJOR_MINOR_FROM_VERSION("${hard_max}" success hard_max_major hard_max_minor) - if(NOT success) - if(${ARGC} GREATER 5) - set(${ARGV5} "hard maximum version '${hard_max}' is invalid" PARENT_SCOPE) - endif() - return() - endif() - - if( "${major}.${minor}" VERSION_GREATER "${hard_max_major}.${hard_max_minor}" ) - set(${output} "MISMATCH" PARENT_SCOPE) - if(${ARGC} GREATER 5) - set(${ARGV5} "version '${version}' does not meet hard maximum version requirement of ${hard_max_major}.${hard_max_minor}" PARENT_SCOPE) - endif() - return() - endif() - endif() - - EXTRACT_MAJOR_MINOR_FROM_VERSION("${soft_max}" success soft_max_major soft_max_minor) - if(NOT success) - set(${output} "MISMATCH" PARENT_SCOPE) - if(${ARGC} GREATER 5) - set(${ARGV5} "soft maximum version '${soft_max}' is invalid" PARENT_SCOPE) - endif() - return() - endif() - - if( ${major} GREATER ${soft_max_major} ) - set(${output} "MISMATCH" PARENT_SCOPE) - if(${ARGC} GREATER 5) - set(${ARGV5} "version '${version}' must have the same major version as the soft maximum version (${soft_max_major})" PARENT_SCOPE) - endif() - return() - endif() - - if( "${major}.${minor}" VERSION_GREATER "${soft_max_major}.${soft_max_minor}" ) - set(${output} "WARN" PARENT_SCOPE) - if(${ARGC} GREATER 5) - set(${ARGV5} "version '${version}' matches requirements but is greater than the soft maximum version of ${soft_max_major}.${soft_max_minor}" PARENT_SCOPE) - endif() - return() - endif() - - set(${output} "MATCH" PARENT_SCOPE) -endfunction(EOSIO_CHECK_VERSION) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index 3da9f16f..a22bff2d 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -2,9 +2,13 @@ include(ExternalProject) find_package(Git REQUIRED) include(GNUInstallDirs) +string(REPLACE ";" "|" TEST_FRAMEWORK_PATH "${CMAKE_FRAMEWORK_PATH}") +string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") + ExternalProject_Add( contracts_unit_tests - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DEOSIO_ROOT=${EOSIO_ROOT} + LIST_SEPARATOR | # Use the alternate list separator + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ef8603fb..1e78a70f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,17 +1,10 @@ cmake_minimum_required( VERSION 3.5 ) -set(EOSIO_VERSION_MIN "1.3") -set(EOSIO_VERSION_SOFT_MAX "1.3") +set(EOSIO_VERSION_MIN "1.4") +set(EOSIO_VERSION_SOFT_MAX "1.4") #set(EOSIO_VERSION_HARD_MAX "") -include(../CheckVersion.txt) - -if(EOSIO_ROOT STREQUAL "" OR NOT EOSIO_ROOT) - set(EOSIO_ROOT "/usr/local/eosio") -endif() - -list(APPEND CMAKE_MODULE_PATH ${EOSIO_ROOT}/lib/cmake) -include(EosioTester) +find_package(eosio) ### Check the version of eosio set(VERSION_MATCH_ERROR_MSG "") From 6b37aba876227b19d128c4d1e5b451483d7ade20 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 6 Nov 2018 11:55:23 -0500 Subject: [PATCH 0621/1048] Change REX system initial state --- eosio.system/src/rex.cpp | 12 ++++++------ tests/eosio.system_tester.hpp | 4 ++-- tests/eosio.system_tests.cpp | 36 ++++++++++++++++++++--------------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index ba8653c7..4ad33010 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -50,8 +50,8 @@ namespace eosiosystem { eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); - const int64_t rex_ratio = 10000; - const int64_t init_rent = 1000000; + const int64_t rex_ratio = 10000; + const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() are made available { auto vitr = _voters.find( from.value ); eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), @@ -70,9 +70,9 @@ namespace eosiosystem { rp.total_lendable = amount; rp.total_lent = asset( 0, core_symbol() ); - rp.total_rent = asset( init_rent, core_symbol() ); /// base amount prevents renting profitably until at least a minimum number of core_symbol() are made available - rp.total_rex = rex_received; rp.total_unlent = rp.total_lendable - rp.total_lent; + rp.total_rent = asset( init_total_rent, core_symbol() ); + rp.total_rex = rex_received; rp.namebid_proceeds = asset( 0, core_symbol() ); }); } else if( !rex_available() ) { /// should be a rare corner case @@ -81,9 +81,9 @@ namespace eosiosystem { rp.total_lendable.amount = amount.amount; rp.total_lent.amount = 0; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + rp.total_rent.amount = init_total_rent; rp.total_rex.amount = rex_received.amount; - rp.total_unlent.amount = amount.amount; - rp.total_rent.amount = std::min( init_rent, rp.total_rent.amount ); }); } else { const auto S0 = itr->total_lendable.amount; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index dfe15dd3..c095d97a 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -510,7 +510,7 @@ class eosio_system_tester : public TESTER { const asset& init_balance, const asset& net = core_sym::from_string("80.0000"), const asset& cpu = core_sym::from_string("80.0000"), - bool deposit_into_rex = true ) { + bool deposit_into_rex_fund = true ) { const asset nstake = core_sym::from_string("10.0000"); const asset cstake = core_sym::from_string("10.0000"); create_account_with_resources( N(proxyaccount), config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); @@ -522,7 +522,7 @@ class eosio_system_tester : public TESTER { BOOST_REQUIRE_EQUAL( success(), vote( a, { }, N(proxyaccount) ) ); BOOST_REQUIRE_EQUAL( init_balance, get_balance(a) ); BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - if (deposit_into_rex) { + if (deposit_into_rex_fund) { BOOST_REQUIRE_EQUAL( success(), deposit( a, init_balance ) ); BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( a ) ); BOOST_REQUIRE_EQUAL( 0, get_balance( a ).get_amount() ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 00a43255..7f843327 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3392,6 +3392,7 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; + const asset init_rent = core_sym::from_string("100000.0000"); const asset init_balance = core_sym::from_string("1000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; @@ -3407,7 +3408,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_unlent"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); BOOST_REQUIRE_EQUAL( get_rex_balance(alice), rex_pool["total_rex"].as() ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("75.0000") ) ); @@ -3417,7 +3418,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("105.0000"), rex_pool["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("105.0000"), rex_pool["total_unlent"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first buyrex"), sellrex( carol, asset::from_string("5.0000 REX") ) ); @@ -3435,7 +3436,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_total_rex / init_total_lendable, total_rex / total_lendable ); BOOST_REQUIRE_EQUAL( total_lendable, rex_pool["total_unlent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); } FC_LOG_AND_RETHROW() @@ -3541,16 +3542,16 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); + auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; + + const asset init_balance = core_sym::from_string("2000000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - const auto purchase1 = core_sym::from_string("880.0000"); - const auto purchase2 = core_sym::from_string("471.0000"); - const auto purchase3 = core_sym::from_string("469.0000"); + const auto purchase1 = core_sym::from_string("880000.0000"); + const auto purchase2 = core_sym::from_string("471000.0000"); + const auto purchase3 = core_sym::from_string("469000.0000"); const auto init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); @@ -3564,16 +3565,21 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto init_alice_rex = get_rex_balance(alice); auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_sym::from_string("1100.0000") ) ); + + BOOST_REQUIRE_EQUAL(core_sym::from_string("100000.0000"), get_rex_pool()["total_rent"].as() ); + + const asset rent_payment = core_sym::from_string("1100000.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment ) ); + const auto init_rex_pool = get_rex_pool(); - const int64_t init_alice_rex_stake = ( init_alice_rex.get_amount() * init_rex_pool["total_lendable"].as().get_amount() ) + const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * init_rex_pool["total_lendable"].as().get_amount() ) / init_rex_pool["total_rex"].as().get_amount(); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); - BOOST_REQUIRE_EQUAL( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ); + BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); + BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); + BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); From 017c474112d177f80e42d3b26a2e135b0e32c148 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 6 Nov 2018 21:04:12 -0500 Subject: [PATCH 0622/1048] add proposal_hash as binary_extension to eosio.msig::approve action #87 If the proposal_hash is specified, the approve action will enforce that the specified hash matches the SHA256 hash of the packed_transaction in the referenced proposal. --- CMakeLists.txt | 4 ++-- eosio.msig/include/eosio.msig/eosio.msig.hpp | 3 ++- eosio.msig/src/eosio.msig.cpp | 11 ++++++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c26001e7..be312ed7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts VERSION 1.4.0) -set(EOSIO_CDT_VERSION_MIN "1.3") -set(EOSIO_CDT_VERSION_SOFT_MAX "1.3") +set(EOSIO_CDT_VERSION_MIN "1.4") +set(EOSIO_CDT_VERSION_SOFT_MAX "1.4") #set(EOSIO_CDT_VERSION_HARD_MAX "") find_package(eosio.cdt) diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index 8ba22542..1544f2e0 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -13,7 +13,8 @@ namespace eosio { void propose(ignore proposer, ignore proposal_name, ignore> requested, ignore trx); [[eosio::action]] - void approve( name proposer, name proposal_name, permission_level level ); + void approve( name proposer, name proposal_name, permission_level level, + const eosio::binary_extension& proposal_hash ); [[eosio::action]] void unapprove( name proposer, name proposal_name, permission_level level ); [[eosio::action]] diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index 0c88c56b..d04d5b17 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -1,6 +1,7 @@ #include #include #include +#include namespace eosio { @@ -57,9 +58,17 @@ void multisig::propose( ignore proposer, }); } -void multisig::approve( name proposer, name proposal_name, permission_level level ) { +void multisig::approve( name proposer, name proposal_name, permission_level level, + const eosio::binary_extension& proposal_hash ) +{ require_auth( level ); + if( proposal_hash ) { + proposals proptable( _self, proposer.value ); + auto& prop = proptable.get( proposal_name.value, "proposal not found" ); + assert_sha256( prop.packed_transaction.data(), prop.packed_transaction.size(), *proposal_hash ); + } + approvals apptable( _self, proposer.value ); auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { From 2b533f0e284f89013c8feb49b170d89fecbf7217 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 7 Nov 2018 15:57:19 -0500 Subject: [PATCH 0623/1048] eosio::digest256 renamed to eosio::checksum256 in CDT #87 --- eosio.msig/include/eosio.msig/eosio.msig.hpp | 2 +- eosio.msig/src/eosio.msig.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/eosio.msig/include/eosio.msig/eosio.msig.hpp index 1544f2e0..a8c506e7 100644 --- a/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -14,7 +14,7 @@ namespace eosio { ignore> requested, ignore trx); [[eosio::action]] void approve( name proposer, name proposal_name, permission_level level, - const eosio::binary_extension& proposal_hash ); + const eosio::binary_extension& proposal_hash ); [[eosio::action]] void unapprove( name proposer, name proposal_name, permission_level level ); [[eosio::action]] diff --git a/eosio.msig/src/eosio.msig.cpp b/eosio.msig/src/eosio.msig.cpp index d04d5b17..0b682b6c 100644 --- a/eosio.msig/src/eosio.msig.cpp +++ b/eosio.msig/src/eosio.msig.cpp @@ -59,7 +59,7 @@ void multisig::propose( ignore proposer, } void multisig::approve( name proposer, name proposal_name, permission_level level, - const eosio::binary_extension& proposal_hash ) + const eosio::binary_extension& proposal_hash ) { require_auth( level ); From a3cc6e6e86b1c97e350524a5aea3b3ee1a33d185 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 7 Nov 2018 16:20:14 -0500 Subject: [PATCH 0624/1048] add unit tests for eosio.msig::approve with proposal_hash specified #87 --- tests/eosio.msig_tests.cpp | 86 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index a5e3a830..39b6a5f9 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -861,4 +861,90 @@ BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { + auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx_hash = fc::sha256::hash( trx ); + auto not_trx_hash = fc::sha256::hash( trx_hash ); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + //fail to approve with incorrect hash + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ("proposal_hash", not_trx_hash) + ), + eosio::chain::crypto_api_exception, + fc_exception_message_is("hash mismatch") + ); + + //approve and execute + push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ("proposal_hash", trx_hash) + ); + + transaction_trace_ptr trace; + control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + push_action( N(alice), N(exec), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("executer", "alice") + ); + + BOOST_REQUIRE( bool(trace) ); + BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); + BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( switch_proposal_and_fail_approve_with_hash, eosio_msig_tester ) try { + auto trx1 = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx1_hash = fc::sha256::hash( trx1 ); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx1) + ("requested", vector{{ N(alice), config::active_name }}) + ); + + auto trx2 = reqauth("alice", + { permission_level{N(alice), config::active_name}, + permission_level{N(alice), config::owner_name} }, + abi_serializer_max_time ); + + push_action( N(alice), N(cancel), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("canceler", "alice") + ); + + push_action( N(alice), N(propose), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("trx", trx2) + ("requested", vector{ { N(alice), config::active_name }, + { N(alice), config::owner_name } }) + ); + + //fail to approve with hash meant for old proposal + BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(approve), mvo() + ("proposer", "alice") + ("proposal_name", "first") + ("level", permission_level{ N(alice), config::active_name }) + ("proposal_hash", trx1_hash) + ), + eosio::chain::crypto_api_exception, + fc_exception_message_is("hash mismatch") + ); +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() From 9484eaee7e065e3be2d1e60a3eb2f84395dbf17e Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 7 Nov 2018 19:15:53 -0500 Subject: [PATCH 0625/1048] bump version to 1.5.0 --- CMakeLists.txt | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index be312ed7..58f698dc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.4.0) +project(eosio_contracts VERSION 1.5.0) set(EOSIO_CDT_VERSION_MIN "1.4") set(EOSIO_CDT_VERSION_SOFT_MAX "1.4") diff --git a/README.md b/README.md index 8ff86a9d..0b485d37 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.4.0 +## Version : 1.5.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.3.x](https://github.com/EOSIO/eos/releases/tag/v1.3.2) -* [eosio.cdt v1.3.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.3.0) +* [eosio v1.4.x](https://github.com/EOSIO/eos/releases/tag/v1.4.3) +* [eosio.cdt v1.4.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.4.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From 9d70f413f8e01df27251af7b95bba6980e3c38ea Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 13 Nov 2018 12:24:01 -0500 Subject: [PATCH 0626/1048] Setup a delay on selling purchased REX - 1 --- .../include/eosio.system/eosio.system.hpp | 6 ++ eosio.system/src/rex.cpp | 75 ++++++++++++------- 2 files changed, 56 insertions(+), 25 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 96cc79ce..d1bd8c1e 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace eosiosystem { @@ -202,6 +203,8 @@ namespace eosiosystem { name owner; asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote asset rex_balance; /// the amount of REX owned by owner + int64_t matured_rex = 0; + std::queue> rex_maturities; uint64_t primary_key()const { return owner.value; } }; @@ -524,6 +527,9 @@ namespace eosiosystem { bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end() && rex_available(); } bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } + uint32_t get_rex_maturity()const; + void process_rex_maturities( rex_balance& rb ); + void consolidate_rex_balance( rex_balance& rb ); // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 4ad33010..90753d4e 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -15,7 +15,7 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { owner, active_permission }, { owner, rex_account, amount, "deposit to REX fund" } ); auto itr = _rexfunds.find( owner.value ); - if( itr == _rexfunds.end() ) { + if ( itr == _rexfunds.end() ) { _rexfunds.emplace( owner, [&]( auto& fund ) { fund.owner = owner; fund.balance = amount; @@ -63,7 +63,7 @@ namespace eosiosystem { asset rex_received( 0, rex_symbol ); auto itr = _rexpool.begin(); - if( !rex_system_initialized() ) { + if ( !rex_system_initialized() ) { /// initialize REX pool _rexpool.emplace( _self, [&]( auto& rp ) { rex_received.amount = amount.amount * rex_ratio; @@ -75,7 +75,7 @@ namespace eosiosystem { rp.total_rex = rex_received; rp.namebid_proceeds = asset( 0, core_symbol() ); }); - } else if( !rex_available() ) { /// should be a rare corner case + } else if ( !rex_available() ) { /// should be a rare corner case _rexpool.modify( itr, same_payer, [&]( auto& rp ) { rex_received.amount = amount.amount * rex_ratio; @@ -104,7 +104,7 @@ namespace eosiosystem { auto bitr = _rexbalance.find( from.value ); asset init_rex_stake( 0, core_symbol() ); asset current_rex_stake( 0, core_symbol() ); - if( bitr == _rexbalance.end() ) { + if ( bitr == _rexbalance.end() ) { _rexbalance.emplace( from, [&]( auto& rb ) { rb.owner = from; rb.vote_stake = amount; @@ -139,13 +139,13 @@ namespace eosiosystem { auto current_order = close_rex_order( bitr, rex ); update_rex_account( from, current_order.proceeds, current_order.stake_change ); - if( !current_order.success ) { + if ( !current_order.success ) { /** * REX order couldn't be filled and is added to queue. * If account already has an open order, requested rex is added to existing order. */ auto oitr = _rexorders.find( from.value ); - if( oitr == _rexorders.end() ) { + if ( oitr == _rexorders.end() ) { _rexorders.emplace( from, [&]( auto& order ) { order.owner = from; order.rex_requested = rex; @@ -187,7 +187,7 @@ namespace eosiosystem { auto out = int64_t((I*T0) / (I+F0)); - if( out < 0 ) out = 0; + if ( out < 0 ) out = 0; conin += in; conout -= out; @@ -302,7 +302,7 @@ namespace eosiosystem { require_auth( owner ); - if( rex_system_initialized() ) + if ( rex_system_initialized() ) runrex(2); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); @@ -324,7 +324,7 @@ namespace eosiosystem { /// check for remaining rex balance { auto rex_itr = _rexbalance.find( owner.value ); - if( rex_itr != _rexbalance.end() ) { + if ( rex_itr != _rexbalance.end() ) { eosio_assert( rex_itr->rex_balance.amount == 0, "account has remaining REX, must sell first"); _rexbalance.erase( rex_itr ); } @@ -333,7 +333,7 @@ namespace eosiosystem { /// check for remaining rex fund balance { auto fund_itr =_rexfunds.find( owner.value ); - if( fund_itr != _rexfunds.end() ) { + if ( fund_itr != _rexfunds.end() ) { eosio_assert( fund_itr->balance.amount == 0, "account has remaining funds, must withdraw first"); _rexfunds.erase( fund_itr ); } @@ -378,7 +378,7 @@ namespace eosiosystem { delete_loan = true; delta_stake = -( itr->total_staked.amount ); /// refund "from" account if the closed loan balance is positive - if( itr->balance.amount > 0 ) { + if ( itr->balance.amount > 0 ) { transfer_to_fund( itr->from, itr->balance ); } } @@ -400,13 +400,13 @@ namespace eosiosystem { auto cpu_idx = cpu_loans.get_index<"byexpr"_n>(); for( uint16_t i = 0; i < max; ++i ) { auto itr = cpu_idx.begin(); - if( itr == cpu_idx.end() || itr->expiration > current_time_point() ) break; + if ( itr == cpu_idx.end() || itr->expiration > current_time_point() ) break; auto result = process_expired_loan( cpu_idx, itr ); - if( result.second != 0 ) + if ( result.second != 0 ) update_resource_limits( itr->receiver, result.second, 0 ); - if( result.first ) + if ( result.first ) cpu_idx.erase( itr ); } } @@ -415,15 +415,15 @@ namespace eosiosystem { { rex_net_loan_table net_loans( _self, _self.value ); auto net_idx = net_loans.get_index<"byexpr"_n>(); - for( uint16_t i = 0; i < max; ++i ) { + for ( uint16_t i = 0; i < max; ++i ) { auto itr = net_idx.begin(); if( itr == net_idx.end() || itr->expiration > current_time_point() ) break; auto result = process_expired_loan( net_idx, itr ); - if( result.second != 0 ) + if ( result.second != 0 ) update_resource_limits( itr->receiver, 0, result.second ); - if( result.first ) + if ( result.first ) net_idx.erase( itr ); } } @@ -432,13 +432,13 @@ namespace eosiosystem { { auto idx = _rexorders.get_index<"bytime"_n>(); auto oitr = idx.begin(); - for( uint16_t i = 0; i < max; ++i ) { + for ( uint16_t i = 0; i < max; ++i ) { if( oitr == idx.end() || !oitr->is_open ) break; auto bitr = _rexbalance.find( oitr->owner.value ); // bitr != _rexbalance.end() auto result = close_rex_order( bitr, oitr->rex_requested ); auto next = oitr; ++next; - if( result.success ) { + if ( result.success ) { idx.modify( oitr, same_payer, [&]( auto& order ) { order.proceeds.amount = result.proceeds.amount; order.stake_change.amount = result.stake_change.amount; @@ -504,7 +504,7 @@ namespace eosiosystem { asset stake_change( 0, core_symbol() ); bool success = false; - if( proceeds.amount <= rexitr->total_unlent.amount ) { + if ( proceeds.amount <= rexitr->total_unlent.amount ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; _rexpool.modify( rexitr, same_payer, [&]( auto& rt ) { @@ -575,19 +575,19 @@ namespace eosiosystem { asset to_fund( proceeds ); asset to_stake( delta_stake ); auto itr = _rexorders.find( owner.value ); - if( itr != _rexorders.end() && !itr->is_open ) { + if ( itr != _rexorders.end() && !itr->is_open ) { to_fund.amount += itr->proceeds.amount; to_stake.amount += itr->stake_change.amount; _rexorders.erase( itr ); } - if( to_fund.amount > 0 ) + if ( to_fund.amount > 0 ) transfer_to_fund( owner, to_fund ); - if( to_stake.amount != 0 ) + if ( to_stake.amount != 0 ) update_voting_power( owner, to_stake ); } void system_contract::channel_to_rex( const name& from, const asset& amount ) { - if( rex_available() ) { + if ( rex_available() ) { _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.total_unlent.amount += amount.amount; rp.total_lendable.amount += amount.amount; @@ -599,11 +599,36 @@ namespace eosiosystem { } void system_contract::channel_namebid_to_rex( const int64_t highest_bid ) { - if( rex_available() ) { + if ( rex_available() ) { _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.namebid_proceeds.amount += highest_bid; }); } } + uint32_t system_contract::get_rex_maturity()const { + const uint32_t num_of_slots = 5; + uint32_t now = current_time_point().elapsed.count() / 1000000; + uint32_t r = (now + 1) % seconds_per_day; + return now - r + (num_of_slots + 1) * seconds_per_day; + } + + void system_contract::process_rex_maturities( rex_balance& rb ) { + uint32_t now = current_time_point().elapsed.count() / 1000000; + while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { + rb.matured_rex += rb.rex_maturities.front().second; + rb.rex_maturities.pop(); + } + } + + void system_contract::consolidate_rex_balance( rex_balance& rb ) { + int64_t total = rb.matured_rex; + rb.matured_rex = 0; + while ( !rb.rex_maturities.empty() ) { + total += rb.rex_maturities.front().second; + rb.rex_maturities.pop(); + } + rb.rex_maturities.push( { get_rex_maturity(), total } ); + } + }; /// namespace eosiosystem From ccd1a99a0986e756d7c590d6b7609e021284a5d5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 13 Nov 2018 19:06:08 -0500 Subject: [PATCH 0627/1048] Setup a delay on selling purchased REX - 2 --- .../include/eosio.system/eosio.system.hpp | 14 +- eosio.system/src/rex.cpp | 120 ++++++++++++------ 2 files changed, 92 insertions(+), 42 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index d1bd8c1e..ed6858b4 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -397,6 +397,12 @@ namespace eosiosystem { [[eosio::action]] void rexexec( const name& user, uint16_t max ); + /** + * + */ + [[eosio::action]] + void consolidate( const name& owner ); + /** * Deletes owner records from REX tables and frees used RAM. Owner must have no outstanding loans, * REX balance, or remaining REX fund balance. @@ -513,7 +519,7 @@ namespace eosiosystem { void runrex( uint16_t max ); void update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ); rex_order_outcome close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); - void update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant ); + asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant ); void channel_to_rex( const name& from, const asset& amount ); void channel_namebid_to_rex( const int64_t highest_bid ); template @@ -528,8 +534,10 @@ namespace eosiosystem { bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } uint32_t get_rex_maturity()const; - void process_rex_maturities( rex_balance& rb ); - void consolidate_rex_balance( rex_balance& rb ); + asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); + void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); + void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, + const asset& rex_in_sell_order ); // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 90753d4e..b7a6860e 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -101,28 +101,9 @@ namespace eosiosystem { }); } - auto bitr = _rexbalance.find( from.value ); - asset init_rex_stake( 0, core_symbol() ); - asset current_rex_stake( 0, core_symbol() ); - if ( bitr == _rexbalance.end() ) { - _rexbalance.emplace( from, [&]( auto& rb ) { - rb.owner = from; - rb.vote_stake = amount; - rb.rex_balance = rex_received; - }); - current_rex_stake.amount = amount.amount; - } else { - init_rex_stake.amount = bitr->vote_stake.amount; - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.rex_balance.amount += rex_received.amount; - rb.vote_stake.amount = ( uint128_t(rb.rex_balance.amount) * itr->total_lendable.amount ) / itr->total_rex.amount; - }); - current_rex_stake.amount = bitr->vote_stake.amount; - } - + asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); runrex(2); - - update_rex_account( from, asset( 0, core_symbol() ), current_rex_stake - init_rex_stake ); + update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); } void system_contract::sellrex( const name& from, const asset& rex ) { @@ -134,8 +115,9 @@ namespace eosiosystem { eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); - eosio_assert( bitr->rex_balance.symbol == rex.symbol, "asset symbol must be (4, REX)" ); - eosio_assert( bitr->rex_balance >= rex, "insufficient funds" ); + eosio_assert( rex.symbol == bitr->rex_balance.symbol , "asset symbol must be (4, REX)" ); + process_rex_maturities( bitr ); + eosio_assert( rex.amount <= bitr->matured_rex, "insufficient funds" ); auto current_order = close_rex_order( bitr, rex ); update_rex_account( from, current_order.proceeds, current_order.stake_change ); @@ -157,7 +139,8 @@ namespace eosiosystem { } else { _rexorders.modify( oitr, same_payer, [&]( auto& order ) { order.rex_requested.amount += rex.amount; - eosio_assert( bitr->rex_balance >= order.rex_requested, "insufficient funds for current and scheduled orders"); + eosio_assert( order.rex_requested.amount <= bitr->matured_rex, + "insufficient funds for current and scheduled orders"); }); } } @@ -298,6 +281,17 @@ namespace eosiosystem { runrex( max ); } + void system_contract::consolidate( const name& owner ) { + + require_auth( owner ); + + runrex(2); + + auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); + asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); + consolidate_rex_balance( bitr, rex_in_sell_order ); + } + void system_contract::closerex( const name& owner ) { require_auth( owner ); @@ -515,12 +509,14 @@ namespace eosiosystem { _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { rb.vote_stake.amount = current_stake_value - proceeds.amount; rb.rex_balance.amount -= rex.amount; + rb.matured_rex -= rex.amount; }); stake_change.amount = bitr->vote_stake.amount - init_vote_stake_amount; success = true; } else { proceeds.amount = 0; } + return { success, proceeds, stake_change }; } @@ -571,19 +567,25 @@ namespace eosiosystem { * Additional proceeds and stake change can be passed. * This function is called only by actions pushed by owner, unlike close_rex_order. */ - void system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake ) { + asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake ) { asset to_fund( proceeds ); asset to_stake( delta_stake ); + asset rex_in_sell_order( 0, core_symbol() ); auto itr = _rexorders.find( owner.value ); if ( itr != _rexorders.end() && !itr->is_open ) { to_fund.amount += itr->proceeds.amount; to_stake.amount += itr->stake_change.amount; _rexorders.erase( itr ); + } else if ( itr != _rexorders.end() ) { + rex_in_sell_order.amount = itr->rex_requested.amount; } + if ( to_fund.amount > 0 ) transfer_to_fund( owner, to_fund ); if ( to_stake.amount != 0 ) update_voting_power( owner, to_stake ); + + return rex_in_sell_order; } void system_contract::channel_to_rex( const name& from, const asset& amount ) { @@ -607,28 +609,68 @@ namespace eosiosystem { } uint32_t system_contract::get_rex_maturity()const { - const uint32_t num_of_slots = 5; + const uint32_t num_of_maturity_buckets = 4; uint32_t now = current_time_point().elapsed.count() / 1000000; uint32_t r = (now + 1) % seconds_per_day; - return now - r + (num_of_slots + 1) * seconds_per_day; + return now - r + (num_of_maturity_buckets + 1) * seconds_per_day; } - void system_contract::process_rex_maturities( rex_balance& rb ) { + void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) { uint32_t now = current_time_point().elapsed.count() / 1000000; - while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { - rb.matured_rex += rb.rex_maturities.front().second; - rb.rex_maturities.pop(); - } + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { + rb.matured_rex += rb.rex_maturities.front().second; + rb.rex_maturities.pop(); + } + }); + } + + void system_contract::consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, + const asset& rex_in_sell_order ) + { + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + int64_t total = rb.matured_rex - rex_in_sell_order.amount; + rb.matured_rex = rex_in_sell_order.amount; + while ( !rb.rex_maturities.empty() ) { + total += rb.rex_maturities.front().second; + rb.rex_maturities.pop(); + } + rb.rex_maturities.push( { get_rex_maturity(), total } ); + }); } - void system_contract::consolidate_rex_balance( rex_balance& rb ) { - int64_t total = rb.matured_rex; - rb.matured_rex = 0; - while ( !rb.rex_maturities.empty() ) { - total += rb.rex_maturities.front().second; - rb.rex_maturities.pop(); + asset system_contract::add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ) { + auto bitr = _rexbalance.find( owner.value ); + asset init_rex_stake( 0, core_symbol() ); + asset current_rex_stake( 0, core_symbol() ); + if ( bitr == _rexbalance.end() ) { + bitr = _rexbalance.emplace( owner, [&]( auto& rb ) { + rb.owner = owner; + rb.vote_stake = payment; + rb.rex_balance = rex_received; + }); + current_rex_stake.amount = payment.amount; + } else { + init_rex_stake.amount = bitr->vote_stake.amount; + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + rb.rex_balance.amount += rex_received.amount; + rb.vote_stake.amount = ( uint128_t(rb.rex_balance.amount) * _rexpool.begin()->total_lendable.amount ) + / _rexpool.begin()->total_rex.amount; + }); + current_rex_stake.amount = bitr->vote_stake.amount; } - rb.rex_maturities.push( { get_rex_maturity(), total } ); + + process_rex_maturities( bitr ); + const auto maturity = get_rex_maturity(); + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { + rb.rex_maturities.back().second += rex_received.amount; + } else { + rb.rex_maturities.push( { maturity, rex_received.amount } ); + } + }); + + return current_rex_stake - init_rex_stake; } }; /// namespace eosiosystem From 9ec855ca5dd24716721c5c125121199d788c5dfb Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 14 Nov 2018 19:36:47 -0500 Subject: [PATCH 0628/1048] Setup a delay on selling purchased REX - 3 --- .../include/eosio.system/eosio.system.hpp | 10 +++++---- eosio.system/src/eosio.system.cpp | 5 +++++ eosio.system/src/rex.cpp | 21 ++++++++++--------- tests/eosio.system_tests.cpp | 18 +++++++++++----- 4 files changed, 35 insertions(+), 19 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index ed6858b4..3938b40a 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -12,7 +12,7 @@ #include #include -#include +#include namespace eosiosystem { @@ -24,6 +24,7 @@ namespace eosiosystem { using eosio::const_mem_fun; using eosio::block_timestamp; using eosio::time_point; + using eosio::time_point_sec; using eosio::microseconds; using eosio::datastream; @@ -203,8 +204,8 @@ namespace eosiosystem { name owner; asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote asset rex_balance; /// the amount of REX owned by owner - int64_t matured_rex = 0; - std::queue> rex_maturities; + int64_t matured_rex = 0; /// matured REX available for selling + std::deque> rex_maturities; /// REX daily maturity buckets uint64_t primary_key()const { return owner.value; } }; @@ -509,6 +510,7 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); static time_point current_time_point(); + static time_point_sec current_time_point_sec(); static block_timestamp current_block_time(); symbol core_symbol()const; @@ -533,7 +535,7 @@ namespace eosiosystem { bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end() && rex_available(); } bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } - uint32_t get_rex_maturity()const; + static time_point_sec get_rex_maturity(); asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 2c3fa512..799a4bb3 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -41,6 +41,11 @@ namespace eosiosystem { return ct; } + time_point_sec system_contract::current_time_point_sec() { + const static time_point_sec cts{ current_time_point() }; + return cts; + } + block_timestamp system_contract::current_block_time() { const static block_timestamp cbt{ current_time_point() }; return cbt; diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index b7a6860e..cb887f84 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -608,19 +608,20 @@ namespace eosiosystem { } } - uint32_t system_contract::get_rex_maturity()const { + time_point_sec system_contract::get_rex_maturity() { const uint32_t num_of_maturity_buckets = 4; - uint32_t now = current_time_point().elapsed.count() / 1000000; - uint32_t r = (now + 1) % seconds_per_day; - return now - r + (num_of_maturity_buckets + 1) * seconds_per_day; + static const uint32_t now = current_time_point_sec().utc_seconds; + static const uint32_t r = (current_time_point_sec().utc_seconds + 1) % seconds_per_day; + static const time_point_sec rms{ now - r + (num_of_maturity_buckets + 1) * seconds_per_day }; + return rms; } void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) { - uint32_t now = current_time_point().elapsed.count() / 1000000; + time_point_sec now = current_time_point_sec(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { rb.matured_rex += rb.rex_maturities.front().second; - rb.rex_maturities.pop(); + rb.rex_maturities.pop_front(); } }); } @@ -633,9 +634,9 @@ namespace eosiosystem { rb.matured_rex = rex_in_sell_order.amount; while ( !rb.rex_maturities.empty() ) { total += rb.rex_maturities.front().second; - rb.rex_maturities.pop(); + rb.rex_maturities.pop_front(); } - rb.rex_maturities.push( { get_rex_maturity(), total } ); + rb.rex_maturities.emplace_back( get_rex_maturity(), total ); }); } @@ -661,12 +662,12 @@ namespace eosiosystem { } process_rex_maturities( bitr ); - const auto maturity = get_rex_maturity(); + const time_point_sec maturity = get_rex_maturity(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { rb.rex_maturities.back().second += rex_received.amount; } else { - rb.rex_maturities.push( { maturity, rex_received.amount } ); + rb.rex_maturities.emplace_back( maturity, rex_received.amount ); } }); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 7f843327..c9a37e85 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3421,6 +3421,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); + produce_block( fc::days(6) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first buyrex"), sellrex( carol, asset::from_string("5.0000 REX") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset symbol must be (4, REX)"), sellrex( bob, core_sym::from_string("55.0000") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); @@ -3501,6 +3502,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { // alice tries to sellrex, order gets scheduled then she cancels order BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no sellrex order is scheduled") ); + produce_block( fc::days(6) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); @@ -3575,12 +3577,16 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * init_rex_pool["total_lendable"].as().get_amount() ) / init_rex_pool["total_rex"].as().get_amount(); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); + produce_block( fc::days(5) ); + init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); @@ -3602,7 +3608,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); // wait for 30 days minus 1 hour - produce_block( fc::hours(29*24 + 23) ); + produce_block( fc::hours(19*24 + 23) ); BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("0.0001") ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); @@ -3869,7 +3875,8 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const auto current_rex_pool = get_rex_pool(); const int64_t init_alice_rex_stake = ( init_rex.get_amount() * current_rex_pool["total_lendable"].as().get_amount() ) / current_rex_pool["total_rex"].as().get_amount(); - const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); + produce_block( fc::days(5) ); + const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ); @@ -3887,9 +3894,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { - const asset init_balance = core_sym::from_string("1000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); + const asset init_balance = core_sym::from_string("1000.0000"); + const asset init_net = core_sym::from_string("70.0000"); + const asset init_cpu = core_sym::from_string("90.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; account_name alice = accounts[0], bob = accounts[1]; setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); @@ -3939,6 +3946,7 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( bob ).is_null() ); BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX, must sell first") ); + produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining funds, must withdraw first") ); BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); From e497d28bbd2a2a65f573ca08ec0bb449cc5af4d2 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 16 Nov 2018 19:03:48 -0500 Subject: [PATCH 0629/1048] Setup a delay on selling purchased REX - testing --- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/rex.cpp | 4 +- tests/eosio.system_tester.hpp | 4 + tests/eosio.system_tests.cpp | 134 ++++++++++++++++++++++++++++++ 4 files changed, 141 insertions(+), 3 deletions(-) diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 799a4bb3..9e0a775b 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -324,7 +324,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp (deposit)(withdraw)(buyrex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) - (defcpuloan)(defnetloan)(updaterex)(rexexec)(closerex) + (defcpuloan)(defnetloan)(updaterex)(consolidate)(rexexec)(closerex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index cb887f84..1c3ac551 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -270,8 +270,8 @@ namespace eosiosystem { rb.vote_stake = current_stake; }); - asset delta_stake = current_stake - init_stake; - update_rex_account( owner, asset( 0, core_symbol() ), delta_stake ); + update_rex_account( owner, asset( 0, core_symbol() ), current_stake - init_stake ); + process_rex_maturities( itr ); } void system_contract::rexexec( const name& user, uint16_t max ) { diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index c095d97a..823d35cd 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -403,6 +403,10 @@ class eosio_system_tester : public TESTER { return push_action( name(user), N(rexexec), mvo()("user", user)("max", max) ); } + action_result consolidate( const account_name& owner ) { + return push_action( name(owner), N(consolidate), mvo()("owner", owner) ); + } + action_result closerex( const account_name& owner ) { return push_action( name(owner), N(closerex), mvo()("owner", owner) ); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index c9a37e85..5c6d6c87 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3827,6 +3827,140 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { + + const asset init_balance = core_sym::from_string("1000000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance ); + + const int64_t rex_ratio = 10000; + const symbol rex_sym( SY(4, REX) ); + + { + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("11.5000") ) ); + produce_block( fc::hours(3) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("18.5000") ) ); + produce_block( fc::hours(25) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("25.0000") ) ); + + auto rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 550000 * rex_ratio, rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + sellrex( alice, asset::from_string("115000.0000 REX") ) ); + produce_block( fc::hours( 3*24 + 20) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("300000.0000 REX") ) ); + rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 250000 * rex_ratio, rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + produce_block( fc::hours(23) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + sellrex( alice, asset::from_string("250000.0000 REX") ) ); + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("130000.0000 REX") ) ); + rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + sellrex( alice, asset::from_string("130000.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("120000.0000 REX") ) ); + rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); + } + + { + const asset payment1 = core_sym::from_string("14.8000"); + const asset payment2 = core_sym::from_string("15.2000"); + const asset payment = payment1 + payment2; + const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); + for ( uint8_t i = 0; i < 8; ++i ) { + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment1 ) ); + produce_block( fc::hours(2) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); + produce_block( fc::hours(24) ); + } + + auto rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); + + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); + + produce_block( fc::hours(2) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); + + produce_block( fc::hours(1) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 3 * rex_bucket.get_amount(), rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + sellrex( bob, asset( 2 * rex_bucket.get_amount(), rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket.get_amount(), rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + + produce_block( fc::hours(23) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); + + BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + + produce_block( fc::days(3) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); + produce_block( fc::hours(24 + 20) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + } + + { + const asset payment1 = core_sym::from_string("25.0000"); + const asset payment2 = core_sym::from_string("1.0000"); + const asset rex_bucket1( rex_ratio * payment1.get_amount(), rex_sym ); + const asset rex_bucket2( rex_ratio * payment2.get_amount(), rex_sym ); + const asset tot_rex = rex_bucket1 + rex_bucket2; + + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment1 ) ); + produce_block( fc::days(3) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); + produce_block( fc::days(2) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); + + auto rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( tot_rex.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); + + BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, alice, core_sym::from_string("800000.0000") ) ); + } + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { const asset init_balance = core_sym::from_string("10000.0000"); From e5f9e60cf98b54a8179f091bab0afd765609c209 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 16 Nov 2018 22:26:37 -0500 Subject: [PATCH 0630/1048] Setup a delay on selling purchased REX - more testing --- tests/eosio.system_tests.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 5c6d6c87..8d34d59b 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3939,8 +3939,8 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { } { - const asset payment1 = core_sym::from_string("25.0000"); - const asset payment2 = core_sym::from_string("1.0000"); + const asset payment1 = core_sym::from_string("250000.0000"); + const asset payment2 = core_sym::from_string("10000.0000"); const asset rex_bucket1( rex_ratio * payment1.get_amount(), rex_sym ); const asset rex_bucket2( rex_ratio * payment2.get_amount(), rex_sym ); const asset tot_rex = rex_bucket1 + rex_bucket2; @@ -3952,10 +3952,21 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); auto rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( tot_rex.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, alice, core_sym::from_string("800000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket1.get_amount() - 20, rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), get_rex_order( bob )["rex_requested"].as().get_amount() + 20 ); + BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); + BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() + 20 ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( bob ) ); + BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); } } FC_LOG_AND_RETHROW() From cffcdb6cdeaf64da130ed6622292521f760c6a6c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 19 Nov 2018 18:47:39 -0500 Subject: [PATCH 0631/1048] Allow REX purchase using staked tokens - incomplete --- .../include/eosio.system/eosio.system.hpp | 6 +- eosio.system/src/delegate_bandwidth.cpp | 4 +- eosio.system/src/eosio.system.cpp | 2 +- eosio.system/src/rex.cpp | 149 ++++++++++++------ 4 files changed, 108 insertions(+), 53 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 3938b40a..e7e20697 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -339,6 +339,9 @@ namespace eosiosystem { [[eosio::action]] void buyrex( const name& from, const asset& amount ); + [[eosio::action]] + void unstaketorex( const name& from, const asset& from_cpu, const asset& from_net ); + /** * Converts REX stake back into core tokens at current exchange rate. If order cannot be * processed, it gets queued until there is enough in REX pool to fill order. @@ -537,6 +540,7 @@ namespace eosiosystem { bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } static time_point_sec get_rex_maturity(); asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); + asset add_to_rex_pool( const asset& payment ); void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ); @@ -544,7 +548,7 @@ namespace eosiosystem { // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); - void update_voting_power( const name& voter, const asset& total_update, bool update_votes_flag = true ); + void update_voting_power( const name& voter, const asset& total_update ); // defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index 14885562..f614991b 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -385,7 +385,7 @@ namespace eosiosystem { update_voting_power( from, stake_net_delta + stake_cpu_delta ); } - void system_contract::update_voting_power( const name& voter, const asset& total_update, bool update_votes_flag ) + void system_contract::update_voting_power( const name& voter, const asset& total_update ) { auto voter_itr = _voters.find( voter.value ); if( voter_itr == _voters.end() ) { @@ -405,7 +405,7 @@ namespace eosiosystem { validate_b1_vesting( voter_itr->staked ); } - if( update_votes_flag && ( voter_itr->producers.size() || voter_itr->proxy ) ) { + if( voter_itr->producers.size() || voter_itr->proxy ) { update_votes( voter, voter_itr->proxy, voter_itr->producers, false ); } } diff --git a/eosio.system/src/eosio.system.cpp b/eosio.system/src/eosio.system.cpp index 9e0a775b..6388d61e 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/eosio.system/src/eosio.system.cpp @@ -323,7 +323,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, // eosio.system.cpp (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp - (deposit)(withdraw)(buyrex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) + (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) (defcpuloan)(defnetloan)(updaterex)(consolidate)(rexexec)(closerex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 1c3ac551..be353e56 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -49,59 +49,57 @@ namespace eosiosystem { require_auth( from ); eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); + eosio_assert( amount.amount > 0, "must use positive amount" ); - const int64_t rex_ratio = 10000; - const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() are made available + const asset rex_received = add_to_rex_pool( amount ); + const asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); + runrex(2); + update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); + } + + void system_contract::unstaketorex( const name& from, const asset& from_cpu, const asset& from_net ) + { + require_auth( from ); + + eosio_assert( from_cpu.symbol == core_symbol() && from_net.symbol == core_symbol(), "asset must be core token" ); + eosio_assert( 0 <= from_cpu.amount, "must unstake a positive amount to buy rex" ); + eosio_assert( 0 <= from_net.amount, "must unstake a positive amount to buy rex" ); + eosio_assert( 0 < from_cpu.amount || 0 < from_net.amount, "must unstake a positive amount to buy rex" ); + { auto vitr = _voters.find( from.value ); - eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), + eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), "must vote for proxy or at least 21 producers before buying REX" ); } - transfer_from_fund( from, amount ); - - asset rex_received( 0, rex_symbol ); - - auto itr = _rexpool.begin(); - if ( !rex_system_initialized() ) { - /// initialize REX pool - _rexpool.emplace( _self, [&]( auto& rp ) { - rex_received.amount = amount.amount * rex_ratio; - - rp.total_lendable = amount; - rp.total_lent = asset( 0, core_symbol() ); - rp.total_unlent = rp.total_lendable - rp.total_lent; - rp.total_rent = asset( init_total_rent, core_symbol() ); - rp.total_rex = rex_received; - rp.namebid_proceeds = asset( 0, core_symbol() ); - }); - } else if ( !rex_available() ) { /// should be a rare corner case - _rexpool.modify( itr, same_payer, [&]( auto& rp ) { - rex_received.amount = amount.amount * rex_ratio; - - rp.total_lendable.amount = amount.amount; - rp.total_lent.amount = 0; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - rp.total_rent.amount = init_total_rent; - rp.total_rex.amount = rex_received.amount; + { + user_resources_table resources_table( _self, from.value ); + auto res_itr = resources_table.require_find( from.value, "!!!!!!!!" ); + eosio_assert( from_cpu.amount <= res_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); + eosio_assert( from_net.amount <= res_itr->net_weight.amount, "amount exceeds tokens staked for net"); + resources_table.modify( res_itr, same_payer, [&]( user_resources& res ) { + res.cpu_weight.amount -= from_cpu.amount; + res.net_weight.amount -= from_net.amount; }); - } else { - const auto S0 = itr->total_lendable.amount; - const auto S1 = S0 + amount.amount; - const auto R0 = itr->total_rex.amount; - const auto R1 = (uint128_t(S1) * R0) / S0; - - rex_received.amount = R1 - R0; - _rexpool.modify( itr, same_payer, [&]( auto& rp ) { - rp.total_lendable.amount = S1; - rp.total_rex.amount = R1; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); - }); + if ( res_itr->cpu_weight.amount == 0 && res_itr->net_weight.amount == 0 && res_itr->ram_bytes == 0 ) { + resources_table.erase( res_itr ); + } + } + + { + del_bandwidth_table dbw_table( _self, from.value ); + // TODO: update dbw_table } - asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); + update_resource_limits( from, -from_cpu.amount, -from_net.amount ); + + const asset payment = from_cpu + from_net; + INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { stake_account, active_permission }, + { stake_account, rex_account, payment, "buy REX with staked tokens" } ); + + asset rex_received = add_to_rex_pool( payment ); + asset delta_rex_stake = add_to_rex_balance( from, payment, rex_received ); runrex(2); update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); } @@ -545,7 +543,8 @@ namespace eosiosystem { transfer_to_fund( from, amount ); } - void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { + void system_contract::transfer_from_fund( const name& owner, const asset& amount ) + { auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); eosio_assert( amount <= itr->balance, "insufficient funds"); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { @@ -553,7 +552,8 @@ namespace eosiosystem { }); } - void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { + void system_contract::transfer_to_fund( const name& owner, const asset& amount ) + { auto itr = _rexfunds.require_find( owner.value, "programmer error" ); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { fund.balance.amount += amount.amount; @@ -567,7 +567,8 @@ namespace eosiosystem { * Additional proceeds and stake change can be passed. * This function is called only by actions pushed by owner, unlike close_rex_order. */ - asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake ) { + asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake ) + { asset to_fund( proceeds ); asset to_stake( delta_stake ); asset rex_in_sell_order( 0, core_symbol() ); @@ -588,7 +589,8 @@ namespace eosiosystem { return rex_in_sell_order; } - void system_contract::channel_to_rex( const name& from, const asset& amount ) { + void system_contract::channel_to_rex( const name& from, const asset& amount ) + { if ( rex_available() ) { _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.total_unlent.amount += amount.amount; @@ -600,7 +602,8 @@ namespace eosiosystem { } } - void system_contract::channel_namebid_to_rex( const int64_t highest_bid ) { + void system_contract::channel_namebid_to_rex( const int64_t highest_bid ) + { if ( rex_available() ) { _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.namebid_proceeds.amount += highest_bid; @@ -608,7 +611,8 @@ namespace eosiosystem { } } - time_point_sec system_contract::get_rex_maturity() { + time_point_sec system_contract::get_rex_maturity() + { const uint32_t num_of_maturity_buckets = 4; static const uint32_t now = current_time_point_sec().utc_seconds; static const uint32_t r = (current_time_point_sec().utc_seconds + 1) % seconds_per_day; @@ -640,6 +644,53 @@ namespace eosiosystem { }); } + asset system_contract::add_to_rex_pool( const asset& payment ) + { + const int64_t rex_ratio = 10000; + const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() are made available + asset rex_received( 0, rex_symbol ); + auto itr = _rexpool.begin(); + if ( !rex_system_initialized() ) { + /// initialize REX pool + _rexpool.emplace( _self, [&]( auto& rp ) { + rex_received.amount = payment.amount * rex_ratio; + + rp.total_lendable = payment; + rp.total_lent = asset( 0, core_symbol() ); + rp.total_unlent = rp.total_lendable - rp.total_lent; + rp.total_rent = asset( init_total_rent, core_symbol() ); + rp.total_rex = rex_received; + rp.namebid_proceeds = asset( 0, core_symbol() ); + }); + } else if ( !rex_available() ) { /// should be a rare corner case + _rexpool.modify( itr, same_payer, [&]( auto& rp ) { + rex_received.amount = payment.amount * rex_ratio; + + rp.total_lendable.amount = payment.amount; + rp.total_lent.amount = 0; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + rp.total_rent.amount = init_total_rent; + rp.total_rex.amount = rex_received.amount; + }); + } else { + const auto S0 = itr->total_lendable.amount; + const auto S1 = S0 + payment.amount; + const auto R0 = itr->total_rex.amount; + const auto R1 = (uint128_t(S1) * R0) / S0; + + rex_received.amount = R1 - R0; + + _rexpool.modify( itr, same_payer, [&]( auto& rp ) { + rp.total_lendable.amount = S1; + rp.total_rex.amount = R1; + rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; + eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); + }); + } + + return rex_received; + } + asset system_contract::add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ) { auto bitr = _rexbalance.find( owner.value ); asset init_rex_stake( 0, core_symbol() ); From 99088019a2df3a691f808f048de171a69439ea78 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 19 Nov 2018 23:55:36 -0500 Subject: [PATCH 0632/1048] Allow REX purchase using staked tokens --- .../include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/rex.cpp | 121 ++++++++++-------- 2 files changed, 69 insertions(+), 54 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index e7e20697..381aebd7 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,7 +340,7 @@ namespace eosiosystem { void buyrex( const name& from, const asset& amount ); [[eosio::action]] - void unstaketorex( const name& from, const asset& from_cpu, const asset& from_net ); + void unstaketorex( const name& owner, const name& receiver, const asset& from_cpu, const asset& from_net ); /** * Converts REX stake back into core tokens at current exchange rate. If order cannot be diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index be353e56..d456b3aa 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -6,8 +6,8 @@ namespace eosiosystem { - void system_contract::deposit( const name& owner, const asset& amount ) { - + void system_contract::deposit( const name& owner, const asset& amount ) + { require_auth( owner ); eosio_assert( amount.symbol == core_symbol(), "must deposit core token" ); @@ -29,8 +29,8 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } - void system_contract::withdraw( const name& owner, const asset& amount ) { - + void system_contract::withdraw( const name& owner, const asset& amount ) + { require_auth( owner ); eosio_assert( amount.symbol == core_symbol(), "must withdraw core token" ); @@ -44,8 +44,8 @@ namespace eosiosystem { /** * Transfers SYS tokens from user balance and credits converts them to REX stake. */ - void system_contract::buyrex( const name& from, const asset& amount ) { - + void system_contract::buyrex( const name& from, const asset& amount ) + { require_auth( from ); eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); @@ -57,9 +57,9 @@ namespace eosiosystem { update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); } - void system_contract::unstaketorex( const name& from, const asset& from_cpu, const asset& from_net ) + void system_contract::unstaketorex( const name& owner, const name& receiver, const asset& from_cpu, const asset& from_net ) { - require_auth( from ); + require_auth( owner ); eosio_assert( from_cpu.symbol == core_symbol() && from_net.symbol == core_symbol(), "asset must be core token" ); eosio_assert( 0 <= from_cpu.amount, "must unstake a positive amount to buy rex" ); @@ -67,45 +67,53 @@ namespace eosiosystem { eosio_assert( 0 < from_cpu.amount || 0 < from_net.amount, "must unstake a positive amount to buy rex" ); { - auto vitr = _voters.find( from.value ); + auto vitr = _voters.find( owner.value ); eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), "must vote for proxy or at least 21 producers before buying REX" ); } { - user_resources_table resources_table( _self, from.value ); - auto res_itr = resources_table.require_find( from.value, "!!!!!!!!" ); + user_resources_table resources_table( _self, receiver.value ); + auto res_itr = resources_table.require_find( receiver.value, "account does not exist in resources table" ); eosio_assert( from_cpu.amount <= res_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); eosio_assert( from_net.amount <= res_itr->net_weight.amount, "amount exceeds tokens staked for net"); resources_table.modify( res_itr, same_payer, [&]( user_resources& res ) { res.cpu_weight.amount -= from_cpu.amount; res.net_weight.amount -= from_net.amount; }); - if ( res_itr->cpu_weight.amount == 0 && res_itr->net_weight.amount == 0 && res_itr->ram_bytes == 0 ) { resources_table.erase( res_itr ); } } { - del_bandwidth_table dbw_table( _self, from.value ); - // TODO: update dbw_table + del_bandwidth_table dbw_table( _self, owner.value ); + auto del_itr = dbw_table.require_find( receiver.value, "account does not exist in delegated bandwidth table" ); + eosio_assert( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); + eosio_assert( from_net.amount <= del_itr->net_weight.amount, "amount exceeds tokens staked for net"); + dbw_table.modify( del_itr, same_payer, [&]( delegated_bandwidth& dbw ) { + dbw.cpu_weight.amount -= from_cpu.amount; + dbw.net_weight.amount -= from_net.amount; + }); + if ( del_itr->cpu_weight.amount == 0 && del_itr->net_weight.amount == 0 ) { + dbw_table.erase( del_itr ); + } } - update_resource_limits( from, -from_cpu.amount, -from_net.amount ); + update_resource_limits( receiver, -from_cpu.amount, -from_net.amount ); const asset payment = from_cpu + from_net; INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { stake_account, active_permission }, { stake_account, rex_account, payment, "buy REX with staked tokens" } ); - asset rex_received = add_to_rex_pool( payment ); - asset delta_rex_stake = add_to_rex_balance( from, payment, rex_received ); + const asset rex_received = add_to_rex_pool( payment ); + const asset delta_rex_stake = add_to_rex_balance( owner, payment, rex_received ); runrex(2); - update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); + update_rex_account( owner, asset( 0, core_symbol() ), delta_rex_stake ); } - void system_contract::sellrex( const name& from, const asset& rex ) { - + void system_contract::sellrex( const name& from, const asset& rex ) + { runrex(2); require_auth( from ); @@ -144,8 +152,8 @@ namespace eosiosystem { } } - void system_contract::cnclrexorder( const name& owner ) { - + void system_contract::cnclrexorder( const name& owner ) + { require_auth( owner ); auto itr = _rexorders.require_find( owner.value, "no sellrex order is scheduled" ); @@ -161,7 +169,8 @@ namespace eosiosystem { * @param conin - the input connector balance * @param conout - the output connector balance */ - int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { + int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) + { const double F0 = double(conin); const double T0 = double(conout); const double I = double(in); @@ -176,7 +185,8 @@ namespace eosiosystem { return out; } - void system_contract::update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ) { + void system_contract::update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ) + { user_resources_table totals_tbl( _self, receiver.value ); auto tot_itr = totals_tbl.find( receiver.value ); eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); @@ -196,8 +206,8 @@ namespace eosiosystem { * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. */ - void system_contract::rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { - + void system_contract::rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) + { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); @@ -205,8 +215,8 @@ namespace eosiosystem { update_resource_limits( receiver, rented_tokens, 0 ); } - void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { - + void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) + { require_auth( from ); rex_net_loan_table net_loans( _self, _self.value ); @@ -214,40 +224,40 @@ namespace eosiosystem { update_resource_limits( receiver, 0, rented_tokens ); } - void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) { - + void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) + { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); fund_rex_loan( cpu_loans, from, loan_num, payment ); } - void system_contract::fundnetloan( const name& from, uint64_t loan_num, const asset& payment ) { - + void system_contract::fundnetloan( const name& from, uint64_t loan_num, const asset& payment ) + { require_auth( from ); rex_net_loan_table net_loans( _self, _self.value ); fund_rex_loan( net_loans, from, loan_num, payment ); } - void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) { - + void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) + { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); defund_rex_loan( cpu_loans, from, loan_num, amount ); } - void system_contract::defnetloan( const name& from, uint64_t loan_num, const asset& amount ) { - + void system_contract::defnetloan( const name& from, uint64_t loan_num, const asset& amount ) + { require_auth( from ); rex_net_loan_table net_loans( _self, _self.value ); defund_rex_loan( net_loans, from, loan_num, amount ); } - void system_contract::updaterex( const name& owner ) { - + void system_contract::updaterex( const name& owner ) + { require_auth( owner ); runrex(2); @@ -272,15 +282,15 @@ namespace eosiosystem { process_rex_maturities( itr ); } - void system_contract::rexexec( const name& user, uint16_t max ) { - + void system_contract::rexexec( const name& user, uint16_t max ) + { require_auth( user ); runrex( max ); } - void system_contract::consolidate( const name& owner ) { - + void system_contract::consolidate( const name& owner ) + { require_auth( owner ); runrex(2); @@ -290,8 +300,8 @@ namespace eosiosystem { consolidate_rex_balance( bitr, rex_in_sell_order ); } - void system_contract::closerex( const name& owner ) { - + void system_contract::closerex( const name& owner ) + { require_auth( owner ); if ( rex_system_initialized() ) @@ -335,8 +345,8 @@ namespace eosiosystem { /** * Perform maintenance operations on expired rex */ - void system_contract::runrex( uint16_t max ) { - + void system_contract::runrex( uint16_t max ) + { eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); auto rexi = _rexpool.begin(); @@ -444,8 +454,8 @@ namespace eosiosystem { } template - int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) { - + int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) + { runrex(2); eosio_assert( rex_loans_available(), "rex loans are not currently available" ); @@ -486,7 +496,8 @@ namespace eosiosystem { * function returns success flag, order proceeds, and vote stake change. These are used later to finish * order processing, which includes transfering proceeds and updating user vote weight. */ - rex_order_outcome system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { + rex_order_outcome system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) + { auto rexitr = _rexpool.begin(); const auto S0 = rexitr->total_lendable.amount; const auto R0 = rexitr->total_rex.amount; @@ -519,7 +530,8 @@ namespace eosiosystem { } template - void system_contract::fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ) { + void system_contract::fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ) + { eosio_assert( payment.symbol == core_symbol(), "must use core token" ); transfer_from_fund( from, payment ); auto itr = table.require_find( loan_num, "loan not found" ); @@ -531,7 +543,8 @@ namespace eosiosystem { } template - void system_contract::defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ) { + void system_contract::defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ) + { eosio_assert( amount.symbol == core_symbol(), "must use core token" ); auto itr = table.require_find( loan_num, "loan not found" ); eosio_assert( itr->from == from, "actor has to be loan creator" ); @@ -620,7 +633,8 @@ namespace eosiosystem { return rms; } - void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) { + void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) + { time_point_sec now = current_time_point_sec(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { @@ -691,7 +705,8 @@ namespace eosiosystem { return rex_received; } - asset system_contract::add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ) { + asset system_contract::add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ) + { auto bitr = _rexbalance.find( owner.value ); asset init_rex_stake( 0, core_symbol() ); asset current_rex_stake( 0, core_symbol() ); From b965ab2e533d083e5ef6f2492967925040e0cb98 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 20 Nov 2018 18:32:54 -0500 Subject: [PATCH 0633/1048] Testing REX purchase with staked tokens - 1 --- .../include/eosio.system/eosio.system.hpp | 4 +- eosio.system/src/rex.cpp | 23 ++++++----- tests/eosio.system_tester.hpp | 9 +++++ tests/eosio.system_tests.cpp | 39 +++++++++++++++++++ 4 files changed, 63 insertions(+), 12 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 381aebd7..64d38d94 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,7 +340,7 @@ namespace eosiosystem { void buyrex( const name& from, const asset& amount ); [[eosio::action]] - void unstaketorex( const name& owner, const name& receiver, const asset& from_cpu, const asset& from_net ); + void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); /** * Converts REX stake back into core tokens at current exchange rate. If order cannot be @@ -524,7 +524,7 @@ namespace eosiosystem { void runrex( uint16_t max ); void update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ); rex_order_outcome close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); - asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant ); + asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); void channel_to_rex( const name& from, const asset& amount ); void channel_namebid_to_rex( const int64_t highest_bid ); template diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index d456b3aa..b11d4a83 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -11,6 +11,7 @@ namespace eosiosystem { require_auth( owner ); eosio_assert( amount.symbol == core_symbol(), "must deposit core token" ); + eosio_assert( 0 < amount.amount, "must deposit a positive amount" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { owner, active_permission }, { owner, rex_account, amount, "deposit to REX fund" } ); @@ -34,6 +35,7 @@ namespace eosiosystem { require_auth( owner ); eosio_assert( amount.symbol == core_symbol(), "must withdraw core token" ); + eosio_assert( 0 < amount.amount, "must withdraw a positive amount" ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( owner, amount ); @@ -50,14 +52,15 @@ namespace eosiosystem { eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); eosio_assert( amount.amount > 0, "must use positive amount" ); - + + transfer_from_fund( from, amount ); const asset rex_received = add_to_rex_pool( amount ); const asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); runrex(2); update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); } - void system_contract::unstaketorex( const name& owner, const name& receiver, const asset& from_cpu, const asset& from_net ) + void system_contract::unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ) { require_auth( owner ); @@ -106,10 +109,10 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { stake_account, active_permission }, { stake_account, rex_account, payment, "buy REX with staked tokens" } ); - const asset rex_received = add_to_rex_pool( payment ); - const asset delta_rex_stake = add_to_rex_balance( owner, payment, rex_received ); + const asset rex_received = add_to_rex_pool( payment ); + add_to_rex_balance( owner, payment, rex_received ); runrex(2); - update_rex_account( owner, asset( 0, core_symbol() ), delta_rex_stake ); + update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ), true ); } void system_contract::sellrex( const name& from, const asset& rex ) @@ -458,7 +461,7 @@ namespace eosiosystem { { runrex(2); - eosio_assert( rex_loans_available(), "rex loans are not currently available" ); + eosio_assert( rex_loans_available(), "rex loans are not currently available" ); eosio_assert( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); @@ -577,10 +580,10 @@ namespace eosiosystem { * update_rex_account checks if user has a scheduled sellrex order that has been closed, completes its processing, * and deletes it. * Processing entails transfering proceeds to user REX fund and updating user vote weight. - * Additional proceeds and stake change can be passed. + * Additional proceeds and stake change can be passed as arguments. * This function is called only by actions pushed by owner, unlike close_rex_order. */ - asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake ) + asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake, bool force_vote_update ) { asset to_fund( proceeds ); asset to_stake( delta_stake ); @@ -590,13 +593,13 @@ namespace eosiosystem { to_fund.amount += itr->proceeds.amount; to_stake.amount += itr->stake_change.amount; _rexorders.erase( itr ); - } else if ( itr != _rexorders.end() ) { + } else if ( itr != _rexorders.end() ) { // itr->is_open is satisfied rex_in_sell_order.amount = itr->rex_requested.amount; } if ( to_fund.amount > 0 ) transfer_to_fund( owner, to_fund ); - if ( to_stake.amount != 0 ) + if ( force_vote_update || to_stake.amount != 0 ) update_voting_power( owner, to_stake ); return rex_in_sell_order; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 823d35cd..2cd81815 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -333,6 +333,15 @@ class eosio_system_tester : public TESTER { ); } + action_result unstaketorex( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { + return push_action( name(owner), N(unstaketorex), mvo() + ("owner", owner) + ("receiver", receiver) + ("from_net", from_net) + ("from_cpu", from_cpu) + ); + } + action_result sellrex( const account_name& from, const asset& rex ) { return push_action( name(from), N(sellrex), mvo() ("from", from) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 8d34d59b..565ce75b 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3443,6 +3443,45 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester ) try { + + auto get_net_limit = [&](account_name a) -> int64_t { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return net; + }; + auto get_cpu_limit = [&](account_name a) -> int64_t { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return cpu; + }; + + const int64_t ratio = 10000; + const asset init_balance = core_sym::from_string("10000.0000"); + const asset init_net = core_sym::from_string("70.0000"); + const asset init_cpu = core_sym::from_string("90.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); + + const int64_t init_cpu_limit = get_cpu_limit( alice ); + const int64_t init_net_limit = get_net_limit( alice ); + + const asset net_stake = core_sym::from_string("25.5000"); + const asset cpu_stake = core_sym::from_string("12.4000"); + const asset tot_stake = net_stake + cpu_stake; + BOOST_REQUIRE_EQUAL( init_balance, get_balance( alice ) ); + BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit + cpu_stake.get_amount() ); + BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); + BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); + BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; From 61d593602364ba67d93b34cab18760681763d2b9 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 21 Nov 2018 09:55:50 -0500 Subject: [PATCH 0634/1048] Testing REX purchase with staked tokens - 2 --- eosio.system/src/rex.cpp | 14 -------------- tests/eosio.system_tests.cpp | 32 +++++++++++++++++++------------- 2 files changed, 19 insertions(+), 27 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index b11d4a83..c097f27e 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -75,20 +75,6 @@ namespace eosiosystem { "must vote for proxy or at least 21 producers before buying REX" ); } - { - user_resources_table resources_table( _self, receiver.value ); - auto res_itr = resources_table.require_find( receiver.value, "account does not exist in resources table" ); - eosio_assert( from_cpu.amount <= res_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); - eosio_assert( from_net.amount <= res_itr->net_weight.amount, "amount exceeds tokens staked for net"); - resources_table.modify( res_itr, same_payer, [&]( user_resources& res ) { - res.cpu_weight.amount -= from_cpu.amount; - res.net_weight.amount -= from_net.amount; - }); - if ( res_itr->cpu_weight.amount == 0 && res_itr->net_weight.amount == 0 && res_itr->ram_bytes == 0 ) { - resources_table.erase( res_itr ); - } - } - { del_bandwidth_table dbw_table( _self, owner.value ); auto del_itr = dbw_table.require_find( receiver.value, "account does not exist in delegated bandwidth table" ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 565ce75b..14b52c0a 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3460,24 +3460,30 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester ) try { const asset init_balance = core_sym::from_string("10000.0000"); const asset init_net = core_sym::from_string("70.0000"); const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); const int64_t init_cpu_limit = get_cpu_limit( alice ); const int64_t init_net_limit = get_net_limit( alice ); - const asset net_stake = core_sym::from_string("25.5000"); - const asset cpu_stake = core_sym::from_string("12.4000"); - const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( init_balance, get_balance( alice ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit + cpu_stake.get_amount() ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); + { + const asset net_stake = core_sym::from_string("25.5000"); + const asset cpu_stake = core_sym::from_string("12.4000"); + const asset tot_stake = net_stake + cpu_stake; + BOOST_REQUIRE_EQUAL( init_balance, get_balance( alice ) ); + BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit + cpu_stake.get_amount() ); + BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); + const asset init_eosio_stake_balance = get_balance( N(eosio.stake) ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); + BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); + BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( tot_stake, get_rex_balance_obj( alice )["vote_stake"].as() ); + BOOST_REQUIRE_EQUAL( tot_stake, get_balance( N(eosio.rex) ) ); + BOOST_REQUIRE_EQUAL( tot_stake, init_eosio_stake_balance - get_balance( N(eosio.stake) ) ); + } } FC_LOG_AND_RETHROW() From 660f58ace618c14527a5c0315f34155691b4916f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 21 Nov 2018 12:42:02 -0500 Subject: [PATCH 0635/1048] Changes to REX update_resource_limits --- .../include/eosio.system/eosio.system.hpp | 2 +- eosio.system/src/rex.cpp | 111 ++++++++++-------- 2 files changed, 66 insertions(+), 47 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 64d38d94..37a4bc2f 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -522,7 +522,7 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); - void update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ); + void update_resource_limits( const name& from, const name& receiver, int64_t delta_cpu, int64_t delta_net ); rex_order_outcome close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); void channel_to_rex( const name& from, const asset& amount ); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index c097f27e..523ea3d9 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -89,7 +89,7 @@ namespace eosiosystem { } } - update_resource_limits( receiver, -from_cpu.amount, -from_net.amount ); + update_resource_limits( name(0), receiver, -from_cpu.amount, -from_net.amount ); const asset payment = from_cpu + from_net; INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { stake_account, active_permission }, @@ -150,47 +150,6 @@ namespace eosiosystem { _rexorders.erase( itr ); } - /** - * Given two connector balances (conin, and conout), and an incoming amount of - * in, this function will modify conin and conout and return the delta out. - * - * @param in - same units as conin - * @param conin - the input connector balance - * @param conout - the output connector balance - */ - int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) - { - const double F0 = double(conin); - const double T0 = double(conout); - const double I = double(in); - - auto out = int64_t((I*T0) / (I+F0)); - - if ( out < 0 ) out = 0; - - conin += in; - conout -= out; - - return out; - } - - void system_contract::update_resource_limits( const name& receiver, int64_t delta_cpu, int64_t delta_net ) - { - user_resources_table totals_tbl( _self, receiver.value ); - auto tot_itr = totals_tbl.find( receiver.value ); - eosio_assert( tot_itr != totals_tbl.end(), "expected to find resource table" ); - totals_tbl.modify( tot_itr, same_payer, [&]( auto& tot ) { - tot.cpu_weight.amount += delta_cpu; - tot.net_weight.amount += delta_net; - }); - eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); - eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); - - int64_t ram_bytes, net, cpu; - get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); - set_resource_limits( receiver.value, ram_bytes, tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - } - /** * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, * after 30 days the rented SYS delegation of CPU or NET will expire. @@ -201,7 +160,7 @@ namespace eosiosystem { rex_cpu_loan_table cpu_loans( _self, _self.value ); int64_t rented_tokens = rent_rex( cpu_loans, from, receiver, loan_payment, loan_fund ); - update_resource_limits( receiver, rented_tokens, 0 ); + update_resource_limits( from, receiver, rented_tokens, 0 ); } void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) @@ -210,7 +169,7 @@ namespace eosiosystem { rex_net_loan_table net_loans( _self, _self.value ); int64_t rented_tokens = rent_rex( net_loans, from, receiver, loan_payment, loan_fund ); - update_resource_limits( receiver, 0, rented_tokens ); + update_resource_limits( from, receiver, 0, rented_tokens ); } void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) @@ -331,6 +290,66 @@ namespace eosiosystem { } } + /** + * Given two connector balances (conin, and conout), and an incoming amount of + * in, this function will modify conin and conout and return the delta out. + * + * @param in - same units as conin + * @param conin - the input connector balance + * @param conout - the output connector balance + */ + int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) + { + const double F0 = double(conin); + const double T0 = double(conout); + const double I = double(in); + + auto out = int64_t((I*T0) / (I+F0)); + + if ( out < 0 ) out = 0; + + conin += in; + conout -= out; + + return out; + } + + void system_contract::update_resource_limits( const name& from, const name& receiver, int64_t delta_cpu, int64_t delta_net ) + { + if ( delta_cpu == 0 && delta_net == 0 ) { // nothing to update + return; + } + + { + user_resources_table totals_tbl( _self, receiver.value ); + auto tot_itr = totals_tbl.find( receiver.value ); + if ( tot_itr == totals_tbl.end() ) { + eosio_assert( 0 <= delta_cpu && 0 <= delta_net, "logic error, should not occur"); + eosio_assert( 0 < delta_cpu || 0 < delta_net, ""); + tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { + tot.owner = receiver; + tot.cpu_weight = asset( delta_cpu, core_symbol() ); + tot.net_weight = asset( delta_net, core_symbol() ); + }); + } else { + totals_tbl.modify( tot_itr, same_payer, [&]( auto& tot ) { + tot.cpu_weight.amount += delta_cpu; + tot.net_weight.amount += delta_net; + }); + } + eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); + eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); + + if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) { + totals_tbl.erase( tot_itr ); + } + } + + int64_t ram_bytes, net, cpu; + get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); + set_resource_limits( receiver.value, ram_bytes, net + delta_net, cpu + delta_cpu ); + } + /** * Perform maintenance operations on expired rex */ @@ -395,7 +414,7 @@ namespace eosiosystem { auto result = process_expired_loan( cpu_idx, itr ); if ( result.second != 0 ) - update_resource_limits( itr->receiver, result.second, 0 ); + update_resource_limits( itr->from, itr->receiver, result.second, 0 ); if ( result.first ) cpu_idx.erase( itr ); @@ -412,7 +431,7 @@ namespace eosiosystem { auto result = process_expired_loan( net_idx, itr ); if ( result.second != 0 ) - update_resource_limits( itr->receiver, 0, result.second ); + update_resource_limits( itr->from, itr->receiver, 0, result.second ); if ( result.first ) net_idx.erase( itr ); From 2d1bde11331c96df84ef2da8d4ae95cfa958a45b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 21 Nov 2018 23:10:21 -0500 Subject: [PATCH 0636/1048] Testing REX purchase with staked tokens - 3 --- eosio.system/src/rex.cpp | 8 +-- tests/eosio.system_tests.cpp | 104 ++++++++++++++++++++++++++++++----- 2 files changed, 93 insertions(+), 19 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 523ea3d9..c3f5e14a 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -77,7 +77,7 @@ namespace eosiosystem { { del_bandwidth_table dbw_table( _self, owner.value ); - auto del_itr = dbw_table.require_find( receiver.value, "account does not exist in delegated bandwidth table" ); + auto del_itr = dbw_table.require_find( receiver.value, "delegated bandwidth record does not exist" ); eosio_assert( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); eosio_assert( from_net.amount <= del_itr->net_weight.amount, "amount exceeds tokens staked for net"); dbw_table.modify( del_itr, same_payer, [&]( delegated_bandwidth& dbw ) { @@ -238,7 +238,7 @@ namespace eosiosystem { } void system_contract::consolidate( const name& owner ) - { + { require_auth( owner ); runrex(2); @@ -598,7 +598,7 @@ namespace eosiosystem { to_fund.amount += itr->proceeds.amount; to_stake.amount += itr->stake_change.amount; _rexorders.erase( itr ); - } else if ( itr != _rexorders.end() ) { // itr->is_open is satisfied + } else if ( itr != _rexorders.end() ) { // itr->is_open is true rex_in_sell_order.amount = itr->rex_requested.amount; } @@ -619,7 +619,7 @@ namespace eosiosystem { }); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { from, active_permission }, - { from, rex_account, amount, std::string("transfer from ") + name{from}.to_string() + " REX"} ); + { from, rex_account, amount, std::string("transfer from ") + name{from}.to_string() + " to eosio.rex"} ); } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 14b52c0a..a966ed25 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3443,7 +3443,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester ) try { +BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { auto get_net_limit = [&](account_name a) -> int64_t { int64_t ram_bytes = 0, net = 0, cpu = 0; @@ -3457,13 +3457,32 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester ) try { }; const int64_t ratio = 10000; + const asset zero_asset = core_sym::from_string("0.0000"); + const asset neg_asset = core_sym::from_string("-0.0001"); + const asset one_token = core_sym::from_string("1.0000"); const asset init_balance = core_sym::from_string("10000.0000"); const asset init_net = core_sym::from_string("70.0000"); const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'z'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + + setup_producer_accounts(producer_names); + for ( const auto& p: producer_names ) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); + } + } + const int64_t init_cpu_limit = get_cpu_limit( alice ); const int64_t init_net_limit = get_net_limit( alice ); @@ -3471,19 +3490,74 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester ) try { const asset net_stake = core_sym::from_string("25.5000"); const asset cpu_stake = core_sym::from_string("12.4000"); const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( init_balance, get_balance( alice ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit + cpu_stake.get_amount() ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); + BOOST_REQUIRE_EQUAL( init_balance, get_balance( alice ) ); + BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit + cpu_stake.get_amount() ); + BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); + BOOST_REQUIRE_EQUAL( success(), + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for proxy or at least 21 producers before buying REX"), + unstaketorex( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( success(), + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); const asset init_eosio_stake_balance = get_balance( N(eosio.stake) ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( tot_stake, get_rex_balance_obj( alice )["vote_stake"].as() ); - BOOST_REQUIRE_EQUAL( tot_stake, get_balance( N(eosio.rex) ) ); - BOOST_REQUIRE_EQUAL( tot_stake, init_eosio_stake_balance - get_balance( N(eosio.stake) ) ); - } + const auto init_voter_info = get_voter_info( alice ); + const auto init_prod_info = get_producer_info( producer_names[0] ); + BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() == + stake2votes( asset( init_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); + produce_block( fc::days(4) ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); + BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); + BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( tot_stake, get_rex_balance_obj( alice )["vote_stake"].as() ); + BOOST_REQUIRE_EQUAL( tot_stake, get_balance( N(eosio.rex) ) ); + BOOST_REQUIRE_EQUAL( tot_stake, init_eosio_stake_balance - get_balance( N(eosio.stake) ) ); + auto current_voter_info = get_voter_info( alice ); + auto current_prod_info = get_producer_info( producer_names[0] ); + BOOST_REQUIRE_EQUAL( init_voter_info["staked"].as(), current_voter_info["staked"].as() ); + BOOST_TEST_REQUIRE( current_prod_info["total_votes"].as_double() == + stake2votes( asset( current_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); + BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() < current_prod_info["total_votes"].as_double() ); + } + + { + const asset net_stake = core_sym::from_string("200.5000"); + const asset cpu_stake = core_sym::from_string("120.0000"); + const asset tot_stake = net_stake + cpu_stake; + BOOST_REQUIRE_EQUAL( success(), stake( bob, carol, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("amount exceeds tokens staked for net"), + unstaketorex( bob, carol, net_stake + one_token, zero_asset ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("amount exceeds tokens staked for cpu"), + unstaketorex( bob, carol, zero_asset, cpu_stake + one_token ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), + unstaketorex( bob, emily, zero_asset, one_token ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), + unstaketorex( bob, carol, zero_asset, zero_asset ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), + unstaketorex( bob, carol, neg_asset, one_token ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), + unstaketorex( bob, carol, one_token, neg_asset ) ); + BOOST_REQUIRE_EQUAL( init_net_limit + net_stake.get_amount(), get_net_limit( carol ) ); + BOOST_REQUIRE_EQUAL( init_cpu_limit + cpu_stake.get_amount(), get_cpu_limit( carol ) ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance( carol ).get_amount() ); + BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( bob ).get_amount() ); + BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( bob ) ); + BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( bob ) ); + BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); + BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); + } + + { + const asset net_stake = core_sym::from_string("130.5000"); + const asset cpu_stake = core_sym::from_string("220.0800"); + const asset tot_stake = net_stake + cpu_stake; + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( emily, frank, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), + unstaketorex( emily, frank, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( frank, frank, net_stake, cpu_stake ) ); + } } FC_LOG_AND_RETHROW() From ad244179833434867e06146d14e9d045161ef9ae Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 22 Nov 2018 16:58:05 -0500 Subject: [PATCH 0637/1048] Testing REX purchase with staked tokens - 4 --- eosio.system/src/rex.cpp | 19 ++++++++++++++----- tests/eosio.system_tests.cpp | 3 +++ 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index c3f5e14a..2dc633d1 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -566,6 +566,7 @@ namespace eosiosystem { void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { + eosio_assert( 0 < amount.amount, "must transfer positive amount from REX fund" ); auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); eosio_assert( amount <= itr->balance, "insufficient funds"); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { @@ -575,10 +576,18 @@ namespace eosiosystem { void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { - auto itr = _rexfunds.require_find( owner.value, "programmer error" ); - _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { - fund.balance.amount += amount.amount; - }); + eosio_assert( 0 < amount.amount, "must transfer positive amount to REX fund" ); + auto itr = _rexfunds.find( owner.value ); + if ( itr == _rexfunds.end() ) { + _rexfunds.emplace( owner, [&]( auto& fund ) { + fund.owner = owner; + fund.balance = amount; + }); + } else { + _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { + fund.balance.amount += amount.amount; + }); + } } /** @@ -684,7 +693,7 @@ namespace eosiosystem { rp.total_rex = rex_received; rp.namebid_proceeds = asset( 0, core_symbol() ); }); - } else if ( !rex_available() ) { /// should be a rare corner case + } else if ( !rex_available() ) { /// should be a rare corner case, REX pool initialized but empty _rexpool.modify( itr, same_payer, [&]( auto& rp ) { rex_received.amount = payment.amount * rex_ratio; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index a966ed25..0b6e719b 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3557,6 +3557,9 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), unstaketorex( emily, frank, net_stake, cpu_stake ) ); BOOST_REQUIRE_EQUAL( success(), unstaketorex( frank, frank, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), sellrex( frank, asset::from_string("1.0000 REX") ) ); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( frank, asset::from_string("1.0000 REX") ) ); } } FC_LOG_AND_RETHROW() From 9c97e1e92a1de218cce928558d5e144d854bd171 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 22 Nov 2018 18:22:56 -0500 Subject: [PATCH 0638/1048] Code cleaning --- eosio.system/src/delegate_bandwidth.cpp | 9 ++++++--- eosio.system/src/rex.cpp | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/eosio.system/src/delegate_bandwidth.cpp b/eosio.system/src/delegate_bandwidth.cpp index f614991b..2fd293a6 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/eosio.system/src/delegate_bandwidth.cpp @@ -37,6 +37,7 @@ namespace eosiosystem { asset cpu_weight; int64_t ram_bytes = 0; + bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0 && ram_bytes == 0; } uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -53,6 +54,7 @@ namespace eosiosystem { asset net_weight; asset cpu_weight; + bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0; } uint64_t primary_key()const { return to.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -66,6 +68,7 @@ namespace eosiosystem { eosio::asset net_amount; eosio::asset cpu_amount; + bool is_empty()const { return net_amount.amount == 0 && cpu_amount.amount == 0; } uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -258,7 +261,7 @@ namespace eosiosystem { } eosio_assert( 0 <= itr->net_weight.amount, "insufficient staked net bandwidth" ); eosio_assert( 0 <= itr->cpu_weight.amount, "insufficient staked cpu bandwidth" ); - if ( itr->net_weight.amount == 0 && itr->cpu_weight.amount == 0 ) { + if ( itr->is_empty() ) { del_tbl.erase( itr ); } } // itr can be invalid, should go out of scope @@ -287,7 +290,7 @@ namespace eosiosystem { set_resource_limits( receiver.value, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) { + if ( tot_itr->is_empty() ) { totals_tbl.erase( tot_itr ); } } // tot_itr can be invalid, should go out of scope @@ -333,7 +336,7 @@ namespace eosiosystem { eosio_assert( 0 <= req->net_amount.amount, "negative net refund amount" ); //should never happen eosio_assert( 0 <= req->cpu_amount.amount, "negative cpu refund amount" ); //should never happen - if ( req->net_amount.amount == 0 && req->cpu_amount.amount == 0 ) { + if ( req->is_empty() ) { refunds_tbl.erase( req ); need_deferred_trx = false; } else { diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 2dc633d1..6288a967 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -84,7 +84,7 @@ namespace eosiosystem { dbw.cpu_weight.amount -= from_cpu.amount; dbw.net_weight.amount -= from_net.amount; }); - if ( del_itr->cpu_weight.amount == 0 && del_itr->net_weight.amount == 0 ) { + if ( del_itr->is_empty() ) { dbw_table.erase( del_itr ); } } @@ -340,7 +340,7 @@ namespace eosiosystem { eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); - if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) { + if ( tot_itr->is_empty() ) { totals_tbl.erase( tot_itr ); } } From 9ff7e2331958372aa75dd152acdb8ca61c7f82e4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 26 Nov 2018 14:03:05 -0500 Subject: [PATCH 0639/1048] Small changes --- .../include/eosio.system/eosio.system.hpp | 4 +- eosio.system/src/rex.cpp | 70 +++++++++---------- 2 files changed, 37 insertions(+), 37 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 37a4bc2f..c3649598 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -522,8 +522,8 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); - void update_resource_limits( const name& from, const name& receiver, int64_t delta_cpu, int64_t delta_net ); - rex_order_outcome close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); + rex_order_outcome fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); void channel_to_rex( const name& from, const asset& amount ); void channel_namebid_to_rex( const int64_t highest_bid ); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 6288a967..56190b8b 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -64,10 +64,10 @@ namespace eosiosystem { { require_auth( owner ); - eosio_assert( from_cpu.symbol == core_symbol() && from_net.symbol == core_symbol(), "asset must be core token" ); - eosio_assert( 0 <= from_cpu.amount, "must unstake a positive amount to buy rex" ); + eosio_assert( from_net.symbol == core_symbol() && from_cpu.symbol == core_symbol(), "asset must be core token" ); eosio_assert( 0 <= from_net.amount, "must unstake a positive amount to buy rex" ); - eosio_assert( 0 < from_cpu.amount || 0 < from_net.amount, "must unstake a positive amount to buy rex" ); + eosio_assert( 0 <= from_cpu.amount, "must unstake a positive amount to buy rex" ); + eosio_assert( 0 < from_net.amount || 0 < from_cpu.amount, "must unstake a positive amount to buy rex" ); { auto vitr = _voters.find( owner.value ); @@ -78,20 +78,20 @@ namespace eosiosystem { { del_bandwidth_table dbw_table( _self, owner.value ); auto del_itr = dbw_table.require_find( receiver.value, "delegated bandwidth record does not exist" ); - eosio_assert( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); eosio_assert( from_net.amount <= del_itr->net_weight.amount, "amount exceeds tokens staked for net"); + eosio_assert( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); dbw_table.modify( del_itr, same_payer, [&]( delegated_bandwidth& dbw ) { - dbw.cpu_weight.amount -= from_cpu.amount; dbw.net_weight.amount -= from_net.amount; + dbw.cpu_weight.amount -= from_cpu.amount; }); if ( del_itr->is_empty() ) { dbw_table.erase( del_itr ); } } - update_resource_limits( name(0), receiver, -from_cpu.amount, -from_net.amount ); + update_resource_limits( name(0), receiver, -from_net.amount, -from_cpu.amount ); - const asset payment = from_cpu + from_net; + const asset payment = from_net + from_cpu; INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { stake_account, active_permission }, { stake_account, rex_account, payment, "buy REX with staked tokens" } ); @@ -114,7 +114,7 @@ namespace eosiosystem { process_rex_maturities( bitr ); eosio_assert( rex.amount <= bitr->matured_rex, "insufficient funds" ); - auto current_order = close_rex_order( bitr, rex ); + auto current_order = fill_rex_order( bitr, rex ); update_rex_account( from, current_order.proceeds, current_order.stake_change ); if ( !current_order.success ) { /** @@ -146,7 +146,7 @@ namespace eosiosystem { require_auth( owner ); auto itr = _rexorders.require_find( owner.value, "no sellrex order is scheduled" ); - eosio_assert( itr->is_open, "sellrex order has been closed and cannot be canceled" ); + eosio_assert( itr->is_open, "sellrex order has been filled and cannot be canceled" ); _rexorders.erase( itr ); } @@ -160,7 +160,7 @@ namespace eosiosystem { rex_cpu_loan_table cpu_loans( _self, _self.value ); int64_t rented_tokens = rent_rex( cpu_loans, from, receiver, loan_payment, loan_fund ); - update_resource_limits( from, receiver, rented_tokens, 0 ); + update_resource_limits( from, receiver, 0, rented_tokens ); } void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) @@ -169,7 +169,7 @@ namespace eosiosystem { rex_net_loan_table net_loans( _self, _self.value ); int64_t rented_tokens = rent_rex( net_loans, from, receiver, loan_payment, loan_fund ); - update_resource_limits( from, receiver, 0, rented_tokens ); + update_resource_limits( from, receiver, rented_tokens, 0 ); } void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) @@ -314,7 +314,7 @@ namespace eosiosystem { return out; } - void system_contract::update_resource_limits( const name& from, const name& receiver, int64_t delta_cpu, int64_t delta_net ) + void system_contract::update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ) { if ( delta_cpu == 0 && delta_net == 0 ) { // nothing to update return; @@ -324,17 +324,16 @@ namespace eosiosystem { user_resources_table totals_tbl( _self, receiver.value ); auto tot_itr = totals_tbl.find( receiver.value ); if ( tot_itr == totals_tbl.end() ) { - eosio_assert( 0 <= delta_cpu && 0 <= delta_net, "logic error, should not occur"); - eosio_assert( 0 < delta_cpu || 0 < delta_net, ""); + eosio_assert( 0 <= delta_net && 0 <= delta_cpu, "logic error, should not occur"); tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { - tot.owner = receiver; - tot.cpu_weight = asset( delta_cpu, core_symbol() ); + tot.owner = receiver; tot.net_weight = asset( delta_net, core_symbol() ); + tot.cpu_weight = asset( delta_cpu, core_symbol() ); }); } else { totals_tbl.modify( tot_itr, same_payer, [&]( auto& tot ) { - tot.cpu_weight.amount += delta_cpu; tot.net_weight.amount += delta_net; + tot.cpu_weight.amount += delta_cpu; }); } eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); @@ -345,7 +344,7 @@ namespace eosiosystem { } } - int64_t ram_bytes, net, cpu; + int64_t ram_bytes = 0, net = 0, cpu = 0; get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); set_resource_limits( receiver.value, ram_bytes, net + delta_net, cpu + delta_cpu ); } @@ -393,7 +392,7 @@ namespace eosiosystem { } } - return std::make_pair( delete_loan, delta_stake ); + return { delete_loan, delta_stake }; }; /// transfer from eosio.names to eosio.rex @@ -414,7 +413,7 @@ namespace eosiosystem { auto result = process_expired_loan( cpu_idx, itr ); if ( result.second != 0 ) - update_resource_limits( itr->from, itr->receiver, result.second, 0 ); + update_resource_limits( itr->from, itr->receiver, 0, result.second ); if ( result.first ) cpu_idx.erase( itr ); @@ -431,7 +430,7 @@ namespace eosiosystem { auto result = process_expired_loan( net_idx, itr ); if ( result.second != 0 ) - update_resource_limits( itr->from, itr->receiver, 0, result.second ); + update_resource_limits( itr->from, itr->receiver, result.second, 0 ); if ( result.first ) net_idx.erase( itr ); @@ -444,16 +443,18 @@ namespace eosiosystem { auto oitr = idx.begin(); for ( uint16_t i = 0; i < max; ++i ) { if( oitr == idx.end() || !oitr->is_open ) break; - auto bitr = _rexbalance.find( oitr->owner.value ); // bitr != _rexbalance.end() - auto result = close_rex_order( bitr, oitr->rex_requested ); + auto bitr = _rexbalance.find( oitr->owner.value ); auto next = oitr; ++next; - if ( result.success ) { - idx.modify( oitr, same_payer, [&]( auto& order ) { - order.proceeds.amount = result.proceeds.amount; - order.stake_change.amount = result.stake_change.amount; - order.close(); - }); + if ( bitr != _rexbalance.end() ) { // should always be true + auto result = fill_rex_order( bitr, oitr->rex_requested ); + if ( result.success ) { + idx.modify( oitr, same_payer, [&]( auto& order ) { + order.proceeds.amount = result.proceeds.amount; + order.stake_change.amount = result.stake_change.amount; + order.close(); + }); + } } oitr = next; } @@ -472,8 +473,7 @@ namespace eosiosystem { update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( from, payment + fund ); - auto itr = _rexpool.begin(); - eosio_assert( itr != _rexpool.end(), "rex system not initialized yet" ); + auto itr = _rexpool.begin(); /// already checked that _rexpool.begin() != _rexpool.end() in rex_loans_available() int64_t rented_tokens = 0; _rexpool.modify( itr, same_payer, [&]( auto& rt ) { @@ -498,13 +498,13 @@ namespace eosiosystem { } /** - * close_rex_order processes an incoming of already scheduled sellrex order. If REX pool has enough core + * fill_rex_order processes an incoming of already scheduled sellrex order. If REX pool has enough core * tokens (not frozen in loans), order can be filled. In this case, REX pool totals, user rex_balance * and user vote_stake are updated. However, user voting power is not updated inside this function. The * function returns success flag, order proceeds, and vote stake change. These are used later to finish * order processing, which includes transfering proceeds and updating user vote weight. */ - rex_order_outcome system_contract::close_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) + rex_order_outcome system_contract::fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rexpool.begin(); const auto S0 = rexitr->total_lendable.amount; @@ -591,11 +591,11 @@ namespace eosiosystem { } /** - * update_rex_account checks if user has a scheduled sellrex order that has been closed, completes its processing, + * update_rex_account checks if user has a scheduled sellrex order that has been filled, completes its processing, * and deletes it. * Processing entails transfering proceeds to user REX fund and updating user vote weight. * Additional proceeds and stake change can be passed as arguments. - * This function is called only by actions pushed by owner, unlike close_rex_order. + * This function is called only by actions pushed by owner, unlike fill_rex_order. */ asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake, bool force_vote_update ) { From 382c50b437ab61664b7d312d0c782903a90de87c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 26 Nov 2018 14:58:39 -0500 Subject: [PATCH 0640/1048] Changes to closerex --- eosio.system/src/rex.cpp | 29 ++++++++++++----------------- tests/eosio.system_tests.cpp | 17 ++++++++--------- 2 files changed, 20 insertions(+), 26 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 56190b8b..76a24c28 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -257,37 +257,32 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - /// check for any outstanding cpu loans + /// check for any outstanding loans or rex fund { rex_cpu_loan_table cpu_loans( _self, _self.value ); auto cpu_idx = cpu_loans.get_index<"byowner"_n>(); - eosio_assert( cpu_idx.find( owner.value ) == cpu_idx.end(), "account has outstanding CPU loan" ); - } - - /// check for any outstanding net loans - { + bool no_outstanding_cpu_loans = ( cpu_idx.find( owner.value ) == cpu_idx.end() ); + rex_net_loan_table net_loans( _self, _self.value ); auto net_idx = net_loans.get_index<"byowner"_n>(); - eosio_assert( net_idx.find( owner.value ) == net_idx.end(), "account has outstanding NET loan" ); + bool no_outstanding_net_loans = ( net_idx.find( owner.value ) == net_idx.end() ); + + auto fund_itr = _rexfunds.find( owner.value ); + bool no_outstanding_rex_fund = ( fund_itr != _rexfunds.end() ) && ( fund_itr->balance.amount == 0 ); + + if ( no_outstanding_cpu_loans && no_outstanding_net_loans && no_outstanding_rex_fund ) { + _rexfunds.erase( fund_itr ); + } } /// check for remaining rex balance { auto rex_itr = _rexbalance.find( owner.value ); if ( rex_itr != _rexbalance.end() ) { - eosio_assert( rex_itr->rex_balance.amount == 0, "account has remaining REX, must sell first"); + eosio_assert( rex_itr->rex_balance.amount == 0, "account has remaining REX balance, must sell first"); _rexbalance.erase( rex_itr ); } } - - /// check for remaining rex fund balance - { - auto fund_itr =_rexfunds.find( owner.value ); - if ( fund_itr != _rexfunds.end() ) { - eosio_assert( fund_itr->balance.amount == 0, "account has remaining funds, must withdraw first"); - _rexfunds.erase( fund_itr ); - } - } } /** diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0b6e719b..75239f3e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4200,7 +4200,7 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( alice ).is_null() ); BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( alice ) ); - BOOST_REQUIRE_EQUAL( closerex( alice ), wasm_assert_msg("account has remaining funds, must withdraw first") ); + BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); BOOST_REQUIRE_EQUAL( success(), withdraw( alice, init_balance ) ); BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( alice).is_null() ); @@ -4212,10 +4212,10 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( false, get_rex_balance_obj( bob ).is_null() ); BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( bob ).is_null() ); BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX, must sell first") ); + BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining funds, must withdraw first") ); + BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); @@ -4228,7 +4228,7 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { produce_block( fc::days(20) ); - BOOST_REQUIRE_EQUAL( closerex( carol ), wasm_assert_msg("account has outstanding CPU loan") ); + BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); produce_block( fc::days(10) ); @@ -4237,16 +4237,15 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( carol ).is_null() ); BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, init_balance ) ); - BOOST_REQUIRE_EQUAL( closerex( emily ), wasm_assert_msg("account has outstanding NET loan") ); + BOOST_REQUIRE_EQUAL( success(), closerex( emily ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX, must sell first") ); + BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); produce_block( fc::days(30) ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining funds, must withdraw first") ); - BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); + BOOST_REQUIRE_EQUAL( closerex( bob ), success() ); + BOOST_REQUIRE ( 0 < get_rex_fund( bob ).get_amount() ); BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); From 29dbf52a4e34906b1676c728c2ce34ca0f720e8b Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 26 Nov 2018 15:49:03 -0500 Subject: [PATCH 0641/1048] Fix for abi generation to match old abi --- eosio.bios/CMakeLists.txt | 3 ++- eosio.bios/include/eosio.bios/eosio.bios.hpp | 5 +++-- eosio.system/include/eosio.system/native.hpp | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/eosio.bios/CMakeLists.txt b/eosio.bios/CMakeLists.txt index d4ed66f8..b1af9a7e 100644 --- a/eosio.bios/CMakeLists.txt +++ b/eosio.bios/CMakeLists.txt @@ -1,7 +1,8 @@ add_contract(eosio.bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) target_include_directories(eosio.bios.wasm PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) + ${CMAKE_CURRENT_SOURCE_DIR}/include + ${CMAKE_SOURCE_DIR}/eosio.system/include) set_target_properties(eosio.bios.wasm PROPERTIES diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index c1d5a2cc..1baef886 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -2,12 +2,13 @@ #include #include #include +#include namespace eosio { - class [[eosio::contract("eosio.bios")]] bios : public contract { + class [[eosio::contract("eosio.bios")]] bios : public eosiosystem::native { public: - using contract::contract; + using native::native; [[eosio::action]] void setpriv( name account, uint8_t is_priv ) { diff --git a/eosio.system/include/eosio.system/native.hpp b/eosio.system/include/eosio.system/native.hpp index 61a23eee..6b0445f0 100644 --- a/eosio.system/include/eosio.system/native.hpp +++ b/eosio.system/include/eosio.system/native.hpp @@ -98,7 +98,7 @@ namespace eosiosystem { */ [[eosio::action]] void newaccount( name creator, - name newact, + name name, ignore owner, ignore active); From a6b8e0eaccd1ef752c85e1dde65e07dbfa37ac1b Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 26 Nov 2018 16:18:46 -0500 Subject: [PATCH 0642/1048] need to explicitly add actions to class, inheritance is expecting the contract name to match --- eosio.bios/include/eosio.bios/eosio.bios.hpp | 53 +++++++++++++++++++- 1 file changed, 51 insertions(+), 2 deletions(-) diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 1baef886..789f22cb 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -2,13 +2,62 @@ #include #include #include +#include #include namespace eosio { - class [[eosio::contract("eosio.bios")]] bios : public eosiosystem::native { + class [[eosio::contract("eosio.bios")]] bios : public contract { public: - using native::native; + using contract::contract; + /** + * Called after a new account is created. This code enforces resource-limits rules + * for new accounts as well as new account naming conventions. + * + * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 + * characters long without '.' until a future account auction process is implemented + * which prevents name squatting. + * + * 2. new accounts must stake a minimal number of tokens (as set in system parameters) + * therefore, this method will execute an inline buyram from receiver for newacnt in + * an amount equal to the current new account creation fee. + */ + [[eosio::action]] + void newaccount( name creator, + name name, + ignore owner, + ignore active){} + + + [[eosio::action]] + void updateauth( ignore account, + ignore permission, + ignore parent, + ignore auth ) {} + + [[eosio::action]] + void deleteauth( ignore account, + ignore permission ) {} + + [[eosio::action]] + void linkauth( ignore account, + ignore code, + ignore type, + ignore requirement ) {} + + [[eosio::action]] + void unlinkauth( ignore account, + ignore code, + ignore type ) {} + + [[eosio::action]] + void canceldelay( ignore canceling_auth, ignore trx_id ) {} + + [[eosio::action]] + void onerror( ignore sender_id, ignore> sent_trx ) {} + + [[eosio::action]] + void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} [[eosio::action]] void setpriv( name account, uint8_t is_priv ) { From a13054f0b57b938d1d36d7d74663d30a6dcb113a Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 26 Nov 2018 17:00:48 -0500 Subject: [PATCH 0643/1048] pull all of native.hpp in --- eosio.bios/CMakeLists.txt | 3 +- eosio.bios/include/eosio.bios/eosio.bios.hpp | 74 +++++++++++++++----- 2 files changed, 58 insertions(+), 19 deletions(-) diff --git a/eosio.bios/CMakeLists.txt b/eosio.bios/CMakeLists.txt index b1af9a7e..d4ed66f8 100644 --- a/eosio.bios/CMakeLists.txt +++ b/eosio.bios/CMakeLists.txt @@ -1,8 +1,7 @@ add_contract(eosio.bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) target_include_directories(eosio.bios.wasm PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_SOURCE_DIR}/eosio.system/include) + ${CMAKE_CURRENT_SOURCE_DIR}/include) set_target_properties(eosio.bios.wasm PROPERTIES diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/eosio.bios/include/eosio.bios/eosio.bios.hpp index 789f22cb..06c24a01 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -1,39 +1,79 @@ #pragma once +#include #include #include #include -#include -#include +#include namespace eosio { + using eosio::permission_level; + using eosio::public_key; + using eosio::ignore; + + struct permission_level_weight { + permission_level permission; + uint16_t weight; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) + }; + + struct key_weight { + eosio::public_key key; + uint16_t weight; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( key_weight, (key)(weight) ) + }; + + struct wait_weight { + uint32_t wait_sec; + uint16_t weight; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) + }; + + struct authority { + uint32_t threshold = 0; + std::vector keys; + std::vector accounts; + std::vector waits; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) + }; + + struct block_header { + uint32_t timestamp; + name producer; + uint16_t confirmed = 0; + capi_checksum256 previous; + capi_checksum256 transaction_mroot; + capi_checksum256 action_mroot; + uint32_t schedule_version = 0; + std::optional new_producers; + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE(block_header, (timestamp)(producer)(confirmed)(previous)(transaction_mroot)(action_mroot) + (schedule_version)(new_producers)) + }; class [[eosio::contract("eosio.bios")]] bios : public contract { public: using contract::contract; - /** - * Called after a new account is created. This code enforces resource-limits rules - * for new accounts as well as new account naming conventions. - * - * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 - * characters long without '.' until a future account auction process is implemented - * which prevents name squatting. - * - * 2. new accounts must stake a minimal number of tokens (as set in system parameters) - * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. - */ [[eosio::action]] void newaccount( name creator, name name, - ignore owner, - ignore active){} + ignore owner, + ignore active){} [[eosio::action]] void updateauth( ignore account, ignore permission, ignore parent, - ignore auth ) {} + ignore auth ) {} [[eosio::action]] void deleteauth( ignore account, From 9042ed605b651be2bb9ac849c6dfd81d003285a6 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 26 Nov 2018 18:34:09 -0500 Subject: [PATCH 0644/1048] Impose a dynamic lower bound on REX pool total_unlent --- eosio.system/include/eosio.system/eosio.system.hpp | 2 -- eosio.system/src/rex.cpp | 6 ++++-- tests/eosio.system_tests.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index c3649598..8e811152 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -515,9 +515,7 @@ namespace eosiosystem { static time_point current_time_point(); static time_point_sec current_time_point_sec(); static block_timestamp current_block_time(); - symbol core_symbol()const; - void update_ram_supply(); // defined in rex.cpp diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 76a24c28..a001d69c 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -509,8 +509,10 @@ namespace eosiosystem { asset proceeds( S0 - S1, core_symbol() ); asset stake_change( 0, core_symbol() ); bool success = false; - - if ( proceeds.amount <= rexitr->total_unlent.amount ) { + + const int64_t unlent_lower_bound = ( 2 * rexitr->total_lent.amount ) / 10; + const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible + if ( proceeds.amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; _rexpool.modify( rexitr, same_payer, [&]( auto& rt ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 75239f3e..3a2a3182 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3701,11 +3701,11 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( (3*get_rex_balance(alice).get_amount())/4, symbol(SY(4,REX)) ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( (get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); - BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); + BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); + BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); + BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); produce_block( fc::days(5) ); From b288caafb87edd433a966487a63997e87c230148 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 27 Nov 2018 12:04:36 -0500 Subject: [PATCH 0645/1048] passthrough LLVM_DIR to unit tests external project --- UnitTestsExternalProject.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt index a22bff2d..30ba24fb 100644 --- a/UnitTestsExternalProject.txt +++ b/UnitTestsExternalProject.txt @@ -8,7 +8,7 @@ string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") ExternalProject_Add( contracts_unit_tests LIST_SEPARATOR | # Use the alternate list separator - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 From 4a7e076bdfb6f08194a1c11124dc0d3114223276 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 27 Nov 2018 13:53:08 -0500 Subject: [PATCH 0646/1048] bump version to 1.5.1 --- CMakeLists.txt | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 58f698dc..c9646789 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.5.0) +project(eosio_contracts VERSION 1.5.1) set(EOSIO_CDT_VERSION_MIN "1.4") set(EOSIO_CDT_VERSION_SOFT_MAX "1.4") diff --git a/README.md b/README.md index 0b485d37..d055e7a8 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.5.0 +## Version : 1.5.1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.4.x](https://github.com/EOSIO/eos/releases/tag/v1.4.3) -* [eosio.cdt v1.4.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.4.0) +* [eosio v1.4.x](https://github.com/EOSIO/eos/releases/tag/v1.4.4) +* [eosio.cdt v1.4.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.4.1) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From 5399d822b0834a12f400df5d3068003cc736de5a Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 27 Nov 2018 18:15:55 -0500 Subject: [PATCH 0647/1048] Small fixes, comments --- .../include/eosio.system/eosio.system.hpp | 16 ++- eosio.system/src/rex.cpp | 106 ++++++++++++++++-- tests/eosio.system_tests.cpp | 8 +- 3 files changed, 110 insertions(+), 20 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 8e811152..4188087f 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -327,18 +327,25 @@ namespace eosiosystem { void deposit( const name& owner, const asset& amount ); /** - * Withdraws core tokens from user REX fund. Inline token transfer to user balance is executed. + * Withdraws core tokens from user REX fund. Inline token transfer to user balance is + * executed. */ [[eosio::action]] void withdraw( const name& owner, const asset& amount ); /** * Transfers core tokens from user REX fund and converts them to REX stake. + * A voting requirement must be satisfied before action can be executed. * User votes are updated following this action. */ [[eosio::action]] void buyrex( const name& from, const asset& amount ); + /** + * Use staked core tokens to buy REX. + * A voting requirement must be satisfied before action can be executed. + * User votes are updated following this action. + */ [[eosio::action]] void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); @@ -402,14 +409,15 @@ namespace eosiosystem { void rexexec( const name& user, uint16_t max ); /** - * + * Consolidate REX maturity buckets into one that can be sold only 4 days + * from the end of today. */ [[eosio::action]] void consolidate( const name& owner ); /** - * Deletes owner records from REX tables and frees used RAM. Owner must have no outstanding loans, - * REX balance, or remaining REX fund balance. + * Deletes owner records from REX tables and frees used RAM. + * Owner must not have an outstanding REX balance. */ [[eosio::action]] void closerex( const name& owner ); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index a001d69c..77367d35 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -7,7 +7,7 @@ namespace eosiosystem { void system_contract::deposit( const name& owner, const asset& amount ) - { + { require_auth( owner ); eosio_assert( amount.symbol == core_symbol(), "must deposit core token" ); @@ -47,7 +47,7 @@ namespace eosiosystem { * Transfers SYS tokens from user balance and credits converts them to REX stake. */ void system_contract::buyrex( const name& from, const asset& amount ) - { + { require_auth( from ); eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); @@ -110,7 +110,7 @@ namespace eosiosystem { eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); - eosio_assert( rex.symbol == bitr->rex_balance.symbol , "asset symbol must be (4, REX)" ); + eosio_assert( rex.symbol == bitr->rex_balance.symbol , "asset symbol must be (REX, 4)" ); process_rex_maturities( bitr ); eosio_assert( rex.amount <= bitr->matured_rex, "insufficient funds" ); @@ -289,9 +289,11 @@ namespace eosiosystem { * Given two connector balances (conin, and conout), and an incoming amount of * in, this function will modify conin and conout and return the delta out. * - * @param in - same units as conin + * @param in - input amount, same units as conin * @param conin - the input connector balance * @param conout - the output connector balance + * + * @return int64_t - conversion result output amount */ int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { @@ -309,6 +311,14 @@ namespace eosiosystem { return out; } + /** + * @brief Updates account Net and CPU resource limits + * + * @param from - account charged for RAM if there is a need + * @param receiver - account whose resource limits are updated + * @param delta_net - change in Net bandwidth limit + * @param delta_cpu - change in CPU limit + */ void system_contract::update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ) { if ( delta_cpu == 0 && delta_net == 0 ) { // nothing to update @@ -345,7 +355,9 @@ namespace eosiosystem { } /** - * Perform maintenance operations on expired rex + * @brief Performs maintenance operations on expired Net and CPU loans and sellrex oders + * + * @param max - maximum number of each of the three categories to be processed */ void system_contract::runrex( uint16_t max ) { @@ -457,6 +469,9 @@ namespace eosiosystem { } + /** + * + */ template int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) { @@ -510,7 +525,7 @@ namespace eosiosystem { asset stake_change( 0, core_symbol() ); bool success = false; - const int64_t unlent_lower_bound = ( 2 * rexitr->total_lent.amount ) / 10; + const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible if ( proceeds.amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; @@ -561,6 +576,14 @@ namespace eosiosystem { transfer_to_fund( from, amount ); } + /** + * @brief Transfers tokens from owner REX fund + * + * @pre - owner REX fund has sufficient balance + * + * @param owner - owner account name + * @param amount - asset to be taken out of REX fund + */ void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { eosio_assert( 0 < amount.amount, "must transfer positive amount from REX fund" ); @@ -571,6 +594,12 @@ namespace eosiosystem { }); } + /** + * @brief Transfers tokens to owner REX fund + * + * @param owner - owner account name + * @param amount - asset to be transfered to REX fund + */ void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { eosio_assert( 0 < amount.amount, "must transfer positive amount to REX fund" ); @@ -588,11 +617,19 @@ namespace eosiosystem { } /** - * update_rex_account checks if user has a scheduled sellrex order that has been filled, completes its processing, - * and deletes it. - * Processing entails transfering proceeds to user REX fund and updating user vote weight. - * Additional proceeds and stake change can be passed as arguments. - * This function is called only by actions pushed by owner, unlike fill_rex_order. + * @brief Processes owner filled sellrex orders and updates vote weight + * + * Checks if user has a scheduled sellrex order that has been filled, completes its processing, + * and deletes it. Processing entails transfering proceeds to user REX fund and updating user + * vote weight. Additional proceeds and stake change can be passed as arguments. This function + * is called only by actions pushed by owner. + * + * @param owner - owner account name + * @param proceeds - additional proceeds to be transfered to owner REX fund + * @param delta_stake - additional stake to be added to owner vote weight + * @param force_vote_update - if true, vote weight is updated even if vote stake didn't change + * + * @return asset - REX amount of owner unfilled sell order if one exists */ asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake, bool force_vote_update ) { @@ -616,6 +653,12 @@ namespace eosiosystem { return rex_in_sell_order; } + /** + * @brief Channels system fees to REX pool + * + * @param from - account from which asset is transfered to REX pool + * @param amount - amount of tokens to be transfered + */ void system_contract::channel_to_rex( const name& from, const asset& amount ) { if ( rex_available() ) { @@ -629,6 +672,11 @@ namespace eosiosystem { } } + /** + * @brief Updates namebid proceeds to be transfered to REX pool + * + * @param highest_bid - highest bidding amount of closed namebid + */ void system_contract::channel_namebid_to_rex( const int64_t highest_bid ) { if ( rex_available() ) { @@ -638,6 +686,11 @@ namespace eosiosystem { } } + /** + * @brief Calculates maturity time of purchased REX tokens + * + * @return time_point_sec + */ time_point_sec system_contract::get_rex_maturity() { const uint32_t num_of_maturity_buckets = 4; @@ -647,6 +700,11 @@ namespace eosiosystem { return rms; } + /** + * @brief Updates REX owner maturity buckets + * + * @param bitr - iterator pointing to rex_balance object + */ void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) { time_point_sec now = current_time_point_sec(); @@ -658,6 +716,12 @@ namespace eosiosystem { }); } + /** + * @brief + * + * @param bitr - + * @param rex_in_sell_order - + */ void system_contract::consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ) { @@ -672,6 +736,13 @@ namespace eosiosystem { }); } + /** + * @brief Updates REX pool balances upon REX purchase + * + * @param payment - amount of core tokens paid + * + * @return asset - calculated amount of REX tokens purchased + */ asset system_contract::add_to_rex_pool( const asset& payment ) { const int64_t rex_ratio = 10000; @@ -690,7 +761,7 @@ namespace eosiosystem { rp.total_rex = rex_received; rp.namebid_proceeds = asset( 0, core_symbol() ); }); - } else if ( !rex_available() ) { /// should be a rare corner case, REX pool initialized but empty + } else if ( !rex_available() ) { /// should be a rare corner case, REX pool is initialized but empty _rexpool.modify( itr, same_payer, [&]( auto& rp ) { rex_received.amount = payment.amount * rex_ratio; @@ -701,6 +772,8 @@ namespace eosiosystem { rp.total_rex.amount = rex_received.amount; }); } else { + /// total_lendable > 0 if total_rex > 0 except in a rare case and due to rounding errors + eosio_assert( itr->total_lendable.amount > 0, "lendable REX pool is empty" ); const auto S0 = itr->total_lendable.amount; const auto S1 = S0 + payment.amount; const auto R0 = itr->total_rex.amount; @@ -719,6 +792,15 @@ namespace eosiosystem { return rex_received; } + /** + * @brief Updates owner REX balance upon buying REX tokens + * + * @param owner - account name of REX owner + * @param payment - amount core tokens paid for buying REX + * @param rex_received - amount of purchased REX tokens + * + * @return asset - change in owner REX vote stake + */ asset system_contract::add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ) { auto bitr = _rexbalance.find( owner.value ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 3a2a3182..3ce24497 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3423,7 +3423,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { produce_block( fc::days(6) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first buyrex"), sellrex( carol, asset::from_string("5.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset symbol must be (4, REX)"), sellrex( bob, core_sym::from_string("55.0000") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset symbol must be (REX, 4)"), sellrex( bob, core_sym::from_string("55.0000") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); auto init_total_rex = rex_pool["total_rex"].as().get_amount(); @@ -3668,7 +3668,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; - const asset init_balance = core_sym::from_string("2000000.0000"); + const asset init_balance = core_sym::from_string("3000000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); @@ -3693,7 +3693,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL(core_sym::from_string("100000.0000"), get_rex_pool()["total_rent"].as() ); const asset rent_payment = core_sym::from_string("1100000.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); const auto init_rex_pool = get_rex_pool(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * init_rex_pool["total_lendable"].as().get_amount() ) @@ -3701,7 +3701,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( (get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); From fc83f42cf22e5f4a5aa55c9634fb22e3d4a05ef4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 27 Nov 2018 23:06:52 -0500 Subject: [PATCH 0648/1048] REX pool lower bound test --- tests/eosio.system_tests.cpp | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 3ce24497..2cc33ff2 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4191,6 +4191,36 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { + + const asset init_balance = core_sym::from_string("200.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance ); + const symbol rex_sym( SY(4, REX) ); + + const asset payment = core_sym::from_string("50.0000"); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, payment ) ); + + const auto rex_pool = get_rex_pool(); + const int64_t tot_rex = rex_pool["total_rex"].as().get_amount(); + const int64_t tot_unlent = rex_pool["total_unlent"].as().get_amount(); + const int64_t tot_lent = rex_pool["total_lent"].as().get_amount(); + const int64_t tot_lendable = rex_pool["total_lendable"].as().get_amount(); + double rex_per_eos = double(tot_rex) / double(tot_lendable); + int64_t sell_amount = rex_per_eos * ( tot_unlent - 1.9 * tot_lent / 10. ); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + sell_amount = rex_per_eos * ( tot_unlent - 2. * tot_lent / 10. ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("no sellrex order is scheduled"), + cancelrexorder( alice ) ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { const asset init_balance = core_sym::from_string("200.0000"); From 6e4c181ad89c1c0f0d6cfd31b8f06c766759f0f4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sat, 1 Dec 2018 14:04:35 -0500 Subject: [PATCH 0649/1048] Small changes, tests --- eosio.system/src/rex.cpp | 15 +++++++-------- tests/eosio.system_tester.hpp | 5 +++++ tests/eosio.system_tests.cpp | 30 +++++++++++++++++++----------- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 77367d35..5a113cf7 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -65,10 +65,8 @@ namespace eosiosystem { require_auth( owner ); eosio_assert( from_net.symbol == core_symbol() && from_cpu.symbol == core_symbol(), "asset must be core token" ); - eosio_assert( 0 <= from_net.amount, "must unstake a positive amount to buy rex" ); - eosio_assert( 0 <= from_cpu.amount, "must unstake a positive amount to buy rex" ); - eosio_assert( 0 < from_net.amount || 0 < from_cpu.amount, "must unstake a positive amount to buy rex" ); - + eosio_assert( (0 <= from_net.amount) && (0 <= from_cpu.amount) && (0 < from_net.amount || 0 < from_cpu.amount), + "must unstake a positive amount to buy rex" ); { auto vitr = _voters.find( owner.value ); eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), @@ -110,9 +108,10 @@ namespace eosiosystem { eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); - eosio_assert( rex.symbol == bitr->rex_balance.symbol , "asset symbol must be (REX, 4)" ); + eosio_assert( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, + "asset must be a positive amount of (REX, 4)" ); process_rex_maturities( bitr ); - eosio_assert( rex.amount <= bitr->matured_rex, "insufficient funds" ); + eosio_assert( rex.amount <= bitr->matured_rex, "insufficient available rex" ); auto current_order = fill_rex_order( bitr, rex ); update_rex_account( from, current_order.proceeds, current_order.stake_change ); @@ -555,7 +554,7 @@ namespace eosiosystem { eosio_assert( payment.symbol == core_symbol(), "must use core token" ); transfer_from_fund( from, payment ); auto itr = table.require_find( loan_num, "loan not found" ); - eosio_assert( itr->from == from, "actor has to be loan creator" ); + eosio_assert( itr->from == from, "user must be loan creator" ); eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); table.modify( itr, same_payer, [&]( auto& loan ) { loan.balance.amount += payment.amount; @@ -567,7 +566,7 @@ namespace eosiosystem { { eosio_assert( amount.symbol == core_symbol(), "must use core token" ); auto itr = table.require_find( loan_num, "loan not found" ); - eosio_assert( itr->from == from, "actor has to be loan creator" ); + eosio_assert( itr->from == from, "user must be loan creator" ); eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); eosio_assert( itr->balance >= amount, "insufficent loan balance" ); table.modify( itr, same_payer, [&]( auto& loan ) { diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 2cd81815..434928d5 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -468,6 +468,11 @@ class eosio_system_tester : public TESTER { return get_loan_info( loan_num, false ); } + fc::variant get_dbw_obj( const account_name& from, const account_name& receiver ) const { + vector data = get_row_by_account( config::system_account_name, from, N(delband), receiver ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant("delegated_bandwidth", data, abi_serializer_max_time); + } + asset get_rex_balance( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 2cc33ff2..aed756ed 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3423,8 +3423,11 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { produce_block( fc::days(6) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first buyrex"), sellrex( carol, asset::from_string("5.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset symbol must be (REX, 4)"), sellrex( bob, core_sym::from_string("55.0000") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), + sellrex( bob, core_sym::from_string("55.0000") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), + sellrex( bob, asset::from_string("-75.0030 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); auto init_total_rex = rex_pool["total_rex"].as().get_amount(); auto init_total_lendable = rex_pool["total_lendable"].as().get_amount(); @@ -3540,7 +3543,11 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes unstaketorex( bob, carol, one_token, neg_asset ) ); BOOST_REQUIRE_EQUAL( init_net_limit + net_stake.get_amount(), get_net_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_cpu_limit + cpu_stake.get_amount(), get_cpu_limit( carol ) ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( false, get_dbw_obj( bob, carol ).is_null() ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, net_stake, zero_asset ) ); + BOOST_REQUIRE_EQUAL( false, get_dbw_obj( bob, carol ).is_null() ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, zero_asset, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( true, get_dbw_obj( bob, carol ).is_null() ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( carol ).get_amount() ); BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( bob ).get_amount() ); BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( bob ) ); @@ -3557,7 +3564,8 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), unstaketorex( emily, frank, net_stake, cpu_stake ) ); BOOST_REQUIRE_EQUAL( success(), unstaketorex( frank, frank, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), sellrex( frank, asset::from_string("1.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( frank, asset::from_string("1.0000 REX") ) ); produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( success(), sellrex( frank, asset::from_string("1.0000 REX") ) ); } @@ -3821,7 +3829,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { // frank funds his loan enough to be renewed once const asset fund = core_sym::from_string("35.0000"); BOOST_REQUIRE_EQUAL( fundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); - BOOST_REQUIRE_EQUAL( fundcpuloan( alice, 1, fund ), wasm_assert_msg("actor has to be loan creator") ); + BOOST_REQUIRE_EQUAL( fundcpuloan( alice, 1, fund ), wasm_assert_msg("user must be loan creator") ); BOOST_REQUIRE_EQUAL( success(), fundcpuloan( frank, 1, fund ) ); old_frank_balance = cur_frank_balance; cur_frank_balance = get_rex_fund( frank ); @@ -3834,7 +3842,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { { const asset amount = core_sym::from_string("7.5000"); BOOST_REQUIRE_EQUAL( defundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); - BOOST_REQUIRE_EQUAL( defundcpuloan( alice, 1, fund ), wasm_assert_msg("actor has to be loan creator") ); + BOOST_REQUIRE_EQUAL( defundcpuloan( alice, 1, fund ), wasm_assert_msg("user must be loan creator") ); BOOST_REQUIRE_EQUAL( defundcpuloan( frank, 1, core_sym::from_string("75.0000") ), wasm_assert_msg("insufficent loan balance") ); old_frank_balance = cur_frank_balance; asset old_loan_balance = get_cpu_loan(1)["balance"].as(); @@ -3971,7 +3979,7 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( alice, asset::from_string("115000.0000 REX") ) ); produce_block( fc::hours( 3*24 + 20) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("300000.0000 REX") ) ); @@ -3980,7 +3988,7 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); produce_block( fc::hours(23) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( alice, asset::from_string("250000.0000 REX") ) ); produce_block( fc::days(1) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("130000.0000 REX") ) ); @@ -3988,7 +3996,7 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["rex_balance"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( alice, asset::from_string("130000.0000 REX") ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("120000.0000 REX") ) ); rex_balance = get_rex_balance_obj( alice ); @@ -4030,7 +4038,7 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset( 2 * rex_bucket.get_amount(), rex_sym ) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket.get_amount(), rex_sym ) ) ); rex_balance = get_rex_balance_obj( bob ); @@ -4050,7 +4058,7 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); produce_block( fc::days(3) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); produce_block( fc::hours(24 + 20) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); From 3c77a9c10badb6fb62e1892c9fe25154a929496f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 4 Dec 2018 19:06:32 -0500 Subject: [PATCH 0650/1048] Code cleaning, comments --- eosio.system/src/rex.cpp | 125 ++++++++++++++++++++++++++++++--------- 1 file changed, 98 insertions(+), 27 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 5a113cf7..b5470928 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -12,21 +12,9 @@ namespace eosiosystem { eosio_assert( amount.symbol == core_symbol(), "must deposit core token" ); eosio_assert( 0 < amount.amount, "must deposit a positive amount" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { owner, active_permission }, { owner, rex_account, amount, "deposit to REX fund" } ); - auto itr = _rexfunds.find( owner.value ); - if ( itr == _rexfunds.end() ) { - _rexfunds.emplace( owner, [&]( auto& fund ) { - fund.owner = owner; - fund.balance = amount; - }); - } else { - _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { - fund.balance.amount += amount.amount; - }); - } - + transfer_to_fund( owner, amount ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } @@ -38,7 +26,6 @@ namespace eosiosystem { eosio_assert( 0 < amount.amount, "must withdraw a positive amount" ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( owner, amount ); - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, { rex_account, owner, amount, "withdraw from REX fund" } ); } @@ -52,7 +39,6 @@ namespace eosiosystem { eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); eosio_assert( amount.amount > 0, "must use positive amount" ); - transfer_from_fund( from, amount ); const asset rex_received = add_to_rex_pool( amount ); const asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); @@ -60,6 +46,14 @@ namespace eosiosystem { update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); } + /** + * @brief Buys REX using staked SYS tokens + * + * @param owner - owner of staked tokens account name + * @param receiver - account name that tokens have previously been staked to + * @param from_net - amount of tokens to be unstaked from Net bandwidth and used for REX purchase + * @param from_cpu - amount of tokens to be unstaked from CPU bandwidth and used for REX purchase + */ void system_contract::unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ) { require_auth( owner ); @@ -92,13 +86,18 @@ namespace eosiosystem { const asset payment = from_net + from_cpu; INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { stake_account, active_permission }, { stake_account, rex_account, payment, "buy REX with staked tokens" } ); - const asset rex_received = add_to_rex_pool( payment ); add_to_rex_balance( owner, payment, rex_received ); runrex(2); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ), true ); } + /** + * @brief Sells REX in exchange for SYS tokens + * + * @param from - owner of REX tokens + * @param rex - amount of REX tokens to be sold + */ void system_contract::sellrex( const name& from, const asset& rex ) { runrex(2); @@ -150,8 +149,16 @@ namespace eosiosystem { } /** - * Uses payment to rent as many SYS tokens as possible and stake them for either cpu or net for the benefit of receiver, - * after 30 days the rented SYS delegation of CPU or NET will expire. + * Rents as many SYS tokens as determined by market price and stakes them for CPU bandwidth + * for the benefit of receiver account. After 30 days the rented SYS delegation of CPU will + * expire or be renewed at new market price depending on available loan fund. + * + * @brief Rents CPU resources for 30 days in exchange for market-determined price + * + * @param from - account creating and paying for CPU loan + * @param receiver - account receiving rented CPU resources + * @param loan_payment - tokens paid for the loan + * @param loan_fund - additional tokens added to loan fund and used later for loan renewal */ void system_contract::rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { @@ -162,6 +169,18 @@ namespace eosiosystem { update_resource_limits( from, receiver, 0, rented_tokens ); } + /** + * Rents as many SYS tokens as determined by market price and stakes them for NET bandwidth + * for the benefit of receiver account. After 30 days the rented SYS delegation of NET will + * expire or be renewed at new market price depending on available loan fund. + * + * @brief Rents NET resources for 30 days in exchange for market-determined price + * + * @param from - account creating and paying for NET loan + * @param receiver - account receiving rented NET resources + * @param loan_payment - tokens paid for the loan + * @param loan_fund - additional tokens added to loan fund and used later for loan renewal + */ void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { require_auth( from ); @@ -171,6 +190,14 @@ namespace eosiosystem { update_resource_limits( from, receiver, rented_tokens, 0 ); } + /** + * @brief Transfers tokens to the fund of a specific CPU loan in order to be used in loan + * renewal at expiry + * + * @param from - loan creator + * @param loan_num - loan id + * @param payment - tokens added to loan fund + */ void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) { require_auth( from ); @@ -179,6 +206,14 @@ namespace eosiosystem { fund_rex_loan( cpu_loans, from, loan_num, payment ); } + /** + * @brief Transfers tokens to the fund of a specific NET loan in order to be used in loan + * renewal at expiry + * + * @param from - loan creator + * @param loan_num - loan id + * @param payment - tokens added to loan fund + */ void system_contract::fundnetloan( const name& from, uint64_t loan_num, const asset& payment ) { require_auth( from ); @@ -187,6 +222,13 @@ namespace eosiosystem { fund_rex_loan( net_loans, from, loan_num, payment ); } + /** + * @brief Withdraws tokens from the fund of a specific CPU loan + * + * @param from - loan creator + * @param loan_num - loan id + * @param amount - tokens to be withdrawn from loan fund + */ void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) { require_auth( from ); @@ -195,6 +237,13 @@ namespace eosiosystem { defund_rex_loan( cpu_loans, from, loan_num, amount ); } + /** + * @brief Withdraws tokens from the fund of a specific NET loan + * + * @param from - loan creator + * @param loan_num - loan id + * @param amount - tokens to be withdrawn from loan fund + */ void system_contract::defnetloan( const name& from, uint64_t loan_num, const asset& amount ) { require_auth( from ); @@ -203,6 +252,11 @@ namespace eosiosystem { defund_rex_loan( net_loans, from, loan_num, amount ); } + /** + * @brief Updates REX owner vote weight to current value of held REX tokens + * + * @param owner - owner of REX tokens + */ void system_contract::updaterex( const name& owner ) { require_auth( owner ); @@ -229,6 +283,13 @@ namespace eosiosystem { process_rex_maturities( itr ); } + /** + * @brief Performs REX maintenance by processing a specified number of REX sell orders + * and expired loans + * + * @param user - any user can execute this action + * @param max - number of each of CPU loans, NET loans, and sell orders to be processed + */ void system_contract::rexexec( const name& user, uint16_t max ) { require_auth( user ); @@ -236,6 +297,12 @@ namespace eosiosystem { runrex( max ); } + /** + * @brief Consolidates REX maturity buckets into one bucket that cannot be sold before + * 4 days + * + * @param owner - account name of REX owner + */ void system_contract::consolidate( const name& owner ) { require_auth( owner ); @@ -247,6 +314,11 @@ namespace eosiosystem { consolidate_rex_balance( bitr, rex_in_sell_order ); } + /** + * @brief Deletes unused REX-related database entries and frees RAM + * + * @param owner - user account name + */ void system_contract::closerex( const name& owner ) { require_auth( owner ); @@ -468,9 +540,6 @@ namespace eosiosystem { } - /** - * - */ template int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) { @@ -636,12 +705,14 @@ namespace eosiosystem { asset to_stake( delta_stake ); asset rex_in_sell_order( 0, core_symbol() ); auto itr = _rexorders.find( owner.value ); - if ( itr != _rexorders.end() && !itr->is_open ) { - to_fund.amount += itr->proceeds.amount; - to_stake.amount += itr->stake_change.amount; - _rexorders.erase( itr ); - } else if ( itr != _rexorders.end() ) { // itr->is_open is true - rex_in_sell_order.amount = itr->rex_requested.amount; + if ( itr != _rexorders.end() ) { + if ( itr->is_open ) { + rex_in_sell_order.amount = itr->rex_requested.amount; + } else { + to_fund.amount += itr->proceeds.amount; + to_stake.amount += itr->stake_change.amount; + _rexorders.erase( itr ); + } } if ( to_fund.amount > 0 ) From cc78cb456f481b086e1912a18856b8f586620cda Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 5 Dec 2018 14:37:01 -0500 Subject: [PATCH 0651/1048] Code cleaning, comments - 2 --- eosio.system/src/rex.cpp | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index b5470928..e478b908 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -6,6 +6,12 @@ namespace eosiosystem { + /** + * @brief Deposits SYS tokens to user REX fund + * + * @param owner - REX fund owner + * @param amount - amount of tokens to be deposited + */ void system_contract::deposit( const name& owner, const asset& amount ) { require_auth( owner ); @@ -17,7 +23,12 @@ namespace eosiosystem { transfer_to_fund( owner, amount ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } - + /** + * @brief Withdraws SYS tokens from user REX fund + * + * @param owner - REX fund owner + * @param amount - amount of tokens to be withdrawn + */ void system_contract::withdraw( const name& owner, const asset& amount ) { require_auth( owner ); @@ -31,7 +42,10 @@ namespace eosiosystem { } /** - * Transfers SYS tokens from user balance and credits converts them to REX stake. + * @brief Buys REX in exchange for SYS tokens taken out of user REX fund + * + * @param from - owner account name + * @param amount - amount of SYS tokens to be used for purchase */ void system_contract::buyrex( const name& from, const asset& amount ) { @@ -757,7 +771,8 @@ namespace eosiosystem { } /** - * @brief Calculates maturity time of purchased REX tokens + * @brief Calculates maturity time of purchased REX tokens which is 4 days from end + * of the day UTC * * @return time_point_sec */ @@ -765,7 +780,7 @@ namespace eosiosystem { { const uint32_t num_of_maturity_buckets = 4; static const uint32_t now = current_time_point_sec().utc_seconds; - static const uint32_t r = (current_time_point_sec().utc_seconds + 1) % seconds_per_day; + static const uint32_t r = now % seconds_per_day; static const time_point_sec rms{ now - r + (num_of_maturity_buckets + 1) * seconds_per_day }; return rms; } @@ -787,10 +802,10 @@ namespace eosiosystem { } /** - * @brief + * @brief Consolidate REX maturity buckets into one. * - * @param bitr - - * @param rex_in_sell_order - + * @param bitr - iterator pointing to rex_balance object + * @param rex_in_sell_order - REX tokens in owner unfilled sell order, if one exists */ void system_contract::consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ) From af6f9619c08c188f2e9b6fcb10955e945b35b85e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 6 Dec 2018 19:15:41 -0500 Subject: [PATCH 0652/1048] Code cleaning, tests --- eosio.system/src/rex.cpp | 41 ++++++++++++++++++------------------ tests/eosio.system_tests.cpp | 21 ++++++++++++++++++ 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index e478b908..dfebfe90 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -118,8 +118,6 @@ namespace eosiosystem { require_auth( from ); - eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); - auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); eosio_assert( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); @@ -293,7 +291,7 @@ namespace eosiosystem { rb.vote_stake = current_stake; }); - update_rex_account( owner, asset( 0, core_symbol() ), current_stake - init_stake ); + update_rex_account( owner, asset( 0, core_symbol() ), current_stake - init_stake, true ); process_rex_maturities( itr ); } @@ -454,7 +452,7 @@ namespace eosiosystem { _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, itr->total_staked.amount ); rt.total_lent.amount -= itr->total_staked.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + // rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); bool delete_loan = false; @@ -531,13 +529,13 @@ namespace eosiosystem { /// process sellrex orders { - auto idx = _rexorders.get_index<"bytime"_n>(); + auto idx = _rexorders.get_index<"bytime"_n>(); auto oitr = idx.begin(); for ( uint16_t i = 0; i < max; ++i ) { - if( oitr == idx.end() || !oitr->is_open ) break; - auto bitr = _rexbalance.find( oitr->owner.value ); - auto next = oitr; + if ( oitr == idx.end() || !oitr->is_open ) break; + auto next = oitr; ++next; + auto bitr = _rexbalance.find( oitr->owner.value ); if ( bitr != _rexbalance.end() ) { // should always be true auto result = fill_rex_order( bitr, oitr->rex_requested ); if ( result.success ) { @@ -561,7 +559,8 @@ namespace eosiosystem { eosio_assert( rex_loans_available(), "rex loans are not currently available" ); eosio_assert( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); - + eosio_assert( 0 < payment.amount && 0 <= fund.amount, "must use positive asset amount" ); + update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( from, payment + fund ); @@ -599,12 +598,12 @@ namespace eosiosystem { rex_order_outcome system_contract::fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { auto rexitr = _rexpool.begin(); - const auto S0 = rexitr->total_lendable.amount; - const auto R0 = rexitr->total_rex.amount; - const auto R1 = R0 - rex.amount; - const auto S1 = (uint128_t(R1) * S0) / R0; + const int64_t S0 = rexitr->total_lendable.amount; + const int64_t R0 = rexitr->total_rex.amount; + const int64_t R1 = R0 - rex.amount; + const int64_t S1 = (uint128_t(R1) * S0) / R0; asset proceeds( S0 - S1, core_symbol() ); - asset stake_change( 0, core_symbol() ); + asset stake_change( 0, core_symbol() ); bool success = false; const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; @@ -738,7 +737,7 @@ namespace eosiosystem { } /** - * @brief Channels system fees to REX pool + * @brief Channels system fees to REX pool * * @param from - account from which asset is transfered to REX pool * @param amount - amount of tokens to be transfered @@ -802,7 +801,7 @@ namespace eosiosystem { } /** - * @brief Consolidate REX maturity buckets into one. + * @brief Consolidates REX maturity buckets into one * * @param bitr - iterator pointing to rex_balance object * @param rex_in_sell_order - REX tokens in owner unfilled sell order, if one exists @@ -831,7 +830,7 @@ namespace eosiosystem { asset system_contract::add_to_rex_pool( const asset& payment ) { const int64_t rex_ratio = 10000; - const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() are made available + const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() is made available asset rex_received( 0, rex_symbol ); auto itr = _rexpool.begin(); if ( !rex_system_initialized() ) { @@ -859,10 +858,10 @@ namespace eosiosystem { } else { /// total_lendable > 0 if total_rex > 0 except in a rare case and due to rounding errors eosio_assert( itr->total_lendable.amount > 0, "lendable REX pool is empty" ); - const auto S0 = itr->total_lendable.amount; - const auto S1 = S0 + payment.amount; - const auto R0 = itr->total_rex.amount; - const auto R1 = (uint128_t(S1) * R0) / S0; + const int64_t S0 = itr->total_lendable.amount; + const int64_t S1 = S0 + payment.amount; + const int64_t R0 = itr->total_rex.amount; + const int64_t R1 = (uint128_t(S1) * R0) / S0; rex_received.amount = R1 - R0; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index aed756ed..d0b0ff3e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3800,12 +3800,25 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { auto rex_pool = get_rex_pool(); const asset payment = core_sym::from_string("30.0000"); + const asset zero_asset = core_sym::from_string("0.0000"); + const asset neg_asset = core_sym::from_string("-1.0000"); + BOOST_TEST_REQUIRE( 0 > neg_asset.get_amount() ); asset cur_frank_balance = get_rex_fund( frank ); int64_t expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount(), rex_pool["total_unlent"].as().get_amount(), payment.get_amount() ); const int64_t init_stake = get_cpu_limit( frank ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use core token"), + rentcpu( frank, bob, asset::from_string("10.0000 RND") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use core token"), + rentcpu( frank, bob, payment, asset::from_string("10.0000 RND") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), + rentcpu( frank, bob, zero_asset ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), + rentcpu( frank, bob, payment, neg_asset ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), + rentcpu( frank, bob, neg_asset, payment ) ); // create 2 cpu and 3 net loans BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, payment ) ); // loan_num = 1 BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment ) ); // loan_num = 2 @@ -4146,6 +4159,14 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); + produce_block( fc::days(20) ); + BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() + < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); + BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) + == get_producer_info(producer_names[20])["total_votes"].as() ); + const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); const int64_t init_alice_rex_stake = ( init_rex.get_amount() * current_rex_pool["total_lendable"].as().get_amount() ) From d1bcb7d5830a755a8cd7c78637df849ecc951bea Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 9 Dec 2018 19:37:23 -0500 Subject: [PATCH 0653/1048] Small changes --- eosio.system/src/rex.cpp | 46 +++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index dfebfe90..8fb641b3 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -65,7 +65,7 @@ namespace eosiosystem { * * @param owner - owner of staked tokens account name * @param receiver - account name that tokens have previously been staked to - * @param from_net - amount of tokens to be unstaked from Net bandwidth and used for REX purchase + * @param from_net - amount of tokens to be unstaked from NET bandwidth and used for REX purchase * @param from_cpu - amount of tokens to be unstaked from CPU bandwidth and used for REX purchase */ void system_contract::unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ) @@ -151,6 +151,11 @@ namespace eosiosystem { } } + /** + * @brief Cancels unfilled REX sell order by owner if one exists + * + * @param owner - owner account name + */ void system_contract::cnclrexorder( const name& owner ) { require_auth( owner ); @@ -376,7 +381,7 @@ namespace eosiosystem { * @param conin - the input connector balance * @param conout - the output connector balance * - * @return int64_t - conversion result output amount + * @return int64_t - conversion output amount */ int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) { @@ -395,12 +400,12 @@ namespace eosiosystem { } /** - * @brief Updates account Net and CPU resource limits + * @brief Updates account NET and CPU resource limits * * @param from - account charged for RAM if there is a need * @param receiver - account whose resource limits are updated - * @param delta_net - change in Net bandwidth limit - * @param delta_cpu - change in CPU limit + * @param delta_net - change in NET bandwidth limit + * @param delta_cpu - change in CPU bandwidth limit */ void system_contract::update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ) { @@ -438,7 +443,7 @@ namespace eosiosystem { } /** - * @brief Performs maintenance operations on expired Net and CPU loans and sellrex oders + * @brief Performs maintenance operations on expired NET and CPU loans and sellrex oders * * @param max - maximum number of each of the three categories to be processed */ @@ -452,12 +457,12 @@ namespace eosiosystem { _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, itr->total_staked.amount ); rt.total_lent.amount -= itr->total_staked.amount; - // rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); bool delete_loan = false; int64_t delta_stake = 0; - if( itr->payment <= itr->balance && rex_loans_available() ) { + if ( itr->payment <= itr->balance && rex_loans_available() ) { int64_t rented_tokens = 0; _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { rented_tokens = bancor_convert( rt.total_rent.amount, @@ -486,7 +491,7 @@ namespace eosiosystem { }; /// transfer from eosio.names to eosio.rex - if( rexi->namebid_proceeds.amount > 0 ) { + if ( rexi->namebid_proceeds.amount > 0 ) { channel_to_rex( names_account, rexi->namebid_proceeds ); _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { rt.namebid_proceeds.amount = 0; @@ -497,7 +502,7 @@ namespace eosiosystem { { rex_cpu_loan_table cpu_loans( _self, _self.value ); auto cpu_idx = cpu_loans.get_index<"byexpr"_n>(); - for( uint16_t i = 0; i < max; ++i ) { + for ( uint16_t i = 0; i < max; ++i ) { auto itr = cpu_idx.begin(); if ( itr == cpu_idx.end() || itr->expiration > current_time_point() ) break; @@ -516,7 +521,7 @@ namespace eosiosystem { auto net_idx = net_loans.get_index<"byexpr"_n>(); for ( uint16_t i = 0; i < max; ++i ) { auto itr = net_idx.begin(); - if( itr == net_idx.end() || itr->expiration > current_time_point() ) break; + if ( itr == net_idx.end() || itr->expiration > current_time_point() ) break; auto result = process_expired_loan( net_idx, itr ); if ( result.second != 0 ) @@ -589,11 +594,12 @@ namespace eosiosystem { } /** - * fill_rex_order processes an incoming of already scheduled sellrex order. If REX pool has enough core - * tokens (not frozen in loans), order can be filled. In this case, REX pool totals, user rex_balance - * and user vote_stake are updated. However, user voting power is not updated inside this function. The - * function returns success flag, order proceeds, and vote stake change. These are used later to finish - * order processing, which includes transfering proceeds and updating user vote weight. + * Processes an incoming or already scheduled sellrex order. If REX pool has enough core + * tokens not frozen in loans, order is filled. In this case, REX pool totals, user rex_balance + * and user vote_stake are updated. However, this function does not update user voting power. The + * function returns success flag, order proceeds, and vote stake delta. These are used later in a + * different function to complete order processing, i.e. transfer proceeds to user REX fund and + * update user vote weight. */ rex_order_outcome system_contract::fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { @@ -663,7 +669,7 @@ namespace eosiosystem { * @pre - owner REX fund has sufficient balance * * @param owner - owner account name - * @param amount - asset to be taken out of REX fund + * @param amount - tokens to be transfered out of REX fund */ void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { @@ -679,7 +685,7 @@ namespace eosiosystem { * @brief Transfers tokens to owner REX fund * * @param owner - owner account name - * @param amount - asset to be transfered to REX fund + * @param amount - tokens to be transfered to REX fund */ void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { @@ -698,7 +704,7 @@ namespace eosiosystem { } /** - * @brief Processes owner filled sellrex orders and updates vote weight + * @brief Processes owner filled sellrex order and updates vote weight * * Checks if user has a scheduled sellrex order that has been filled, completes its processing, * and deletes it. Processing entails transfering proceeds to user REX fund and updating user @@ -880,7 +886,7 @@ namespace eosiosystem { * @brief Updates owner REX balance upon buying REX tokens * * @param owner - account name of REX owner - * @param payment - amount core tokens paid for buying REX + * @param payment - amount core tokens paid to buy REX * @param rex_received - amount of purchased REX tokens * * @return asset - change in owner REX vote stake From 88baf0b32ea2fdc2c560f4f3d76df8b4552a23b8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 10 Dec 2018 23:15:09 -0500 Subject: [PATCH 0654/1048] Code cleaning, tests --- .../include/eosio.system/eosio.system.hpp | 1 + eosio.system/src/rex.cpp | 26 ++++++++++++------- tests/eosio.system_tests.cpp | 4 ++- 3 files changed, 20 insertions(+), 11 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 4188087f..6d2d4365 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -529,6 +529,7 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); + void check_voting_requirement( const name& owner )const; rex_order_outcome fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); void channel_to_rex( const name& from, const asset& amount ); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 8fb641b3..3a6df32f 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -52,7 +52,8 @@ namespace eosiosystem { require_auth( from ); eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); - eosio_assert( amount.amount > 0, "must use positive amount" ); + eosio_assert( 0 < amount.amount, "must use positive amount" ); + check_voting_requirement( from ); transfer_from_fund( from, amount ); const asset rex_received = add_to_rex_pool( amount ); const asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); @@ -75,11 +76,7 @@ namespace eosiosystem { eosio_assert( from_net.symbol == core_symbol() && from_cpu.symbol == core_symbol(), "asset must be core token" ); eosio_assert( (0 <= from_net.amount) && (0 <= from_cpu.amount) && (0 < from_net.amount || 0 < from_cpu.amount), "must unstake a positive amount to buy rex" ); - { - auto vitr = _voters.find( owner.value ); - eosio_assert( vitr != _voters.end() && ( vitr->proxy || vitr->producers.size() >= 21 ), - "must vote for proxy or at least 21 producers before buying REX" ); - } + check_voting_requirement( owner ); { del_bandwidth_table dbw_table( _self, owner.value ); @@ -114,10 +111,10 @@ namespace eosiosystem { */ void system_contract::sellrex( const name& from, const asset& rex ) { - runrex(2); - require_auth( from ); + runrex(2); + auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); eosio_assert( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); @@ -442,6 +439,13 @@ namespace eosiosystem { set_resource_limits( receiver.value, ram_bytes, net + delta_net, cpu + delta_cpu ); } + void system_contract::check_voting_requirement( const name& owner )const + { + auto vitr = _voters.find( owner.value ); + eosio_assert( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), + "must vote for at least 21 producers or for a proxy before buying REX" ); + } + /** * @brief Performs maintenance operations on expired NET and CPU loans and sellrex oders * @@ -673,7 +677,8 @@ namespace eosiosystem { */ void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { - eosio_assert( 0 < amount.amount, "must transfer positive amount from REX fund" ); + eosio_assert( 0 < amount.amount && amount.symbol == core_symbol(), + "must transfer positive amount from REX fund" ); auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); eosio_assert( amount <= itr->balance, "insufficient funds"); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { @@ -689,7 +694,8 @@ namespace eosiosystem { */ void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { - eosio_assert( 0 < amount.amount, "must transfer positive amount to REX fund" ); + eosio_assert( 0 < amount.amount && amount.symbol == core_symbol(), + "must transfer positive amount to REX fund" ); auto itr = _rexfunds.find( owner.value ); if ( itr == _rexfunds.end() ) { _rexfunds.emplace( owner, [&]( auto& fund ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d0b0ff3e..34f9db1c 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3499,7 +3499,7 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for proxy or at least 21 producers before buying REX"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), unstaketorex( alice, alice, net_stake, cpu_stake ) ); BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); @@ -4184,6 +4184,8 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), + buyrex( alice, core_sym::from_string("1.0000") ) ); } FC_LOG_AND_RETHROW() From 85e555a35abc66637429af92d3c4b0988f186285 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 11 Dec 2018 19:45:29 -0500 Subject: [PATCH 0655/1048] Small change --- eosio.system/src/rex.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 3a6df32f..86a4ae07 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -244,7 +244,7 @@ namespace eosiosystem { * @param amount - tokens to be withdrawn from loan fund */ void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) - { + { require_auth( from ); rex_cpu_loan_table cpu_loans( _self, _self.value ); @@ -272,7 +272,7 @@ namespace eosiosystem { * @param owner - owner of REX tokens */ void system_contract::updaterex( const name& owner ) - { + { require_auth( owner ); runrex(2); @@ -789,10 +789,10 @@ namespace eosiosystem { */ time_point_sec system_contract::get_rex_maturity() { - const uint32_t num_of_maturity_buckets = 4; + const uint32_t num_of_maturity_buckets = 5; static const uint32_t now = current_time_point_sec().utc_seconds; static const uint32_t r = now % seconds_per_day; - static const time_point_sec rms{ now - r + (num_of_maturity_buckets + 1) * seconds_per_day }; + static const time_point_sec rms{ now - r + num_of_maturity_buckets * seconds_per_day }; return rms; } @@ -899,9 +899,9 @@ namespace eosiosystem { */ asset system_contract::add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ) { - auto bitr = _rexbalance.find( owner.value ); asset init_rex_stake( 0, core_symbol() ); asset current_rex_stake( 0, core_symbol() ); + auto bitr = _rexbalance.find( owner.value ); if ( bitr == _rexbalance.end() ) { bitr = _rexbalance.emplace( owner, [&]( auto& rb ) { rb.owner = owner; From 86b4c240504868081f2234aee7c8d5bdae04748e Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 12 Dec 2018 16:23:14 -0500 Subject: [PATCH 0656/1048] use new cmake system and rc --- CMakeLists.txt | 59 ++++- UnitTestsExternalProject.txt | 17 -- contracts/CMakeLists.txt | 10 + .../eosio.bios}/CMakeLists.txt | 5 +- .../include/eosio.bios/eosio.bios.hpp | 2 +- .../eosio.bios}/src/eosio.bios.cpp | 0 .../eosio.msig}/CMakeLists.txt | 5 +- .../eosio.msig}/README.md | 0 .../include/eosio.msig/eosio.msig.hpp | 0 .../eosio.msig}/src/eosio.msig.cpp | 0 .../eosio.system}/CMakeLists.txt | 6 +- .../eosio.system}/README.md | 0 .../include/eosio.system/eosio.system.hpp | 232 +++++++++++++++++- .../include/eosio.system/exchange_state.hpp | 0 .../include/eosio.system/native.hpp | 0 .../eosio.system}/src/delegate_bandwidth.cpp | 58 +++-- .../eosio.system}/src/eosio.system.cpp | 21 +- .../eosio.system}/src/exchange_state.cpp | 0 .../eosio.system}/src/producer_pay.cpp | 1 + .../eosio.system}/src/voting.cpp | 4 + .../eosio.token}/CMakeLists.txt | 5 +- .../eosio.token}/README.md | 0 .../include/eosio.token/eosio.token.hpp | 0 .../eosio.token}/src/eosio.token.cpp | 0 .../eosio.wrap}/CMakeLists.txt | 5 +- .../eosio.wrap}/README.md | 0 .../include/eosio.wrap/eosio.wrap.hpp | 0 .../eosio.wrap}/src/eosio.wrap.cpp | 0 tests/contracts.hpp.in | 30 +-- 29 files changed, 369 insertions(+), 91 deletions(-) delete mode 100644 UnitTestsExternalProject.txt create mode 100644 contracts/CMakeLists.txt rename {eosio.bios => contracts/eosio.bios}/CMakeLists.txt (71%) rename {eosio.bios => contracts/eosio.bios}/include/eosio.bios/eosio.bios.hpp (100%) rename {eosio.bios => contracts/eosio.bios}/src/eosio.bios.cpp (100%) rename {eosio.msig => contracts/eosio.msig}/CMakeLists.txt (71%) rename {eosio.msig => contracts/eosio.msig}/README.md (100%) rename {eosio.msig => contracts/eosio.msig}/include/eosio.msig/eosio.msig.hpp (100%) rename {eosio.msig => contracts/eosio.msig}/src/eosio.msig.cpp (100%) rename {eosio.system => contracts/eosio.system}/CMakeLists.txt (61%) rename {eosio.system => contracts/eosio.system}/README.md (100%) rename {eosio.system => contracts/eosio.system}/include/eosio.system/eosio.system.hpp (58%) rename {eosio.system => contracts/eosio.system}/include/eosio.system/exchange_state.hpp (100%) rename {eosio.system => contracts/eosio.system}/include/eosio.system/native.hpp (100%) rename {eosio.system => contracts/eosio.system}/src/delegate_bandwidth.cpp (92%) rename {eosio.system => contracts/eosio.system}/src/eosio.system.cpp (94%) rename {eosio.system => contracts/eosio.system}/src/exchange_state.cpp (100%) rename {eosio.system => contracts/eosio.system}/src/producer_pay.cpp (99%) rename {eosio.system => contracts/eosio.system}/src/voting.cpp (98%) rename {eosio.token => contracts/eosio.token}/CMakeLists.txt (71%) rename {eosio.token => contracts/eosio.token}/README.md (100%) rename {eosio.token => contracts/eosio.token}/include/eosio.token/eosio.token.hpp (100%) rename {eosio.token => contracts/eosio.token}/src/eosio.token.cpp (100%) rename {eosio.wrap => contracts/eosio.wrap}/CMakeLists.txt (71%) rename {eosio.wrap => contracts/eosio.wrap}/README.md (100%) rename {eosio.wrap => contracts/eosio.wrap}/include/eosio.wrap/eosio.wrap.hpp (100%) rename {eosio.wrap => contracts/eosio.wrap}/src/eosio.wrap.cpp (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index c9646789..c24d1bb4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,12 +1,27 @@ cmake_minimum_required(VERSION 3.5) -project(eosio_contracts VERSION 1.5.1) -set(EOSIO_CDT_VERSION_MIN "1.4") -set(EOSIO_CDT_VERSION_SOFT_MAX "1.4") -#set(EOSIO_CDT_VERSION_HARD_MAX "") +project(eosio_contracts) + +set(VERSION_MAJOR 1) +set(VERSION_MINOR 6) +set(VERSION_PATCH 0) +set(VERSION_SUFFIX develop) + +if (VERSION_SUFFIX) + set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") +else() + set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +endif() + +include(ExternalProject) find_package(eosio.cdt) +message(STATUS "Building eosio.contracts v${VERSION_FULL}") + +set(EOSIO_CDT_VERSION_MIN "1.5") +set(EOSIO_CDT_VERSION_SOFT_MAX "1.5") + ### Check the version of eosio.cdt set(VERSION_MATCH_ERROR_MSG "") EOSIO_CHECK_VERSION(VERSION_OUTPUT "${EOSIO_CDT_VERSION}" @@ -29,12 +44,24 @@ else() set(TEST_BUILD_TYPE ${CMAKE_BUILD_TYPE}) endif() +ExternalProject_Add( + contracts_project + SOURCE_DIR ${CMAKE_SOURCE_DIR}/contracts + BINARY_DIR ${CMAKE_BINARY_DIR}/contracts + CMAKE_ARGS -DCMAKE_TOOLCHAIN_FILE=${EOSIO_CDT_ROOT}/lib/cmake/eosio.cdt/EosioWasmToolchain.cmake + UPDATE_COMMAND "" + PATCH_COMMAND "" + TEST_COMMAND "" + INSTALL_COMMAND "" + BUILD_ALWAYS 1 +) -add_subdirectory(eosio.bios) -add_subdirectory(eosio.msig) -add_subdirectory(eosio.wrap) -add_subdirectory(eosio.system) -add_subdirectory(eosio.token) +if (APPLE) + set(OPENSSL_ROOT "/usr/local/opt/openssl") +elseif (UNIX) + set(OPENSSL_ROOT "/usr/include/openssl") +endif() +set(SECP256K1_ROOT "/usr/local") if (APPLE) set(OPENSSL_ROOT "/usr/local/opt/openssl") @@ -43,4 +70,16 @@ elseif (UNIX) endif() set(SECP256K1_ROOT "/usr/local") -include(UnitTestsExternalProject.txt) +string(REPLACE ";" "|" TEST_FRAMEWORK_PATH "${CMAKE_FRAMEWORK_PATH}") +string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") + +ExternalProject_Add( + contracts_unit_tests + LIST_SEPARATOR | # Use the alternate list separator + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} + SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests + BINARY_DIR ${CMAKE_BINARY_DIR}/tests + BUILD_ALWAYS 1 + TEST_COMMAND "" + INSTALL_COMMAND "" +) diff --git a/UnitTestsExternalProject.txt b/UnitTestsExternalProject.txt deleted file mode 100644 index 30ba24fb..00000000 --- a/UnitTestsExternalProject.txt +++ /dev/null @@ -1,17 +0,0 @@ -include(ExternalProject) -find_package(Git REQUIRED) -include(GNUInstallDirs) - -string(REPLACE ";" "|" TEST_FRAMEWORK_PATH "${CMAKE_FRAMEWORK_PATH}") -string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") - -ExternalProject_Add( - contracts_unit_tests - LIST_SEPARATOR | # Use the alternate list separator - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} - SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests - BINARY_DIR ${CMAKE_BINARY_DIR}/tests - BUILD_ALWAYS 1 - TEST_COMMAND "" - INSTALL_COMMAND "" -) diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt new file mode 100644 index 00000000..7474785e --- /dev/null +++ b/contracts/CMakeLists.txt @@ -0,0 +1,10 @@ +project(contracts) + +set(EOSIO_WASM_OLD_BEHAVIOR "Off") +find_package(eosio.cdt) + +add_subdirectory(eosio.bios) +add_subdirectory(eosio.msig) +add_subdirectory(eosio.system) +add_subdirectory(eosio.token) +add_subdirectory(eosio.wrap) diff --git a/eosio.bios/CMakeLists.txt b/contracts/eosio.bios/CMakeLists.txt similarity index 71% rename from eosio.bios/CMakeLists.txt rename to contracts/eosio.bios/CMakeLists.txt index d4ed66f8..b8ce19a5 100644 --- a/eosio.bios/CMakeLists.txt +++ b/contracts/eosio.bios/CMakeLists.txt @@ -1,8 +1,9 @@ add_contract(eosio.bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) -target_include_directories(eosio.bios.wasm + +target_include_directories(eosio.bios PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -set_target_properties(eosio.bios.wasm +set_target_properties(eosio.bios PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp similarity index 100% rename from eosio.bios/include/eosio.bios/eosio.bios.hpp rename to contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 06c24a01..ebe7f23b 100644 --- a/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -1,9 +1,9 @@ #pragma once -#include #include #include #include #include +#include namespace eosio { using eosio::permission_level; diff --git a/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp similarity index 100% rename from eosio.bios/src/eosio.bios.cpp rename to contracts/eosio.bios/src/eosio.bios.cpp diff --git a/eosio.msig/CMakeLists.txt b/contracts/eosio.msig/CMakeLists.txt similarity index 71% rename from eosio.msig/CMakeLists.txt rename to contracts/eosio.msig/CMakeLists.txt index 84614e87..089587f2 100644 --- a/eosio.msig/CMakeLists.txt +++ b/contracts/eosio.msig/CMakeLists.txt @@ -1,8 +1,9 @@ add_contract(eosio.msig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) -target_include_directories(eosio.msig.wasm + +target_include_directories(eosio.msig PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -set_target_properties(eosio.msig.wasm +set_target_properties(eosio.msig PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/eosio.msig/README.md b/contracts/eosio.msig/README.md similarity index 100% rename from eosio.msig/README.md rename to contracts/eosio.msig/README.md diff --git a/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp similarity index 100% rename from eosio.msig/include/eosio.msig/eosio.msig.hpp rename to contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp diff --git a/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp similarity index 100% rename from eosio.msig/src/eosio.msig.cpp rename to contracts/eosio.msig/src/eosio.msig.cpp diff --git a/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt similarity index 61% rename from eosio.system/CMakeLists.txt rename to contracts/eosio.system/CMakeLists.txt index 66a9e312..6c8a4c5b 100644 --- a/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -1,10 +1,10 @@ add_contract(eosio.system eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) -#add_executable(eosio.system.wasm ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) -target_include_directories(eosio.system.wasm + +target_include_directories(eosio.system PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/../eosio.token/include) -set_target_properties(eosio.system.wasm +set_target_properties(eosio.system PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/eosio.system/README.md b/contracts/eosio.system/README.md similarity index 100% rename from eosio.system/README.md rename to contracts/eosio.system/README.md diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp similarity index 58% rename from eosio.system/include/eosio.system/eosio.system.hpp rename to contracts/eosio.system/include/eosio.system/eosio.system.hpp index 32ccdce7..4188087f 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -12,6 +12,7 @@ #include #include +#include namespace eosiosystem { @@ -23,6 +24,7 @@ namespace eosiosystem { using eosio::const_mem_fun; using eosio::block_timestamp; using eosio::time_point; + using eosio::time_point_sec; using eosio::microseconds; using eosio::datastream; @@ -173,10 +175,91 @@ namespace eosiosystem { typedef eosio::singleton< "global2"_n, eosio_global_state2 > global_state2_singleton; typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; - // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; + struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { + asset total_lent; /// total EOS in open rex_loans + asset total_unlent; /// total EOS available to be lent (connector) + asset total_rent; /// fees received in exchange for lent (connector) + asset total_lendable; /// total EOS that have been lent (total_unlent + total_lent) + asset total_rex; /// total number of REX shares allocated to contributors to total_lendable + asset namebid_proceeds; /// EOS to be transferred from namebids to REX pool + uint64_t loan_num = 0; /// increments with each new loan + + uint64_t primary_key()const { return 0; } + }; + + typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; + + struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { + name owner; + asset balance; + + uint64_t primary_key()const { return owner.value; } + }; + + typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; + + struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { + name owner; + asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote + asset rex_balance; /// the amount of REX owned by owner + int64_t matured_rex = 0; /// matured REX available for selling + std::deque> rex_maturities; /// REX daily maturity buckets + + uint64_t primary_key()const { return owner.value; } + }; + + typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; + + struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { + name from; + name receiver; + asset payment; + asset balance; + asset total_staked; + uint64_t loan_num; + eosio::time_point expiration; + + uint64_t primary_key()const { return loan_num; } + uint64_t by_expr()const { return expiration.elapsed.count(); } + uint64_t by_owner()const { return from.value; } + }; + + typedef eosio::multi_index< "cpuloan"_n, rex_loan, + indexed_by<"byexpr"_n, const_mem_fun>, + indexed_by<"byowner"_n, const_mem_fun> + > rex_cpu_loan_table; + + typedef eosio::multi_index< "netloan"_n, rex_loan, + indexed_by<"byexpr"_n, const_mem_fun>, + indexed_by<"byowner"_n, const_mem_fun> + > rex_net_loan_table; + + struct [[eosio::table,eosio::contract("eosio.system")]] rex_order { + name owner; + asset rex_requested; + asset proceeds; + asset stake_change; + eosio::time_point order_time; + bool is_open = true; + + void close() { is_open = false; } + uint64_t primary_key()const { return owner.value; } + uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } + }; + + typedef eosio::multi_index< "rexqueue"_n, rex_order, + indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; + + struct rex_order_outcome { + bool success; + asset proceeds; + asset stake_change; + }; + class [[eosio::contract("eosio.system")]] system_contract : public native { + private: voters_table _voters; producers_table _producers; @@ -188,6 +271,10 @@ namespace eosiosystem { eosio_global_state2 _gstate2; eosio_global_state3 _gstate3; rammarket _rammarket; + rex_pool_table _rexpool; + rex_fund_table _rexfunds; + rex_balance_table _rexbalance; + rex_order_table _rexorders; public: static constexpr eosio::name active_permission{"active"_n}; @@ -199,8 +286,10 @@ namespace eosiosystem { static constexpr eosio::name vpay_account{"eosio.vpay"_n}; static constexpr eosio::name names_account{"eosio.names"_n}; static constexpr eosio::name saving_account{"eosio.saving"_n}; + static constexpr eosio::name rex_account{"eosio.rex"_n}; static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); + static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); system_contract( name s, name code, datastream ds ); ~system_contract(); @@ -230,6 +319,108 @@ namespace eosiosystem { void delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + /** + * Deposits core tokens to user REX fund. All proceeds and expenses related to REX are added to + * or taken out of this fund. Inline token transfer from user balance is executed. + */ + [[eosio::action]] + void deposit( const name& owner, const asset& amount ); + + /** + * Withdraws core tokens from user REX fund. Inline token transfer to user balance is + * executed. + */ + [[eosio::action]] + void withdraw( const name& owner, const asset& amount ); + + /** + * Transfers core tokens from user REX fund and converts them to REX stake. + * A voting requirement must be satisfied before action can be executed. + * User votes are updated following this action. + */ + [[eosio::action]] + void buyrex( const name& from, const asset& amount ); + + /** + * Use staked core tokens to buy REX. + * A voting requirement must be satisfied before action can be executed. + * User votes are updated following this action. + */ + [[eosio::action]] + void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); + + /** + * Converts REX stake back into core tokens at current exchange rate. If order cannot be + * processed, it gets queued until there is enough in REX pool to fill order. + * If successful, user votes are updated. + */ + [[eosio::action]] + void sellrex( const name& from, const asset& rex ); + + /** + * Cancels queued sellrex order. Order cannot be cancelled once it's been filled. + */ + [[eosio::action]] + void cnclrexorder( const name& owner ); + + /** + * Use payment to rent as many SYS tokens as possible and stake them for either CPU or NET for the + * benefit of receiver, after 30 days the rented SYS delegation of CPU or NET will expire unless loan + * balance is larger than or equal to payment. + * + * If loan has enough balance, it gets renewed at current market price, otherwise, it is closed and + * remaining balance is refunded to loan owner. + * + * Owner can fund or defund a loan at any time before its expiration. + * + * All loan expenses and refunds come out of or are added to owner's REX fund. + */ + [[eosio::action]] + void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); + [[eosio::action]] + void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); + + /** + * Loan owner funds a given CPU or NET loan. + */ + [[eosio::action]] + void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); + [[eosio::action]] + void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); + /** + * Loan owner defunds a given CPU or NET loan. + */ + [[eosio::action]] + void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); + [[eosio::action]] + void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); + + /** + * Updates REX vote stake of owner to its current value. + */ + [[eosio::action]] + void updaterex( const name& owner ); + + /** + * Processes max CPU loans, max NET loans, and max queued sellrex orders. + * Action does not execute anything related to a specific user. + */ + [[eosio::action]] + void rexexec( const name& user, uint16_t max ); + + /** + * Consolidate REX maturity buckets into one that can be sold only 4 days + * from the end of today. + */ + [[eosio::action]] + void consolidate( const name& owner ); + + /** + * Deletes owner records from REX tables and frees used RAM. + * Owner must not have an outstanding REX balance. + */ + [[eosio::action]] + void closerex( const name& owner ); /** * Decreases the total tokens delegated by from to receiver and/or @@ -316,8 +507,9 @@ namespace eosiosystem { [[eosio::action]] void bidrefund( name bidder, name newname ); - + private: + // Implementation details: static symbol get_core_symbol( const rammarket& rm ) { @@ -329,23 +521,45 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); static time_point current_time_point(); + static time_point_sec current_time_point_sec(); static block_timestamp current_block_time(); - symbol core_symbol()const; - void update_ram_supply(); - //defined in delegate_bandwidth.cpp + // defined in rex.cpp + void runrex( uint16_t max ); + void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); + rex_order_outcome fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); + asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); + void channel_to_rex( const name& from, const asset& amount ); + void channel_namebid_to_rex( const int64_t highest_bid ); + template + int64_t rent_rex( T& table, const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); + template + void fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ); + template + void defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ); + void transfer_from_fund( const name& owner, const asset& amount ); + void transfer_to_fund( const name& owner, const asset& amount ); + bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end() && rex_available(); } + bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } + bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } + static time_point_sec get_rex_maturity(); + asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); + asset add_to_rex_pool( const asset& payment ); + void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); + void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, + const asset& rex_in_sell_order ); + + // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + void update_voting_power( const name& voter, const asset& total_update ); - //defined in voting.hpp + // defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); void update_votes( const name voter, const name proxy, const std::vector& producers, bool voting ); - - // defined in voting.cpp void propagate_weight_change( const voter_info& voter ); - double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, time_point ct, double shares_rate, bool reset_to_zero = false ); diff --git a/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp similarity index 100% rename from eosio.system/include/eosio.system/exchange_state.hpp rename to contracts/eosio.system/include/eosio.system/exchange_state.hpp diff --git a/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp similarity index 100% rename from eosio.system/include/eosio.system/native.hpp rename to contracts/eosio.system/include/eosio.system/native.hpp diff --git a/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp similarity index 92% rename from eosio.system/src/delegate_bandwidth.cpp rename to contracts/eosio.system/src/delegate_bandwidth.cpp index dfe073a6..2fd293a6 100644 --- a/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -37,6 +37,7 @@ namespace eosiosystem { asset cpu_weight; int64_t ram_bytes = 0; + bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0 && ram_bytes == 0; } uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -53,6 +54,7 @@ namespace eosiosystem { asset net_weight; asset cpu_weight; + bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0; } uint64_t primary_key()const { return to.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -66,6 +68,7 @@ namespace eosiosystem { eosio::asset net_amount; eosio::asset cpu_amount; + bool is_empty()const { return net_amount.amount == 0 && cpu_amount.amount == 0; } uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -131,8 +134,9 @@ namespace eosiosystem { token_account, { {payer, active_permission} }, { payer, ramfee_account, fee, std::string("ram fee") } ); + channel_to_rex( ramfee_account, fee ); } - + int64_t bytes_out; const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); @@ -211,6 +215,7 @@ namespace eosiosystem { token_account, { {account, active_permission} }, { account, ramfee_account, asset(fee, core_symbol()), std::string("sell ram fee") } ); + channel_to_rex( ramfee_account, asset(fee, core_symbol() )); } } @@ -256,7 +261,7 @@ namespace eosiosystem { } eosio_assert( 0 <= itr->net_weight.amount, "insufficient staked net bandwidth" ); eosio_assert( 0 <= itr->cpu_weight.amount, "insufficient staked cpu bandwidth" ); - if ( itr->net_weight.amount == 0 && itr->cpu_weight.amount == 0 ) { + if ( itr->is_empty() ) { del_tbl.erase( itr ); } } // itr can be invalid, should go out of scope @@ -285,7 +290,7 @@ namespace eosiosystem { set_resource_limits( receiver.value, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) { + if ( tot_itr->is_empty() ) { totals_tbl.erase( tot_itr ); } } // tot_itr can be invalid, should go out of scope @@ -331,7 +336,7 @@ namespace eosiosystem { eosio_assert( 0 <= req->net_amount.amount, "negative net refund amount" ); //should never happen eosio_assert( 0 <= req->cpu_amount.amount, "negative cpu refund amount" ); //should never happen - if ( req->net_amount.amount == 0 && req->cpu_amount.amount == 0 ) { + if ( req->is_empty() ) { refunds_tbl.erase( req ); need_deferred_trx = false; } else { @@ -380,28 +385,31 @@ namespace eosiosystem { } } - // update voting power - { - asset total_update = stake_net_delta + stake_cpu_delta; - auto from_voter = _voters.find( from.value ); - if( from_voter == _voters.end() ) { - from_voter = _voters.emplace( from, [&]( auto& v ) { - v.owner = from; - v.staked = total_update.amount; - }); - } else { - _voters.modify( from_voter, same_payer, [&]( auto& v ) { - v.staked += total_update.amount; - }); - } - eosio_assert( 0 <= from_voter->staked, "stake for voting cannot be negative"); - if( from == "b1"_n ) { - validate_b1_vesting( from_voter->staked ); - } + update_voting_power( from, stake_net_delta + stake_cpu_delta ); + } - if( from_voter->producers.size() || from_voter->proxy ) { - update_votes( from, from_voter->proxy, from_voter->producers, false ); - } + void system_contract::update_voting_power( const name& voter, const asset& total_update ) + { + auto voter_itr = _voters.find( voter.value ); + if( voter_itr == _voters.end() ) { + voter_itr = _voters.emplace( voter, [&]( auto& v ) { + v.owner = voter; + v.staked = total_update.amount; + }); + } else { + _voters.modify( voter_itr, same_payer, [&]( auto& v ) { + v.staked += total_update.amount; + }); + } + + eosio_assert( 0 <= voter_itr->staked, "stake for voting cannot be negative"); + + if( voter == "b1"_n ) { + validate_b1_vesting( voter_itr->staked ); + } + + if( voter_itr->producers.size() || voter_itr->proxy ) { + update_votes( voter, voter_itr->proxy, voter_itr->producers, false ); } } diff --git a/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp similarity index 94% rename from eosio.system/src/eosio.system.cpp rename to contracts/eosio.system/src/eosio.system.cpp index eb99a208..9d74c143 100644 --- a/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -6,7 +6,7 @@ #include "delegate_bandwidth.cpp" #include "voting.cpp" #include "exchange_state.cpp" - +#include "rex.cpp" namespace eosiosystem { @@ -18,9 +18,12 @@ namespace eosiosystem { _global(_self, _self.value), _global2(_self, _self.value), _global3(_self, _self.value), - _rammarket(_self, _self.value) + _rammarket(_self, _self.value), + _rexpool(_self, _self.value), + _rexfunds(_self, _self.value), + _rexbalance(_self, _self.value), + _rexorders(_self, _self.value) { - //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; @@ -38,6 +41,11 @@ namespace eosiosystem { return ct; } + time_point_sec system_contract::current_time_point_sec() { + const static time_point_sec cts{ current_time_point() }; + return cts; + } + block_timestamp system_contract::current_block_time() { const static block_timestamp cbt{ current_time_point() }; return cbt; @@ -300,7 +308,11 @@ namespace eosiosystem { m.quote.balance.amount = system_token_supply.amount / 1000; m.quote.balance.symbol = core; }); + + INLINE_ACTION_SENDER(eosio::token, open)( token_account, { _self, active_permission }, + { rex_account, core, _self } ); } + } /// eosio.system @@ -309,6 +321,9 @@ EOSIO_DISPATCH( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) + // rex.cpp + (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) + (defcpuloan)(defnetloan)(updaterex)(consolidate)(rexexec)(closerex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp similarity index 100% rename from eosio.system/src/exchange_state.cpp rename to contracts/eosio.system/src/exchange_state.cpp diff --git a/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp similarity index 99% rename from eosio.system/src/producer_pay.cpp rename to contracts/eosio.system/src/producer_pay.cpp index 287ab8b6..70dd093b 100644 --- a/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -65,6 +65,7 @@ namespace eosiosystem { (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) ) { _gstate.last_name_close = timestamp; + channel_namebid_to_rex( highest->high_bid ); idx.modify( highest, same_payer, [&]( auto& b ){ b.high_bid = -b.high_bid; }); diff --git a/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp similarity index 98% rename from eosio.system/src/voting.cpp rename to contracts/eosio.system/src/voting.cpp index 2ad09981..35cc76a2 100644 --- a/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -194,6 +194,10 @@ namespace eosiosystem { */ void system_contract::voteproducer( const name voter_name, const name proxy, const std::vector& producers ) { require_auth( voter_name ); + auto rex_itr = _rexbalance.find( voter_name.value ); + if( rex_itr != _rexbalance.end() && rex_itr->rex_balance.amount > 0 ) { + eosio_assert( proxy || producers.size() >= 21, "voter holding REX must vote for a proxy or at least 21 producers"); + } update_votes( voter_name, proxy, producers, true ); } diff --git a/eosio.token/CMakeLists.txt b/contracts/eosio.token/CMakeLists.txt similarity index 71% rename from eosio.token/CMakeLists.txt rename to contracts/eosio.token/CMakeLists.txt index 5582d04a..25c56b51 100644 --- a/eosio.token/CMakeLists.txt +++ b/contracts/eosio.token/CMakeLists.txt @@ -1,8 +1,9 @@ add_contract(eosio.token eosio.token ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.token.cpp) -target_include_directories(eosio.token.wasm + +target_include_directories(eosio.token PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -set_target_properties(eosio.token.wasm +set_target_properties(eosio.token PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/eosio.token/README.md b/contracts/eosio.token/README.md similarity index 100% rename from eosio.token/README.md rename to contracts/eosio.token/README.md diff --git a/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp similarity index 100% rename from eosio.token/include/eosio.token/eosio.token.hpp rename to contracts/eosio.token/include/eosio.token/eosio.token.hpp diff --git a/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp similarity index 100% rename from eosio.token/src/eosio.token.cpp rename to contracts/eosio.token/src/eosio.token.cpp diff --git a/eosio.wrap/CMakeLists.txt b/contracts/eosio.wrap/CMakeLists.txt similarity index 71% rename from eosio.wrap/CMakeLists.txt rename to contracts/eosio.wrap/CMakeLists.txt index d67ef83a..6d064bff 100644 --- a/eosio.wrap/CMakeLists.txt +++ b/contracts/eosio.wrap/CMakeLists.txt @@ -1,8 +1,9 @@ add_contract(eosio.wrap eosio.wrap ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.wrap.cpp) -target_include_directories(eosio.wrap.wasm + +target_include_directories(eosio.wrap PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) -set_target_properties(eosio.wrap.wasm +set_target_properties(eosio.wrap PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") diff --git a/eosio.wrap/README.md b/contracts/eosio.wrap/README.md similarity index 100% rename from eosio.wrap/README.md rename to contracts/eosio.wrap/README.md diff --git a/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp similarity index 100% rename from eosio.wrap/include/eosio.wrap/eosio.wrap.hpp rename to contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp diff --git a/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp similarity index 100% rename from eosio.wrap/src/eosio.wrap.cpp rename to contracts/eosio.wrap/src/eosio.wrap.cpp diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index efe4950d..acff5b87 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -4,21 +4,21 @@ namespace eosio { namespace testing { struct contracts { - static std::vector system_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.wast"); } - static std::vector system_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.system/eosio.system.abi"); } - static std::vector token_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.wast"); } - static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.token/eosio.token.abi"); } - static std::vector msig_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.wast"); } - static std::vector msig_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.msig/eosio.msig.abi"); } - static std::vector wrap_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.wrap/eosio.wrap.wasm"); } - static std::string wrap_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.wrap/eosio.wrap.wast"); } - static std::vector wrap_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.wrap/eosio.wrap.abi"); } - static std::vector bios_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.wasm"); } - static std::string bios_wast() { return read_wast("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.wast"); } - static std::vector bios_abi() { return read_abi("${CMAKE_BINARY_DIR}/../eosio.bios/eosio.bios.abi"); } + static std::vector system_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.system/eosio.system.wasm"); } + static std::string system_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.system/eosio.system.wast"); } + static std::vector system_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.system/eosio.system.abi"); } + static std::vector token_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.token/eosio.token.wasm"); } + static std::string token_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.token/eosio.token.wast"); } + static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.token/eosio.token.abi"); } + static std::vector msig_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.msig/eosio.msig.wasm"); } + static std::string msig_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.msig/eosio.msig.wast"); } + static std::vector msig_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.msig/eosio.msig.abi"); } + static std::vector wrap_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.wrap/eosio.wrap.wasm"); } + static std::string wrap_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.wrap/eosio.wrap.wast"); } + static std::vector wrap_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.wrap/eosio.wrap.abi"); } + static std::vector bios_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.bios/eosio.bios.wasm"); } + static std::string bios_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.bios/eosio.bios.wast"); } + static std::vector bios_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.bios/eosio.bios.abi"); } struct util { static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } From 4a170c85827da4d521e522da189c95ccea368cdf Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 12 Dec 2018 16:32:09 -0500 Subject: [PATCH 0657/1048] fixed to use develop contracts --- contracts/eosio.bios/CMakeLists.txt | 0 .../include/eosio.bios/eosio.bios.hpp | 2 +- contracts/eosio.bios/src/eosio.bios.cpp | 0 contracts/eosio.msig/CMakeLists.txt | 0 contracts/eosio.msig/README.md | 0 .../include/eosio.msig/eosio.msig.hpp | 0 contracts/eosio.msig/src/eosio.msig.cpp | 0 contracts/eosio.system/CMakeLists.txt | 0 contracts/eosio.system/README.md | 0 .../include/eosio.system/eosio.system.hpp | 232 +----------------- .../include/eosio.system/exchange_state.hpp | 0 .../include/eosio.system/native.hpp | 0 .../eosio.system/src/delegate_bandwidth.cpp | 58 ++--- contracts/eosio.system/src/eosio.system.cpp | 21 +- contracts/eosio.system/src/exchange_state.cpp | 0 contracts/eosio.system/src/producer_pay.cpp | 1 - contracts/eosio.system/src/voting.cpp | 4 - contracts/eosio.token/CMakeLists.txt | 0 contracts/eosio.token/README.md | 0 .../include/eosio.token/eosio.token.hpp | 0 contracts/eosio.token/src/eosio.token.cpp | 0 contracts/eosio.wrap/CMakeLists.txt | 0 contracts/eosio.wrap/README.md | 0 .../include/eosio.wrap/eosio.wrap.hpp | 0 contracts/eosio.wrap/src/eosio.wrap.cpp | 0 25 files changed, 38 insertions(+), 280 deletions(-) mode change 100644 => 100755 contracts/eosio.bios/CMakeLists.txt mode change 100644 => 100755 contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp mode change 100644 => 100755 contracts/eosio.bios/src/eosio.bios.cpp mode change 100644 => 100755 contracts/eosio.msig/CMakeLists.txt mode change 100644 => 100755 contracts/eosio.msig/README.md mode change 100644 => 100755 contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp mode change 100644 => 100755 contracts/eosio.msig/src/eosio.msig.cpp mode change 100644 => 100755 contracts/eosio.system/CMakeLists.txt mode change 100644 => 100755 contracts/eosio.system/README.md mode change 100644 => 100755 contracts/eosio.system/include/eosio.system/eosio.system.hpp mode change 100644 => 100755 contracts/eosio.system/include/eosio.system/exchange_state.hpp mode change 100644 => 100755 contracts/eosio.system/include/eosio.system/native.hpp mode change 100644 => 100755 contracts/eosio.system/src/delegate_bandwidth.cpp mode change 100644 => 100755 contracts/eosio.system/src/eosio.system.cpp mode change 100644 => 100755 contracts/eosio.system/src/exchange_state.cpp mode change 100644 => 100755 contracts/eosio.system/src/producer_pay.cpp mode change 100644 => 100755 contracts/eosio.system/src/voting.cpp mode change 100644 => 100755 contracts/eosio.token/CMakeLists.txt mode change 100644 => 100755 contracts/eosio.token/README.md mode change 100644 => 100755 contracts/eosio.token/include/eosio.token/eosio.token.hpp mode change 100644 => 100755 contracts/eosio.token/src/eosio.token.cpp mode change 100644 => 100755 contracts/eosio.wrap/CMakeLists.txt mode change 100644 => 100755 contracts/eosio.wrap/README.md mode change 100644 => 100755 contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp mode change 100644 => 100755 contracts/eosio.wrap/src/eosio.wrap.cpp diff --git a/contracts/eosio.bios/CMakeLists.txt b/contracts/eosio.bios/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp old mode 100644 new mode 100755 index ebe7f23b..06c24a01 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -1,9 +1,9 @@ #pragma once +#include #include #include #include #include -#include namespace eosio { using eosio::permission_level; diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.msig/CMakeLists.txt b/contracts/eosio.msig/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/contracts/eosio.msig/README.md b/contracts/eosio.msig/README.md old mode 100644 new mode 100755 diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/contracts/eosio.system/README.md b/contracts/eosio.system/README.md old mode 100644 new mode 100755 diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp old mode 100644 new mode 100755 index 4188087f..32ccdce7 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -12,7 +12,6 @@ #include #include -#include namespace eosiosystem { @@ -24,7 +23,6 @@ namespace eosiosystem { using eosio::const_mem_fun; using eosio::block_timestamp; using eosio::time_point; - using eosio::time_point_sec; using eosio::microseconds; using eosio::datastream; @@ -175,91 +173,10 @@ namespace eosiosystem { typedef eosio::singleton< "global2"_n, eosio_global_state2 > global_state2_singleton; typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; + // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; - struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { - asset total_lent; /// total EOS in open rex_loans - asset total_unlent; /// total EOS available to be lent (connector) - asset total_rent; /// fees received in exchange for lent (connector) - asset total_lendable; /// total EOS that have been lent (total_unlent + total_lent) - asset total_rex; /// total number of REX shares allocated to contributors to total_lendable - asset namebid_proceeds; /// EOS to be transferred from namebids to REX pool - uint64_t loan_num = 0; /// increments with each new loan - - uint64_t primary_key()const { return 0; } - }; - - typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; - - struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { - name owner; - asset balance; - - uint64_t primary_key()const { return owner.value; } - }; - - typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; - - struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { - name owner; - asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote - asset rex_balance; /// the amount of REX owned by owner - int64_t matured_rex = 0; /// matured REX available for selling - std::deque> rex_maturities; /// REX daily maturity buckets - - uint64_t primary_key()const { return owner.value; } - }; - - typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; - - struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { - name from; - name receiver; - asset payment; - asset balance; - asset total_staked; - uint64_t loan_num; - eosio::time_point expiration; - - uint64_t primary_key()const { return loan_num; } - uint64_t by_expr()const { return expiration.elapsed.count(); } - uint64_t by_owner()const { return from.value; } - }; - - typedef eosio::multi_index< "cpuloan"_n, rex_loan, - indexed_by<"byexpr"_n, const_mem_fun>, - indexed_by<"byowner"_n, const_mem_fun> - > rex_cpu_loan_table; - - typedef eosio::multi_index< "netloan"_n, rex_loan, - indexed_by<"byexpr"_n, const_mem_fun>, - indexed_by<"byowner"_n, const_mem_fun> - > rex_net_loan_table; - - struct [[eosio::table,eosio::contract("eosio.system")]] rex_order { - name owner; - asset rex_requested; - asset proceeds; - asset stake_change; - eosio::time_point order_time; - bool is_open = true; - - void close() { is_open = false; } - uint64_t primary_key()const { return owner.value; } - uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } - }; - - typedef eosio::multi_index< "rexqueue"_n, rex_order, - indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; - - struct rex_order_outcome { - bool success; - asset proceeds; - asset stake_change; - }; - class [[eosio::contract("eosio.system")]] system_contract : public native { - private: voters_table _voters; producers_table _producers; @@ -271,10 +188,6 @@ namespace eosiosystem { eosio_global_state2 _gstate2; eosio_global_state3 _gstate3; rammarket _rammarket; - rex_pool_table _rexpool; - rex_fund_table _rexfunds; - rex_balance_table _rexbalance; - rex_order_table _rexorders; public: static constexpr eosio::name active_permission{"active"_n}; @@ -286,10 +199,8 @@ namespace eosiosystem { static constexpr eosio::name vpay_account{"eosio.vpay"_n}; static constexpr eosio::name names_account{"eosio.names"_n}; static constexpr eosio::name saving_account{"eosio.saving"_n}; - static constexpr eosio::name rex_account{"eosio.rex"_n}; static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); - static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); system_contract( name s, name code, datastream ds ); ~system_contract(); @@ -319,108 +230,6 @@ namespace eosiosystem { void delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); - /** - * Deposits core tokens to user REX fund. All proceeds and expenses related to REX are added to - * or taken out of this fund. Inline token transfer from user balance is executed. - */ - [[eosio::action]] - void deposit( const name& owner, const asset& amount ); - - /** - * Withdraws core tokens from user REX fund. Inline token transfer to user balance is - * executed. - */ - [[eosio::action]] - void withdraw( const name& owner, const asset& amount ); - - /** - * Transfers core tokens from user REX fund and converts them to REX stake. - * A voting requirement must be satisfied before action can be executed. - * User votes are updated following this action. - */ - [[eosio::action]] - void buyrex( const name& from, const asset& amount ); - - /** - * Use staked core tokens to buy REX. - * A voting requirement must be satisfied before action can be executed. - * User votes are updated following this action. - */ - [[eosio::action]] - void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); - - /** - * Converts REX stake back into core tokens at current exchange rate. If order cannot be - * processed, it gets queued until there is enough in REX pool to fill order. - * If successful, user votes are updated. - */ - [[eosio::action]] - void sellrex( const name& from, const asset& rex ); - - /** - * Cancels queued sellrex order. Order cannot be cancelled once it's been filled. - */ - [[eosio::action]] - void cnclrexorder( const name& owner ); - - /** - * Use payment to rent as many SYS tokens as possible and stake them for either CPU or NET for the - * benefit of receiver, after 30 days the rented SYS delegation of CPU or NET will expire unless loan - * balance is larger than or equal to payment. - * - * If loan has enough balance, it gets renewed at current market price, otherwise, it is closed and - * remaining balance is refunded to loan owner. - * - * Owner can fund or defund a loan at any time before its expiration. - * - * All loan expenses and refunds come out of or are added to owner's REX fund. - */ - [[eosio::action]] - void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); - [[eosio::action]] - void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); - - /** - * Loan owner funds a given CPU or NET loan. - */ - [[eosio::action]] - void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); - [[eosio::action]] - void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); - /** - * Loan owner defunds a given CPU or NET loan. - */ - [[eosio::action]] - void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); - [[eosio::action]] - void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); - - /** - * Updates REX vote stake of owner to its current value. - */ - [[eosio::action]] - void updaterex( const name& owner ); - - /** - * Processes max CPU loans, max NET loans, and max queued sellrex orders. - * Action does not execute anything related to a specific user. - */ - [[eosio::action]] - void rexexec( const name& user, uint16_t max ); - - /** - * Consolidate REX maturity buckets into one that can be sold only 4 days - * from the end of today. - */ - [[eosio::action]] - void consolidate( const name& owner ); - - /** - * Deletes owner records from REX tables and frees used RAM. - * Owner must not have an outstanding REX balance. - */ - [[eosio::action]] - void closerex( const name& owner ); /** * Decreases the total tokens delegated by from to receiver and/or @@ -507,9 +316,8 @@ namespace eosiosystem { [[eosio::action]] void bidrefund( name bidder, name newname ); - - private: + private: // Implementation details: static symbol get_core_symbol( const rammarket& rm ) { @@ -521,45 +329,23 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); static time_point current_time_point(); - static time_point_sec current_time_point_sec(); static block_timestamp current_block_time(); + symbol core_symbol()const; + void update_ram_supply(); - // defined in rex.cpp - void runrex( uint16_t max ); - void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); - rex_order_outcome fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); - asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); - void channel_to_rex( const name& from, const asset& amount ); - void channel_namebid_to_rex( const int64_t highest_bid ); - template - int64_t rent_rex( T& table, const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); - template - void fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ); - template - void defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ); - void transfer_from_fund( const name& owner, const asset& amount ); - void transfer_to_fund( const name& owner, const asset& amount ); - bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end() && rex_available(); } - bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } - bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } - static time_point_sec get_rex_maturity(); - asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); - asset add_to_rex_pool( const asset& payment ); - void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); - void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, - const asset& rex_in_sell_order ); - - // defined in delegate_bandwidth.cpp + //defined in delegate_bandwidth.cpp void changebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); - void update_voting_power( const name& voter, const asset& total_update ); - // defined in voting.hpp + //defined in voting.hpp void update_elected_producers( block_timestamp timestamp ); void update_votes( const name voter, const name proxy, const std::vector& producers, bool voting ); + + // defined in voting.cpp void propagate_weight_change( const voter_info& voter ); + double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, time_point ct, double shares_rate, bool reset_to_zero = false ); diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp old mode 100644 new mode 100755 index 2fd293a6..dfe073a6 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -37,7 +37,6 @@ namespace eosiosystem { asset cpu_weight; int64_t ram_bytes = 0; - bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0 && ram_bytes == 0; } uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -54,7 +53,6 @@ namespace eosiosystem { asset net_weight; asset cpu_weight; - bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0; } uint64_t primary_key()const { return to.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -68,7 +66,6 @@ namespace eosiosystem { eosio::asset net_amount; eosio::asset cpu_amount; - bool is_empty()const { return net_amount.amount == 0 && cpu_amount.amount == 0; } uint64_t primary_key()const { return owner.value; } // explicit serialization macro is not necessary, used here only to improve compilation time @@ -134,9 +131,8 @@ namespace eosiosystem { token_account, { {payer, active_permission} }, { payer, ramfee_account, fee, std::string("ram fee") } ); - channel_to_rex( ramfee_account, fee ); } - + int64_t bytes_out; const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); @@ -215,7 +211,6 @@ namespace eosiosystem { token_account, { {account, active_permission} }, { account, ramfee_account, asset(fee, core_symbol()), std::string("sell ram fee") } ); - channel_to_rex( ramfee_account, asset(fee, core_symbol() )); } } @@ -261,7 +256,7 @@ namespace eosiosystem { } eosio_assert( 0 <= itr->net_weight.amount, "insufficient staked net bandwidth" ); eosio_assert( 0 <= itr->cpu_weight.amount, "insufficient staked cpu bandwidth" ); - if ( itr->is_empty() ) { + if ( itr->net_weight.amount == 0 && itr->cpu_weight.amount == 0 ) { del_tbl.erase( itr ); } } // itr can be invalid, should go out of scope @@ -290,7 +285,7 @@ namespace eosiosystem { set_resource_limits( receiver.value, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); - if ( tot_itr->is_empty() ) { + if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) { totals_tbl.erase( tot_itr ); } } // tot_itr can be invalid, should go out of scope @@ -336,7 +331,7 @@ namespace eosiosystem { eosio_assert( 0 <= req->net_amount.amount, "negative net refund amount" ); //should never happen eosio_assert( 0 <= req->cpu_amount.amount, "negative cpu refund amount" ); //should never happen - if ( req->is_empty() ) { + if ( req->net_amount.amount == 0 && req->cpu_amount.amount == 0 ) { refunds_tbl.erase( req ); need_deferred_trx = false; } else { @@ -385,31 +380,28 @@ namespace eosiosystem { } } - update_voting_power( from, stake_net_delta + stake_cpu_delta ); - } - - void system_contract::update_voting_power( const name& voter, const asset& total_update ) - { - auto voter_itr = _voters.find( voter.value ); - if( voter_itr == _voters.end() ) { - voter_itr = _voters.emplace( voter, [&]( auto& v ) { - v.owner = voter; - v.staked = total_update.amount; - }); - } else { - _voters.modify( voter_itr, same_payer, [&]( auto& v ) { - v.staked += total_update.amount; - }); - } - - eosio_assert( 0 <= voter_itr->staked, "stake for voting cannot be negative"); - - if( voter == "b1"_n ) { - validate_b1_vesting( voter_itr->staked ); - } + // update voting power + { + asset total_update = stake_net_delta + stake_cpu_delta; + auto from_voter = _voters.find( from.value ); + if( from_voter == _voters.end() ) { + from_voter = _voters.emplace( from, [&]( auto& v ) { + v.owner = from; + v.staked = total_update.amount; + }); + } else { + _voters.modify( from_voter, same_payer, [&]( auto& v ) { + v.staked += total_update.amount; + }); + } + eosio_assert( 0 <= from_voter->staked, "stake for voting cannot be negative"); + if( from == "b1"_n ) { + validate_b1_vesting( from_voter->staked ); + } - if( voter_itr->producers.size() || voter_itr->proxy ) { - update_votes( voter, voter_itr->proxy, voter_itr->producers, false ); + if( from_voter->producers.size() || from_voter->proxy ) { + update_votes( from, from_voter->proxy, from_voter->producers, false ); + } } } diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp old mode 100644 new mode 100755 index 9d74c143..eb99a208 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -6,7 +6,7 @@ #include "delegate_bandwidth.cpp" #include "voting.cpp" #include "exchange_state.cpp" -#include "rex.cpp" + namespace eosiosystem { @@ -18,12 +18,9 @@ namespace eosiosystem { _global(_self, _self.value), _global2(_self, _self.value), _global3(_self, _self.value), - _rammarket(_self, _self.value), - _rexpool(_self, _self.value), - _rexfunds(_self, _self.value), - _rexbalance(_self, _self.value), - _rexorders(_self, _self.value) + _rammarket(_self, _self.value) { + //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; @@ -41,11 +38,6 @@ namespace eosiosystem { return ct; } - time_point_sec system_contract::current_time_point_sec() { - const static time_point_sec cts{ current_time_point() }; - return cts; - } - block_timestamp system_contract::current_block_time() { const static block_timestamp cbt{ current_time_point() }; return cbt; @@ -308,11 +300,7 @@ namespace eosiosystem { m.quote.balance.amount = system_token_supply.amount / 1000; m.quote.balance.symbol = core; }); - - INLINE_ACTION_SENDER(eosio::token, open)( token_account, { _self, active_permission }, - { rex_account, core, _self } ); } - } /// eosio.system @@ -321,9 +309,6 @@ EOSIO_DISPATCH( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) - // rex.cpp - (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) - (defcpuloan)(defnetloan)(updaterex)(consolidate)(rexexec)(closerex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp old mode 100644 new mode 100755 index 70dd093b..287ab8b6 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -65,7 +65,6 @@ namespace eosiosystem { (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) ) { _gstate.last_name_close = timestamp; - channel_namebid_to_rex( highest->high_bid ); idx.modify( highest, same_payer, [&]( auto& b ){ b.high_bid = -b.high_bid; }); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp old mode 100644 new mode 100755 index 35cc76a2..2ad09981 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -194,10 +194,6 @@ namespace eosiosystem { */ void system_contract::voteproducer( const name voter_name, const name proxy, const std::vector& producers ) { require_auth( voter_name ); - auto rex_itr = _rexbalance.find( voter_name.value ); - if( rex_itr != _rexbalance.end() && rex_itr->rex_balance.amount > 0 ) { - eosio_assert( proxy || producers.size() >= 21, "voter holding REX must vote for a proxy or at least 21 producers"); - } update_votes( voter_name, proxy, producers, true ); } diff --git a/contracts/eosio.token/CMakeLists.txt b/contracts/eosio.token/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/contracts/eosio.token/README.md b/contracts/eosio.token/README.md old mode 100644 new mode 100755 diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.wrap/CMakeLists.txt b/contracts/eosio.wrap/CMakeLists.txt old mode 100644 new mode 100755 diff --git a/contracts/eosio.wrap/README.md b/contracts/eosio.wrap/README.md old mode 100644 new mode 100755 diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp old mode 100644 new mode 100755 diff --git a/contracts/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp old mode 100644 new mode 100755 From 7083d3a6f67b3cef034157432a710e96d8e81666 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Dec 2018 16:36:46 -0500 Subject: [PATCH 0658/1048] Small changes following code review --- eosio.system/include/eosio.system/eosio.system.hpp | 11 ++++++++++- eosio.system/src/rex.cpp | 9 ++++++--- eosio.system/src/voting.cpp | 4 ++-- tests/eosio.system_tests.cpp | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/eosio.system/include/eosio.system/eosio.system.hpp b/eosio.system/include/eosio.system/eosio.system.hpp index 6d2d4365..2c7e2197 100644 --- a/eosio.system/include/eosio.system/eosio.system.hpp +++ b/eosio.system/include/eosio.system/eosio.system.hpp @@ -14,6 +14,14 @@ #include #include +#ifdef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX +#undef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX +#endif +// CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX macro determines whether ramfee and namebid proceeds are +// channeled to REX pool. In order to stop these proceeds from being channeled, the macro must +// be set to 0. +#define CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX 1 + namespace eosiosystem { using eosio::name; @@ -529,7 +537,8 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); - void check_voting_requirement( const name& owner )const; + void check_voting_requirement( const name& owner, + const char* error_msg = "must vote for at least 21 producers or for a proxy before buying REX" )const; rex_order_outcome fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); void channel_to_rex( const name& from, const asset& amount ); diff --git a/eosio.system/src/rex.cpp b/eosio.system/src/rex.cpp index 86a4ae07..9ee07f87 100644 --- a/eosio.system/src/rex.cpp +++ b/eosio.system/src/rex.cpp @@ -439,11 +439,10 @@ namespace eosiosystem { set_resource_limits( receiver.value, ram_bytes, net + delta_net, cpu + delta_cpu ); } - void system_contract::check_voting_requirement( const name& owner )const + void system_contract::check_voting_requirement( const name& owner, const char* error_msg )const { auto vitr = _voters.find( owner.value ); - eosio_assert( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), - "must vote for at least 21 producers or for a proxy before buying REX" ); + eosio_assert( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), error_msg ); } /** @@ -756,6 +755,7 @@ namespace eosiosystem { */ void system_contract::channel_to_rex( const name& from, const asset& amount ) { +#if CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX if ( rex_available() ) { _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.total_unlent.amount += amount.amount; @@ -765,6 +765,7 @@ namespace eosiosystem { INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { from, active_permission }, { from, rex_account, amount, std::string("transfer from ") + name{from}.to_string() + " to eosio.rex"} ); } +#endif } /** @@ -774,11 +775,13 @@ namespace eosiosystem { */ void system_contract::channel_namebid_to_rex( const int64_t highest_bid ) { +#if CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX if ( rex_available() ) { _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { rp.namebid_proceeds.amount += highest_bid; }); } +#endif } /** diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 35cc76a2..8371119f 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -194,11 +194,11 @@ namespace eosiosystem { */ void system_contract::voteproducer( const name voter_name, const name proxy, const std::vector& producers ) { require_auth( voter_name ); + update_votes( voter_name, proxy, producers, true ); auto rex_itr = _rexbalance.find( voter_name.value ); if( rex_itr != _rexbalance.end() && rex_itr->rex_balance.amount > 0 ) { - eosio_assert( proxy || producers.size() >= 21, "voter holding REX must vote for a proxy or at least 21 producers"); + check_voting_requirement( voter_name, "voter holding REX tokens must vote for at least 21 producers or for a proxy" ); } - update_votes( voter_name, proxy, producers, true ); } void system_contract::update_votes( const name voter_name, const name proxy, const std::vector& producers, bool voting ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 34f9db1c..bb237b13 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4149,7 +4149,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } } - BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX must vote for a proxy or at least 21 producers"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); From a47669a87ecd517c9f2766bb430c70e5c613d08c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Dec 2018 17:01:05 -0500 Subject: [PATCH 0659/1048] Merge develop branch into rex-2 --- {eosio.system => contracts/eosio.system}/src/rex.cpp | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {eosio.system => contracts/eosio.system}/src/rex.cpp (100%) diff --git a/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp similarity index 100% rename from eosio.system/src/rex.cpp rename to contracts/eosio.system/src/rex.cpp From 6514308cd803655757fb920eae40b896ccee2782 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Dec 2018 18:00:41 -0500 Subject: [PATCH 0660/1048] Replace eosio_assert by check --- .../include/eosio.system/eosio.system.hpp | 3 +- .../eosio.system/src/delegate_bandwidth.cpp | 56 +++++++-------- contracts/eosio.system/src/eosio.system.cpp | 56 +++++++-------- contracts/eosio.system/src/exchange_state.cpp | 6 +- contracts/eosio.system/src/producer_pay.cpp | 6 +- contracts/eosio.system/src/rex.cpp | 70 +++++++++---------- contracts/eosio.system/src/voting.cpp | 34 ++++----- 7 files changed, 116 insertions(+), 115 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 2c7e2197..940583e5 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -35,6 +35,7 @@ namespace eosiosystem { using eosio::time_point_sec; using eosio::microseconds; using eosio::datastream; + using eosio::check; struct [[eosio::table, eosio::contract("eosio.system")]] name_bid { name newname; @@ -522,7 +523,7 @@ namespace eosiosystem { static symbol get_core_symbol( const rammarket& rm ) { auto itr = rm.find(ramcore_symbol.raw()); - eosio_assert(itr != rm.end(), "system contract must first be initialized"); + check(itr != rm.end(), "system contract must first be initialized"); return itr->quote.balance.symbol; } diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 2fd293a6..1b574da3 100755 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -111,8 +111,8 @@ namespace eosiosystem { require_auth( payer ); update_ram_supply(); - eosio_assert( quant.symbol == core_symbol(), "must buy ram with core token" ); - eosio_assert( quant.amount > 0, "must purchase a positive amount" ); + check( quant.symbol == core_symbol(), "must buy ram with core token" ); + check( quant.amount > 0, "must purchase a positive amount" ); auto fee = quant; fee.amount = ( fee.amount + 199 ) / 200; /// .5% fee (round up) @@ -144,7 +144,7 @@ namespace eosiosystem { bytes_out = es.convert( quant_after_fee, ram_symbol ).amount; }); - eosio_assert( bytes_out > 0, "must reserve a positive amount" ); + check( bytes_out > 0, "must reserve a positive amount" ); _gstate.total_ram_bytes_reserved += uint64_t(bytes_out); _gstate.total_ram_stake += quant_after_fee.amount; @@ -176,12 +176,12 @@ namespace eosiosystem { require_auth( account ); update_ram_supply(); - eosio_assert( bytes > 0, "cannot sell negative byte" ); + check( bytes > 0, "cannot sell negative byte" ); user_resources_table userres( _self, account.value ); auto res_itr = userres.find( account.value ); - eosio_assert( res_itr != userres.end(), "no resource row" ); - eosio_assert( res_itr->ram_bytes >= bytes, "insufficient quota" ); + check( res_itr != userres.end(), "no resource row" ); + check( res_itr->ram_bytes >= bytes, "insufficient quota" ); asset tokens_out; auto itr = _rammarket.find(ramcore_symbol.raw()); @@ -190,13 +190,13 @@ namespace eosiosystem { tokens_out = es.convert( asset(bytes, ram_symbol), core_symbol()); }); - eosio_assert( tokens_out.amount > 1, "token amount received from selling ram is too low" ); + check( tokens_out.amount > 1, "token amount received from selling ram is too low" ); _gstate.total_ram_bytes_reserved -= static_cast(bytes); // bytes > 0 is asserted above _gstate.total_ram_stake -= tokens_out.amount; //// this shouldn't happen, but just in case it does we should prevent it - eosio_assert( _gstate.total_ram_stake >= 0, "error, attempt to unstake more tokens than previously staked" ); + check( _gstate.total_ram_stake >= 0, "error, attempt to unstake more tokens than previously staked" ); userres.modify( res_itr, account, [&]( auto& res ) { res.ram_bytes -= bytes; @@ -224,15 +224,15 @@ namespace eosiosystem { const int64_t max_claimable = 100'000'000'0000ll; const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / (10*seconds_per_year) ); - eosio_assert( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); + check( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } void system_contract::changebw( name from, name receiver, const asset stake_net_delta, const asset stake_cpu_delta, bool transfer ) { require_auth( from ); - eosio_assert( stake_net_delta.amount != 0 || stake_cpu_delta.amount != 0, "should stake non-zero amount" ); - eosio_assert( std::abs( (stake_net_delta + stake_cpu_delta).amount ) + check( stake_net_delta.amount != 0 || stake_cpu_delta.amount != 0, "should stake non-zero amount" ); + check( std::abs( (stake_net_delta + stake_cpu_delta).amount ) >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), "net and cpu deltas cannot be opposite signs" ); @@ -259,8 +259,8 @@ namespace eosiosystem { dbo.cpu_weight += stake_cpu_delta; }); } - eosio_assert( 0 <= itr->net_weight.amount, "insufficient staked net bandwidth" ); - eosio_assert( 0 <= itr->cpu_weight.amount, "insufficient staked cpu bandwidth" ); + check( 0 <= itr->net_weight.amount, "insufficient staked net bandwidth" ); + check( 0 <= itr->cpu_weight.amount, "insufficient staked cpu bandwidth" ); if ( itr->is_empty() ) { del_tbl.erase( itr ); } @@ -282,8 +282,8 @@ namespace eosiosystem { tot.cpu_weight += stake_cpu_delta; }); } - eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); - eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); + check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); + check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); int64_t ram_bytes, net, cpu; get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); @@ -333,8 +333,8 @@ namespace eosiosystem { } }); - eosio_assert( 0 <= req->net_amount.amount, "negative net refund amount" ); //should never happen - eosio_assert( 0 <= req->cpu_amount.amount, "negative cpu refund amount" ); //should never happen + check( 0 <= req->net_amount.amount, "negative net refund amount" ); //should never happen + check( 0 <= req->cpu_amount.amount, "negative cpu refund amount" ); //should never happen if ( req->is_empty() ) { refunds_tbl.erase( req ); @@ -402,7 +402,7 @@ namespace eosiosystem { }); } - eosio_assert( 0 <= voter_itr->staked, "stake for voting cannot be negative"); + check( 0 <= voter_itr->staked, "stake for voting cannot be negative"); if( voter == "b1"_n ) { validate_b1_vesting( voter_itr->staked ); @@ -418,10 +418,10 @@ namespace eosiosystem { asset stake_cpu_quantity, bool transfer ) { asset zero_asset( 0, core_symbol() ); - eosio_assert( stake_cpu_quantity >= zero_asset, "must stake a positive amount" ); - eosio_assert( stake_net_quantity >= zero_asset, "must stake a positive amount" ); - eosio_assert( stake_net_quantity.amount + stake_cpu_quantity.amount > 0, "must stake a positive amount" ); - eosio_assert( !transfer || from != receiver, "cannot use transfer flag if delegating to self" ); + check( stake_cpu_quantity >= zero_asset, "must stake a positive amount" ); + check( stake_net_quantity >= zero_asset, "must stake a positive amount" ); + check( stake_net_quantity.amount + stake_cpu_quantity.amount > 0, "must stake a positive amount" ); + check( !transfer || from != receiver, "cannot use transfer flag if delegating to self" ); changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); } // delegatebw @@ -430,10 +430,10 @@ namespace eosiosystem { asset unstake_net_quantity, asset unstake_cpu_quantity ) { asset zero_asset( 0, core_symbol() ); - eosio_assert( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); - eosio_assert( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); - eosio_assert( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, + check( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); + check( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); + check( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); + check( _gstate.total_activated_stake >= min_activated_stake, "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); @@ -445,8 +445,8 @@ namespace eosiosystem { refunds_table refunds_tbl( _self, owner.value ); auto req = refunds_tbl.find( owner.value ); - eosio_assert( req != refunds_tbl.end(), "refund request not found" ); - eosio_assert( req->request_time + seconds(refund_delay_sec) <= current_time_point(), + check( req != refunds_tbl.end(), "refund request not found" ); + check( req->request_time + seconds(refund_delay_sec) <= current_time_point(), "refund is not available yet" ); INLINE_ACTION_SENDER(eosio::token, transfer)( diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 9d74c143..3e8374c3 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -65,9 +65,9 @@ namespace eosiosystem { void system_contract::setram( uint64_t max_ram_size ) { require_auth( _self ); - eosio_assert( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues - eosio_assert( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" ); - eosio_assert( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); + check( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues + check( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" ); + check( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size); auto itr = _rammarket.find(ramcore_symbol.raw()); @@ -117,7 +117,7 @@ namespace eosiosystem { void system_contract::setparams( const eosio::blockchain_parameters& params ) { require_auth( _self ); (eosio::blockchain_parameters&)(_gstate) = params; - eosio_assert( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); + check( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); set_blockchain_parameters( params ); } @@ -130,14 +130,14 @@ namespace eosiosystem { require_auth( _self ); user_resources_table userres( _self, account.value ); auto ritr = userres.find( account.value ); - eosio_assert( ritr == userres.end(), "only supports unlimited accounts" ); + check( ritr == userres.end(), "only supports unlimited accounts" ); set_resource_limits( account.value, ram, net, cpu ); } void system_contract::rmvproducer( name producer ) { require_auth( _self ); auto prod = _producers.find( producer.value ); - eosio_assert( prod != _producers.end(), "producer not found" ); + check( prod != _producers.end(), "producer not found" ); _producers.modify( prod, same_payer, [&](auto& p) { p.deactivate(); }); @@ -145,23 +145,23 @@ namespace eosiosystem { void system_contract::updtrevision( uint8_t revision ) { require_auth( _self ); - eosio_assert( _gstate2.revision < 255, "can not increment revision" ); // prevent wrap around - eosio_assert( revision == _gstate2.revision + 1, "can only increment revision by one" ); - eosio_assert( revision <= 1, // set upper bound to greatest revision supported in the code + check( _gstate2.revision < 255, "can not increment revision" ); // prevent wrap around + check( revision == _gstate2.revision + 1, "can only increment revision by one" ); + check( revision <= 1, // set upper bound to greatest revision supported in the code "specified revision is not yet supported by the code" ); _gstate2.revision = revision; } void system_contract::bidname( name bidder, name newname, asset bid ) { require_auth( bidder ); - eosio_assert( newname.suffix() == newname, "you can only bid on top-level suffix" ); + check( newname.suffix() == newname, "you can only bid on top-level suffix" ); - eosio_assert( (bool)newname, "the empty name is not a valid account name to bid on" ); - eosio_assert( (newname.value & 0xFull) == 0, "13 character names are not valid account names to bid on" ); - eosio_assert( (newname.value & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); - eosio_assert( !is_account( newname ), "account already exists" ); - eosio_assert( bid.symbol == core_symbol(), "asset must be system token" ); - eosio_assert( bid.amount > 0, "insufficient bid" ); + check( (bool)newname, "the empty name is not a valid account name to bid on" ); + check( (newname.value & 0xFull) == 0, "13 character names are not valid account names to bid on" ); + check( (newname.value & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); + check( !is_account( newname ), "account already exists" ); + check( bid.symbol == core_symbol(), "asset must be system token" ); + check( bid.amount > 0, "insufficient bid" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {bidder, active_permission} }, @@ -179,9 +179,9 @@ namespace eosiosystem { b.last_bid_time = current_time_point(); }); } else { - eosio_assert( current->high_bid > 0, "this auction has already closed" ); - eosio_assert( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); - eosio_assert( current->high_bidder != bidder, "account is already highest bidder" ); + check( current->high_bid > 0, "this auction has already closed" ); + check( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); + check( current->high_bidder != bidder, "account is already highest bidder" ); bid_refund_table refunds_table(_self, newname.value); @@ -218,7 +218,7 @@ namespace eosiosystem { void system_contract::bidrefund( name bidder, name newname ) { bid_refund_table refunds_table(_self, newname.value); auto it = refunds_table.find( bidder.value ); - eosio_assert( it != refunds_table.end(), "refund not found" ); + check( it != refunds_table.end(), "refund not found" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {names_account, active_permission}, {bidder, active_permission} }, { names_account, bidder, asset(it->amount), std::string("refund bid on name ")+(name{newname}).to_string() } @@ -253,12 +253,12 @@ namespace eosiosystem { if( suffix == newact ) { name_bid_table bids(_self, _self.value); auto current = bids.find( newact.value ); - eosio_assert( current != bids.end(), "no active bid for name" ); - eosio_assert( current->high_bidder == creator, "only highest bidder can claim" ); - eosio_assert( current->high_bid < 0, "auction for name is not closed yet" ); + check( current != bids.end(), "no active bid for name" ); + check( current->high_bidder == creator, "only highest bidder can claim" ); + check( current->high_bid < 0, "auction for name is not closed yet" ); bids.erase( current ); } else { - eosio_assert( creator == suffix, "only suffix may create this account" ); + check( creator == suffix, "only suffix may create this account" ); } } } @@ -291,15 +291,15 @@ namespace eosiosystem { void system_contract::init( unsigned_int version, symbol core ) { require_auth( _self ); - eosio_assert( version.value == 0, "unsupported version for init action" ); + check( version.value == 0, "unsupported version for init action" ); auto itr = _rammarket.find(ramcore_symbol.raw()); - eosio_assert( itr == _rammarket.end(), "system contract has already been initialized" ); + check( itr == _rammarket.end(), "system contract has already been initialized" ); auto system_token_supply = eosio::token::get_supply(token_account, core.code() ); - eosio_assert( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); + check( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); - eosio_assert( system_token_supply.amount > 0, "system token supply must be greater than 0" ); + check( system_token_supply.amount > 0, "system token supply must be greater than 0" ); _rammarket.emplace( _self, [&]( auto& m ) { m.supply.amount = 100000000000000ll; m.supply.symbol = ramcore_symbol; diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index 28b43de7..ad29f972 100755 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -19,7 +19,7 @@ namespace eosiosystem { } asset exchange_state::convert_from_exchange( connector& c, asset in ) { - eosio_assert( in.symbol== supply.symbol, "unexpected asset symbol input" ); + check( in.symbol== supply.symbol, "unexpected asset symbol input" ); real_type R(supply.amount - in.amount); real_type C(c.balance.amount); @@ -60,7 +60,7 @@ namespace eosiosystem { } else if( sell_symbol == quote_symbol ) { from = convert_to_exchange( quote, from ); } else { - eosio_assert( false, "invalid sell" ); + check( false, "invalid sell" ); } } else { if( to == base_symbol ) { @@ -68,7 +68,7 @@ namespace eosiosystem { } else if( to == quote_symbol ) { from = convert_from_exchange( quote, from ); } else { - eosio_assert( false, "invalid conversion" ); + check( false, "invalid conversion" ); } } diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 70dd093b..83f6a120 100755 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -79,14 +79,14 @@ namespace eosiosystem { require_auth( owner ); const auto& prod = _producers.get( owner.value ); - eosio_assert( prod.active(), "producer does not have an active key" ); + check( prod.active(), "producer does not have an active key" ); - eosio_assert( _gstate.total_activated_stake >= min_activated_stake, + check( _gstate.total_activated_stake >= min_activated_stake, "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" ); const auto ct = current_time_point(); - eosio_assert( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); + check( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); const asset token_supply = eosio::token::get_supply(token_account, core_symbol().code() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 9ee07f87..8c912151 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -16,8 +16,8 @@ namespace eosiosystem { { require_auth( owner ); - eosio_assert( amount.symbol == core_symbol(), "must deposit core token" ); - eosio_assert( 0 < amount.amount, "must deposit a positive amount" ); + check( amount.symbol == core_symbol(), "must deposit core token" ); + check( 0 < amount.amount, "must deposit a positive amount" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { owner, active_permission }, { owner, rex_account, amount, "deposit to REX fund" } ); transfer_to_fund( owner, amount ); @@ -33,8 +33,8 @@ namespace eosiosystem { { require_auth( owner ); - eosio_assert( amount.symbol == core_symbol(), "must withdraw core token" ); - eosio_assert( 0 < amount.amount, "must withdraw a positive amount" ); + check( amount.symbol == core_symbol(), "must withdraw core token" ); + check( 0 < amount.amount, "must withdraw a positive amount" ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( owner, amount ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, @@ -51,8 +51,8 @@ namespace eosiosystem { { require_auth( from ); - eosio_assert( amount.symbol == core_symbol(), "asset must be core token" ); - eosio_assert( 0 < amount.amount, "must use positive amount" ); + check( amount.symbol == core_symbol(), "asset must be core token" ); + check( 0 < amount.amount, "must use positive amount" ); check_voting_requirement( from ); transfer_from_fund( from, amount ); const asset rex_received = add_to_rex_pool( amount ); @@ -73,16 +73,16 @@ namespace eosiosystem { { require_auth( owner ); - eosio_assert( from_net.symbol == core_symbol() && from_cpu.symbol == core_symbol(), "asset must be core token" ); - eosio_assert( (0 <= from_net.amount) && (0 <= from_cpu.amount) && (0 < from_net.amount || 0 < from_cpu.amount), + check( from_net.symbol == core_symbol() && from_cpu.symbol == core_symbol(), "asset must be core token" ); + check( (0 <= from_net.amount) && (0 <= from_cpu.amount) && (0 < from_net.amount || 0 < from_cpu.amount), "must unstake a positive amount to buy rex" ); check_voting_requirement( owner ); { del_bandwidth_table dbw_table( _self, owner.value ); auto del_itr = dbw_table.require_find( receiver.value, "delegated bandwidth record does not exist" ); - eosio_assert( from_net.amount <= del_itr->net_weight.amount, "amount exceeds tokens staked for net"); - eosio_assert( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); + check( from_net.amount <= del_itr->net_weight.amount, "amount exceeds tokens staked for net"); + check( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); dbw_table.modify( del_itr, same_payer, [&]( delegated_bandwidth& dbw ) { dbw.net_weight.amount -= from_net.amount; dbw.cpu_weight.amount -= from_cpu.amount; @@ -116,10 +116,10 @@ namespace eosiosystem { runrex(2); auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); - eosio_assert( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, + check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); process_rex_maturities( bitr ); - eosio_assert( rex.amount <= bitr->matured_rex, "insufficient available rex" ); + check( rex.amount <= bitr->matured_rex, "insufficient available rex" ); auto current_order = fill_rex_order( bitr, rex ); update_rex_account( from, current_order.proceeds, current_order.stake_change ); @@ -141,7 +141,7 @@ namespace eosiosystem { } else { _rexorders.modify( oitr, same_payer, [&]( auto& order ) { order.rex_requested.amount += rex.amount; - eosio_assert( order.rex_requested.amount <= bitr->matured_rex, + check( order.rex_requested.amount <= bitr->matured_rex, "insufficient funds for current and scheduled orders"); }); } @@ -158,7 +158,7 @@ namespace eosiosystem { require_auth( owner ); auto itr = _rexorders.require_find( owner.value, "no sellrex order is scheduled" ); - eosio_assert( itr->is_open, "sellrex order has been filled and cannot be canceled" ); + check( itr->is_open, "sellrex order has been filled and cannot be canceled" ); _rexorders.erase( itr ); } @@ -364,7 +364,7 @@ namespace eosiosystem { { auto rex_itr = _rexbalance.find( owner.value ); if ( rex_itr != _rexbalance.end() ) { - eosio_assert( rex_itr->rex_balance.amount == 0, "account has remaining REX balance, must sell first"); + check( rex_itr->rex_balance.amount == 0, "account has remaining REX balance, must sell first"); _rexbalance.erase( rex_itr ); } } @@ -414,7 +414,7 @@ namespace eosiosystem { user_resources_table totals_tbl( _self, receiver.value ); auto tot_itr = totals_tbl.find( receiver.value ); if ( tot_itr == totals_tbl.end() ) { - eosio_assert( 0 <= delta_net && 0 <= delta_cpu, "logic error, should not occur"); + check( 0 <= delta_net && 0 <= delta_cpu, "logic error, should not occur"); tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { tot.owner = receiver; tot.net_weight = asset( delta_net, core_symbol() ); @@ -426,8 +426,8 @@ namespace eosiosystem { tot.cpu_weight.amount += delta_cpu; }); } - eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); - eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); + check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); + check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); if ( tot_itr->is_empty() ) { totals_tbl.erase( tot_itr ); @@ -442,7 +442,7 @@ namespace eosiosystem { void system_contract::check_voting_requirement( const name& owner, const char* error_msg )const { auto vitr = _voters.find( owner.value ); - eosio_assert( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), error_msg ); + check( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), error_msg ); } /** @@ -452,7 +452,7 @@ namespace eosiosystem { */ void system_contract::runrex( uint16_t max ) { - eosio_assert( rex_system_initialized(), "rex system not initialized yet" ); + check( rex_system_initialized(), "rex system not initialized yet" ); auto rexi = _rexpool.begin(); @@ -565,9 +565,9 @@ namespace eosiosystem { { runrex(2); - eosio_assert( rex_loans_available(), "rex loans are not currently available" ); - eosio_assert( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); - eosio_assert( 0 < payment.amount && 0 <= fund.amount, "must use positive asset amount" ); + check( rex_loans_available(), "rex loans are not currently available" ); + check( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); + check( 0 < payment.amount && 0 <= fund.amount, "must use positive asset amount" ); update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( from, payment + fund ); @@ -642,11 +642,11 @@ namespace eosiosystem { template void system_contract::fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ) { - eosio_assert( payment.symbol == core_symbol(), "must use core token" ); + check( payment.symbol == core_symbol(), "must use core token" ); transfer_from_fund( from, payment ); auto itr = table.require_find( loan_num, "loan not found" ); - eosio_assert( itr->from == from, "user must be loan creator" ); - eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); + check( itr->from == from, "user must be loan creator" ); + check( itr->expiration > current_time_point(), "loan has already expired" ); table.modify( itr, same_payer, [&]( auto& loan ) { loan.balance.amount += payment.amount; }); @@ -655,11 +655,11 @@ namespace eosiosystem { template void system_contract::defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ) { - eosio_assert( amount.symbol == core_symbol(), "must use core token" ); + check( amount.symbol == core_symbol(), "must use core token" ); auto itr = table.require_find( loan_num, "loan not found" ); - eosio_assert( itr->from == from, "user must be loan creator" ); - eosio_assert( itr->expiration > current_time_point(), "loan has already expired" ); - eosio_assert( itr->balance >= amount, "insufficent loan balance" ); + check( itr->from == from, "user must be loan creator" ); + check( itr->expiration > current_time_point(), "loan has already expired" ); + check( itr->balance >= amount, "insufficent loan balance" ); table.modify( itr, same_payer, [&]( auto& loan ) { loan.balance.amount -= amount.amount; }); @@ -676,10 +676,10 @@ namespace eosiosystem { */ void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { - eosio_assert( 0 < amount.amount && amount.symbol == core_symbol(), + check( 0 < amount.amount && amount.symbol == core_symbol(), "must transfer positive amount from REX fund" ); auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); - eosio_assert( amount <= itr->balance, "insufficient funds"); + check( amount <= itr->balance, "insufficient funds"); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { fund.balance.amount -= amount.amount; }); @@ -693,7 +693,7 @@ namespace eosiosystem { */ void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { - eosio_assert( 0 < amount.amount && amount.symbol == core_symbol(), + check( 0 < amount.amount && amount.symbol == core_symbol(), "must transfer positive amount to REX fund" ); auto itr = _rexfunds.find( owner.value ); if ( itr == _rexfunds.end() ) { @@ -872,7 +872,7 @@ namespace eosiosystem { }); } else { /// total_lendable > 0 if total_rex > 0 except in a rare case and due to rounding errors - eosio_assert( itr->total_lendable.amount > 0, "lendable REX pool is empty" ); + check( itr->total_lendable.amount > 0, "lendable REX pool is empty" ); const int64_t S0 = itr->total_lendable.amount; const int64_t S1 = S0 + payment.amount; const int64_t R0 = itr->total_rex.amount; @@ -884,7 +884,7 @@ namespace eosiosystem { rp.total_lendable.amount = S1; rp.total_rex.amount = R1; rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - eosio_assert( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); + check( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); }); } diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 8371119f..d9cc8e5b 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -34,8 +34,8 @@ namespace eosiosystem { * */ void system_contract::regproducer( const name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { - eosio_assert( url.size() < 512, "url too long" ); - eosio_assert( producer_key != eosio::public_key(), "public key should not be the default value" ); + check( url.size() < 512, "url too long" ); + check( producer_key != eosio::public_key(), "public key should not be the default value" ); require_auth( producer ); auto prod = _producers.find( producer.value ); @@ -204,19 +204,19 @@ namespace eosiosystem { void system_contract::update_votes( const name voter_name, const name proxy, const std::vector& producers, bool voting ) { //validate input if ( proxy ) { - eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" ); - eosio_assert( voter_name != proxy, "cannot proxy to self" ); + check( producers.size() == 0, "cannot vote for producers and proxy at same time" ); + check( voter_name != proxy, "cannot proxy to self" ); require_recipient( proxy ); } else { - eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" ); + check( producers.size() <= 30, "attempt to vote for too many producers" ); for( size_t i = 1; i < producers.size(); ++i ) { - eosio_assert( producers[i-1] < producers[i], "producer votes must be unique and sorted" ); + check( producers[i-1] < producers[i], "producer votes must be unique and sorted" ); } } auto voter = _voters.find( voter_name.value ); - eosio_assert( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object - eosio_assert( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" ); + check( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object + check( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" ); /** * The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until @@ -239,7 +239,7 @@ namespace eosiosystem { if ( voter->last_vote_weight > 0 ) { if( voter->proxy ) { auto old_proxy = _voters.find( voter->proxy.value ); - eosio_assert( old_proxy != _voters.end(), "old proxy not found" ); //data corruption + check( old_proxy != _voters.end(), "old proxy not found" ); //data corruption _voters.modify( old_proxy, same_payer, [&]( auto& vp ) { vp.proxied_vote_weight -= voter->last_vote_weight; }); @@ -255,8 +255,8 @@ namespace eosiosystem { if( proxy ) { auto new_proxy = _voters.find( proxy.value ); - eosio_assert( new_proxy != _voters.end(), "invalid proxy specified" ); //if ( !voting ) { data corruption } else { wrong vote } - eosio_assert( !voting || new_proxy->is_proxy, "proxy not found" ); + check( new_proxy != _voters.end(), "invalid proxy specified" ); //if ( !voting ) { data corruption } else { wrong vote } + check( !voting || new_proxy->is_proxy, "proxy not found" ); if ( new_vote_weight >= 0 ) { _voters.modify( new_proxy, same_payer, [&]( auto& vp ) { vp.proxied_vote_weight += new_vote_weight; @@ -279,7 +279,7 @@ namespace eosiosystem { for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first.value ); if( pitr != _producers.end() ) { - eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); + check( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); double init_total_votes = pitr->total_votes; _producers.modify( pitr, same_payer, [&]( auto& p ) { p.total_votes += pd.second.first; @@ -287,7 +287,7 @@ namespace eosiosystem { p.total_votes = 0; } _gstate.total_producer_vote_weight += pd.second.first; - //eosio_assert( p.total_votes >= 0, "something bad happened" ); + //check( p.total_votes >= 0, "something bad happened" ); }); auto prod2 = _producers2.find( pd.first.value ); if( prod2 != _producers2.end() ) { @@ -310,7 +310,7 @@ namespace eosiosystem { } } } else { - eosio_assert( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption + check( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption } } @@ -337,8 +337,8 @@ namespace eosiosystem { auto pitr = _voters.find( proxy.value ); if ( pitr != _voters.end() ) { - eosio_assert( isproxy != pitr->is_proxy, "action has no effect" ); - eosio_assert( !isproxy || !pitr->proxy, "account that uses a proxy is not allowed to become a proxy" ); + check( isproxy != pitr->is_proxy, "action has no effect" ); + check( !isproxy || !pitr->proxy, "account that uses a proxy is not allowed to become a proxy" ); _voters.modify( pitr, same_payer, [&]( auto& p ) { p.is_proxy = isproxy; }); @@ -352,7 +352,7 @@ namespace eosiosystem { } void system_contract::propagate_weight_change( const voter_info& voter ) { - eosio_assert( !voter.proxy || !voter.is_proxy, "account registered as a proxy is not allowed to use a proxy" ); + check( !voter.proxy || !voter.is_proxy, "account registered as a proxy is not allowed to use a proxy" ); double new_weight = stake2vote( voter.staked ); if ( voter.is_proxy ) { new_weight += voter.proxied_vote_weight; From 1862a3e4c62304bc62d78e1075e1197fc995e4b4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Dec 2018 18:21:08 -0500 Subject: [PATCH 0661/1048] Replace eosio_assert by check in eosio.token --- contracts/eosio.token/src/eosio.token.cpp | 54 +++++++++++------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index b18a68af..cd1e8bb4 100755 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -13,13 +13,13 @@ void token::create( name issuer, require_auth( _self ); auto sym = maximum_supply.symbol; - eosio_assert( sym.is_valid(), "invalid symbol name" ); - eosio_assert( maximum_supply.is_valid(), "invalid supply"); - eosio_assert( maximum_supply.amount > 0, "max-supply must be positive"); + check( sym.is_valid(), "invalid symbol name" ); + check( maximum_supply.is_valid(), "invalid supply"); + check( maximum_supply.amount > 0, "max-supply must be positive"); stats statstable( _self, sym.code().raw() ); auto existing = statstable.find( sym.code().raw() ); - eosio_assert( existing == statstable.end(), "token with symbol already exists" ); + check( existing == statstable.end(), "token with symbol already exists" ); statstable.emplace( _self, [&]( auto& s ) { s.supply.symbol = maximum_supply.symbol; @@ -32,20 +32,20 @@ void token::create( name issuer, void token::issue( name to, asset quantity, string memo ) { auto sym = quantity.symbol; - eosio_assert( sym.is_valid(), "invalid symbol name" ); - eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); + check( sym.is_valid(), "invalid symbol name" ); + check( memo.size() <= 256, "memo has more than 256 bytes" ); stats statstable( _self, sym.code().raw() ); auto existing = statstable.find( sym.code().raw() ); - eosio_assert( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); + check( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); const auto& st = *existing; require_auth( st.issuer ); - eosio_assert( quantity.is_valid(), "invalid quantity" ); - eosio_assert( quantity.amount > 0, "must issue positive quantity" ); + check( quantity.is_valid(), "invalid quantity" ); + check( quantity.amount > 0, "must issue positive quantity" ); - eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); - eosio_assert( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); + check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); + check( quantity.amount <= st.max_supply.amount - st.supply.amount, "quantity exceeds available supply"); statstable.modify( st, same_payer, [&]( auto& s ) { s.supply += quantity; @@ -63,19 +63,19 @@ void token::issue( name to, asset quantity, string memo ) void token::retire( asset quantity, string memo ) { auto sym = quantity.symbol; - eosio_assert( sym.is_valid(), "invalid symbol name" ); - eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); + check( sym.is_valid(), "invalid symbol name" ); + check( memo.size() <= 256, "memo has more than 256 bytes" ); stats statstable( _self, sym.code().raw() ); auto existing = statstable.find( sym.code().raw() ); - eosio_assert( existing != statstable.end(), "token with symbol does not exist" ); + check( existing != statstable.end(), "token with symbol does not exist" ); const auto& st = *existing; require_auth( st.issuer ); - eosio_assert( quantity.is_valid(), "invalid quantity" ); - eosio_assert( quantity.amount > 0, "must retire positive quantity" ); + check( quantity.is_valid(), "invalid quantity" ); + check( quantity.amount > 0, "must retire positive quantity" ); - eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); + check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); statstable.modify( st, same_payer, [&]( auto& s ) { s.supply -= quantity; @@ -89,9 +89,9 @@ void token::transfer( name from, asset quantity, string memo ) { - eosio_assert( from != to, "cannot transfer to self" ); + check( from != to, "cannot transfer to self" ); require_auth( from ); - eosio_assert( is_account( to ), "to account does not exist"); + check( is_account( to ), "to account does not exist"); auto sym = quantity.symbol.code(); stats statstable( _self, sym.raw() ); const auto& st = statstable.get( sym.raw() ); @@ -99,10 +99,10 @@ void token::transfer( name from, require_recipient( from ); require_recipient( to ); - eosio_assert( quantity.is_valid(), "invalid quantity" ); - eosio_assert( quantity.amount > 0, "must transfer positive quantity" ); - eosio_assert( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); - eosio_assert( memo.size() <= 256, "memo has more than 256 bytes" ); + check( quantity.is_valid(), "invalid quantity" ); + check( quantity.amount > 0, "must transfer positive quantity" ); + check( quantity.symbol == st.supply.symbol, "symbol precision mismatch" ); + check( memo.size() <= 256, "memo has more than 256 bytes" ); auto payer = has_auth( to ) ? to : from; @@ -114,7 +114,7 @@ void token::sub_balance( name owner, asset value ) { accounts from_acnts( _self, owner.value ); const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" ); - eosio_assert( from.balance.amount >= value.amount, "overdrawn balance" ); + check( from.balance.amount >= value.amount, "overdrawn balance" ); from_acnts.modify( from, owner, [&]( auto& a ) { a.balance -= value; @@ -144,7 +144,7 @@ void token::open( name owner, const symbol& symbol, name ram_payer ) stats statstable( _self, sym_code_raw ); const auto& st = statstable.get( sym_code_raw, "symbol does not exist" ); - eosio_assert( st.supply.symbol == symbol, "symbol precision mismatch" ); + check( st.supply.symbol == symbol, "symbol precision mismatch" ); accounts acnts( _self, owner.value ); auto it = acnts.find( sym_code_raw ); @@ -160,8 +160,8 @@ void token::close( name owner, const symbol& symbol ) require_auth( owner ); accounts acnts( _self, owner.value ); auto it = acnts.find( symbol.code().raw() ); - eosio_assert( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); - eosio_assert( it->balance.amount == 0, "Cannot close because the balance is not zero." ); + check( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); + check( it->balance.amount == 0, "Cannot close because the balance is not zero." ); acnts.erase( it ); } From 13d4d23545a473ade54eb75201709462930e8ba2 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Dec 2018 18:25:23 -0500 Subject: [PATCH 0662/1048] Replace eosio_assert by check in eosio.msig --- contracts/eosio.msig/src/eosio.msig.cpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 0b682b6c..c0baad73 100755 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -27,18 +27,18 @@ void multisig::propose( ignore proposer, _ds >> _trx_header; require_auth( _proposer ); - eosio_assert( _trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); - //eosio_assert( trx_header.actions.size() > 0, "transaction must have at least one action" ); + check( _trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); + //check( trx_header.actions.size() > 0, "transaction must have at least one action" ); proposals proptable( _self, _proposer.value ); - eosio_assert( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); + check( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); auto packed_requested = pack(_requested); auto res = ::check_transaction_authorization( trx_pos, size, (const char*)0, 0, packed_requested.data(), packed_requested.size() ); - eosio_assert( res > 0, "transaction authorization failed" ); + check( res > 0, "transaction authorization failed" ); std::vector pkd_trans; pkd_trans.resize(size); @@ -73,7 +73,7 @@ void multisig::approve( name proposer, name proposal_name, permission_level leve auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { auto itr = std::find_if( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), [&](const approval& a) { return a.level == level; } ); - eosio_assert( itr != apps_it->requested_approvals.end(), "approval is not on the list of requested approvals" ); + check( itr != apps_it->requested_approvals.end(), "approval is not on the list of requested approvals" ); apptable.modify( apps_it, proposer, [&]( auto& a ) { a.provided_approvals.push_back( approval{ level, current_time_point() } ); @@ -84,7 +84,7 @@ void multisig::approve( name proposer, name proposal_name, permission_level leve auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level ); - eosio_assert( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" ); + check( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" ); old_apptable.modify( apps, proposer, [&]( auto& a ) { a.provided_approvals.push_back( level ); @@ -100,7 +100,7 @@ void multisig::unapprove( name proposer, name proposal_name, permission_level le auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { auto itr = std::find_if( apps_it->provided_approvals.begin(), apps_it->provided_approvals.end(), [&](const approval& a) { return a.level == level; } ); - eosio_assert( itr != apps_it->provided_approvals.end(), "no approval previously granted" ); + check( itr != apps_it->provided_approvals.end(), "no approval previously granted" ); apptable.modify( apps_it, proposer, [&]( auto& a ) { a.requested_approvals.push_back( approval{ level, current_time_point() } ); a.provided_approvals.erase( itr ); @@ -109,7 +109,7 @@ void multisig::unapprove( name proposer, name proposal_name, permission_level le old_approvals old_apptable( _self, proposer.value ); auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); - eosio_assert( itr != apps.provided_approvals.end(), "no approval previously granted" ); + check( itr != apps.provided_approvals.end(), "no approval previously granted" ); old_apptable.modify( apps, proposer, [&]( auto& a ) { a.requested_approvals.push_back( level ); a.provided_approvals.erase( itr ); @@ -124,7 +124,7 @@ void multisig::cancel( name proposer, name proposal_name, name canceler ) { auto& prop = proptable.get( proposal_name.value, "proposal not found" ); if( canceler != proposer ) { - eosio_assert( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(current_time_point()), "cannot cancel until expiration" ); + check( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(current_time_point()), "cannot cancel until expiration" ); } proptable.erase(prop); @@ -136,7 +136,7 @@ void multisig::cancel( name proposer, name proposal_name, name canceler ) { } else { old_approvals old_apptable( _self, proposer.value ); auto apps_it = old_apptable.find( proposal_name.value ); - eosio_assert( apps_it != old_apptable.end(), "proposal not found" ); + check( apps_it != old_apptable.end(), "proposal not found" ); old_apptable.erase(apps_it); } } @@ -149,7 +149,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { transaction_header trx_header; datastream ds( prop.packed_transaction.data(), prop.packed_transaction.size() ); ds >> trx_header; - eosio_assert( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); + check( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); approvals apptable( _self, proposer.value ); auto apps_it = apptable.find( proposal_name.value ); @@ -180,7 +180,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { (const char*)0, 0, packed_provided_approvals.data(), packed_provided_approvals.size() ); - eosio_assert( res > 0, "transaction authorization failed" ); + check( res > 0, "transaction authorization failed" ); send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer.value, prop.packed_transaction.data(), prop.packed_transaction.size() ); From b92ede69d90676ac1310f3e22ace225d543a8950 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Dec 2018 18:57:37 -0500 Subject: [PATCH 0663/1048] Add additional fields to REX tables to allow binary extension --- .../eosio.system/include/eosio.system/eosio.system.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 940583e5..806d7dd8 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -187,6 +187,7 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_day = 24 * 3600; struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { + uint8_t which = 0; asset total_lent; /// total EOS in open rex_loans asset total_unlent; /// total EOS available to be lent (connector) asset total_rent; /// fees received in exchange for lent (connector) @@ -201,6 +202,7 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { + uint8_t which = 0; name owner; asset balance; @@ -210,6 +212,7 @@ namespace eosiosystem { typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { + uint8_t which = 0; name owner; asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote asset rex_balance; /// the amount of REX owned by owner @@ -222,6 +225,7 @@ namespace eosiosystem { typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { + uint8_t which = 0; name from; name receiver; asset payment; @@ -246,6 +250,7 @@ namespace eosiosystem { > rex_net_loan_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_order { + uint8_t which = 0; name owner; asset rex_requested; asset proceeds; @@ -298,7 +303,7 @@ namespace eosiosystem { static constexpr eosio::name rex_account{"eosio.rex"_n}; static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); - static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); + static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); system_contract( name s, name code, datastream ds ); ~system_contract(); From 37304ecdfcd3a6c659ca56663933629af77ec536 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 12 Dec 2018 19:31:58 -0500 Subject: [PATCH 0664/1048] rename which to version for added clarity --- .../include/eosio.system/eosio.system.hpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 806d7dd8..289e985d 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -187,7 +187,7 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_day = 24 * 3600; struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { - uint8_t which = 0; + uint8_t version = 0; asset total_lent; /// total EOS in open rex_loans asset total_unlent; /// total EOS available to be lent (connector) asset total_rent; /// fees received in exchange for lent (connector) @@ -202,7 +202,7 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { - uint8_t which = 0; + uint8_t version = 0; name owner; asset balance; @@ -212,7 +212,7 @@ namespace eosiosystem { typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { - uint8_t which = 0; + uint8_t version = 0; name owner; asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote asset rex_balance; /// the amount of REX owned by owner @@ -225,14 +225,14 @@ namespace eosiosystem { typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { - uint8_t which = 0; + uint8_t version = 0; name from; name receiver; asset payment; asset balance; asset total_staked; uint64_t loan_num; - eosio::time_point expiration; + eosio::time_point expiration; uint64_t primary_key()const { return loan_num; } uint64_t by_expr()const { return expiration.elapsed.count(); } @@ -250,14 +250,14 @@ namespace eosiosystem { > rex_net_loan_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_order { - uint8_t which = 0; + uint8_t version = 0; name owner; asset rex_requested; asset proceeds; asset stake_change; eosio::time_point order_time; bool is_open = true; - + void close() { is_open = false; } uint64_t primary_key()const { return owner.value; } uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } @@ -273,7 +273,7 @@ namespace eosiosystem { }; class [[eosio::contract("eosio.system")]] system_contract : public native { - + private: voters_table _voters; producers_table _producers; @@ -339,7 +339,7 @@ namespace eosiosystem { */ [[eosio::action]] void deposit( const name& owner, const asset& amount ); - + /** * Withdraws core tokens from user REX fund. Inline token transfer to user balance is * executed. @@ -364,13 +364,13 @@ namespace eosiosystem { void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); /** - * Converts REX stake back into core tokens at current exchange rate. If order cannot be + * Converts REX stake back into core tokens at current exchange rate. If order cannot be * processed, it gets queued until there is enough in REX pool to fill order. * If successful, user votes are updated. */ [[eosio::action]] void sellrex( const name& from, const asset& rex ); - + /** * Cancels queued sellrex order. Order cannot be cancelled once it's been filled. */ @@ -378,7 +378,7 @@ namespace eosiosystem { void cnclrexorder( const name& owner ); /** - * Use payment to rent as many SYS tokens as possible and stake them for either CPU or NET for the + * Use payment to rent as many SYS tokens as possible and stake them for either CPU or NET for the * benefit of receiver, after 30 days the rented SYS delegation of CPU or NET will expire unless loan * balance is larger than or equal to payment. * @@ -521,7 +521,7 @@ namespace eosiosystem { [[eosio::action]] void bidrefund( name bidder, name newname ); - + private: // Implementation details: From c070922b762815f397062a996ce42cfeb6fbcea2 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 12 Dec 2018 19:32:06 -0500 Subject: [PATCH 0665/1048] update eosio version soft max to 1.5 --- CMakeLists.txt | 1 + contracts/CMakeLists.txt | 2 ++ tests/CMakeLists.txt | 2 +- 3 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c24d1bb4..16095dcd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,6 +21,7 @@ message(STATUS "Building eosio.contracts v${VERSION_FULL}") set(EOSIO_CDT_VERSION_MIN "1.5") set(EOSIO_CDT_VERSION_SOFT_MAX "1.5") +#set(EOSIO_CDT_VERSION_HARD_MAX "") ### Check the version of eosio.cdt set(VERSION_MATCH_ERROR_MSG "") diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt index 7474785e..fb59ebf6 100644 --- a/contracts/CMakeLists.txt +++ b/contracts/CMakeLists.txt @@ -1,3 +1,5 @@ +cmake_minimum_required( VERSION 3.5 ) + project(contracts) set(EOSIO_WASM_OLD_BEHAVIOR "Off") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1e78a70f..b973fa6d 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 3.5 ) set(EOSIO_VERSION_MIN "1.4") -set(EOSIO_VERSION_SOFT_MAX "1.4") +set(EOSIO_VERSION_SOFT_MAX "1.5") #set(EOSIO_VERSION_HARD_MAX "") find_package(eosio) From 1067507f3325593463bba3b969e2298229d57b7c Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 12 Dec 2018 19:55:25 -0500 Subject: [PATCH 0666/1048] consistency for references to core symbol within comments --- .../eosio.system/include/eosio.system/eosio.system.hpp | 8 ++++---- contracts/eosio.system/src/voting.cpp | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 289e985d..ff7758a2 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -188,12 +188,12 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { uint8_t version = 0; - asset total_lent; /// total EOS in open rex_loans - asset total_unlent; /// total EOS available to be lent (connector) + asset total_lent; /// total amount of CORE_SYMBOL in open rex_loans + asset total_unlent; /// total amount of CORE_SYMBOL available to be lent (connector) asset total_rent; /// fees received in exchange for lent (connector) - asset total_lendable; /// total EOS that have been lent (total_unlent + total_lent) + asset total_lendable; /// total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent) asset total_rex; /// total number of REX shares allocated to contributors to total_lendable - asset namebid_proceeds; /// EOS to be transferred from namebids to REX pool + asset namebid_proceeds; /// the amount of CORE_SYMBOL to be transferred from namebids to REX pool uint64_t loan_num = 0; /// increments with each new loan uint64_t primary_key()const { return 0; } diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index d9cc8e5b..153ea9dd 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -182,7 +182,7 @@ namespace eosiosystem { * @pre if proxy is set then proxy account must exist and be registered as a proxy * @pre every listed producer or proxy must have been previously registered * @pre voter must authorize this action - * @pre voter must have previously staked some EOS for voting + * @pre voter must have previously staked some amount of CORE_SYMBOL for voting * @pre voter->staked must be up to date * * @post every producer previously voted for will have vote reduced by previous vote weight From bd5006cc8de62f62d07b43be14a90f06bc56e3a9 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Dec 2018 21:24:34 -0500 Subject: [PATCH 0667/1048] Added a comment on maximum REX token supply --- contracts/eosio.system/src/rex.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 8c912151..db4360b0 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -844,6 +844,14 @@ namespace eosiosystem { */ asset system_contract::add_to_rex_pool( const asset& payment ) { + /** + * If CORE_SYMBOL is (EOS,4), maximum supply is 10^10 tokens (10 billion tokens), i.e., maximum amount + * of indivisible units is 10^14. rex_ratio = 10^4 sets the upper bound on (REX,4) indivisible units to + * 10^18 and that is within the maximum allowable amount field of asset type which is set to 2^62 + * (approximately 4.6 * 10^18). For a different CORE_SYMBOL, and in order for maximum (REX,4) amount not + * to exceed that limit, maximum amount of indivisible units cannot be set to a value larger than 4 * 10^14. + * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. + */ const int64_t rex_ratio = 10000; const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() is made available asset rex_received( 0, rex_symbol ); From 44d53447e04cb9fc32e1a73aacb7119511363a29 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 12 Dec 2018 21:25:16 -0500 Subject: [PATCH 0668/1048] bump version to v1.6.0-rc1 --- CMakeLists.txt | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16095dcd..32c57283 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 6) set(VERSION_PATCH 0) -set(VERSION_SUFFIX develop) +set(VERSION_SUFFIX rc1) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index d055e7a8..ad782b95 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.5.1 +## Version : 1.6.0-rc1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.4.x](https://github.com/EOSIO/eos/releases/tag/v1.4.4) -* [eosio.cdt v1.4.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.4.1) +* [eosio v1.5.x](https://github.com/EOSIO/eos/releases/tag/v1.5.0) +* [eosio.cdt v1.5.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.5.0-rc1) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From e3a33325826217c7ca1f33a0f8c16b725328e627 Mon Sep 17 00:00:00 2001 From: zorba80 <35532164+zorba80@users.noreply.github.com> Date: Fri, 28 Dec 2018 13:41:21 -0500 Subject: [PATCH 0669/1048] Update README.md --- contracts/eosio.system/README.md | 240 +++++++++++++++++++++---------- 1 file changed, 164 insertions(+), 76 deletions(-) diff --git a/contracts/eosio.system/README.md b/contracts/eosio.system/README.md index 9e5c3160..26896b07 100755 --- a/contracts/eosio.system/README.md +++ b/contracts/eosio.system/README.md @@ -1,84 +1,172 @@ eosio.system ---------- -This contract enables users to stake tokens, and then configure and vote on producers and worker proposals. - -Users can also proxy their voting influence to other users. - -The state of this contract is read to determine the 21 active block producers. +This contract provides multiple functionalities: +- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. +- Producers register in order to be voted for, and can claim per-block and per-vote rewards. +- Users can buy and sell RAM at a market-determined price. +- Users can bid on premium names. +- A resource exchange system (REX) allows token holders to lend their tokens, and users to rent CPU and Network resources in return for a market-determined fee. Actions: The naming convention is codeaccount::actionname followed by a list of paramters. -Indicates that a particular account wishes to become a producer -## eosio.system::cfgproducer account config - - **account** the producer account to update - - updates the configuration settings for a particular producer, these - - Storage changes are billed to 'account' +## eosio::regproducer producer producer_key url location + - Indicates that a particular account wishes to become a producer + - **producer** account registering to be a producer candidate + - **producer_key** producer account public key + - **url** producer URL + - **location** currently unused index + +## eosio::voteproducer voter proxy producers + - **voter** the account doing the voting + - **proxy** proxy account to whom voter delegates vote + - **producers** list of producers voted for. A maximum of 30 producers is allowed + - Voter can vote for a proxy __or__ a list of at most 30 producers. Storage change is billed to `voter`. + +## eosio::regproxy proxy is_proxy + - **proxy** the account registering as voter proxy (or unregistering) + - **is_proxy** if true, proxy is registered; if false, proxy is unregistered + - Storage change is billed to `proxy`. -## eosio.system::okproducer account producer vote - - **account** the account which is doing the voting - - **producer** the producer which is being voted for (or unvoted for) - - **vote** true if the producer should be voted for, false if not - - Each account has a maximum number of votes it can maintain. Storage changes will be billed to 'account' - -## eosio.system::setproxy account proxy - - **account** the account which is updating it's proxy - - **proxy** the account which will have the power to vote account's stake - - All current votes are removed and a new proxy link is created. The votes for every producer the proxy - has voted for are updated immediately. - - Storage changes will be billed to 'account' - -## eosio.system::unstake account quantity - - **account** - the account which is requesting their balance be unstaked - - **quantity** - the quantity which will be unstaked, unstaked tokens lose voting influence immediately - - - in order to unstake tokens, an account must request them. The user will receive them over - time via weekly withdraws. The length of time will be configured by the median time as set by - the active producers. - - - If this is called while in the process of unstaking, the currently pending unstake is canceled as if - quantity were 0, then it is applied as if a new unstake request was made. - - - all producers this 'from' has voted for will have their votes updated immediately. - - - bandwidth and storage for the deferred transaction will be billed to 'from' - -## eosio.system::withdraw account - - this action can only be triggered by eosio.system via a deferred transaction generated by unstake - - this will generate an inline eosio.token::transfer call from=eosio.system to=account and amount equal to the next withdraw increment - - this will generate another deferred withdraw to continue the process if there are still withdraws to be made - - -## eosio.system::transfer from to amount memo - - decrements balance of from if amount <= balance - - increments balance of to by amount - - memo is ignored - -## eosio.system::stakevote account amount - - the primary currency of eosio is controlled by the token contract which enables users to transfer - balances from one user to another. The receiver is notified on incoming balances and the vote contract - will stake the tokens on receipt. - - - all producers this 'from' has voted for will have their votes updated immediately. - - -## eosio.system::onblock account blocktime blocknum - - this special action is triggered when a block is applied by the given producer and cannot be generated from - any other source. It is used to pay producers and calculate missed blocks of other producers. - - - producer pay is deposited into the producer's stake balance and can be withdrawn over time. - - - if blocknum is the start of a new round this may update the active producer config from the producer votes. - -## eosio.system::freeze producer accounts true|false - - requires permission of the @producers account - - if an account is frozen, all authorizations of that account are rejected and the code for that account will not be run - -## eosio.system::paystandby producer - - every block some amount of tokens is paid - - at most once per day a producer may claim a percentage of the standby pay equal to their totalvotes / allvotes +## eosio::delegatebw from receiver stake\_net\_quantity stake\_cpu\_quantity transfer + - **from** account holding tokens to be staked + - **receiver** account to whose resources staked tokens are added + - **stake\_net\_quantity** tokens staked for NET bandwidth + - **stake\_cpu\_quantity** tokens staked for CPU bandwidth + - **transfer** if true, ownership of staked tokens is transfered to `receiver` + - All producers `from` account has voted for will have their votes updated immediately. + +## eosio::undelegatebw from receiver unstake\_net\_quantity unstake\_cpu\_quantity + - **from** account whose tokens will be unstaked + - **receiver** account to whose benefit tokens have been staked + - **unstake\_net\_quantity** tokens to be unstaked from NET bandwidth + - **unstake\_cpu\_quantity** tokens to be unstaked from CPU bandwidth + - Unstaked tokens are transferred to `from` liquid balance via a deferred transaction with a delay of 3 days. + - If called during the delay period of a previous `undelegatebw` action, pending action is canceled and timer is reset. + - All producers `from` account has voted for will have their votes updated immediately. + - Bandwidth and storage for the deferred transaction are billed to `from`. + +## eosio::onblock header + - This special action is triggered when a block is applied by a given producer, and cannot be generated from + any other source. It is used increment the number of unpaid blocks by a producer and update producer schedule. + +## eosio::claimrewards producer + - **producer** producer account claiming per-block and per-vote rewards + +## eosio::deposit owner amount + - Deposits tokens to user REX fund + - **owner** REX fund owner account + - **amount** amount of tokens to be deposited + - An inline transfer from 'owner' liquid balance is executed. + - All REX-related costs and proceeds are deducted from and added to 'owner' REX fund, with one exception being buying REX using staked tokens. + - Storage change is billed to 'owner'. + +## eosio::withdraw owner amount + - Withdraws tokens from user REX fund + - **owner** REX fund owner account + - **amount** amount of tokens to be withdrawn + - An inline transfer to 'owner' liquid balance is executed. + +## eosio::buyrex from amount + - Buys REX in exchange for tokens taken out of user REX fund + - **from** owner account name + - **amount** amount of tokens to be used for purchase + - 'amount' tokens are taken out of 'from' REX fund. + - User must vote for at least 21 producers or delegate vote to proxy before buying REX. + - Tokens used in purchase are added to user's voting power. + - Bought REX cannot be sold before 4 days counting from end of day of purchase. + - Storage change is billed to 'from' account. + - By buying REX, user is lending tokens in order to be rented as CPU or NET resourses. + +## eosio::unstaketorex owner receiver from\_net from\_cpu + - Buys REX using staked tokens + - **owner** owner of staked tokens + - **receiver** account name that tokens have previously been staked to + - **from_net** amount of tokens to be unstaked from NET bandwidth and used for REX purchase + - **from_cpu** amount of tokens to be unstaked from CPU bandwidth and used for REX purchase + - User must vote for at least 21 producers or delegate vote to proxy before buying REX. + - Tokens used in purchase are added to user's voting power. + - Bought REX cannot be sold before 4 days counting from end of day of purchase. + - Storage change is billed to 'owner' account. + +## eosio::sellrex from rex + - Sells REX in exchange for core tokens + - **from** owner account of REX + - **rex** amount of REX to be sold + - Proceeds are deducted from user's voting power. + - If cannot be processed immediately, sell order is added to a queue and will be processed within 30 days at most. + - In case sell order is queued, storage change is billed to 'from' account. + +## eosio::cnclrexorder owner + - Cancels unfilled REX sell order by owner if one exists. + - **owner** owner account name + +## eosio::rentcpu from receiver loan\_payment loan\_fund + - Rents CPU resources for 30 days in exchange for market-determined price + - **from** account creating and paying for CPU loan + - **receiver** account receiving rented CPU resources + - **loan_payment** tokens paid for the loan + - **loan_fund** additional tokens (can be zero) added to loan fund and used later for loan renewal + - Rents as many core tokens as determined by market price and stakes them for CPU bandwidth for the benefit of `receiver` account. + - `loan_payment` is used for renting, it has to be greater than zero. Amount of rented resources is calculated from `loan_payment`. + - After 30 days the rented core delegation of CPU will expire or be renewed at new market price depending on available loan fund. + - `loan_fund` can be zero, and is added to loan balance. Loan balance represents a reserve that is used at expiration for automatic loan renewal. + - 'from' account can add tokens to loan balance using action `fundcpuloan` and withdraw from loan balance using `defcpuloan`. + - At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user is refunded any remaining balance. + +## eosio::rentnet from receiver loan\_payment loan\_fund + - Rents Network resources for 30 days in exchange for market-determined price + - **from** account creating and paying for Network loan + - **receiver** account receiving rented Network resources + - **loan_payment** tokens paid for the loan + - **loan_fund** additional tokens (can be zero) added to loan fund and used later for loan renewal + - Rents as many core tokens as determined by market price and stakes them for Network bandwidth for the benefit of `receiver` account. + - `loan_payment` is used for renting, it has to be greater than zero. Amount of rented resources is calculated from `loan_payment`. + - After 30 days the rented core delegation of Network will expire or be renewed at new market price depending on available loan fund. + - `loan_fund` can be zero, and is added to loan balance. Loan balance represents a reserve that is used at expiration for automatic loan renewal. + - 'from' account can add tokens to loan balance using action `fundnetloan` and withdraw from loan balance using `defnetloan`. + - At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user is refunded any remaining balance. + +## eosio::fundcpuloan from loan\_num payment + - Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry + - **from** loan creator account + - **loan_num** loan id + - **payment** tokens transfered from REX fund to loan fund + +## eosio::fundnetloan from loan\_num payment + - Transfers tokens from REX fund to the fund of a specific Network loan in order to be used for loan renewal at expiry + - **from** loan creator account + - **loan_num** loan id + - **payment** tokens transfered from REX fund to loan fund + +## eosio::defcpuloan from loan\_num amount + - Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund + - **from** loan creator account + - **loan_num** loan id + - **amount** tokens transfered from CPU loan fund to REX fund + +## eosio::defcpuloan from loan\_num amount + - Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund + - **from** loan creator account + - **loan_num** loan id + - **amount** tokens transfered from NET loan fund to REX fund + +## eosio::updaterex owner + - Updates REX owner vote weight to current value of held REX + - **owner** REX owner account + +## eosio::rexexec user max + - Performs REX maintenance by processing a specified number of REX sell orders and expired loans + - **user** any account can execute this action + - **max** number of each of CPU loans, NET loans, and sell orders to be processed + +## eosio::consolidate owner + - Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days + - **owner** REX owner account name + +## eosio::closerex owner + - Deletes unused REX-related database entries and frees occupied RAM + - **owner** user account name + - If owner has a non-zero REX balance, the action fails; otherwise, owner REX balance entry is deleted. + - If owner has no outstanding loans and a zero REX fund balance, REX fund entry is deleted. From 6d2f5c4144b6123bbdbeef8174adc34c0e674097 Mon Sep 17 00:00:00 2001 From: Zach <34947245+kj4ezj@users.noreply.github.com> Date: Thu, 3 Jan 2019 15:30:20 -0500 Subject: [PATCH 0670/1048] Created Pull Request Template (#161) Other: Created pull request template --- .github/PULL_REQUEST_TEMPLATE.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..36449129 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,17 @@ + + + +## Change Description + + + +## Deployment Changes + + + +## API Changes + + + +## Documentation Additions + From 20ce75f674e6c5c3c461fb373ce68c340119dcff Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 10 Jan 2019 18:21:37 -0500 Subject: [PATCH 0671/1048] Add inline dummy actions to sell and buy rex for bookkeeping --- .../include/eosio.system/eosio.system.hpp | 1 + contracts/eosio.system/src/rex.cpp | 36 +++++--- contracts/eosio.system/src/voting.cpp | 1 - tests/eosio.system_tester.hpp | 84 +++++++++++++++++++ tests/eosio.system_tests.cpp | 62 +++++--------- 5 files changed, 133 insertions(+), 51 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index ff7758a2..cd2dab44 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -301,6 +301,7 @@ namespace eosiosystem { static constexpr eosio::name names_account{"eosio.names"_n}; static constexpr eosio::name saving_account{"eosio.saving"_n}; static constexpr eosio::name rex_account{"eosio.rex"_n}; + static constexpr eosio::name null_account{"eosio.null"_n}; static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index db4360b0..99e57054 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -59,6 +59,10 @@ namespace eosiosystem { const asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); runrex(2); update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); + // dummy action added so that amount of REX tokens purchased shows up in action trace + dispatch_inline( null_account, "buyresult"_n, + std::vector{ { from, active_permission } }, + std::make_tuple( rex_received ) ); } /** @@ -75,7 +79,7 @@ namespace eosiosystem { check( from_net.symbol == core_symbol() && from_cpu.symbol == core_symbol(), "asset must be core token" ); check( (0 <= from_net.amount) && (0 <= from_cpu.amount) && (0 < from_net.amount || 0 < from_cpu.amount), - "must unstake a positive amount to buy rex" ); + "must unstake a positive amount to buy rex" ); check_voting_requirement( owner ); { @@ -101,6 +105,10 @@ namespace eosiosystem { add_to_rex_balance( owner, payment, rex_received ); runrex(2); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ), true ); + // dummy action added so that amount of REX tokens purchased shows up in action trace + dispatch_inline( null_account, "buyresult"_n, + std::vector{ { owner, active_permission } }, + std::make_tuple( rex_received ) ); } /** @@ -117,7 +125,7 @@ namespace eosiosystem { auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, - "asset must be a positive amount of (REX, 4)" ); + "asset must be a positive amount of (REX, 4)" ); process_rex_maturities( bitr ); check( rex.amount <= bitr->matured_rex, "insufficient available rex" ); @@ -142,10 +150,16 @@ namespace eosiosystem { _rexorders.modify( oitr, same_payer, [&]( auto& order ) { order.rex_requested.amount += rex.amount; check( order.rex_requested.amount <= bitr->matured_rex, - "insufficient funds for current and scheduled orders"); + "insufficient funds for current and scheduled orders"); }); } } + // dummy action added so that sell order proceeds show up in action trace + if ( current_order.success ) { + dispatch_inline( null_account, "sellresult"_n, + std::vector{ { from, active_permission } }, + std::make_tuple( current_order.proceeds ) ); + } } /** @@ -462,7 +476,6 @@ namespace eosiosystem { rt.total_lent.amount -= itr->total_staked.amount; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; }); - bool delete_loan = false; int64_t delta_stake = 0; if ( itr->payment <= itr->balance && rex_loans_available() ) { @@ -547,11 +560,16 @@ namespace eosiosystem { if ( bitr != _rexbalance.end() ) { // should always be true auto result = fill_rex_order( bitr, oitr->rex_requested ); if ( result.success ) { + const name order_owner = oitr->owner; idx.modify( oitr, same_payer, [&]( auto& order ) { order.proceeds.amount = result.proceeds.amount; order.stake_change.amount = result.stake_change.amount; order.close(); }); + /// send dummy action to show and owner and proceeds of filled sellrex order + dispatch_inline( null_account, "orderresult"_n, + std::vector{ { null_account, active_permission } }, + std::make_tuple( order_owner, result.proceeds ) ); } } oitr = next; @@ -676,8 +694,7 @@ namespace eosiosystem { */ void system_contract::transfer_from_fund( const name& owner, const asset& amount ) { - check( 0 < amount.amount && amount.symbol == core_symbol(), - "must transfer positive amount from REX fund" ); + check( 0 < amount.amount && amount.symbol == core_symbol(), "must transfer positive amount from REX fund" ); auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); check( amount <= itr->balance, "insufficient funds"); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { @@ -693,8 +710,7 @@ namespace eosiosystem { */ void system_contract::transfer_to_fund( const name& owner, const asset& amount ) { - check( 0 < amount.amount && amount.symbol == core_symbol(), - "must transfer positive amount to REX fund" ); + check( 0 < amount.amount && amount.symbol == core_symbol(), "must transfer positive amount to REX fund" ); auto itr = _rexfunds.find( owner.value ); if ( itr == _rexfunds.end() ) { _rexfunds.emplace( owner, [&]( auto& fund ) { @@ -860,7 +876,6 @@ namespace eosiosystem { /// initialize REX pool _rexpool.emplace( _self, [&]( auto& rp ) { rex_received.amount = payment.amount * rex_ratio; - rp.total_lendable = payment; rp.total_lent = asset( 0, core_symbol() ); rp.total_unlent = rp.total_lendable - rp.total_lent; @@ -870,8 +885,7 @@ namespace eosiosystem { }); } else if ( !rex_available() ) { /// should be a rare corner case, REX pool is initialized but empty _rexpool.modify( itr, same_payer, [&]( auto& rp ) { - rex_received.amount = payment.amount * rex_ratio; - + rex_received.amount = payment.amount * rex_ratio; rp.total_lendable.amount = payment.amount; rp.total_lent.amount = 0; rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 153ea9dd..a84c9f5a 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -206,7 +206,6 @@ namespace eosiosystem { if ( proxy ) { check( producers.size() == 0, "cannot vote for producers and proxy at same time" ); check( voter_name != proxy, "cannot proxy to self" ); - require_recipient( proxy ); } else { check( producers.size() <= 30, "attempt to vote for too many producers" ); for( size_t i = 1; i < producers.size(); ++i ) { diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 434928d5..0890efe0 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -6,6 +6,7 @@ #include #include +#include #include "contracts.hpp" #include "test_symbol.hpp" @@ -312,6 +313,20 @@ class eosio_system_tester : public TESTER { return unstake( acnt, acnt, net, cpu ); } + int64_t bancor_convert( int64_t S, int64_t R, int64_t T ) { return double(R) * T / ( double(S) + T ); }; + + int64_t get_net_limit( account_name a ) { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return net; + }; + + int64_t get_cpu_limit( account_name a ) { + int64_t ram_bytes = 0, net = 0, cpu = 0; + control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); + return cpu; + }; + action_result deposit( const account_name& owner, const asset& amount ) { return push_action( name(owner), N(deposit), mvo() ("owner", owner) @@ -333,6 +348,22 @@ class eosio_system_tester : public TESTER { ); } + asset get_buyrex_result( const account_name& from, const asset& amount ) { + auto trace = base_tester::push_action( N(eosio), N(buyrex), from, mvo()("from", from)("amount", amount) ); + asset rex_received; + for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { + for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { + if ( trace->action_traces[i].inline_traces[j].act.name == N(buyresult) ) { + fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), + trace->action_traces[i].inline_traces[j].act.data.size(), + rex_received ); + return rex_received; + } + } + } + return rex_received; + } + action_result unstaketorex( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { return push_action( name(owner), N(unstaketorex), mvo() ("owner", owner) @@ -342,6 +373,27 @@ class eosio_system_tester : public TESTER { ); } + asset get_unstaketorex_result( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { + auto trace = base_tester::push_action( N(eosio), N(unstaketorex), owner, mvo() + ("owner", owner) + ("receiver", receiver) + ("from_net", from_net) + ("from_cpu", from_cpu) + ); + asset rex_received; + for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { + for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { + if ( trace->action_traces[i].inline_traces[j].act.name == N(buyresult) ) { + fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), + trace->action_traces[i].inline_traces[j].act.data.size(), + rex_received ); + return rex_received; + } + } + } + return rex_received; + } + action_result sellrex( const account_name& from, const asset& rex ) { return push_action( name(from), N(sellrex), mvo() ("from", from) @@ -349,6 +401,38 @@ class eosio_system_tester : public TESTER { ); } + asset get_sellrex_result( const account_name& from, const asset& rex ) { + auto trace = base_tester::push_action( N(eosio), N(sellrex), from, mvo()("from", from)("rex", rex) ); + asset proceeds; + for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { + for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { + if ( trace->action_traces[i].inline_traces[j].act.name == N(sellresult) ) { + fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), + trace->action_traces[i].inline_traces[j].act.data.size(), + proceeds ); + return proceeds; + } + } + } + return proceeds; + } + + auto get_rexorder_result( const transaction_trace_ptr& trace ) { + std::vector> output; + for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { + for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { + if ( trace->action_traces[i].inline_traces[j].act.name == N(orderresult) ) { + fc::datastream ds( trace->action_traces[i].inline_traces[j].act.data.data(), + trace->action_traces[i].inline_traces[j].act.data.size() ); + account_name owner; fc::raw::unpack( ds, owner ); + asset proceeds; fc::raw::unpack( ds, proceeds ); + output.emplace_back( owner, proceeds ); + } + } + } + return output; + } + action_result cancelrexorder( const account_name& owner ) { return push_action( name(owner), N(cnclrexorder), mvo()("owner", owner) ); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index bb237b13..82bdbbe7 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3398,6 +3398,11 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); + BOOST_REQUIRE_EQUAL( asset::from_string("25000.0000 REX"), get_buyrex_result( alice, core_sym::from_string("2.5000") ) ); + produce_blocks(2); + produce_block(fc::days(5)); + BOOST_REQUIRE_EQUAL( core_sym::from_string("2.5000"), get_sellrex_result( alice, asset::from_string("25000.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("13.0000") ) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("13.0000"), get_rex_vote_stake( alice ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("17.0000") ) ); @@ -3448,17 +3453,6 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { - auto get_net_limit = [&](account_name a) -> int64_t { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return net; - }; - auto get_cpu_limit = [&](account_name a) -> int64_t { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return cpu; - }; - const int64_t ratio = 10000; const asset zero_asset = core_sym::from_string("0.0000"); const asset neg_asset = core_sym::from_string("-0.0001"); @@ -3509,7 +3503,7 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() == stake2votes( asset( init_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); produce_block( fc::days(4) ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( alice, alice, net_stake, cpu_stake ) ); + BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_unstaketorex_result( alice, alice, net_stake, cpu_stake ).get_amount() ); BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); @@ -3575,18 +3569,6 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { - auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; - auto get_net_limit = [&](account_name a) -> int64_t { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return net; - }; - auto get_cpu_limit = [&](account_name a) -> int64_t { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return cpu; - }; - const int64_t ratio = 10000; const asset init_balance = core_sym::from_string("10000.0000"); const asset init_net = core_sym::from_string("70.0000"); @@ -3673,7 +3655,6 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { - auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; const asset init_balance = core_sym::from_string("3000000.0000"); @@ -3751,8 +3732,16 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { produce_block( fc::hours(2) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are not currently available"), rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("0.0001") ) ); + { + auto trace = base_tester::push_action( N(eosio), N(buyrex), frank, + mvo()("from", frank)("amount", core_sym::from_string("0.0001")) ); + auto output = get_rexorder_result( trace ); + BOOST_REQUIRE_EQUAL( output.size(), 2 ); + BOOST_REQUIRE_EQUAL( output[0].first, bob ); + BOOST_REQUIRE_EQUAL( output[0].second, get_rex_order(bob)["proceeds"].as() ); + BOOST_REQUIRE_EQUAL( output[1].first, carol ); + BOOST_REQUIRE_EQUAL( output[1].second, get_rex_order(carol)["proceeds"].as() ); + } BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); @@ -3773,23 +3762,18 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( carol ).get_amount() ); BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); + { + auto trace = base_tester::push_action( N(eosio), N(buyrex), frank, + mvo()("from", frank)("amount", core_sym::from_string("0.0001")) ); + auto output = get_rexorder_result( trace ); + BOOST_REQUIRE_EQUAL( output.size(), 0 ); + } + } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { - auto bancor_convert = [](int64_t S, int64_t R, int64_t T) -> int64_t { return int64_t( double(R * T) / double(S + T) ); }; - auto get_net_limit = [&](account_name a) -> int64_t { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return net; - }; - auto get_cpu_limit = [&](account_name a) -> int64_t { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return cpu; - }; - const int64_t ratio = 10000; const asset init_balance = core_sym::from_string("10000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; From e44c5a1db9f66bac7c2c7cf49ac9fe6a8928e087 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 11 Jan 2019 17:09:15 -0500 Subject: [PATCH 0672/1048] Remove unnecessary permissions from inline dummy actions --- contracts/eosio.system/src/rex.cpp | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 99e57054..cc1113b7 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -60,9 +60,7 @@ namespace eosiosystem { runrex(2); update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); // dummy action added so that amount of REX tokens purchased shows up in action trace - dispatch_inline( null_account, "buyresult"_n, - std::vector{ { from, active_permission } }, - std::make_tuple( rex_received ) ); + dispatch_inline( null_account, "buyresult"_n, { }, std::make_tuple( rex_received ) ); } /** @@ -106,9 +104,7 @@ namespace eosiosystem { runrex(2); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ), true ); // dummy action added so that amount of REX tokens purchased shows up in action trace - dispatch_inline( null_account, "buyresult"_n, - std::vector{ { owner, active_permission } }, - std::make_tuple( rex_received ) ); + dispatch_inline( null_account, "buyresult"_n, { }, std::make_tuple( rex_received ) ); } /** @@ -156,9 +152,7 @@ namespace eosiosystem { } // dummy action added so that sell order proceeds show up in action trace if ( current_order.success ) { - dispatch_inline( null_account, "sellresult"_n, - std::vector{ { from, active_permission } }, - std::make_tuple( current_order.proceeds ) ); + dispatch_inline( null_account, "sellresult"_n, { }, std::make_tuple( current_order.proceeds ) ); } } @@ -567,9 +561,7 @@ namespace eosiosystem { order.close(); }); /// send dummy action to show and owner and proceeds of filled sellrex order - dispatch_inline( null_account, "orderresult"_n, - std::vector{ { null_account, active_permission } }, - std::make_tuple( order_owner, result.proceeds ) ); + dispatch_inline( null_account, "orderresult"_n, { }, std::make_tuple( order_owner, result.proceeds ) ); } } oitr = next; From 38db481eaea3bfdb70065b174b0e04a35cbe4939 Mon Sep 17 00:00:00 2001 From: Zach <34947245+kj4ezj@users.noreply.github.com> Date: Tue, 15 Jan 2019 11:22:09 -0500 Subject: [PATCH 0673/1048] Other: Added checkbox to pull request template (#164) --- .github/PULL_REQUEST_TEMPLATE.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 36449129..bff172e4 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -6,12 +6,18 @@ ## Deployment Changes +- [ ] Deployment Changes + ## API Changes +- [ ] API Changes + ## Documentation Additions +- [ ] Documentation Additions + From 69d7a6c31a12877fed6c7252775bea972767bb70 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 15 Jan 2019 14:27:30 -0500 Subject: [PATCH 0674/1048] add functionality to set explicit resources --- .../include/eosio.system/eosio.system.hpp | 41 ++++- .../eosio.system/src/delegate_bandwidth.cpp | 42 ++++- contracts/eosio.system/src/eosio.system.cpp | 148 +++++++++++++++++- contracts/eosio.system/src/rex.cpp | 61 +++++--- 4 files changed, 259 insertions(+), 33 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index ff7758a2..2cd6e22f 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -13,6 +13,8 @@ #include #include +#include +#include #ifdef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX #undef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX @@ -37,6 +39,25 @@ namespace eosiosystem { using eosio::datastream; using eosio::check; + template + static inline auto has_field( F flags, E field ) + -> std::enable_if_t< std::is_integral_v && std::is_unsigned_v && + std::is_enum_v && std::is_same_v< F, std::underlying_type_t >, bool> + { + return ( (flags & static_cast(field)) != 0 ); + } + + template + static inline auto set_field( F flags, E field, bool value = true ) + -> std::enable_if_t< std::is_integral_v && std::is_unsigned_v && + std::is_enum_v && std::is_same_v< F, std::underlying_type_t >, F > + { + if( value ) + return ( flags | static_cast(field) ); + else + return ( flags & ~static_cast(field) ); + } + struct [[eosio::table, eosio::contract("eosio.system")]] name_bid { name newname; name high_bidder; @@ -162,14 +183,20 @@ namespace eosiosystem { bool is_proxy = 0; /// whether the voter is a proxy for others - uint32_t reserved1 = 0; + uint32_t flags1 = 0; uint32_t reserved2 = 0; eosio::asset reserved3; uint64_t primary_key()const { return owner.value; } + enum class flags1_fields : uint32_t { + ram_managed = 1, + net_managed = 2, + cpu_managed = 4 + }; + // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(reserved1)(reserved2)(reserved3) ) + EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(flags1)(reserved2)(reserved3) ) }; typedef eosio::multi_index< "voters"_n, voter_info > voters_table; @@ -322,6 +349,16 @@ namespace eosiosystem { [[eosio::action]] void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); + + [[eosio::action]] + void setacctram( name account, std::optional ram_bytes ); + + [[eosio::action]] + void setacctnet( name account, std::optional net_weight ); + + [[eosio::action]] + void setacctcpu( name account, std::optional cpu_weight ); + // functions defined in delegate_bandwidth.cpp /** diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 1b574da3..a33bb63c 100755 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -163,7 +163,13 @@ namespace eosiosystem { res.ram_bytes += bytes_out; }); } - set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + + auto voter_itr = _voters.find( res_itr->owner.value ); + if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { + int64_t ram_bytes, net, cpu; + get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); + set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); + } } /** @@ -201,7 +207,13 @@ namespace eosiosystem { userres.modify( res_itr, account, [&]( auto& res ) { res.ram_bytes -= bytes; }); - set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount ); + + auto voter_itr = _voters.find( res_itr->owner.value ); + if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { + int64_t ram_bytes, net, cpu; + get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); + set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); + } INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {ram_account, active_permission}, {account, active_permission} }, @@ -285,10 +297,28 @@ namespace eosiosystem { check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); - int64_t ram_bytes, net, cpu; - get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); - - set_resource_limits( receiver.value, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount ); + { + bool ram_managed = false; + bool net_managed = false; + bool cpu_managed = false; + + auto voter_itr = _voters.find( receiver.value ); + if( voter_itr != _voters.end() ) { + ram_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ); + net_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::net_managed ); + cpu_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::cpu_managed ); + } + + if( !(net_managed && cpu_managed) ) { + int64_t ram_bytes, net, cpu; + get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); + + set_resource_limits( receiver.value, + ram_managed ? ram_bytes : std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), + net_managed ? net : tot_itr->net_weight.amount, + cpu_managed ? cpu : tot_itr->cpu_weight.amount ); + } + } if ( tot_itr->is_empty() ) { totals_tbl.erase( tot_itr ); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 3e8374c3..608d818f 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -128,12 +128,155 @@ namespace eosiosystem { void system_contract::setalimits( name account, int64_t ram, int64_t net, int64_t cpu ) { require_auth( _self ); + user_resources_table userres( _self, account.value ); auto ritr = userres.find( account.value ); check( ritr == userres.end(), "only supports unlimited accounts" ); + + auto vitr = _voters.find( account.value ); + if( vitr != _voters.end() ) { + bool ram_managed = has_field( vitr->flags1, voter_info::flags1_fields::ram_managed ); + bool net_managed = has_field( vitr->flags1, voter_info::flags1_fields::net_managed ); + bool cpu_managed = has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed ); + check( !(ram_managed || net_managed || cpu_managed), "cannot use setalimits on an account with managed resources" ); + } + set_resource_limits( account.value, ram, net, cpu ); } + void system_contract::setacctram( name account, std::optional ram_bytes ) { + require_auth( _self ); + + int64_t current_ram, current_net, current_cpu; + get_resource_limits( account.value, ¤t_ram, ¤t_net, ¤t_cpu ); + + int64_t ram = 0; + + if( !ram_bytes ) { + auto vitr = _voters.find( account.value ); + check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::ram_managed ), + "RAM of account is already unmanaged" ); + + user_resources_table userres( _self, account.value ); + auto ritr = userres.find( account.value ); + + ram = ram_gift_bytes; + if( ritr != userres.end() ) { + ram += ritr->ram_bytes; + } + + _voters.modify( vitr, same_payer, [&]( auto& v ) { + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, false ); + }); + } else { + check( *ram_bytes >= 0, "not allowed to set RAM limit to unlimited" ); + + auto vitr = _voters.find( account.value ); + if ( vitr != _voters.end() ) { + _voters.modify( vitr, same_payer, [&]( auto& v ) { + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, true ); + }); + } else { + _voters.emplace( account, [&]( auto& v ) { + v.owner = account; + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, true ); + }); + } + + ram = *ram_bytes; + } + + set_resource_limits( account.value, ram, current_net, current_cpu ); + } + + void system_contract::setacctnet( name account, std::optional net_weight ) { + require_auth( _self ); + + int64_t current_ram, current_net, current_cpu; + get_resource_limits( account.value, ¤t_ram, ¤t_net, ¤t_cpu ); + + int64_t net = 0; + + if( !net_weight ) { + auto vitr = _voters.find( account.value ); + check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::net_managed ), + "Network bandwidth of account is already unmanaged" ); + + user_resources_table userres( _self, account.value ); + auto ritr = userres.find( account.value ); + + if( ritr != userres.end() ) { + net = ritr->net_weight.amount; + } + + _voters.modify( vitr, same_payer, [&]( auto& v ) { + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, false ); + }); + } else { + check( *net_weight >= -1, "invalid value for net_weight" ); + + auto vitr = _voters.find( account.value ); + if ( vitr != _voters.end() ) { + _voters.modify( vitr, same_payer, [&]( auto& v ) { + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, true ); + }); + } else { + _voters.emplace( account, [&]( auto& v ) { + v.owner = account; + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, true ); + }); + } + + net = *net_weight; + } + + set_resource_limits( account.value, current_ram, net, current_cpu ); + } + + void system_contract::setacctcpu( name account, std::optional cpu_weight ) { + require_auth( _self ); + + int64_t current_ram, current_net, current_cpu; + get_resource_limits( account.value, ¤t_ram, ¤t_net, ¤t_cpu ); + + int64_t cpu = 0; + + if( !cpu_weight ) { + auto vitr = _voters.find( account.value ); + check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed ), + "CPU bandwidth of account is already unmanaged" ); + + user_resources_table userres( _self, account.value ); + auto ritr = userres.find( account.value ); + + if( ritr != userres.end() ) { + cpu = ritr->cpu_weight.amount; + } + + _voters.modify( vitr, same_payer, [&]( auto& v ) { + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, false ); + }); + } else { + check( *cpu_weight >= -1, "invalid value for cpu_weight" ); + + auto vitr = _voters.find( account.value ); + if ( vitr != _voters.end() ) { + _voters.modify( vitr, same_payer, [&]( auto& v ) { + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, true ); + }); + } else { + _voters.emplace( account, [&]( auto& v ) { + v.owner = account; + v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, true ); + }); + } + + cpu = *cpu_weight; + } + + set_resource_limits( account.value, current_ram, current_net, cpu ); + } + void system_contract::rmvproducer( name producer ) { require_auth( _self ); auto prod = _producers.find( producer.value ); @@ -308,7 +451,7 @@ namespace eosiosystem { m.quote.balance.amount = system_token_supply.amount / 1000; m.quote.balance.symbol = core; }); - + INLINE_ACTION_SENDER(eosio::token, open)( token_account, { _self, active_permission }, { rex_account, core, _self } ); } @@ -320,7 +463,8 @@ EOSIO_DISPATCH( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp - (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund) + (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu) + (rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) (defcpuloan)(defnetloan)(updaterex)(consolidate)(rexexec)(closerex) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index db4360b0..ba98a09c 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -410,33 +410,48 @@ namespace eosiosystem { return; } + user_resources_table totals_tbl( _self, receiver.value ); + auto tot_itr = totals_tbl.find( receiver.value ); + if ( tot_itr == totals_tbl.end() ) { + check( 0 <= delta_net && 0 <= delta_cpu, "logic error, should not occur"); + tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { + tot.owner = receiver; + tot.net_weight = asset( delta_net, core_symbol() ); + tot.cpu_weight = asset( delta_cpu, core_symbol() ); + }); + } else { + totals_tbl.modify( tot_itr, same_payer, [&]( auto& tot ) { + tot.net_weight.amount += delta_net; + tot.cpu_weight.amount += delta_cpu; + }); + } + check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); + check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); + + if ( tot_itr->is_empty() ) { + totals_tbl.erase( tot_itr ); + } + { - user_resources_table totals_tbl( _self, receiver.value ); - auto tot_itr = totals_tbl.find( receiver.value ); - if ( tot_itr == totals_tbl.end() ) { - check( 0 <= delta_net && 0 <= delta_cpu, "logic error, should not occur"); - tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { - tot.owner = receiver; - tot.net_weight = asset( delta_net, core_symbol() ); - tot.cpu_weight = asset( delta_cpu, core_symbol() ); - }); - } else { - totals_tbl.modify( tot_itr, same_payer, [&]( auto& tot ) { - tot.net_weight.amount += delta_net; - tot.cpu_weight.amount += delta_cpu; - }); + bool net_managed = false; + bool cpu_managed = false; + + auto voter_itr = _voters.find( receiver.value ); + if( voter_itr != _voters.end() ) { + net_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::net_managed ); + cpu_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::cpu_managed ); } - check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); - check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); - - if ( tot_itr->is_empty() ) { - totals_tbl.erase( tot_itr ); + + if( !(net_managed && cpu_managed) ) { + int64_t ram_bytes = 0, net = 0, cpu = 0; + get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); + + set_resource_limits( receiver.value, + ram_bytes, + net_managed ? net : tot_itr->net_weight.amount, + cpu_managed ? cpu : tot_itr->cpu_weight.amount ); } } - - int64_t ram_bytes = 0, net = 0, cpu = 0; - get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); - set_resource_limits( receiver.value, ram_bytes, net + delta_net, cpu + delta_cpu ); } void system_contract::check_voting_requirement( const name& owner, const char* error_msg )const From 8eef0fc612e0b6f20872b09bc2f29a17a271105b Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 15 Jan 2019 14:28:11 -0500 Subject: [PATCH 0675/1048] unit tests for new actions to set explicit resources --- tests/eosio.system_tests.cpp | 218 ++++++++++++++++++++++++++++------- 1 file changed, 179 insertions(+), 39 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index bb237b13..4740cebc 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include #include @@ -3392,7 +3393,7 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("100000.0000"); + const asset init_rent = core_sym::from_string("100000.0000"); const asset init_balance = core_sym::from_string("1000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; @@ -3428,7 +3429,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), sellrex( bob, asset::from_string("-75.0030 REX") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); - + auto init_total_rex = rex_pool["total_rex"].as().get_amount(); auto init_total_lendable = rex_pool["total_lendable"].as().get_amount(); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset::from_string("550000.6800 REX") ) ); @@ -3523,7 +3524,7 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes stake2votes( asset( current_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() < current_prod_info["total_votes"].as_double() ); } - + { const asset net_stake = core_sym::from_string("200.5000"); const asset cpu_stake = core_sym::from_string("120.0000"); @@ -3607,7 +3608,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { const asset init_tot_unlent = rex_pool["total_unlent"].as(); const asset init_tot_lendable = rex_pool["total_lendable"].as(); const asset init_tot_rent = rex_pool["total_rent"].as(); - const int64_t init_stake = get_voter_info(alice)["staked"].as(); + const int64_t init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); @@ -3625,7 +3626,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_pool["total_lent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); - + // test that carol's resource limits have been updated properly BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); @@ -3636,7 +3637,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); - + produce_block( fc::days(20) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); @@ -3648,7 +3649,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); - + rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 0, rex_pool["total_unlent"].as().get_amount() ); @@ -3688,12 +3689,12 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); BOOST_REQUIRE_EQUAL( success(), buyrex( carol, purchase3) ); - + BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_rex_fund(alice) ); BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_rex_fund(bob) ); BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_rex_fund(carol) ); - + auto init_alice_rex = get_rex_balance(alice); auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); @@ -3706,9 +3707,9 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { const auto init_rex_pool = get_rex_pool(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * init_rex_pool["total_lendable"].as().get_amount() ) / init_rex_pool["total_rex"].as().get_amount(); - + produce_block( fc::days(5) ); - + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); @@ -3725,7 +3726,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); - + // now bob's, carol's and alice's sellrex orders have been queued BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); @@ -3744,7 +3745,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - // wait for 2 more hours, by now frank's loan has expired and there is enough balance in + // wait for 2 more hours, by now frank's loan has expired and there is enough balance in // total_unlent to close some sellrex orders. only two are processed, bob's and carol's // alices's order is still open // an action is needed to trigger queue processing @@ -3765,7 +3766,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); - + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); @@ -3797,7 +3798,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { setup_rex_accounts( accounts, init_balance ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("500.0000") ) ); - + auto rex_pool = get_rex_pool(); const asset payment = core_sym::from_string("30.0000"); const asset zero_asset = core_sym::from_string("0.0000"); @@ -3807,7 +3808,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { int64_t expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount(), rex_pool["total_unlent"].as().get_amount(), payment.get_amount() ); - const int64_t init_stake = get_cpu_limit( frank ); + const int64_t init_stake = get_cpu_limit( frank ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use core token"), rentcpu( frank, bob, asset::from_string("10.0000 RND") ) ); @@ -3868,7 +3869,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( fundcpuloan( frank, 1, amount ), success() ); BOOST_REQUIRE_EQUAL( old_loan_balance + amount, get_cpu_loan(1)["balance"].as() ); cur_frank_balance = get_rex_fund( frank ); - BOOST_REQUIRE_EQUAL( old_frank_balance - amount, cur_frank_balance ); + BOOST_REQUIRE_EQUAL( old_frank_balance - amount, cur_frank_balance ); } // wait for 30 days, frank's loan will be renewed at the current price @@ -3878,14 +3879,14 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { int64_t unlent_tokens = bancor_convert( rex_pool["total_unlent"].as().get_amount(), rex_pool["total_rent"].as().get_amount(), expected_stake ); - - expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount() - unlent_tokens, + + expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount() - unlent_tokens, rex_pool["total_unlent"].as().get_amount() + expected_stake, payment.get_amount() ); } - + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); - + loan_info = get_cpu_loan(1); BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); BOOST_REQUIRE_EQUAL( fund - payment, loan_info["balance"].as() ); @@ -3935,7 +3936,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyram( bob, carol, core_sym::from_string("70.0000") ) ); BOOST_REQUIRE_EQUAL( cur_ramfee_balance, get_balance( N(eosio.ramfee) ) ); BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("0.3500") ); - + cur_rex_balance = get_balance( N(eosio.rex) ); auto cur_rex_pool = get_rex_pool(); @@ -3944,7 +3945,7 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( cur_rex_balance, cur_rex_pool["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); - // required for closing namebids + // required for closing namebids cross_15_percent_threshold(); produce_block( fc::days(14) ); @@ -3986,12 +3987,12 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("18.5000") ) ); produce_block( fc::hours(25) ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("25.0000") ) ); - + auto rex_balance = get_rex_balance_obj( alice ); BOOST_REQUIRE_EQUAL( 550000 * rex_ratio, rex_balance["rex_balance"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( alice, asset::from_string("115000.0000 REX") ) ); produce_block( fc::hours( 3*24 + 20) ); @@ -4017,7 +4018,7 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); } - + { const asset payment1 = core_sym::from_string("14.8000"); const asset payment2 = core_sym::from_string("15.2000"); @@ -4029,22 +4030,22 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); produce_block( fc::hours(24) ); } - + auto rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - + BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - + produce_block( fc::hours(2) ); BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - + produce_block( fc::hours(1) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 3 * rex_bucket.get_amount(), rex_sym ) ) ); rex_balance = get_rex_balance_obj( bob ); @@ -4064,12 +4065,12 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - + BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - + produce_block( fc::days(3) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); @@ -4093,14 +4094,14 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); produce_block( fc::days(2) ); BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - + auto rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, alice, core_sym::from_string("800000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket1.get_amount() - 20, rex_sym ) ) ); rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), get_rex_order( bob )["rex_requested"].as().get_amount() + 20 ); + BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), get_rex_order( bob )["rex_requested"].as().get_amount() + 20 ); BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); @@ -4154,7 +4155,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) + BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); @@ -4203,7 +4204,7 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit to REX fund first"), withdraw( alice, core_sym::from_string("0.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), deposit( alice, init_balance + init_balance ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit core token"), deposit( alice, asset::from_string("1.0000 RNDM") ) ); - + asset deposit_quant( init_balance.get_amount() / 5, init_balance.get_symbol() ); BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant ); @@ -4233,7 +4234,7 @@ BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { const asset payment = core_sym::from_string("50.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, payment ) ); - + const auto rex_pool = get_rex_pool(); const int64_t tot_rex = rex_pool["total_rex"].as().get_amount(); const int64_t tot_unlent = rex_pool["total_unlent"].as().get_amount(); @@ -4284,7 +4285,7 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), deposit( bob, init_balance ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); - + BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, emily, init_balance ) ); produce_block( fc::days(20) ); @@ -4296,7 +4297,7 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( carol ).is_null() ); BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( carol ).is_null() ); - + BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, init_balance ) ); BOOST_REQUIRE_EQUAL( success(), closerex( emily ) ); @@ -4377,4 +4378,143 @@ BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( change_limited_account_back_to_unlimited, eosio_system_tester ) try { + BOOST_REQUIRE( get_total_stake( "eosio" ).is_null() ); + + transfer( N(eosio), N(alice1111111), core_sym::from_string("1.0000") ); + + auto error_msg = stake( N(alice1111111), N(eosio), core_sym::from_string("0.0000"), core_sym::from_string("1.0000") ); + auto semicolon_pos = error_msg.find(';'); + + BOOST_REQUIRE_EQUAL( error("account eosio has insufficient ram"), + error_msg.substr(0, semicolon_pos) ); + + int64_t ram_bytes_needed = 0; + { + std::istringstream s( error_msg ); + s.seekg( semicolon_pos + 7, std::ios_base::beg ); + s >> ram_bytes_needed; + ram_bytes_needed += 256; // enough room to cover total_resources_table + } + + push_action( N(eosio), N(setalimits), mvo() + ("account", "eosio") + ("ram_bytes", ram_bytes_needed) + ("net_weight", -1) + ("cpu_weight", -1) + ); + + stake( N(alice1111111), N(eosio), core_sym::from_string("0.0000"), core_sym::from_string("1.0000") ); + + REQUIRE_MATCHING_OBJECT( get_total_stake( "eosio" ), mvo() + ("owner", "eosio") + ("net_weight", core_sym::from_string("0.0000")) + ("cpu_weight", core_sym::from_string("1.0000")) + ("ram_bytes", 0) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "only supports unlimited accounts" ), + push_action( N(eosio), N(setalimits), mvo() + ("account", "eosio") + ("ram_bytes", ram_bytes_needed) + ("net_weight", -1) + ("cpu_weight", -1) + ) + ); + + BOOST_REQUIRE_EQUAL( error( "transaction net usage is too high: 128 > 0" ), + push_action( N(eosio), N(setalimits), mvo() + ("account", "eosio.saving") + ("ram_bytes", -1) + ("net_weight", -1) + ("cpu_weight", -1) + ) + ); + + BOOST_REQUIRE_EQUAL( success(), + push_action( N(eosio), N(setacctnet), mvo() + ("account", "eosio") + ("net_weight", -1) + ) + ); + + BOOST_REQUIRE_EQUAL( success(), + push_action( N(eosio), N(setacctcpu), mvo() + ("account", "eosio") + ("cpu_weight", -1) + + ) + ); + + BOOST_REQUIRE_EQUAL( success(), + push_action( N(eosio), N(setalimits), mvo() + ("account", "eosio.saving") + ("ram_bytes", ram_bytes_needed) + ("net_weight", -1) + ("cpu_weight", -1) + ) + ); + +} FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( buy_pin_sell_ram, eosio_system_tester ) try { + BOOST_REQUIRE( get_total_stake( "eosio" ).is_null() ); + + transfer( N(eosio), N(alice1111111), core_sym::from_string("1020.0000") ); + + auto error_msg = stake( N(alice1111111), N(eosio), core_sym::from_string("10.0000"), core_sym::from_string("10.0000") ); + auto semicolon_pos = error_msg.find(';'); + + BOOST_REQUIRE_EQUAL( error("account eosio has insufficient ram"), + error_msg.substr(0, semicolon_pos) ); + + int64_t ram_bytes_needed = 0; + { + std::istringstream s( error_msg ); + s.seekg( semicolon_pos + 7, std::ios_base::beg ); + s >> ram_bytes_needed; + ram_bytes_needed += ram_bytes_needed/10; // enough buffer to make up for buyrambytes estimation errors + } + + auto alice_original_balance = get_balance( N(alice1111111) ); + + BOOST_REQUIRE_EQUAL( success(), buyrambytes( N(alice1111111), N(eosio), static_cast(ram_bytes_needed) ) ); + + auto tokens_paid_for_ram = alice_original_balance - get_balance( N(alice1111111) ); + + auto total_res = get_total_stake( "eosio" ); + + REQUIRE_MATCHING_OBJECT( total_res, mvo() + ("owner", "eosio") + ("net_weight", core_sym::from_string("0.0000")) + ("cpu_weight", core_sym::from_string("0.0000")) + ("ram_bytes", total_res["ram_bytes"].as_int64() ) + ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "only supports unlimited accounts" ), + push_action( N(eosio), N(setalimits), mvo() + ("account", "eosio") + ("ram_bytes", ram_bytes_needed) + ("net_weight", -1) + ("cpu_weight", -1) + ) + ); + + BOOST_REQUIRE_EQUAL( success(), + push_action( N(eosio), N(setacctram), mvo() + ("account", "eosio") + ("ram_bytes", total_res["ram_bytes"].as_int64() ) + ) + ); + + auto eosio_original_balance = get_balance( N(eosio) ); + + BOOST_REQUIRE_EQUAL( success(), sellram( N(eosio), total_res["ram_bytes"].as_int64() ) ); + + auto tokens_received_by_selling_ram = get_balance( N(eosio) ) - eosio_original_balance; + + BOOST_REQUIRE( double(tokens_paid_for_ram.get_amount() - tokens_received_by_selling_ram.get_amount()) / tokens_paid_for_ram.get_amount() < 0.01 ); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() From 9f60beead44ca4a33e671f3eab8e1e366fc3e761 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 15 Jan 2019 14:49:19 -0500 Subject: [PATCH 0676/1048] update version and expand eosio version dependency range --- CMakeLists.txt | 2 +- tests/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 32c57283..5426805c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 6) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc1) +set(VERSION_SUFFIX rc2) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b973fa6d..4660381a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 3.5 ) set(EOSIO_VERSION_MIN "1.4") -set(EOSIO_VERSION_SOFT_MAX "1.5") +set(EOSIO_VERSION_SOFT_MAX "1.6") #set(EOSIO_VERSION_HARD_MAX "") find_package(eosio) From 060a9f891c0c766e964c7c1ff6b2cf0adab8f430 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 15 Jan 2019 15:53:31 -0500 Subject: [PATCH 0677/1048] Fix sellrex bug --- contracts/eosio.system/src/rex.cpp | 18 ++++----- tests/eosio.system_tester.hpp | 5 +++ tests/eosio.system_tests.cpp | 64 +++++++++++++++++++++++++++++- 3 files changed, 76 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index cc1113b7..44341b5e 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -126,7 +126,7 @@ namespace eosiosystem { check( rex.amount <= bitr->matured_rex, "insufficient available rex" ); auto current_order = fill_rex_order( bitr, rex ); - update_rex_account( from, current_order.proceeds, current_order.stake_change ); + asset pending_sell_order = update_rex_account( from, current_order.proceeds, current_order.stake_change ); if ( !current_order.success ) { /** * REX order couldn't be filled and is added to queue. @@ -134,7 +134,7 @@ namespace eosiosystem { */ auto oitr = _rexorders.find( from.value ); if ( oitr == _rexorders.end() ) { - _rexorders.emplace( from, [&]( auto& order ) { + oitr = _rexorders.emplace( from, [&]( auto& order ) { order.owner = from; order.rex_requested = rex; order.is_open = true; @@ -145,11 +145,11 @@ namespace eosiosystem { } else { _rexorders.modify( oitr, same_payer, [&]( auto& order ) { order.rex_requested.amount += rex.amount; - check( order.rex_requested.amount <= bitr->matured_rex, - "insufficient funds for current and scheduled orders"); }); } + pending_sell_order.amount = oitr->rex_requested.amount; } + check( pending_sell_order.amount <= bitr->matured_rex, "insufficient funds for current and scheduled orders" ); // dummy action added so that sell order proceeds show up in action trace if ( current_order.success ) { dispatch_inline( null_account, "sellresult"_n, { }, std::make_tuple( current_order.proceeds ) ); @@ -575,7 +575,7 @@ namespace eosiosystem { { runrex(2); - check( rex_loans_available(), "rex loans are not currently available" ); + check( rex_loans_available(), "rex loans are currently not available" ); check( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); check( 0 < payment.amount && 0 <= fund.amount, "must use positive asset amount" ); @@ -735,7 +735,7 @@ namespace eosiosystem { { asset to_fund( proceeds ); asset to_stake( delta_stake ); - asset rex_in_sell_order( 0, core_symbol() ); + asset rex_in_sell_order( 0, rex_symbol ); auto itr = _rexorders.find( owner.value ); if ( itr != _rexorders.end() ) { if ( itr->is_open ) { @@ -839,7 +839,9 @@ namespace eosiosystem { total += rb.rex_maturities.front().second; rb.rex_maturities.pop_front(); } - rb.rex_maturities.emplace_back( get_rex_maturity(), total ); + if (total > 0 ) { + rb.rex_maturities.emplace_back( get_rex_maturity(), total ); + } }); } @@ -891,9 +893,7 @@ namespace eosiosystem { const int64_t S1 = S0 + payment.amount; const int64_t R0 = itr->total_rex.amount; const int64_t R1 = (uint128_t(S1) * R0) / S0; - rex_received.amount = R1 - R0; - _rexpool.modify( itr, same_payer, [&]( auto& rp ) { rp.total_lendable.amount = S1; rp.total_rex.amount = R1; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 0890efe0..1bde1f55 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -587,6 +587,11 @@ class eosio_system_tester : public TESTER { return abi_ser.binary_to_variant( "rex_order", data, abi_serializer_max_time ); } + fc::variant get_rex_order_obj( const account_name& act ) { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_order", data, abi_serializer_max_time ); + } + fc::variant get_rex_pool() const { vector data; const auto& db = control->db(); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 82bdbbe7..2853613f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3653,6 +3653,66 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { + + const int64_t ratio = 10000; + const asset init_balance = core_sym::from_string("10000.0000"); + const asset init_net = core_sym::from_string("70.0000"); + const asset init_cpu = core_sym::from_string("90.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; + setup_rex_accounts( accounts, init_balance, init_net, init_cpu ); + + const int64_t init_cpu_limit = get_cpu_limit( alice ); + const int64_t init_net_limit = get_net_limit( alice ); + + // alice lends rex + const asset payment = core_sym::from_string("65.0000"); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("0.0005") ) ); + BOOST_REQUIRE_EQUAL( init_balance - payment, get_rex_fund(alice) ); + auto rex_pool = get_rex_pool(); + const asset init_tot_unlent = rex_pool["total_unlent"].as(); + const asset init_tot_lendable = rex_pool["total_lendable"].as(); + const asset init_tot_rent = rex_pool["total_rent"].as(); + const int64_t init_stake = get_voter_info(alice)["staked"].as(); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) + get_rex_balance(bob) ); + + // bob rents cpu for carol + const asset fee = core_sym::from_string("7.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); + rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); + + produce_block( fc::days(5) ); + produce_blocks(2); + const asset rex_unit = asset::from_string("0.0001 REX"); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) - rex_unit ) ); + BOOST_REQUIRE_EQUAL( false, get_rex_order_obj( alice ).is_null() ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_unit ) ); + BOOST_REQUIRE_EQUAL( sellrex( alice, rex_unit ), wasm_assert_msg("insufficient funds for current and scheduled orders") ); + BOOST_REQUIRE_EQUAL( ratio * payment.get_amount() - rex_unit.get_amount(), get_rex_order( alice )["rex_requested"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( success(), consolidate( alice ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["rex_maturities"].get_array().size() ); + + produce_block( fc::days(26) ); + produce_blocks(2); + + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 2 ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["matured_rex"].as() ); + const asset init_fund = get_rex_fund( alice ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["matured_rex"].as() ); + BOOST_REQUIRE ( init_fund < get_rex_fund( alice ) ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; @@ -3730,7 +3790,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { // alices's order is still open // an action is needed to trigger queue processing produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are not currently available"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); { auto trace = base_tester::push_action( N(eosio), N(buyrex), frank, @@ -4298,7 +4358,7 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are not currently available"), + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); } FC_LOG_AND_RETHROW() From 50b235c6a327e05e21699b2e837b81db26bd6d7b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 22 Jan 2019 15:21:59 -0500 Subject: [PATCH 0678/1048] Fix bug in updating REX vote stake --- .../include/eosio.system/eosio.system.hpp | 33 ++++++++ .../eosio.system/src/delegate_bandwidth.cpp | 13 ++-- contracts/eosio.system/src/rex.cpp | 34 ++++++++- contracts/eosio.system/src/voting.cpp | 3 +- tests/eosio.system_tests.cpp | 76 ++++++++++++++++++- 5 files changed, 145 insertions(+), 14 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index cd2dab44..d25af39f 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -567,6 +567,7 @@ namespace eosiosystem { void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ); + void update_rex_stake( const name& voter ); // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, @@ -582,6 +583,38 @@ namespace eosiosystem { double shares_rate, bool reset_to_zero = false ); double update_total_votepay_share( time_point ct, double additional_shares_delta = 0.0, double shares_rate_delta = 0.0 ); + + template + class registration { + public: + template + struct for_each { + template + static constexpr void call( system_contract* this_contract, Args&&... args ) + { + std::invoke( P, this_contract, std::forward(args)... ); + for_each::call( this_contract, std::forward(args)... ); + } + }; + template + struct for_each

{ + template + static constexpr void call( system_contract* this_contract, Args&&... args ) + { + std::invoke( P, this_contract, std::forward(args)... ); + } + }; + + template + constexpr void operator() ( Args&&... args ) + { + for_each::call( this_contract, std::forward(args)... ); + } + + system_contract* this_contract; + }; + + registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; }; } /// eosiosystem diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 1b574da3..14c7bd64 100755 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -5,7 +5,6 @@ #include #include -#include #include #include #include @@ -22,7 +21,6 @@ namespace eosiosystem { using eosio::asset; using eosio::indexed_by; using eosio::const_mem_fun; - using eosio::print; using eosio::permission_level; using eosio::time_point_sec; using std::map; @@ -233,8 +231,8 @@ namespace eosiosystem { require_auth( from ); check( stake_net_delta.amount != 0 || stake_cpu_delta.amount != 0, "should stake non-zero amount" ); check( std::abs( (stake_net_delta + stake_cpu_delta).amount ) - >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), - "net and cpu deltas cannot be opposite signs" ); + >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), + "net and cpu deltas cannot be opposite signs" ); name source_stake_from = from; if ( transfer ) { @@ -385,6 +383,7 @@ namespace eosiosystem { } } + vote_stake_updater( from ); update_voting_power( from, stake_net_delta + stake_cpu_delta ); } @@ -402,7 +401,7 @@ namespace eosiosystem { }); } - check( 0 <= voter_itr->staked, "stake for voting cannot be negative"); + check( 0 <= voter_itr->staked, "stake for voting cannot be negative" ); if( voter == "b1"_n ) { validate_b1_vesting( voter_itr->staked ); @@ -434,7 +433,7 @@ namespace eosiosystem { check( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); check( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); check( _gstate.total_activated_stake >= min_activated_stake, - "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); + "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); } // undelegatebw @@ -447,7 +446,7 @@ namespace eosiosystem { auto req = refunds_tbl.find( owner.value ); check( req != refunds_tbl.end(), "refund request not found" ); check( req->request_time + seconds(refund_delay_sec) <= current_time_point(), - "refund is not available yet" ); + "refund is not available yet" ); INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { {stake_account, active_permission}, {req->owner, active_permission} }, diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 44341b5e..c16592ae 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -4,6 +4,8 @@ #include +#include + namespace eosiosystem { /** @@ -23,6 +25,7 @@ namespace eosiosystem { transfer_to_fund( owner, amount ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } + /** * @brief Withdraws SYS tokens from user REX fund * @@ -623,13 +626,13 @@ namespace eosiosystem { const int64_t S1 = (uint128_t(R1) * S0) / R0; asset proceeds( S0 - S1, core_symbol() ); asset stake_change( 0, core_symbol() ); - bool success = false; + bool success = false; const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible - if ( proceeds.amount <= available_unlent ) { + if ( proceeds.amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; - const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; + const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; _rexpool.modify( rexitr, same_payer, [&]( auto& rt ) { rt.total_rex.amount = R1; rt.total_lendable.amount = S1; @@ -949,4 +952,29 @@ namespace eosiosystem { return current_rex_stake - init_rex_stake; } + void system_contract::update_rex_stake( const name& voter ) + { + int64_t delta_stake = 0; + auto bitr = _rexbalance.find( voter.value ); + if ( bitr != _rexbalance.end() && rex_available() ) { + asset init_vote_stake = bitr->vote_stake; + asset current_vote_stake( 0, core_symbol() ); + current_vote_stake.amount = ( uint128_t(bitr->rex_balance.amount) * _rexpool.begin()->total_lendable.amount ) + / _rexpool.begin()->total_rex.amount; + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + rb.vote_stake.amount = current_vote_stake.amount; + }); + delta_stake = current_vote_stake.amount - init_vote_stake.amount; + } + + if ( delta_stake != 0 ) { + auto vitr = _voters.find( voter.value ); + if ( vitr != _voters.end() ) { + _voters.modify( vitr, same_payer, [&]( auto& vinfo ) { + vinfo.staked += delta_stake; + }); + } + } + } + }; /// namespace eosiosystem diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index a84c9f5a..3d9016be 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include #include @@ -21,7 +20,6 @@ namespace eosiosystem { using eosio::indexed_by; using eosio::const_mem_fun; - using eosio::print; using eosio::singleton; using eosio::transaction; @@ -194,6 +192,7 @@ namespace eosiosystem { */ void system_contract::voteproducer( const name voter_name, const name proxy, const std::vector& producers ) { require_auth( voter_name ); + vote_stake_updater( voter_name ); update_votes( voter_name, proxy, producers, true ); auto rex_itr = _rexbalance.find( voter_name.value ); if( rex_itr != _rexbalance.end() && rex_itr->rex_balance.amount > 0 ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 2853613f..9824f1a6 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3729,9 +3729,10 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); BOOST_REQUIRE_EQUAL( success(), buyrex( carol, purchase3) ); - + BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_rex_fund(alice) ); BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); + BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_rex_fund(bob) ); BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_rex_fund(carol) ); @@ -3828,7 +3829,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto output = get_rexorder_result( trace ); BOOST_REQUIRE_EQUAL( output.size(), 0 ); } - + } FC_LOG_AND_RETHROW() @@ -4234,6 +4235,77 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { + + cross_15_percent_threshold(); + + // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers + std::vector producer_names; + { + producer_names.reserve('z' - 'a' + 1); + const std::string root("defproducer"); + for ( char c = 'a'; c <= 'z'; ++c ) { + producer_names.emplace_back(root + std::string(1, c)); + } + + setup_producer_accounts(producer_names); + for ( const auto& p: producer_names ) { + BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); + BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); + } + } + + const asset init_balance = core_sym::from_string("10000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + setup_rex_accounts( accounts, init_balance ); + + const int64_t init_stake_amount = get_voter_info( alice )["staked"].as(); + const asset init_stake( init_stake_amount, symbol{CORE_SYM} ); + + const asset purchase = core_sym::from_string("250.0000"); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("250.0000") ) ); + BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); + BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); + BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); + + BOOST_REQUIRE_EQUAL( success(), + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); + BOOST_REQUIRE_EQUAL( purchase.get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); + + const auto init_rex_pool = get_rex_pool(); + const asset rent = core_sym::from_string("25.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, rent ) ); + const auto curr_rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( curr_rex_pool["total_lendable"].as(), init_rex_pool["total_lendable"].as() + rent ); + BOOST_REQUIRE_EQUAL( success(), + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + BOOST_REQUIRE_EQUAL( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); + BOOST_REQUIRE_EQUAL( purchase + rent, get_rex_vote_stake(alice) ); + BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == + get_producer_info(producer_names[0])["total_votes"].as_double() ); + BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == + get_producer_info(producer_names[20])["total_votes"].as_double() ); + + const asset to_net_stake = core_sym::from_string("60.0000"); + const asset to_cpu_stake = core_sym::from_string("40.0000"); + transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, rent ) ); + BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); + BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); + BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == + get_producer_info(producer_names[0])["total_votes"].as_double() ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, rent ) ); + BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); + BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); + BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + rent) == + get_producer_info(producer_names[0])["total_votes"].as_double() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { const asset init_balance = core_sym::from_string("1000.0000"); From fa5936faf49a5b2a000981b111e08529cf556c69 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 22 Jan 2019 17:52:33 -0500 Subject: [PATCH 0679/1048] fix bug found from @zorba80's review --- contracts/eosio.system/src/rex.cpp | 62 +++++++++++++++--------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index ba98a09c..f756f356 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -182,7 +182,7 @@ namespace eosiosystem { int64_t rented_tokens = rent_rex( cpu_loans, from, receiver, loan_payment, loan_fund ); update_resource_limits( from, receiver, 0, rented_tokens ); } - + /** * Rents as many SYS tokens as determined by market price and stakes them for NET bandwidth * for the benefit of receiver account. After 30 days the rented SYS delegation of NET will @@ -241,12 +241,12 @@ namespace eosiosystem { * * @param from - loan creator * @param loan_num - loan id - * @param amount - tokens to be withdrawn from loan fund + * @param amount - tokens to be withdrawn from loan fund */ void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) { require_auth( from ); - + rex_cpu_loan_table cpu_loans( _self, _self.value ); defund_rex_loan( cpu_loans, from, loan_num, amount ); } @@ -269,7 +269,7 @@ namespace eosiosystem { /** * @brief Updates REX owner vote weight to current value of held REX tokens * - * @param owner - owner of REX tokens + * @param owner - owner of REX tokens */ void system_contract::updaterex( const name& owner ) { @@ -284,7 +284,7 @@ namespace eosiosystem { const int64_t total_rex = rexp_itr->total_rex.amount; const int64_t total_lendable = rexp_itr->total_lendable.amount; const int64_t rex_balance = itr->rex_balance.amount; - + asset current_stake( 0, core_symbol() ); if ( total_rex > 0 ) { current_stake.amount = ( uint128_t(rex_balance) * total_lendable ) / total_rex; @@ -307,7 +307,7 @@ namespace eosiosystem { void system_contract::rexexec( const name& user, uint16_t max ) { require_auth( user ); - + runrex( max ); } @@ -320,9 +320,9 @@ namespace eosiosystem { void system_contract::consolidate( const name& owner ) { require_auth( owner ); - + runrex(2); - + auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); consolidate_rex_balance( bitr, rex_in_sell_order ); @@ -336,12 +336,12 @@ namespace eosiosystem { void system_contract::closerex( const name& owner ) { require_auth( owner ); - + if ( rex_system_initialized() ) runrex(2); - + update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - + /// check for any outstanding loans or rex fund { rex_cpu_loan_table cpu_loans( _self, _self.value ); @@ -354,7 +354,7 @@ namespace eosiosystem { auto fund_itr = _rexfunds.find( owner.value ); bool no_outstanding_rex_fund = ( fund_itr != _rexfunds.end() ) && ( fund_itr->balance.amount == 0 ); - + if ( no_outstanding_cpu_loans && no_outstanding_net_loans && no_outstanding_rex_fund ) { _rexfunds.erase( fund_itr ); } @@ -428,10 +428,6 @@ namespace eosiosystem { check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); - if ( tot_itr->is_empty() ) { - totals_tbl.erase( tot_itr ); - } - { bool net_managed = false; bool cpu_managed = false; @@ -452,6 +448,10 @@ namespace eosiosystem { cpu_managed ? cpu : tot_itr->cpu_weight.amount ); } } + + if ( tot_itr->is_empty() ) { + totals_tbl.erase( tot_itr ); + } } void system_contract::check_voting_requirement( const name& owner, const char* error_msg )const @@ -504,7 +504,7 @@ namespace eosiosystem { transfer_to_fund( itr->from, itr->balance ); } } - + return { delete_loan, delta_stake }; }; @@ -521,9 +521,9 @@ namespace eosiosystem { rex_cpu_loan_table cpu_loans( _self, _self.value ); auto cpu_idx = cpu_loans.get_index<"byexpr"_n>(); for ( uint16_t i = 0; i < max; ++i ) { - auto itr = cpu_idx.begin(); + auto itr = cpu_idx.begin(); if ( itr == cpu_idx.end() || itr->expiration > current_time_point() ) break; - + auto result = process_expired_loan( cpu_idx, itr ); if ( result.second != 0 ) update_resource_limits( itr->from, itr->receiver, 0, result.second ); @@ -715,7 +715,7 @@ namespace eosiosystem { _rexfunds.emplace( owner, [&]( auto& fund ) { fund.owner = owner; fund.balance = amount; - }); + }); } else { _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { fund.balance.amount += amount.amount; @@ -734,9 +734,9 @@ namespace eosiosystem { * @param owner - owner account name * @param proceeds - additional proceeds to be transfered to owner REX fund * @param delta_stake - additional stake to be added to owner vote weight - * @param force_vote_update - if true, vote weight is updated even if vote stake didn't change + * @param force_vote_update - if true, vote weight is updated even if vote stake didn't change * - * @return asset - REX amount of owner unfilled sell order if one exists + * @return asset - REX amount of owner unfilled sell order if one exists */ asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake, bool force_vote_update ) { @@ -765,7 +765,7 @@ namespace eosiosystem { /** * @brief Channels system fees to REX pool * - * @param from - account from which asset is transfered to REX pool + * @param from - account from which asset is transfered to REX pool * @param amount - amount of tokens to be transfered */ void system_contract::channel_to_rex( const name& from, const asset& amount ) @@ -834,10 +834,10 @@ namespace eosiosystem { * @brief Consolidates REX maturity buckets into one * * @param bitr - iterator pointing to rex_balance object - * @param rex_in_sell_order - REX tokens in owner unfilled sell order, if one exists + * @param rex_in_sell_order - REX tokens in owner unfilled sell order, if one exists */ void system_contract::consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, - const asset& rex_in_sell_order ) + const asset& rex_in_sell_order ) { _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { int64_t total = rb.matured_rex - rex_in_sell_order.amount; @@ -860,12 +860,12 @@ namespace eosiosystem { asset system_contract::add_to_rex_pool( const asset& payment ) { /** - * If CORE_SYMBOL is (EOS,4), maximum supply is 10^10 tokens (10 billion tokens), i.e., maximum amount + * If CORE_SYMBOL is (EOS,4), maximum supply is 10^10 tokens (10 billion tokens), i.e., maximum amount * of indivisible units is 10^14. rex_ratio = 10^4 sets the upper bound on (REX,4) indivisible units to - * 10^18 and that is within the maximum allowable amount field of asset type which is set to 2^62 + * 10^18 and that is within the maximum allowable amount field of asset type which is set to 2^62 * (approximately 4.6 * 10^18). For a different CORE_SYMBOL, and in order for maximum (REX,4) amount not * to exceed that limit, maximum amount of indivisible units cannot be set to a value larger than 4 * 10^14. - * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. + * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. */ const int64_t rex_ratio = 10000; const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() is made available @@ -910,7 +910,7 @@ namespace eosiosystem { check( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); }); } - + return rex_received; } @@ -919,7 +919,7 @@ namespace eosiosystem { * * @param owner - account name of REX owner * @param payment - amount core tokens paid to buy REX - * @param rex_received - amount of purchased REX tokens + * @param rex_received - amount of purchased REX tokens * * @return asset - change in owner REX vote stake */ @@ -939,7 +939,7 @@ namespace eosiosystem { init_rex_stake.amount = bitr->vote_stake.amount; _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { rb.rex_balance.amount += rex_received.amount; - rb.vote_stake.amount = ( uint128_t(rb.rex_balance.amount) * _rexpool.begin()->total_lendable.amount ) + rb.vote_stake.amount = ( uint128_t(rb.rex_balance.amount) * _rexpool.begin()->total_lendable.amount ) / _rexpool.begin()->total_rex.amount; }); current_rex_stake.amount = bitr->vote_stake.amount; From ca6e0e063d7baec422f7cb82dcb7f0eb4ed101ad Mon Sep 17 00:00:00 2001 From: wuyahuang Date: Fri, 25 Jan 2019 17:38:34 +0800 Subject: [PATCH 0680/1048] fix update_votes --- eosio.system/src/voting.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/eosio.system/src/voting.cpp b/eosio.system/src/voting.cpp index 2ad09981..c7f53872 100644 --- a/eosio.system/src/voting.cpp +++ b/eosio.system/src/voting.cpp @@ -275,7 +275,8 @@ namespace eosiosystem { for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first.value ); if( pitr != _producers.end() ) { - eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, "producer is not currently registered" ); + eosio_assert( !voting || pitr->active() || !pd.second.second /* not from new set */, + ( "producer " + pitr->owner.to_string() + " is not currently registered" ).data() ); double init_total_votes = pitr->total_votes; _producers.modify( pitr, same_payer, [&]( auto& p ) { p.total_votes += pd.second.first; From 7a6b11477a693636e9ee3f09d6d055a68a539e2c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 25 Jan 2019 15:35:20 -0500 Subject: [PATCH 0681/1048] REX rounding errors --- contracts/eosio.system/src/rex.cpp | 7 ++-- tests/eosio.system_tests.cpp | 53 +++++++++++++++++++++++------- 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 71012c52..72782e80 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -637,12 +637,15 @@ namespace eosiosystem { auto rexitr = _rexpool.begin(); const int64_t S0 = rexitr->total_lendable.amount; const int64_t R0 = rexitr->total_rex.amount; + const int64_t p = (uint128_t(rex.amount) * S0) / R0; const int64_t R1 = R0 - rex.amount; - const int64_t S1 = (uint128_t(R1) * S0) / R0; - asset proceeds( S0 - S1, core_symbol() ); + const int64_t S1 = S0 - p; + asset proceeds( p, core_symbol() ); asset stake_change( 0, core_symbol() ); bool success = false; + check( proceeds.amount > 0, "proceeds are negligible" ); + const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible if ( proceeds.amount <= available_unlent ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index bb41ef11..d7b2a0d2 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3437,12 +3437,11 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { auto init_total_rex = rex_pool["total_rex"].as().get_amount(); auto init_total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset::from_string("550000.6800 REX") ) ); - BOOST_REQUIRE_EQUAL( asset::from_string("199999.3200 REX"), get_rex_balance(bob) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset::from_string("550001.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( asset::from_string("199999.0000 REX"), get_rex_balance(bob) ); rex_pool = get_rex_pool(); auto total_rex = rex_pool["total_rex"].as().get_amount(); auto total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( init_total_rex / init_total_lendable, total_rex / total_lendable ); BOOST_REQUIRE_EQUAL( total_lendable, rex_pool["total_unlent"].as().get_amount() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); @@ -3452,6 +3451,38 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( buy_sell_small_rex, eosio_system_tester ) try { + + const int64_t ratio = 10000; + const asset init_rent = core_sym::from_string("100000.0000"); + const asset init_balance = core_sym::from_string("1000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; + setup_rex_accounts( accounts, init_balance ); + + const asset payment = core_sym::from_string("10.0000"); + BOOST_REQUIRE_EQUAL( ratio * payment.get_amount(), get_buyrex_result( alice, payment ).get_amount() ); + + produce_blocks(2); + produce_block( fc::days(5) ); + produce_blocks(2); + + asset init_rex_stake = get_rex_vote_stake( alice ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.0001 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.9999 REX") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0001"), get_sellrex_result( alice, asset::from_string("1.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0001"), get_sellrex_result( alice, asset::from_string("1.9999 REX") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0002"), get_sellrex_result( alice, asset::from_string("2.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0002"), get_sellrex_result( alice, asset::from_string("2.9999 REX") ) ); + BOOST_REQUIRE_EQUAL( get_rex_vote_stake( alice ), init_rex_stake - core_sym::from_string("0.0006") ); + + BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, bob, core_sym::from_string("10.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("0.9000 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.4000 REX") ) ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { const int64_t ratio = 10000; @@ -3690,14 +3721,14 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { produce_block( fc::days(5) ); produce_blocks(2); - const asset rex_unit = asset::from_string("0.0001 REX"); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) - rex_unit ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_order_obj( alice ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_unit ) ); - BOOST_REQUIRE_EQUAL( sellrex( alice, rex_unit ), wasm_assert_msg("insufficient funds for current and scheduled orders") ); - BOOST_REQUIRE_EQUAL( ratio * payment.get_amount() - rex_unit.get_amount(), get_rex_order( alice )["rex_requested"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), consolidate( alice ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["rex_maturities"].get_array().size() ); + const asset rex_tok = asset::from_string("1.0000 REX"); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) - rex_tok ) ); + BOOST_REQUIRE_EQUAL( false, get_rex_order_obj( alice ).is_null() ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_tok ) ); + BOOST_REQUIRE_EQUAL( sellrex( alice, rex_tok ), wasm_assert_msg("insufficient funds for current and scheduled orders") ); + BOOST_REQUIRE_EQUAL( ratio * payment.get_amount() - rex_tok.get_amount(), get_rex_order( alice )["rex_requested"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( success(), consolidate( alice ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["rex_maturities"].get_array().size() ); produce_block( fc::days(26) ); produce_blocks(2); From e0676472fac96bf0010d20a4fb61988d25930b0c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 29 Jan 2019 16:09:17 -0500 Subject: [PATCH 0682/1048] Add comment --- contracts/eosio.system/src/rex.cpp | 5 +++++ tests/eosio.system_tests.cpp | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 72782e80..ff23b256 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -970,6 +970,11 @@ namespace eosiosystem { return current_rex_stake - init_rex_stake; } + /** + * @brief Updates voter REX vote stake to the current value of REX tokens held + * + * @param voter - account name of voter + */ void system_contract::update_rex_stake( const name& voter ) { int64_t delta_stake = 0; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d7b2a0d2..6276b2d2 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3402,7 +3402,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( asset::from_string("25000.0000 REX"), get_buyrex_result( alice, core_sym::from_string("2.5000") ) ); produce_blocks(2); produce_block(fc::days(5)); - BOOST_REQUIRE_EQUAL( core_sym::from_string("2.5000"), get_sellrex_result( alice, asset::from_string("25000.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("2.5000"), get_sellrex_result( alice, asset::from_string("25000.0000 REX") ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("13.0000") ) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("13.0000"), get_rex_vote_stake( alice ) ); From a4fd33e6e2dea204c9e05729253a580387a7d214 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 30 Jan 2019 18:52:11 -0500 Subject: [PATCH 0683/1048] Change initial REX connector balance, unlent REX pool lower bound --- contracts/eosio.system/src/rex.cpp | 4 ++-- tests/eosio.system_tests.cpp | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index ff23b256..b1450eeb 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -646,7 +646,7 @@ namespace eosiosystem { check( proceeds.amount > 0, "proceeds are negligible" ); - const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; + const int64_t unlent_lower_bound = rexitr->total_lent.amount; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible if ( proceeds.amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; @@ -884,7 +884,7 @@ namespace eosiosystem { * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. */ const int64_t rex_ratio = 10000; - const int64_t init_total_rent = 100'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() is made available + const int64_t init_total_rent = 20'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() is made available asset rex_received( 0, rex_symbol ); auto itr = _rexpool.begin(); if ( !rex_system_initialized() ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 6276b2d2..21a54eb4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3393,7 +3393,7 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("100000.0000"); + const asset init_rent = core_sym::from_string("20000.0000"); const asset init_balance = core_sym::from_string("1000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; @@ -3754,7 +3754,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - const auto purchase1 = core_sym::from_string("880000.0000"); + const auto purchase1 = core_sym::from_string("100000.0000"); const auto purchase2 = core_sym::from_string("471000.0000"); const auto purchase3 = core_sym::from_string("469000.0000"); const auto init_stake = get_voter_info(alice)["staked"].as(); @@ -3772,7 +3772,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); - BOOST_REQUIRE_EQUAL(core_sym::from_string("100000.0000"), get_rex_pool()["total_rent"].as() ); + BOOST_REQUIRE_EQUAL(core_sym::from_string("20000.0000"), get_rex_pool()["total_rent"].as() ); const asset rent_payment = core_sym::from_string("1100000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); @@ -4388,11 +4388,11 @@ BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { const int64_t tot_lent = rex_pool["total_lent"].as().get_amount(); const int64_t tot_lendable = rex_pool["total_lendable"].as().get_amount(); double rex_per_eos = double(tot_rex) / double(tot_lendable); - int64_t sell_amount = rex_per_eos * ( tot_unlent - 1.9 * tot_lent / 10. ); + int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.99 * tot_lent ); produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - sell_amount = rex_per_eos * ( tot_unlent - 2. * tot_lent / 10. ); + sell_amount = rex_per_eos * ( tot_unlent - tot_lent ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("no sellrex order is scheduled"), cancelrexorder( alice ) ); From c99ac02de1f847bb9a7af102dbca831c09d7f24f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 30 Jan 2019 19:06:31 -0500 Subject: [PATCH 0684/1048] Small change --- contracts/eosio.system/src/rex.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index b1450eeb..0e952057 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -4,7 +4,6 @@ #include -#include namespace eosiosystem { From a3b6ce3c6bc271f740f37c984f4456adb6f21969 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 31 Jan 2019 11:17:36 -0500 Subject: [PATCH 0685/1048] Small comment changes --- contracts/eosio.system/src/rex.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 0e952057..d0bb014c 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -4,11 +4,10 @@ #include - namespace eosiosystem { /** - * @brief Deposits SYS tokens to user REX fund + * @brief Deposits core tokens to user REX fund * * @param owner - REX fund owner * @param amount - amount of tokens to be deposited @@ -26,7 +25,7 @@ namespace eosiosystem { } /** - * @brief Withdraws SYS tokens from user REX fund + * @brief Withdraws core tokens from user REX fund * * @param owner - REX fund owner * @param amount - amount of tokens to be withdrawn @@ -44,10 +43,10 @@ namespace eosiosystem { } /** - * @brief Buys REX in exchange for SYS tokens taken out of user REX fund + * @brief Buys REX in exchange for core tokens taken out of user REX fund * * @param from - owner account name - * @param amount - amount of SYS tokens to be used for purchase + * @param amount - amount of core tokens to be used for purchase */ void system_contract::buyrex( const name& from, const asset& amount ) { @@ -66,7 +65,7 @@ namespace eosiosystem { } /** - * @brief Buys REX using staked SYS tokens + * @brief Buys REX using staked core tokens * * @param owner - owner of staked tokens account name * @param receiver - account name that tokens have previously been staked to @@ -110,7 +109,7 @@ namespace eosiosystem { } /** - * @brief Sells REX in exchange for SYS tokens + * @brief Sells REX in exchange for core tokens * * @param from - owner of REX tokens * @param rex - amount of REX tokens to be sold @@ -173,8 +172,8 @@ namespace eosiosystem { } /** - * Rents as many SYS tokens as determined by market price and stakes them for CPU bandwidth - * for the benefit of receiver account. After 30 days the rented SYS delegation of CPU will + * Rents as many core tokens as determined by market price and stakes them for CPU bandwidth + * for the benefit of receiver account. After 30 days the rented core delegation of CPU will * expire or be renewed at new market price depending on available loan fund. * * @brief Rents CPU resources for 30 days in exchange for market-determined price @@ -194,8 +193,8 @@ namespace eosiosystem { } /** - * Rents as many SYS tokens as determined by market price and stakes them for NET bandwidth - * for the benefit of receiver account. After 30 days the rented SYS delegation of NET will + * Rents as many core tokens as determined by market price and stakes them for NET bandwidth + * for the benefit of receiver account. After 30 days the rented core delegation of NET will * expire or be renewed at new market price depending on available loan fund. * * @brief Rents NET resources for 30 days in exchange for market-determined price From 8dc8e1c8c42e2375825d8fe5ac74a7bdcefcf7d8 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 31 Jan 2019 17:27:55 -0500 Subject: [PATCH 0686/1048] fix setabi_bios test The tester instance should be configured to not push its bios contract at startup since the unit test is going to push its own bios contract. Previously, if both bios contracts happened to be identical, the test would fail due to a duplicate transaction. --- tests/eosio.system_tests.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 4740cebc..c5ecd27b 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4321,29 +4321,30 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( setabi_bios, TESTER ) try { - abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::system_abi().data()).template as(), abi_serializer_max_time); - set_code( config::system_account_name, contracts::bios_wasm() ); - set_abi( config::system_account_name, contracts::bios_abi().data() ); - create_account(N(eosio.token)); - set_abi( N(eosio.token), contracts::token_abi().data() ); +BOOST_AUTO_TEST_CASE( setabi_bios ) try { + validating_tester t( validating_tester::default_config() ); + abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); + t.set_code( config::system_account_name, contracts::bios_wasm() ); + t.set_abi( config::system_account_name, contracts::bios_abi().data() ); + t.create_account(N(eosio.token)); + t.set_abi( N(eosio.token), contracts::token_abi().data() ); { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, base_tester::abi_serializer_max_time ); + abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), base_tester::abi_serializer_max_time); auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); BOOST_REQUIRE( abi_hash.hash == result ); } - set_abi( N(eosio.token), contracts::system_abi().data() ); + t.set_abi( N(eosio.token), contracts::system_abi().data() ); { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); + auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, base_tester::abi_serializer_max_time ); + abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), base_tester::abi_serializer_max_time); auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); From 5a2e3b0e4f81934034e4c18c6fee82b281b85db4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 4 Feb 2019 19:52:59 -0500 Subject: [PATCH 0687/1048] Create REX savings --- .../include/eosio.system/eosio.system.hpp | 14 +++ contracts/eosio.system/src/rex.cpp | 102 +++++++++++++++++- 2 files changed, 114 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 066aeeb6..fee8021e 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -467,6 +467,18 @@ namespace eosiosystem { [[eosio::action]] void consolidate( const name& owner ); + /** + * + */ + [[eosio::action]] + void mvtosavings( const name& owner, const asset& rex ); + + /** + * + */ + [[eosio::action]] + void mvfrsavings( const name& owner, const asset& rex ); + /** * Deletes owner records from REX tables and frees used RAM. * Owner must not have an outstanding REX balance. @@ -604,6 +616,8 @@ namespace eosiosystem { void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ); + int64_t read_rex_savings( const rex_balance_table::const_iterator& bitr ); + void put_rex_savings( const rex_balance_table::const_iterator& bitr, int64_t rex ); void update_rex_stake( const name& voter ); // defined in delegate_bandwidth.cpp diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index d0bb014c..c5a38707 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -337,6 +337,69 @@ namespace eosiosystem { consolidate_rex_balance( bitr, rex_in_sell_order ); } + /** + * + */ + void system_contract::mvtosavings( const name& owner, const asset& rex ) + { + require_auth( owner ); + + runrex(2); + auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); + check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); + asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); + check( rex + rex_in_sell_order <= bitr->rex_balance, "insufficient REX balance" ); + process_rex_maturities( bitr ); + int64_t rex_in_savings = read_rex_savings( bitr ); + int64_t moved_rex = 0; + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + int64_t moved_rex = 0; + while ( moved_rex < rex.amount ) { + if ( !rb.rex_maturities.empty() ) { + int64_t drex = std::min( rex.amount - moved_rex, rb.rex_maturities.back().second ); + rb.rex_maturities.back().second -= drex; + moved_rex += drex; + if ( rb.rex_maturities.back().second == 0 ) { + rb.rex_maturities.pop_back(); + } + } else { + int64_t drex = rex.amount - moved_rex; + rb.matured_rex -= drex; + moved_rex += drex; + check( rex_in_sell_order.amount <= rb.matured_rex, " " ); + } + } + }); + put_rex_savings( bitr, rex_in_savings + moved_rex ); + } + + /** + * + */ + void system_contract::mvfrsavings( const name& owner, const asset& rex ) + { + require_auth( owner ); + + runrex(2); + auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); + check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); + const static time_point_sec end_of_days{ std::numeric_limits::max() }; + const auto& maturities = bitr->rex_maturities; + check( !maturities.empty() && maturities.back().first == end_of_days && rex.amount < maturities.back().second, + "insufficient REX in savings" ); + const int64_t rex_in_savings = read_rex_savings( bitr ); + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + rb.rex_maturities.pop_back(); + const time_point_sec maturity = get_rex_maturity(); + if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { + rb.rex_maturities.back().second += rex.amount; + } else { + rb.rex_maturities.emplace_back( maturity, rex.amount ); + } + }); + put_rex_savings( bitr, rex_in_savings - rex.amount ); + } + /** * @brief Deletes unused REX-related database entries and frees RAM * @@ -821,7 +884,7 @@ namespace eosiosystem { { const uint32_t num_of_maturity_buckets = 5; static const uint32_t now = current_time_point_sec().utc_seconds; - static const uint32_t r = now % seconds_per_day; + static const uint32_t r = now % seconds_per_day; static const time_point_sec rms{ now - r + num_of_maturity_buckets * seconds_per_day }; return rms; } @@ -851,6 +914,7 @@ namespace eosiosystem { void system_contract::consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ) { + const int64_t rex_in_savings = read_rex_savings( bitr ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { int64_t total = rb.matured_rex - rex_in_sell_order.amount; rb.matured_rex = rex_in_sell_order.amount; @@ -862,6 +926,7 @@ namespace eosiosystem { rb.rex_maturities.emplace_back( get_rex_maturity(), total ); } }); + put_rex_savings( bitr, rex_in_savings ); } /** @@ -956,6 +1021,7 @@ namespace eosiosystem { } process_rex_maturities( bitr ); + const int64_t rex_in_savings = read_rex_savings( bitr ); const time_point_sec maturity = get_rex_maturity(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { @@ -964,10 +1030,42 @@ namespace eosiosystem { rb.rex_maturities.emplace_back( maturity, rex_received.amount ); } }); - + put_rex_savings( bitr, rex_in_savings ); return current_rex_stake - init_rex_stake; } + /** + * + */ + int64_t system_contract::read_rex_savings( const rex_balance_table::const_iterator& bitr ) + { + int64_t rex_in_savings = 0; + static const time_point_sec end_of_days{ std::numeric_limits::max() }; + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == end_of_days ) { + rex_in_savings = rb.rex_maturities.back().second; + rb.rex_maturities.pop_back(); + } + }); + return rex_in_savings; + } + + /** + * + */ + void system_contract::put_rex_savings( const rex_balance_table::const_iterator& bitr, int64_t rex ) + { + if ( rex == 0 ) return; + static const time_point_sec end_of_days{ std::numeric_limits::max() }; + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == end_of_days ) { + rb.rex_maturities.back().second += rex; + } else { + rb.rex_maturities.emplace_back( end_of_days, rex ); + } + }); + } + /** * @brief Updates voter REX vote stake to the current value of REX tokens held * From c8010b3f56b9c6bd707e5b1dd678a2267441008d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 4 Feb 2019 22:27:46 -0500 Subject: [PATCH 0688/1048] Create REX savings - 2 --- contracts/eosio.system/src/rex.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index c5a38707..16bcb3a2 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -345,13 +345,13 @@ namespace eosiosystem { require_auth( owner ); runrex(2); + auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); check( rex + rex_in_sell_order <= bitr->rex_balance, "insufficient REX balance" ); process_rex_maturities( bitr ); - int64_t rex_in_savings = read_rex_savings( bitr ); - int64_t moved_rex = 0; + const int64_t rex_in_savings = read_rex_savings( bitr ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { int64_t moved_rex = 0; while ( moved_rex < rex.amount ) { @@ -366,11 +366,11 @@ namespace eosiosystem { int64_t drex = rex.amount - moved_rex; rb.matured_rex -= drex; moved_rex += drex; - check( rex_in_sell_order.amount <= rb.matured_rex, " " ); + check( rex_in_sell_order.amount <= rb.matured_rex, "logic error" ); } } }); - put_rex_savings( bitr, rex_in_savings + moved_rex ); + put_rex_savings( bitr, rex_in_savings + rex.amount ); } /** @@ -381,13 +381,11 @@ namespace eosiosystem { require_auth( owner ); runrex(2); + auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); - const static time_point_sec end_of_days{ std::numeric_limits::max() }; - const auto& maturities = bitr->rex_maturities; - check( !maturities.empty() && maturities.back().first == end_of_days && rex.amount < maturities.back().second, - "insufficient REX in savings" ); const int64_t rex_in_savings = read_rex_savings( bitr ); + check( rex.amount <= rex_in_savings, "insufficient REX in savings" ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { rb.rex_maturities.pop_back(); const time_point_sec maturity = get_rex_maturity(); @@ -398,6 +396,7 @@ namespace eosiosystem { } }); put_rex_savings( bitr, rex_in_savings - rex.amount ); + update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } /** @@ -1022,8 +1021,8 @@ namespace eosiosystem { process_rex_maturities( bitr ); const int64_t rex_in_savings = read_rex_savings( bitr ); - const time_point_sec maturity = get_rex_maturity(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { + const time_point_sec maturity = get_rex_maturity(); if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { rb.rex_maturities.back().second += rex_received.amount; } else { From c40bac82d341d34218e606456229d3af8ed3ac71 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 5 Feb 2019 02:59:22 -0500 Subject: [PATCH 0689/1048] Create REX savings - testing --- contracts/eosio.system/src/eosio.system.cpp | 2 +- contracts/eosio.system/src/rex.cpp | 30 ++-- tests/eosio.system_tester.hpp | 8 + tests/eosio.system_tests.cpp | 170 ++++++++++++++++++++ 4 files changed, 193 insertions(+), 17 deletions(-) diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 608d818f..4328afc6 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -467,7 +467,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, (rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) - (defcpuloan)(defnetloan)(updaterex)(consolidate)(rexexec)(closerex) + (defcpuloan)(defnetloan)(updaterex)(consolidate)(mvtosavings)(mvfrsavings)(rexexec)(closerex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 16bcb3a2..201569ef 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -349,26 +349,25 @@ namespace eosiosystem { auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - check( rex + rex_in_sell_order <= bitr->rex_balance, "insufficient REX balance" ); - process_rex_maturities( bitr ); const int64_t rex_in_savings = read_rex_savings( bitr ); + check( rex.amount + rex_in_sell_order.amount + rex_in_savings <= bitr->rex_balance.amount, "insufficient REX balance" ); + process_rex_maturities( bitr ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { int64_t moved_rex = 0; - while ( moved_rex < rex.amount ) { - if ( !rb.rex_maturities.empty() ) { - int64_t drex = std::min( rex.amount - moved_rex, rb.rex_maturities.back().second ); - rb.rex_maturities.back().second -= drex; - moved_rex += drex; - if ( rb.rex_maturities.back().second == 0 ) { - rb.rex_maturities.pop_back(); - } - } else { - int64_t drex = rex.amount - moved_rex; - rb.matured_rex -= drex; - moved_rex += drex; - check( rex_in_sell_order.amount <= rb.matured_rex, "logic error" ); + while ( !rb.rex_maturities.empty() && moved_rex < rex.amount) { + int64_t drex = std::min( rex.amount - moved_rex, rb.rex_maturities.back().second ); + rb.rex_maturities.back().second -= drex; + moved_rex += drex; + if ( rb.rex_maturities.back().second == 0 ) { + rb.rex_maturities.pop_back(); } } + if ( moved_rex < rex.amount ) { + int64_t drex = rex.amount - moved_rex; + rb.matured_rex -= drex; + moved_rex += drex; + check( rex_in_sell_order.amount <= rb.matured_rex, "logic error" ); + } }); put_rex_savings( bitr, rex_in_savings + rex.amount ); } @@ -387,7 +386,6 @@ namespace eosiosystem { const int64_t rex_in_savings = read_rex_savings( bitr ); check( rex.amount <= rex_in_savings, "insufficient REX in savings" ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.rex_maturities.pop_back(); const time_point_sec maturity = get_rex_maturity(); if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { rb.rex_maturities.back().second += rex.amount; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 1bde1f55..cadbf7d8 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -500,6 +500,14 @@ class eosio_system_tester : public TESTER { return push_action( name(owner), N(consolidate), mvo()("owner", owner) ); } + action_result mvtosavings( const account_name& owner, const asset& rex ) { + return push_action( name(owner), N(mvtosavings), mvo()("owner", owner)("rex", rex) ); + } + + action_result mvfrsavings( const account_name& owner, const asset& rex ) { + return push_action( name(owner), N(mvfrsavings), mvo()("owner", owner)("rex", rex) ); + } + action_result closerex( const account_name& owner ) { return push_action( name(owner), N(closerex), mvo()("owner", owner) ); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 1acc15ab..8a505e56 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4192,6 +4192,176 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { + + const asset init_balance = core_sym::from_string("100000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + setup_rex_accounts( accounts, init_balance ); + + const int64_t rex_ratio = 10000; + const symbol rex_sym( SY(4, REX) ); + + { + const asset payment1 = core_sym::from_string("14.8000"); + const asset payment2 = core_sym::from_string("15.2000"); + const asset payment = payment1 + payment2; + const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); + for ( uint8_t i = 0; i < 8; ++i ) { + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); + produce_block( fc::hours(12) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment2 ) ); + produce_block( fc::hours(14) ); + } + + auto rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); + + BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( 8 * rex_bucket.get_amount(), rex_sym ) ) ); + rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + produce_block( fc::days(100) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( alice, asset::from_string( "1.0000 REX" ) ) ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, asset::from_string( "10.0000 REX" ) ) ); + rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); + produce_block( fc::days(3) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( alice, asset::from_string( "1.0000 REX" ) ) ); + produce_blocks( 2 ); + produce_block( fc::days(2) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( alice, asset::from_string( "10.0001 REX" ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string( "10.0000 REX" ) ) ); + rex_balance = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + produce_block( fc::days(100) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( alice, asset::from_string( "0.0001 REX" ) ) ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, get_rex_balance( alice ) ) ); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); + } + + { + const asset payment = core_sym::from_string("20.0000"); + const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); + for ( uint8_t i = 0; i < 5; ++i ) { + produce_block( fc::hours(24) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment ) ); + } + + auto rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 5 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 6, rex_balance["rex_maturities"].get_array().size() ); + + BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + + BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( 3 * rex_bucket.get_amount() / 2, rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( bob, rex_bucket ) ); + + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); + + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( bob, rex_bucket ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( 5 * rex_bucket.get_amount(), 2 * rex_balance["rex_balance"].as().get_amount() ); + + produce_block( fc::days(20) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( bob, rex_bucket ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX in savings"), + mvfrsavings( bob, asset( 3 * rex_bucket.get_amount(), rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, rex_bucket ) ); + BOOST_REQUIRE_EQUAL( 2, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX balance"), + mvtosavings( bob, asset( 3 * rex_bucket.get_amount() / 2, rex_sym ) ) ); + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, rex_bucket ) ); + BOOST_REQUIRE_EQUAL( 3, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); + produce_block( fc::days(4) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( bob, rex_bucket ) ); + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( rex_bucket.get_amount() / 2, rex_balance["rex_balance"].as().get_amount() ); + + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 4, rex_sym ) ) ); + produce_block( fc::days(2) ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 8, rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( 3, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); + BOOST_REQUIRE_EQUAL( 2, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); + + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), + sellrex( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 3 * rex_bucket.get_amount() / 8, rex_sym ) ) ); + rex_balance = get_rex_balance_obj( bob ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + BOOST_REQUIRE_EQUAL( rex_bucket.get_amount() / 8, rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, get_rex_balance( bob ) ) ); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); + } + + { + const asset payment = core_sym::from_string("20000.0000"); + const int64_t rex_bucket_amount = rex_ratio * payment.get_amount(); + const asset rex_bucket( rex_bucket_amount, rex_sym ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); + BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); + BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_pool()["total_rex"].as() ); + + produce_block( fc::days(5) ); + + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("2000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 9 * rex_bucket_amount / 10, rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); + BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX balance"), + mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); + BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); + auto rb = get_rex_balance_obj( alice ); + BOOST_REQUIRE_EQUAL( rb["matured_rex"].as(), 8 * rex_bucket_amount / 10 ); + } + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { const asset init_balance = core_sym::from_string("10000.0000"); From a4b880820cb7244cbe4503aee653dbed1efe1f6d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 5 Feb 2019 14:00:57 -0500 Subject: [PATCH 0690/1048] Comments, small changes --- .../include/eosio.system/eosio.system.hpp | 8 ++++-- contracts/eosio.system/src/rex.cpp | 26 ++++++++++++------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index fee8021e..5d452767 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -468,13 +468,17 @@ namespace eosiosystem { void consolidate( const name& owner ); /** - * + * Moves a specified amount of REX into savings bucket. REX savings bucket + * never matures. In order for it to be sold, it has to be moved explicitly + * out of that bucket. Then the moved amount will have the regular maturity + * period of 4 days starting from the end of the day. */ [[eosio::action]] void mvtosavings( const name& owner, const asset& rex ); /** - * + * Moves a specified amount of REX out of savings bucket. The moved amount + * will have the regular REX maturity period of 4 days. */ [[eosio::action]] void mvfrsavings( const name& owner, const asset& rex ); diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 201569ef..e3399d0b 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -338,7 +338,10 @@ namespace eosiosystem { } /** + * @brief Moves a specified amount of REX to savings bucket * + * @param owner - account name of REX owner + * @param rex - amount of REX to be moved */ void system_contract::mvtosavings( const name& owner, const asset& rex ) { @@ -348,14 +351,15 @@ namespace eosiosystem { auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); - asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - const int64_t rex_in_savings = read_rex_savings( bitr ); - check( rex.amount + rex_in_sell_order.amount + rex_in_savings <= bitr->rex_balance.amount, "insufficient REX balance" ); + const asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); + const int64_t rex_in_savings = read_rex_savings( bitr ); + check( rex.amount + rex_in_sell_order.amount + rex_in_savings <= bitr->rex_balance.amount, + "insufficient REX balance" ); process_rex_maturities( bitr ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { int64_t moved_rex = 0; while ( !rb.rex_maturities.empty() && moved_rex < rex.amount) { - int64_t drex = std::min( rex.amount - moved_rex, rb.rex_maturities.back().second ); + const int64_t drex = std::min( rex.amount - moved_rex, rb.rex_maturities.back().second ); rb.rex_maturities.back().second -= drex; moved_rex += drex; if ( rb.rex_maturities.back().second == 0 ) { @@ -363,17 +367,21 @@ namespace eosiosystem { } } if ( moved_rex < rex.amount ) { - int64_t drex = rex.amount - moved_rex; - rb.matured_rex -= drex; - moved_rex += drex; - check( rex_in_sell_order.amount <= rb.matured_rex, "logic error" ); + const int64_t drex = rex.amount - moved_rex; + rb.matured_rex -= drex; + moved_rex += drex; + check( rex_in_sell_order.amount <= rb.matured_rex, "logic error in mvtosavings" ); } + check( moved_rex == rex.amount, "programmer error in mvtosavings" ); }); put_rex_savings( bitr, rex_in_savings + rex.amount ); } /** + * @brief Moves a specified amount of REX from savings bucket * + * @param owner - account name of REX owner + * @param rex - amount of REX to be moved */ void system_contract::mvfrsavings( const name& owner, const asset& rex ) { @@ -1018,7 +1026,7 @@ namespace eosiosystem { } process_rex_maturities( bitr ); - const int64_t rex_in_savings = read_rex_savings( bitr ); + const int64_t rex_in_savings = read_rex_savings( bitr ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { const time_point_sec maturity = get_rex_maturity(); if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { From 04b43db68d36e0346687134b888fbc1de5c3cd77 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 5 Feb 2019 17:46:44 -0500 Subject: [PATCH 0691/1048] Fixed bug found by @larryk85 code review, more testing --- contracts/eosio.system/src/rex.cpp | 16 ++++++++-- tests/eosio.system_tests.cpp | 49 +++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index e3399d0b..aa8590f1 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -393,6 +393,7 @@ namespace eosiosystem { check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); const int64_t rex_in_savings = read_rex_savings( bitr ); check( rex.amount <= rex_in_savings, "insufficient REX in savings" ); + process_rex_maturities( bitr ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { const time_point_sec maturity = get_rex_maturity(); if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { @@ -1040,12 +1041,20 @@ namespace eosiosystem { } /** + * @brief Reads amount of REX in savings bucket and removes the bucket from maturities + * + * Reads and (temporarily) removes REX savings bucket from REX maturities in order to + * allow uniform processing of remaining buckets as savings is a special case. This + * function is used in conjunction with put_rex_savings. * + * @param bitr - iterator pointing to rex_balance object + * + * @return int64_t - amount of REX in savings bucket */ int64_t system_contract::read_rex_savings( const rex_balance_table::const_iterator& bitr ) { int64_t rex_in_savings = 0; - static const time_point_sec end_of_days{ std::numeric_limits::max() }; + static const time_point_sec end_of_days = time_point_sec::maximum(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == end_of_days ) { rex_in_savings = rb.rex_maturities.back().second; @@ -1056,12 +1065,15 @@ namespace eosiosystem { } /** + * @brief Adds a specified REX amount to savings bucket * + * @param bitr - iterator pointing to rex_balance object + * @param rex - amount of REX to be added */ void system_contract::put_rex_savings( const rex_balance_table::const_iterator& bitr, int64_t rex ) { if ( rex == 0 ) return; - static const time_point_sec end_of_days{ std::numeric_limits::max() }; + static const time_point_sec end_of_days = time_point_sec::maximum(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == end_of_days ) { rb.rex_maturities.back().second += rex; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 8a505e56..2404df53 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4223,7 +4223,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { rex_balance = get_rex_balance_obj( alice ); BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - produce_block( fc::days(100) ); + produce_block( fc::days(1000) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( alice, asset::from_string( "1.0000 REX" ) ) ); BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, asset::from_string( "10.0000 REX" ) ) ); @@ -4357,6 +4357,53 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); auto rb = get_rex_balance_obj( alice ); BOOST_REQUIRE_EQUAL( rb["matured_rex"].as(), 8 * rex_bucket_amount / 10 ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, asset( 2 * rex_bucket_amount / 10, rex_sym ) ) ); + produce_block( fc::days(31) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); + } + + { + const asset payment = core_sym::from_string("250.0000"); + const asset half_payment = core_sym::from_string("125.0000"); + const int64_t rex_bucket_amount = rex_ratio * payment.get_amount(); + const int64_t half_rex_bucket_amount = rex_bucket_amount / 2; + const asset rex_bucket( rex_bucket_amount, rex_sym ); + const asset half_rex_bucket( half_rex_bucket_amount, rex_sym ); + + BOOST_REQUIRE_EQUAL( success(), buyrex( carol, payment ) ); + BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( carol ) ); + auto rex_balance = get_rex_balance_obj( carol ); + + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( carol, payment ) ); + rex_balance = get_rex_balance_obj( carol ); + BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); + + BOOST_REQUIRE_EQUAL( success(), mvtosavings( carol, half_rex_bucket ) ); + rex_balance = get_rex_balance_obj( carol ); + BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); + + BOOST_REQUIRE_EQUAL( success(), buyrex( carol, half_payment ) ); + rex_balance = get_rex_balance_obj( carol ); + BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); + + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), + mvfrsavings( carol, asset::from_string("0.0000 REX") ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), + mvfrsavings( carol, asset::from_string("1.0000 RND") ) ); + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( carol, half_rex_bucket ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX in savings"), + mvfrsavings( carol, asset::from_string("0.0001 REX") ) ); + rex_balance = get_rex_balance_obj( carol ); + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 5 * half_rex_bucket_amount, rex_balance["rex_balance"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 2 * rex_bucket_amount, rex_balance["matured_rex"].as() ); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance( carol) ) ); } } FC_LOG_AND_RETHROW() From e24442d88eee7944bd385c9964d967833cccf365 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 6 Feb 2019 10:56:12 -0500 Subject: [PATCH 0692/1048] Small optimization --- contracts/eosio.system/src/rex.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index aa8590f1..70896063 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -902,7 +902,7 @@ namespace eosiosystem { */ void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) { - time_point_sec now = current_time_point_sec(); + const time_point_sec now = current_time_point_sec(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { rb.matured_rex += rb.rex_maturities.front().second; @@ -1055,12 +1055,12 @@ namespace eosiosystem { { int64_t rex_in_savings = 0; static const time_point_sec end_of_days = time_point_sec::maximum(); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == end_of_days ) { + if ( !bitr->rex_maturities.empty() && bitr->rex_maturities.back().first == end_of_days ) { + _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { rex_in_savings = rb.rex_maturities.back().second; rb.rex_maturities.pop_back(); - } - }); + }); + } return rex_in_savings; } From c9648b8feb4a52f1e7e81cd6a1d75835c8eebbb9 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 6 Feb 2019 11:32:35 -0500 Subject: [PATCH 0693/1048] Small change --- contracts/eosio.system/src/rex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 70896063..7a98b74f 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -1026,8 +1026,8 @@ namespace eosiosystem { current_rex_stake.amount = bitr->vote_stake.amount; } - process_rex_maturities( bitr ); const int64_t rex_in_savings = read_rex_savings( bitr ); + process_rex_maturities( bitr ); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { const time_point_sec maturity = get_rex_maturity(); if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { From 1ec6e8f71b4a261a0e109f923980541ac8f0db22 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 6 Feb 2019 20:40:13 -0500 Subject: [PATCH 0694/1048] added action_wrappers to headers --- .../include/eosio.bios/eosio.bios.hpp | 16 ++++++++ .../include/eosio.msig/eosio.msig.hpp | 6 +++ .../include/eosio.system/eosio.system.hpp | 41 +++++++++++++++++++ .../include/eosio.system/native.hpp | 10 +++++ .../include/eosio.token/eosio.token.hpp | 6 +++ .../include/eosio.wrap/eosio.wrap.hpp | 1 + 6 files changed, 80 insertions(+) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 06c24a01..86cc9857 100755 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -165,6 +165,22 @@ namespace eosio { }; typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; + + using newaccount_action = action_wrapper<"newaccount"_n, &bios::newaccount>; + using updateauth_action = action_wrapper<"updateauth"_n, &bios::updateauth>; + using deleteauth_action = action_wrapper<"deleteauth"_n, &bios::deleteauth>; + using unlinkauth_action = action_wrapper<"unlinkauth"_n, &bios::unlinkauth>; + using canceldelay_action = action_wrapper<"canceldelay"_n, &bios::canceldelay>; + using onerror_action = action_wrapper<"onerror"_n, &bios::onerror>; + using setcode_action = action_wrapper<"setcode"_n, &bios::setcode>; + using setpriv_action = action_wrapper<"setpriv"_n, &bios::setpriv>; + using setalimits_action = action_wrapper<"setalimits"_n, &bios::setalimits>; + using setglimits_action = action_wrapper<"setglimits"_n, &bios::setglimits>; + using setprods_action = action_wrapper<"setprods"_n, &bios::setprods>; + using setparams_action = action_wrapper<"setparams"_n, &bios::setparams>; + using reqauth_action = action_wrapper<"reqauth"_n, &bios::reqauth>; + using setabi_action = action_wrapper<"setabi"_n, &bios::setabi>; + }; } /// namespace eosio diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index a8c506e7..9589fe52 100755 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -24,6 +24,12 @@ namespace eosio { [[eosio::action]] void invalidate( name account ); + using propose_action = eosio::action_wrapper<"propose"_n, &multisig::propose>; + using approve_action = eosio::action_wrapper<"approve"_n, &multisig::approve>; + using unapprove_action = eosio::action_wrapper<"unapprove"_n, &multisig::unapprove>; + using cancel_action = eosio::action_wrapper<"cancel"_n, &multisig::cancel>; + using exec_action = eosio::action_wrapper<"exec"_n, &multisig::exec>; + using invalidate_action = eosio::action_wrapper<"invalidate"_n, &multisig::invalidate>; private: struct [[eosio::table]] proposal { name proposal_name; diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 2cd6e22f..af344f37 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -559,6 +559,47 @@ namespace eosiosystem { [[eosio::action]] void bidrefund( name bidder, name newname ); + using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; + using onblock_action = eosio::action_wrapper<"onblock"_n, &system_contract::onblock>; + using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; + using setacctnet_action = eosio::action_wrapper<"setacctnet"_n, &system_contract::setacctnet>; + using setacctcpu_action = eosio::action_wrapper<"setacctcpu"_n, &system_contract::setacctcpu>; + using delegatebw_action = eosio::action_wrapper<"delegatebw"_n, &system_contract::delegatebw>; + using deposit_action = eosio::action_wrapper<"deposit"_n, &system_contract::deposit>; + using withdraw_action = eosio::action_wrapper<"withdraw"_n, &system_contract::withdraw>; + using buyrex_action = eosio::action_wrapper<"buyrex"_n, &system_contract::buyrex>; + using unstaketorex_action = eosio::action_wrapper<"unstaketorex"_n, &system_contract::unstaketorex>; + using sellrex_action = eosio::action_wrapper<"sellrex"_n, &system_contract::sellrex>; + using cnclrexorder_action = eosio::action_wrapper<"cnclrexorder"_n, &system_contract::cnclrexorder>; + using rentcpu_action = eosio::action_wrapper<"rentcpu"_n, &system_contract::rentcpu>; + using rentnet_action = eosio::action_wrapper<"rentnet"_n, &system_contract::rentnet>; + using fundcpuloan_action = eosio::action_wrapper<"fundcpuloan"_n, &system_contract::fundcpuloan>; + using fundnetloan_action = eosio::action_wrapper<"fundnetloan"_n, &system_contract::fundnetloan>; + using defcpuloan_action = eosio::action_wrapper<"defcpuloan"_n, &system_contract::defcpuloan>; + using defnetloan_action = eosio::action_wrapper<"defnetloan"_n, &system_contract::defnetloan>; + using updaterex_action = eosio::action_wrapper<"updaterex"_n, &system_contract::updaterex>; + using rexexec_action = eosio::action_wrapper<"rexexec"_n, &system_contract::rexexec>; + using consolidate_action = eosio::action_wrapper<"consolidate"_n, &system_contract::consolidate>; + using closerex_action = eosio::action_wrapper<"closerex"_n, &system_contract::closerex>; + using undelegatebw_action = eosio::action_wrapper<"undelegatebw"_n, &system_contract::undelegatebw>; + using buyram_action = eosio::action_wrapper<"buyram"_n, &system_contract::buyram>; + using buyrambytes_action = eosio::action_wrapper<"buyrambytes"_n, &system_contract::buyrambytes>; + using sellram_action = eosio::action_wrapper<"sellram"_n, &system_contract::sellram>; + using refund_action = eosio::action_wrapper<"refund"_n, &system_contract::refund>; + using regproducer_action = eosio::action_wrapper<"regproducer"_n, &system_contract::regproducer>; + using unregprod_action = eosio::action_wrapper<"unregprod"_n, &system_contract::unregprod>; + using setram_action = eosio::action_wrapper<"setram"_n, &system_contract::setram>; + using setramrate_action = eosio::action_wrapper<"setramrate"_n, &system_contract::setramrate>; + using voteproducer_action = eosio::action_wrapper<"voteproducer"_n, &system_contract::voteproducer>; + using regproxy_action = eosio::action_wrapper<"regproxy"_n, &system_contract::regproxy>; + using claimrewards_action = eosio::action_wrapper<"claimrewards"_n, &system_contract::claimrewards>; + using rmvproducer_action = eosio::action_wrapper<"rmvproducer"_n, &system_contract::rmvproducer>; + using updtrevision_action = eosio::action_wrapper<"updtrevision"_n, &system_contract::updtrevision>; + using bidname_action = eosio::action_wrapper<"bidname"_n, &system_contract::bidname>; + using bidrefund_action = eosio::action_wrapper<"bidrefund"_n, &system_contract::bidrefund>; + using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; + using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; + private: // Implementation details: diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 6b0445f0..1ebcd8f8 100755 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -135,5 +135,15 @@ namespace eosiosystem { [[eosio::action]] void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} + + using newaccount_action = eosio::action_wrapper<"newaccount"_n, &native::newaccount>; + using updateauth_action = eosio::action_wrapper<"updateauth"_n, &native::updateauth>; + using deleteauth_action = eosio::action_wrapper<"deleteauth"_n, &native::deleteauth>; + using unlinkauth_action = eosio::action_wrapper<"unlinkauth"_n, &native::unlinkauth>; + using canceldelay_action = eosio::action_wrapper<"canceldelay"_n, &native::canceldelay>; + using onerror_action = eosio::action_wrapper<"onerror"_n, &native::onerror>; + using setcode_action = eosio::action_wrapper<"setcode"_n, &native::setcode>; + using setabi_action = eosio::action_wrapper<"setabi"_n, &native::setabi>; + }; } diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index 53130bdb..2463d121 100755 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -57,6 +57,12 @@ namespace eosio { return ac.balance; } + using create_action = eosio::action_wrapper<"create"_n, &token::create>; + using issue_action = eosio::action_wrapper<"issue"_n, &token::issue>; + using retire_action = eosio::action_wrapper<"retire"_n, &token::retire>; + using transfer_action = eosio::action_wrapper<"transfer"_n, &token::transfer>; + using open_action = eosio::action_wrapper<"open"_n, &token::open>; + using close_action = eosio::action_wrapper<"close"_n, &token::close>; private: struct [[eosio::table]] account { asset balance; diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp index a01aa363..243cb8b0 100755 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -13,6 +13,7 @@ namespace eosio { [[eosio::action]] void exec( ignore executer, ignore trx ); + using exec_action = eosio::action_wrapper<"exec"_n, &wrap::exec>; }; } /// namespace eosio From 95cdefe72092f5c4c9d9188129b2bd699ed36cbc Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Wed, 6 Feb 2019 20:57:15 -0500 Subject: [PATCH 0695/1048] remove onerror, onblock and adding linkauth --- contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp | 3 +-- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 1 - contracts/eosio.system/include/eosio.system/native.hpp | 3 +-- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 86cc9857..e3acabe7 100755 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -169,9 +169,9 @@ namespace eosio { using newaccount_action = action_wrapper<"newaccount"_n, &bios::newaccount>; using updateauth_action = action_wrapper<"updateauth"_n, &bios::updateauth>; using deleteauth_action = action_wrapper<"deleteauth"_n, &bios::deleteauth>; + using linkauth_action = action_wrapper<"linkauth"_n, &bios::linkauth>; using unlinkauth_action = action_wrapper<"unlinkauth"_n, &bios::unlinkauth>; using canceldelay_action = action_wrapper<"canceldelay"_n, &bios::canceldelay>; - using onerror_action = action_wrapper<"onerror"_n, &bios::onerror>; using setcode_action = action_wrapper<"setcode"_n, &bios::setcode>; using setpriv_action = action_wrapper<"setpriv"_n, &bios::setpriv>; using setalimits_action = action_wrapper<"setalimits"_n, &bios::setalimits>; @@ -180,7 +180,6 @@ namespace eosio { using setparams_action = action_wrapper<"setparams"_n, &bios::setparams>; using reqauth_action = action_wrapper<"reqauth"_n, &bios::reqauth>; using setabi_action = action_wrapper<"setabi"_n, &bios::setabi>; - }; } /// namespace eosio diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index af344f37..4cad63d5 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -560,7 +560,6 @@ namespace eosiosystem { void bidrefund( name bidder, name newname ); using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; - using onblock_action = eosio::action_wrapper<"onblock"_n, &system_contract::onblock>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; using setacctnet_action = eosio::action_wrapper<"setacctnet"_n, &system_contract::setacctnet>; using setacctcpu_action = eosio::action_wrapper<"setacctcpu"_n, &system_contract::setacctcpu>; diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 1ebcd8f8..868dea33 100755 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -139,11 +139,10 @@ namespace eosiosystem { using newaccount_action = eosio::action_wrapper<"newaccount"_n, &native::newaccount>; using updateauth_action = eosio::action_wrapper<"updateauth"_n, &native::updateauth>; using deleteauth_action = eosio::action_wrapper<"deleteauth"_n, &native::deleteauth>; + using linkauth_action = eosio::action_wrapper<"linkauth"_n, &native::linkauth>; using unlinkauth_action = eosio::action_wrapper<"unlinkauth"_n, &native::unlinkauth>; using canceldelay_action = eosio::action_wrapper<"canceldelay"_n, &native::canceldelay>; - using onerror_action = eosio::action_wrapper<"onerror"_n, &native::onerror>; using setcode_action = eosio::action_wrapper<"setcode"_n, &native::setcode>; using setabi_action = eosio::action_wrapper<"setabi"_n, &native::setabi>; - }; } From 79197293518f776c75165cd45bfb4f27a7702da6 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 6 Feb 2019 21:20:49 -0500 Subject: [PATCH 0696/1048] bump version to v1.6.0-rc2 --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index ad782b95..6c894b18 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.6.0-rc1 +## Version : 1.6.0-rc2 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.5.x](https://github.com/EOSIO/eos/releases/tag/v1.5.0) -* [eosio.cdt v1.5.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.5.0-rc1) +* [eosio v1.6.x](https://github.com/EOSIO/eos/releases/tag/v1.6.1) +* [eosio.cdt v1.5.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.5.0) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From 42aa5b159315372ae401dea409c1469f58e719da Mon Sep 17 00:00:00 2001 From: zorba80 <35532164+zorba80@users.noreply.github.com> Date: Mon, 11 Feb 2019 11:04:51 -0500 Subject: [PATCH 0697/1048] Update README.md --- contracts/eosio.system/README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/contracts/eosio.system/README.md b/contracts/eosio.system/README.md index 26896b07..9e8c0fa6 100755 --- a/contracts/eosio.system/README.md +++ b/contracts/eosio.system/README.md @@ -102,6 +102,19 @@ The naming convention is codeaccount::actionname followed by a list of paramters - Cancels unfilled REX sell order by owner if one exists. - **owner** owner account name +## eosio::mvtosavings owner rex + - Moves REX to owner's REX savings bucket + - REX held in savings bucket does not mature and cannot be sold directly + - REX is moved out from the owner's maturity buckets as necessary starting with the bucket with furthest maturity date + - **owner** owner account of REX + - **rex** amount of REX to be moved to savings bucket + +## eosio::mvfrsavings owner rex + - Moves REX from owner's savings bucket to a bucket with a maturity date that is 4 days after the end of the day + - This action is required if the owner wants to sell REX held in savings bucket + - **owner** owner account of REX + - **rex** amount of REX to be moved from savings bucket + ## eosio::rentcpu from receiver loan\_payment loan\_fund - Rents CPU resources for 30 days in exchange for market-determined price - **from** account creating and paying for CPU loan From 8550d753fef817e52440d543f5212ba44e34f178 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 20 Feb 2019 17:02:11 -0500 Subject: [PATCH 0698/1048] Refactored parts of REX loans code --- .../include/eosio.system/eosio.system.hpp | 17 ++- contracts/eosio.system/src/rex.cpp | 124 +++++++++++++----- 2 files changed, 99 insertions(+), 42 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 1030e036..79987da9 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -667,6 +667,11 @@ namespace eosiosystem { void put_rex_savings( const rex_balance_table::const_iterator& bitr, int64_t rex ); void update_rex_stake( const name& voter ); + void add_loan_to_rex_pool( const asset& payment, int64_t rented_tokens, bool new_loan ); + void remove_loan_from_rex_pool( const rex_loan& loan ); + template + int64_t update_renewed_loan( Index& idx, const Iterator& itr, int64_t rented_tokens ); + // defined in delegate_bandwidth.cpp void changebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); @@ -687,12 +692,12 @@ namespace eosiosystem { public: template struct for_each { - template - static constexpr void call( system_contract* this_contract, Args&&... args ) - { - std::invoke( P, this_contract, std::forward(args)... ); - for_each::call( this_contract, std::forward(args)... ); - } + template + static constexpr void call( system_contract* this_contract, Args&&... args ) + { + std::invoke( P, this_contract, std::forward(args)... ); + for_each::call( this_contract, std::forward(args)... ); + } }; template struct for_each

{ diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 7a98b74f..20f727b7 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -474,6 +474,29 @@ namespace eosiosystem { return out; } + /** + * Given two connector balances (conin, and conout), and an incoming amount of + * in, this function calculates the delta out using Banacor equation. + * + * @param in - input amount, same units as conin + * @param conin - the input connector balance + * @param conout - the output connector balance + * + * @return int64_t - conversion output amount + */ + int64_t get_bancor_output( int64_t conin, int64_t conout, int64_t in ) + { + const double F0 = double(conin); + const double T0 = double(conout); + const double I = double(in); + + auto out = int64_t((I*T0) / (I+F0)); + + if ( out < 0 ) out = 0; + + return out; + } + /** * @brief Updates account NET and CPU resource limits * @@ -538,6 +561,55 @@ namespace eosiosystem { check( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), error_msg ); } + /** + * @brief Updates rex_pool balances upon creating a new loan or renewing an existing one + */ + void system_contract::add_loan_to_rex_pool( const asset& payment, int64_t rented_tokens, bool new_loan ) + { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rt ) { + rt.total_unlent.amount -= rented_tokens; + rt.total_lent.amount += rented_tokens; + rt.total_unlent.amount += payment.amount; + rt.total_rent.amount += payment.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + if ( new_loan ) { + rt.loan_num++; + } + }); + } + + /** + * @brief Updates rex_pool balances upon closing an expired loan + */ + void system_contract::remove_loan_from_rex_pool( const rex_loan& loan ) + { + const auto& pool = _rexpool.begin(); + const int64_t delta_total_rent = get_bancor_output( pool->total_unlent.amount, + pool->total_rent.amount, + loan.total_staked.amount ); + _rexpool.modify( pool, same_payer, [&]( auto& rt ) { + rt.total_rent.amount -= delta_total_rent; + rt.total_unlent.amount += loan.total_staked.amount; + rt.total_lent.amount -= loan.total_staked.amount; + rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + }); + } + + /** + * @brief Updates the fields of an existing loan that is being renewed + */ + template + int64_t system_contract::update_renewed_loan( Index& idx, const Iterator& itr, int64_t rented_tokens ) + { + int64_t delta_stake = rented_tokens - itr->total_staked.amount; + idx.modify ( itr, same_payer, [&]( auto& loan ) { + loan.total_staked.amount = rented_tokens; + loan.expiration += eosio::days(30); + loan.balance.amount -= loan.payment.amount; + }); + return delta_stake; + } + /** * @brief Performs maintenance operations on expired NET and CPU loans and sellrex oders * @@ -547,32 +619,18 @@ namespace eosiosystem { { check( rex_system_initialized(), "rex system not initialized yet" ); - auto rexi = _rexpool.begin(); + const auto& pool = _rexpool.begin(); auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { - _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { - bancor_convert( rt.total_unlent.amount, rt.total_rent.amount, itr->total_staked.amount ); - rt.total_lent.amount -= itr->total_staked.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - }); - bool delete_loan = false; - int64_t delta_stake = 0; + remove_loan_from_rex_pool( *itr ); + bool delete_loan = false; + int64_t delta_stake = 0; + int64_t rented_tokens = get_bancor_output( pool->total_rent.amount, + pool->total_unlent.amount, + itr->payment.amount ); if ( itr->payment <= itr->balance && rex_loans_available() ) { - int64_t rented_tokens = 0; - _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, - rt.total_unlent.amount, - itr->payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += itr->payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - }); - idx.modify ( itr, same_payer, [&]( auto& loan ) { - delta_stake = rented_tokens - loan.total_staked.amount; - loan.total_staked.amount = rented_tokens; - loan.expiration += eosio::days(30); - loan.balance.amount -= loan.payment.amount; - }); + add_loan_to_rex_pool( itr->payment, rented_tokens, false ); + delta_stake = update_renewed_loan( idx, itr, rented_tokens ); } else { delete_loan = true; delta_stake = -( itr->total_staked.amount ); @@ -586,9 +644,9 @@ namespace eosiosystem { }; /// transfer from eosio.names to eosio.rex - if ( rexi->namebid_proceeds.amount > 0 ) { - channel_to_rex( names_account, rexi->namebid_proceeds ); - _rexpool.modify( rexi, same_payer, [&]( auto& rt ) { + if ( pool->namebid_proceeds.amount > 0 ) { + channel_to_rex( names_account, pool->namebid_proceeds ); + _rexpool.modify( pool, same_payer, [&]( auto& rt ) { rt.namebid_proceeds.amount = 0; }); } @@ -667,16 +725,10 @@ namespace eosiosystem { update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( from, payment + fund ); - auto itr = _rexpool.begin(); /// already checked that _rexpool.begin() != _rexpool.end() in rex_loans_available() + const auto& pool = _rexpool.begin(); /// already checked that _rexpool.begin() != _rexpool.end() in rex_loans_available() - int64_t rented_tokens = 0; - _rexpool.modify( itr, same_payer, [&]( auto& rt ) { - rented_tokens = bancor_convert( rt.total_rent.amount, rt.total_unlent.amount, payment.amount ); - rt.total_lent.amount += rented_tokens; - rt.total_unlent.amount += payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - rt.loan_num++; - }); + int64_t rented_tokens = get_bancor_output( pool->total_rent.amount, pool->total_unlent.amount, payment.amount ); + add_loan_to_rex_pool( payment, rented_tokens, true ); table.emplace( from, [&]( auto& c ) { c.from = from; @@ -685,7 +737,7 @@ namespace eosiosystem { c.balance = fund; c.total_staked = asset( rented_tokens, core_symbol() ); c.expiration = current_time_point() + eosio::days(30); - c.loan_num = itr->loan_num; + c.loan_num = pool->loan_num; }); return rented_tokens; From 6f72cabbdc8e5fb205945b8e844185ee5aa78278 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Feb 2019 13:26:57 -0500 Subject: [PATCH 0699/1048] Added a check to verify that rented stake is larger than the fee paid --- contracts/eosio.system/src/rex.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 20f727b7..dbaaea83 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -628,7 +628,11 @@ namespace eosiosystem { int64_t rented_tokens = get_bancor_output( pool->total_rent.amount, pool->total_unlent.amount, itr->payment.amount ); - if ( itr->payment <= itr->balance && rex_loans_available() ) { + // conditions for loan renewal + bool renew_loan = itr->payment <= itr->balance // loan has sufficient balance + && itr->payment.amount < rented_tokens // loan has favorable return + && rex_loans_available(); // no pending sell orders + if ( renew_loan ) { add_loan_to_rex_pool( itr->payment, rented_tokens, false ); delta_stake = update_renewed_loan( idx, itr, rented_tokens ); } else { @@ -728,6 +732,7 @@ namespace eosiosystem { const auto& pool = _rexpool.begin(); /// already checked that _rexpool.begin() != _rexpool.end() in rex_loans_available() int64_t rented_tokens = get_bancor_output( pool->total_rent.amount, pool->total_unlent.amount, payment.amount ); + check( payment.amount < rented_tokens, "loan price does not favor renting" ); add_loan_to_rex_pool( payment, rented_tokens, true ); table.emplace( from, [&]( auto& c ) { @@ -1005,7 +1010,7 @@ namespace eosiosystem { * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. */ const int64_t rex_ratio = 10000; - const int64_t init_total_rent = 20'000'0000; /// base amount prevents renting profitably until at least a minimum number of core_symbol() is made available + const asset init_total_rent( 20'000'0000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available asset rex_received( 0, rex_symbol ); auto itr = _rexpool.begin(); if ( !rex_system_initialized() ) { @@ -1015,7 +1020,7 @@ namespace eosiosystem { rp.total_lendable = payment; rp.total_lent = asset( 0, core_symbol() ); rp.total_unlent = rp.total_lendable - rp.total_lent; - rp.total_rent = asset( init_total_rent, core_symbol() ); + rp.total_rent = init_total_rent; rp.total_rex = rex_received; rp.namebid_proceeds = asset( 0, core_symbol() ); }); @@ -1025,7 +1030,7 @@ namespace eosiosystem { rp.total_lendable.amount = payment.amount; rp.total_lent.amount = 0; rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - rp.total_rent.amount = init_total_rent; + rp.total_rent.amount = init_total_rent.amount; rp.total_rex.amount = rex_received.amount; }); } else { From 4fa105cdbdc67628245c9af885c84b8c36924440 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Feb 2019 18:21:56 -0500 Subject: [PATCH 0700/1048] Fixed error in REX sell order queue and loan availability --- .../include/eosio.system/eosio.system.hpp | 2 +- contracts/eosio.system/src/rex.cpp | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 79987da9..7028e3ec 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -654,7 +654,7 @@ namespace eosiosystem { void defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ); void transfer_from_fund( const name& owner, const asset& amount ); void transfer_to_fund( const name& owner, const asset& amount ); - bool rex_loans_available()const { return _rexorders.begin() == _rexorders.end() && rex_available(); } + bool rex_loans_available()const; bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } static time_point_sec get_rex_maturity(); diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index dbaaea83..0fb91f35 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -561,6 +561,23 @@ namespace eosiosystem { check( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), error_msg ); } + bool system_contract::rex_loans_available()const + { + if ( !rex_available() ) { + return false; + } else if ( _rexorders.begin() == _rexorders.end() ) { // rex_available() && _rexorders.begin() == _rexorders.end() + return true; + } else { // rex_available() && _rexorders.begin() != _rexorders.end() + auto idx = _rexorders.get_index<"bytime"_n>(); + auto begin = idx.begin(); + if ( begin->is_open ) { + return false; + } else { + return true; + } + } + } + /** * @brief Updates rex_pool balances upon creating a new loan or renewing an existing one */ From c1fbc6ceaa09e2528375424e3cee7b775f9806a5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Feb 2019 19:18:55 -0500 Subject: [PATCH 0701/1048] Modified balances. Unit tests for new checks --- contracts/eosio.system/src/rex.cpp | 6 +- tests/eosio.system_tests.cpp | 109 ++++++++++++++++++++--------- 2 files changed, 78 insertions(+), 37 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 0fb91f35..aaf3f1cd 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -787,7 +787,7 @@ namespace eosiosystem { check( proceeds.amount > 0, "proceeds are negligible" ); - const int64_t unlent_lower_bound = rexitr->total_lent.amount; + const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible if ( proceeds.amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; @@ -1026,8 +1026,8 @@ namespace eosiosystem { * to exceed that limit, maximum amount of indivisible units cannot be set to a value larger than 4 * 10^14. * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. */ - const int64_t rex_ratio = 10000; - const asset init_total_rent( 20'000'0000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available + const int64_t rex_ratio = 10000; + const asset init_total_rent( 200 * 10000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available asset rex_received( 0, rex_symbol ); auto itr = _rexpool.begin(); if ( !rex_system_initialized() ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 2404df53..91b1add4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3393,7 +3393,7 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("20000.0000"); + const asset init_rent = core_sym::from_string("200.0000"); const asset init_balance = core_sym::from_string("1000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; @@ -3460,7 +3460,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_small_rex, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; setup_rex_accounts( accounts, init_balance ); - const asset payment = core_sym::from_string("10.0000"); + const asset payment = core_sym::from_string("500.0000"); BOOST_REQUIRE_EQUAL( ratio * payment.get_amount(), get_buyrex_result( alice, payment ).get_amount() ); produce_blocks(2); @@ -3477,7 +3477,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_small_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( get_rex_vote_stake( alice ), init_rex_stake - core_sym::from_string("0.0006") ); BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, bob, core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("0.9000 REX") ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.4000 REX") ) ); } FC_LOG_AND_RETHROW() @@ -3615,8 +3615,8 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { // bob tries to rent rex BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_sym::from_string("5.0000") ) ); // alice lends rex - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("65.0000") ) ); - BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("65.0000"), get_rex_fund(alice) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("265.0000") ) ); + BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("265.0000"), get_rex_fund(alice) ); auto rex_pool = get_rex_pool(); const asset init_tot_unlent = rex_pool["total_unlent"].as(); const asset init_tot_lendable = rex_pool["total_lendable"].as(); @@ -3672,9 +3672,9 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { { const int64_t init_net_limit = get_net_limit( emily ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("110.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("210.0000") ) ); rex_pool = get_rex_pool(); - const asset fee = core_sym::from_string("132.4560"); + const asset fee = core_sym::from_string("2.4560"); int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), rex_pool["total_unlent"].as().get_amount(), fee.get_amount() ); @@ -3699,7 +3699,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { const int64_t init_net_limit = get_net_limit( alice ); // alice lends rex - const asset payment = core_sym::from_string("65.0000"); + const asset payment = core_sym::from_string("650.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("0.0005") ) ); BOOST_REQUIRE_EQUAL( init_balance - payment, get_rex_fund(alice) ); @@ -3772,7 +3772,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); - BOOST_REQUIRE_EQUAL(core_sym::from_string("20000.0000"), get_rex_pool()["total_rent"].as() ); + BOOST_REQUIRE_EQUAL(core_sym::from_string("200.0000"), get_rex_pool()["total_rent"].as() ); const asset rent_payment = core_sym::from_string("1100000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); @@ -3819,8 +3819,8 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); // wait for 2 more hours, by now frank's loan has expired and there is enough balance in - // total_unlent to close some sellrex orders. only two are processed, bob's and carol's - // alices's order is still open + // total_unlent to close some sellrex orders. only two are processed, bob's and carol's. + // alices's order is still open. // an action is needed to trigger queue processing produce_block( fc::hours(2) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), @@ -3991,6 +3991,37 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_loan_checks, eosio_system_tester ) try { + + const int64_t ratio = 10000; + const asset init_balance = core_sym::from_string("10000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance ); + + const asset payment1 = core_sym::from_string("200.0000"); + const asset payment2 = core_sym::from_string("2.0000"); + const asset fee = core_sym::from_string("1.0000"); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("loan price does not favor renting"), + rentcpu( bob, bob, fee ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment2 ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee, fee + fee + fee ) ); + BOOST_REQUIRE_EQUAL( true, !get_cpu_loan(1).is_null() ); + BOOST_REQUIRE_EQUAL( 3 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); + + produce_block( fc::days(31) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 3) ); + BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); + + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1000000.0000 REX") ) ); + produce_block( fc::days(31) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 3) ); + BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); + +} FC_LOG_AND_RETHROW() + + BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { const int64_t ratio = 10000; @@ -4174,7 +4205,7 @@ BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { auto rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, alice, core_sym::from_string("800000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, alice, core_sym::from_string("8000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket1.get_amount() - 20, rex_sym ) ) ); rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), get_rex_order( bob )["rex_requested"].as().get_amount() + 20 ); @@ -4418,13 +4449,15 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const int64_t init_stake = get_voter_info( alice )["staked"].as(); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("250.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("250.0000"), get_rex_vote_stake(alice) ); + const asset payment = core_sym::from_string("2500.0000"); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); + BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, core_sym::from_string("50.0000") ) ); + const asset fee = core_sym::from_string("50.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, fee ) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_rex_vote_stake(alice) ); + BOOST_REQUIRE_EQUAL( payment + fee, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers @@ -4512,8 +4545,8 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const int64_t init_stake_amount = get_voter_info( alice )["staked"].as(); const asset init_stake( init_stake_amount, symbol{CORE_SYM} ); - const asset purchase = core_sym::from_string("250.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("250.0000") ) ); + const asset purchase = core_sym::from_string("500.0000"); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase ) ); BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); @@ -4589,15 +4622,16 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { - const asset init_balance = core_sym::from_string("200.0000"); + const asset init_balance = core_sym::from_string("500.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; account_name alice = accounts[0], bob = accounts[1]; setup_rex_accounts( accounts, init_balance ); const symbol rex_sym( SY(4, REX) ); - const asset payment = core_sym::from_string("50.0000"); + const asset payment = core_sym::from_string("500.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, payment ) ); + const asset fee = core_sym::from_string("5.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); const auto rex_pool = get_rex_pool(); const int64_t tot_rex = rex_pool["total_rex"].as().get_amount(); @@ -4605,11 +4639,11 @@ BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { const int64_t tot_lent = rex_pool["total_lent"].as().get_amount(); const int64_t tot_lendable = rex_pool["total_lendable"].as().get_amount(); double rex_per_eos = double(tot_rex) / double(tot_lendable); - int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.99 * tot_lent ); + int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.19 * tot_lent ); produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - sell_amount = rex_per_eos * ( tot_unlent - tot_lent ); + sell_amount = rex_per_eos * ( tot_unlent - 0.2 * tot_lent ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("no sellrex order is scheduled"), cancelrexorder( alice ) ); @@ -4619,24 +4653,24 @@ BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { - const asset init_balance = core_sym::from_string("200.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + const asset init_balance = core_sym::from_string("2000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; setup_rex_accounts( accounts, init_balance ); - BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( alice ).is_null() ); + BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( alice ).is_null() ); BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( alice ) ); BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); BOOST_REQUIRE_EQUAL( success(), withdraw( alice, init_balance ) ); BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( alice).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( alice ).is_null() ); BOOST_REQUIRE_EQUAL( success(), deposit( alice, init_balance ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( alice).is_null() ); + BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( alice ).is_null() ); BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( false, get_rex_fund_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( true, !get_rex_balance_obj( bob ).is_null() ); + BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( bob ).is_null() ); BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); produce_block( fc::days(5) ); @@ -4650,11 +4684,16 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), deposit( bob, init_balance ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, emily, init_balance ) ); + const asset fee = core_sym::from_string("1.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, emily, fee ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), + withdraw( carol, init_balance ) ); + BOOST_REQUIRE_EQUAL( success(), withdraw( carol, init_balance - fee ) ); produce_block( fc::days(20) ); BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); + BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( carol ).is_null() ); produce_block( fc::days(10) ); @@ -4662,8 +4701,10 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( carol ).is_null() ); BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( carol ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, init_balance ) ); + BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, fee ) ); + BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( emily ).is_null() ); BOOST_REQUIRE_EQUAL( success(), closerex( emily ) ); + BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( emily ).is_null() ); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); @@ -4680,7 +4721,7 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_lendable"].as().get_amount() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); + rentcpu( emily, emily, core_sym::from_string("1.0000") ) ); } FC_LOG_AND_RETHROW() From 383320eebad246a014feee5e56a317a58771593e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 22 Feb 2019 15:53:13 -0500 Subject: [PATCH 0702/1048] REX code cleaning, comments --- contracts/eosio.system/src/rex.cpp | 68 ++++++++++++++---------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index aaf3f1cd..aab265f7 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -61,7 +61,7 @@ namespace eosiosystem { runrex(2); update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); // dummy action added so that amount of REX tokens purchased shows up in action trace - dispatch_inline( null_account, "buyresult"_n, { }, std::make_tuple( rex_received ) ); + dispatch_inline( null_account, "buyresult"_n, { }, std::make_tuple( rex_received ) ); } /** @@ -448,32 +448,6 @@ namespace eosiosystem { } } - /** - * Given two connector balances (conin, and conout), and an incoming amount of - * in, this function will modify conin and conout and return the delta out. - * - * @param in - input amount, same units as conin - * @param conin - the input connector balance - * @param conout - the output connector balance - * - * @return int64_t - conversion output amount - */ - int64_t bancor_convert( int64_t& conin, int64_t& conout, int64_t in ) - { - const double F0 = double(conin); - const double T0 = double(conout); - const double I = double(in); - - auto out = int64_t((I*T0) / (I+F0)); - - if ( out < 0 ) out = 0; - - conin += in; - conout -= out; - - return out; - } - /** * Given two connector balances (conin, and conout), and an incoming amount of * in, this function calculates the delta out using Banacor equation. @@ -555,40 +529,58 @@ namespace eosiosystem { } } + /** + * @brief Checks if account voting requirements (voting for a proxy or 21 producers) when + * buying REX + * + * @param owner - account buying or already holding REX tokens + * @err_msg - error message + */ void system_contract::check_voting_requirement( const name& owner, const char* error_msg )const { auto vitr = _voters.find( owner.value ); check( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), error_msg ); } + /** + * @brief Checks if CPU and Network loans are available + * + * Loans are available if 1) REX pool lendable balance is nonempty, and 2) there are no + * unfilled sellrex orders. + */ bool system_contract::rex_loans_available()const { if ( !rex_available() ) { return false; - } else if ( _rexorders.begin() == _rexorders.end() ) { // rex_available() && _rexorders.begin() == _rexorders.end() - return true; - } else { // rex_available() && _rexorders.begin() != _rexorders.end() - auto idx = _rexorders.get_index<"bytime"_n>(); - auto begin = idx.begin(); - if ( begin->is_open ) { - return false; + } else { + if ( _rexorders.begin() == _rexorders.end() ) { + return true; // no outstanding sellrex orders } else { - return true; + auto idx = _rexorders.get_index<"bytime"_n>(); + return !idx.begin()->is_open; // no outstanding unfilled sellrex orders } } } /** * @brief Updates rex_pool balances upon creating a new loan or renewing an existing one + * + * @param payment - loan fee paid + * @param rented_tokens - amount of tokens to be staked to loan receiver + * @param new_loan - flag indicating whether the loan is new or being renewed */ void system_contract::add_loan_to_rex_pool( const asset& payment, int64_t rented_tokens, bool new_loan ) { _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rt ) { + // add payment to total_rent + rt.total_rent.amount += payment.amount; + // move rented_tokens from total_unlent to total_lent rt.total_unlent.amount -= rented_tokens; rt.total_lent.amount += rented_tokens; + // add payment to total_unlent rt.total_unlent.amount += payment.amount; - rt.total_rent.amount += payment.amount; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; + // increment loan_num if a new loan is being created if ( new_loan ) { rt.loan_num++; } @@ -597,6 +589,8 @@ namespace eosiosystem { /** * @brief Updates rex_pool balances upon closing an expired loan + * + * @param loan - loan to be closed */ void system_contract::remove_loan_from_rex_pool( const rex_loan& loan ) { @@ -605,7 +599,9 @@ namespace eosiosystem { pool->total_rent.amount, loan.total_staked.amount ); _rexpool.modify( pool, same_payer, [&]( auto& rt ) { + // deduct calculated delta_total_rent from total_rent rt.total_rent.amount -= delta_total_rent; + // move rented tokens from total_lent to total_unlent rt.total_unlent.amount += loan.total_staked.amount; rt.total_lent.amount -= loan.total_staked.amount; rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; From 4a8fddca484b9630d5c8dbd2ea47e510f784d07b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 25 Feb 2019 15:37:57 -0500 Subject: [PATCH 0703/1048] Add ABI support for inline dummy actions --- contracts/eosio.system/CMakeLists.txt | 10 ++++++++++ contracts/eosio.system/src/rex.cpp | 15 ++++++++++----- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index 6c8a4c5b..de993ef0 100755 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -8,3 +8,13 @@ target_include_directories(eosio.system set_target_properties(eosio.system PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +add_contract(rex.results rex.results ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.results.cpp) + +target_include_directories(rex.results + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) + +set_target_properties(rex.results + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.rex") diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index aab265f7..e235cce2 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -3,6 +3,7 @@ */ #include +#include namespace eosiosystem { @@ -61,7 +62,8 @@ namespace eosiosystem { runrex(2); update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); // dummy action added so that amount of REX tokens purchased shows up in action trace - dispatch_inline( null_account, "buyresult"_n, { }, std::make_tuple( rex_received ) ); + rex_results::buyresult_action buyrex_act( rex_account, std::vector{ } ); + buyrex_act.send( rex_received ); } /** @@ -105,7 +107,8 @@ namespace eosiosystem { runrex(2); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ), true ); // dummy action added so that amount of REX tokens purchased shows up in action trace - dispatch_inline( null_account, "buyresult"_n, { }, std::make_tuple( rex_received ) ); + rex_results::buyresult_action buyrex_act( rex_account, std::vector{ } ); + buyrex_act.send( rex_received ); } /** @@ -153,7 +156,8 @@ namespace eosiosystem { check( pending_sell_order.amount <= bitr->matured_rex, "insufficient funds for current and scheduled orders" ); // dummy action added so that sell order proceeds show up in action trace if ( current_order.success ) { - dispatch_inline( null_account, "sellresult"_n, { }, std::make_tuple( current_order.proceeds ) ); + rex_results::sellresult_action sellrex_act( rex_account, std::vector{ } ); + sellrex_act.send( current_order.proceeds ); } } @@ -721,7 +725,8 @@ namespace eosiosystem { order.close(); }); /// send dummy action to show and owner and proceeds of filled sellrex order - dispatch_inline( null_account, "orderresult"_n, { }, std::make_tuple( order_owner, result.proceeds ) ); + rex_results::orderresult_action order_act( rex_account, std::vector{ } ); + order_act.send( order_owner, result.proceeds ); } } oitr = next; @@ -1172,7 +1177,7 @@ namespace eosiosystem { }); delta_stake = current_vote_stake.amount - init_vote_stake.amount; } - + if ( delta_stake != 0 ) { auto vitr = _voters.find( voter.value ); if ( vitr != _voters.end() ) { From efd824ed65f57db90b6f167d57818884b448db5e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 25 Feb 2019 20:07:37 -0500 Subject: [PATCH 0704/1048] REX unit tests --- contracts/eosio.system/src/rex.cpp | 2 +- tests/eosio.system_tests.cpp | 68 +++++++++++++++++------------- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index e235cce2..d983a014 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -1028,7 +1028,7 @@ namespace eosiosystem { * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. */ const int64_t rex_ratio = 10000; - const asset init_total_rent( 200 * 10000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available + const asset init_total_rent( 1000 * 10000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available asset rex_received( 0, rex_symbol ); auto itr = _rexpool.begin(); if ( !rex_system_initialized() ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 91b1add4..b1f3512b 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3393,7 +3393,7 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("200.0000"); + const asset init_rent = core_sym::from_string("1000.0000"); const asset init_balance = core_sym::from_string("1000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; @@ -3455,12 +3455,12 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_small_rex, eosio_system_tester ) try { const int64_t ratio = 10000; const asset init_rent = core_sym::from_string("100000.0000"); - const asset init_balance = core_sym::from_string("1000.0000"); + const asset init_balance = core_sym::from_string("5000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; setup_rex_accounts( accounts, init_balance ); - const asset payment = core_sym::from_string("500.0000"); + const asset payment = core_sym::from_string("2000.0000"); BOOST_REQUIRE_EQUAL( ratio * payment.get_amount(), get_buyrex_result( alice, payment ).get_amount() ); produce_blocks(2); @@ -3615,8 +3615,8 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { // bob tries to rent rex BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_sym::from_string("5.0000") ) ); // alice lends rex - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("265.0000") ) ); - BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("265.0000"), get_rex_fund(alice) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("5265.0000") ) ); + BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("5265.0000"), get_rex_fund(alice) ); auto rex_pool = get_rex_pool(); const asset init_tot_unlent = rex_pool["total_unlent"].as(); const asset init_tot_lendable = rex_pool["total_lendable"].as(); @@ -3672,9 +3672,9 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { { const int64_t init_net_limit = get_net_limit( emily ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("210.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("1050.0000") ) ); rex_pool = get_rex_pool(); - const asset fee = core_sym::from_string("2.4560"); + const asset fee = core_sym::from_string("0.4560"); int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), rex_pool["total_unlent"].as().get_amount(), fee.get_amount() ); @@ -3699,7 +3699,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { const int64_t init_net_limit = get_net_limit( alice ); // alice lends rex - const asset payment = core_sym::from_string("650.0000"); + const asset payment = core_sym::from_string("3250.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("0.0005") ) ); BOOST_REQUIRE_EQUAL( init_balance - payment, get_rex_fund(alice) ); @@ -3754,9 +3754,9 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - const auto purchase1 = core_sym::from_string("100000.0000"); - const auto purchase2 = core_sym::from_string("471000.0000"); - const auto purchase3 = core_sym::from_string("469000.0000"); + const auto purchase1 = core_sym::from_string("2500.0000"); + const auto purchase2 = core_sym::from_string("11775.0000"); + const auto purchase3 = core_sym::from_string("11725.0000"); const auto init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); @@ -3772,9 +3772,14 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); - BOOST_REQUIRE_EQUAL(core_sym::from_string("200.0000"), get_rex_pool()["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_rex_pool()["total_rent"].as() ); + + for (uint8_t i = 0; i < 4; ++i) { + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("1000.0000") ) ); + } + + const asset rent_payment = core_sym::from_string("2000.0000"); - const asset rent_payment = core_sym::from_string("1100000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); const auto init_rex_pool = get_rex_pool(); @@ -3783,11 +3788,11 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); - BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); + BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); + BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); + BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); produce_block( fc::days(5) ); @@ -3829,11 +3834,9 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto trace = base_tester::push_action( N(eosio), N(buyrex), frank, mvo()("from", frank)("amount", core_sym::from_string("0.0001")) ); auto output = get_rexorder_result( trace ); - BOOST_REQUIRE_EQUAL( output.size(), 2 ); + BOOST_REQUIRE_EQUAL( output.size(), 1 ); BOOST_REQUIRE_EQUAL( output[0].first, bob ); BOOST_REQUIRE_EQUAL( output[0].second, get_rex_order(bob)["proceeds"].as() ); - BOOST_REQUIRE_EQUAL( output[1].first, carol ); - BOOST_REQUIRE_EQUAL( output[1].second, get_rex_order(carol)["proceeds"].as() ); } BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); @@ -3844,9 +3847,9 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(carol)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(carol)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); @@ -3860,6 +3863,13 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { mvo()("from", frank)("amount", core_sym::from_string("0.0001")) ); auto output = get_rexorder_result( trace ); BOOST_REQUIRE_EQUAL( output.size(), 0 ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); + } + + { + auto trace = base_tester::push_action( N(eosio), N(rexexec), frank, mvo()("user", frank)("max", 4) ); + auto output = get_rexorder_result( trace ); + BOOST_REQUIRE_EQUAL( output.size(), 0 ); } } FC_LOG_AND_RETHROW() @@ -3873,7 +3883,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("500.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("2500.0000") ) ); auto rex_pool = get_rex_pool(); const asset payment = core_sym::from_string("30.0000"); @@ -3994,12 +4004,12 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_loan_checks, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); + const asset init_balance = core_sym::from_string("20000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; account_name alice = accounts[0], bob = accounts[1]; setup_rex_accounts( accounts, init_balance ); - const asset payment1 = core_sym::from_string("200.0000"); + const asset payment1 = core_sym::from_string("1000.0000"); const asset payment2 = core_sym::from_string("2.0000"); const asset fee = core_sym::from_string("1.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); @@ -4545,7 +4555,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const int64_t init_stake_amount = get_voter_info( alice )["staked"].as(); const asset init_stake( init_stake_amount, symbol{CORE_SYM} ); - const asset purchase = core_sym::from_string("500.0000"); + const asset purchase = core_sym::from_string("2500.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase ) ); BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); @@ -4622,15 +4632,15 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { - const asset init_balance = core_sym::from_string("500.0000"); + const asset init_balance = core_sym::from_string("2500.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; account_name alice = accounts[0], bob = accounts[1]; setup_rex_accounts( accounts, init_balance ); const symbol rex_sym( SY(4, REX) ); - const asset payment = core_sym::from_string("500.0000"); + const asset payment = core_sym::from_string("2500.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - const asset fee = core_sym::from_string("5.0000"); + const asset fee = core_sym::from_string("25.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); const auto rex_pool = get_rex_pool(); From 54e57ba08d428b5fe9c03fadf31fd48143311c47 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 26 Feb 2019 09:46:56 -0500 Subject: [PATCH 0705/1048] Add ABI support for inline dummy actions - 2 --- .../include/eosio.system/rex.results.hpp | 24 +++++++++++++++++++ contracts/eosio.system/src/rex.results.cpp | 9 +++++++ 2 files changed, 33 insertions(+) create mode 100644 contracts/eosio.system/include/eosio.system/rex.results.hpp create mode 100644 contracts/eosio.system/src/rex.results.cpp diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp new file mode 100644 index 00000000..4ca11962 --- /dev/null +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -0,0 +1,24 @@ +#pragma once + +#include +#include +#include + +using eosio::name; +using eosio::asset; + +class [[eosio::contract("rex.results")]] rex_results { + public: + [[eosio::action]] + void buyresult( const asset& rex_received ); + + [[eosio::action]] + void sellresult( const asset& proceeds ); + + [[eosio::action]] + void orderresult( const name& owner, const asset& proceeds ); + + using buyresult_action = eosio::action_wrapper<"buyresult"_n, &rex_results::buyresult>; + using sellresult_action = eosio::action_wrapper<"sellresult"_n, &rex_results::sellresult>; + using orderresult_action = eosio::action_wrapper<"orderresult"_n, &rex_results::orderresult>; +}; diff --git a/contracts/eosio.system/src/rex.results.cpp b/contracts/eosio.system/src/rex.results.cpp new file mode 100644 index 00000000..5db7ffe2 --- /dev/null +++ b/contracts/eosio.system/src/rex.results.cpp @@ -0,0 +1,9 @@ +#include + +void rex_results::buyresult( const asset& rex_received ) { } + +void rex_results::sellresult( const asset& proceeds ) { } + +void rex_results::orderresult( const name& owner, const asset& proceeds ) { } + +extern "C" void apply( uint64_t, uint64_t, uint64_t ) { } From ef99886173960126d0d560b259c94a86987897e4 Mon Sep 17 00:00:00 2001 From: Zach <34947245+kj4ezj@users.noreply.github.com> Date: Tue, 26 Feb 2019 11:02:05 -0500 Subject: [PATCH 0706/1048] Created Buildkite Pipeline with Docker Build (#188) Added Buildkite pipeline for contracts, including docker stuff and dependency file in root to declare corresponding CDT and EOSIO versions --- dependencies | 3 +++ docker/Dockerfile | 33 +++++++++++++++++++++++++++++++++ docker/buildContracts.sh | 5 +++++ docker/downloadDependencies.sh | 27 +++++++++++++++++++++++++++ 4 files changed, 68 insertions(+) create mode 100644 dependencies create mode 100644 docker/Dockerfile create mode 100755 docker/buildContracts.sh create mode 100755 docker/downloadDependencies.sh diff --git a/dependencies b/dependencies new file mode 100644 index 00000000..daa58525 --- /dev/null +++ b/dependencies @@ -0,0 +1,3 @@ +# dependencies to pull for a build of contracts, by branch, tag, or commit hash +eosio=release/1.6.x +cdt=release/1.5.x diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..cf59a029 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,33 @@ +FROM gcr.io/b1-automation-dev/eosio/builder:develop as builder +# import build-time arguments +ARG CONTRACTS_COMMIT +ARG CONTRACTS_BRANCH +# install external dependencies +RUN apt-get update && \ +apt-get -y upgrade && \ +DEBIAN_FRONTEND=noninteractive apt-get -y install openssl ca-certificates build-essential libbz2-dev zlib1g-dev libssl-dev libgmp3-dev libicu-dev cmake bc jq curl wget net-tools unzip gnupg git graphviz awscli +# download contracts +RUN echo "# git clone -n https://github.com/EOSIO/eosio.contracts.git --quiet" && \ +git clone -n https://github.com/EOSIO/eosio.contracts.git --quiet && \ +echo "# cd eosio.contracts" && \ +cd eosio.contracts && \ +echo "# git checkout $CONTRACTS_COMMIT --quiet" && \ +git checkout $CONTRACTS_COMMIT --quiet && \ +echo "# git submodule update --recursive --init --quiet" && \ +git submodule update --recursive --init --quiet +# download internal dependencies +RUN /eosio.contracts/docker/downloadDependencies.sh +# build eosio +RUN cd eos && \ +./eosio_build.sh +# install eosio +RUN cd eos && \ +./eosio_install.sh +# install cdt +RUN for filename in $(ls *.deb); do /usr/bin/dpkg -i "$filename" && rm -f "$filename"; done +# set environment variables +RUN PATH=/usr/local/eosio/bin:$(echo "/usr/opt/eosio.cdt/$(ls /usr/opt/eosio.cdt)/bin"):$PATH +ENV EOSIO_ROOT=/usr/local/eosio +ENV LD_LIBRARY_PATH=/usr/local/lib +# add the entrypoint script +ENTRYPOINT ["/eosio.contracts/docker/buildContracts.sh"] \ No newline at end of file diff --git a/docker/buildContracts.sh b/docker/buildContracts.sh new file mode 100755 index 00000000..8d63f759 --- /dev/null +++ b/docker/buildContracts.sh @@ -0,0 +1,5 @@ +#!/bin/bash +cd /eosio.contracts +./build.sh +cd build +tar -pczf /artifacts/contracts.tar.gz * diff --git a/docker/downloadDependencies.sh b/docker/downloadDependencies.sh new file mode 100755 index 00000000..67b677dd --- /dev/null +++ b/docker/downloadDependencies.sh @@ -0,0 +1,27 @@ +#!/bin/bash +CONTRACTS_PATH='/eosio.contracts' # location in Docker container, not your local machine +# get EOSIO +echo "downloadDependencies.sh - Cloning EOSIO source from GitHub..." +EOSIO_VERSION=$(cat $CONTRACTS_PATH/dependencies | sed 's,//,#,g' | cut -d '#' -f 1 | grep -v 'eos.*cdt.*=' | grep -v 'eos.*contracts.*=' | grep '.*eos.*=' | cut -d '=' -f 2 | awk '{print $1}') +EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match +test -z $EOSIO_COMMIT && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | awk '{print $1}') # if both searches returned nothing, the version is probably specified by commit hash already +git clone -n https://github.com/EOSIO/eos.git --quiet +echo "downloadDependencies.sh - Cloned EOSIO. Checking out ${EOSIO_COMMIT:0:7}..." +cd eos +test "$(git cat-file -t $EOSIO_COMMIT 2>/dev/null)" != "commit" && cd .. && echo "downloadDependencies.sh - ERROR: EOSIO tag, branch, or commit \"$EOSIO_VERSION\" not found in github.com/EOSIO/eos$(test $EOSIO_VERSION != $EOSIO_COMMIT && echo " using commit \"${EOSIO_COMMIT:0:7}\"")! Exiting..." && exit 1 +git checkout $EOSIO_COMMIT --quiet +git submodule update --recursive --init --quiet +echo "downloadDependencies.sh - Checked out EOSIO at $EOSIO_COMMIT from \"$EOSIO_VERSION\""'!' +echo "$CONTRACTS_BRANCH:$EOSIO_COMMIT" > /etc/eosio-version # this is necessary for our eos CMake VersionMacros which construct the string returned from "$ nodeos --version"; CONTRACTS_BRANCH is a build-arg passed from pipeline.yml into the Docker container +echo "downloadDependencies.sh - Wrote \"/etc/eosio-version\"." +cd .. +# get CDT +echo "downloadDependencies.sh - Getting CDT binary from Amazon S3..." +CDT_VERSION=$(cat $CONTRACTS_PATH/dependencies | sed 's,//,#,g' | cut -d '#' -f 1 | grep 'cdt.*=' | cut -d '=' -f 2 | awk '{print $1}') +CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match +test -z $CDT_COMMIT && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | awk '{print $1}') # if both searches returned nothing, the version is probably specified by commit hash already +CDT_PKG_NAME=$(aws s3 ls s3://eos-binaries | grep ${CDT_COMMIT:0:7} | grep "ubuntu-18.04_amd64.deb" | tr ' ' '\n' | grep '.deb') # get Ubuntu 18.04 *.deb package from S3 bucket by commit hash +echo "downloadDependencies.sh - Found \"$CDT_PKG_NAME\" in s3://eos-binaries. Downloading..." +test -z $CDT_PKG_NAME && echo "downloadDependencies.sh - ERROR: CDT tag, branch, or commit \"$CDT_VERSION\" not found in s3://eos-binaries$(test $CDT_VERSION != $CDT_COMMIT && echo " using commit \"${CDT_COMMIT:0:7}\"")! Exiting..." && exit 1 +aws s3 cp s3://eos-binaries/$CDT_PKG_NAME ./$CDT_PKG_NAME --quiet # download CDT +echo "downloadDependencies.sh - Downloaded CDT at $CDT_COMMIT from \"$CDT_VERSION\""'!' \ No newline at end of file From ca9221cfb13f652b014baa4851499769b4d10f10 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 26 Feb 2019 13:17:22 -0500 Subject: [PATCH 0707/1048] Update REX unit tests --- tests/eosio.system_tests.cpp | 70 +++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 29 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b1f3512b..bc36da62 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3818,7 +3818,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { // wait for 30 days minus 1 hour produce_block( fc::hours(19*24 + 23) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("0.0001") ) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); @@ -3831,45 +3831,57 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); { - auto trace = base_tester::push_action( N(eosio), N(buyrex), frank, - mvo()("from", frank)("amount", core_sym::from_string("0.0001")) ); + auto trace = base_tester::push_action( config::system_account_name, N(rexexec), frank, + mvo()("user", frank)("max", 2) ); auto output = get_rexorder_result( trace ); BOOST_REQUIRE_EQUAL( output.size(), 1 ); BOOST_REQUIRE_EQUAL( output[0].first, bob ); BOOST_REQUIRE_EQUAL( output[0].second, get_rex_order(bob)["proceeds"].as() ); } - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); - BOOST_REQUIRE_EQUAL( success(), updaterex( carol ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( carol ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); - { - auto trace = base_tester::push_action( N(eosio), N(buyrex), frank, - mvo()("from", frank)("amount", core_sym::from_string("0.0001")) ); - auto output = get_rexorder_result( trace ); - BOOST_REQUIRE_EQUAL( output.size(), 0 ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); + + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); + BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), + rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); } { - auto trace = base_tester::push_action( N(eosio), N(rexexec), frank, mvo()("user", frank)("max", 4) ); - auto output = get_rexorder_result( trace ); - BOOST_REQUIRE_EQUAL( output.size(), 0 ); + auto trace1 = base_tester::push_action( config::system_account_name, N(updaterex), bob, mvo()("owner", bob) ); + auto trace2 = base_tester::push_action( config::system_account_name, N(updaterex), carol, mvo()("owner", carol) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); + BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( carol ).get_amount() ); + BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); + auto output1 = get_rexorder_result( trace1 ); + auto output2 = get_rexorder_result( trace2 ); + BOOST_REQUIRE_EQUAL( 2, output1.size() + output2.size() ); + + BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(bob).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(carol).is_null() ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); + + const auto& rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), + rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); + + BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_sym::from_string("1100.0000") ) ); + BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); + BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); + + BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); } } FC_LOG_AND_RETHROW() From 41ff2cd426702f1ba1b310566f113aa6f2918d04 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 26 Feb 2019 14:46:30 -0500 Subject: [PATCH 0708/1048] More REX comments --- contracts/eosio.system/src/rex.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index d983a014..162efe60 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -639,18 +639,22 @@ namespace eosiosystem { const auto& pool = _rexpool.begin(); auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { + /// update rex_pool in order to delete existing loan remove_loan_from_rex_pool( *itr ); bool delete_loan = false; int64_t delta_stake = 0; + /// calculate rented tokens at current price int64_t rented_tokens = get_bancor_output( pool->total_rent.amount, pool->total_unlent.amount, itr->payment.amount ); - // conditions for loan renewal - bool renew_loan = itr->payment <= itr->balance // loan has sufficient balance - && itr->payment.amount < rented_tokens // loan has favorable return - && rex_loans_available(); // no pending sell orders + /// conditions for loan renewal + bool renew_loan = itr->payment <= itr->balance /// loan has sufficient balance + && itr->payment.amount < rented_tokens /// loan has favorable return + && rex_loans_available(); /// no pending sell orders if ( renew_loan ) { + /// update rex_pool in order to account for renewed loan add_loan_to_rex_pool( itr->payment, rented_tokens, false ); + /// update renewed loan fields delta_stake = update_renewed_loan( idx, itr, rented_tokens ); } else { delete_loan = true; @@ -767,12 +771,20 @@ namespace eosiosystem { } /** + * @brief Processes a sellrex order and returns object containing the results + * * Processes an incoming or already scheduled sellrex order. If REX pool has enough core * tokens not frozen in loans, order is filled. In this case, REX pool totals, user rex_balance * and user vote_stake are updated. However, this function does not update user voting power. The * function returns success flag, order proceeds, and vote stake delta. These are used later in a * different function to complete order processing, i.e. transfer proceeds to user REX fund and * update user vote weight. + * + * @param bitr - iterator pointing to rex_balance database record + * @param rex - amount of rex to be sold + * + * @return rex_order_outcome - a struct containing success flag, order proceeds, and resultant + * vote stake change */ rex_order_outcome system_contract::fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) { From 4b7ec27fbcfe6dedabb4935721ee26e699a1772b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 27 Feb 2019 11:24:54 -0500 Subject: [PATCH 0709/1048] Revert rex pool initial balance change, more tests --- contracts/eosio.system/src/rex.cpp | 2 +- tests/eosio.system_tests.cpp | 91 ++++++++++++++++-------------- 2 files changed, 49 insertions(+), 44 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 162efe60..4000245e 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -1040,7 +1040,7 @@ namespace eosiosystem { * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. */ const int64_t rex_ratio = 10000; - const asset init_total_rent( 1000 * 10000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available + const asset init_total_rent( 20'000'0000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available asset rex_received( 0, rex_symbol ); auto itr = _rexpool.begin(); if ( !rex_system_initialized() ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index bc36da62..720105e6 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3393,13 +3393,15 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("1000.0000"); + const asset init_rent = core_sym::from_string("20000.0000"); const asset init_balance = core_sym::from_string("1000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - BOOST_REQUIRE_EQUAL( asset::from_string("25000.0000 REX"), get_buyrex_result( alice, core_sym::from_string("2.5000") ) ); + const asset one_unit = core_sym::from_string("0.0001"); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), buyrex( alice, init_balance + one_unit ) ); + BOOST_REQUIRE_EQUAL( asset::from_string("25000.0000 REX"), get_buyrex_result( alice, core_sym::from_string("2.5000") ) ); produce_blocks(2); produce_block(fc::days(5)); BOOST_REQUIRE_EQUAL( core_sym::from_string("2.5000"), get_sellrex_result( alice, asset::from_string("25000.0000 REX") ) ); @@ -3454,13 +3456,12 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_small_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("100000.0000"); - const asset init_balance = core_sym::from_string("5000.0000"); + const asset init_balance = core_sym::from_string("50000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; setup_rex_accounts( accounts, init_balance ); - const asset payment = core_sym::from_string("2000.0000"); + const asset payment = core_sym::from_string("40000.0000"); BOOST_REQUIRE_EQUAL( ratio * payment.get_amount(), get_buyrex_result( alice, payment ).get_amount() ); produce_blocks(2); @@ -3602,7 +3603,7 @@ BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_tes BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); + const asset init_balance = core_sym::from_string("60000.0000"); const asset init_net = core_sym::from_string("70.0000"); const asset init_cpu = core_sym::from_string("90.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; @@ -3615,8 +3616,8 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { // bob tries to rent rex BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_sym::from_string("5.0000") ) ); // alice lends rex - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("5265.0000") ) ); - BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("5265.0000"), get_rex_fund(alice) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("50265.0000") ) ); + BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("50265.0000"), get_rex_fund(alice) ); auto rex_pool = get_rex_pool(); const asset init_tot_unlent = rex_pool["total_unlent"].as(); const asset init_tot_lendable = rex_pool["total_lendable"].as(); @@ -3672,7 +3673,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { { const int64_t init_net_limit = get_net_limit( emily ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("1050.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("20050.0000") ) ); rex_pool = get_rex_pool(); const asset fee = core_sym::from_string("0.4560"); int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), @@ -3688,7 +3689,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); + const asset init_balance = core_sym::from_string("40000.0000"); const asset init_net = core_sym::from_string("70.0000"); const asset init_cpu = core_sym::from_string("90.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; @@ -3699,7 +3700,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { const int64_t init_net_limit = get_net_limit( alice ); // alice lends rex - const asset payment = core_sym::from_string("3250.0000"); + const asset payment = core_sym::from_string("30250.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("0.0005") ) ); BOOST_REQUIRE_EQUAL( init_balance - payment, get_rex_fund(alice) ); @@ -3754,9 +3755,9 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - const auto purchase1 = core_sym::from_string("2500.0000"); - const auto purchase2 = core_sym::from_string("11775.0000"); - const auto purchase3 = core_sym::from_string("11725.0000"); + const auto purchase1 = core_sym::from_string("50000.0000"); + const auto purchase2 = core_sym::from_string("235500.0000"); + const auto purchase3 = core_sym::from_string("234500.0000"); const auto init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); @@ -3772,19 +3773,20 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { auto init_bob_rex = get_rex_balance(bob); auto init_carol_rex = get_rex_balance(carol); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_rex_pool()["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("20000.0000"), get_rex_pool()["total_rent"].as() ); for (uint8_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("1000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("20000.0000") ) ); } - const asset rent_payment = core_sym::from_string("2000.0000"); + const asset rent_payment = core_sym::from_string("40000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); const auto init_rex_pool = get_rex_pool(); - const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * init_rex_pool["total_lendable"].as().get_amount() ) - / init_rex_pool["total_rex"].as().get_amount(); + const int64_t total_lendable = init_rex_pool["total_lendable"].as().get_amount(); + const int64_t total_rex = init_rex_pool["total_rex"].as().get_amount(); + const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * total_lendable ) / total_rex; produce_block( fc::days(5) ); @@ -3877,7 +3879,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_sym::from_string("1100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_sym::from_string("22000.0000") ) ); BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); @@ -3890,12 +3892,13 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); + const asset init_balance = core_sym::from_string("40000.0000"); + const asset one_unit = core_sym::from_string("0.0001"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; setup_rex_accounts( accounts, init_balance ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("2500.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("25000.0000") ) ); auto rex_pool = get_rex_pool(); const asset payment = core_sym::from_string("30.0000"); @@ -3940,6 +3943,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { // frank funds his loan enough to be renewed once const asset fund = core_sym::from_string("35.0000"); + BOOST_REQUIRE_EQUAL( fundcpuloan( frank, 1, cur_frank_balance + one_unit), wasm_assert_msg("insufficient funds") ); BOOST_REQUIRE_EQUAL( fundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); BOOST_REQUIRE_EQUAL( fundcpuloan( alice, 1, fund ), wasm_assert_msg("user must be loan creator") ); BOOST_REQUIRE_EQUAL( success(), fundcpuloan( frank, 1, fund ) ); @@ -4016,13 +4020,13 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_loan_checks, eosio_system_tester ) try { const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("20000.0000"); + const asset init_balance = core_sym::from_string("40000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; account_name alice = accounts[0], bob = accounts[1]; setup_rex_accounts( accounts, init_balance ); - const asset payment1 = core_sym::from_string("1000.0000"); - const asset payment2 = core_sym::from_string("2.0000"); + const asset payment1 = core_sym::from_string("20000.0000"); + const asset payment2 = core_sym::from_string("4.0000"); const asset fee = core_sym::from_string("1.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("loan price does not favor renting"), @@ -4391,7 +4395,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { } { - const asset payment = core_sym::from_string("20000.0000"); + const asset payment = core_sym::from_string("40000.0000"); const int64_t rex_bucket_amount = rex_ratio * payment.get_amount(); const asset rex_bucket( rex_bucket_amount, rex_sym ); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); @@ -4464,20 +4468,20 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { - const asset init_balance = core_sym::from_string("10000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + const asset init_balance = core_sym::from_string("30000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; setup_rex_accounts( accounts, init_balance ); const int64_t init_stake = get_voter_info( alice )["staked"].as(); - const asset payment = core_sym::from_string("2500.0000"); + const asset payment = core_sym::from_string("25000.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); const asset fee = core_sym::from_string("50.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, fee ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, fee ) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_REQUIRE_EQUAL( payment + fee, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); @@ -4518,8 +4522,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); - const int64_t init_alice_rex_stake = ( init_rex.get_amount() * current_rex_pool["total_lendable"].as().get_amount() ) - / current_rex_pool["total_rex"].as().get_amount(); + const int64_t total_lendable = current_rex_pool["total_lendable"].as().get_amount(); + const int64_t total_rex = current_rex_pool["total_rex"].as().get_amount(); + const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_rex.get_amount()) * total_lendable ) / total_rex; produce_block( fc::days(5) ); const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); @@ -4559,15 +4564,15 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes } } - const asset init_balance = core_sym::from_string("10000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; + const asset init_balance = core_sym::from_string("30000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; + account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; setup_rex_accounts( accounts, init_balance ); const int64_t init_stake_amount = get_voter_info( alice )["staked"].as(); const asset init_stake( init_stake_amount, symbol{CORE_SYM} ); - const asset purchase = core_sym::from_string("2500.0000"); + const asset purchase = core_sym::from_string("25000.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase ) ); BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); @@ -4581,7 +4586,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const auto init_rex_pool = get_rex_pool(); const asset rent = core_sym::from_string("25.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, rent ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); const auto curr_rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( curr_rex_pool["total_lendable"].as(), init_rex_pool["total_lendable"].as() + rent ); BOOST_REQUIRE_EQUAL( success(), @@ -4596,12 +4601,12 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const asset to_net_stake = core_sym::from_string("60.0000"); const asset to_cpu_stake = core_sym::from_string("40.0000"); transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, rent ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, rent ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + rent) == @@ -4644,13 +4649,13 @@ BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { - const asset init_balance = core_sym::from_string("2500.0000"); + const asset init_balance = core_sym::from_string("25000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; account_name alice = accounts[0], bob = accounts[1]; setup_rex_accounts( accounts, init_balance ); const symbol rex_sym( SY(4, REX) ); - const asset payment = core_sym::from_string("2500.0000"); + const asset payment = core_sym::from_string("25000.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); const asset fee = core_sym::from_string("25.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); @@ -4675,7 +4680,7 @@ BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { - const asset init_balance = core_sym::from_string("2000.0000"); + const asset init_balance = core_sym::from_string("25000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; setup_rex_accounts( accounts, init_balance ); From 6337c0c17437d933d404b5ed247511002f394377 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 27 Feb 2019 18:08:38 -0500 Subject: [PATCH 0710/1048] Added setrex action, unit test --- .../include/eosio.system/eosio.system.hpp | 6 +++ contracts/eosio.system/src/eosio.system.cpp | 2 +- contracts/eosio.system/src/rex.cpp | 17 ++++++++ tests/eosio.system_tests.cpp | 40 +++++++++++++++++++ 4 files changed, 64 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 7028e3ec..bbbf1b04 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -371,6 +371,12 @@ namespace eosiosystem { void delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + /** + * Sets total_rent balance of REX pool to the passed value + */ + [[eosio::action]] + void setrex( const asset& balance ); + /** * Deposits core tokens to user REX fund. All proceeds and expenses related to REX are added to * or taken out of this fund. Inline token transfer from user balance is executed. diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 4328afc6..b8c3bba3 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -467,7 +467,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, (rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) - (defcpuloan)(defnetloan)(updaterex)(consolidate)(mvtosavings)(mvfrsavings)(rexexec)(closerex) + (defcpuloan)(defnetloan)(updaterex)(consolidate)(mvtosavings)(mvfrsavings)(setrex)(rexexec)(closerex) // delegate_bandwidth.cpp (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) // voting.cpp diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 4000245e..ef8d8be8 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -310,6 +310,23 @@ namespace eosiosystem { process_rex_maturities( itr ); } + /** + * @brief Sets total_rent balance of REX pool to the passed value + * + * @param balance - the value to which total_rent will be set + */ + void system_contract::setrex( const asset& balance ) + { + require_auth( "eosio"_n ); + + check( balance.amount > 0, "balance must be set to have a positive amount" ); + check( balance.symbol == core_symbol(), "balance symbol must be core symbol" ); + check( rex_system_initialized(), "rex system is not initialized" ); + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { + pool.total_rent = balance; + }); + } + /** * @brief Performs REX maintenance by processing a specified number of REX sell orders * and expired loans diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 720105e6..9f049911 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4753,6 +4753,46 @@ BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( set_rex, eosio_system_tester ) try { + + const asset init_balance = core_sym::from_string("25000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance ); + + const name act_name{ N(setrex) }; + const asset init_total_rent = core_sym::from_string("20000.0000"); + const asset set_total_rent = core_sym::from_string("10000.0000"); + const asset negative_balance = core_sym::from_string("-10000.0000"); + const asset different_symbol = asset::from_string("10000.0000 RND"); + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), + push_action( alice, act_name, mvo()("balance", set_total_rent) ) ); + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), + push_action( bob, act_name, mvo()("balance", set_total_rent) ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system is not initialized"), + push_action( config::system_account_name, act_name, mvo()("balance", set_total_rent) ) ); + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, init_balance ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("balance must be set to have a positive amount"), + push_action( config::system_account_name, act_name, mvo()("balance", negative_balance) ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("balance symbol must be core symbol"), + push_action( config::system_account_name, act_name, mvo()("balance", different_symbol) ) ); + const asset fee = core_sym::from_string("100.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + const auto& init_rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( init_total_rent + fee, init_rex_pool["total_rent"].as() ); + BOOST_TEST_REQUIRE( set_total_rent != init_rex_pool["total_rent"].as() ); + BOOST_REQUIRE_EQUAL( success(), + push_action( config::system_account_name, act_name, mvo()("balance", set_total_rent) ) ); + const auto& curr_rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( init_rex_pool["total_lendable"].as(), curr_rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( init_rex_pool["total_lent"].as(), curr_rex_pool["total_lent"].as() ); + BOOST_REQUIRE_EQUAL( init_rex_pool["total_unlent"].as(), curr_rex_pool["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( init_rex_pool["namebid_proceeds"].as(), curr_rex_pool["namebid_proceeds"].as() ); + BOOST_REQUIRE_EQUAL( init_rex_pool["loan_num"].as_uint64(), curr_rex_pool["loan_num"].as_uint64() ); + BOOST_REQUIRE_EQUAL( set_total_rent, curr_rex_pool["total_rent"].as() ); + +} FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_CASE( setabi_bios ) try { validating_tester t( validating_tester::default_config() ); abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); From 9c35ed224bf72d0a51cd069b2a251bda17660452 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 27 Feb 2019 19:26:28 -0500 Subject: [PATCH 0711/1048] Unit test for REX actions authorizations --- tests/eosio.system_tests.cpp | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 9f049911..d70b7433 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3390,6 +3390,42 @@ BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_auth, eosio_system_tester ) try { + + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + const account_name alice = accounts[0], bob = accounts[1]; + const asset init_balance = core_sym::from_string("1000.0000"); + const asset one_eos = core_sym::from_string("1.0000"); + const asset one_rex = asset::from_string("1.0000 REX"); + setup_rex_accounts( accounts, init_balance ); + + const std::string error_msg("missing authority of aliceaccount"); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(deposit), mvo()("owner", alice)("amount", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(withdraw), mvo()("owner", alice)("amount", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(buyrex), mvo()("from", alice)("amount", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), + push_action( bob, N(unstaketorex), mvo()("owner", alice)("receiver", alice)("from_net", one_eos)("from_cpu", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(sellrex), mvo()("from", alice)("rex", one_rex) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(cnclrexorder), mvo()("owner", alice) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), + push_action( bob, N(rentcpu), mvo()("from", alice)("receiver", alice)("loan_payment", one_eos)("loan_fund", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), + push_action( bob, N(rentnet), mvo()("from", alice)("receiver", alice)("loan_payment", one_eos)("loan_fund", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(fundcpuloan), mvo()("from", alice)("loan_num", 1)("payment", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(fundnetloan), mvo()("from", alice)("loan_num", 1)("payment", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(defcpuloan), mvo()("from", alice)("loan_num", 1)("amount", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(defnetloan), mvo()("from", alice)("loan_num", 1)("amount", one_eos) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(updaterex), mvo()("owner", alice) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(rexexec), mvo()("user", alice)("max", 1) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(consolidate), mvo()("owner", alice) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(mvtosavings), mvo()("owner", alice)("rex", one_rex) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(mvfrsavings), mvo()("owner", alice)("rex", one_rex) ) ); + BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(closerex), mvo()("owner", alice) ) ); + + BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), push_action( alice, N(setrex), mvo()("balance", one_eos) ) ); + +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; From e5f1fa39aa33fbb2f4159c8d283ecda049445649 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 1 Mar 2019 16:53:05 -0500 Subject: [PATCH 0712/1048] Action wrapper for setrex --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 1 + contracts/eosio.system/src/rex.cpp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index bbbf1b04..43b2c353 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -601,6 +601,7 @@ namespace eosiosystem { using defnetloan_action = eosio::action_wrapper<"defnetloan"_n, &system_contract::defnetloan>; using updaterex_action = eosio::action_wrapper<"updaterex"_n, &system_contract::updaterex>; using rexexec_action = eosio::action_wrapper<"rexexec"_n, &system_contract::rexexec>; + using setrex_action = eosio::action_wrapper<"setrex"_n, &system_contract::setrex>; using mvtosavings_action = eosio::action_wrapper<"mvtosavings"_n, &system_contract::mvtosavings>; using mvfrsavings_action = eosio::action_wrapper<"mvfrsavings"_n, &system_contract::mvfrsavings>; using consolidate_action = eosio::action_wrapper<"consolidate"_n, &system_contract::consolidate>; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index ef8d8be8..502c462d 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -551,8 +551,8 @@ namespace eosiosystem { } /** - * @brief Checks if account voting requirements (voting for a proxy or 21 producers) when - * buying REX + * @brief Checks if account satisfies voting requirement (voting for a proxy or 21 producers) + * for buying REX * * @param owner - account buying or already holding REX tokens * @err_msg - error message From fcd4da071f2e89b89e32c95004850b2dcdd3e55d Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Tue, 26 Feb 2019 11:21:46 -0500 Subject: [PATCH 0713/1048] adding ctest support --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5426805c..fafad4a4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,6 +74,9 @@ set(SECP256K1_ROOT "/usr/local") string(REPLACE ";" "|" TEST_FRAMEWORK_PATH "${CMAKE_FRAMEWORK_PATH}") string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") +include(CTest) +enable_testing() + ExternalProject_Add( contracts_unit_tests LIST_SEPARATOR | # Use the alternate list separator @@ -84,3 +87,6 @@ ExternalProject_Add( TEST_COMMAND "" INSTALL_COMMAND "" ) + +file( GLOB UNIT_TESTS "${CMAKE_SOURCE_DIR}/tests/*.cpp" ) +add_test( system_tests ${CMAKE_BINARY_DIR}/tests/unit_test ) From ae814f2fbe040fc2769cd2a402c5a2aa1e8e0fab Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 6 Mar 2019 18:17:54 -0500 Subject: [PATCH 0714/1048] bump version to v1.6.0-rc3 --- CMakeLists.txt | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5426805c..0121c2d2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 6) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc2) +set(VERSION_SUFFIX rc3) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 6c894b18..5bfacdf1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.6.0-rc2 +## Version : 1.6.0-rc3 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -14,7 +14,7 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.6.x](https://github.com/EOSIO/eos/releases/tag/v1.6.1) +* [eosio v1.6.x](https://github.com/EOSIO/eos/releases/tag/v1.6.3) * [eosio.cdt v1.5.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.5.0) To build the contracts and the unit tests: From a51f31f18dce34c9db20a382080c7d4a643c425b Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 7 Mar 2019 11:24:39 -0500 Subject: [PATCH 0715/1048] Added parameter expansion to downloadDependencies.sh --- docker/downloadDependencies.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/downloadDependencies.sh b/docker/downloadDependencies.sh index 67b677dd..e5249ff8 100755 --- a/docker/downloadDependencies.sh +++ b/docker/downloadDependencies.sh @@ -1,5 +1,6 @@ #!/bin/bash CONTRACTS_PATH='/eosio.contracts' # location in Docker container, not your local machine +CONTRACTS_PATH="${CONTRACTS_PATH/#\~/$HOME}" # perform parameter expansion for paths including '~' # get EOSIO echo "downloadDependencies.sh - Cloning EOSIO source from GitHub..." EOSIO_VERSION=$(cat $CONTRACTS_PATH/dependencies | sed 's,//,#,g' | cut -d '#' -f 1 | grep -v 'eos.*cdt.*=' | grep -v 'eos.*contracts.*=' | grep '.*eos.*=' | cut -d '=' -f 2 | awk '{print $1}') From 4e2dbc02e9d94412d54566b8ba901ccf6a40841c Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 7 Mar 2019 14:10:29 -0500 Subject: [PATCH 0716/1048] Added partial Dockerfiles used to dynamically build Dockerfile at runtime --- docker/environment.Dockerfile | 6 ++++++ docker/external-dependencies.Dockerfile | 4 ++++ 2 files changed, 10 insertions(+) create mode 100644 docker/environment.Dockerfile create mode 100644 docker/external-dependencies.Dockerfile diff --git a/docker/environment.Dockerfile b/docker/environment.Dockerfile new file mode 100644 index 00000000..bf5dbd25 --- /dev/null +++ b/docker/environment.Dockerfile @@ -0,0 +1,6 @@ +# set environment variables +RUN PATH=/usr/local/eosio/bin:$(echo "/usr/opt/eosio.cdt/$(ls /usr/opt/eosio.cdt)/bin"):$PATH +ENV EOSIO_ROOT=/usr/local/eosio +ENV LD_LIBRARY_PATH=/usr/local/lib +# add the entrypoint script +ENTRYPOINT ["/eosio.contracts/docker/buildContracts.sh"] \ No newline at end of file diff --git a/docker/external-dependencies.Dockerfile b/docker/external-dependencies.Dockerfile new file mode 100644 index 00000000..287448d6 --- /dev/null +++ b/docker/external-dependencies.Dockerfile @@ -0,0 +1,4 @@ +# install external dependencies +RUN apt-get update && \ +apt-get -y upgrade && \ +DEBIAN_FRONTEND=noninteractive apt-get -y install openssl ca-certificates build-essential libbz2-dev zlib1g-dev libssl-dev libgmp3-dev libicu-dev cmake bc jq curl wget net-tools unzip gnupg git graphviz awscli \ No newline at end of file From cadaf8d671bc6766573d4dfcade0033fd552d8b2 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Fri, 8 Mar 2019 10:01:04 -0500 Subject: [PATCH 0717/1048] Removed awscli from Docker image as the AWS S3 download is now performed by the Buildkite agent --- docker/external-dependencies.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/external-dependencies.Dockerfile b/docker/external-dependencies.Dockerfile index 287448d6..f2e27275 100644 --- a/docker/external-dependencies.Dockerfile +++ b/docker/external-dependencies.Dockerfile @@ -1,4 +1,4 @@ # install external dependencies RUN apt-get update && \ apt-get -y upgrade && \ -DEBIAN_FRONTEND=noninteractive apt-get -y install openssl ca-certificates build-essential libbz2-dev zlib1g-dev libssl-dev libgmp3-dev libicu-dev cmake bc jq curl wget net-tools unzip gnupg git graphviz awscli \ No newline at end of file +DEBIAN_FRONTEND=noninteractive apt-get -y install openssl ca-certificates build-essential libbz2-dev zlib1g-dev libssl-dev libgmp3-dev libicu-dev cmake bc jq curl wget net-tools unzip gnupg git graphviz \ No newline at end of file From bb13641e023061abf166cfd447dde1191cdc0047 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Fri, 8 Mar 2019 18:52:43 -0500 Subject: [PATCH 0718/1048] Added third partial Dockerfile for autogeneration, created script to verify correct installation of eosio in container and accept the container or reject it accordingly --- docker/entrypoint.Dockerfile | 2 ++ docker/environment.Dockerfile | 7 ++----- docker/verifyInstallation.sh | 11 +++++++++++ 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 docker/entrypoint.Dockerfile create mode 100755 docker/verifyInstallation.sh diff --git a/docker/entrypoint.Dockerfile b/docker/entrypoint.Dockerfile new file mode 100644 index 00000000..fe2fd75f --- /dev/null +++ b/docker/entrypoint.Dockerfile @@ -0,0 +1,2 @@ +# add the entrypoint script +ENTRYPOINT ["/eosio.contracts/docker/buildContracts.sh"] \ No newline at end of file diff --git a/docker/environment.Dockerfile b/docker/environment.Dockerfile index bf5dbd25..cde89d50 100644 --- a/docker/environment.Dockerfile +++ b/docker/environment.Dockerfile @@ -1,6 +1,3 @@ -# set environment variables +# set environment variables (EOSIO_ROOT and CMAKE_FRAMEWORK_PATH are autogenerated) RUN PATH=/usr/local/eosio/bin:$(echo "/usr/opt/eosio.cdt/$(ls /usr/opt/eosio.cdt)/bin"):$PATH -ENV EOSIO_ROOT=/usr/local/eosio -ENV LD_LIBRARY_PATH=/usr/local/lib -# add the entrypoint script -ENTRYPOINT ["/eosio.contracts/docker/buildContracts.sh"] \ No newline at end of file +ENV LD_LIBRARY_PATH=/usr/local/lib \ No newline at end of file diff --git a/docker/verifyInstallation.sh b/docker/verifyInstallation.sh new file mode 100755 index 00000000..37fcb529 --- /dev/null +++ b/docker/verifyInstallation.sh @@ -0,0 +1,11 @@ +#!/bin/bash +# expected places to find EOSIO CMAKE in the docker container, in ascending order of preference +[[ -e /usr/lib/eosio/lib/cmake/eosio/eosio-config.cmake ]] && export CMAKE_FRAMEWORK_PATH="/usr/lib/eosio" +[[ -e /opt/eosio/lib/cmake/eosio/eosio-config.cmake ]] && export CMAKE_FRAMEWORK_PATH="/opt/eosio" +[[ ! -z "$EOSIO_ROOT" && -e $EOSIO_ROOT/lib/cmake/eosio/eosio-config.cmake ]] && export CMAKE_FRAMEWORK_PATH="$EOSIO_ROOT" +# fail if we didn't find it +[[ -z "$CMAKE_FRAMEWORK_PATH" ]] && exit 1 +# export variables +echo "" >> /eosio.contracts/docker/environment.Dockerfile # necessary if there is no '\n' at end of file +echo "ENV CMAKE_FRAMEWORK_PATH=$CMAKE_FRAMEWORK_PATH" >> /eosio.contracts/docker/environment.Dockerfile +echo "ENV EOSIO_ROOT=$CMAKE_FRAMEWORK_PATH" >> /eosio.contracts/docker/environment.Dockerfile \ No newline at end of file From 9486da3e259383ee70f1a9df01a9b40f263d7931 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 11 Mar 2019 15:28:40 -0400 Subject: [PATCH 0719/1048] Changed name of partial dockerfile(s) to appease linters --- docker/entrypoint.Dockerfile | 2 -- docker/{environment.Dockerfile => environment.dockerpart} | 0 ...dependencies.Dockerfile => external-dependencies.dockerpart} | 0 3 files changed, 2 deletions(-) delete mode 100644 docker/entrypoint.Dockerfile rename docker/{environment.Dockerfile => environment.dockerpart} (100%) rename docker/{external-dependencies.Dockerfile => external-dependencies.dockerpart} (100%) diff --git a/docker/entrypoint.Dockerfile b/docker/entrypoint.Dockerfile deleted file mode 100644 index fe2fd75f..00000000 --- a/docker/entrypoint.Dockerfile +++ /dev/null @@ -1,2 +0,0 @@ -# add the entrypoint script -ENTRYPOINT ["/eosio.contracts/docker/buildContracts.sh"] \ No newline at end of file diff --git a/docker/environment.Dockerfile b/docker/environment.dockerpart similarity index 100% rename from docker/environment.Dockerfile rename to docker/environment.dockerpart diff --git a/docker/external-dependencies.Dockerfile b/docker/external-dependencies.dockerpart similarity index 100% rename from docker/external-dependencies.Dockerfile rename to docker/external-dependencies.dockerpart From ce78fc0fe3eab24c13e2978cca8b7c4dc0a8e8de Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 11 Mar 2019 15:42:27 -0400 Subject: [PATCH 0720/1048] Fixed unregistered_producer_voting unit test, small optimizations --- contracts/eosio.system/src/voting.cpp | 9 ++++++--- tests/eosio.system_tests.cpp | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 4defa966..caf38b93 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -277,8 +277,9 @@ namespace eosiosystem { for( const auto& pd : producer_deltas ) { auto pitr = _producers.find( pd.first.value ); if( pitr != _producers.end() ) { - check( !voting || pitr->active() || !pd.second.second /* not from new set */, - ( "producer " + pitr->owner.to_string() + " is not currently registered" ).data() ); + if( voting && !pitr->active() && pd.second.second /* from new set */ ) { + check( false, ( "producer " + pitr->owner.to_string() + " is not currently registered" ).data() ); + } double init_total_votes = pitr->total_votes; _producers.modify( pitr, same_payer, [&]( auto& p ) { p.total_votes += pd.second.first; @@ -309,7 +310,9 @@ namespace eosiosystem { } } } else { - check( !pd.second.second /* not from new set */, "producer is not registered" ); //data corruption + if( pd.second.second ) { + check( false, ( "producer " + pd.first.to_string() + " is not registered" ).data() ); + } } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d70b7433..9c638921 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -846,7 +846,7 @@ BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * bo REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer is not registered" ), + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer alice1111111 is not registered" ), vote( N(bob111111111), { N(alice1111111) } ) ); //alice1111111 registers as a producer @@ -869,7 +869,7 @@ BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * bo BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(prod["producer_key"].as_string()) ); //bob111111111 should not be able to vote for alice1111111 who is an unregistered producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer is not currently registered" ), + BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer alice1111111 is not currently registered" ), vote( N(bob111111111), { N(alice1111111) } ) ); } FC_LOG_AND_RETHROW() From 5dd56d731fd87958f87c748fe7cad24bbbb28661 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 11 Mar 2019 17:37:17 -0400 Subject: [PATCH 0721/1048] Added unit test script run by Docker --- docker/unit-test.sh | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 docker/unit-test.sh diff --git a/docker/unit-test.sh b/docker/unit-test.sh new file mode 100644 index 00000000..a764a7b9 --- /dev/null +++ b/docker/unit-test.sh @@ -0,0 +1,4 @@ +#!/bin/bash +set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) +cd /eosio.contracts/build +ctest -j8 --output-on-failure \ No newline at end of file From f2c439d2687a7137a7caf9382db2e65fa2b96b8c Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 11 Mar 2019 18:35:12 -0400 Subject: [PATCH 0722/1048] Fixed permissions on unit-test.sh --- docker/unit-test.sh | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 docker/unit-test.sh diff --git a/docker/unit-test.sh b/docker/unit-test.sh old mode 100644 new mode 100755 From 288f063477e111e6f55245a19a00a31a6d9c9f09 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 11 Mar 2019 18:43:23 -0400 Subject: [PATCH 0723/1048] Parallelized Unit Tests --- tests/CMakeLists.txt | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4660381a..71f98721 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -28,6 +28,16 @@ configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contract include_directories(${CMAKE_BINARY_DIR}) -file(GLOB UNIT_TESTS "*.cpp" "*.hpp") - -add_eosio_test( unit_test ${UNIT_TESTS} ) +### BUILD UNIT TEST EXECUTABLE ### +file(GLOB UNIT_TESTS "*.cpp" "*.hpp") # find all unit test suites +add_executable( unit_test ${UNIT_TESTS}) # build unit tests as one executable + +### MARK TEST SUITES FOR EXECUTION ### +foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test suite + execute_process(COMMAND bash -c "grep -E 'BOOST_AUTO_TEST_SUITE\\s*[(]' ${TEST_SUITE} | grep -vE '//.*BOOST_AUTO_TEST_SUITE\\s*[(]' | cut -d ')' -f 1 | cut -d '(' -f 2" OUTPUT_VARIABLE SUITE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE) # get the test suite name from the *.cpp file + if (NOT "" STREQUAL "${SUITE_NAME}") # ignore empty lines + execute_process(COMMAND bash -c "echo ${SUITE_NAME} | sed -e 's/s$//' | sed -e 's/_test$//'" OUTPUT_VARIABLE TRIMMED_SUITE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE) # trim "_test" or "_tests" from the end of ${SUITE_NAME} + # to run unit_test with all log from blockchain displayed, put "--verbose" after "--", i.e. "unit_test -- --verbose" + add_test(NAME ${TRIMMED_SUITE_NAME}_unit_test COMMAND unit_test --run_test=${SUITE_NAME} --report_level=detailed --color_output) + endif() +endforeach(TEST_SUITE) \ No newline at end of file From a4943fd5044ee16010b71ea1ea5aed6e78facca3 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 11 Mar 2019 19:16:25 -0400 Subject: [PATCH 0724/1048] Fixed copy-pasta error --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 71f98721..421e2c1f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -30,7 +30,7 @@ include_directories(${CMAKE_BINARY_DIR}) ### BUILD UNIT TEST EXECUTABLE ### file(GLOB UNIT_TESTS "*.cpp" "*.hpp") # find all unit test suites -add_executable( unit_test ${UNIT_TESTS}) # build unit tests as one executable +add_eosio_test(unit_test ${UNIT_TESTS}) # build unit tests as one executable ### MARK TEST SUITES FOR EXECUTION ### foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test suite From dc97e4d2e59f8d3f6378ff25a0ce294b2056ed33 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ba=C5=9Farcan=20Celebci?= Date: Mon, 25 Feb 2019 23:11:07 +0300 Subject: [PATCH 0725/1048] old unused producer pay vars updated --- contracts/eosio.system/src/producer_pay.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 83f6a120..af015e20 100755 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -7,8 +7,8 @@ namespace eosiosystem { const int64_t min_pervote_daily_pay = 100'0000; const int64_t min_activated_stake = 150'000'000'0000; const double continuous_rate = 0.04879; // 5% annual rate - const double perblock_rate = 0.0025; // 0.25% - const double standby_rate = 0.0075; // 0.75% + const double producer_rate = 0.20; // 20% of the inflation + const double standby_rate = 0.25; // 0.25% of the producer pay const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year const uint32_t seconds_per_year = 52*7*24*3600; const uint32_t blocks_per_day = 2 * 24 * 3600; @@ -94,9 +94,9 @@ namespace eosiosystem { if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { auto new_tokens = static_cast( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); - auto to_producers = new_tokens / 5; + auto to_producers = new_tokens * producer_rate; auto to_savings = new_tokens - to_producers; - auto to_per_block_pay = to_producers / 4; + auto to_per_block_pay = to_producers * standby_rate; auto to_per_vote_pay = to_producers - to_per_block_pay; INLINE_ACTION_SENDER(eosio::token, issue)( From 0668762393cafb1ee69f8b4385899578a5678dd7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 11 Mar 2019 18:59:56 -0400 Subject: [PATCH 0726/1048] Change variable types in producer pay from double to int64_t --- contracts/eosio.system/src/producer_pay.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index af015e20..c917adf0 100755 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -7,8 +7,8 @@ namespace eosiosystem { const int64_t min_pervote_daily_pay = 100'0000; const int64_t min_activated_stake = 150'000'000'0000; const double continuous_rate = 0.04879; // 5% annual rate - const double producer_rate = 0.20; // 20% of the inflation - const double standby_rate = 0.25; // 0.25% of the producer pay + const int64_t inflation_pay_factor = 5; // 20% of the inflation + const int64_t votepay_factor = 4; // 0.25% of the producer pay const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year const uint32_t seconds_per_year = 52*7*24*3600; const uint32_t blocks_per_day = 2 * 24 * 3600; @@ -94,9 +94,9 @@ namespace eosiosystem { if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { auto new_tokens = static_cast( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); - auto to_producers = new_tokens * producer_rate; + auto to_producers = new_tokens / inflation_pay_factor; auto to_savings = new_tokens - to_producers; - auto to_per_block_pay = to_producers * standby_rate; + auto to_per_block_pay = to_producers / votepay_factor; auto to_per_vote_pay = to_producers - to_per_block_pay; INLINE_ACTION_SENDER(eosio::token, issue)( From 190b721f08ce81d5a1201f52820c20fac6270be7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 11 Mar 2019 19:03:55 -0400 Subject: [PATCH 0727/1048] Small change in comments --- contracts/eosio.system/src/producer_pay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index c917adf0..05df265a 100755 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -8,7 +8,7 @@ namespace eosiosystem { const int64_t min_activated_stake = 150'000'000'0000; const double continuous_rate = 0.04879; // 5% annual rate const int64_t inflation_pay_factor = 5; // 20% of the inflation - const int64_t votepay_factor = 4; // 0.25% of the producer pay + const int64_t votepay_factor = 4; // 25% of the producer pay const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year const uint32_t seconds_per_year = 52*7*24*3600; const uint32_t blocks_per_day = 2 * 24 * 3600; From c2bcb9a7e2cfff19d5fd8f5010d979aef2c8fda7 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 11 Mar 2019 20:05:43 -0400 Subject: [PATCH 0728/1048] Removed duplicate ctest registration and fixed calling path in unit-test.sh --- CMakeLists.txt | 8 +------- docker/unit-test.sh | 2 +- tests/CMakeLists.txt | 5 +---- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fafad4a4..d6c09f9b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -74,9 +74,6 @@ set(SECP256K1_ROOT "/usr/local") string(REPLACE ";" "|" TEST_FRAMEWORK_PATH "${CMAKE_FRAMEWORK_PATH}") string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") -include(CTest) -enable_testing() - ExternalProject_Add( contracts_unit_tests LIST_SEPARATOR | # Use the alternate list separator @@ -86,7 +83,4 @@ ExternalProject_Add( BUILD_ALWAYS 1 TEST_COMMAND "" INSTALL_COMMAND "" -) - -file( GLOB UNIT_TESTS "${CMAKE_SOURCE_DIR}/tests/*.cpp" ) -add_test( system_tests ${CMAKE_BINARY_DIR}/tests/unit_test ) +) \ No newline at end of file diff --git a/docker/unit-test.sh b/docker/unit-test.sh index a764a7b9..e13ca5c2 100755 --- a/docker/unit-test.sh +++ b/docker/unit-test.sh @@ -1,4 +1,4 @@ #!/bin/bash set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) -cd /eosio.contracts/build +cd /eosio.contracts/build/tests ctest -j8 --output-on-failure \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 421e2c1f..a0846ecf 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -21,17 +21,14 @@ else() # INVALID OR MISMATCH message(FATAL_ERROR "Found eosio version ${EOSIO_VERSION} but it does not satisfy version requirements: ${VERSION_MATCH_ERROR_MSG}\nPlease use eosio version ${EOSIO_VERSION_SOFT_MAX}.x") endif(VERSION_OUTPUT STREQUAL "MATCH") - -enable_testing() - configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contracts.hpp) include_directories(${CMAKE_BINARY_DIR}) +enable_testing() ### BUILD UNIT TEST EXECUTABLE ### file(GLOB UNIT_TESTS "*.cpp" "*.hpp") # find all unit test suites add_eosio_test(unit_test ${UNIT_TESTS}) # build unit tests as one executable - ### MARK TEST SUITES FOR EXECUTION ### foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test suite execute_process(COMMAND bash -c "grep -E 'BOOST_AUTO_TEST_SUITE\\s*[(]' ${TEST_SUITE} | grep -vE '//.*BOOST_AUTO_TEST_SUITE\\s*[(]' | cut -d ')' -f 1 | cut -d '(' -f 2" OUTPUT_VARIABLE SUITE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE) # get the test suite name from the *.cpp file From a5e1a5e62da3544ab1c83edafd2b70b7414fcacc Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 18 Mar 2019 11:58:01 -0400 Subject: [PATCH 0729/1048] Added xUnit-formatted XML test result output; parallelization now scales across cores --- docker/unit-test.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/docker/unit-test.sh b/docker/unit-test.sh index e13ca5c2..20d7067e 100755 --- a/docker/unit-test.sh +++ b/docker/unit-test.sh @@ -1,4 +1,8 @@ #!/bin/bash set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) +CPU_CORES=$(getconf _NPROCESSORS_ONLN) +echo "$CPU_CORES cpu cores detected." cd /eosio.contracts/build/tests -ctest -j8 --output-on-failure \ No newline at end of file +echo "$ ctest -j $CPU_CORES --output-on-failure -T Test" +ctest -j $CPU_CORES --output-on-failure -T Test +mv /eosio.contracts/build/tests/Testing/$(ls /eosio.contracts/build/tests/Testing/ | grep '20' | tail -n 1)/Test.xml /artifacts/Test.xml \ No newline at end of file From a7f7557fd3124bb9f26848e4d64328108f90d9bd Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 18 Mar 2019 12:36:55 -0400 Subject: [PATCH 0730/1048] Added 'include(ctest)' to CMakeLists.txt to suppress DartConfiguration.tcl errors at test runtime --- tests/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a0846ecf..57cdfc55 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -24,12 +24,13 @@ endif(VERSION_OUTPUT STREQUAL "MATCH") configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contracts.hpp) include_directories(${CMAKE_BINARY_DIR}) - +### UNIT TESTING ### +include(ctest) # eliminates DartConfiguration.tcl errors at test runtime enable_testing() -### BUILD UNIT TEST EXECUTABLE ### +# build unit test executable file(GLOB UNIT_TESTS "*.cpp" "*.hpp") # find all unit test suites add_eosio_test(unit_test ${UNIT_TESTS}) # build unit tests as one executable -### MARK TEST SUITES FOR EXECUTION ### +# mark test suites for execution foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test suite execute_process(COMMAND bash -c "grep -E 'BOOST_AUTO_TEST_SUITE\\s*[(]' ${TEST_SUITE} | grep -vE '//.*BOOST_AUTO_TEST_SUITE\\s*[(]' | cut -d ')' -f 1 | cut -d '(' -f 2" OUTPUT_VARIABLE SUITE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE) # get the test suite name from the *.cpp file if (NOT "" STREQUAL "${SUITE_NAME}") # ignore empty lines From f352d27e5ad5a289a924b100a165dc208568d15a Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 18 Mar 2019 13:52:34 -0400 Subject: [PATCH 0731/1048] Incumbent contracts pipeline base image has changed. --- docker/Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/Dockerfile b/docker/Dockerfile index cf59a029..83d6ea78 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,4 +1,4 @@ -FROM gcr.io/b1-automation-dev/eosio/builder:develop as builder +FROM gcr.io/b1-automation-dev/eosio/builder:latest as builder # import build-time arguments ARG CONTRACTS_COMMIT ARG CONTRACTS_BRANCH From d197b62af8aa8333dadf3bed5623fbb3f228a9a7 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 18 Mar 2019 14:52:45 -0400 Subject: [PATCH 0732/1048] Added code to check that ctest has non-zero registered tests --- docker/unit-test.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docker/unit-test.sh b/docker/unit-test.sh index 20d7067e..25d98b64 100755 --- a/docker/unit-test.sh +++ b/docker/unit-test.sh @@ -3,6 +3,8 @@ set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) CPU_CORES=$(getconf _NPROCESSORS_ONLN) echo "$CPU_CORES cpu cores detected." cd /eosio.contracts/build/tests +TEST_COUNT=$(ctest -N | grep -i 'Total Tests: ' | cut -d ':' -f 2 | awk '{print $1}') +[[ $TEST_COUNT > 0 ]] && echo "$TEST_COUNT tests found." || (echo "ERROR: No tests registered with ctest! Exiting..." && exit 1) echo "$ ctest -j $CPU_CORES --output-on-failure -T Test" ctest -j $CPU_CORES --output-on-failure -T Test mv /eosio.contracts/build/tests/Testing/$(ls /eosio.contracts/build/tests/Testing/ | grep '20' | tail -n 1)/Test.xml /artifacts/Test.xml \ No newline at end of file From b73cd459e0a511de78731b5e3678e1f426f00e4c Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 18 Mar 2019 15:07:03 -0400 Subject: [PATCH 0733/1048] One more attempt at include(CTest) --- tests/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 57cdfc55..fa03d582 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -25,7 +25,7 @@ configure_file(${CMAKE_SOURCE_DIR}/contracts.hpp.in ${CMAKE_BINARY_DIR}/contract include_directories(${CMAKE_BINARY_DIR}) ### UNIT TESTING ### -include(ctest) # eliminates DartConfiguration.tcl errors at test runtime +include(CTest) # eliminates DartConfiguration.tcl errors at test runtime enable_testing() # build unit test executable file(GLOB UNIT_TESTS "*.cpp" "*.hpp") # find all unit test suites From 9d56a29972aee6a6ec396c3e10187beed539e1ad Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 18 Mar 2019 17:20:39 -0400 Subject: [PATCH 0734/1048] Use action wrappers for inline actions in REX --- contracts/eosio.system/src/rex.cpp | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 502c462d..0f6fdb5b 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -19,8 +19,11 @@ namespace eosiosystem { check( amount.symbol == core_symbol(), "must deposit core token" ); check( 0 < amount.amount, "must deposit a positive amount" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { owner, active_permission }, - { owner, rex_account, amount, "deposit to REX fund" } ); + // inline transfer from owner's token balance + { + token::transfer_action transfer_act{ token_account, { owner, active_permission } }; + transfer_act.send( owner, rex_account, amount, "deposit to REX fund" ); + } transfer_to_fund( owner, amount ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } @@ -39,8 +42,11 @@ namespace eosiosystem { check( 0 < amount.amount, "must withdraw a positive amount" ); update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( owner, amount ); - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { rex_account, active_permission }, - { rex_account, owner, amount, "withdraw from REX fund" } ); + // inline transfer to owner's token balance + { + token::transfer_action transfer_act{ token_account, { rex_account, active_permission } }; + transfer_act.send( rex_account, owner, amount, "withdraw from REX fund" ); + } } /** @@ -100,8 +106,11 @@ namespace eosiosystem { update_resource_limits( name(0), receiver, -from_net.amount, -from_cpu.amount ); const asset payment = from_net + from_cpu; - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { stake_account, active_permission }, - { stake_account, rex_account, payment, "buy REX with staked tokens" } ); + // inline transfer from stake_account to rex_account + { + token::transfer_action transfer_act{ token_account, { stake_account, active_permission } }; + transfer_act.send( stake_account, rex_account, payment, "buy REX with staked tokens" ); + } const asset rex_received = add_to_rex_pool( payment ); add_to_rex_balance( owner, payment, rex_received ); runrex(2); @@ -961,9 +970,10 @@ namespace eosiosystem { rp.total_unlent.amount += amount.amount; rp.total_lendable.amount += amount.amount; }); - - INLINE_ACTION_SENDER(eosio::token, transfer)( token_account, { from, active_permission }, - { from, rex_account, amount, std::string("transfer from ") + name{from}.to_string() + " to eosio.rex"} ); + // inline transfer to rex_account + token::transfer_action transfer_act{ token_account, { from, active_permission } }; + transfer_act.send( from, rex_account, amount, + std::string("transfer from ") + from.to_string() + " to eosio.rex" ); } #endif } From d0ba55d997bbcbf822ecfc47b0d53e6d15196679 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 18 Mar 2019 18:56:30 -0400 Subject: [PATCH 0735/1048] Add inline dummy actions to rentcpu and rentnet, tests --- .../include/eosio.system/rex.results.hpp | 17 +++++--- contracts/eosio.system/src/rex.cpp | 2 + contracts/eosio.system/src/rex.results.cpp | 2 + tests/eosio.system_tester.hpp | 41 ++++++++++++++++--- tests/eosio.system_tests.cpp | 25 +++++++---- 5 files changed, 68 insertions(+), 19 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index 4ca11962..a129e56c 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -6,19 +6,24 @@ using eosio::name; using eosio::asset; +using eosio::action_wrapper; class [[eosio::contract("rex.results")]] rex_results { public: [[eosio::action]] void buyresult( const asset& rex_received ); - + [[eosio::action]] void sellresult( const asset& proceeds ); - + [[eosio::action]] void orderresult( const name& owner, const asset& proceeds ); - - using buyresult_action = eosio::action_wrapper<"buyresult"_n, &rex_results::buyresult>; - using sellresult_action = eosio::action_wrapper<"sellresult"_n, &rex_results::sellresult>; - using orderresult_action = eosio::action_wrapper<"orderresult"_n, &rex_results::orderresult>; + + [[eosio::action]] + void rentresult( const asset& rented_tokens ); + + using buyresult_action = action_wrapper<"buyresult"_n, &rex_results::buyresult>; + using sellresult_action = action_wrapper<"sellresult"_n, &rex_results::sellresult>; + using orderresult_action = action_wrapper<"orderresult"_n, &rex_results::orderresult>; + using rentresult_action = action_wrapper<"rentresult"_n, &rex_results::rentresult>; }; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 0f6fdb5b..4d0d72c0 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -793,6 +793,8 @@ namespace eosiosystem { c.loan_num = pool->loan_num; }); + rex_results::rentresult_action rentresult_act{ rex_account, std::vector{ } }; + rentresult_act.send( asset{ rented_tokens, core_symbol() } ); return rented_tokens; } diff --git a/contracts/eosio.system/src/rex.results.cpp b/contracts/eosio.system/src/rex.results.cpp index 5db7ffe2..1aabca02 100644 --- a/contracts/eosio.system/src/rex.results.cpp +++ b/contracts/eosio.system/src/rex.results.cpp @@ -6,4 +6,6 @@ void rex_results::sellresult( const asset& proceeds ) { } void rex_results::orderresult( const name& owner, const asset& proceeds ) { } +void rex_results::rentresult( const asset& rented_tokens ) { } + extern "C" void apply( uint64_t, uint64_t, uint64_t ) { } diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index cadbf7d8..0af1b9e0 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -349,7 +349,7 @@ class eosio_system_tester : public TESTER { } asset get_buyrex_result( const account_name& from, const asset& amount ) { - auto trace = base_tester::push_action( N(eosio), N(buyrex), from, mvo()("from", from)("amount", amount) ); + auto trace = base_tester::push_action( config::system_account_name, N(buyrex), from, mvo()("from", from)("amount", amount) ); asset rex_received; for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { @@ -362,7 +362,7 @@ class eosio_system_tester : public TESTER { } } return rex_received; - } + } action_result unstaketorex( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { return push_action( name(owner), N(unstaketorex), mvo() @@ -374,7 +374,7 @@ class eosio_system_tester : public TESTER { } asset get_unstaketorex_result( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { - auto trace = base_tester::push_action( N(eosio), N(unstaketorex), owner, mvo() + auto trace = base_tester::push_action( config::system_account_name, N(unstaketorex), owner, mvo() ("owner", owner) ("receiver", receiver) ("from_net", from_net) @@ -402,7 +402,7 @@ class eosio_system_tester : public TESTER { } asset get_sellrex_result( const account_name& from, const asset& rex ) { - auto trace = base_tester::push_action( N(eosio), N(sellrex), from, mvo()("from", from)("rex", rex) ); + auto trace = base_tester::push_action( config::system_account_name, N(sellrex), from, mvo()("from", from)("rex", rex) ); asset proceeds; for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { @@ -416,7 +416,7 @@ class eosio_system_tester : public TESTER { } return proceeds; } - + auto get_rexorder_result( const transaction_trace_ptr& trace ) { std::vector> output; for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { @@ -455,6 +455,37 @@ class eosio_system_tester : public TESTER { ); } + asset _get_rentrex_result( const account_name& from, const account_name& receiver, const asset& payment, bool cpu ) { + const name act = cpu ? N(rentcpu) : N(rentnet); + auto trace = base_tester::push_action( config::system_account_name, act, from, mvo() + ("from", from) + ("receiver", receiver) + ("loan_payment", payment) + ("loan_fund", core_sym::from_string("0.0000") ) + ); + + asset rented_tokens = core_sym::from_string("0.0000"); + for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { + for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { + if ( trace->action_traces[i].inline_traces[j].act.name == N(rentresult) ) { + fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), + trace->action_traces[i].inline_traces[j].act.data.size(), + rented_tokens ); + return rented_tokens; + } + } + } + return rented_tokens; + } + + asset get_rentcpu_result( const account_name& from, const account_name& receiver, const asset& payment ) { + return _get_rentrex_result( from, receiver, payment, true ); + } + + asset get_rentnet_result( const account_name& from, const account_name& receiver, const asset& payment ) { + return _get_rentrex_result( from, receiver, payment, false ); + } + action_result fundcpuloan( const account_name& from, const uint64_t loan_num, const asset& payment ) { return push_action( name(from), N(fundcpuloan), mvo() ("from", from) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d70b7433..af1d8507 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3958,14 +3958,23 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), rentcpu( frank, bob, neg_asset, payment ) ); // create 2 cpu and 3 net loans - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, bob, payment ) ); // loan_num = 1 - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment ) ); // loan_num = 2 - BOOST_REQUIRE_EQUAL( 2, get_last_cpu_loan()["loan_num"].as_uint64() ); - - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, emily, payment ) ); // loan_num = 3 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, alice, payment ) ); // loan_num = 4 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, frank, payment ) ); // loan_num = 5 - BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); + const asset rented_tokens{ expected_stake, symbol{CORE_SYM} }; + BOOST_REQUIRE_EQUAL( rented_tokens, get_rentcpu_result( frank, bob, payment ) ); // loan_num = 1 + BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment ) ); // loan_num = 2 + BOOST_REQUIRE_EQUAL( 2, get_last_cpu_loan()["loan_num"].as_uint64() ); + + asset expected_rented_net; + { + const auto& pool = get_rex_pool(); + const int64_t r = bancor_convert( pool["total_rent"].as().get_amount(), + pool["total_unlent"].as().get_amount(), + payment.get_amount() ); + expected_rented_net = asset{ r, symbol{CORE_SYM} }; + } + BOOST_REQUIRE_EQUAL( expected_rented_net, get_rentnet_result( alice, emily, payment ) ); // loan_num = 3 + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, alice, payment ) ); // loan_num = 4 + BOOST_REQUIRE_EQUAL( success(), rentnet( alice, frank, payment ) ); // loan_num = 5 + BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); auto loan_info = get_cpu_loan(1); auto old_frank_balance = cur_frank_balance; From e9244200b582841c357233ff7fbad90695f116bb Mon Sep 17 00:00:00 2001 From: ovi Date: Tue, 8 Jan 2019 00:07:18 +0200 Subject: [PATCH 0736/1048] Annotate all public EOSIO system contracts classes, structs, methods, actions. annotate the eosio.wrap and half of the eosio.msig Finish annotating the eosio.msig contract group all eosio.contracts using the 'module' grouping method continue annotation spree for the eosio.contracts correction on regproducer action annotation first round of annotations for eosio.contracts there's still a couple TO DOs to address. Minor correction on the TO DOs Address the TO DOs for native action handlers and references to outside documentation. corrections on @pre and @params annotations. Improve system_contract ctor params annotations. get rid of the root group, not needed. fix the eosio.system.hpp annotations after merging from upstream/release/1.6.x fix eosio.system_tests.cpp after mergin upstream/release/1.6.x fix voting.cpp after merging from upstream/release/1.6.x fix eosio.system/README.md after merging from upstream/develop branch Annotate REX and clean the README.md files, rename them and moved them to root docs folder; clean the redundant content from them (found in code annotations as well). small improvement. clean redundant/duplicated annotations from cpp, they are all found in hpp file. add eosio.bios reference as well in the root README.md small correction on the order of the system contracts list, to be the same as in other places -- consistency. corrections after rebase fix system tests cpp after rebase remove README.md eosio.wrap, it is present in root/docs remove README.md eosio.system, it is redundant with the annotations from source code Fix typo in annotation fix eosio.system.hpp after rebase fix typos in annotations annotate missed REX structures clean up TO DO Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix typo Co-Authored-By: iamveritas Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix punctuation. Co-Authored-By: iamveritas Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix punctuation. Co-Authored-By: iamveritas Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp fix punctuation. Co-Authored-By: iamveritas Update contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp Fix typo. Co-Authored-By: iamveritas Update contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp Fix typo. Co-Authored-By: iamveritas Update contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp Fix typo. Co-Authored-By: iamveritas Update contracts/eosio.msig/src/eosio.msig.cpp Fix typo. Co-Authored-By: iamveritas Update contracts/eosio.msig/src/eosio.msig.cpp Fix typo. Co-Authored-By: iamveritas Update contracts/eosio.token/include/eosio.token/eosio.token.hpp Fix typo. Co-Authored-By: iamveritas Update contracts/eosio.system/include/eosio.system/native.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.token/include/eosio.token/eosio.token.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.token/include/eosio.token/eosio.token.hpp fix typo. Co-Authored-By: iamveritas Update contracts/eosio.token/include/eosio.token/eosio.token.hpp fix typo. Co-Authored-By: iamveritas Update docs/eosio.msig.md fix typo. Co-Authored-By: iamveritas Apply suggestions from code review fix typo. Co-Authored-By: iamveritas Better description for eosio.bios system contract. Correct the annotation for get_supply and get_balance methods. cosmetic changes in annotations clean redundant annotations from cpp, they are the same in hpp file. Move annotation from rex.cpp to eosio.system.hpp for public actions Address PR comments/review from @zorba80 --- README.md | 3 +- .../include/eosio.bios/eosio.bios.hpp | 239 +++++- contracts/eosio.msig/README.md | 113 --- .../include/eosio.msig/eosio.msig.hpp | 96 ++- contracts/eosio.msig/src/eosio.msig.cpp | 8 + .../include/eosio.system/eosio.system.hpp | 726 ++++++++++++++++-- .../include/eosio.system/exchange_state.hpp | 13 +- .../include/eosio.system/native.hpp | 165 +++- contracts/eosio.system/src/eosio.system.cpp | 7 - contracts/eosio.system/src/rex.cpp | 131 ---- contracts/eosio.system/src/voting.cpp | 33 - contracts/eosio.token/README.md | 7 - .../include/eosio.token/eosio.token.hpp | 100 ++- .../include/eosio.wrap/eosio.wrap.hpp | 25 +- docs/eosio.msig.md | 182 +++++ .../README.md => docs/eosio.wrap.md | 46 +- 16 files changed, 1465 insertions(+), 429 deletions(-) delete mode 100755 contracts/eosio.msig/README.md delete mode 100755 contracts/eosio.token/README.md create mode 100644 docs/eosio.msig.md rename contracts/eosio.wrap/README.md => docs/eosio.wrap.md (98%) mode change 100755 => 100644 diff --git a/README.md b/README.md index 5bfacdf1..86929d3e 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,11 @@ ## Version : 1.6.0-rc3 -The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. +The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. This repository contains examples of these privileged contracts that are useful when deploying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: + * [eosio.bios](https://github.com/eosio/eosio.contracts/tree/master/eosio.bios) * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) * [eosio.wrap](https://github.com/eosio/eosio.contracts/tree/master/eosio.wrap) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index e3acabe7..6ad3e5d4 100755 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -5,11 +5,39 @@ #include #include +/** + * EOSIO Contracts + * + * @details The design of the EOSIO blockchain calls for a number of smart contracts that are run at a + * privileged permission level in order to support functions such as block producer registration and + * voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart + * contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. + * + * This repository contains examples of these privileged contracts that are useful when deploying, + * managing, and/or using an EOSIO blockchain. They are provided for reference purposes: + * - eosio.bios + * - eosio.system + * - eosio.msig + * - eosio.wrap + * + * The following unprivileged contract(s) are also part of the system. + * - eosio.token + */ + namespace eosio { + using eosio::permission_level; using eosio::public_key; using eosio::ignore; + /** + * A weighted permission. + * + * @details Defines a weighted permission, that is a permission which has a weight associated. + * A permission is defined by an account name plus a permission name. The weight is going to be + * used against a threshold, if the weight is equal or greater than the threshold set then authorization + * will pass. + */ struct permission_level_weight { permission_level permission; uint16_t weight; @@ -18,6 +46,11 @@ namespace eosio { EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) }; + /** + * Weighted key. + * + * @details A weighted key is defined by a public key and an associated weight. + */ struct key_weight { eosio::public_key key; uint16_t weight; @@ -26,6 +59,11 @@ namespace eosio { EOSLIB_SERIALIZE( key_weight, (key)(weight) ) }; + /** + * Wait weight. + * + * @details A wait weight is defined by a number of seconds to wait for and a weight. + */ struct wait_weight { uint32_t wait_sec; uint16_t weight; @@ -34,6 +72,15 @@ namespace eosio { EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) }; + /** + * Blockchain authority. + * + * @details An authority is defined by: + * - a vector of key_weights (a key_weight is a public key plus a weight), + * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) + * - a vector of wait_weights (a wait_weight is defined by a number of seconds to wait and a weight) + * - a threshold value + */ struct authority { uint32_t threshold = 0; std::vector keys; @@ -44,6 +91,19 @@ namespace eosio { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) }; + /** + * Blockchain block header. + * + * @details A block header is defined by: + * - a timestamp, + * - the producer that created it, + * - a confirmed flag default as zero, + * - a link to previous block, + * - a link to the transaction merkel root, + * - a link to action root, + * - a schedule version, + * - and a producers' schedule. + */ struct block_header { uint32_t timestamp; name producer; @@ -59,64 +119,202 @@ namespace eosio { (schedule_version)(new_producers)) }; + /** + * @defgroup eosiobios eosio.bios + * @ingroup eosiocontracts + * + * eosio.bios is a minimalistic system contract that only supplies the actions that are absolutely + * critical to bootstrap a chain and nothing more. + * + * @{ + */ class [[eosio::contract("eosio.bios")]] bios : public contract { public: using contract::contract; + /** + * @{ + * These actions map one-on-one with the ones defined in + * [Native Action Handlers](@ref native_action_handlers) section. + * They are present here so they can show up in the abi file and thus user can send them + * to this contract, but they have no specific implementation at this contract level, + * they will execute the implementation at the core level and nothing else. + */ + /** + * New account action + * + * @details Called after a new account is created. This code enforces resource-limits rules + * for new accounts as well as new account naming conventions. + * + * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 + * characters long without '.' until a future account auction process is implemented + * which prevents name squatting. + * + * 2. new accounts must stake a minimal number of tokens (as set in system parameters) + * therefore, this method will execute an inline buyram from receiver for newacnt in + * an amount equal to the current new account creation fee. + */ [[eosio::action]] void newaccount( name creator, name name, ignore owner, ignore active){} - - + /** + * Update authorization action. + * + * @details Updates pemission for an account. + * + * @param account - the account for which the permission is updated, + * @param pemission - the permission name which is updated, + * @param parem - the parent of the permission which is updated, + * @param aut - the json describing the permission authorization. + */ [[eosio::action]] void updateauth( ignore account, ignore permission, ignore parent, ignore auth ) {} + /** + * Delete authorization action. + * + * @details Deletes the authorization for an account's permision. + * + * @param account - the account for which the permission authorization is deleted, + * @param permission - the permission name been deleted. + */ [[eosio::action]] void deleteauth( ignore account, ignore permission ) {} + /** + * Link authorization action. + * + * @details Assigns a specific action from a contract to a permission you have created. Five system + * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. + * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the + * action needed to be authorized (and the contract belonging to), and looks up which permission + * is needed to pass authorization validation. If a link is set, that permission is used for authoraization + * validation otherwise then active is the default, with the exception of `eosio.any`. + * `eosio.any` is an implicit permission which exists on every account; you can link actions to `eosio.any` + * and that will make it so linked actions are accessible to any permissions defined for the account. + * + * @param account - the permission's owner to be linked and the payer of the RAM needed to store this link, + * @param code - the owner of the action to be linked, + * @param type - the action to be linked, + * @param requirement - the permission to be linked. + */ [[eosio::action]] void linkauth( ignore account, ignore code, ignore type, ignore requirement ) {} + /** + * Unlink authorization action. + * + * @details It's doing the reverse of linkauth action, by unlinking the given action. + * + * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, + * @param code - the owner of the action to be unlinked, + * @param type - the action to be unlinked. + */ [[eosio::action]] void unlinkauth( ignore account, ignore code, ignore type ) {} + /** + * Cancel delay action. + * + * @details Cancels a deferred transaction. + * + * @param canceling_auth - the permission that authorizes this action, + * @param trx_id - the deferred transaction id to be cancelled. + */ [[eosio::action]] void canceldelay( ignore canceling_auth, ignore trx_id ) {} + /** + * On error action. + * + * @details Called every time an error occurs while a transaction was processed. + * + * @param sender_id - the id of the sender, + * @param sent_trx - the transaction that failed. + */ [[eosio::action]] void onerror( ignore sender_id, ignore> sent_trx ) {} + /** + * Set code action. + * + * @details Sets the contract code for an account. + * + * @param account - the account for which to set the contract code. + * @param vmtype - reserved, set it to zero. + * @param vmversion - reserved, set it to zero. + * @param code - the code content to be set, in the form of a blob binary.. + */ [[eosio::action]] void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} - + + /** @}*/ + + /** + * Set privilege status for an account. + * + * @details Allows to set privilege status for an account (turn it on/off). + * @param account - the account to set the privileged status for. + * @param is_priv - 0 for false, > 0 for true. + */ [[eosio::action]] void setpriv( name account, uint8_t is_priv ) { require_auth( _self ); set_privileged( account.value, is_priv ); } + /** + * Set the resource limits of an account + * + * @details Set the resource limits of an account + * + * @param account - name of the account whose resource limit to be set + * @param ram_bytes - ram limit in absolute bytes + * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts) + * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts) + */ [[eosio::action]] void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { require_auth( _self ); set_resource_limits( account.value, ram_bytes, net_weight, cpu_weight ); } + /** + * Set global resource limits. + * + * @details Not implemented yet. + * Set global resource limits + * + * @param ram - ram limit + * @param net - net limit + * @param cpu - cpu limit + */ [[eosio::action]] void setglimits( uint64_t ram, uint64_t net, uint64_t cpu ) { (void)ram; (void)net; (void)cpu; require_auth( _self ); } + /** + * Set a new list of active producers, that is, a new producers' schedule. + * + * @details Set a new list of active producers, by proposing a schedule change, once the block that + * contains the proposal becomes irreversible, the schedule is promoted to "pending" + * automatically. Once the block that promotes the schedule is irreversible, the schedule will + * become "active". + * + * @param schedule - New list of active producers to set + */ [[eosio::action]] void setprods( std::vector schedule ) { (void)schedule; // schedule argument just forces the deserialization of the action data into vector (necessary check) @@ -129,17 +327,42 @@ namespace eosio { set_proposed_producers(buffer, size); } + /** + * Set the blockchain parameters + * + * @details Set the blockchain parameters. By tuning these parameters, various degrees of customization can be achieved. + * + * @param params - New blockchain parameters to set + */ [[eosio::action]] void setparams( const eosio::blockchain_parameters& params ) { require_auth( _self ); set_blockchain_parameters( params ); } + /** + * Check if an account has authorization to access current action. + * + * @details Checks if the account name `from` passed in as param has authorization to access + * current action, that is, if it is listed in the action’s allowed permissions vector. + * + * @param from - the account name to authorize + */ [[eosio::action]] void reqauth( name from ) { require_auth( from ); } + /** + * Set abi for contract. + * + * @details Set the abi for contract identified by `account` name. Creates an entry in the abi_hash_table + * index, with `account` name as key, if it is not already present and sets its value with the abi hash. + * Otherwise it is updating the current abi hash value for the existing `account` key. + * + * @param account - the name of the account to set the abi for + * @param abi - the abi hash represented as a vector of characters + */ [[eosio::action]] void setabi( name account, const std::vector& abi ) { abi_hash_table table(_self, _self.value); @@ -156,6 +379,11 @@ namespace eosio { } } + /** + * Abi hash structure + * + * @details Abi hash structure is defined by contract owner and the contract hash. + */ struct [[eosio::table]] abi_hash { name owner; capi_checksum256 hash; @@ -164,6 +392,9 @@ namespace eosio { EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; + /** + * Multi index table that stores the contracts' abi index by their owners/accounts. + */ typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; using newaccount_action = action_wrapper<"newaccount"_n, &bios::newaccount>; @@ -181,5 +412,5 @@ namespace eosio { using reqauth_action = action_wrapper<"reqauth"_n, &bios::reqauth>; using setabi_action = action_wrapper<"setabi"_n, &bios::setabi>; }; - + /** @}*/ // end of @defgroup eosiobios eosio.bios } /// namespace eosio diff --git a/contracts/eosio.msig/README.md b/contracts/eosio.msig/README.md deleted file mode 100755 index 1d727913..00000000 --- a/contracts/eosio.msig/README.md +++ /dev/null @@ -1,113 +0,0 @@ -eosio.msig --------- - -Actions: -The naming convention is codeaccount::actionname followed by a list of paramters. - -Create a proposal -## eosio.msig::propose proposer proposal_name requested trx - - **proposer** account proposing a transaction - - **proposal_name** name of the proposal (should be unique for proposer) - - **requested** permission levels expected to approve the proposal - - **trx** proposed transaction - - Storage changes are billed to 'proposer' - -Approve a proposal -## eosio.msig::approve proposer proposal_name level - - **proposer** account proposing a transaction - - **proposal_name** name of the proposal - - **level** permission level approving the transaction - - Storage changes are billed to 'proposer' - -Revoke an approval of transaction -## eosio.msig::unapprove proposer proposal_name level - - **proposer** account proposing a transaction - - **proposal_name** name of the proposal - - **level** permission level revoking approval from the transaction - - Storage changes are billed to 'proposer' - -Cancel a proposal -## eosio.msig::cancel proposer proposal_name canceler - - **proposer** account proposing a transaction - - **proposal_name** name of the proposal - - **canceler** account canceling the transaction (only proposer can cancel not expired transaction) - -Execute a proposal -## eosio.msig::exec proposer proposal_name executer - - **proposer** account proposing a transaction - - **proposal_name** name of the proposal - - **executer** account executing the transaction - - -Cleos usage example. - -Prerequisites: - - eosio.token contract installed to eosio.token accountm, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' is the issuer of EOS token. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 EOS", "memo": ""}' -p tester -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -Another user reviews the transaction: -```` -$ cleos multisig review tester test -p treasury -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "issue", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "to": "tester", - "quantity": "1000.0000 EOS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -First user initiates execution: -```` -$ cleos multisig exec tester test -p tester -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index 9589fe52..bb22cea0 100755 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -4,23 +4,115 @@ #include namespace eosio { - + /** + * @defgroup eosiomsig eosio.msig + * @ingroup eosiocontracts + * eosio.msig contract defines the structures and actions needed to manage the proposals and approvals on blockchain. + * @{ + */ class [[eosio::contract("eosio.msig")]] multisig : public contract { public: using contract::contract; + /** + * Create proposal + * + * @details Creates a proposal containing one transaction. + * Allows an account `proposer` to make a proposal `proposal_name` which has `requested` + * permission levels expected to approve the proposal, and if approved by all expected + * permission levels then `trx` transaction can we executed by this proposal. + * The `proposer` account is authorized and the `trx` transaction is verified if it was + * authorized by the provided keys and permissions, and if the proposal name doesn’t + * already exist; if all validations pass the `proposal_name` and `trx` trasanction are + * saved in the proposals table and the `requested` permission levels to the + * approvals table (for the `proposer` context). + * Storage changes are billed to `proposer`. + * + * @param proposer - The account proposing a transaction + * @param proposal_name - The name of the proposal (should be unique for proposer) + * @param requested - Permission levels expected to approve the proposal + * @param trx - Proposed transaction + */ [[eosio::action]] void propose(ignore proposer, ignore proposal_name, ignore> requested, ignore trx); + /** + * Approve proposal + * + * @details Approves an existing proposal + * Allows an account, the owner of `level` permission, to approve a proposal `proposal_name` + * proposed by `proposer`. If the proposal's requested approval list contains the `level` + * permission then the `level` permission is moved from internal `requested_approvals` list to + * internal `provided_approvals` list of the proposal, thus persisting the approval for + * the `proposal_name` proposal. + * Storage changes are billed to `proposer`. + * + * @param proposer - The account proposing a transaction + * @param proposal_name - The name of the proposal (should be unique for proposer) + * @param level - Permission level approving the transaction + * @param proposal_hash - Transaction's checksum + */ [[eosio::action]] void approve( name proposer, name proposal_name, permission_level level, const eosio::binary_extension& proposal_hash ); + /** + * Revoke proposal + * + * @details Revokes an existing proposal + * This action is the reverse of the `approve` action: if all validations pass + * the `level` permission is erased from internal `provided_approvals` and added to the internal + * `requested_approvals` list, and thus un-approve or revoke the proposal. + * + * @param proposer - The account proposing a transaction + * @param proposal_name - The name of the proposal (should be an existing proposal) + * @param level - Permission level revoking approval for proposal + */ [[eosio::action]] void unapprove( name proposer, name proposal_name, permission_level level ); + /** + * Cancel proposal + * + * @details Cancels an existing proposal + * + * @param proposer - The account proposing a transaction + * @param proposal_name - The name of the proposal (should be an existing proposal) + * @param canceler - The account cancelling the proposal (only the proposer can cancel an unexpired transaction, and the canceler has to be different than the proposer) + * + * Allows the `canceler` account to cancel the `proposal_name` proposal, created by a `proposer`, + * only after time has expired on the proposed transaction. It removes corresponding entries from + * internal proptable and from approval (or old approvals) tables as well. + */ [[eosio::action]] void cancel( name proposer, name proposal_name, name canceler ); + /** + * Execute proposal + * + * @details Allows an `executer` account to execute a proposal. + * + * Preconditions: + * - `executer` has authorization, + * - `proposal_name` is found in the proposals table, + * - all requested approvals are received, + * - proposed transaction is not expired, + * - and approval accounts are not found in invalidations table. + * + * If all preconditions are met the transaction is executed as a deferred transaction, + * and the proposal is erased from the proposals table. + * + * @param proposer - The account proposing a transaction + * @param proposal_name - The name of the proposal (should be an existing proposal) + * @param executer - The account executing the transaction + */ [[eosio::action]] void exec( name proposer, name proposal_name, name executer ); + /** + * Invalidate proposal + * + * @details Allows an `account` to invalidate itself, that is, its name is added to + * the invalidations table and this table will be cross referenced when exec is performed. + * + * @param account - The account invalidating the transaction + */ [[eosio::action]] void invalidate( name account ); @@ -76,5 +168,5 @@ namespace eosio { typedef eosio::multi_index< "invals"_n, invalidation > invalidations; }; - + /** @}*/ // end of @defgroup eosiomsig eosio.msig } /// namespace eosio diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index c0baad73..1a9ca4e0 100755 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -5,6 +5,14 @@ namespace eosio { +/** + * @ingroup eosiocontracts + * + * Returns a high resolution time_point + * + * @details Returns a high resolution time_point which represents the number of microseconds + * from 1970 until the current time. + */ time_point current_time_point() { const static time_point ct{ microseconds{ static_cast( current_time() ) } }; return ct; diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 43b2c353..f7a99b44 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -58,6 +58,30 @@ namespace eosiosystem { return ( flags & ~static_cast(field) ); } + /** + * + * @defgroup eosiosystem eosio.system + * @ingroup eosiocontracts + * eosio.system contract defines the structures and actions needed for blockchain's core functionality. + * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or + * delegate their vote to a proxy. + * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. + * - Users can buy and sell RAM at a market-determined price. + * - Users can bid on premium names. + * - A resource exchange system (REX) allows token holders to lend their tokens, + * and users to rent CPU and Network resources in return for a market-determined fee. + * @{ + */ + + /** + * A name bid. + * + * @details A name bid consists of: + * - a `newname` name that the bid is for + * - a `high_bidder` account name that is the one with the highest bid so far + * - the `high_bid` which is amount of highest bid + * - and `last_bid_time` which is the time of the highest bid + */ struct [[eosio::table, eosio::contract("eosio.system")]] name_bid { name newname; name high_bidder; @@ -68,6 +92,13 @@ namespace eosiosystem { uint64_t by_high_bid()const { return static_cast(-high_bid); } }; + /** + * A bid refund. + * + * @details A bid refund is defined by: + * - the `bidder` account name owning the refund + * - the `amount` to be refunded + */ struct [[eosio::table, eosio::contract("eosio.system")]] bid_refund { name bidder; asset amount; @@ -75,12 +106,25 @@ namespace eosiosystem { uint64_t primary_key()const { return bidder.value; } }; + /** + * Name bid table + * + * @details The name bid table is storing all the `name_bid`s instances. + */ typedef eosio::multi_index< "namebids"_n, name_bid, indexed_by<"highbid"_n, const_mem_fun > > name_bid_table; + /** + * Bid refund table. + * + * @details The bid refund table is storing all the `bid_refund`s instances. + */ typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; + /** + * Defines new global state parameters. + */ struct [[eosio::table("global"), eosio::contract("eosio.system")]] eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } @@ -123,6 +167,9 @@ namespace eosiosystem { (total_producer_votepay_share)(revision) ) }; + /** + * Defines new global state parameters added after version 1.3.0 + */ struct [[eosio::table("global3"), eosio::contract("eosio.system")]] eosio_global_state3 { eosio_global_state3() { } time_point last_vpay_state_update; @@ -131,6 +178,9 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) }; + /** + * Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 + */ struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { name owner; double total_votes = 0; @@ -151,6 +201,9 @@ namespace eosiosystem { (unpaid_blocks)(last_claim_time)(location) ) }; + /** + * Defines new producer info structure to be stored in new producer info table, added after version 1.3.0 + */ struct [[eosio::table, eosio::contract("eosio.system")]] producer_info2 { name owner; double votepay_share = 0; @@ -162,6 +215,15 @@ namespace eosiosystem { EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) }; + /** + * Voter info. + * + * @details Voter info stores information about the voter: + * - `owner` the voter + * - `proxy` the proxy set by the voter, if any + * - `producers` the producers approved by this voter if no proxy set + * - `staked` the amount staked + */ struct [[eosio::table, eosio::contract("eosio.system")]] voter_info { name owner; /// the voter name proxy; /// the proxy set by the voter, if any @@ -199,35 +261,83 @@ namespace eosiosystem { EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(flags1)(reserved2)(reserved3) ) }; + /** + * Voters table + * + * @details The voters table stores all the `voter_info`s instances, all voters information. + */ typedef eosio::multi_index< "voters"_n, voter_info > voters_table; + /** + * Defines producer info table added in version 1.0 + */ typedef eosio::multi_index< "producers"_n, producer_info, indexed_by<"prototalvote"_n, const_mem_fun > > producers_table; + /** + * Defines new producer info table added in version 1.3.0 + */ typedef eosio::multi_index< "producers2"_n, producer_info2 > producers_table2; + /** + * Global state singleton added in version 1.0 + */ typedef eosio::singleton< "global"_n, eosio_global_state > global_state_singleton; + /** + * Global state singleton added in version 1.1.0 + */ typedef eosio::singleton< "global2"_n, eosio_global_state2 > global_state2_singleton; + /** + * Global state singleton added in version 1.3 + */ typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; + // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; + /** + * `rex_pool` structure underlying the rex pool table. + * + * @details A rex pool table entry is defined by: + * - `version` defaulted to zero, + * - `total_lent` total amount of CORE_SYMBOL in open rex_loans + * - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), + * - `total_rent` fees received in exchange for lent (connector), + * - `total_lendable` total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent), + * - `total_rex` total number of REX shares allocated to contributors to total_lendable, + * - `namebid_proceeds` the amount of CORE_SYMBOL to be transferred from namebids to REX pool, + * - `loan_num` increments with each new loan. + */ struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { uint8_t version = 0; - asset total_lent; /// total amount of CORE_SYMBOL in open rex_loans - asset total_unlent; /// total amount of CORE_SYMBOL available to be lent (connector) - asset total_rent; /// fees received in exchange for lent (connector) - asset total_lendable; /// total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent) - asset total_rex; /// total number of REX shares allocated to contributors to total_lendable - asset namebid_proceeds; /// the amount of CORE_SYMBOL to be transferred from namebids to REX pool - uint64_t loan_num = 0; /// increments with each new loan + asset total_lent; + asset total_unlent; + asset total_rent; + asset total_lendable; + asset total_rex; + asset namebid_proceeds; + uint64_t loan_num = 0; uint64_t primary_key()const { return 0; } }; + /** + * Rex pool table + * + * @details The rex pool table is storing the only one instance of rex_pool which it stores + * the global state of the REX system. + */ typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; + /** + * `rex_fund` structure underlying the rex fund table. + * + * @details A rex fund table entry is defined by: + * - `version` defaulted to zero, + * - `owner` the owner of the rex fund, + * - `balance` the balance of the fund. + */ struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { uint8_t version = 0; name owner; @@ -236,21 +346,55 @@ namespace eosiosystem { uint64_t primary_key()const { return owner.value; } }; + /** + * Rex fund table + * + * @details The rex fund table is storing all the `rex_fund`s instances. + */ typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; + /** + * `rex_balance` structure underlying the rex balance table. + * + * @details A rex balance table entry is defined by: + * - `version` defaulted to zero, + * - `owner` the owner of the rex fund, + * - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, + * - `rex_balance` the amount of REX owned by owner, + * - `matured_rex` matured REX available for selling. + */ struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { uint8_t version = 0; name owner; - asset vote_stake; /// the amount of CORE_SYMBOL currently included in owner's vote - asset rex_balance; /// the amount of REX owned by owner - int64_t matured_rex = 0; /// matured REX available for selling + asset vote_stake; + asset rex_balance; + int64_t matured_rex = 0; std::deque> rex_maturities; /// REX daily maturity buckets uint64_t primary_key()const { return owner.value; } }; + /** + * Rex balance table + * + * @details The rex balance table is storing all the `rex_balance`s instances. + */ typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; + /** + * `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. + * + * @details A rex net/cpu loan table entry is defined by: + * - `version` defaulted to zero, + * - `from` account creating and paying for loan, + * - `receiver` account receiving rented resources, + * - `payment` SYS tokens paid for the loan, + * - `balance` is the amount of SYS tokens available to be used for loan auto-renewal, + * - `total_staked` total amount staked, + * - `loan_num` loan number/id, + * - `expiration` the expiration time when loan will be either closed or renewed + * If payment <= balance, the loan is renewed, and closed otherwise. + */ struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { uint8_t version = 0; name from; @@ -266,11 +410,21 @@ namespace eosiosystem { uint64_t by_owner()const { return from.value; } }; + /** + * Rex cpu loan table + * + * @details The rex cpu loan table is storing all the `rex_load`s instances for cpu, indexed by loan number, expiration and owner. + */ typedef eosio::multi_index< "cpuloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, indexed_by<"byowner"_n, const_mem_fun> > rex_cpu_loan_table; + /** + * Rex net loan table + * + * @details The rex net loan table is storing all the `rex_load`s instances for net, indexed by loan number,expiration and owner. + */ typedef eosio::multi_index< "netloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, indexed_by<"byowner"_n, const_mem_fun> @@ -290,6 +444,11 @@ namespace eosiosystem { uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } }; + /** + * Rex order table + * + * @details The rex order table is storing all the `rex_order`s instances, indexed by owner and time and owner. + */ typedef eosio::multi_index< "rexqueue"_n, rex_order, indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; @@ -299,6 +458,11 @@ namespace eosiosystem { asset stake_change; }; + /** + * The EOSIO system contract. + * + * @details The EOSIO system contract governs ram market, voters, producers, global state. + */ class [[eosio::contract("eosio.system")]] system_contract : public native { private: @@ -333,9 +497,23 @@ namespace eosiosystem { static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); + /** + * System contract constructor. + * + * @details Constructs a system contract based on self account, code account and data. + * + * @params s - The current code account that is executing the action, + * @params code - The original code account that executed the action, + * @params ds - The contract data represented as an `eosio::datastream`. + */ system_contract( name s, name code, datastream ds ); ~system_contract(); + /** + * Returns the core symbol by system account name + * + * @params system_account - the system account to get the core symbol for. + */ static symbol get_core_symbol( name system_account = "eosio"_n ) { rammarket rm(system_account, system_account.value); const static auto sym = get_core_symbol( rm ); @@ -343,242 +521,611 @@ namespace eosiosystem { } // Actions: + /** + * Init action. + * + * @details Init action initializes the system contract for a version and a symbol. + * Only succeeds when: + * - version is 0 and + * - symbol is found and + * - system token supply is greater than 0, + * - and system contract wasn’t already been initialized. + * + * @param version - the version, has to be 0, + * @param core - the system symbol. + */ [[eosio::action]] void init( unsigned_int version, symbol core ); + + /** + * On block action. + * + * @details This special action is triggered when a block is applied by the given producer + * and cannot be generated from any other source. It is used to pay producers and calculate + * missed blocks of other producers. Producer pay is deposited into the producer's stake + * balance and can be withdrawn over time. If blocknum is the start of a new round this may + * update the active producer config from the producer votes. + * + * @param header - the block header produced. + */ [[eosio::action]] void onblock( ignore header ); + /** + * Set account limits action. + * + * @details Set the resource limits of an account + * + * @param account - name of the account whose resource limit to be set, + * @param ram_bytes - ram limit in absolute bytes, + * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts), + * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). + */ [[eosio::action]] void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); + /** + * Set account RAM limits action. + * + * @details Set the RAM limits of an account + * + * @param account - name of the account whose resource limit to be set, + * @param ram_bytes - ram limit in absolute bytes. + */ [[eosio::action]] void setacctram( name account, std::optional ram_bytes ); + /** + * Set account NET limits action. + * + * @details Set the NET limits of an account + * + * @param account - name of the account whose resource limit to be set, + * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts). + */ [[eosio::action]] void setacctnet( name account, std::optional net_weight ); + /** + * Set account CPU limits action. + * + * @details Set the CPU limits of an account + * + * @param account - name of the account whose resource limit to be set, + * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). + */ [[eosio::action]] void setacctcpu( name account, std::optional cpu_weight ); // functions defined in delegate_bandwidth.cpp /** - * Stakes SYS from the balance of 'from' for the benfit of 'receiver'. - * If transfer == true, then 'receiver' can unstake to their account - * Else 'from' can unstake at any time. + * Delegate bandwidth and/or cpu action. + * + * @details Stakes SYS from the balance of `from` for the benefit of `receiver`. + * + * @param from - the account to delegate bandwidth from, that is, the account holding + * tokens to be staked, + * @param receiver - the account to delegate bandwith to, that is, the account to + * whose resources staked tokens are added + * @param stake_net_quantity - tokens staked for NET bandwidth, + * @param stake_cpu_quantity - tokens staked for CPU bandwidth, + * @param transfer - if true, ownership of staked tokens is transfered to `receiver`. + * + * @post All producers `from` account has voted for will have their votes updated immediately. */ [[eosio::action]] void delegatebw( name from, name receiver, asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); /** - * Sets total_rent balance of REX pool to the passed value + * Setrex action. + * + * @details Sets total_rent balance of REX pool to the passed value. + * @param balance - amount to set the REX pool balance. */ [[eosio::action]] void setrex( const asset& balance ); /** - * Deposits core tokens to user REX fund. All proceeds and expenses related to REX are added to - * or taken out of this fund. Inline token transfer from user balance is executed. + * Deposit to REX fund action. + * + * @details Deposits core tokens to user REX fund. + * All proceeds and expenses related to REX are added to or taken out of this fund. + * An inline transfer from 'owner' liquid balance is executed. + * All REX-related costs and proceeds are deducted from and added to 'owner' REX fund, + * with one exception being buying REX using staked tokens. + * Storage change is billed to 'owner'. + * + * @param owner - REX fund owner account, + * @param amount - amount of tokens to be deposited. */ [[eosio::action]] void deposit( const name& owner, const asset& amount ); /** - * Withdraws core tokens from user REX fund. Inline token transfer to user balance is - * executed. + * Withdraw from REX fund action. + * + * @details Withdraws core tokens from user REX fund. + * An inline token transfer to user balance is executed. + * + * @param owner - REX fund owner account, + * @param amount - amount of tokens to be withdrawn. */ [[eosio::action]] void withdraw( const name& owner, const asset& amount ); /** - * Transfers core tokens from user REX fund and converts them to REX stake. - * A voting requirement must be satisfied before action can be executed. - * User votes are updated following this action. + * Buyrex action. + * + * @details Buys REX in exchange for tokens taken out of user's REX fund by transfering + * core tokens from user REX fund and converts them to REX stake. By buying REX, user is + * lending tokens in order to be rented as CPU or NET resourses. + * Storage change is billed to 'from' account. + * + * @param from - owner account name, + * @param amount - amount of tokens taken out of 'from' REX fund. + * + * @pre A voting requirement must be satisfied before action can be executed. + * @pre User must vote for at least 21 producers or delegate vote to proxy before buying REX. + * + * @post User votes are updated following this action. + * @post Tokens used in purchase are added to user's voting power. + * @post Bought REX cannot be sold before 4 days counting from end of day of purchase. */ [[eosio::action]] void buyrex( const name& from, const asset& amount ); /** - * Use staked core tokens to buy REX. - * A voting requirement must be satisfied before action can be executed. - * User votes are updated following this action. + * Unstaketorex action. + * + * @details Use staked core tokens to buy REX. + * Storage change is billed to 'owner' account. + * + * @param owner - owner of staked tokens, + * @param receiver - account name that tokens have previously been staked to, + * @param from_net - amount of tokens to be unstaked from NET bandwidth and used for REX purchase, + * @param from_cpu - amount of tokens to be unstaked from CPU bandwidth and used for REX purchase. + * + * @pre A voting requirement must be satisfied before action can be executed. + * @pre User must vote for at least 21 producers or delegate vote to proxy before buying REX. + * + * @post User votes are updated following this action. + * @post Tokens used in purchase are added to user's voting power. + * @post Bought REX cannot be sold before 4 days counting from end of day of purchase. */ [[eosio::action]] void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); /** - * Converts REX stake back into core tokens at current exchange rate. If order cannot be - * processed, it gets queued until there is enough in REX pool to fill order. - * If successful, user votes are updated. + * Sellrex action. + * + * @details Sells REX in exchange for core tokens by converting REX stake back into core tokens + * at current exchange rate. If order cannot be processed, it gets queued until there is enough + * in REX pool to fill order, and will be processed within 30 days at most. If successful, user + * votes are updated, that is, proceeds are deducted from user's voting power. In case sell order + * is queued, storage change is billed to 'from' account. + * + * @param from - owner account of REX, + * @param rex - amount of REX to be sold. */ [[eosio::action]] void sellrex( const name& from, const asset& rex ); /** - * Cancels queued sellrex order. Order cannot be cancelled once it's been filled. + * Cnclrexorder action. + * + * @details Cancels unfilled REX sell order by owner if one exists. + * + * @param owner - owner account name. + * + * @pre Order cannot be cancelled once it's been filled. */ [[eosio::action]] void cnclrexorder( const name& owner ); /** - * Use payment to rent as many SYS tokens as possible and stake them for either CPU or NET for the - * benefit of receiver, after 30 days the rented SYS delegation of CPU or NET will expire unless loan - * balance is larger than or equal to payment. - * - * If loan has enough balance, it gets renewed at current market price, otherwise, it is closed and - * remaining balance is refunded to loan owner. - * - * Owner can fund or defund a loan at any time before its expiration. - * + * Rentcpu action. + * + * @details Use payment to rent as many SYS tokens as possible as determined by market price and + * stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU + * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` + * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user + * is refunded any remaining balance. + * Owner can fund or refund a loan at any time before its expiration. * All loan expenses and refunds come out of or are added to owner's REX fund. + * + * @param from - account creating and paying for CPU loan, 'from' account can add tokens to loan + * balance using action `fundcpuloan` and withdraw from loan balance using `defcpuloan` + * @param receiver - account receiving rented CPU resources, + * @param loan_payment - tokens paid for the loan, it has to be greater than zero, + * amount of rented resources is calculated from `loan_payment`, + * @param loan_fund - additional tokens can be zero, and is added to loan balance. + * Loan balance represents a reserve that is used at expiration for automatic loan renewal. */ [[eosio::action]] void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); + + /** + * Rentnet action. + * + * @details Use payment to rent as many SYS tokens as possible as determined by market price and + * stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET + * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` + * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user + * is refunded any remaining balance. + * Owner can fund or refund a loan at any time before its expiration. + * All loan expenses and refunds come out of or are added to owner's REX fund. + * + * @param from - account creating and paying for NET loan, 'from' account can add tokens to loan + * balance using action `fundnetloan` and withdraw from loan balance using `defnetloan`, + * @param receiver - account receiving rented NET resources, + * @param loan_payment - tokens paid for the loan, it has to be greater than zero, + * amount of rented resources is calculated from `loan_payment`, + * @param loan_fund - additional tokens can be zero, and is added to loan balance. + * Loan balance represents a reserve that is used at expiration for automatic loan renewal. + */ [[eosio::action]] void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Loan owner funds a given CPU or NET loan. + * Fundcpuloan action. + * + * @details Transfers tokens from REX fund to the fund of a specific CPU loan in order to + * be used for loan renewal at expiry. + * + * @param from - loan creator account, + * @param loan_num - load id, + * @param payment - tokens transfered from REX fund to loan fund. */ [[eosio::action]] void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); + + /** + * Fundnetloan action. + * + * @details Transfers tokens from REX fund to the fund of a specific NET loan in order to + * be used for loan renewal at expiry. + * + * @param from - loan creator account, + * @param loan_num - load id, + * @param payment - tokens transfered from REX fund to loan fund. + */ [[eosio::action]] void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); + /** - * Loan owner defunds a given CPU or NET loan. + * Defcpuload action. + * + * @details Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. + * + * @param from - loan creator account, + * @param loan_num - load id, + * @param amount - tokens transfered from CPU loan fund to REX fund. */ [[eosio::action]] void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); + + /** + * Defnetloan action. + * + * @details Withdraws tokens from the fund of a specific NET loan and adds them to REX fund. + * + * @param from - loan creator account, + * @param loan_num - load id, + * @param amount - tokens transfered from NET loan fund to REX fund. + */ [[eosio::action]] void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); /** - * Updates REX vote stake of owner to its current value. + * Updaterex action. + * + * @details Updates REX owner vote weight to current value of held REX tokens. + * + * @params owner - REX owner account. */ [[eosio::action]] void updaterex( const name& owner ); /** - * Processes max CPU loans, max NET loans, and max queued sellrex orders. + * Rexexec action. + * + * @details Processes max CPU loans, max NET loans, and max queued sellrex orders. * Action does not execute anything related to a specific user. + * + * @param user - any account can execute this action, + * @param max - number of each of CPU loans, NET loans, and sell orders to be processed. */ [[eosio::action]] void rexexec( const name& user, uint16_t max ); /** - * Consolidate REX maturity buckets into one that can be sold only 4 days - * from the end of today. + * Consolidate action. + * + * @details Consolidate REX maturity buckets into one bucket that can be sold after 4 days. + * + * @param owner - REX owner account name. */ [[eosio::action]] void consolidate( const name& owner ); /** - * Moves a specified amount of REX into savings bucket. REX savings bucket - * never matures. In order for it to be sold, it has to be moved explicitly - * out of that bucket. Then the moved amount will have the regular maturity - * period of 4 days starting from the end of the day. - */ - [[eosio::action]] - void mvtosavings( const name& owner, const asset& rex ); - - /** - * Moves a specified amount of REX out of savings bucket. The moved amount - * will have the regular REX maturity period of 4 days. - */ - [[eosio::action]] - void mvfrsavings( const name& owner, const asset& rex ); - - /** - * Deletes owner records from REX tables and frees used RAM. - * Owner must not have an outstanding REX balance. + * Closerex action. + * + * @details Deletes owner records from REX tables and frees used RAM. Owner must not have + * an outstanding REX balance. + * + * @param owner - user account name. + * + * @pre If owner has a non-zero REX balance, the action fails; otherwise, + * owner REX balance entry is deleted. + * @pre If owner has no outstanding loans and a zero REX fund balance, + * REX fund entry is deleted. */ [[eosio::action]] void closerex( const name& owner ); /** - * Decreases the total tokens delegated by from to receiver and/or - * frees the memory associated with the delegation if there is nothing - * left to delegate. - * - * This will cause an immediate reduction in net/cpu bandwidth of the - * receiver. - * - * A transaction is scheduled to send the tokens back to 'from' after - * the staking period has passed. If existing transaction is scheduled, it - * will be canceled and a new transaction issued that has the combined - * undelegated amount. - * - * The 'from' account loses voting power as a result of this call and - * all producer tallies are updated. + * Undelegate bandwitdh action. + * + * @details Decreases the total tokens delegated by `from` to `receiver` and/or + * frees the memory associated with the delegation if there is nothing + * left to delegate. + * This will cause an immediate reduction in net/cpu bandwidth of the + * receiver. + * A transaction is scheduled to send the tokens back to `from` after + * the staking period has passed. If existing transaction is scheduled, it + * will be canceled and a new transaction issued that has the combined + * undelegated amount. + * The `from` account loses voting power as a result of this call and + * all producer tallies are updated. + * + * @param from - the account to undelegate bandwidth from, that is, + * the account whose tokens will be unstaked, + * @param receiver - the account to undelegate bandwith to, that is, + * the account to whose benefit tokens have been staked, + * @param unstake_net_quantity - tokens to be unstaked from NET bandwidth, + * @param unstake_cpu_quantity - tokens to be unstaked from CPU bandwidth, + * + * @post Unstaked tokens are transferred to `from` liquid balance via a + * deferred transaction with a delay of 3 days. + * @post If called during the delay period of a previous `undelegatebw` + * action, pending action is canceled and timer is reset. + * @post All producers `from` account has voted for will have their votes updated immediately. + * @post Bandwidth and storage for the deferred transaction are billed to `from`. */ [[eosio::action]] void undelegatebw( name from, name receiver, asset unstake_net_quantity, asset unstake_cpu_quantity ); - /** - * Increases receiver's ram quota based upon current price and quantity of + * Buy ram action. + * + * @details Increases receiver's ram quota based upon current price and quantity of * tokens provided. An inline transfer from receiver to system contract of * tokens will be executed. + * + * @param payer - the ram buyer, + * @param receiver - the ram receiver, + * @param quant - the quntity of tokens to buy ram with. */ [[eosio::action]] void buyram( name payer, name receiver, asset quant ); + + /** + * Buy a specific amount of ram bytes action. + * + * @details Increases receiver's ram in quantity of bytes provided. + * An inline transfer from receiver to system contract of tokens will be executed. + * + * @param payer - the ram buyer, + * @param receiver - the ram receiver, + * @param bytes - the quntity of ram to buy specified in bytes. + */ [[eosio::action]] void buyrambytes( name payer, name receiver, uint32_t bytes ); /** - * Reduces quota my bytes and then performs an inline transfer of tokens - * to receiver based upon the average purchase price of the original quota. + * Sell ram action. + * + * @details Reduces quota by bytes and then performs an inline transfer of tokens + * to receiver based upon the average purchase price of the original quota. + * + * @param account - the ram seller account, + * @param bytes - the amount of ram to sell in bytes. */ [[eosio::action]] void sellram( name account, int64_t bytes ); /** - * This action is called after the delegation-period to claim all pending - * unstaked tokens belonging to owner + * Refund action. + * + * @details This action is called after the delegation-period to claim all pending + * unstaked tokens belonging to owner. + * + * @param owner - the owner of the tokens claimed. */ [[eosio::action]] void refund( name owner ); // functions defined in voting.cpp + /** + * Register producer action. + * + * @details Register producer action, indicates that a particular account wishes to become a producer, + * this action will create a `producer_config` and a `producer_info` object for `producer` scope + * in producers tables. + * + * @param producer - account registering to be a producer candidate, + * @param producer_key - the public key of the block producer, this is the key used by block producer to sign blocks, + * @param url - the url of the block producer, normally the url of the block producer presentation website, + * @param location - is the country code as defined in the ISO 3166, https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes + * + * @pre Producer is not already registered + * @pre Producer to register is an account + * @pre Authority of producer to register + */ [[eosio::action]] void regproducer( const name producer, const public_key& producer_key, const std::string& url, uint16_t location ); + /** + * Unregister producer action. + * + * @details Deactivate the block producer with account name `producer`. + * @param producer - the block producer account to unregister. + */ [[eosio::action]] void unregprod( const name producer ); + /** + * Set ram action. + * + * @details Set the ram supply. + * @param max_ram_size - the amount of ram supply to set. + */ [[eosio::action]] void setram( uint64_t max_ram_size ); + + /** + * Set ram rate action. + + * @details Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to + * a maximum rate of 3 TB per year. If update_ram_supply hasn't been called for the most recent block, + * then new ram will be allocated at the old rate up to the present block before switching the rate. + * + * @param bytes_per_block - the amount of bytes per block increase to set. + */ [[eosio::action]] void setramrate( uint16_t bytes_per_block ); + /** + * Vote producer action. + * + * @details Votes for a set of producers. This action updates the list of `producers` voted for, + * for `voter` account. If voting for a `proxy`, the producer votes will not change until the + * proxy updates their own vote. Voter can vote for a proxy __or__ a list of at most 30 producers. + * Storage change is billed to `voter`. + * + * @params voter - the account to change the voted producers for, + * @params proxy - the proxy to change the voted producers for, + * @params producers - the list of producers to vote for, a maximum of 30 producers is allowed. + * + * @pre Producers must be sorted from lowest to highest and must be registered and active + * @pre If proxy is set then no producers can be voted for + * @pre If proxy is set then proxy account must exist and be registered as a proxy + * @pre Every listed producer or proxy must have been previously registered + * @pre Voter must authorize this action + * @pre Voter must have previously staked some EOS for voting + * @pre Voter->staked must be up to date + * + * @post Every producer previously voted for will have vote reduced by previous vote weight + * @post Every producer newly voted for will have vote increased by new vote amount + * @post Prior proxy will proxied_vote_weight decremented by previous vote weight + * @post New proxy will proxied_vote_weight incremented by new vote weight + */ [[eosio::action]] void voteproducer( const name voter, const name proxy, const std::vector& producers ); + /** + * Register proxy action. + * + * @details Set `proxy` account as proxy. + * An account marked as a proxy can vote with the weight of other accounts which + * have selected it as a proxy. Other accounts must refresh their voteproducer to + * update the proxy's weight. + * Storage change is billed to `proxy`. + * + * @param rpoxy - the account registering as voter proxy (or unregistering), + * @param isproxy - if true, proxy is registered; if false, proxy is unregistered. + * + * @pre Proxy must have something staked (existing row in voters table) + * @pre New state must be different than current state + */ [[eosio::action]] void regproxy( const name proxy, bool isproxy ); + /** + * Set the blockchain parameters + * + * @details Set the blockchain parameters. By tunning these parameters a degree of + * customization can be achieved. + * @param params - New blockchain parameters to set. + */ [[eosio::action]] void setparams( const eosio::blockchain_parameters& params ); // functions defined in producer_pay.cpp + /** + * Claim rewards action. + * + * @details Claim block producing and vote rewards. + * @param owner - producer account claiming per-block and per-vote rewards. + */ [[eosio::action]] void claimrewards( const name owner ); + /** + * Set privilege status for an account. + * + * @details Allows to set privilege status for an account (turn it on/off). + * @param account - the account to set the privileged status for. + * @param is_priv - 0 for false, > 0 for true. + */ [[eosio::action]] void setpriv( name account, uint8_t is_priv ); + /** + * Remove producer action. + * + * @details Deactivates a producer by name, if not found asserts. + * @param producer - the producer account to deactivate. + */ [[eosio::action]] void rmvproducer( name producer ); + /** + * Update revision action. + * + * @details Updates the current revision. + * @param revision - it has to be incremented by 1 compared with current revision. + * + * @pre Current revision can not be higher than 254, and has to be smaller + * than or equal 1 (“set upper bound to greatest revision supported in the code”). + */ [[eosio::action]] void updtrevision( uint8_t revision ); + /** + * Bid name action. + * + * @details Allows an account `bidder` to place a bid for a name `newname`. + * @param bidder - the account placing the bid, + * @param newname - the name the bid is placed for, + * @param bid - the amount of system tokens payed for the bid. + * + * @pre Bids can be placed only on top-level suffix, + * @pre Non empty name, + * @pre Names longer than 12 chars are not allowed, + * @pre Names equal with 12 chars can be created without placing a bid, + * @pre Bid has to be bigger than zero, + * @pre Bid's symbol must be system token, + * @pre Bidder account has to be different than current highest bidder, + * @pre Bid must increase current bid by 10%, + * @pre Auction must still be opened. + */ [[eosio::action]] void bidname( name bidder, name newname, asset bid ); + /** + * Bid refund action. + * + * @details Allows the account `bidder` to get back the amount it bid so far on a `newname` name. + * + * @param bidder - the account that gets refunded, + * @param newname - the name for which the bid was placed and now it gets refunded for. + */ [[eosio::action]] void bidrefund( name bidder, name newname ); @@ -602,7 +1149,21 @@ namespace eosiosystem { using updaterex_action = eosio::action_wrapper<"updaterex"_n, &system_contract::updaterex>; using rexexec_action = eosio::action_wrapper<"rexexec"_n, &system_contract::rexexec>; using setrex_action = eosio::action_wrapper<"setrex"_n, &system_contract::setrex>; + /** + * Move to savings action. + * + * @details Moves a specified amount of REX to savings bucket. + * @param owner - account name of REX owner + * @param rex - amount of REX to be moved + */ using mvtosavings_action = eosio::action_wrapper<"mvtosavings"_n, &system_contract::mvtosavings>; + /** + * Move from savings action. + * + * @details Moves a specified amount of REX from savings bucket + * @param owner - account name of REX owner + * @param rex - amount of REX to be moved + */ using mvfrsavings_action = eosio::action_wrapper<"mvfrsavings"_n, &system_contract::mvfrsavings>; using consolidate_action = eosio::action_wrapper<"consolidate"_n, &system_contract::consolidate>; using closerex_action = eosio::action_wrapper<"closerex"_n, &system_contract::closerex>; @@ -727,4 +1288,5 @@ namespace eosiosystem { registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; }; -} /// eosiosystem + /** @}*/ // end of @defgroup eosiosystem eosio.system +} /// eosiosystem \ No newline at end of file diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index aba1eefe..e7dc2d2a 100755 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -6,12 +6,17 @@ namespace eosiosystem { using eosio::asset; using eosio::symbol; + /** + * @addtogroup eosiosystem + * @{ + */ typedef double real_type; /** - * Uses Bancor math to create a 50/50 relay between two asset types. The state of the - * bancor exchange is entirely contained within this struct. There are no external - * side effects associated with using this API. + * Uses Bancor math to create a 50/50 relay between two asset types. + * + * @details The state of the bancor exchange is entirely contained within this struct. + * There are no external side effects associated with using this API. */ struct [[eosio::table, eosio::contract("eosio.system")]] exchange_state { asset supply; @@ -36,5 +41,5 @@ namespace eosiosystem { }; typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; - + /** @}*/ // enf of @addtogroup eosiosystem } /// namespace eosiosystem diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 868dea33..9ae04ffd 100755 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -18,6 +18,16 @@ namespace eosiosystem { using eosio::public_key; using eosio::ignore; + /** + * @addtogroup eosiosystem + * @{ + */ + /** + * A weighted permission. + * + * @details Defines a weighted permission, that is a permission which has a weight associated. + * A permission is defined by an account name plus a permission name. + */ struct permission_level_weight { permission_level permission; uint16_t weight; @@ -26,6 +36,11 @@ namespace eosiosystem { EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) }; + /** + * Weighted key. + * + * @details A weighted key is defined by a public key and an associated weight. + */ struct key_weight { eosio::public_key key; uint16_t weight; @@ -34,6 +49,11 @@ namespace eosiosystem { EOSLIB_SERIALIZE( key_weight, (key)(weight) ) }; + /** + * Wait weight. + * + * @details A wait weight is defined by a number of seconds to wait for and a weight. + */ struct wait_weight { uint32_t wait_sec; uint16_t weight; @@ -42,6 +62,15 @@ namespace eosiosystem { EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) }; + /** + * Blockchain authority. + * + * @details An authority is defined by: + * - a vector of key_weights (a key_weight is a public key plus a wieght), + * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) + * - a vector of wait_weights (a wait_weight is defined by a number of seconds to wait and a weight) + * - a threshold value + */ struct authority { uint32_t threshold = 0; std::vector keys; @@ -52,6 +81,19 @@ namespace eosiosystem { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) }; + /** + * Blockchain block header. + * + * @details A block header is defined by: + * - a timestamp, + * - the producer that created it, + * - a confirmed flag default as zero, + * - a link to previous block, + * - a link to the transaction merkel root, + * - a link to action root, + * - a schedule version, + * - and a producers' schedule. + */ struct block_header { uint32_t timestamp; name producer; @@ -67,7 +109,13 @@ namespace eosiosystem { (schedule_version)(new_producers)) }; - + /** + * abi_hash + * + * @details abi_hash is the structure underlying the abihash table and consists of: + * - `owner`: the account owner of the contract's abi + * - `hash`: is the sha256 hash of the abi/binary + */ struct [[eosio::table("abihash"), eosio::contract("eosio.system")]] abi_hash { name owner; capi_checksum256 hash; @@ -76,8 +124,11 @@ namespace eosiosystem { EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; - /* - * Method parameters commented out to prevent generation of code that parses input data. + // Method parameters commented out to prevent generation of code that parses input data. + /** + * The EOSIO core native contract that governs authorization and contracts' abi. + * + * @details */ class [[eosio::contract("eosio.system")]] native : public eosio::contract { public: @@ -85,16 +136,26 @@ namespace eosiosystem { using eosio::contract::contract; /** - * Called after a new account is created. This code enforces resource-limits rules - * for new accounts as well as new account naming conventions. + * @{ + * These actions map one-on-one with the ones defined in + * [Native Action Handlers](@ref native_action_handlers) section. + * They are present here so they can show up in the abi file and thus user can send them + * to this contract, but they have no specific implementation at this contract level, + * they will execute the implementation at the core level and nothing else. + */ + /** + * New account action + * + * @details Called after a new account is created. This code enforces resource-limits rules + * for new accounts as well as new account naming conventions. * - * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 - * characters long without '.' until a future account auction process is implemented - * which prevents name squatting. + * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 + * characters long without '.' until a future account auction process is implemented + * which prevents name squatting. * - * 2. new accounts must stake a minimal number of tokens (as set in system parameters) - * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. + * 2. new accounts must stake a minimal number of tokens (as set in system parameters) + * therefore, this method will execute an inline buyram from receiver for newacnt in + * an amount equal to the current new account creation fee. */ [[eosio::action]] void newaccount( name creator, @@ -102,40 +163,119 @@ namespace eosiosystem { ignore owner, ignore active); - + /** + * Update authorization action. + * + * @details Updates pemission for an account + * + * @param account - the account for which the permission is updated + * @param pemission - the permission name which is updated + * @param parem - the parent of the permission which is updated + * @param aut - the json describing the permission authorization + */ [[eosio::action]] void updateauth( ignore account, ignore permission, ignore parent, ignore auth ) {} + /** + * Delete authorization action. + * + * @details Deletes the authorization for an account's permision. + * + * @param account - the account for which the permission authorization is deleted, + * @param permission - the permission name been deleted. + */ [[eosio::action]] void deleteauth( ignore account, ignore permission ) {} + /** + * Link authorization action. + * + * @details Assigns a specific action from a contract to a permission you have created. Five system + * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. + * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the + * action needed to be authorized (and the contract belonging to), and looks up which permission + * is needed to pass authorization validation. If a link is set, that permission is used for authoraization + * validation otherwise then active is the default, with the exception of `eosio.any`. + * `eosio.any` is an implicit permission which exists on every account; you can link actions to `eosio.any` + * and that will make it so linked actions are accessible to any permissions defined for the account. + * + * @param account - the permission's owner to be linked and the payer of the RAM needed to store this link, + * @param code - the owner of the action to be linked, + * @param type - the action to be linked, + * @param requirement - the permission to be linked. + */ [[eosio::action]] void linkauth( ignore account, ignore code, ignore type, ignore requirement ) {} + /** + * Unlink authorization action. + * + * @details It's doing the reverse of linkauth action, by unlinking the given action. + * + * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, + * @param code - the owner of the action to be unlinked, + * @param type - the action to be unlinked. + */ [[eosio::action]] void unlinkauth( ignore account, ignore code, ignore type ) {} + /** + * Cancel delay action. + * + * @details Cancels a deferred transaction. + * + * @param canceling_auth - the permission that authorizes this action, + * @param trx_id - the deferred transaction id to be cancelled. + */ [[eosio::action]] void canceldelay( ignore canceling_auth, ignore trx_id ) {} + /** + * On error action. + * + * @details Called every time an error occurs while a transaction was processed. + * + * @param sender_id - the id of the sender, + * @param sent_trx - the transaction that failed. + */ [[eosio::action]] void onerror( ignore sender_id, ignore> sent_trx ) {} + /** + * Set abi action. + * + * @details Sets the contract abi for an account. + * + * @param account - the account for which to set the contract abi. + * @param abi - the abi content to be set, in the form of a blob binary. + */ [[eosio::action]] void setabi( name account, const std::vector& abi ); + /** + * Set code action. + * + * @details Sets the contract code for an account. + * + * @param account - the account for which to set the contract code. + * @param vmtype - reserved, set it to zero. + * @param vmversion - reserved, set it to zero. + * @param code - the code content to be set, in the form of a blob binary.. + */ [[eosio::action]] void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} + /** @}*/ + using newaccount_action = eosio::action_wrapper<"newaccount"_n, &native::newaccount>; using updateauth_action = eosio::action_wrapper<"updateauth"_n, &native::updateauth>; using deleteauth_action = eosio::action_wrapper<"deleteauth"_n, &native::deleteauth>; @@ -145,4 +285,5 @@ namespace eosiosystem { using setcode_action = eosio::action_wrapper<"setcode"_n, &native::setcode>; using setabi_action = eosio::action_wrapper<"setabi"_n, &native::setabi>; }; + /** @}*/ // @addtogroup eosiosystem } diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index b8c3bba3..db44cec3 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -100,13 +100,6 @@ namespace eosiosystem { _gstate2.last_ram_increase = cbt; } - /** - * Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to - * a maximum rate of 3 TB per year. - * - * If update_ram_supply hasn't been called for the most recent block, then new ram will - * be allocated at the old rate up to the present block before switching the rate. - */ void system_contract::setramrate( uint16_t bytes_per_block ) { require_auth( _self ); diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 502c462d..f2fc637f 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -7,12 +7,6 @@ namespace eosiosystem { - /** - * @brief Deposits core tokens to user REX fund - * - * @param owner - REX fund owner - * @param amount - amount of tokens to be deposited - */ void system_contract::deposit( const name& owner, const asset& amount ) { require_auth( owner ); @@ -25,12 +19,6 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } - /** - * @brief Withdraws core tokens from user REX fund - * - * @param owner - REX fund owner - * @param amount - amount of tokens to be withdrawn - */ void system_contract::withdraw( const name& owner, const asset& amount ) { require_auth( owner ); @@ -43,12 +31,6 @@ namespace eosiosystem { { rex_account, owner, amount, "withdraw from REX fund" } ); } - /** - * @brief Buys REX in exchange for core tokens taken out of user REX fund - * - * @param from - owner account name - * @param amount - amount of core tokens to be used for purchase - */ void system_contract::buyrex( const name& from, const asset& amount ) { require_auth( from ); @@ -66,14 +48,6 @@ namespace eosiosystem { buyrex_act.send( rex_received ); } - /** - * @brief Buys REX using staked core tokens - * - * @param owner - owner of staked tokens account name - * @param receiver - account name that tokens have previously been staked to - * @param from_net - amount of tokens to be unstaked from NET bandwidth and used for REX purchase - * @param from_cpu - amount of tokens to be unstaked from CPU bandwidth and used for REX purchase - */ void system_contract::unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ) { require_auth( owner ); @@ -111,12 +85,6 @@ namespace eosiosystem { buyrex_act.send( rex_received ); } - /** - * @brief Sells REX in exchange for core tokens - * - * @param from - owner of REX tokens - * @param rex - amount of REX tokens to be sold - */ void system_contract::sellrex( const name& from, const asset& rex ) { require_auth( from ); @@ -161,11 +129,6 @@ namespace eosiosystem { } } - /** - * @brief Cancels unfilled REX sell order by owner if one exists - * - * @param owner - owner account name - */ void system_contract::cnclrexorder( const name& owner ) { require_auth( owner ); @@ -175,18 +138,6 @@ namespace eosiosystem { _rexorders.erase( itr ); } - /** - * Rents as many core tokens as determined by market price and stakes them for CPU bandwidth - * for the benefit of receiver account. After 30 days the rented core delegation of CPU will - * expire or be renewed at new market price depending on available loan fund. - * - * @brief Rents CPU resources for 30 days in exchange for market-determined price - * - * @param from - account creating and paying for CPU loan - * @param receiver - account receiving rented CPU resources - * @param loan_payment - tokens paid for the loan - * @param loan_fund - additional tokens added to loan fund and used later for loan renewal - */ void system_contract::rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { require_auth( from ); @@ -196,18 +147,6 @@ namespace eosiosystem { update_resource_limits( from, receiver, 0, rented_tokens ); } - /** - * Rents as many core tokens as determined by market price and stakes them for NET bandwidth - * for the benefit of receiver account. After 30 days the rented core delegation of NET will - * expire or be renewed at new market price depending on available loan fund. - * - * @brief Rents NET resources for 30 days in exchange for market-determined price - * - * @param from - account creating and paying for NET loan - * @param receiver - account receiving rented NET resources - * @param loan_payment - tokens paid for the loan - * @param loan_fund - additional tokens added to loan fund and used later for loan renewal - */ void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) { require_auth( from ); @@ -217,14 +156,6 @@ namespace eosiosystem { update_resource_limits( from, receiver, rented_tokens, 0 ); } - /** - * @brief Transfers tokens to the fund of a specific CPU loan in order to be used in loan - * renewal at expiry - * - * @param from - loan creator - * @param loan_num - loan id - * @param payment - tokens added to loan fund - */ void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) { require_auth( from ); @@ -233,14 +164,6 @@ namespace eosiosystem { fund_rex_loan( cpu_loans, from, loan_num, payment ); } - /** - * @brief Transfers tokens to the fund of a specific NET loan in order to be used in loan - * renewal at expiry - * - * @param from - loan creator - * @param loan_num - loan id - * @param payment - tokens added to loan fund - */ void system_contract::fundnetloan( const name& from, uint64_t loan_num, const asset& payment ) { require_auth( from ); @@ -249,13 +172,6 @@ namespace eosiosystem { fund_rex_loan( net_loans, from, loan_num, payment ); } - /** - * @brief Withdraws tokens from the fund of a specific CPU loan - * - * @param from - loan creator - * @param loan_num - loan id - * @param amount - tokens to be withdrawn from loan fund - */ void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) { require_auth( from ); @@ -264,13 +180,6 @@ namespace eosiosystem { defund_rex_loan( cpu_loans, from, loan_num, amount ); } - /** - * @brief Withdraws tokens from the fund of a specific NET loan - * - * @param from - loan creator - * @param loan_num - loan id - * @param amount - tokens to be withdrawn from loan fund - */ void system_contract::defnetloan( const name& from, uint64_t loan_num, const asset& amount ) { require_auth( from ); @@ -279,11 +188,6 @@ namespace eosiosystem { defund_rex_loan( net_loans, from, loan_num, amount ); } - /** - * @brief Updates REX owner vote weight to current value of held REX tokens - * - * @param owner - owner of REX tokens - */ void system_contract::updaterex( const name& owner ) { require_auth( owner ); @@ -310,11 +214,6 @@ namespace eosiosystem { process_rex_maturities( itr ); } - /** - * @brief Sets total_rent balance of REX pool to the passed value - * - * @param balance - the value to which total_rent will be set - */ void system_contract::setrex( const asset& balance ) { require_auth( "eosio"_n ); @@ -327,13 +226,6 @@ namespace eosiosystem { }); } - /** - * @brief Performs REX maintenance by processing a specified number of REX sell orders - * and expired loans - * - * @param user - any user can execute this action - * @param max - number of each of CPU loans, NET loans, and sell orders to be processed - */ void system_contract::rexexec( const name& user, uint16_t max ) { require_auth( user ); @@ -341,12 +233,6 @@ namespace eosiosystem { runrex( max ); } - /** - * @brief Consolidates REX maturity buckets into one bucket that cannot be sold before - * 4 days - * - * @param owner - account name of REX owner - */ void system_contract::consolidate( const name& owner ) { require_auth( owner ); @@ -358,12 +244,6 @@ namespace eosiosystem { consolidate_rex_balance( bitr, rex_in_sell_order ); } - /** - * @brief Moves a specified amount of REX to savings bucket - * - * @param owner - account name of REX owner - * @param rex - amount of REX to be moved - */ void system_contract::mvtosavings( const name& owner, const asset& rex ) { require_auth( owner ); @@ -398,12 +278,6 @@ namespace eosiosystem { put_rex_savings( bitr, rex_in_savings + rex.amount ); } - /** - * @brief Moves a specified amount of REX from savings bucket - * - * @param owner - account name of REX owner - * @param rex - amount of REX to be moved - */ void system_contract::mvfrsavings( const name& owner, const asset& rex ) { require_auth( owner ); @@ -427,11 +301,6 @@ namespace eosiosystem { update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } - /** - * @brief Deletes unused REX-related database entries and frees RAM - * - * @param owner - user account name - */ void system_contract::closerex( const name& owner ) { require_auth( owner ); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 3d9016be..14e2400c 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -23,14 +23,6 @@ namespace eosiosystem { using eosio::singleton; using eosio::transaction; - /** - * This method will create a producer_config and producer_info object for 'producer' - * - * @pre producer is not already registered - * @pre producer to register is an account - * @pre authority of producer to register - * - */ void system_contract::regproducer( const name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { check( url.size() < 512, "url too long" ); check( producer_key != eosio::public_key(), "public key should not be the default value" ); @@ -174,22 +166,6 @@ namespace eosiosystem { return new_votepay_share; } - /** - * @pre producers must be sorted from lowest to highest and must be registered and active - * @pre if proxy is set then no producers can be voted for - * @pre if proxy is set then proxy account must exist and be registered as a proxy - * @pre every listed producer or proxy must have been previously registered - * @pre voter must authorize this action - * @pre voter must have previously staked some amount of CORE_SYMBOL for voting - * @pre voter->staked must be up to date - * - * @post every producer previously voted for will have vote reduced by previous vote weight - * @post every producer newly voted for will have vote increased by new vote amount - * @post prior proxy will proxied_vote_weight decremented by previous vote weight - * @post new proxy will proxied_vote_weight incremented by new vote weight - * - * If voting for a proxy, the producer votes will not change until the proxy updates their own vote. - */ void system_contract::voteproducer( const name voter_name, const name proxy, const std::vector& producers ) { require_auth( voter_name ); vote_stake_updater( voter_name ); @@ -321,15 +297,6 @@ namespace eosiosystem { }); } - /** - * An account marked as a proxy can vote with the weight of other accounts which - * have selected it as a proxy. Other accounts must refresh their voteproducer to - * update the proxy's weight. - * - * @param isproxy - true if proxy wishes to vote on behalf of others, false otherwise - * @pre proxy must have something staked (existing row in voters table) - * @pre new state must be different than current state - */ void system_contract::regproxy( const name proxy, bool isproxy ) { require_auth( proxy ); diff --git a/contracts/eosio.token/README.md b/contracts/eosio.token/README.md deleted file mode 100755 index b482fc40..00000000 --- a/contracts/eosio.token/README.md +++ /dev/null @@ -1,7 +0,0 @@ -eosio.token ------------ - -This eosio contract allows users to create, issue, and manage tokens on -eosio based blockchains. - - diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index 2463d121..ee01c4d1 100755 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -17,32 +17,116 @@ namespace eosio { using std::string; + /** + * @defgroup eosiotoken eosio.token + * @ingroup eosiocontracts + * + * eosio.token contract + * + * @details eosio.token contract defines the structures and actions that allow users to create, issue, and manage + * tokens on eosio based blockchains. + * @{ + */ class [[eosio::contract("eosio.token")]] token : public contract { public: using contract::contract; + /** + * Create action. + * + * @details Allows `issuer` account to create a token in supply of `maximum_supply`. + * @param issuer - the account that creates the token, + * @param maximum_supply - the maximum supply set for the token created. + * + * @pre Token symbol has to be valid, + * @pre Token symbol must not be already created, + * @pre maximum_supply has to be smaller than the maximum supply allowed by the system: 1^62 - 1. + * @pre Maximum supply must be positive; + * + * If validation is successful a new entry in statstable for token symbol scope gets created. + */ [[eosio::action]] void create( name issuer, asset maximum_supply); - + /** + * Issue action. + * + * @details This action issues to `to` account a `quantity` of tokens. + * + * @param to - the account to issue tokens to, + * @param quntity - the amount of tokens to be issued, + * @memo - the memo string that accompanies the token issue transaction. + */ [[eosio::action]] void issue( name to, asset quantity, string memo ); + /** + * Retire action. + * + * @details The opposite for create action, if all validations succeed, + * it debits the statstable.supply amount. + * + * @param quantity - the quantity of tokens to retire, + * @param memo - the memo string to accompany the transaction. + */ [[eosio::action]] void retire( asset quantity, string memo ); + /** + * Transfer action. + * + * @details Allows `from` account to transfer to `to` account the `quantity` tokens. + * One account is debited and the other is credited with quantity tokens. + * + * @param from - the account to transfer from, + * @param to - the account to be transferred to, + * @param quantity - the quantity of tokens to be transferred, + * @param memo - the memo string to accompany the transaction. + */ [[eosio::action]] void transfer( name from, name to, asset quantity, string memo ); - + /** + * Open action. + * + * @details Allows `ram_payer` to create an account `owner` with zero balance for + * token `symbol` at the expense of `ram_payer`. + * + * @param owner - the account to be created, + * @param symbol - the token to be payed with by `ram_payer`, + * @param ram_payer - the account that supports the cost of this action. + * + * More information can be read [here](https://github.com/EOSIO/eosio.contracts/issues/62) + * and [here](https://github.com/EOSIO/eosio.contracts/issues/61). + */ [[eosio::action]] void open( name owner, const symbol& symbol, name ram_payer ); + /** + * Close action. + * + * @details This action is the opposite for open, it closes the account `owner` + * for token `symbol`. + * + * @param owner - the owner account to execute the close action for, + * @param symbol - the symbol of the token to execute the close action for. + * + * @pre The pair of owner plus symbol has to exist otherwise no action is executed, + * @pre If the pair of owner plus symbol exists, the balance has to be zero. + */ [[eosio::action]] void close( name owner, const symbol& symbol ); + /** + * Get supply method. + * + * @details Gets the supply for token `sym_code`, created by `token_contract_account` account. + * + * @param token_contract_account - the account to get the supply for, + * @param sym_code - the symbol to get the supply for. + */ static asset get_supply( name token_contract_account, symbol_code sym_code ) { stats statstable( token_contract_account, sym_code.raw() ); @@ -50,6 +134,16 @@ namespace eosio { return st.supply; } + /** + * Get balance method. + * + * @details Get the balance for a token `sym_code` created by `token_contract_account` account, + * for account `owner`. + * + * @param token_contract_account - the token creator account, + * @param owner - the account for which the token balance is returned, + * @param sym_code - the token for which the balance is returned. + */ static asset get_balance( name token_contract_account, name owner, symbol_code sym_code ) { accounts accountstable( token_contract_account, owner.value ); @@ -84,5 +178,5 @@ namespace eosio { void sub_balance( name owner, asset value ); void add_balance( name owner, asset value, name ram_payer ); }; - + /** @}*/ // end of @defgroup eosiotoken eosio.token } /// namespace eosio diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp index 243cb8b0..c887df43 100755 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -5,15 +5,38 @@ #include namespace eosio { + /** + * @defgroup eosiowrap eosio.wrap + * @ingroup eosiocontracts + * eosio.wrap contract simplifies Block Producer superuser actions by making them more readable and easier to audit. + * @details It does not grant block producers any additional powers that do not already exist within the + * system. Currently, 15/21 block producers can already change an account's keys or modify an + * account's contract at the request of ECAF or an account's owner. However, the current method + * is opaque and leaves undesirable side effects on specific system accounts. + * eosio.wrap allows for a cleaner method of implementing these important governance actions. + * @{ + */ class [[eosio::contract("eosio.wrap")]] wrap : public contract { public: using contract::contract; + /** + * Execute action. + * + * @details Execute a transaction while bypassing regular authorization checks. + * + * @param executer - account executing the transaction, + * @param trx - the transaction to be executed. + * + * @pre Requires authorization of eosio.wrap which needs to be a privileged account. + * + * @post Deferred transaction RAM usage is billed to 'executer' + */ [[eosio::action]] void exec( ignore executer, ignore trx ); using exec_action = eosio::action_wrapper<"exec"_n, &wrap::exec>; }; - + /** @}*/ // end of @defgroup eosiowrap eosio.wrap } /// namespace eosio diff --git a/docs/eosio.msig.md b/docs/eosio.msig.md new file mode 100644 index 00000000..2006a468 --- /dev/null +++ b/docs/eosio.msig.md @@ -0,0 +1,182 @@ +eosio.msig examples +------------------- + +Cleos usage example for issuing tokens. +--------------------------------------- + +Prerequisites: + - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. + - account 'treasury' is the issuer of SYS token. + - account 'tester' exists. + - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. + +One user creates a proposal: +```` +$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester + +executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles +# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... +```` + + +Another user reviews the transaction: +```` +$ cleos multisig review tester test +{ + "proposal_name": "test", + "requested_approvals": [{ + "actor": "treasury", + "permission": "active" + } + ], + "provided_approvals": [], + "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", + "transaction": { + "expiration": "2018-05-01T00:00:00", + "region": 0, + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_kcpu_usage": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "issue", + "authorization": [{ + "actor": "treasury", + "permission": "active" + } + ], + "data": { + "to": "tester", + "quantity": "1000.0000 SYS", + "memo": "" + }, + "hex_data": "000000005c95b1ca809698000000000004454f530000000000" + } + ] + } +} +```` + + +And then approves it: +```` +$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury + +executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles +# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} +```` + + +First user initiates execution: +```` +$ cleos multisig exec tester test -p tester + +executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles +# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} +```` + + +Cleos usage example for transferring tokens. +------------------------------------------- + +Prerequisites: + - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. + - account 'treasury' has at least 1.1000 SYS token balance. + - account 'tester' exists. + - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. + +One user creates a proposal: +```` +$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester + +executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles +# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... +```` + + +Another user reviews the transaction: +```` +$ cleos multisig review tester test +{ + "proposal_name": "test", + "requested_approvals": [{ + "actor": "treasury", + "permission": "active" + } + ], + "provided_approvals": [], + "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", + "transaction": { + "expiration": "2018-05-01T00:00:00", + "region": 0, + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_kcpu_usage": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "transfer", + "authorization": [{ + "actor": "treasury", + "permission": "active" + } + ], + "data": { + "from": "treasury", + "to": "tester", + "quantity": "1.0000 SYS", + "memo": "" + }, + "hex_data": "000000005c95b1ca809698000000000004454f530000000000" + } + ] + } +} +```` + + +And then approves it: +```` +$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury + +executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles +# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} +```` + + +First user check account balance before executing the proposed transaction +```` +$ cleos get account tester +... +SYS balances: + liquid: 1.0487 SYS + staked: 2.0000 SYS + unstaking: 0.0000 SYS + total: 4.0487 SYS +```` + + +First user initiates execution of proposed transaction: +```` +$ cleos multisig exec tester test -p tester + +executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles +# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} +```` + + +First user can check account balance, it should be increased by 1.0000 SYS +```` +$ cleos get account tester +... +SYS balances: + liquid: 2.0487 SYS + staked: 2.0000 SYS + unstaking: 0.0000 SYS + total: 4.0487 SYS +```` diff --git a/contracts/eosio.wrap/README.md b/docs/eosio.wrap.md old mode 100755 new mode 100644 similarity index 98% rename from contracts/eosio.wrap/README.md rename to docs/eosio.wrap.md index 0bbdb1d8..0f3395fc --- a/contracts/eosio.wrap/README.md +++ b/docs/eosio.wrap.md @@ -1,18 +1,6 @@ # eosio.wrap -## 1. Actions: -The naming convention is codeaccount::actionname followed by a list of parameters. - -Execute a transaction while bypassing regular authorization checks (requires authorization of eosio.wrap which needs to be a privileged account). - -### eosio.wrap::exec executer trx - - **executer** account executing the transaction - - **trx** transaction to execute - - Deferred transaction RAM usage is billed to 'executer' - - -## 2. Installing the eosio.wrap contract +## 1. Installing the eosio.wrap contract The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. @@ -22,9 +10,9 @@ The `eosio.wrap` account also needs to have sufficient RAM to host the contract This guide will be using cleos to carry out the process. -### 2.1 Create the eosio.wrap account +### 1.1 Create the eosio.wrap account -#### 2.1.1 Generate the transaction to create the eosio.wrap account +#### 1.1.1 Generate the transaction to create the eosio.wrap account The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. @@ -287,7 +275,7 @@ $ cat producer_permissions.json ] ``` -#### 2.1.2 Propose the transaction to create the eosio.wrap account +#### 1.1.2 Propose the transaction to create the eosio.wrap account Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. @@ -303,7 +291,7 @@ executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.1.3 Review and approve the transaction to create the eosio.wrap account +#### 1.1.3 Review and approve the transaction to create the eosio.wrap account Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. @@ -362,7 +350,7 @@ executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.1.4 Execute the transaction to create the eosio.wrap account +#### 1.1.4 Execute the transaction to create the eosio.wrap account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). @@ -401,9 +389,9 @@ producers: ``` -### 2.2 Deploy the eosio.wrap contract +### 1.2 Deploy the eosio.wrap contract -#### 2.2.1 Generate the transaction to deploy the eosio.wrap contract +#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. @@ -464,7 +452,7 @@ $ head -n 9 deploy_wrap_contract_trx.json This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. -#### 2.2.2 Propose the transaction to deploy the eosio.wrap contract +#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. @@ -480,7 +468,7 @@ executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.2.3 Review and approve the transaction to deploy the eosio.wrap contract +#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. @@ -555,7 +543,7 @@ executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e4648 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.2.4 Execute the transaction to create the eosio.wrap account +#### 1.2.4 Execute the transaction to create the eosio.wrap account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). @@ -577,9 +565,9 @@ $ sha256sum contracts/eosio.wrap/eosio.wrap.wasm If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. -## 3. Using the eosio.wrap contract +## 2. Using the eosio.wrap contract -### 3.1 Example: Updating owner authority of an arbitrary account +### 2.1 Example: Updating owner authority of an arbitrary account This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. @@ -613,7 +601,7 @@ $ cat producer_permissions.json ] ``` -#### 3.1.1 Generate the transaction to change the owner permission of an account +#### 2.1.1 Generate the transaction to change the owner permission of an account The goal of this example is for the block producers to change the owner permission of the account `alice`. @@ -754,7 +742,7 @@ Then modify the transaction in wrap_update_alice_owner_trx.json as follows: * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. -#### 3.1.2 Propose the transaction to change the owner permission of an account +#### 2.1.2 Propose the transaction to change the owner permission of an account The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: ``` @@ -764,7 +752,7 @@ executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 3.1.3 Review and approve the transaction to change the owner permission of an account +#### 2.1.3 Review and approve the transaction to change the owner permission of an account Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. ``` @@ -847,7 +835,7 @@ executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 3.1.4 Execute the transaction to change the owner permission of an account +#### 2.1.4 Execute the transaction to change the owner permission of an account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). From 765310c71682ee93a9c920cf4ebf04e6cda2d39f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Mar 2019 15:07:57 -0400 Subject: [PATCH 0737/1048] Add additional check specific to b1 account --- contracts/eosio.system/src/rex.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 4d0d72c0..fc2c1408 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -141,6 +141,9 @@ namespace eosiosystem { auto current_order = fill_rex_order( bitr, rex ); asset pending_sell_order = update_rex_account( from, current_order.proceeds, current_order.stake_change ); if ( !current_order.success ) { + if ( from == "b1"_n ) { + check( false, "b1 sellrex orders should not be queued" ); + } /** * REX order couldn't be filled and is added to queue. * If account already has an open order, requested rex is added to existing order. From 3dfd2a39ae03d5cdd4b2695fffa3cbd400617b01 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Mar 2019 15:10:52 -0400 Subject: [PATCH 0738/1048] Removed unnecessary update_rex_account call in REX rent actions --- contracts/eosio.system/src/rex.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index fc2c1408..c81cad83 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -777,7 +777,6 @@ namespace eosiosystem { check( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); check( 0 < payment.amount && 0 <= fund.amount, "must use positive asset amount" ); - update_rex_account( from, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); transfer_from_fund( from, payment + fund ); const auto& pool = _rexpool.begin(); /// already checked that _rexpool.begin() != _rexpool.end() in rex_loans_available() From 67301ae92214a56d8433794d6511e47e364b3634 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Mar 2019 15:11:25 -0400 Subject: [PATCH 0739/1048] Unit test for b1 vesting --- tests/eosio.system_tests.cpp | 82 ++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index af1d8507..e00a3159 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4838,6 +4838,88 @@ BOOST_FIXTURE_TEST_CASE( set_rex, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { + + cross_15_percent_threshold(); + + produce_block( fc::days(14) ); + + const asset init_balance = core_sym::from_string("25000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance ); + + const name b1{ N(b1) }; + + issue( alice, core_sym::from_string("20000.0000"), config::system_account_name ); + issue( bob, core_sym::from_string("20000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), bidname( bob, b1, core_sym::from_string( "0.5000" ) ) ); + BOOST_REQUIRE_EQUAL( success(), bidname( alice, b1, core_sym::from_string( "1.0000" ) ) ); + + produce_block( fc::days(1) ); + + create_accounts_with_resources( { b1 }, alice ); + + const asset stake_amount = core_sym::from_string("50000000.0000"); + const asset half_stake = core_sym::from_string("25000000.0000"); + const asset small_amount = core_sym::from_string("1000.0000"); + issue( b1, stake_amount + stake_amount + stake_amount, config::system_account_name ); + + stake( b1, b1, stake_amount, stake_amount ); + + BOOST_REQUIRE_EQUAL( 2 * stake_amount.get_amount(), get_voter_info( b1 )["staked"].as() ); + + BOOST_REQUIRE_EQUAL( success(), unstake( b1, b1, small_amount, small_amount ) ); + + produce_block( fc::days(4) ); + + BOOST_REQUIRE_EQUAL( success(), push_action( b1, N(refund), mvo()("owner", b1) ) ); + + BOOST_REQUIRE_EQUAL( 2 * ( stake_amount.get_amount() - small_amount.get_amount() ), + get_voter_info( b1 )["staked"].as() ); + + produce_block( fc::days( 3 * 364 ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), + unstake( b1, b1, half_stake, half_stake ) ); + + BOOST_REQUIRE_EQUAL( success(), vote( b1, { }, N(proxyaccount) ) ); + BOOST_REQUIRE_EQUAL( success(), unstaketorex( b1, b1, half_stake, half_stake ) ); + + produce_block( fc::days(5) ); + produce_blocks(1); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), + sellrex( b1, get_rex_balance( b1 ) ) ); + + produce_block( fc::days( 2 * 364 ) ); + + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("10000.0000") ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 sellrex orders should not be queued"), + sellrex( b1, get_rex_balance( b1 ) ) ); + + produce_block( fc::days( 30 ) ); + + BOOST_REQUIRE_EQUAL( success(), sellrex( b1, get_rex_balance( b1 ) ) ); + + produce_block( fc::days( 3 * 364 ) ); + + BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), + unstake( b1, b1, half_stake - small_amount, half_stake - small_amount ) ); + + produce_block( fc::days( 1 * 364 ) ); + + BOOST_REQUIRE_EQUAL( success(), + unstake( b1, b1, half_stake - small_amount, half_stake - small_amount ) ); + + produce_block( fc::days(4) ); + BOOST_REQUIRE_EQUAL( success(), push_action( b1, N(refund), mvo()("owner", b1) ) ); + +} FC_LOG_AND_RETHROW() + + BOOST_AUTO_TEST_CASE( setabi_bios ) try { validating_tester t( validating_tester::default_config() ); abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); From 23dc03530c55dea6c0f4d633fe9783b5a98d6567 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 22 Mar 2019 10:52:37 -0400 Subject: [PATCH 0740/1048] Removed unnecessary update_rex_account call in REX deposit action --- contracts/eosio.system/src/rex.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index c81cad83..e6d82236 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -25,7 +25,6 @@ namespace eosiosystem { transfer_act.send( owner, rex_account, amount, "deposit to REX fund" ); } transfer_to_fund( owner, amount ); - update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); } /** From 9b6b6fbd4dd15ad0277ce5f86858e3f477edd7cf Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Fri, 22 Mar 2019 18:07:52 -0400 Subject: [PATCH 0741/1048] inherit rex_result from eosio::contract --- contracts/eosio.system/include/eosio.system/rex.results.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index a129e56c..d1ba0fb0 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -8,8 +8,11 @@ using eosio::name; using eosio::asset; using eosio::action_wrapper; -class [[eosio::contract("rex.results")]] rex_results { +class [[eosio::contract("rex.results")]] rex_results : eosio::contract { public: + + using eosio::contract::contract; + [[eosio::action]] void buyresult( const asset& rex_received ); From 06e1b2f797b757a41bab5087cf64864e0115b5e4 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sat, 23 Mar 2019 13:54:11 -0400 Subject: [PATCH 0742/1048] Small optimization in runrex --- contracts/eosio.system/src/rex.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index e6d82236..4dcf24ad 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -739,7 +739,7 @@ namespace eosiosystem { } /// process sellrex orders - { + if ( _rexorders.begin() != _rexorders.end() ) { auto idx = _rexorders.get_index<"bytime"_n>(); auto oitr = idx.begin(); for ( uint16_t i = 0; i < max; ++i ) { @@ -1045,7 +1045,7 @@ namespace eosiosystem { total += rb.rex_maturities.front().second; rb.rex_maturities.pop_front(); } - if (total > 0 ) { + if ( total > 0 ) { rb.rex_maturities.emplace_back( get_rex_maturity(), total ); } }); From 6299023ffba6af7ecf6d59ae52a11c65b91d08d2 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 24 Mar 2019 16:10:09 -0400 Subject: [PATCH 0743/1048] Moved check to outside fill_rex_order --- contracts/eosio.system/src/rex.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 4dcf24ad..1f19a312 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -137,7 +137,10 @@ namespace eosiosystem { process_rex_maturities( bitr ); check( rex.amount <= bitr->matured_rex, "insufficient available rex" ); - auto current_order = fill_rex_order( bitr, rex ); + const auto current_order = fill_rex_order( bitr, rex ); + if ( current_order.success && current_order.proceeds.amount == 0 ) { + check( false, "proceeds are negligible" ); + } asset pending_sell_order = update_rex_account( from, current_order.proceeds, current_order.stake_change ); if ( !current_order.success ) { if ( from == "b1"_n ) { @@ -827,8 +830,6 @@ namespace eosiosystem { asset stake_change( 0, core_symbol() ); bool success = false; - check( proceeds.amount > 0, "proceeds are negligible" ); - const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible if ( proceeds.amount <= available_unlent ) { @@ -892,7 +893,7 @@ namespace eosiosystem { { check( 0 < amount.amount && amount.symbol == core_symbol(), "must transfer positive amount from REX fund" ); auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); - check( amount <= itr->balance, "insufficient funds"); + check( amount <= itr->balance, "insufficient funds" ); _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { fund.balance.amount -= amount.amount; }); From 2f26d46cb174ccae87a9df5e4a2661197c93e86f Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Tue, 26 Mar 2019 14:00:44 -0400 Subject: [PATCH 0744/1048] Create CONTRIBUTING.md --- CONTRIBUTING.md | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..76e61028 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,148 @@ +# Contributing to eosio.contracts + +Interested in contributing? That's awesome! Here are some guidelines to get started quickly and easily: + +- [Reporting An Issue](#reporting-an-issue) + - [Bug Reports](#bug-reports) + - [Feature Requests](#feature-requests) + - [Change Requests](#change-requests) +- [Working on eosio.contracts](#working-on-eosiocontracts) + - [Feature Branches](#feature-branches) + - [Submitting Pull Requests](#submitting-pull-requests) + - [Testing and Quality Assurance](#testing-and-quality-assurance) +- [Conduct](#conduct) +- [Contributor License & Acknowledgments](#contributor-license--acknowledgments) +- [References](#references) + +## Reporting An Issue + +If you're about to raise an issue because you think you've found a problem with eosio.contracts, or you'd like to make a request for a new feature in the codebase, or any other reason… please read this first. + +The GitHub issue tracker is the preferred channel for [bug reports](#bug-reports), [feature requests](#feature-requests), and [submitting pull requests](#submitting-pull-requests), but please respect the following restrictions: + +* Please **search for existing issues**. Help us keep duplicate issues to a minimum by checking to see if someone has already reported your problem or requested your idea. + +* Please **be civil**. Keep the discussion on topic and respect the opinions of others. See also our [Contributor Code of Conduct](#conduct). + +### Bug Reports + +A bug is a _demonstrable problem_ that is caused by the code in the repository. Good bug reports are extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +1. **Check if the issue has been fixed** — look for [closed issues in the + current milestone](https://github.com/EOSIO/eosio.contracts/issues?q=is%3Aissue+is%3Aclosed) or try to reproduce it + using the latest `develop` branch. + +A good bug report shouldn't leave others needing to chase you up for more information. Be sure to include the details of your environment and relevant tests that demonstrate the failure. + +[Report a bug](https://github.com/EOSIO/eosio.contracts/issues/new?title=Bug%3A) + +### Feature Requests + +Feature requests are welcome. Before you submit one be sure to have: + +1. **Use the GitHub search** and check the feature hasn't already been requested. +1. Take a moment to think about whether your idea fits with the scope and aims of the project. +1. Remember, it's up to *you* to make a strong case to convince the project's leaders of the merits of this feature. Please provide as much detail and context as possible, this means explaining the use case and why it is likely to be common. + +### Change Requests + +Change requests cover both architectural and functional changes to how eosio.contracts works. If you have an idea for a new or different dependency, a refactor, or an improvement to a feature, etc - please be sure to: + +1. **Use the GitHub search** and check someone else didn't get there first +1. Take a moment to think about the best way to make a case for, and explain what you're thinking. Are you sure this shouldn't really be + a [bug report](#bug-reports) or a [feature request](#feature-requests)? Is it really one idea or is it many? What's the context? What problem are you solving? Why is what you are suggesting better than what's already there? + +## Working on eosio.contracts + +Code contributions are welcome and encouraged! If you are looking for a good place to start, check out the [good first issue](https://github.com/EOSIO/eosio.contracts/labels/good%20first%20issue) label in GitHub issues. + +Also, please follow these guidelines when submitting code: + +### Feature Branches + +To get it out of the way: + +- **[develop](https://github.com/EOSIO/eosio.contracts/tree/develop)** is the development branch. All work on the next release happens here so you should generally branch off `develop`. Do **NOT** use this branch for a production site. +- **[master](https://github.com/EOSIO/eosio.contracts/tree/master)** contains the latest release of eosio.contracts. This branch may be used in production. Do **NOT** use this branch to work on eosio.contracts's source. + +### Submitting Pull Requests + +Pull requests are awesome. If you're looking to raise a PR for something which doesn't have an open issue, please think carefully about [raising an issue](#reporting-an-issue) which your PR can close, especially if you're fixing a bug. This makes it more likely that there will be enough information available for your PR to be properly tested and merged. + +### Testing and Quality Assurance + +Never underestimate just how useful quality assurance is. If you're looking to get involved with the code base and don't know where to start, checking out and testing a pull request is one of the most useful things you could do. + +Essentially, [check out the latest develop branch](#working-on-eosio.contracts), take it for a spin, and if you find anything odd, please follow the [bug report guidelines](#bug-reports) and let us know! + +## Conduct + +While contributing, please be respectful and constructive, so that participation in our project is a positive experience for everyone. + +Examples of behavior that contributes to creating a positive environment include: +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior include: +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Contributor License & Acknowledgments + +Whenever you make a contribution to this project, you license your contribution under the same terms as set out in LICENSE, and you represent and warrant that you have the right to license your contribution under those terms. Whenever you make a contribution to this project, you also certify in the terms of the Developer’s Certificate of Origin set out below: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## References + +* Overall CONTRIB adapted from https://github.com/mathjax/MathJax/blob/master/CONTRIBUTING.md +* Conduct section adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html From ca5071f2a480b5cbcb2499811128bbdaf927e832 Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Tue, 26 Mar 2019 14:01:08 -0400 Subject: [PATCH 0745/1048] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 55e80764..31dee1d9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018, Respective Authors all rights reserved. +Copyright (c) 2017-2019 block.one all rights reserved. The MIT License From 8bf9584461c1b4c269385e77ede25d167e1d86c8 Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Tue, 26 Mar 2019 14:02:21 -0400 Subject: [PATCH 0746/1048] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 5bfacdf1..74e5ce7b 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,17 @@ After build: * The unit tests executable is placed in the _build/tests_ and is named __unit_test__. * The contracts are built into a _bin/\_ folder in their respective directories. * Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory. + +## Contributing + +[Contributing Guide](./CONTRIBUTING.md) + +[Code of Conduct](./CONTRIBUTING.md#conduct) + +## License + +[MIT](./LICENSE) + +## Important + +See LICENSE for copyright and license terms. Block.one makes its contribution on a voluntary basis as a member of the EOSIO community and is not responsible for ensuring the overall performance of the software or any related applications. We make no representation, warranty, guarantee or undertaking in respect of the software or any related documentation, whether expressed or implied, including but not limited to the warranties or merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or documentation or the use or other dealings in the software or documentation. Any test results or performance figures are indicative and will not reflect performance under all conditions. Any reference to any third party or third-party product, service or other resource is not an endorsement or recommendation by Block.one. We are not responsible, and disclaim any and all responsibility and liability, for your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so the information here may be out of date or inaccurate. From 3ad902db15f2bc7daf9ee8127a928c77b31f3726 Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Thu, 28 Mar 2019 13:41:24 -0400 Subject: [PATCH 0747/1048] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 31dee1d9..22d36d65 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017-2019 block.one all rights reserved. +Copyright (c) 2017-2019 block.one and its contributors. All rights reserved. The MIT License From 2eb6b8a005d124f18dce08a20f7fbba219eb814e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 28 Mar 2019 20:12:06 -0400 Subject: [PATCH 0748/1048] Bump version to v1.6.0 --- CMakeLists.txt | 2 +- README.md | 4 ++-- contracts/eosio.system/src/rex.cpp | 2 +- tests/CMakeLists.txt | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0121c2d2..f6c69514 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 6) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc3) +#set(VERSION_SUFFIX rc3) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 5bfacdf1..c84a10fd 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.6.0-rc3 +## Version : 1.6.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -14,7 +14,7 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) Dependencies: -* [eosio v1.6.x](https://github.com/EOSIO/eos/releases/tag/v1.6.3) +* [eosio v1.7.x](https://github.com/EOSIO/eos/releases/tag/v1.7.0) * [eosio.cdt v1.5.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.5.0) To build the contracts and the unit tests: diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 1f19a312..6bb1c92a 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -759,7 +759,7 @@ namespace eosiosystem { order.stake_change.amount = result.stake_change.amount; order.close(); }); - /// send dummy action to show and owner and proceeds of filled sellrex order + /// send dummy action to show owner and proceeds of filled sellrex order rex_results::orderresult_action order_act( rex_account, std::vector{ } ); order_act.send( order_owner, result.proceeds ); } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4660381a..40502b3f 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 3.5 ) -set(EOSIO_VERSION_MIN "1.4") -set(EOSIO_VERSION_SOFT_MAX "1.6") +set(EOSIO_VERSION_MIN "1.6") +set(EOSIO_VERSION_SOFT_MAX "1.7") #set(EOSIO_VERSION_HARD_MAX "") find_package(eosio) From cc4158ac58f9620343e8cb50d6ee5e0173d11c2d Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Tue, 26 Mar 2019 14:00:44 -0400 Subject: [PATCH 0749/1048] Create CONTRIBUTING.md --- CONTRIBUTING.md | 148 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..76e61028 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,148 @@ +# Contributing to eosio.contracts + +Interested in contributing? That's awesome! Here are some guidelines to get started quickly and easily: + +- [Reporting An Issue](#reporting-an-issue) + - [Bug Reports](#bug-reports) + - [Feature Requests](#feature-requests) + - [Change Requests](#change-requests) +- [Working on eosio.contracts](#working-on-eosiocontracts) + - [Feature Branches](#feature-branches) + - [Submitting Pull Requests](#submitting-pull-requests) + - [Testing and Quality Assurance](#testing-and-quality-assurance) +- [Conduct](#conduct) +- [Contributor License & Acknowledgments](#contributor-license--acknowledgments) +- [References](#references) + +## Reporting An Issue + +If you're about to raise an issue because you think you've found a problem with eosio.contracts, or you'd like to make a request for a new feature in the codebase, or any other reason… please read this first. + +The GitHub issue tracker is the preferred channel for [bug reports](#bug-reports), [feature requests](#feature-requests), and [submitting pull requests](#submitting-pull-requests), but please respect the following restrictions: + +* Please **search for existing issues**. Help us keep duplicate issues to a minimum by checking to see if someone has already reported your problem or requested your idea. + +* Please **be civil**. Keep the discussion on topic and respect the opinions of others. See also our [Contributor Code of Conduct](#conduct). + +### Bug Reports + +A bug is a _demonstrable problem_ that is caused by the code in the repository. Good bug reports are extremely helpful - thank you! + +Guidelines for bug reports: + +1. **Use the GitHub issue search** — check if the issue has already been + reported. + +1. **Check if the issue has been fixed** — look for [closed issues in the + current milestone](https://github.com/EOSIO/eosio.contracts/issues?q=is%3Aissue+is%3Aclosed) or try to reproduce it + using the latest `develop` branch. + +A good bug report shouldn't leave others needing to chase you up for more information. Be sure to include the details of your environment and relevant tests that demonstrate the failure. + +[Report a bug](https://github.com/EOSIO/eosio.contracts/issues/new?title=Bug%3A) + +### Feature Requests + +Feature requests are welcome. Before you submit one be sure to have: + +1. **Use the GitHub search** and check the feature hasn't already been requested. +1. Take a moment to think about whether your idea fits with the scope and aims of the project. +1. Remember, it's up to *you* to make a strong case to convince the project's leaders of the merits of this feature. Please provide as much detail and context as possible, this means explaining the use case and why it is likely to be common. + +### Change Requests + +Change requests cover both architectural and functional changes to how eosio.contracts works. If you have an idea for a new or different dependency, a refactor, or an improvement to a feature, etc - please be sure to: + +1. **Use the GitHub search** and check someone else didn't get there first +1. Take a moment to think about the best way to make a case for, and explain what you're thinking. Are you sure this shouldn't really be + a [bug report](#bug-reports) or a [feature request](#feature-requests)? Is it really one idea or is it many? What's the context? What problem are you solving? Why is what you are suggesting better than what's already there? + +## Working on eosio.contracts + +Code contributions are welcome and encouraged! If you are looking for a good place to start, check out the [good first issue](https://github.com/EOSIO/eosio.contracts/labels/good%20first%20issue) label in GitHub issues. + +Also, please follow these guidelines when submitting code: + +### Feature Branches + +To get it out of the way: + +- **[develop](https://github.com/EOSIO/eosio.contracts/tree/develop)** is the development branch. All work on the next release happens here so you should generally branch off `develop`. Do **NOT** use this branch for a production site. +- **[master](https://github.com/EOSIO/eosio.contracts/tree/master)** contains the latest release of eosio.contracts. This branch may be used in production. Do **NOT** use this branch to work on eosio.contracts's source. + +### Submitting Pull Requests + +Pull requests are awesome. If you're looking to raise a PR for something which doesn't have an open issue, please think carefully about [raising an issue](#reporting-an-issue) which your PR can close, especially if you're fixing a bug. This makes it more likely that there will be enough information available for your PR to be properly tested and merged. + +### Testing and Quality Assurance + +Never underestimate just how useful quality assurance is. If you're looking to get involved with the code base and don't know where to start, checking out and testing a pull request is one of the most useful things you could do. + +Essentially, [check out the latest develop branch](#working-on-eosio.contracts), take it for a spin, and if you find anything odd, please follow the [bug report guidelines](#bug-reports) and let us know! + +## Conduct + +While contributing, please be respectful and constructive, so that participation in our project is a positive experience for everyone. + +Examples of behavior that contributes to creating a positive environment include: +- Using welcoming and inclusive language +- Being respectful of differing viewpoints and experiences +- Gracefully accepting constructive criticism +- Focusing on what is best for the community +- Showing empathy towards other community members + +Examples of unacceptable behavior include: +- The use of sexualized language or imagery and unwelcome sexual attention or advances +- Trolling, insulting/derogatory comments, and personal or political attacks +- Public or private harassment +- Publishing others’ private information, such as a physical or electronic address, without explicit permission +- Other conduct which could reasonably be considered inappropriate in a professional setting + +## Contributor License & Acknowledgments + +Whenever you make a contribution to this project, you license your contribution under the same terms as set out in LICENSE, and you represent and warrant that you have the right to license your contribution under those terms. Whenever you make a contribution to this project, you also certify in the terms of the Developer’s Certificate of Origin set out below: + +``` +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +1 Letterman Drive +Suite D4700 +San Francisco, CA, 94129 + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. +``` + +## References + +* Overall CONTRIB adapted from https://github.com/mathjax/MathJax/blob/master/CONTRIBUTING.md +* Conduct section adapted from the Contributor Covenant, version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html From 0c25a927ac334a31d2a2d69c19ebb57f8db5499f Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Tue, 26 Mar 2019 14:01:08 -0400 Subject: [PATCH 0750/1048] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 55e80764..31dee1d9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2018, Respective Authors all rights reserved. +Copyright (c) 2017-2019 block.one all rights reserved. The MIT License From 037046c9d373007c60ff663ccaef90431ec7dabb Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Tue, 26 Mar 2019 14:02:21 -0400 Subject: [PATCH 0751/1048] Update README.md --- README.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/README.md b/README.md index 5bfacdf1..74e5ce7b 100644 --- a/README.md +++ b/README.md @@ -26,3 +26,17 @@ After build: * The unit tests executable is placed in the _build/tests_ and is named __unit_test__. * The contracts are built into a _bin/\_ folder in their respective directories. * Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory. + +## Contributing + +[Contributing Guide](./CONTRIBUTING.md) + +[Code of Conduct](./CONTRIBUTING.md#conduct) + +## License + +[MIT](./LICENSE) + +## Important + +See LICENSE for copyright and license terms. Block.one makes its contribution on a voluntary basis as a member of the EOSIO community and is not responsible for ensuring the overall performance of the software or any related applications. We make no representation, warranty, guarantee or undertaking in respect of the software or any related documentation, whether expressed or implied, including but not limited to the warranties or merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or documentation or the use or other dealings in the software or documentation. Any test results or performance figures are indicative and will not reflect performance under all conditions. Any reference to any third party or third-party product, service or other resource is not an endorsement or recommendation by Block.one. We are not responsible, and disclaim any and all responsibility and liability, for your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so the information here may be out of date or inaccurate. From fc3f14803805266f2de815fda8aa2937000191ee Mon Sep 17 00:00:00 2001 From: Joseph J Guerra <8146030+josephjguerra@users.noreply.github.com> Date: Thu, 28 Mar 2019 13:41:24 -0400 Subject: [PATCH 0752/1048] Update LICENSE --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 31dee1d9..22d36d65 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017-2019 block.one all rights reserved. +Copyright (c) 2017-2019 block.one and its contributors. All rights reserved. The MIT License From 37163b9d14924c3a6f37d8c09c67538c87b47da4 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 28 Mar 2019 20:47:13 -0400 Subject: [PATCH 0753/1048] update version to 1.7.0-develop --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c2c073af..755cc11b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,9 +3,9 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts) set(VERSION_MAJOR 1) -set(VERSION_MINOR 6) +set(VERSION_MINOR 7) set(VERSION_PATCH 0) -#set(VERSION_SUFFIX rc3) +set(VERSION_SUFFIX develop) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") @@ -83,4 +83,4 @@ ExternalProject_Add( BUILD_ALWAYS 1 TEST_COMMAND "" INSTALL_COMMAND "" -) \ No newline at end of file +) From d38b91c52dc8cd6822acb40613c9d10d159f924f Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 28 Mar 2019 20:58:35 -0400 Subject: [PATCH 0754/1048] upgrade eosio buildkite dependency to 1.7.x --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index daa58525..e70223ba 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=release/1.6.x +eosio=release/1.7.x cdt=release/1.5.x From af81ff668ff54273f61cbb180b6eca18c75a3758 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 1 Apr 2019 19:03:24 -0400 Subject: [PATCH 0755/1048] Used direct Bancor conversion in RAM market --- .../include/eosio.system/exchange_state.hpp | 4 ++ .../eosio.system/src/delegate_bandwidth.cpp | 8 ++-- contracts/eosio.system/src/exchange_state.cpp | 37 ++++++++++++++++++- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index aba1eefe..37702663 100755 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -31,6 +31,10 @@ namespace eosiosystem { asset convert_to_exchange( connector& c, asset in ); asset convert_from_exchange( connector& c, asset in ); asset convert( asset from, const symbol& to ); + asset direct_convert( const asset& from, const symbol& to ); + static asset get_bancor_output( const asset& inp_balance, + const asset& out_balance, + const asset& inp ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) }; diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 7f4270cf..faf1bea7 100755 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -90,7 +90,7 @@ namespace eosiosystem { auto itr = _rammarket.find(ramcore_symbol.raw()); auto tmp = *itr; - auto eosout = tmp.convert( asset(bytes, ram_symbol), core_symbol() ); + auto eosout = tmp.direct_convert( asset(bytes, ram_symbol), core_symbol() ); buyram( payer, receiver, eosout ); } @@ -139,7 +139,7 @@ namespace eosiosystem { const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); _rammarket.modify( market, same_payer, [&]( auto& es ) { - bytes_out = es.convert( quant_after_fee, ram_symbol ).amount; + bytes_out = es.direct_convert( quant_after_fee, ram_symbol ).amount; }); check( bytes_out > 0, "must reserve a positive amount" ); @@ -190,8 +190,8 @@ namespace eosiosystem { asset tokens_out; auto itr = _rammarket.find(ramcore_symbol.raw()); _rammarket.modify( itr, same_payer, [&]( auto& es ) { - /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.convert( asset(bytes, ram_symbol), core_symbol()); + /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases + tokens_out = es.direct_convert( asset(bytes, ram_symbol), core_symbol()); }); check( tokens_out.amount > 1, "token amount received from selling ram is too low" ); diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index ad29f972..8f3ea8f2 100755 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -4,7 +4,7 @@ namespace eosiosystem { asset exchange_state::convert_to_exchange( connector& c, asset in ) { real_type R(supply.amount); - real_type C(c.balance.amount+in.amount); + real_type C(c.balance.amount/* + in.amount*/); real_type F(c.weight); real_type T(in.amount); real_type ONE(1.0); @@ -21,7 +21,7 @@ namespace eosiosystem { asset exchange_state::convert_from_exchange( connector& c, asset in ) { check( in.symbol== supply.symbol, "unexpected asset symbol input" ); - real_type R(supply.amount - in.amount); + real_type R(supply.amount /*- in.amount*/); real_type C(c.balance.amount); real_type F(1.0/c.weight); real_type E(in.amount); @@ -78,6 +78,39 @@ namespace eosiosystem { return from; } + asset exchange_state::direct_convert( const asset& from, const symbol& to ) { + const auto& sell_symbol = from.symbol; + const auto& base_symbol = base.balance.symbol; + const auto& quote_symbol = quote.balance.symbol; + check( sell_symbol != to, "cannot convert to the same symbol" ); + asset out( 0, to ); + if ( from.symbol == base_symbol && to == quote_symbol ) { + out = get_bancor_output( base.balance, quote.balance, from ); + base.balance += from; + quote.balance -= out; + } else if ( from.symbol == quote_symbol && to == base_symbol ) { + out = get_bancor_output( quote.balance, base.balance, from ); + quote.balance += from; + base.balance -= out; + } else { + check( false, "invalid conversion" ); + } + return out; + } + + asset exchange_state::get_bancor_output( const asset& inp_balance, + const asset& out_balance, + const asset& inp ) + { + const double ib = double(inp_balance.amount); + const double ob = double(out_balance.amount); + const double in = double(inp.amount); + int64_t out = int64_t( (in * ob) / (ib + in) ); + + if ( out < 0 ) out = 0; + + return asset( out, out_balance.symbol ); + } } /// namespace eosiosystem From 48e19cc1ea06998db1b05d075112a7e32560fb4b Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Tue, 2 Apr 2019 12:12:50 -0400 Subject: [PATCH 0756/1048] Deleted docker files and scripts used by old contracts pipeline --- docker/Dockerfile | 33 --------------------------------- docker/downloadDependencies.sh | 28 ---------------------------- 2 files changed, 61 deletions(-) delete mode 100644 docker/Dockerfile delete mode 100755 docker/downloadDependencies.sh diff --git a/docker/Dockerfile b/docker/Dockerfile deleted file mode 100644 index 83d6ea78..00000000 --- a/docker/Dockerfile +++ /dev/null @@ -1,33 +0,0 @@ -FROM gcr.io/b1-automation-dev/eosio/builder:latest as builder -# import build-time arguments -ARG CONTRACTS_COMMIT -ARG CONTRACTS_BRANCH -# install external dependencies -RUN apt-get update && \ -apt-get -y upgrade && \ -DEBIAN_FRONTEND=noninteractive apt-get -y install openssl ca-certificates build-essential libbz2-dev zlib1g-dev libssl-dev libgmp3-dev libicu-dev cmake bc jq curl wget net-tools unzip gnupg git graphviz awscli -# download contracts -RUN echo "# git clone -n https://github.com/EOSIO/eosio.contracts.git --quiet" && \ -git clone -n https://github.com/EOSIO/eosio.contracts.git --quiet && \ -echo "# cd eosio.contracts" && \ -cd eosio.contracts && \ -echo "# git checkout $CONTRACTS_COMMIT --quiet" && \ -git checkout $CONTRACTS_COMMIT --quiet && \ -echo "# git submodule update --recursive --init --quiet" && \ -git submodule update --recursive --init --quiet -# download internal dependencies -RUN /eosio.contracts/docker/downloadDependencies.sh -# build eosio -RUN cd eos && \ -./eosio_build.sh -# install eosio -RUN cd eos && \ -./eosio_install.sh -# install cdt -RUN for filename in $(ls *.deb); do /usr/bin/dpkg -i "$filename" && rm -f "$filename"; done -# set environment variables -RUN PATH=/usr/local/eosio/bin:$(echo "/usr/opt/eosio.cdt/$(ls /usr/opt/eosio.cdt)/bin"):$PATH -ENV EOSIO_ROOT=/usr/local/eosio -ENV LD_LIBRARY_PATH=/usr/local/lib -# add the entrypoint script -ENTRYPOINT ["/eosio.contracts/docker/buildContracts.sh"] \ No newline at end of file diff --git a/docker/downloadDependencies.sh b/docker/downloadDependencies.sh deleted file mode 100755 index e5249ff8..00000000 --- a/docker/downloadDependencies.sh +++ /dev/null @@ -1,28 +0,0 @@ -#!/bin/bash -CONTRACTS_PATH='/eosio.contracts' # location in Docker container, not your local machine -CONTRACTS_PATH="${CONTRACTS_PATH/#\~/$HOME}" # perform parameter expansion for paths including '~' -# get EOSIO -echo "downloadDependencies.sh - Cloning EOSIO source from GitHub..." -EOSIO_VERSION=$(cat $CONTRACTS_PATH/dependencies | sed 's,//,#,g' | cut -d '#' -f 1 | grep -v 'eos.*cdt.*=' | grep -v 'eos.*contracts.*=' | grep '.*eos.*=' | cut -d '=' -f 2 | awk '{print $1}') -EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match -test -z $EOSIO_COMMIT && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | awk '{print $1}') # if both searches returned nothing, the version is probably specified by commit hash already -git clone -n https://github.com/EOSIO/eos.git --quiet -echo "downloadDependencies.sh - Cloned EOSIO. Checking out ${EOSIO_COMMIT:0:7}..." -cd eos -test "$(git cat-file -t $EOSIO_COMMIT 2>/dev/null)" != "commit" && cd .. && echo "downloadDependencies.sh - ERROR: EOSIO tag, branch, or commit \"$EOSIO_VERSION\" not found in github.com/EOSIO/eos$(test $EOSIO_VERSION != $EOSIO_COMMIT && echo " using commit \"${EOSIO_COMMIT:0:7}\"")! Exiting..." && exit 1 -git checkout $EOSIO_COMMIT --quiet -git submodule update --recursive --init --quiet -echo "downloadDependencies.sh - Checked out EOSIO at $EOSIO_COMMIT from \"$EOSIO_VERSION\""'!' -echo "$CONTRACTS_BRANCH:$EOSIO_COMMIT" > /etc/eosio-version # this is necessary for our eos CMake VersionMacros which construct the string returned from "$ nodeos --version"; CONTRACTS_BRANCH is a build-arg passed from pipeline.yml into the Docker container -echo "downloadDependencies.sh - Wrote \"/etc/eosio-version\"." -cd .. -# get CDT -echo "downloadDependencies.sh - Getting CDT binary from Amazon S3..." -CDT_VERSION=$(cat $CONTRACTS_PATH/dependencies | sed 's,//,#,g' | cut -d '#' -f 1 | grep 'cdt.*=' | cut -d '=' -f 2 | awk '{print $1}') -CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match -test -z $CDT_COMMIT && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | awk '{print $1}') # if both searches returned nothing, the version is probably specified by commit hash already -CDT_PKG_NAME=$(aws s3 ls s3://eos-binaries | grep ${CDT_COMMIT:0:7} | grep "ubuntu-18.04_amd64.deb" | tr ' ' '\n' | grep '.deb') # get Ubuntu 18.04 *.deb package from S3 bucket by commit hash -echo "downloadDependencies.sh - Found \"$CDT_PKG_NAME\" in s3://eos-binaries. Downloading..." -test -z $CDT_PKG_NAME && echo "downloadDependencies.sh - ERROR: CDT tag, branch, or commit \"$CDT_VERSION\" not found in s3://eos-binaries$(test $CDT_VERSION != $CDT_COMMIT && echo " using commit \"${CDT_COMMIT:0:7}\"")! Exiting..." && exit 1 -aws s3 cp s3://eos-binaries/$CDT_PKG_NAME ./$CDT_PKG_NAME --quiet # download CDT -echo "downloadDependencies.sh - Downloaded CDT at $CDT_COMMIT from \"$CDT_VERSION\""'!' \ No newline at end of file From d14ba85c78b17d0a7e963bc093462bbb674feabc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 3 Apr 2019 14:52:25 -0400 Subject: [PATCH 0757/1048] Update exchange state Bancor equations --- .../include/eosio.system/exchange_state.hpp | 14 +- contracts/eosio.system/src/exchange_state.cpp | 129 +++++++----------- 2 files changed, 57 insertions(+), 86 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 37702663..3658b5c7 100755 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -6,8 +6,6 @@ namespace eosiosystem { using eosio::asset; using eosio::symbol; - typedef double real_type; - /** * Uses Bancor math to create a 50/50 relay between two asset types. The state of the * bancor exchange is entirely contained within this struct. There are no external @@ -28,13 +26,13 @@ namespace eosiosystem { uint64_t primary_key()const { return supply.symbol.raw(); } - asset convert_to_exchange( connector& c, asset in ); - asset convert_from_exchange( connector& c, asset in ); - asset convert( asset from, const symbol& to ); + asset convert_to_exchange( connector& c, const asset& in ); + asset convert_from_exchange( connector& c, const asset& in ); + asset convert( const asset& from, const symbol& to ); asset direct_convert( const asset& from, const symbol& to ); - static asset get_bancor_output( const asset& inp_balance, - const asset& out_balance, - const asset& inp ); + static asset get_direct_bancor_output( const asset& inp_reserve, + const asset& out_reserve, + const asset& inp ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) }; diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index 8f3ea8f2..b3ac7441 100755 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -1,81 +1,53 @@ #include namespace eosiosystem { - asset exchange_state::convert_to_exchange( connector& c, asset in ) { - real_type R(supply.amount); - real_type C(c.balance.amount/* + in.amount*/); - real_type F(c.weight); - real_type T(in.amount); - real_type ONE(1.0); - - real_type E = -R * (ONE - std::pow( ONE + T / C, F) ); - int64_t issued = int64_t(E); - - supply.amount += issued; - c.balance.amount += in.amount; - - return asset( issued, supply.symbol ); + asset exchange_state::convert_to_exchange( connector& reserve, const asset& payment ) + { + const double S0 = supply.amount; + const double R0 = reserve.balance.amount; + const double dR = payment.amount; + const double F = reserve.weight; + + double dS = S0 * ( std::pow(1. + dR / R0, F) - 1. ); + if ( dS < 0 ) dS = 0; // rounding errors + reserve.balance += payment; + supply.amount += int64_t(dS); + return asset( int64_t(dS), supply.symbol ); } - asset exchange_state::convert_from_exchange( connector& c, asset in ) { - check( in.symbol== supply.symbol, "unexpected asset symbol input" ); - - real_type R(supply.amount /*- in.amount*/); - real_type C(c.balance.amount); - real_type F(1.0/c.weight); - real_type E(in.amount); - real_type ONE(1.0); - - - // potentially more accurate: - // The functions std::expm1 and std::log1p are useful for financial calculations, for example, - // when calculating small daily interest rates: (1+x)n - // -1 can be expressed as std::expm1(n * std::log1p(x)). - // real_type T = C * std::expm1( F * std::log1p(E/R) ); - - real_type T = C * (std::pow( ONE + E/R, F) - ONE); - int64_t out = int64_t(T); - - supply.amount -= in.amount; - c.balance.amount -= out; - - return asset( out, c.balance.symbol ); + asset exchange_state::convert_from_exchange( connector& reserve, const asset& tokens ) + { + const double R0 = reserve.balance.amount; + const double S0 = supply.amount; + const double dS = -tokens.amount; // tokens are subtracted from supply + const double Fi = double(1) / reserve.weight; + + double dR = R0 * ( std::pow(1. + dS / S0, Fi) - 1. ); // dR < 0 + if ( dR > 0 ) dR = 0; // rounding errors + reserve.balance.amount -= int64_t(-dR); + supply -= tokens; + return asset( int64_t(-dR), reserve.balance.symbol ); } - asset exchange_state::convert( asset from, const symbol& to ) { - auto sell_symbol = from.symbol; - auto ex_symbol = supply.symbol; - auto base_symbol = base.balance.symbol; - auto quote_symbol = quote.balance.symbol; - - //print( "From: ", from, " TO ", asset( 0,to), "\n" ); - //print( "base: ", base_symbol, "\n" ); - //print( "quote: ", quote_symbol, "\n" ); - //print( "ex: ", supply.symbol, "\n" ); + asset exchange_state::convert( const asset& from, const symbol& to ) + { + const auto& sell_symbol = from.symbol; + const auto& base_symbol = base.balance.symbol; + const auto& quote_symbol = quote.balance.symbol; + check( sell_symbol != to, "cannot convert to the same symbol" ); - if( sell_symbol != ex_symbol ) { - if( sell_symbol == base_symbol ) { - from = convert_to_exchange( base, from ); - } else if( sell_symbol == quote_symbol ) { - from = convert_to_exchange( quote, from ); - } else { - check( false, "invalid sell" ); - } + asset out( 0, to ); + if ( sell_symbol == base_symbol && to == quote_symbol ) { + const asset tmp = convert_to_exchange( base, from ); + out = convert_from_exchange( quote, tmp ); + } else if ( sell_symbol == quote_symbol && to == base_symbol ) { + const asset tmp = convert_to_exchange( quote, from ); + out = convert_from_exchange( base, tmp ); } else { - if( to == base_symbol ) { - from = convert_from_exchange( base, from ); - } else if( to == quote_symbol ) { - from = convert_from_exchange( quote, from ); - } else { - check( false, "invalid conversion" ); - } + check( false, "invalid conversion" ); } - - if( to != from.symbol ) - return convert( from, to ); - - return from; + return out; } asset exchange_state::direct_convert( const asset& from, const symbol& to ) { @@ -83,13 +55,14 @@ namespace eosiosystem { const auto& base_symbol = base.balance.symbol; const auto& quote_symbol = quote.balance.symbol; check( sell_symbol != to, "cannot convert to the same symbol" ); + asset out( 0, to ); - if ( from.symbol == base_symbol && to == quote_symbol ) { - out = get_bancor_output( base.balance, quote.balance, from ); + if ( sell_symbol == base_symbol && to == quote_symbol ) { + out = get_direct_bancor_output( base.balance, quote.balance, from ); base.balance += from; quote.balance -= out; - } else if ( from.symbol == quote_symbol && to == base_symbol ) { - out = get_bancor_output( quote.balance, base.balance, from ); + } else if ( sell_symbol == quote_symbol && to == base_symbol ) { + out = get_direct_bancor_output( quote.balance, base.balance, from ); quote.balance += from; base.balance -= out; } else { @@ -98,19 +71,19 @@ namespace eosiosystem { return out; } - asset exchange_state::get_bancor_output( const asset& inp_balance, - const asset& out_balance, - const asset& inp ) + asset exchange_state::get_direct_bancor_output( const asset& inp_reserve, + const asset& out_reserve, + const asset& inp ) { - const double ib = double(inp_balance.amount); - const double ob = double(out_balance.amount); - const double in = double(inp.amount); + const double ib = inp_reserve.amount; + const double ob = out_reserve.amount; + const double in = inp.amount; int64_t out = int64_t( (in * ob) / (ib + in) ); if ( out < 0 ) out = 0; - return asset( out, out_balance.symbol ); + return asset( out, out_reserve.symbol ); } } /// namespace eosiosystem From 97701b1b1e0d6e398e6b669039e6aee5290ffcaa Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Wed, 3 Apr 2019 17:11:34 -0400 Subject: [PATCH 0758/1048] Add mv[to,fr]saving() back. Minor comment fixes. --- .../include/eosio.system/eosio.system.hpp | 61 +++++++++++++------ 1 file changed, 44 insertions(+), 17 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index f7a99b44..d4301b71 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -413,7 +413,7 @@ namespace eosiosystem { /** * Rex cpu loan table * - * @details The rex cpu loan table is storing all the `rex_load`s instances for cpu, indexed by loan number, expiration and owner. + * @details The rex cpu loan table is storing all the `rex_loan`s instances for cpu, indexed by loan number, expiration and owner. */ typedef eosio::multi_index< "cpuloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, @@ -423,7 +423,7 @@ namespace eosiosystem { /** * Rex net loan table * - * @details The rex net loan table is storing all the `rex_load`s instances for net, indexed by loan number,expiration and owner. + * @details The rex net loan table is storing all the `rex_loan`s instances for net, indexed by loan number, expiration and owner. */ typedef eosio::multi_index< "netloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, @@ -502,9 +502,9 @@ namespace eosiosystem { * * @details Constructs a system contract based on self account, code account and data. * - * @params s - The current code account that is executing the action, - * @params code - The original code account that executed the action, - * @params ds - The contract data represented as an `eosio::datastream`. + * @param s - The current code account that is executing the action, + * @param code - The original code account that executed the action, + * @param ds - The contract data represented as an `eosio::datastream`. */ system_contract( name s, name code, datastream ds ); ~system_contract(); @@ -512,7 +512,7 @@ namespace eosiosystem { /** * Returns the core symbol by system account name * - * @params system_account - the system account to get the core symbol for. + * @param system_account - the system account to get the core symbol for. */ static symbol get_core_symbol( name system_account = "eosio"_n ) { rammarket rm(system_account, system_account.value); @@ -775,7 +775,7 @@ namespace eosiosystem { * be used for loan renewal at expiry. * * @param from - loan creator account, - * @param loan_num - load id, + * @param loan_num - loan id, * @param payment - tokens transfered from REX fund to loan fund. */ [[eosio::action]] @@ -788,19 +788,19 @@ namespace eosiosystem { * be used for loan renewal at expiry. * * @param from - loan creator account, - * @param loan_num - load id, + * @param loan_num - loan id, * @param payment - tokens transfered from REX fund to loan fund. */ [[eosio::action]] void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); /** - * Defcpuload action. + * Defcpuloan action. * * @details Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. * * @param from - loan creator account, - * @param loan_num - load id, + * @param loan_num - loan id, * @param amount - tokens transfered from CPU loan fund to REX fund. */ [[eosio::action]] @@ -812,7 +812,7 @@ namespace eosiosystem { * @details Withdraws tokens from the fund of a specific NET loan and adds them to REX fund. * * @param from - loan creator account, - * @param loan_num - load id, + * @param loan_num - loan id, * @param amount - tokens transfered from NET loan fund to REX fund. */ [[eosio::action]] @@ -823,7 +823,7 @@ namespace eosiosystem { * * @details Updates REX owner vote weight to current value of held REX tokens. * - * @params owner - REX owner account. + * @param owner - REX owner account. */ [[eosio::action]] void updaterex( const name& owner ); @@ -843,13 +843,40 @@ namespace eosiosystem { /** * Consolidate action. * - * @details Consolidate REX maturity buckets into one bucket that can be sold after 4 days. + * @details Consolidates REX maturity buckets into one bucket that can be sold after 4 days + * starting from the end of the day. * * @param owner - REX owner account name. */ [[eosio::action]] void consolidate( const name& owner ); + /** + * Mvtosavings action. + * + * @details Moves a specified amount of REX into savings bucket. REX savings bucket + * never matures. In order for it to be sold, it has to be moved explicitly + * out of that bucket. Then the moved amount will have the regular maturity + * period of 4 days starting from the end of the day. + * + * @param owner - REX owner account name. + * @param rex - amount of REX to be moved. + */ + [[eosio::action]] + void mvtosavings( const name& owner, const asset& rex ); + + /** + * Mvfrsavings action. + * + * @details Moves a specified amount of REX out of savings bucket. The moved amount + * will have the regular REX maturity period of 4 days. + * + * @param owner - REX owner account name. + * @param rex - amount of REX to be moved. + */ + [[eosio::action]] + void mvfrsavings( const name& owner, const asset& rex ); + /** * Closerex action. * @@ -1008,9 +1035,9 @@ namespace eosiosystem { * proxy updates their own vote. Voter can vote for a proxy __or__ a list of at most 30 producers. * Storage change is billed to `voter`. * - * @params voter - the account to change the voted producers for, - * @params proxy - the proxy to change the voted producers for, - * @params producers - the list of producers to vote for, a maximum of 30 producers is allowed. + * @param voter - the account to change the voted producers for, + * @param proxy - the proxy to change the voted producers for, + * @param producers - the list of producers to vote for, a maximum of 30 producers is allowed. * * @pre Producers must be sorted from lowest to highest and must be registered and active * @pre If proxy is set then no producers can be voted for @@ -1179,6 +1206,7 @@ namespace eosiosystem { using voteproducer_action = eosio::action_wrapper<"voteproducer"_n, &system_contract::voteproducer>; using regproxy_action = eosio::action_wrapper<"regproxy"_n, &system_contract::regproxy>; using claimrewards_action = eosio::action_wrapper<"claimrewards"_n, &system_contract::claimrewards>; + using rmvproducer_action = eosio::action_wrapper<"rmvproducer"_n, &system_contract::rmvproducer>; using updtrevision_action = eosio::action_wrapper<"updtrevision"_n, &system_contract::updtrevision>; using bidname_action = eosio::action_wrapper<"bidname"_n, &system_contract::bidname>; @@ -1188,7 +1216,6 @@ namespace eosiosystem { using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; private: - // Implementation details: static symbol get_core_symbol( const rammarket& rm ) { From 45c95c404809789e790a22141c0efc6891f3640d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 3 Apr 2019 18:26:27 -0400 Subject: [PATCH 0759/1048] prevent system contract from proposing an empty producer schedule; fix tests to work with protocol features changes in eosio --- contracts/eosio.system/src/voting.cpp | 2 +- tests/eosio.system_tests.cpp | 36 +++++++++++++-------------- tests/eosio.wrap_tests.cpp | 4 +-- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index caf38b93..5637f754 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -97,7 +97,7 @@ namespace eosiosystem { top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location}) ); } - if ( top_producers.size() < _gstate.last_producer_schedule_size ) { + if ( top_producers.size() == 0 || top_producers.size() < _gstate.last_producer_schedule_size ) { return; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index cd8e0f63..82644bbd 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3755,7 +3755,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); - + produce_block( fc::days(5) ); produce_blocks(2); const asset rex_tok = asset::from_string("1.0000 REX"); @@ -3766,10 +3766,10 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( ratio * payment.get_amount() - rex_tok.get_amount(), get_rex_order( alice )["rex_requested"].as().get_amount() ); BOOST_REQUIRE_EQUAL( success(), consolidate( alice ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["rex_maturities"].get_array().size() ); - + produce_block( fc::days(26) ); produce_blocks(2); - + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 2 ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["matured_rex"].as() ); @@ -3881,11 +3881,11 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - + BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); @@ -3906,7 +3906,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(bob).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(carol).is_null() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(carol).is_null() ); BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); const auto& rex_pool = get_rex_pool(); @@ -4080,7 +4080,7 @@ BOOST_FIXTURE_TEST_CASE( rex_loan_checks, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee, fee + fee + fee ) ); BOOST_REQUIRE_EQUAL( true, !get_cpu_loan(1).is_null() ); BOOST_REQUIRE_EQUAL( 3 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); - + produce_block( fc::days(31) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 3) ); BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); @@ -4303,7 +4303,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { const int64_t rex_ratio = 10000; const symbol rex_sym( SY(4, REX) ); - + { const asset payment1 = core_sym::from_string("14.8000"); const asset payment2 = core_sym::from_string("15.2000"); @@ -4320,7 +4320,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - + BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( 8 * rex_bucket.get_amount(), rex_sym ) ) ); rex_balance = get_rex_balance_obj( alice ); BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); @@ -4374,7 +4374,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - + BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( 3 * rex_bucket.get_amount() / 2, rex_sym ) ) ); rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); @@ -4387,7 +4387,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - + produce_block( fc::days(1) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, rex_bucket ) ); @@ -4396,7 +4396,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); BOOST_REQUIRE_EQUAL( 5 * rex_bucket.get_amount(), 2 * rex_balance["rex_balance"].as().get_amount() ); - + produce_block( fc::days(20) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, rex_bucket ) ); @@ -4418,14 +4418,14 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { rex_balance = get_rex_balance_obj( bob ); BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( rex_bucket.get_amount() / 2, rex_balance["rex_balance"].as().get_amount() ); - + BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 4, rex_sym ) ) ); produce_block( fc::days(2) ); BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 8, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( 3, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); BOOST_REQUIRE_EQUAL( 2, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - + produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); @@ -4475,7 +4475,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), buyrex( carol, payment ) ); BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( carol ) ); auto rex_balance = get_rex_balance_obj( carol ); - + BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); produce_block( fc::days(1) ); @@ -4483,15 +4483,15 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { rex_balance = get_rex_balance_obj( carol ); BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - + BOOST_REQUIRE_EQUAL( success(), mvtosavings( carol, half_rex_bucket ) ); rex_balance = get_rex_balance_obj( carol ); BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - + BOOST_REQUIRE_EQUAL( success(), buyrex( carol, half_payment ) ); rex_balance = get_rex_balance_obj( carol ); BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - + produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), mvfrsavings( carol, asset::from_string("0.0000 REX") ) ); diff --git a/tests/eosio.wrap_tests.cpp b/tests/eosio.wrap_tests.cpp index b6f1424d..1d9e33d2 100644 --- a/tests/eosio.wrap_tests.cpp +++ b/tests/eosio.wrap_tests.cpp @@ -79,7 +79,7 @@ class eosio_wrap_tester : public tester { BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); abi_ser.set_abi(abi, abi_serializer_max_time); - while( control->pending_block_state()->header.producer.to_string() == "eosio" ) { + while( control->pending_block_producer().to_string() == "eosio" ) { produce_block(); } } @@ -299,7 +299,7 @@ BOOST_FIXTURE_TEST_CASE( wrap_with_msig_producers_change, eosio_wrap_tester ) tr set_producers( {N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(newprod1)} ); // With 6 producers, the 2/3+1 threshold becomes 5 - while( control->pending_block_state()->active_schedule.producers.size() != 6 ) { + while( control->active_producers().producers.size() != 6 ) { produce_block(); } From 6e7da84fa9134db4bf14cc269349be4078a35c25 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 11 Mar 2019 21:35:22 -0400 Subject: [PATCH 0760/1048] add preactivate and reqactivated actions to eosio.bios (related to PREACTIVATE_FEATURE protocol feature) --- .../include/eosio.bios/eosio.bios.hpp | 42 ++++++++++++++++++- contracts/eosio.bios/src/eosio.bios.cpp | 2 +- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index e3acabe7..44ad2508 100755 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -4,6 +4,35 @@ #include #include #include +#include + +namespace eosio { + namespace internal_use_do_not_use { + extern "C" { + __attribute__((eosio_wasm_import)) + bool is_feature_activated( const ::capi_checksum256* feature_digest ); + + __attribute__((eosio_wasm_import)) + void preactivate_feature( const ::capi_checksum256* feature_digest ); + } + } +} + +namespace eosio { + bool is_feature_activated( const eosio::checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + return internal_use_do_not_use::is_feature_activated( + reinterpret_cast( feature_digest_data.data() ) + ); + } + + void preactivate_feature( const eosio::checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + internal_use_do_not_use::preactivate_feature( + reinterpret_cast( feature_digest_data.data() ) + ); + } +} namespace eosio { using eosio::permission_level; @@ -140,6 +169,17 @@ namespace eosio { require_auth( from ); } + [[eosio::action]] + void preactivate( const eosio::checksum256& feature_digest ) { + require_auth( get_self() ); + preactivate_feature( feature_digest ); + } + + [[eosio::action]] + void reqactivated( const eosio::checksum256& feature_digest ) { + check( is_feature_activated( feature_digest ), "protocol feature is not activated" ); + } + [[eosio::action]] void setabi( name account, const std::vector& abi ) { abi_hash_table table(_self, _self.value); @@ -165,7 +205,7 @@ namespace eosio { }; typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; - + using newaccount_action = action_wrapper<"newaccount"_n, &bios::newaccount>; using updateauth_action = action_wrapper<"updateauth"_n, &bios::updateauth>; using deleteauth_action = action_wrapper<"deleteauth"_n, &bios::deleteauth>; diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index 01e85c02..abbb6f72 100755 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,3 @@ #include -EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi) ) +EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi)(preactivate)(reqactivated) ) From fc1ea9870c9fcf423dddcd76ba00371de00cfe3d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 3 Apr 2019 18:40:09 -0400 Subject: [PATCH 0761/1048] add preactivate action to eosio.system (related to PREACTIVATE_FEATURE protocol feature) --- .../include/eosio.system/eosio.system.hpp | 7 +++-- .../include/eosio.system/native.hpp | 29 +++++++++++++++++++ contracts/eosio.system/src/eosio.system.cpp | 7 ++++- 3 files changed, 40 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 43b2c353..6f66aa5a 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -360,6 +360,9 @@ namespace eosiosystem { [[eosio::action]] void setacctcpu( name account, std::optional cpu_weight ); + [[eosio::action]] + void preactivate( const eosio::checksum256& feature_digest ); + // functions defined in delegate_bandwidth.cpp /** @@ -481,10 +484,10 @@ namespace eosiosystem { */ [[eosio::action]] void mvtosavings( const name& owner, const asset& rex ); - + /** * Moves a specified amount of REX out of savings bucket. The moved amount - * will have the regular REX maturity period of 4 days. + * will have the regular REX maturity period of 4 days. */ [[eosio::action]] void mvfrsavings( const name& owner, const asset& rex ); diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 868dea33..ec0b0b5e 100755 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -11,6 +11,35 @@ #include #include #include +#include + +namespace eosio { + namespace internal_use_do_not_use { + extern "C" { + __attribute__((eosio_wasm_import)) + bool is_feature_activated( const ::capi_checksum256* feature_digest ); + + __attribute__((eosio_wasm_import)) + void preactivate_feature( const ::capi_checksum256* feature_digest ); + } + } +} + + namespace eosio { + bool is_feature_activated( const eosio::checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + return internal_use_do_not_use::is_feature_activated( + reinterpret_cast( feature_digest_data.data() ) + ); + } + + void preactivate_feature( const eosio::checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + internal_use_do_not_use::preactivate_feature( + reinterpret_cast( feature_digest_data.data() ) + ); + } +} namespace eosiosystem { using eosio::name; diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index b8c3bba3..aa17181f 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -277,6 +277,11 @@ namespace eosiosystem { set_resource_limits( account.value, current_ram, current_net, cpu ); } + void system_contract::preactivate( const eosio::checksum256& feature_digest ) { + require_auth( get_self() ); + preactivate_feature( feature_digest ); + } + void system_contract::rmvproducer( name producer ) { require_auth( _self ); auto prod = _producers.find( producer.value ); @@ -463,7 +468,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp - (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu) + (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu)(preactivate) (rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) From b186384f88010717cee442168d89e684a69a0ebb Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 3 Apr 2019 18:53:17 -0400 Subject: [PATCH 0762/1048] fix eosio_system_tests/setabi_bios by activating PREACTIVATE_FEATURE before deploying bios contract --- tests/eosio.system_tests.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 82644bbd..b38d068f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4922,6 +4922,7 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { BOOST_AUTO_TEST_CASE( setabi_bios ) try { validating_tester t( validating_tester::default_config() ); + t.execute_setup_policy( setup_policy::preactivate_feature_only ); abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); t.set_code( config::system_account_name, contracts::bios_wasm() ); t.set_abi( config::system_account_name, contracts::bios_abi().data() ); From 2357ec1e514067df1218bd4cd9ad722d4eb7682e Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 3 Apr 2019 18:59:58 -0400 Subject: [PATCH 0763/1048] update dependencies to point to EOSIO build with protocol feature support --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index e70223ba..820cdb6f 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=release/1.7.x +eosio=forced-replay cdt=release/1.5.x From 690aa21d4055f419c71449b948957f3c5f0fd720 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 3 Apr 2019 19:11:35 -0400 Subject: [PATCH 0764/1048] try updating dependencies to use eosio.cdt 1.6.x --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index 820cdb6f..d0604ef9 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash eosio=forced-replay -cdt=release/1.5.x +cdt=release/1.6.x From bbea6fb79b90039c1fd0bdc8c131f055df18eadc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 4 Apr 2019 13:21:08 -0400 Subject: [PATCH 0765/1048] Small changes to exchange_state --- .../include/eosio.system/exchange_state.hpp | 6 ++--- contracts/eosio.system/src/exchange_state.cpp | 25 ++++++++++--------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 3658b5c7..7aeee247 100755 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -30,9 +30,9 @@ namespace eosiosystem { asset convert_from_exchange( connector& c, const asset& in ); asset convert( const asset& from, const symbol& to ); asset direct_convert( const asset& from, const symbol& to ); - static asset get_direct_bancor_output( const asset& inp_reserve, - const asset& out_reserve, - const asset& inp ); + static int64_t get_bancor_output( int64_t inp_reserve, + int64_t out_reserve, + int64_t inp ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) }; diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index b3ac7441..10fd11f8 100755 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -20,10 +20,10 @@ namespace eosiosystem { { const double R0 = reserve.balance.amount; const double S0 = supply.amount; - const double dS = -tokens.amount; // tokens are subtracted from supply + const double dS = -tokens.amount; // dS < 0, tokens are subtracted from supply const double Fi = double(1) / reserve.weight; - double dR = R0 * ( std::pow(1. + dS / S0, Fi) - 1. ); // dR < 0 + double dR = R0 * ( std::pow(1. + dS / S0, Fi) - 1. ); // dR < 0 since dS < 0 if ( dR > 0 ) dR = 0; // rounding errors reserve.balance.amount -= int64_t(-dR); supply -= tokens; @@ -50,7 +50,8 @@ namespace eosiosystem { return out; } - asset exchange_state::direct_convert( const asset& from, const symbol& to ) { + asset exchange_state::direct_convert( const asset& from, const symbol& to ) + { const auto& sell_symbol = from.symbol; const auto& base_symbol = base.balance.symbol; const auto& quote_symbol = quote.balance.symbol; @@ -58,11 +59,11 @@ namespace eosiosystem { asset out( 0, to ); if ( sell_symbol == base_symbol && to == quote_symbol ) { - out = get_direct_bancor_output( base.balance, quote.balance, from ); + out.amount = get_bancor_output( base.balance.amount, quote.balance.amount, from.amount ); base.balance += from; quote.balance -= out; } else if ( sell_symbol == quote_symbol && to == base_symbol ) { - out = get_direct_bancor_output( quote.balance, base.balance, from ); + out.amount = get_bancor_output( quote.balance.amount, base.balance.amount, from.amount ); quote.balance += from; base.balance -= out; } else { @@ -71,19 +72,19 @@ namespace eosiosystem { return out; } - asset exchange_state::get_direct_bancor_output( const asset& inp_reserve, - const asset& out_reserve, - const asset& inp ) + int64_t exchange_state::get_bancor_output( int64_t inp_reserve, + int64_t out_reserve, + int64_t inp ) { - const double ib = inp_reserve.amount; - const double ob = out_reserve.amount; - const double in = inp.amount; + const double ib = inp_reserve; + const double ob = out_reserve; + const double in = inp; int64_t out = int64_t( (in * ob) / (ib + in) ); if ( out < 0 ) out = 0; - return asset( out, out_reserve.symbol ); + return out; } } /// namespace eosiosystem From 1c0f788bd2cbe68b573ccf7eec8099729a81d06d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 4 Apr 2019 13:53:05 -0400 Subject: [PATCH 0766/1048] Use exchange_state function in REX --- contracts/eosio.system/src/rex.cpp | 39 +++++++----------------------- 1 file changed, 9 insertions(+), 30 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 6bb1c92a..e53c58cb 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -483,29 +483,6 @@ namespace eosiosystem { } } - /** - * Given two connector balances (conin, and conout), and an incoming amount of - * in, this function calculates the delta out using Banacor equation. - * - * @param in - input amount, same units as conin - * @param conin - the input connector balance - * @param conout - the output connector balance - * - * @return int64_t - conversion output amount - */ - int64_t get_bancor_output( int64_t conin, int64_t conout, int64_t in ) - { - const double F0 = double(conin); - const double T0 = double(conout); - const double I = double(in); - - auto out = int64_t((I*T0) / (I+F0)); - - if ( out < 0 ) out = 0; - - return out; - } - /** * @brief Updates account NET and CPU resource limits * @@ -630,9 +607,9 @@ namespace eosiosystem { void system_contract::remove_loan_from_rex_pool( const rex_loan& loan ) { const auto& pool = _rexpool.begin(); - const int64_t delta_total_rent = get_bancor_output( pool->total_unlent.amount, - pool->total_rent.amount, - loan.total_staked.amount ); + const int64_t delta_total_rent = exchange_state::get_bancor_output( pool->total_unlent.amount, + pool->total_rent.amount, + loan.total_staked.amount ); _rexpool.modify( pool, same_payer, [&]( auto& rt ) { // deduct calculated delta_total_rent from total_rent rt.total_rent.amount -= delta_total_rent; @@ -675,9 +652,9 @@ namespace eosiosystem { bool delete_loan = false; int64_t delta_stake = 0; /// calculate rented tokens at current price - int64_t rented_tokens = get_bancor_output( pool->total_rent.amount, - pool->total_unlent.amount, - itr->payment.amount ); + int64_t rented_tokens = exchange_state::get_bancor_output( pool->total_rent.amount, + pool->total_unlent.amount, + itr->payment.amount ); /// conditions for loan renewal bool renew_loan = itr->payment <= itr->balance /// loan has sufficient balance && itr->payment.amount < rented_tokens /// loan has favorable return @@ -783,7 +760,9 @@ namespace eosiosystem { const auto& pool = _rexpool.begin(); /// already checked that _rexpool.begin() != _rexpool.end() in rex_loans_available() - int64_t rented_tokens = get_bancor_output( pool->total_rent.amount, pool->total_unlent.amount, payment.amount ); + int64_t rented_tokens = exchange_state::get_bancor_output( pool->total_rent.amount, + pool->total_unlent.amount, + payment.amount ); check( payment.amount < rented_tokens, "loan price does not favor renting" ); add_loan_to_rex_pool( payment, rented_tokens, true ); From f263ac2cc900137c61fdc478d2b0cf8254b5aa0e Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 4 Apr 2019 21:14:07 -0400 Subject: [PATCH 0767/1048] Added "set -e" to docker/buildContracts.sh to fix issue Areg discovered in build 117 --- docker/buildContracts.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/buildContracts.sh b/docker/buildContracts.sh index 8d63f759..56f4e0de 100755 --- a/docker/buildContracts.sh +++ b/docker/buildContracts.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) cd /eosio.contracts ./build.sh cd build From d21f84592d703165ed09f7b0b87e42e2b1118df8 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 4 Apr 2019 21:19:15 -0400 Subject: [PATCH 0768/1048] Added "set -e" to build.sh to fix issue Areg discovered in build 117 --- build.sh | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/build.sh b/build.sh index 5ef9e1eb..001f3c64 100755 --- a/build.sh +++ b/build.sh @@ -1,13 +1,11 @@ #! /bin/bash - +set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) printf "\t=========== Building eosio.contracts ===========\n\n" - RED='\033[0;31m' NC='\033[0m' - -CORES=`getconf _NPROCESSORS_ONLN` +CPU_CORES=$(getconf _NPROCESSORS_ONLN) mkdir -p build pushd build &> /dev/null cmake ../ -make -j${CORES} +make -j $CPU_CORES popd &> /dev/null From ecc363b249f454d4bc95b10f31947689a4296d24 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 4 Apr 2019 21:22:06 -0400 Subject: [PATCH 0769/1048] Added "set -e" to docker/verifyInstallation.sh to prevent issues similar to build 117 --- docker/verifyInstallation.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/docker/verifyInstallation.sh b/docker/verifyInstallation.sh index 37fcb529..c5e198d1 100755 --- a/docker/verifyInstallation.sh +++ b/docker/verifyInstallation.sh @@ -1,4 +1,5 @@ #!/bin/bash +set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) # expected places to find EOSIO CMAKE in the docker container, in ascending order of preference [[ -e /usr/lib/eosio/lib/cmake/eosio/eosio-config.cmake ]] && export CMAKE_FRAMEWORK_PATH="/usr/lib/eosio" [[ -e /opt/eosio/lib/cmake/eosio/eosio-config.cmake ]] && export CMAKE_FRAMEWORK_PATH="/opt/eosio" From 4e7255fb908f615a20145b35f84268a230ef3547 Mon Sep 17 00:00:00 2001 From: Hyung-Kyu Choi Date: Fri, 12 Apr 2019 18:40:29 +0900 Subject: [PATCH 0770/1048] Fix broken links in README.md Fix broken links in README.md Signed-off-by: Hyung-Kyu Choi --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 5c5a2ebd..0e07153f 100644 --- a/README.md +++ b/README.md @@ -6,13 +6,13 @@ The design of the EOSIO blockchain calls for a number of smart contracts that ar This repository contains examples of these privileged contracts that are useful when deploying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: - * [eosio.bios](https://github.com/eosio/eosio.contracts/tree/master/eosio.bios) - * [eosio.system](https://github.com/eosio/eosio.contracts/tree/master/eosio.system) - * [eosio.msig](https://github.com/eosio/eosio.contracts/tree/master/eosio.msig) - * [eosio.wrap](https://github.com/eosio/eosio.contracts/tree/master/eosio.wrap) + * [eosio.bios](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.bios) + * [eosio.system](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.system) + * [eosio.msig](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.msig) + * [eosio.wrap](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.wrap) The following unprivileged contract(s) are also part of the system. - * [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token) + * [eosio.token](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.token) Dependencies: * [eosio v1.7.x](https://github.com/EOSIO/eos/releases/tag/v1.7.0) From 37a03f74a0d1b76cafae16dd044b39e2d3a0fca1 Mon Sep 17 00:00:00 2001 From: Yaroslav Erohin Date: Sat, 13 Apr 2019 14:28:47 +0300 Subject: [PATCH 0771/1048] fix comment typo --- contracts/eosio.system/src/rex.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 6bb1c92a..7a8935a0 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -659,7 +659,7 @@ namespace eosiosystem { } /** - * @brief Performs maintenance operations on expired NET and CPU loans and sellrex oders + * @brief Performs maintenance operations on expired NET and CPU loans and sellrex orders * * @param max - maximum number of each of the three categories to be processed */ From 809217859147f2ec68ace19dbdaa3c53e833f1df Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 16 Apr 2019 21:12:27 -0400 Subject: [PATCH 0772/1048] fix rex functions in eosio.system_tester.hpp to reflect transaction trace restructure changes --- tests/eosio.system_tester.hpp | 66 +++++++++++++++-------------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 0af1b9e0..397d1cdc 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -352,13 +352,11 @@ class eosio_system_tester : public TESTER { auto trace = base_tester::push_action( config::system_account_name, N(buyrex), from, mvo()("from", from)("amount", amount) ); asset rex_received; for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { - if ( trace->action_traces[i].inline_traces[j].act.name == N(buyresult) ) { - fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), - trace->action_traces[i].inline_traces[j].act.data.size(), - rex_received ); - return rex_received; - } + if ( trace->action_traces[i].act.name == N(buyresult) ) { + fc::raw::unpack( trace->action_traces[i].act.data.data(), + trace->action_traces[i].act.data.size(), + rex_received ); + return rex_received; } } return rex_received; @@ -382,13 +380,11 @@ class eosio_system_tester : public TESTER { ); asset rex_received; for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { - if ( trace->action_traces[i].inline_traces[j].act.name == N(buyresult) ) { - fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), - trace->action_traces[i].inline_traces[j].act.data.size(), - rex_received ); - return rex_received; - } + if ( trace->action_traces[i].act.name == N(buyresult) ) { + fc::raw::unpack( trace->action_traces[i].act.data.data(), + trace->action_traces[i].act.data.size(), + rex_received ); + return rex_received; } } return rex_received; @@ -405,29 +401,25 @@ class eosio_system_tester : public TESTER { auto trace = base_tester::push_action( config::system_account_name, N(sellrex), from, mvo()("from", from)("rex", rex) ); asset proceeds; for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { - if ( trace->action_traces[i].inline_traces[j].act.name == N(sellresult) ) { - fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), - trace->action_traces[i].inline_traces[j].act.data.size(), - proceeds ); - return proceeds; - } + if ( trace->action_traces[i].act.name == N(sellresult) ) { + fc::raw::unpack( trace->action_traces[i].act.data.data(), + trace->action_traces[i].act.data.size(), + proceeds ); + return proceeds; } - } + } return proceeds; } auto get_rexorder_result( const transaction_trace_ptr& trace ) { std::vector> output; for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { - if ( trace->action_traces[i].inline_traces[j].act.name == N(orderresult) ) { - fc::datastream ds( trace->action_traces[i].inline_traces[j].act.data.data(), - trace->action_traces[i].inline_traces[j].act.data.size() ); - account_name owner; fc::raw::unpack( ds, owner ); - asset proceeds; fc::raw::unpack( ds, proceeds ); - output.emplace_back( owner, proceeds ); - } + if ( trace->action_traces[i].act.name == N(orderresult) ) { + fc::datastream ds( trace->action_traces[i].act.data.data(), + trace->action_traces[i].act.data.size() ); + account_name owner; fc::raw::unpack( ds, owner ); + asset proceeds; fc::raw::unpack( ds, proceeds ); + output.emplace_back( owner, proceeds ); } } return output; @@ -466,13 +458,11 @@ class eosio_system_tester : public TESTER { asset rented_tokens = core_sym::from_string("0.0000"); for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - for ( size_t j = 0; j < trace->action_traces[i].inline_traces.size(); ++j ) { - if ( trace->action_traces[i].inline_traces[j].act.name == N(rentresult) ) { - fc::raw::unpack( trace->action_traces[i].inline_traces[j].act.data.data(), - trace->action_traces[i].inline_traces[j].act.data.size(), - rented_tokens ); - return rented_tokens; - } + if ( trace->action_traces[i].act.name == N(rentresult) ) { + fc::raw::unpack( trace->action_traces[i].act.data.data(), + trace->action_traces[i].act.data.size(), + rented_tokens ); + return rented_tokens; } } return rented_tokens; @@ -595,7 +585,7 @@ class eosio_system_tester : public TESTER { vector data = get_row_by_account( config::system_account_name, from, N(delband), receiver ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant("delegated_bandwidth", data, abi_serializer_max_time); } - + asset get_rex_balance( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); From fc6429a920672bfcc9a4141153d848572fbc1659 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 16 Apr 2019 22:51:26 -0400 Subject: [PATCH 0773/1048] fix tests that broke because of RESTRICT_ACTION_TO_SELF and FORWARD_SETCODE protocol features --- tests/contracts.hpp.in | 7 +- tests/eosio.msig_tests.cpp | 12 +- tests/eosio.system_tester.hpp | 30 +- tests/eosio.token_tests.cpp | 20 +- tests/test_contracts/exchange.wast | 47435 ---------------------- tests/test_contracts/reject_all.wasm | Bin 0 -> 1013 bytes tests/test_contracts/test_api.wasm | Bin 89736 -> 0 bytes tests/test_contracts/test_api.wast | 53138 ------------------------- 8 files changed, 42 insertions(+), 100600 deletions(-) delete mode 100644 tests/test_contracts/exchange.wast create mode 100755 tests/test_contracts/reject_all.wasm delete mode 100644 tests/test_contracts/test_api.wasm delete mode 100644 tests/test_contracts/test_api.wast diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index acff5b87..f7780d3e 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -5,23 +5,18 @@ namespace eosio { namespace testing { struct contracts { static std::vector system_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.system/eosio.system.wasm"); } - static std::string system_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.system/eosio.system.wast"); } static std::vector system_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.system/eosio.system.abi"); } static std::vector token_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.token/eosio.token.wasm"); } - static std::string token_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.token/eosio.token.wast"); } static std::vector token_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.token/eosio.token.abi"); } static std::vector msig_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.msig/eosio.msig.wasm"); } - static std::string msig_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.msig/eosio.msig.wast"); } static std::vector msig_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.msig/eosio.msig.abi"); } static std::vector wrap_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.wrap/eosio.wrap.wasm"); } - static std::string wrap_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.wrap/eosio.wrap.wast"); } static std::vector wrap_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.wrap/eosio.wrap.abi"); } static std::vector bios_wasm() { return read_wasm("${CMAKE_BINARY_DIR}/../contracts/eosio.bios/eosio.bios.wasm"); } - static std::string bios_wast() { return read_wast("${CMAKE_BINARY_DIR}/../contracts/eosio.bios/eosio.bios.wast"); } static std::vector bios_abi() { return read_abi("${CMAKE_BINARY_DIR}/../contracts/eosio.bios/eosio.bios.abi"); } struct util { - static std::vector test_api_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/test_api.wasm"); } + static std::vector reject_all_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/reject_all.wasm"); } static std::vector exchange_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/exchange.wasm"); } static std::vector system_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/eosio.system.old/eosio.system.wasm"); } static std::vector system_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.system.old/eosio.system.abi"); } diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 39b6a5f9..c0ae25fd 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -431,7 +431,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) vector action_perm = {{N(eosio), config::active_name}}; - auto wasm = contracts::util::test_api_wasm(); + auto wasm = contracts::util::reject_all_wasm(); variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") @@ -497,10 +497,10 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - // can't create account because system contract was replace by the test_api contract + // can't create account because system contract was replaced by the reject_all contract BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), - eosio_assert_message_exception, eosio_assert_message_is("Unknown Test") + eosio_assert_message_exception, eosio_assert_message_is("rejecting all actions") ); } FC_LOG_AND_RETHROW() @@ -546,7 +546,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester vector action_perm = {{N(eosio), config::active_name}}; - auto wasm = contracts::util::test_api_wasm(); + auto wasm = contracts::util::reject_all_wasm(); variant pretty_trx = fc::mutable_variant_object() ("expiration", "2020-01-01T00:30") @@ -624,10 +624,10 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - // can't create account because system contract was replace by the test_api contract + // can't create account because system contract was replaced by the reject_all contract BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), - eosio_assert_message_exception, eosio_assert_message_is("Unknown Test") + eosio_assert_message_exception, eosio_assert_message_is("rejecting all actions") ); } FC_LOG_AND_RETHROW() diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 397d1cdc..ff8d73e4 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -753,11 +753,31 @@ class eosio_system_tester : public TESTER { } void issue( name to, const asset& amount, name manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() - ("to", to ) - ("quantity", amount ) - ("memo", "") - ); + signed_transaction trx; + trx.actions.emplace_back( + get_action( N(eosio.token), N(issue), + vector{{manager, config::active_name}}, + mutable_variant_object() + ("to", manager ) + ("quantity", amount ) + ("memo", "") + ) + ); + if( to != manager ) { + trx.actions.emplace_back( + get_action( N(eosio.token), N(transfer), + vector{{manager, config::active_name}}, + mutable_variant_object() + ("from", manager) + ("to", to ) + ("quantity", amount ) + ("memo", "") + ) + ); + } + set_transaction_headers( trx ); + trx.sign( get_private_key( manager, "active" ), control->get_chain_id() ); + push_transaction( trx ); } void transfer( name from, name to, const asset& amount, name manager = config::system_account_name ) { base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 8d7d73ff..0ad042f8 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -72,9 +72,9 @@ class eosio_token_tester : public tester { ); } - action_result issue( account_name issuer, account_name to, asset quantity, string memo ) { + action_result issue( account_name issuer, asset quantity, string memo ) { return push_action( issuer, N(issue), mvo() - ( "to", to) + ( "to", issuer) ( "quantity", quantity) ( "memo", memo) ); @@ -214,7 +214,7 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { auto token = create( N(alice), asset::from_string("1000.000 TKN")); produce_blocks(1); - issue( N(alice), N(alice), asset::from_string("500.000 TKN"), "hola" ); + issue( N(alice), asset::from_string("500.000 TKN"), "hola" ); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -229,15 +229,15 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "quantity exceeds available supply" ), - issue( N(alice), N(alice), asset::from_string("500.001 TKN"), "hola" ) + issue( N(alice), asset::from_string("500.001 TKN"), "hola" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must issue positive quantity" ), - issue( N(alice), N(alice), asset::from_string("-1.000 TKN"), "hola" ) + issue( N(alice), asset::from_string("-1.000 TKN"), "hola" ) ); BOOST_REQUIRE_EQUAL( success(), - issue( N(alice), N(alice), asset::from_string("1.000 TKN"), "hola" ) + issue( N(alice), asset::from_string("1.000 TKN"), "hola" ) ); @@ -248,7 +248,7 @@ BOOST_FIXTURE_TEST_CASE( retire_tests, eosio_token_tester ) try { auto token = create( N(alice), asset::from_string("1000.000 TKN")); produce_blocks(1); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("500.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("500.000 TKN"), "hola" ) ); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -305,7 +305,7 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { auto token = create( N(alice), asset::from_string("1000 CERO")); produce_blocks(1); - issue( N(alice), N(alice), asset::from_string("1000 CERO"), "hola" ); + issue( N(alice), asset::from_string("1000 CERO"), "hola" ); auto stats = get_stats("0,CERO"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -353,7 +353,7 @@ BOOST_FIXTURE_TEST_CASE( open_tests, eosio_token_tester ) try { auto alice_balance = get_account(N(alice), "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("1000 CERO"), "issue" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("1000 CERO"), "issue" ) ); alice_balance = get_account(N(alice), "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() @@ -392,7 +392,7 @@ BOOST_FIXTURE_TEST_CASE( close_tests, eosio_token_tester ) try { auto alice_balance = get_account(N(alice), "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("1000 CERO"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("1000 CERO"), "hola" ) ); alice_balance = get_account(N(alice), "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() diff --git a/tests/test_contracts/exchange.wast b/tests/test_contracts/exchange.wast deleted file mode 100644 index 2b690021..00000000 --- a/tests/test_contracts/exchange.wast +++ /dev/null @@ -1,47435 +0,0 @@ -(module - (type $FUNCSIG$vijiiii (func (param i32 i64 i32 i32 i32 i32))) - (type $FUNCSIG$viji (func (param i32 i64 i32))) - (type $FUNCSIG$vijji (func (param i32 i64 i64 i32))) - (type $FUNCSIG$vijjdi (func (param i32 i64 i64 f64 i32))) - (type $FUNCSIG$v (func)) - (type $FUNCSIG$j (func (result i64))) - (type $FUNCSIG$vjj (func (param i64 i64))) - (type $FUNCSIG$vii (func (param i32 i32))) - (type $FUNCSIG$ijjjj (func (param i64 i64 i64 i64) (result i32))) - (type $FUNCSIG$iiii (func (param i32 i32 i32) (result i32))) - (type $FUNCSIG$vijii (func (param i32 i64 i32 i32))) - (type $FUNCSIG$ijjjjii (func (param i64 i64 i64 i64 i32 i32) (result i32))) - (type $FUNCSIG$vi (func (param i32))) - (type $FUNCSIG$ijjjij (func (param i64 i64 i64 i32 i64) (result i32))) - (type $FUNCSIG$iii (func (param i32 i32) (result i32))) - (type $FUNCSIG$ijjjii (func (param i64 i64 i64 i32 i32) (result i32))) - (type $FUNCSIG$vj (func (param i64))) - (type $FUNCSIG$vd (func (param f64))) - (type $FUNCSIG$ijjjji (func (param i64 i64 i64 i64 i32) (result i32))) - (type $FUNCSIG$ij (func (param i64) (result i32))) - (type $FUNCSIG$i (func (result i32))) - (import "env" "abort" (func $abort)) - (import "env" "action_data_size" (func $action_data_size (result i32))) - (import "env" "current_receiver" (func $current_receiver (result i64))) - (import "env" "current_time" (func $current_time (result i64))) - (import "env" "db_find_i64" (func $db_find_i64 (param i64 i64 i64 i64) (result i32))) - (import "env" "db_get_i64" (func $db_get_i64 (param i32 i32 i32) (result i32))) - (import "env" "db_idx64_find_primary" (func $db_idx64_find_primary (param i64 i64 i64 i32 i64) (result i32))) - (import "env" "db_idx64_lowerbound" (func $db_idx64_lowerbound (param i64 i64 i64 i32 i32) (result i32))) - (import "env" "db_idx64_next" (func $db_idx64_next (param i32 i32) (result i32))) - (import "env" "db_idx64_remove" (func $db_idx64_remove (param i32))) - (import "env" "db_idx64_store" (func $db_idx64_store (param i64 i64 i64 i64 i32) (result i32))) - (import "env" "db_idx64_update" (func $db_idx64_update (param i32 i64 i32))) - (import "env" "db_lowerbound_i64" (func $db_lowerbound_i64 (param i64 i64 i64 i64) (result i32))) - (import "env" "db_next_i64" (func $db_next_i64 (param i32 i32) (result i32))) - (import "env" "db_remove_i64" (func $db_remove_i64 (param i32))) - (import "env" "db_store_i64" (func $db_store_i64 (param i64 i64 i64 i64 i32 i32) (result i32))) - (import "env" "db_update_i64" (func $db_update_i64 (param i32 i64 i32 i32))) - (import "env" "eosio_assert" (func $eosio_assert (param i32 i32))) - (import "env" "eosio_exit" (func $eosio_exit (param i32))) - (import "env" "has_auth" (func $has_auth (param i64) (result i32))) - (import "env" "memcpy" (func $memcpy (param i32 i32 i32) (result i32))) - (import "env" "printdf" (func $printdf (param f64))) - (import "env" "printi" (func $printi (param i64))) - (import "env" "printn" (func $printn (param i64))) - (import "env" "prints" (func $prints (param i32))) - (import "env" "prints_l" (func $prints_l (param i32 i32))) - (import "env" "printui" (func $printui (param i64))) - (import "env" "read_action_data" (func $read_action_data (param i32 i32) (result i32))) - (import "env" "require_auth" (func $require_auth (param i64))) - (import "env" "require_auth2" (func $require_auth2 (param i64 i64))) - (import "env" "require_recipient" (func $require_recipient (param i64))) - (import "env" "send_inline" (func $send_inline (param i32 i32))) - (table 6 6 anyfunc) - (elem (i32.const 0) $__wasm_nullptr $_ZN5eosio8exchange7createxEyNS_5assetEmNS_14extended_assetES2_ $_ZN5eosio8exchange4lendEyNS_11symbol_typeENS_14extended_assetE $_ZN5eosio8exchange8withdrawEyNS_14extended_assetE $_ZN5eosio8exchange6unlendEyNS_11symbol_typeEdNS_15extended_symbolE $_ZN5eosio8exchange7depositEyNS_14extended_assetE) - (memory $0 1) - (data (i32.const 4) "\b0W\00\00") - (data (i32.const 16) "magnitude of asset amount must be less than 2^62\00") - (data (i32.const 80) "invalid symbol name\00") - (data (i32.const 112) "unexpected asset contract input\00") - (data (i32.const 144) "unexpected asset symbol input\00") - (data (i32.const 176) "invalid sell\00") - (data (i32.const 192) "invalid conversion\00") - (data (i32.const 224) "object passed to iterator_to is not in multi_index\00") - (data (i32.const 288) "cannot create objects in table of another contract\00") - (data (i32.const 352) "cannot pass end iterator to modify\00") - (data (i32.const 400) "object passed to modify is not in multi_index\00") - (data (i32.const 448) "cannot modify objects in table of another contract\00") - (data (i32.const 512) "overdrawn balance 2\00") - (data (i32.const 544) "updater cannot change primary key when modifying an object\00") - (data (i32.const 608) "write\00") - (data (i32.const 624) "overdrawn balance 1\00") - (data (i32.const 656) "error reading iterator\00") - (data (i32.const 688) "read\00") - (data (i32.const 704) "get\00") - (data (i32.const 720) "unknown market\00") - (data (i32.const 736) "programmer error: insufficient collateral to cover\00") - (data (i32.const 800) "type mismatch\00") - (data (i32.const 816) "attempt to subtract asset with different symbol\00") - (data (i32.const 864) "subtraction underflow\00") - (data (i32.const 896) "subtraction overflow\00") - (data (i32.const 928) "cannot pass end iterator to erase\00") - (data (i32.const 976) "object passed to erase is not in multi_index\00") - (data (i32.const 1024) "cannot erase objects in table of another contract\00") - (data (i32.const 1088) "attempt to remove object that was not in multi_index\00") - (data (i32.const 1152) "cannot increment end iterator\00") - (data (i32.const 1184) "unable to lend to this market\00") - (data (i32.const 1216) "underflow\00") - (data (i32.const 1232) "cannot unlend negative balance\00") - (data (i32.const 1264) "sym: \00") - (data (i32.const 1280) "@\00") - (data (i32.const 1296) "unlend: \00") - (data (i32.const 1312) " existing interest_shares: \00") - (data (i32.const 1344) "\n\00") - (data (i32.const 1360) ",\00") - (data (i32.const 1376) "invalid debt asset\00") - (data (i32.const 1408) "no known margin position\00") - (data (i32.const 1440) "attempt to cover more than user has\00") - (data (i32.const 1488) "unable to cover debt\00") - (data (i32.const 1520) "cannot borrow neg\00") - (data (i32.const 1552) "cannot have neg collat\00") - (data (i32.const 1584) "user failed to claim all collateral\00") - (data (i32.const 1632) "attempt to add asset with different symbol\00") - (data (i32.const 1680) "addition underflow\00") - (data (i32.const 1712) "addition overflow\00") - (data (i32.const 1744) "insufficient funds availalbe to borrow\00") - (data (i32.const 1792) "this update would trigger a margin call\00") - (data (i32.const 1840) "invalid quantity\00") - (data (i32.const 1872) "deposit\00") - (data (i32.const 1888) "active\00") - (data (i32.const 1904) "transfer\00") - (data (i32.const 1920) "cannot withdraw negative balance\00") - (data (i32.const 1968) "withdraw\00") - (data (i32.const 1984) "invalid sell amount\00") - (data (i32.const 2016) "sell amount must be positive\00") - (data (i32.const 2048) "invalid min receive amount\00") - (data (i32.const 2080) "min receive amount cannot be negative\00") - (data (i32.const 2128) " \00") - (data (i32.const 2144) " => \00") - (data (i32.const 2160) "unable to fill\00") - (data (i32.const 2176) "sold\00") - (data (i32.const 2192) "received\00") - (data (i32.const 2224) "unable to find key\00") - (data (i32.const 2256) "can only transfer to white listed accounts\00") - (data (i32.const 2304) "receiver requires whitelist by issuer\00") - (data (i32.const 2352) ".\00") - (data (i32.const 2368) " \00") - (data (i32.const 2384) "invalid borrow delta\00") - (data (i32.const 2416) "invalid collateral delta\00") - (data (i32.const 2448) "no effect\00") - (data (i32.const 2464) "invalid args\00") - (data (i32.const 2480) "invalid asset for market\00") - (data (i32.const 2512) "borrowed\00") - (data (i32.const 2528) "collateral\00") - (data (i32.const 2544) "invalid cover amount\00") - (data (i32.const 2576) "cover amount must be positive\00") - (data (i32.const 2608) "invalid initial supply\00") - (data (i32.const 2640) "initial supply must be positive\00") - (data (i32.const 2672) "invalid base deposit\00") - (data (i32.const 2704) "base deposit must be positive\00") - (data (i32.const 2736) "invalid quote deposit\00") - (data (i32.const 2768) "quote deposit must be positive\00") - (data (i32.const 2800) "must exchange between two different currencies\00") - (data (i32.const 2848) "base: \00") - (data (i32.const 2864) "quote: \00") - (data (i32.const 2880) "marketid: \00") - (data (i32.const 2896) " \n \00") - (data (i32.const 2912) "market already exists\00") - (data (i32.const 2944) "initial exchange tokens\00") - (data (i32.const 2976) "new exchange issue\00") - (data (i32.const 3008) "new exchange deposit\00") - (data (i32.const 3040) "token with symbol already exists\00") - (data (i32.const 3088) "must lend a positive amount\00") - (data (i32.const 3120) "must unlend a positive amount\00") - (data (i32.const 3152) "invalid quantity in transfer\00") - (data (i32.const 3184) "zero quantity is disallowed in transfer\00") - (data (i32.const 3232) "withdrew tokens without withdraw in memo\00") - (data (i32.const 3280) "received tokens without deposit in memo\00") - (data (i32.const 3328) "must transfer positive quantity\00") - (data (i32.const 3360) "overdrawn balance\00") - (data (i32.const 3392) "account is frozen by issuer\00") - (data (i32.const 3424) "all transfers are frozen by issuer\00") - (data (i32.const 3472) "account is not white listed\00") - (data (i32.const 3504) "issuer may not recall token\00") - (data (i32.const 3536) "insufficient authority\00") - (data (i32.const 3568) "issue\n\00") - (data (i32.const 3584) "transfer\n\00") - (data (i32.const 3600) "create\n\00") - (data (i32.const 3616) "must issue positive quantity\00") - (data (i32.const 3664) "\00\00\00\00\00\00\f0?\00\00\00\00\00\00\f8?") - (data (i32.const 3680) "\00\00\00\00\00\00\00\00\06\d0\cfC\eb\fdL>") - (data (i32.const 3696) "\00\00\00\00\00\00\00\00\00\00\00@\03\b8\e2?") - (data (i32.const 12112) "malloc_from_freed was designed to only be called after _heap was completely allocated\00") - (export "memory" (memory $0)) - (export "_ZeqRK11checksum256S1_" (func $_ZeqRK11checksum256S1_)) - (export "_ZeqRK11checksum160S1_" (func $_ZeqRK11checksum160S1_)) - (export "_ZneRK11checksum160S1_" (func $_ZneRK11checksum160S1_)) - (export "now" (func $now)) - (export "_ZN5eosio12require_authERKNS_16permission_levelE" (func $_ZN5eosio12require_authERKNS_16permission_levelE)) - (export "_ZN5eosio14exchange_state19convert_to_exchangeERNS0_9connectorENS_14extended_assetE" (func $_ZN5eosio14exchange_state19convert_to_exchangeERNS0_9connectorENS_14extended_assetE)) - (export "_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE" (func $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE)) - (export "_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE" (func $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE)) - (export "_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE" (func $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE)) - (export "_ZNK5eosio14exchange_state20requires_margin_callEv" (func $_ZNK5eosio14exchange_state20requires_margin_callEv)) - (export "_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE" (func $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE)) - (export "_ZN5eosio12market_stateC2EyNS_11symbol_typeERNS_17exchange_accountsE" (func $_ZN5eosio12market_stateC2EyNS_11symbol_typeERNS_17exchange_accountsE)) - (export "_ZN5eosio12market_state11margin_callENS_15extended_symbolE" (func $_ZN5eosio12market_state11margin_callENS_15extended_symbolE)) - (export "_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE" (func $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE)) - (export "_ZNK5eosio12market_state13initial_stateEv" (func $_ZNK5eosio12market_state13initial_stateEv)) - (export "_ZN5eosio12market_state4lendEyRKNS_14extended_assetE" (func $_ZN5eosio12market_state4lendEyRKNS_14extended_assetE)) - (export "_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd" (func $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd)) - (export "_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE" (func $_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE)) - (export "_ZN5eosio12market_state12cover_marginEyRKNS_14extended_assetE" (func $_ZN5eosio12market_state12cover_marginEyRKNS_14extended_assetE)) - (export "_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE" (func $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE)) - (export "_ZN5eosio12market_state13update_marginEyRKNS_14extended_assetES3_" (func $_ZN5eosio12market_state13update_marginEyRKNS_14extended_assetES3_)) - (export "_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_" (func $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_)) - (export "_ZN5eosio12market_state4saveEv" (func $_ZN5eosio12market_state4saveEv)) - (export "_ZN5eosio8exchange7depositEyNS_14extended_assetE" (func $_ZN5eosio8exchange7depositEyNS_14extended_assetE)) - (export "_ZN5eosio8exchange8withdrawEyNS_14extended_assetE" (func $_ZN5eosio8exchange8withdrawEyNS_14extended_assetE)) - (export "_ZN5eosio8exchange2onERKNS0_5tradeE" (func $_ZN5eosio8exchange2onERKNS0_5tradeE)) - (export "_ZN5eosio8exchange2onERKNS0_8upmarginE" (func $_ZN5eosio8exchange2onERKNS0_8upmarginE)) - (export "_ZN5eosio8exchange2onERKNS0_11covermarginE" (func $_ZN5eosio8exchange2onERKNS0_11covermarginE)) - (export "_ZN5eosio8exchange7createxEyNS_5assetEmNS_14extended_assetES2_" (func $_ZN5eosio8exchange7createxEyNS_5assetEmNS_14extended_assetES2_)) - (export "_ZN5eosio8exchange4lendEyNS_11symbol_typeENS_14extended_assetE" (func $_ZN5eosio8exchange4lendEyNS_11symbol_typeENS_14extended_assetE)) - (export "_ZN5eosio8exchange6unlendEyNS_11symbol_typeEdNS_15extended_symbolE" (func $_ZN5eosio8exchange6unlendEyNS_11symbol_typeEdNS_15extended_symbolE)) - (export "_ZN5eosio8exchange2onERKNS_8currency8transferEy" (func $_ZN5eosio8exchange2onERKNS_8currency8transferEy)) - (export "_ZN5eosio8exchange5applyEyy" (func $_ZN5eosio8exchange5applyEyy)) - (export "apply" (func $apply)) - (export "pow" (func $pow)) - (export "sqrt" (func $sqrt)) - (export "fabs" (func $fabs)) - (export "scalbn" (func $scalbn)) - (export "memcmp" (func $memcmp)) - (export "strlen" (func $strlen)) - (export "malloc" (func $malloc)) - (export "free" (func $free)) - (func $_ZeqRK11checksum256S1_ (param $0 i32) (param $1 i32) (result i32) - (i32.eqz - (call $memcmp - (get_local $0) - (get_local $1) - (i32.const 32) - ) - ) - ) - (func $_ZeqRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) - (i32.eqz - (call $memcmp - (get_local $0) - (get_local $1) - (i32.const 32) - ) - ) - ) - (func $_ZneRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) - (i32.ne - (call $memcmp - (get_local $0) - (get_local $1) - (i32.const 32) - ) - (i32.const 0) - ) - ) - (func $now (result i32) - (i32.wrap/i64 - (i64.div_u - (call $current_time) - (i64.const 1000000) - ) - ) - ) - (func $_ZN5eosio12require_authERKNS_16permission_levelE (param $0 i32) - (call $require_auth2 - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (func $_ZN5eosio14exchange_state19convert_to_exchangeERNS0_9connectorENS_14extended_assetE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (i64.store offset=8 - (get_local $1) - (i64.add - (tee_local $5 - (i64.trunc_s/f64 - (f64.neg - (f64.mul - (f64.convert_s/i64 - (i64.load offset=8 - (get_local $1) - ) - ) - (f64.sub - (f64.const 1) - (call $pow - (f64.add - (f64.div - (f64.convert_s/i64 - (tee_local $6 - (i64.load - (get_local $3) - ) - ) - ) - (f64.convert_s/i64 - (i64.add - (get_local $6) - (i64.load - (get_local $2) - ) - ) - ) - ) - (f64.const 1) - ) - (f64.div - (f64.convert_u/i32 - (i32.load offset=24 - (get_local $2) - ) - ) - (f64.const 1e3) - ) - ) - ) - ) - ) - ) - ) - (i64.load offset=8 - (get_local $1) - ) - ) - ) - (i64.store - (get_local $2) - (i64.add - (get_local $6) - (i64.load - (get_local $2) - ) - ) - ) - (set_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (set_local $6 - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i64.store - (get_local $0) - (get_local $5) - ) - (i64.store offset=8 - (get_local $0) - (get_local $6) - ) - (call $eosio_assert - (i64.lt_u - (i64.add - (get_local $5) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775807) - ) - (i32.const 16) - ) - (set_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (set_local $1 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $6) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $2 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $2 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $2) - (i32.const 80) - ) - (i64.store offset=16 - (get_local $0) - (get_local $4) - ) - ) - (func $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i64) - (local $5 f64) - (local $6 i64) - (local $7 i64) - (call $eosio_assert - (i64.eq - (i64.load offset=16 - (get_local $3) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (i32.const 112) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $3) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i32.const 144) - ) - (set_local $6 - (i64.load - (get_local $2) - ) - ) - (set_local $5 - (call $pow - (f64.add - (f64.div - (f64.convert_s/i64 - (tee_local $7 - (i64.load - (get_local $3) - ) - ) - ) - (f64.convert_s/i64 - (i64.sub - (i64.load offset=8 - (get_local $1) - ) - (get_local $7) - ) - ) - ) - (f64.const 1) - ) - (f64.div - (f64.const 1e3) - (f64.convert_u/i32 - (i32.load offset=24 - (get_local $2) - ) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $1) - (i64.sub - (i64.load offset=8 - (get_local $1) - ) - (get_local $7) - ) - ) - (i64.store - (get_local $2) - (i64.sub - (i64.load - (get_local $2) - ) - (tee_local $7 - (i64.trunc_s/f64 - (f64.mul - (f64.convert_s/i64 - (get_local $6) - ) - (f64.add - (get_local $5) - (f64.const -1) - ) - ) - ) - ) - ) - ) - (set_local $4 - (i64.load offset=16 - (get_local $2) - ) - ) - (set_local $6 - (i64.load offset=8 - (get_local $2) - ) - ) - (i64.store - (get_local $0) - (get_local $7) - ) - (i64.store offset=8 - (get_local $0) - (get_local $6) - ) - (call $eosio_assert - (i64.lt_u - (i64.add - (get_local $7) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775807) - ) - (i32.const 16) - ) - (set_local $7 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $7) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $1 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 80) - ) - (i64.store offset=16 - (get_local $0) - (get_local $4) - ) - ) - (func $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 f64) - (local $10 i32) - (local $11 i32) - (local $12 i64) - (local $13 i32) - (local $14 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $14 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 208) - ) - ) - ) - (set_local $8 - (i64.load - (i32.add - (get_local $1) - (i32.const 152) - ) - ) - ) - (set_local $7 - (i64.load - (i32.add - (get_local $1) - (i32.const 144) - ) - ) - ) - (set_local $6 - (i64.load - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - ) - (set_local $5 - (i64.load - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - ) - (set_local $12 - (i64.load offset=16 - (get_local $2) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (br_if $label$8 - (i64.ne - (tee_local $4 - (i64.load offset=8 - (get_local $2) - ) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - ) - (br_if $label$8 - (i64.ne - (get_local $12) - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - ) - (br_if $label$7 - (i64.ne - (tee_local $12 - (i64.load - (get_local $3) - ) - ) - (get_local $5) - ) - ) - (br_if $label$7 - (i64.ne - (i64.load offset=8 - (get_local $3) - ) - (get_local $6) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 160) - ) - (i32.const 16) - ) - (tee_local $5 - (i64.load - (tee_local $13 - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 160) - ) - (i32.const 8) - ) - (tee_local $4 - (i64.load - (tee_local $10 - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - ) - ) - (set_local $12 - (i64.load - (get_local $2) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 48) - ) - (i32.const 16) - ) - (get_local $5) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 48) - ) - (i32.const 8) - ) - (get_local $4) - ) - (i64.store offset=160 - (get_local $14) - (get_local $12) - ) - (i64.store offset=48 - (get_local $14) - (get_local $12) - ) - (call $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE - (i32.add - (get_local $14) - (i32.const 184) - ) - (get_local $1) - (i32.add - (get_local $1) - (i32.const 40) - ) - (i32.add - (get_local $14) - (i32.const 48) - ) - ) - (i64.store - (get_local $13) - (i64.load - (i32.add - (i32.add - (get_local $14) - (i32.const 184) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (get_local $10) - (i64.load - (i32.add - (i32.add - (get_local $14) - (i32.const 184) - ) - (i32.const 8) - ) - ) - ) - (i64.store - (get_local $2) - (i64.load offset=184 - (get_local $14) - ) - ) - (br $label$0) - ) - (br_if $label$6 - (i64.ne - (get_local $4) - (get_local $5) - ) - ) - (br_if $label$6 - (i64.ne - (get_local $12) - (get_local $6) - ) - ) - (set_local $5 - (i64.load offset=8 - (get_local $1) - ) - ) - (set_local $9 - (call $pow - (f64.add - (f64.div - (f64.convert_s/i64 - (tee_local $12 - (i64.load - (get_local $2) - ) - ) - ) - (f64.convert_s/i64 - (i64.add - (i64.load - (tee_local $13 - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - ) - (get_local $12) - ) - ) - ) - (f64.const 1) - ) - (f64.div - (f64.convert_u/i32 - (i32.load - (i32.add - (get_local $1) - (i32.const 64) - ) - ) - ) - (f64.const 1e3) - ) - ) - ) - (i64.store - (get_local $13) - (i64.add - (get_local $12) - (i64.load - (get_local $13) - ) - ) - ) - (i64.store offset=8 - (get_local $1) - (i64.add - (tee_local $5 - (i64.trunc_s/f64 - (f64.neg - (f64.mul - (f64.convert_s/i64 - (get_local $5) - ) - (f64.sub - (f64.const 1) - (get_local $9) - ) - ) - ) - ) - ) - (i64.load offset=8 - (get_local $1) - ) - ) - ) - (set_local $6 - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (set_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i64.lt_u - (i64.add - (get_local $5) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775807) - ) - (i32.const 16) - ) - (set_local $12 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (set_local $13 - (i32.const 0) - ) - (loop $label$9 - (br_if $label$5 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $12) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$10 - (br_if $label$10 - (i64.ne - (i64.and - (tee_local $12 - (i64.shr_u - (get_local $12) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$11 - (br_if $label$5 - (i64.ne - (i64.and - (tee_local $12 - (i64.shr_u - (get_local $12) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$11 - (i32.lt_s - (tee_local $13 - (i32.add - (get_local $13) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $10 - (i32.const 1) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $13 - (i32.add - (get_local $13) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$4) - ) - ) - (block $label$12 - (br_if $label$12 - (i64.ne - (get_local $12) - (get_local $7) - ) - ) - (br_if $label$12 - (i64.ne - (i64.load offset=8 - (get_local $3) - ) - (get_local $8) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 136) - ) - (i32.const 16) - ) - (tee_local $5 - (i64.load - (tee_local $13 - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 136) - ) - (i32.const 8) - ) - (tee_local $4 - (i64.load - (tee_local $10 - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - ) - ) - (set_local $12 - (i64.load - (get_local $2) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 72) - ) - (i32.const 16) - ) - (get_local $5) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 72) - ) - (i32.const 8) - ) - (get_local $4) - ) - (i64.store offset=136 - (get_local $14) - (get_local $12) - ) - (i64.store offset=72 - (get_local $14) - (get_local $12) - ) - (call $_ZN5eosio14exchange_state21convert_from_exchangeERNS0_9connectorENS_14extended_assetE - (i32.add - (get_local $14) - (i32.const 184) - ) - (get_local $1) - (i32.add - (get_local $1) - (i32.const 136) - ) - (i32.add - (get_local $14) - (i32.const 72) - ) - ) - (i64.store - (get_local $13) - (i64.load - (i32.add - (i32.add - (get_local $14) - (i32.const 184) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (get_local $10) - (i64.load - (i32.add - (i32.add - (get_local $14) - (i32.const 184) - ) - (i32.const 8) - ) - ) - ) - (i64.store - (get_local $2) - (i64.load offset=184 - (get_local $14) - ) - ) - (br $label$0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 192) - ) - (br $label$0) - ) - (br_if $label$3 - (i64.ne - (get_local $4) - (get_local $7) - ) - ) - (br_if $label$3 - (i64.ne - (get_local $12) - (get_local $8) - ) - ) - (set_local $5 - (i64.load offset=8 - (get_local $1) - ) - ) - (set_local $9 - (call $pow - (f64.add - (f64.div - (f64.convert_s/i64 - (tee_local $12 - (i64.load - (get_local $2) - ) - ) - ) - (f64.convert_s/i64 - (i64.add - (i64.load - (tee_local $13 - (i32.add - (get_local $1) - (i32.const 136) - ) - ) - ) - (get_local $12) - ) - ) - ) - (f64.const 1) - ) - (f64.div - (f64.convert_u/i32 - (i32.load - (i32.add - (get_local $1) - (i32.const 160) - ) - ) - ) - (f64.const 1e3) - ) - ) - ) - (i64.store - (get_local $13) - (i64.add - (get_local $12) - (i64.load - (get_local $13) - ) - ) - ) - (i64.store offset=8 - (get_local $1) - (i64.add - (tee_local $5 - (i64.trunc_s/f64 - (f64.neg - (f64.mul - (f64.convert_s/i64 - (get_local $5) - ) - (f64.sub - (f64.const 1) - (get_local $9) - ) - ) - ) - ) - ) - (i64.load offset=8 - (get_local $1) - ) - ) - ) - (set_local $6 - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (set_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i64.lt_u - (i64.add - (get_local $5) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775807) - ) - (i32.const 16) - ) - (set_local $12 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (set_local $13 - (i32.const 0) - ) - (loop $label$13 - (br_if $label$2 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $12) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$14 - (br_if $label$14 - (i64.ne - (i64.and - (tee_local $12 - (i64.shr_u - (get_local $12) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$15 - (br_if $label$2 - (i64.ne - (i64.and - (tee_local $12 - (i64.shr_u - (get_local $12) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$15 - (i32.lt_s - (tee_local $13 - (i32.add - (get_local $13) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $10 - (i32.const 1) - ) - (br_if $label$13 - (i32.lt_s - (tee_local $13 - (i32.add - (get_local $13) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$1) - ) - ) - (set_local $10 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $10) - (i32.const 80) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 8) - ) - (get_local $4) - ) - (i64.store - (get_local $2) - (get_local $5) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (get_local $6) - ) - (br $label$0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 176) - ) - (br $label$0) - ) - (set_local $10 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $10) - (i32.const 80) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 8) - ) - (get_local $4) - ) - (i64.store - (get_local $2) - (get_local $5) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (get_local $6) - ) - ) - (block $label$16 - (block $label$17 - (br_if $label$17 - (i64.ne - (i64.load - (get_local $3) - ) - (i64.load - (tee_local $13 - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - ) - ) - (br_if $label$17 - (i64.ne - (i64.load offset=8 - (get_local $3) - ) - (i64.load - (tee_local $10 - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - ) - ) - (i64.store - (get_local $0) - (i64.load - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.load - (get_local $10) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (br $label$16) - ) - (i64.store - (tee_local $10 - (i32.add - (i32.add - (get_local $14) - (i32.const 112) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - (i64.store - (tee_local $11 - (i32.add - (i32.add - (get_local $14) - (i32.const 112) - ) - (i32.const 8) - ) - ) - (i64.load - (get_local $13) - ) - ) - (i64.store offset=112 - (get_local $14) - (i64.load - (get_local $2) - ) - ) - (i64.store - (tee_local $13 - (i32.add - (i32.add - (get_local $14) - (i32.const 96) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - (i64.store offset=96 - (get_local $14) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 24) - ) - (i32.const 16) - ) - (i64.load - (get_local $10) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 24) - ) - (i32.const 8) - ) - (i64.load - (get_local $11) - ) - ) - (i64.store offset=24 - (get_local $14) - (i64.load offset=112 - (get_local $14) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $14) - (i32.const 8) - ) - (i32.const 8) - ) - (i64.load - (get_local $13) - ) - ) - (i64.store offset=8 - (get_local $14) - (i64.load offset=96 - (get_local $14) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (get_local $0) - (get_local $1) - (i32.add - (get_local $14) - (i32.const 24) - ) - (i32.add - (get_local $14) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $14) - (i32.const 208) - ) - ) - ) - (func $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE (param $0 i32) (param $1 i32) (result i32) - (local $2 i64) - (local $3 f64) - (local $4 i64) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 336) - ) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i64.lt_s - (tee_local $5 - (i64.load - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - ) - (i64.const 1) - ) - ) - (drop - (call $memcpy - (i32.add - (get_local $7) - (i32.const 104) - ) - (get_local $0) - (i32.const 232) - ) - ) - (set_local $3 - (f64.load - (i32.add - (get_local $1) - (i32.const 80) - ) - ) - ) - (i64.store offset=64 - (get_local $7) - (tee_local $4 - (i64.load offset=8 - (get_local $1) - ) - ) - ) - (i64.store offset=56 - (get_local $7) - (tee_local $5 - (i64.trunc_s/f64 - (f64.mul - (get_local $3) - (f64.convert_s/i64 - (get_local $5) - ) - ) - ) - ) - ) - (set_local $2 - (i64.load offset=16 - (get_local $1) - ) - ) - (call $eosio_assert - (i64.lt_u - (i64.add - (get_local $5) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775807) - ) - (i32.const 16) - ) - (set_local $5 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$2 - (block $label$3 - (loop $label$4 - (br_if $label$3 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $5) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$5 - (br_if $label$5 - (i64.ne - (i64.and - (tee_local $5 - (i64.shr_u - (get_local $5) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$6 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $5 - (i64.shr_u - (get_local $5) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$6 - (i32.lt_s - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $6 - (i32.const 1) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$2) - ) - ) - (set_local $6 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 80) - ) - (i64.store offset=72 - (get_local $7) - (get_local $2) - ) - (set_local $5 - (i64.load - (i32.add - (get_local $1) - (i32.const 64) - ) - ) - ) - (set_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 72) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 56) - ) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 32) - ) - (i32.load offset=72 - (get_local $7) - ) - ) - (i64.store offset=48 - (get_local $7) - (get_local $4) - ) - (i32.store - (i32.add - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 56) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 8) - ) - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 56) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=40 - (get_local $7) - (get_local $5) - ) - (i32.store offset=20 - (get_local $7) - (i32.load offset=60 - (get_local $7) - ) - ) - (i32.store offset=16 - (get_local $7) - (i32.load offset=56 - (get_local $7) - ) - ) - (i64.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i64.load offset=48 - (get_local $7) - ) - ) - (i64.store - (get_local $7) - (i64.load offset=40 - (get_local $7) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $7) - (i32.const 80) - ) - (i32.add - (get_local $7) - (i32.const 104) - ) - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $7) - ) - (set_local $0 - (i32.const 1) - ) - (br_if $label$0 - (i64.le_s - (i64.load offset=80 - (get_local $7) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - ) - ) - ) - (set_local $0 - (i32.const 0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 336) - ) - ) - (get_local $0) - ) - (func $_ZNK5eosio14exchange_state20requires_margin_callEv (param $0 i32) (result i32) - (local $1 i32) - (set_local $1 - (i32.const 1) - ) - (block $label$0 - (br_if $label$0 - (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE - (get_local $0) - (i32.add - (get_local $0) - (i32.const 40) - ) - ) - ) - (set_local $1 - (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE - (get_local $0) - (i32.add - (get_local $0) - (i32.const 136) - ) - ) - ) - ) - (get_local $1) - ) - (func $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i64) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $12 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 96) - ) - ) - ) - (i64.store offset=16 - (get_local $12) - (get_local $1) - ) - (set_local $4 - (i32.add - (tee_local $11 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $10 - (i32.mul - (i32.load - (i32.add - (get_local $0) - (i32.const 12) - ) - ) - (i32.const 48) - ) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $10) - ) - ) - (set_local $10 - (i32.div_s - (get_local $10) - (i32.const 48) - ) - ) - (set_local $9 - (get_local $11) - ) - (loop $label$1 - (set_local $9 - (select - (tee_local $7 - (i32.add - (tee_local $6 - (i32.add - (get_local $9) - (i32.mul - (tee_local $5 - (i32.shr_u - (get_local $10) - (i32.const 1) - ) - ) - (i32.const 48) - ) - ) - ) - (i32.const 48) - ) - ) - (get_local $9) - (tee_local $6 - (i64.lt_u - (i64.load - (get_local $6) - ) - (get_local $1) - ) - ) - ) - ) - (set_local $11 - (select - (get_local $7) - (get_local $11) - (get_local $6) - ) - ) - (br_if $label$1 - (tee_local $10 - (select - (i32.sub - (i32.add - (get_local $10) - (i32.const -1) - ) - (get_local $5) - ) - (get_local $5) - (get_local $6) - ) - ) - ) - ) - ) - (block $label$2 - (br_if $label$2 - (i32.eq - (get_local $11) - (get_local $4) - ) - ) - (set_local $11 - (select - (get_local $4) - (get_local $11) - (i64.gt_u - (i64.load - (get_local $11) - ) - (get_local $1) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.ne - (get_local $11) - (get_local $4) - ) - ) - (set_local $8 - (i64.load - (get_local $0) - ) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 64) - ) - (get_local $1) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 72) - ) - (i64.const -1) - ) - (i64.store - (tee_local $10 - (i32.add - (get_local $12) - (i32.const 80) - ) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 88) - ) - (i32.const 0) - ) - (i64.store offset=56 - (get_local $12) - (get_local $8) - ) - (i64.store offset=48 - (get_local $12) - (get_local $1) - ) - (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS1_9select1stIyEENSt3__14lessIyEENS0_13new_allocatorIS8_EEE13insert_uniqueEOS8_ - (i32.add - (get_local $12) - (i32.const 40) - ) - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.add - (get_local $12) - (i32.const 48) - ) - ) - (block $label$4 - (br_if $label$4 - (i32.eqz - (tee_local $5 - (i32.load - (get_local $10) - ) - ) - ) - ) - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.eq - (tee_local $10 - (i32.load - (tee_local $6 - (i32.add - (get_local $12) - (i32.const 84) - ) - ) - ) - ) - (get_local $5) - ) - ) - (loop $label$7 - (set_local $9 - (i32.load - (tee_local $10 - (i32.add - (get_local $10) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $10) - (i32.const 0) - ) - (block $label$8 - (br_if $label$8 - (i32.eqz - (get_local $9) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (i32.load - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $9) - ) - ) - ) - (call $_ZdlPv - (get_local $9) - ) - ) - (br_if $label$7 - (i32.ne - (get_local $5) - (get_local $10) - ) - ) - ) - (set_local $10 - (i32.load - (i32.add - (get_local $12) - (i32.const 80) - ) - ) - ) - (br $label$5) - ) - (set_local $10 - (get_local $5) - ) - ) - (i32.store - (get_local $6) - (get_local $5) - ) - (call $_ZdlPv - (get_local $10) - ) - ) - (set_local $11 - (i32.load offset=40 - (get_local $12) - ) - ) - (set_local $1 - (i64.load offset=16 - (get_local $12) - ) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eq - (tee_local $5 - (i32.load - (i32.add - (get_local $11) - (i32.const 36) - ) - ) - ) - (tee_local $7 - (i32.load - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - ) - ) - ) - (set_local $10 - (i32.add - (get_local $5) - (i32.const -24) - ) - ) - (set_local $6 - (i32.sub - (i32.const 0) - (get_local $7) - ) - ) - (loop $label$11 - (br_if $label$10 - (i64.eq - (i64.load - (i32.load - (get_local $10) - ) - ) - (get_local $1) - ) - ) - (set_local $5 - (get_local $10) - ) - (set_local $10 - (tee_local $9 - (i32.add - (get_local $10) - (i32.const -24) - ) - ) - ) - (br_if $label$11 - (i32.ne - (i32.add - (get_local $9) - (get_local $6) - ) - (i32.const -24) - ) - ) - ) - ) - (set_local $10 - (i32.add - (get_local $11) - (i32.const 8) - ) - ) - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_if $label$15 - (i32.eq - (get_local $5) - (get_local $7) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=20 - (tee_local $9 - (i32.load - (i32.add - (get_local $5) - (i32.const -24) - ) - ) - ) - ) - (get_local $10) - ) - (i32.const 224) - ) - (br_if $label$14 - (get_local $9) - ) - (br $label$13) - ) - (br_if $label$13 - (i32.lt_s - (tee_local $9 - (call $db_find_i64 - (i64.load - (i32.add - (get_local $11) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $11) - (i32.const 16) - ) - ) - (i64.const 6290548272952901632) - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=20 - (tee_local $9 - (call $_ZNK5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE31load_object_by_primary_iteratorEl - (get_local $10) - (get_local $9) - ) - ) - ) - (get_local $10) - ) - (i32.const 224) - ) - ) - (i32.store offset=48 - (get_local $12) - (get_local $2) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 352) - ) - (call $_ZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE6modifyIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_1EEvRKS1_yOT_ - (get_local $10) - (get_local $9) - (i32.add - (get_local $12) - (i32.const 48) - ) - ) - (br $label$12) - ) - (set_local $1 - (i64.load offset=16 - (get_local $12) - ) - ) - (i32.store offset=12 - (get_local $12) - (get_local $2) - ) - (i32.store offset=8 - (get_local $12) - (i32.add - (get_local $12) - (i32.const 16) - ) - ) - (i64.store offset=40 - (get_local $12) - (get_local $1) - ) - (call $eosio_assert - (i64.eq - (i64.load - (i32.add - (get_local $11) - (i32.const 8) - ) - ) - (call $current_receiver) - ) - (i32.const 288) - ) - (i32.store offset=48 - (get_local $12) - (get_local $10) - ) - (i32.store offset=52 - (get_local $12) - (i32.add - (get_local $12) - (i32.const 8) - ) - ) - (i32.store offset=56 - (get_local $12) - (i32.add - (get_local $12) - (i32.const 40) - ) - ) - (i32.store offset=16 - (tee_local $9 - (call $_Znwj - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i64.store offset=8 align=4 - (get_local $9) - (i64.const 0) - ) - (i32.store offset=20 - (get_local $9) - (get_local $10) - ) - (call $_ZZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE7emplaceIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_0EENS2_14const_iteratorEyOT_ENKUlRSH_E_clINS2_4itemEEEDaSJ_ - (i32.add - (get_local $12) - (i32.const 48) - ) - (get_local $9) - ) - (i32.store offset=32 - (get_local $12) - (get_local $9) - ) - (i64.store offset=48 - (get_local $12) - (tee_local $1 - (i64.load - (get_local $9) - ) - ) - ) - (i32.store offset=28 - (get_local $12) - (tee_local $5 - (i32.load offset=24 - (get_local $9) - ) - ) - ) - (block $label$16 - (block $label$17 - (br_if $label$17 - (i32.ge_u - (tee_local $10 - (i32.load - (tee_local $6 - (i32.add - (get_local $11) - (i32.const 36) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $11) - (i32.const 40) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $10) - (get_local $1) - ) - (i32.store offset=16 - (get_local $10) - (get_local $5) - ) - (i32.store offset=32 - (get_local $12) - (i32.const 0) - ) - (i32.store - (get_local $10) - (get_local $9) - ) - (i32.store - (get_local $6) - (i32.add - (get_local $10) - (i32.const 24) - ) - ) - (br $label$16) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy6290548272952901632ENS1_9exaccountEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $11) - (i32.const 32) - ) - (i32.add - (get_local $12) - (i32.const 32) - ) - (i32.add - (get_local $12) - (i32.const 48) - ) - (i32.add - (get_local $12) - (i32.const 28) - ) - ) - ) - (set_local $10 - (i32.load offset=32 - (get_local $12) - ) - ) - (i32.store offset=32 - (get_local $12) - (i32.const 0) - ) - (br_if $label$12 - (i32.eqz - (get_local $10) - ) - ) - (block $label$18 - (br_if $label$18 - (i32.eqz - (i32.load - (i32.add - (get_local $10) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $10) - ) - ) - ) - (call $_ZdlPv - (get_local $10) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $12) - (i32.const 96) - ) - ) - ) - (func $_ZN5boost9container3dtl9flat_treeINS1_4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS1_9select1stIyEENSt3__14lessIyEENS0_13new_allocatorIS8_EEE13insert_uniqueEOS8_ (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i64) - (local $10 i32) - (i32.store8 offset=4 - (get_local $0) - (i32.const 0) - ) - (i32.store - (get_local $0) - (i32.const 0) - ) - (set_local $5 - (i64.load - (get_local $2) - ) - ) - (set_local $6 - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $7 - (i32.div_s - (i32.mul - (tee_local $4 - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.const 48) - ) - (i32.const 48) - ) - ) - ) - ) - (loop $label$1 - (block $label$2 - (br_if $label$2 - (i64.ge_u - (i64.load - (tee_local $8 - (i32.add - (get_local $6) - (i32.mul - (tee_local $10 - (i32.shr_u - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 48) - ) - ) - ) - ) - (get_local $5) - ) - ) - (set_local $6 - (i32.add - (get_local $8) - (i32.const 48) - ) - ) - (set_local $10 - (i32.sub - (i32.add - (get_local $7) - (i32.const -1) - ) - (get_local $10) - ) - ) - ) - (br_if $label$1 - (tee_local $7 - (get_local $10) - ) - ) - ) - ) - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.eq - (get_local $6) - (i32.add - (get_local $3) - (i32.mul - (get_local $4) - (i32.const 48) - ) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $0) - (i32.const 4) - ) - (i64.lt_u - (get_local $5) - (tee_local $9 - (i64.load - (get_local $6) - ) - ) - ) - ) - (br_if $label$5 - (i64.lt_u - (get_local $5) - (get_local $9) - ) - ) - (br $label$4) - ) - (i32.store8 - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.const 1) - ) - ) - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (br_if $label$10 - (i32.ne - (i32.load offset=8 - (get_local $1) - ) - (get_local $4) - ) - ) - (br_if $label$3 - (i32.eq - (get_local $4) - (i32.const 89478485) - ) - ) - (br_if $label$9 - (i32.gt_u - (get_local $4) - (i32.const 536870911) - ) - ) - (set_local $7 - (i32.div_u - (i32.shl - (get_local $4) - (i32.const 3) - ) - (i32.const 5) - ) - ) - (br $label$8) - ) - (call $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_expand_forwardINS2_17insert_move_proxyISA_PS8_EEEEvSE_jT_ - (get_local $1) - (get_local $6) - (i32.const 1) - (get_local $2) - ) - (br $label$7) - ) - (set_local $7 - (select - (i32.const -1) - (i32.shl - (get_local $4) - (i32.const 3) - ) - (i32.gt_u - (get_local $4) - (i32.const -1610612737) - ) - ) - ) - ) - (br_if $label$3 - (i32.ge_u - (tee_local $7 - (select - (tee_local $10 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (tee_local $7 - (select - (get_local $7) - (i32.const 89478485) - (i32.lt_u - (get_local $7) - (i32.const 89478485) - ) - ) - ) - (i32.gt_u - (get_local $10) - (get_local $7) - ) - ) - ) - (i32.const 89478486) - ) - ) - (call $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_new_allocationINS2_17insert_move_proxyISA_PS8_EEEEvSE_jSE_jT_ - (get_local $1) - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 48) - ) - ) - (get_local $7) - (get_local $6) - (i32.const 1) - (get_local $2) - ) - ) - (set_local $6 - (i32.add - (i32.load - (get_local $1) - ) - (i32.mul - (i32.div_s - (i32.sub - (get_local $6) - (get_local $3) - ) - (i32.const 48) - ) - (i32.const 48) - ) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - (return) - ) - (call $abort) - (unreachable) - ) - (func $_ZNK5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (set_local $8 - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $9) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $2 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $2) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i32.eq - (i32.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $4 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $4) - (get_local $3) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - (set_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i32.xor - (i32.shr_u - (tee_local $6 - (call $db_get_i64 - (get_local $1) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 31) - ) - (i32.const 1) - ) - (i32.const 656) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.lt_u - (get_local $6) - (i32.const 513) - ) - ) - (set_local $4 - (call $malloc - (get_local $6) - ) - ) - (br $label$4) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (get_local $9) - (i32.and - (i32.add - (get_local $6) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $db_get_i64 - (get_local $1) - (get_local $4) - (get_local $6) - ) - ) - (i32.store offset=36 - (get_local $8) - (get_local $4) - ) - (i32.store offset=32 - (get_local $8) - (get_local $4) - ) - (i32.store offset=40 - (get_local $8) - (tee_local $7 - (i32.add - (get_local $4) - (get_local $6) - ) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.le_u - (get_local $6) - (i32.const 512) - ) - ) - (call $free - (get_local $4) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $8) - (i32.const 40) - ) - ) - ) - (set_local $4 - (i32.load offset=36 - (get_local $8) - ) - ) - ) - (i32.store offset=16 - (tee_local $6 - (call $_Znwj - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i64.store offset=8 align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store offset=20 - (get_local $6) - (get_local $0) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (get_local $7) - (get_local $4) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $6) - (get_local $4) - (i32.const 8) - ) - ) - (i32.store offset=36 - (get_local $8) - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEENS_15extended_symbolExEERT_S7_RN5boost9container8flat_mapIT0_T1_NSt3__14lessISB_EENS9_13new_allocatorINSD_4pairISB_SC_EEEEEE - (i32.add - (get_local $8) - (i32.const 32) - ) - (i32.add - (get_local $6) - (i32.const 8) - ) - ) - ) - (i32.store offset=24 - (get_local $6) - (get_local $1) - ) - (i32.store offset=24 - (get_local $8) - (get_local $6) - ) - (i64.store offset=16 - (get_local $8) - (tee_local $5 - (i64.load - (get_local $6) - ) - ) - ) - (i32.store offset=12 - (get_local $8) - (tee_local $7 - (i32.load offset=24 - (get_local $6) - ) - ) - ) - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ge_u - (tee_local $4 - (i32.load - (tee_local $1 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $4) - (get_local $5) - ) - (i32.store offset=16 - (get_local $4) - (get_local $7) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $4) - (get_local $6) - ) - (i32.store - (get_local $1) - (i32.add - (get_local $4) - (i32.const 24) - ) - ) - (br $label$7) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy6290548272952901632ENS1_9exaccountEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 12) - ) - ) - ) - (set_local $4 - (i32.load offset=24 - (get_local $8) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $4) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (i32.load - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $4) - ) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 48) - ) - ) - (get_local $6) - ) - (func $_ZZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE7emplaceIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_0EENS2_14const_iteratorEyOT_ENKUlRSH_E_clINS2_4itemEEEDaSJ_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i64) - (local $14 i32) - (local $15 i32) - (set_local $14 - (tee_local $15 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $15) - ) - (i64.store - (get_local $1) - (i64.load - (i32.load - (tee_local $3 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - ) - ) - (set_local $6 - (i32.add - (tee_local $11 - (i32.load offset=8 - (get_local $1) - ) - ) - (tee_local $10 - (i32.mul - (i32.load - (i32.add - (get_local $1) - (i32.const 12) - ) - ) - (i32.const 24) - ) - ) - ) - ) - (set_local $2 - (i32.load - (get_local $0) - ) - ) - (set_local $5 - (i64.load offset=16 - (tee_local $12 - (i32.load offset=4 - (get_local $3) - ) - ) - ) - ) - (set_local $13 - (i64.load offset=8 - (get_local $12) - ) - ) - (set_local $4 - (i64.load - (get_local $12) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $10) - ) - ) - (set_local $12 - (i32.div_s - (get_local $10) - (i32.const 24) - ) - ) - (set_local $10 - (get_local $11) - ) - (loop $label$1 - (set_local $10 - (select - (tee_local $9 - (i32.add - (tee_local $8 - (i32.add - (get_local $10) - (i32.mul - (tee_local $7 - (i32.shr_u - (get_local $12) - (i32.const 1) - ) - ) - (i32.const 24) - ) - ) - ) - (i32.const 24) - ) - ) - (get_local $10) - (tee_local $8 - (i64.lt_u - (i64.load - (get_local $8) - ) - (get_local $13) - ) - ) - ) - ) - (set_local $11 - (select - (get_local $9) - (get_local $11) - (get_local $8) - ) - ) - (br_if $label$1 - (tee_local $12 - (select - (i32.sub - (i32.add - (get_local $12) - (i32.const -1) - ) - (get_local $7) - ) - (get_local $7) - (get_local $8) - ) - ) - ) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $11) - (get_local $6) - ) - ) - (br_if $label$2 - (i64.ge_u - (get_local $13) - (i64.load - (get_local $11) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $14) - (get_local $5) - ) - (i64.store - (get_local $14) - (get_local $13) - ) - (i64.store offset=16 - (get_local $14) - (i64.const 0) - ) - (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueENS0_12vec_iteratorIPS6_Lb1EEEOS6_ - (i32.add - (get_local $14) - (i32.const 24) - ) - (get_local $7) - (get_local $11) - (get_local $14) - ) - (set_local $11 - (i32.load offset=24 - (get_local $14) - ) - ) - ) - (i64.store offset=16 - (get_local $11) - (get_local $4) - ) - (call $eosio_assert - (i32.xor - (i32.wrap/i64 - (i64.shr_u - (i64.load - (i32.load - (i32.add - (get_local $3) - (i32.const 4) - ) - ) - ) - (i64.const 63) - ) - ) - (i32.const 1) - ) - (i32.const 624) - ) - (set_local $13 - (i64.extend_u/i32 - (tee_local $10 - (i32.load - (i32.add - (get_local $1) - (i32.const 12) - ) - ) - ) - ) - ) - (set_local $12 - (i32.const 8) - ) - (loop $label$4 - (set_local $12 - (i32.add - (get_local $12) - (i32.const 1) - ) - ) - (br_if $label$4 - (i64.ne - (tee_local $13 - (i64.shr_u - (get_local $13) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (get_local $10) - ) - ) - (set_local $12 - (i32.add - (i32.sub - (tee_local $10 - (i32.mul - (get_local $10) - (i32.const 24) - ) - ) - (i32.rem_u - (i32.add - (get_local $10) - (i32.const -24) - ) - (i32.const 24) - ) - ) - (get_local $12) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.lt_u - (get_local $12) - (i32.const 513) - ) - ) - (set_local $10 - (call $malloc - (get_local $12) - ) - ) - (br $label$6) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (get_local $15) - (i32.and - (i32.add - (get_local $12) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (i32.store - (get_local $14) - (get_local $10) - ) - (i32.store offset=8 - (get_local $14) - (i32.add - (get_local $10) - (get_local $12) - ) - ) - (call $eosio_assert - (i32.gt_s - (get_local $12) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (get_local $10) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $14) - (i32.add - (get_local $10) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEENS_15extended_symbolExEERT_S6_RKN5boost9container8flat_mapIT0_T1_NSt3__14lessISA_EENS8_13new_allocatorINSC_4pairISA_SB_EEEEEE - (get_local $14) - (get_local $7) - ) - ) - (i32.store offset=24 - (get_local $1) - (call $db_store_i64 - (i64.load offset=8 - (get_local $2) - ) - (i64.const 6290548272952901632) - (i64.load - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $13 - (i64.load - (get_local $1) - ) - ) - (get_local $10) - (get_local $12) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.lt_u - (get_local $12) - (i32.const 513) - ) - ) - (call $free - (get_local $10) - ) - ) - (block $label$9 - (br_if $label$9 - (i64.lt_u - (get_local $13) - (i64.load offset=16 - (get_local $2) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (select - (i64.const -2) - (i64.add - (get_local $13) - (i64.const 1) - ) - (i64.gt_u - (get_local $13) - (i64.const -3) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $14) - (i32.const 32) - ) - ) - ) - (func $_ZNSt3__16vectorIN5eosio11multi_indexILy6290548272952901632ENS1_9exaccountEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.add - (tee_local $4 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 24) - ) - ) - (i32.const 1) - ) - ) - (i32.const 178956971) - ) - ) - (set_local $7 - (i32.const 178956970) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $6 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $6) - ) - (i32.const 24) - ) - ) - (i32.const 89478484) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $5) - (tee_local $7 - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $5) - ) - ) - ) - ) - ) - ) - (set_local $6 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $5 - (i32.load - (get_local $1) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $6) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - (get_local $5) - ) - (i64.store offset=8 - (get_local $1) - (i64.load - (get_local $2) - ) - ) - (i32.store offset=16 - (get_local $1) - (i32.load - (get_local $3) - ) - ) - (set_local $4 - (i32.add - (get_local $6) - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (loop $label$6 - (set_local $3 - (i32.load - (tee_local $2 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -24) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -8) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -12) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -16) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const -24) - ) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$6 - (i32.ne - (get_local $7) - (get_local $2) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $6 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $5) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $6) - ) - ) - (loop $label$8 - (set_local $1 - (i32.load - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $1) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (i32.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $1) - ) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $6) - (get_local $7) - ) - ) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $_ZN5eosio11multi_indexILy6290548272952901632ENS_9exaccountEJEE6modifyIZNS_17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEEE3$_1EEvRKS1_yOT_ (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i64) - (local $13 i32) - (local $14 i32) - (set_local $13 - (tee_local $14 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $14) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=20 - (get_local $1) - ) - (get_local $0) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $0) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (set_local $6 - (i32.add - (tee_local $11 - (i32.load offset=8 - (get_local $1) - ) - ) - (tee_local $10 - (i32.mul - (i32.load - (i32.add - (get_local $1) - (i32.const 12) - ) - ) - (i32.const 24) - ) - ) - ) - ) - (set_local $3 - (i64.load - (get_local $1) - ) - ) - (set_local $5 - (i64.load offset=16 - (tee_local $2 - (i32.load - (get_local $2) - ) - ) - ) - ) - (set_local $12 - (i64.load offset=8 - (get_local $2) - ) - ) - (set_local $4 - (i64.load - (get_local $2) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $10) - ) - ) - (set_local $2 - (i32.div_s - (get_local $10) - (i32.const 24) - ) - ) - (set_local $10 - (get_local $11) - ) - (loop $label$1 - (set_local $10 - (select - (tee_local $9 - (i32.add - (tee_local $8 - (i32.add - (get_local $10) - (i32.mul - (tee_local $7 - (i32.shr_u - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 24) - ) - ) - ) - (i32.const 24) - ) - ) - (get_local $10) - (tee_local $8 - (i64.lt_u - (i64.load - (get_local $8) - ) - (get_local $12) - ) - ) - ) - ) - (set_local $11 - (select - (get_local $9) - (get_local $11) - (get_local $8) - ) - ) - (br_if $label$1 - (tee_local $2 - (select - (i32.sub - (i32.add - (get_local $2) - (i32.const -1) - ) - (get_local $7) - ) - (get_local $7) - (get_local $8) - ) - ) - ) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $11) - (get_local $6) - ) - ) - (br_if $label$2 - (i64.ge_u - (get_local $12) - (i64.load - (get_local $11) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $13) - (get_local $5) - ) - (i64.store - (get_local $13) - (get_local $12) - ) - (i64.store offset=16 - (get_local $13) - (i64.const 0) - ) - (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueENS0_12vec_iteratorIPS6_Lb1EEEOS6_ - (i32.add - (get_local $13) - (i32.const 24) - ) - (get_local $7) - (get_local $11) - (get_local $13) - ) - (set_local $11 - (i32.load offset=24 - (get_local $13) - ) - ) - ) - (i64.store offset=16 - (get_local $11) - (tee_local $12 - (i64.add - (i64.load offset=16 - (get_local $11) - ) - (get_local $4) - ) - ) - ) - (call $eosio_assert - (i32.xor - (i32.wrap/i64 - (i64.shr_u - (get_local $12) - (i64.const 63) - ) - ) - (i32.const 1) - ) - (i32.const 512) - ) - (call $eosio_assert - (i64.eq - (get_local $3) - (i64.load - (get_local $1) - ) - ) - (i32.const 544) - ) - (set_local $12 - (i64.extend_u/i32 - (tee_local $10 - (i32.load - (i32.add - (get_local $1) - (i32.const 12) - ) - ) - ) - ) - ) - (set_local $2 - (i32.const 8) - ) - (loop $label$4 - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (br_if $label$4 - (i64.ne - (tee_local $12 - (i64.shr_u - (get_local $12) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (get_local $10) - ) - ) - (set_local $2 - (i32.add - (i32.sub - (tee_local $10 - (i32.mul - (get_local $10) - (i32.const 24) - ) - ) - (i32.rem_u - (i32.add - (get_local $10) - (i32.const -24) - ) - (i32.const 24) - ) - ) - (get_local $2) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.lt_u - (get_local $2) - (i32.const 513) - ) - ) - (set_local $10 - (call $malloc - (get_local $2) - ) - ) - (br $label$6) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (get_local $14) - (i32.and - (i32.add - (get_local $2) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (i32.store - (get_local $13) - (get_local $10) - ) - (i32.store offset=8 - (get_local $13) - (i32.add - (get_local $10) - (get_local $2) - ) - ) - (call $eosio_assert - (i32.gt_s - (get_local $2) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (get_local $10) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $13) - (i32.add - (get_local $10) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEENS_15extended_symbolExEERT_S6_RKN5boost9container8flat_mapIT0_T1_NSt3__14lessISA_EENS8_13new_allocatorINSC_4pairISA_SB_EEEEEE - (get_local $13) - (get_local $7) - ) - ) - (call $db_update_i64 - (i32.load offset=24 - (get_local $1) - ) - (i64.const 0) - (get_local $10) - (get_local $2) - ) - (block $label$8 - (br_if $label$8 - (i32.lt_u - (get_local $2) - (i32.const 513) - ) - ) - (call $free - (get_local $10) - ) - ) - (block $label$9 - (br_if $label$9 - (i64.lt_u - (get_local $3) - (i64.load offset=16 - (get_local $0) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (select - (i64.const -2) - (i64.add - (get_local $3) - (i64.const 1) - ) - (i64.gt_u - (get_local $3) - (i64.const -3) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $13) - (i32.const 32) - ) - ) - ) - (func $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueENS0_12vec_iteratorIPS6_Lb1EEEOS6_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i64) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $13 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.eq - (tee_local $6 - (i32.add - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - (i32.mul - (tee_local $5 - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.const 24) - ) - ) - ) - (get_local $2) - ) - ) - (br_if $label$7 - (i64.ge_u - (tee_local $7 - (i64.load - (get_local $3) - ) - ) - (i64.load - (get_local $2) - ) - ) - ) - ) - (br_if $label$4 - (i32.eq - (get_local $4) - (get_local $2) - ) - ) - (br_if $label$4 - (i64.lt_u - (tee_local $8 - (i64.load - (tee_local $12 - (i32.add - (get_local $2) - (i32.const -24) - ) - ) - ) - ) - (tee_local $7 - (i64.load - (get_local $3) - ) - ) - ) - ) - (br_if $label$3 - (i64.ge_u - (get_local $7) - (get_local $8) - ) - ) - (set_local $2 - (get_local $4) - ) - (br_if $label$6 - (tee_local $11 - (i32.div_s - (i32.sub - (get_local $12) - (get_local $4) - ) - (i32.const 24) - ) - ) - ) - (br $label$5) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (tee_local $11 - (i32.div_s - (i32.sub - (get_local $6) - (get_local $2) - ) - (i32.const 24) - ) - ) - ) - ) - (loop $label$10 - (block $label$11 - (br_if $label$11 - (i64.ge_u - (i64.load - (tee_local $9 - (i32.add - (get_local $2) - (i32.mul - (tee_local $10 - (i32.shr_u - (get_local $11) - (i32.const 1) - ) - ) - (i32.const 24) - ) - ) - ) - ) - (get_local $7) - ) - ) - (set_local $2 - (i32.add - (get_local $9) - (i32.const 24) - ) - ) - (set_local $10 - (i32.sub - (i32.add - (get_local $11) - (i32.const -1) - ) - (get_local $10) - ) - ) - ) - (br_if $label$10 - (tee_local $11 - (get_local $10) - ) - ) - ) - ) - (br_if $label$4 - (i32.eq - (get_local $2) - (get_local $6) - ) - ) - (set_local $12 - (get_local $2) - ) - (br_if $label$4 - (i64.lt_u - (get_local $7) - (i64.load - (get_local $2) - ) - ) - ) - (br $label$3) - ) - (loop $label$12 - (block $label$13 - (br_if $label$13 - (i64.ge_u - (i64.load - (tee_local $9 - (i32.add - (get_local $2) - (i32.mul - (tee_local $10 - (i32.shr_u - (get_local $11) - (i32.const 1) - ) - ) - (i32.const 24) - ) - ) - ) - ) - (get_local $7) - ) - ) - (set_local $2 - (i32.add - (get_local $9) - (i32.const 24) - ) - ) - (set_local $10 - (i32.sub - (i32.add - (get_local $11) - (i32.const -1) - ) - (get_local $10) - ) - ) - ) - (br_if $label$12 - (tee_local $11 - (get_local $10) - ) - ) - ) - ) - (br_if $label$4 - (i32.eq - (get_local $2) - (get_local $12) - ) - ) - (set_local $12 - (get_local $2) - ) - (br_if $label$3 - (i64.ge_u - (get_local $7) - (i64.load - (get_local $2) - ) - ) - ) - ) - (i32.store offset=8 - (get_local $13) - (get_local $2) - ) - (block $label$14 - (br_if $label$14 - (i32.ne - (i32.load offset=8 - (get_local $1) - ) - (get_local $5) - ) - ) - (call $_ZN5boost9container6vectorINS0_3dtl4pairIN5eosio15extended_symbolExEENS0_13new_allocatorIS6_EEvE37priv_forward_range_insert_no_capacityINS2_17insert_move_proxyIS8_PS6_EEEENS0_12vec_iteratorISC_Lb0EEERKSC_jT_NS_11move_detail17integral_constantIjLj1EEE - (get_local $0) - (get_local $1) - (i32.add - (get_local $13) - (i32.const 8) - ) - (i32.const 1) - (get_local $3) - ) - (br $label$0) - ) - (set_local $9 - (i32.div_s - (i32.sub - (get_local $2) - (get_local $4) - ) - (i32.const 24) - ) - ) - (br_if $label$2 - (i32.eq - (get_local $6) - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $6) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - ) - (i64.store - (get_local $6) - (i64.load - (tee_local $11 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - ) - (i64.store offset=16 - (i32.add - (get_local $4) - (i32.mul - (get_local $5) - (i32.const 24) - ) - ) - (i64.load - (i32.add - (get_local $6) - (i32.const -8) - ) - ) - ) - (i32.store - (tee_local $10 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (get_local $10) - ) - (i32.const 1) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eq - (get_local $11) - (get_local $2) - ) - ) - (loop $label$16 - (i64.store - (i32.add - (get_local $11) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $11) - (i32.const -16) - ) - ) - ) - (i64.store - (get_local $11) - (i64.load - (tee_local $10 - (i32.add - (get_local $11) - (i32.const -24) - ) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $11) - (i32.const -8) - ) - ) - ) - (set_local $11 - (get_local $10) - ) - (br_if $label$16 - (i32.ne - (get_local $2) - (get_local $10) - ) - ) - ) - ) - (i64.store - (get_local $2) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - (i64.store offset=16 - (get_local $2) - (i64.load offset=16 - (get_local $3) - ) - ) - (br $label$1) - ) - (i32.store - (get_local $0) - (i32.add - (get_local $4) - (i32.mul - (i32.div_s - (i32.sub - (get_local $12) - (get_local $4) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - (br $label$0) - ) - (i64.store - (get_local $2) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - (i64.store offset=16 - (i32.add - (get_local $4) - (i32.mul - (get_local $5) - (i32.const 24) - ) - ) - (i64.load offset=16 - (get_local $3) - ) - ) - (i32.store - (tee_local $11 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (i32.store - (get_local $0) - (i32.add - (i32.load - (get_local $1) - ) - (i32.mul - (get_local $9) - (i32.const 24) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $13) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEENS_15extended_symbolExEERT_S6_RKN5boost9container8flat_mapIT0_T1_NSt3__14lessISA_EENS8_13new_allocatorINSC_4pairISA_SB_EEEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $5 - (i64.load32_u offset=4 - (get_local $1) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $7 - (i32.wrap/i64 - (get_local $5) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $2 - (i64.ne - (tee_local $5 - (i64.shr_u - (get_local $5) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $7) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $3) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $2) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $4 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (set_local $3 - (i32.add - (tee_local $7 - (i32.load - (get_local $1) - ) - ) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$2 - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $6) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (get_local $7) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $6) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $6) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - ) - (br_if $label$2 - (i32.ne - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 24) - ) - ) - (get_local $3) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5boost9container6vectorINS0_3dtl4pairIN5eosio15extended_symbolExEENS0_13new_allocatorIS6_EEvE37priv_forward_range_insert_no_capacityINS2_17insert_move_proxyIS8_PS6_EEEENS0_12vec_iteratorISC_Lb0EEERKSC_jT_NS_11move_detail17integral_constantIjLj1EEE (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (set_local $6 - (i32.div_s - (i32.sub - (tee_local $5 - (i32.load - (get_local $2) - ) - ) - (i32.load - (get_local $1) - ) - ) - (i32.const 24) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.lt_u - (i32.sub - (i32.const 178956970) - (tee_local $2 - (i32.load offset=8 - (get_local $1) - ) - ) - ) - (i32.add - (i32.sub - (get_local $3) - (get_local $2) - ) - (tee_local $10 - (i32.load offset=4 - (get_local $1) - ) - ) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.gt_u - (get_local $2) - (i32.const 536870911) - ) - ) - (set_local $2 - (i32.div_u - (i32.shl - (get_local $2) - (i32.const 3) - ) - (i32.const 5) - ) - ) - (br $label$1) - ) - (set_local $2 - (select - (i32.const -1) - (i32.shl - (get_local $2) - (i32.const 3) - ) - (i32.gt_u - (get_local $2) - (i32.const -1610612737) - ) - ) - ) - ) - (br_if $label$0 - (i32.ge_u - (tee_local $7 - (select - (tee_local $10 - (i32.add - (get_local $10) - (get_local $3) - ) - ) - (tee_local $2 - (select - (get_local $2) - (i32.const 178956970) - (i32.lt_u - (get_local $2) - (i32.const 178956970) - ) - ) - ) - (i32.gt_u - (get_local $10) - (get_local $2) - ) - ) - ) - (i32.const 178956971) - ) - ) - (set_local $2 - (tee_local $9 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eq - (tee_local $8 - (i32.load - (get_local $1) - ) - ) - (get_local $5) - ) - ) - (set_local $2 - (get_local $9) - ) - (br_if $label$3 - (i32.eqz - (get_local $8) - ) - ) - (set_local $10 - (get_local $8) - ) - (set_local $2 - (get_local $9) - ) - (loop $label$4 - (i64.store - (get_local $2) - (i64.load - (get_local $10) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const 8) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const 16) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 24) - ) - ) - (br_if $label$4 - (i32.ne - (tee_local $10 - (i32.add - (get_local $10) - (i32.const 24) - ) - ) - (get_local $5) - ) - ) - ) - ) - (i64.store - (get_local $2) - (i64.load - (get_local $4) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - ) - (i64.store offset=16 - (get_local $2) - (i64.load offset=16 - (get_local $4) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.mul - (get_local $3) - (i32.const 24) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (get_local $8) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.eq - (tee_local $10 - (i32.add - (get_local $8) - (i32.mul - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (i32.const 24) - ) - ) - ) - (get_local $5) - ) - ) - (loop $label$7 - (i64.store - (get_local $2) - (i64.load - (get_local $5) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 24) - ) - ) - (br_if $label$7 - (i32.ne - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 24) - ) - ) - (get_local $10) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load - (get_local $1) - ) - ) - ) - (i32.store - (get_local $1) - (get_local $9) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 8) - ) - (get_local $7) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.div_s - (i32.sub - (get_local $2) - (get_local $9) - ) - (i32.const 24) - ) - ) - (i32.store - (get_local $0) - (i32.add - (get_local $9) - (i32.mul - (get_local $6) - (i32.const 24) - ) - ) - ) - (return) - ) - (call $abort) - (unreachable) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEENS_15extended_symbolExEERT_S7_RN5boost9container8flat_mapIT0_T1_NSt3__14lessISB_EENS9_13new_allocatorINSD_4pairISB_SC_EEEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=4 - (get_local $1) - (i32.const 0) - ) - (set_local $8 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $5 - (i64.const 0) - ) - (set_local $7 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $8) - (i32.load - (get_local $7) - ) - ) - (i32.const 704) - ) - (set_local $3 - (i32.load8_u - (tee_local $8 - (i32.load - (get_local $2) - ) - ) - ) - ) - (i32.store - (get_local $2) - (tee_local $8 - (i32.add - (get_local $8) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $3) - (i32.const 127) - ) - (tee_local $6 - (i32.and - (get_local $6) - (i32.const 255) - ) - ) - ) - ) - (get_local $5) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $3) - (i32.const 7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $3 - (i32.wrap/i64 - (get_local $5) - ) - ) - ) - ) - (set_local $7 - (i32.add - (get_local $3) - (i32.const -1) - ) - ) - (set_local $6 - (i32.add - (i32.add - (get_local $9) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (set_local $4 - (i32.add - (get_local $9) - (i32.const 56) - ) - ) - (loop $label$2 - (i64.store - (get_local $6) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $9) - (i64.const 0) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $8) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $9) - (i32.const 16) - ) - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $3) - (tee_local $8 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $8) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $6) - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $3) - (tee_local $8 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $8) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $9) - (i32.const 8) - ) - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $3) - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 40) - ) - (i32.const 8) - ) - (i64.load - (get_local $6) - ) - ) - (i64.store offset=40 - (get_local $9) - (i64.load offset=16 - (get_local $9) - ) - ) - (i64.store - (get_local $4) - (i64.load offset=8 - (get_local $9) - ) - ) - (call $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueEOS6_ - (i32.add - (get_local $9) - (i32.const 32) - ) - (get_local $1) - (i32.add - (get_local $9) - (i32.const 40) - ) - ) - (br_if $label$1 - (i32.eqz - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const -1) - ) - ) - (set_local $8 - (i32.load - (get_local $3) - ) - ) - (br $label$2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 64) - ) - ) - (get_local $0) - ) - (func $_ZN5boost9container3dtl9flat_treeINS1_4pairIN5eosio15extended_symbolExEENS1_9select1stIS5_EENSt3__14lessIS5_EENS0_13new_allocatorIS6_EEE13insert_uniqueEOS6_ (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i64) - (local $10 i32) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store8 offset=4 - (get_local $0) - (i32.const 0) - ) - (i32.store - (get_local $0) - (i32.const 0) - ) - (set_local $5 - (i64.load - (get_local $2) - ) - ) - (set_local $6 - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $7 - (i32.div_s - (i32.mul - (tee_local $4 - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.const 24) - ) - (i32.const 24) - ) - ) - ) - ) - (loop $label$1 - (block $label$2 - (br_if $label$2 - (i64.ge_u - (i64.load - (tee_local $8 - (i32.add - (get_local $6) - (i32.mul - (tee_local $10 - (i32.shr_u - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 24) - ) - ) - ) - ) - (get_local $5) - ) - ) - (set_local $6 - (i32.add - (get_local $8) - (i32.const 24) - ) - ) - (set_local $10 - (i32.sub - (i32.add - (get_local $7) - (i32.const -1) - ) - (get_local $10) - ) - ) - ) - (br_if $label$1 - (tee_local $7 - (get_local $10) - ) - ) - ) - ) - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.eqz - (tee_local $7 - (i32.ne - (get_local $6) - (tee_local $10 - (i32.add - (get_local $3) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - ) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $0) - (i32.const 4) - ) - (i64.lt_u - (get_local $5) - (tee_local $9 - (i64.load - (get_local $6) - ) - ) - ) - ) - (br_if $label$5 - (i64.lt_u - (get_local $5) - (get_local $9) - ) - ) - (br $label$4) - ) - (i32.store8 - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.const 1) - ) - ) - (i32.store offset=8 - (get_local $11) - (get_local $6) - ) - (block $label$7 - (br_if $label$7 - (i32.ne - (i32.load offset=8 - (get_local $1) - ) - (get_local $4) - ) - ) - (call $_ZN5boost9container6vectorINS0_3dtl4pairIN5eosio15extended_symbolExEENS0_13new_allocatorIS6_EEvE37priv_forward_range_insert_no_capacityINS2_17insert_move_proxyIS8_PS6_EEEENS0_12vec_iteratorISC_Lb0EEERKSC_jT_NS_11move_detail17integral_constantIjLj1EEE - (get_local $11) - (get_local $1) - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.const 1) - (get_local $2) - ) - (set_local $6 - (i32.load - (get_local $11) - ) - ) - (br $label$3) - ) - (set_local $8 - (i32.div_s - (i32.sub - (get_local $6) - (get_local $3) - ) - (i32.const 24) - ) - ) - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $7) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const -16) - ) - ) - ) - (i64.store - (get_local $10) - (i64.load - (tee_local $7 - (i32.add - (get_local $10) - (i32.const -24) - ) - ) - ) - ) - (i64.store offset=16 - (i32.add - (get_local $3) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const -8) - ) - ) - ) - (i32.store - (tee_local $10 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (get_local $10) - ) - (i32.const 1) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eq - (get_local $7) - (get_local $6) - ) - ) - (loop $label$11 - (i64.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -16) - ) - ) - ) - (i64.store - (get_local $7) - (i64.load - (tee_local $10 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i64.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -8) - ) - ) - ) - (set_local $7 - (get_local $10) - ) - (br_if $label$11 - (i32.ne - (get_local $6) - (get_local $10) - ) - ) - ) - ) - (i64.store - (get_local $6) - (i64.load - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $6) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i64.store offset=16 - (get_local $6) - (i64.load offset=16 - (get_local $2) - ) - ) - (br $label$8) - ) - (i64.store - (get_local $6) - (i64.load - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $6) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i64.store offset=16 - (i32.add - (get_local $3) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - (i64.load offset=16 - (get_local $2) - ) - ) - (i32.store - (tee_local $7 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (get_local $7) - ) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i32.add - (i32.load - (get_local $1) - ) - (i32.mul - (get_local $8) - (i32.const 24) - ) - ) - ) - ) - (i32.store - (get_local $11) - (get_local $6) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 16) - ) - ) - ) - (func $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_new_allocationINS2_17insert_move_proxyISA_PS8_EEEEvSE_jSE_jT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (set_local $11 - (get_local $1) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $10 - (i32.load - (get_local $0) - ) - ) - (get_local $3) - ) - ) - (set_local $11 - (get_local $1) - ) - (br_if $label$0 - (i32.eqz - (get_local $10) - ) - ) - (set_local $6 - (get_local $10) - ) - (set_local $11 - (get_local $1) - ) - (loop $label$1 - (i64.store - (get_local $11) - (i64.load - (get_local $6) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $6) - (i32.const 24) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $6) - (i32.const 8) - ) - ) - ) - (i32.store - (tee_local $12 - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $9 - (i32.add - (get_local $11) - (i32.const 36) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $7 - (i32.add - (get_local $11) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $12) - (i32.load - (tee_local $8 - (i32.add - (get_local $6) - (i32.const 32) - ) - ) - ) - ) - (i32.store - (get_local $9) - (i32.load - (i32.add - (get_local $6) - (i32.const 36) - ) - ) - ) - (i32.store - (get_local $7) - (i32.load - (tee_local $12 - (i32.add - (get_local $6) - (i32.const 40) - ) - ) - ) - ) - (i32.store - (get_local $12) - (i32.const 0) - ) - (i64.store align=4 - (get_local $8) - (i64.const 0) - ) - (set_local $11 - (i32.add - (get_local $11) - (i32.const 48) - ) - ) - (br_if $label$1 - (i32.ne - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 48) - ) - ) - (get_local $3) - ) - ) - ) - ) - (i64.store - (get_local $11) - (i64.load - (get_local $5) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 24) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $11) - (i64.load offset=8 - (get_local $5) - ) - ) - (i32.store - (tee_local $6 - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $12 - (i32.add - (get_local $11) - (i32.const 36) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $9 - (i32.add - (get_local $11) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $6) - (i32.load - (tee_local $7 - (i32.add - (get_local $5) - (i32.const 32) - ) - ) - ) - ) - (i32.store - (get_local $12) - (i32.load - (i32.add - (get_local $5) - (i32.const 36) - ) - ) - ) - (i32.store - (get_local $9) - (i32.load - (tee_local $6 - (i32.add - (get_local $5) - (i32.const 40) - ) - ) - ) - ) - (i32.store - (get_local $6) - (i32.const 0) - ) - (i64.store align=4 - (get_local $7) - (i64.const 0) - ) - (set_local $12 - (i32.add - (get_local $11) - (i32.mul - (get_local $4) - (i32.const 48) - ) - ) - ) - (block $label$2 - (br_if $label$2 - (i32.eqz - (get_local $10) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eq - (tee_local $8 - (i32.add - (get_local $10) - (i32.mul - (tee_local $9 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.const 48) - ) - ) - ) - (get_local $3) - ) - ) - (loop $label$4 - (i64.store - (get_local $12) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 24) - ) - ) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - (i32.store - (tee_local $11 - (i32.add - (get_local $12) - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $6 - (i32.add - (get_local $12) - (i32.const 36) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $9 - (i32.add - (get_local $12) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $11) - (i32.load - (tee_local $7 - (i32.add - (get_local $3) - (i32.const 32) - ) - ) - ) - ) - (i32.store - (get_local $6) - (i32.load - (i32.add - (get_local $3) - (i32.const 36) - ) - ) - ) - (i32.store - (get_local $9) - (i32.load - (tee_local $11 - (i32.add - (get_local $3) - (i32.const 40) - ) - ) - ) - ) - (i32.store - (get_local $11) - (i32.const 0) - ) - (i64.store align=4 - (get_local $7) - (i64.const 0) - ) - (set_local $12 - (i32.add - (get_local $12) - (i32.const 48) - ) - ) - (br_if $label$4 - (i32.ne - (tee_local $3 - (i32.add - (get_local $3) - (i32.const 48) - ) - ) - (get_local $8) - ) - ) - ) - (set_local $9 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (get_local $9) - ) - ) - (loop $label$6 - (set_local $9 - (i32.add - (get_local $9) - (i32.const -1) - ) - ) - (block $label$7 - (br_if $label$7 - (i32.eqz - (tee_local $3 - (i32.load - (tee_local $7 - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - ) - ) - ) - ) - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.eq - (tee_local $11 - (i32.load - (tee_local $8 - (i32.add - (get_local $10) - (i32.const 36) - ) - ) - ) - ) - (get_local $3) - ) - ) - (loop $label$10 - (set_local $6 - (i32.load - (tee_local $11 - (i32.add - (get_local $11) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $11) - (i32.const 0) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $6) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (i32.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $6) - ) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - (br_if $label$10 - (i32.ne - (get_local $3) - (get_local $11) - ) - ) - ) - (set_local $11 - (i32.load - (get_local $7) - ) - ) - (br $label$8) - ) - (set_local $11 - (get_local $3) - ) - ) - (i32.store - (get_local $8) - (get_local $3) - ) - (call $_ZdlPv - (get_local $11) - ) - ) - (set_local $10 - (i32.add - (get_local $10) - (i32.const 48) - ) - ) - (br_if $label$6 - (get_local $9) - ) - ) - ) - (call $_ZdlPv - (i32.load - (get_local $0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store offset=8 - (get_local $0) - (get_local $2) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.div_s - (i32.sub - (get_local $12) - (get_local $1) - ) - (i32.const 48) - ) - ) - ) - (func $_ZN5boost9container6vectorINS0_3dtl4pairIyN5eosio11multi_indexILy6290548272952901632ENS4_9exaccountEJEEEEENS0_13new_allocatorIS8_EEvE40priv_forward_range_insert_expand_forwardINS2_17insert_move_proxyISA_PS8_EEEEvSE_jT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i32) - (local $14 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $2) - ) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $13 - (i32.sub - (tee_local $11 - (i32.add - (tee_local $4 - (i32.load - (get_local $0) - ) - ) - (i32.mul - (tee_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 48) - ) - ) - ) - (get_local $1) - ) - ) - ) - ) - (br_if $label$9 - (i32.ge_u - (i32.div_s - (get_local $13) - (i32.const 48) - ) - (get_local $2) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eq - (get_local $11) - (get_local $1) - ) - ) - (set_local $9 - (i32.sub - (i32.sub - (i32.const 0) - (get_local $4) - ) - (i32.mul - (get_local $6) - (i32.const 48) - ) - ) - ) - (set_local $10 - (i32.mul - (get_local $2) - (i32.const 48) - ) - ) - (set_local $13 - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (loop $label$12 - (i64.store - (i32.add - (tee_local $8 - (i32.add - (get_local $13) - (get_local $10) - ) - ) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $13) - (i32.const -40) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -28) - ) - (i32.load - (i32.add - (get_local $13) - (i32.const -28) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -32) - ) - (i32.load - (i32.add - (get_local $13) - (i32.const -32) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -16) - ) - (i64.load - (i32.add - (get_local $13) - (i32.const -16) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -24) - ) - (i64.load - (i32.add - (get_local $13) - (i32.const -24) - ) - ) - ) - (i32.store - (tee_local $7 - (i32.add - (get_local $8) - (i32.const -8) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $12 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $7) - (i32.load - (tee_local $14 - (i32.add - (get_local $13) - (i32.const -8) - ) - ) - ) - ) - (i32.store - (get_local $12) - (i32.load - (tee_local $7 - (i32.add - (get_local $13) - (i32.const -4) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.load - (get_local $13) - ) - ) - (i32.store - (get_local $14) - (i32.const 0) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (i32.store - (get_local $13) - (i32.const 0) - ) - (br_if $label$12 - (i32.ne - (i32.add - (tee_local $13 - (i32.add - (get_local $13) - (i32.const 48) - ) - ) - (get_local $9) - ) - (i32.const 40) - ) - ) - ) - ) - (i64.store - (get_local $1) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (get_local $1) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 24) - ) - ) - ) - (i64.store - (i32.add - (get_local $1) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $1) - (i64.load offset=8 - (get_local $3) - ) - ) - (set_local $12 - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - (br_if $label$8 - (i32.eqz - (tee_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - ) - ) - (br_if $label$6 - (i32.eq - (tee_local $13 - (i32.load - (tee_local $9 - (i32.add - (get_local $1) - (i32.const 36) - ) - ) - ) - ) - (get_local $7) - ) - ) - (loop $label$13 - (set_local $8 - (i32.load - (tee_local $13 - (i32.add - (get_local $13) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $13) - (i32.const 0) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (get_local $8) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (i32.load - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $8) - ) - ) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$13 - (i32.ne - (get_local $7) - (get_local $13) - ) - ) - ) - (set_local $13 - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - (br $label$5) - ) - (i64.store - (get_local $11) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 24) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $11) - (i64.load offset=8 - (get_local $3) - ) - ) - (i32.store - (tee_local $13 - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $8 - (i32.add - (get_local $11) - (i32.const 36) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $7 - (i32.add - (get_local $11) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $13) - (i32.load - (tee_local $11 - (i32.add - (get_local $3) - (i32.const 32) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.load - (i32.add - (get_local $3) - (i32.const 36) - ) - ) - ) - (i32.store - (get_local $7) - (i32.load - (tee_local $13 - (i32.add - (get_local $3) - (i32.const 40) - ) - ) - ) - ) - (i32.store - (get_local $13) - (i32.const 0) - ) - (i64.store align=4 - (get_local $11) - (i64.const 0) - ) - (i32.store - (tee_local $13 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (get_local $13) - ) - (get_local $2) - ) - ) - (return) - ) - (set_local $6 - (i32.add - (i32.add - (get_local $4) - (tee_local $13 - (i32.mul - (i32.sub - (i32.const 0) - (get_local $2) - ) - (i32.const 48) - ) - ) - ) - (tee_local $8 - (i32.mul - (get_local $6) - (i32.const 48) - ) - ) - ) - ) - (set_local $5 - (i32.mul - (get_local $2) - (i32.const 48) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (get_local $8) - ) - ) - (set_local $12 - (i32.add - (get_local $11) - (get_local $13) - ) - ) - (set_local $7 - (i32.const 0) - ) - (loop $label$16 - (i64.store - (tee_local $13 - (i32.add - (get_local $4) - (get_local $7) - ) - ) - (i64.load - (tee_local $8 - (i32.add - (get_local $6) - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $13) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $8) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $13) - (i32.const 8) - ) - (i32.load - (i32.add - (get_local $8) - (i32.const 8) - ) - ) - ) - (i64.store - (i32.add - (get_local $13) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $8) - (i32.const 24) - ) - ) - ) - (i64.store - (i32.add - (get_local $13) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - (i32.store - (tee_local $14 - (i32.add - (get_local $13) - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $9 - (i32.add - (get_local $13) - (i32.const 36) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $13 - (i32.add - (get_local $13) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $14) - (i32.load - (tee_local $10 - (i32.add - (get_local $8) - (i32.const 32) - ) - ) - ) - ) - (i32.store - (get_local $9) - (i32.load - (tee_local $14 - (i32.add - (get_local $8) - (i32.const 36) - ) - ) - ) - ) - (i32.store - (get_local $13) - (i32.load - (tee_local $8 - (i32.add - (get_local $8) - (i32.const 40) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $10) - (i32.const 0) - ) - (i32.store - (get_local $14) - (i32.const 0) - ) - (br_if $label$16 - (i32.ne - (get_local $5) - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 48) - ) - ) - ) - ) - ) - (i32.store - (tee_local $13 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (get_local $13) - ) - (get_local $2) - ) - ) - (block $label$17 - (br_if $label$17 - (i32.eq - (get_local $12) - (get_local $1) - ) - ) - (loop $label$18 - (i64.store - (tee_local $5 - (i32.add - (get_local $11) - (i32.const -48) - ) - ) - (i64.load - (tee_local $10 - (i32.add - (get_local $12) - (i32.const -48) - ) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const -24) - ) - (i64.load - (i32.add - (get_local $12) - (i32.const -24) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const -32) - ) - (i64.load - (i32.add - (get_local $12) - (i32.const -32) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $12) - (i32.const -40) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $12) - (i32.const -16) - ) - ) - (block $label$19 - (block $label$20 - (block $label$21 - (block $label$22 - (br_if $label$22 - (i32.eqz - (tee_local $7 - (i32.load - (tee_local $9 - (i32.add - (get_local $11) - (i32.const -16) - ) - ) - ) - ) - ) - ) - (br_if $label$21 - (i32.eq - (tee_local $13 - (i32.load - (tee_local $14 - (i32.add - (get_local $11) - (i32.const -12) - ) - ) - ) - ) - (get_local $7) - ) - ) - (loop $label$23 - (set_local $8 - (i32.load - (tee_local $13 - (i32.add - (get_local $13) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $13) - (i32.const 0) - ) - (block $label$24 - (br_if $label$24 - (i32.eqz - (get_local $8) - ) - ) - (block $label$25 - (br_if $label$25 - (i32.eqz - (i32.load - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $8) - ) - ) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$23 - (i32.ne - (get_local $7) - (get_local $13) - ) - ) - ) - (set_local $13 - (i32.load - (get_local $9) - ) - ) - (br $label$20) - ) - (set_local $8 - (i32.add - (get_local $11) - (i32.const -8) - ) - ) - (set_local $14 - (i32.add - (get_local $11) - (i32.const -12) - ) - ) - (br $label$19) - ) - (set_local $13 - (get_local $7) - ) - ) - (i32.store - (get_local $14) - (get_local $7) - ) - (call $_ZdlPv - (get_local $13) - ) - (i32.store - (get_local $14) - (i32.const 0) - ) - (i32.store - (tee_local $8 - (i32.add - (get_local $11) - (i32.const -8) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $9) - (i32.const 0) - ) - ) - (i32.store - (get_local $9) - (i32.load - (get_local $6) - ) - ) - (i32.store - (get_local $14) - (i32.load - (tee_local $13 - (i32.add - (get_local $12) - (i32.const -12) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.load - (i32.add - (get_local $12) - (i32.const -8) - ) - ) - ) - (i32.store - (get_local $6) - (i32.const 0) - ) - (i64.store align=4 - (get_local $13) - (i64.const 0) - ) - (set_local $11 - (get_local $5) - ) - (set_local $12 - (get_local $10) - ) - (br_if $label$18 - (i32.ne - (get_local $10) - (get_local $1) - ) - ) - ) - ) - (i64.store - (get_local $1) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (get_local $1) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 24) - ) - ) - ) - (i64.store - (i32.add - (get_local $1) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $1) - (i64.load offset=8 - (get_local $3) - ) - ) - (br_if $label$7 - (i32.eqz - (tee_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - ) - ) - (br_if $label$3 - (i32.eq - (tee_local $13 - (i32.load - (tee_local $11 - (i32.add - (get_local $1) - (i32.const 36) - ) - ) - ) - ) - (get_local $7) - ) - ) - (loop $label$26 - (set_local $8 - (i32.load - (tee_local $13 - (i32.add - (get_local $13) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $13) - (i32.const 0) - ) - (block $label$27 - (br_if $label$27 - (i32.eqz - (get_local $8) - ) - ) - (block $label$28 - (br_if $label$28 - (i32.eqz - (i32.load - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=8 - (get_local $8) - ) - ) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$26 - (i32.ne - (get_local $7) - (get_local $13) - ) - ) - ) - (set_local $13 - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - (br $label$2) - ) - (set_local $13 - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (set_local $9 - (i32.add - (get_local $1) - (i32.const 36) - ) - ) - (br $label$4) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (set_local $11 - (i32.add - (get_local $1) - (i32.const 36) - ) - ) - (br $label$1) - ) - (set_local $13 - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 36) - ) - (get_local $7) - ) - (call $_ZdlPv - (get_local $13) - ) - (i32.store - (tee_local $13 - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $1) - (i32.const 32) - ) - (i64.const 0) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.load - (tee_local $8 - (i32.add - (get_local $3) - (i32.const 32) - ) - ) - ) - ) - (i32.store - (get_local $9) - (i32.load - (tee_local $14 - (i32.add - (get_local $3) - (i32.const 36) - ) - ) - ) - ) - (i32.store - (get_local $13) - (i32.load - (tee_local $7 - (i32.add - (get_local $3) - (i32.const 40) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (i64.store align=4 - (get_local $8) - (i64.const 0) - ) - (i64.store - (get_local $11) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (tee_local $13 - (i32.add - (get_local $4) - (i32.mul - (get_local $6) - (i32.const 48) - ) - ) - ) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $12) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $13) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $12) - (i32.const 8) - ) - ) - ) - (i64.store offset=8 - (get_local $13) - (i64.load - (get_local $12) - ) - ) - (i32.store - (tee_local $11 - (i32.add - (get_local $13) - (i32.const 32) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $12 - (i32.add - (get_local $13) - (i32.const 36) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $13 - (i32.add - (get_local $13) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $11) - (i32.load - (get_local $8) - ) - ) - (i32.store - (get_local $12) - (i32.load - (get_local $14) - ) - ) - (i32.store - (get_local $13) - (i32.load - (get_local $7) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (i64.store align=4 - (get_local $8) - (i64.const 0) - ) - (i32.store - (tee_local $13 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (i32.add - (i32.load - (get_local $13) - ) - (get_local $2) - ) - ) - (return) - ) - (set_local $13 - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 36) - ) - (get_local $7) - ) - (call $_ZdlPv - (get_local $13) - ) - (i32.store - (tee_local $7 - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $1) - (i32.const 32) - ) - (i64.const 0) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.load - (tee_local $13 - (i32.add - (get_local $3) - (i32.const 32) - ) - ) - ) - ) - (i32.store - (get_local $11) - (i32.load - (i32.add - (get_local $3) - (i32.const 36) - ) - ) - ) - (i32.store - (get_local $7) - (i32.load - (tee_local $8 - (i32.add - (get_local $3) - (i32.const 40) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i64.store align=4 - (get_local $13) - (i64.const 0) - ) - ) - ) - (func $_ZN5eosio12market_stateC2EyNS_11symbol_typeERNS_17exchange_accountsE (param $0 i32) (param $1 i64) (param $2 i64) (param $3 i32) (result i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (i64.store - (get_local $0) - (i64.shr_u - (get_local $2) - (i64.const 8) - ) - ) - (set_local $4 - (call $_ZN5eosio14exchange_stateC2Ev - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (i64.store offset=240 - (get_local $0) - (get_local $1) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 256) - ) - (i64.const -1) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 264) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 272) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 248) - ) - (tee_local $2 - (i64.load - (get_local $0) - ) - ) - ) - (i64.store offset=280 - (get_local $0) - (get_local $1) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 288) - ) - (tee_local $6 - (i64.or - (tee_local $5 - (i64.shl - (get_local $2) - (i64.const 4) - ) - ) - (i64.const 1) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 296) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 304) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 308) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 312) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $0) - (i32.const 316) - ) - (i32.const 0) - ) - (i64.store offset=320 - (get_local $0) - (get_local $1) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 328) - ) - (tee_local $5 - (i64.or - (get_local $5) - (i64.const 2) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 336) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 344) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 348) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 352) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $0) - (i32.const 356) - ) - (i32.const 0) - ) - (i64.store offset=360 - (get_local $0) - (get_local $1) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 368) - ) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 376) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 384) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 388) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 392) - ) - (i32.const 0) - ) - (i64.store offset=400 - (get_local $0) - (get_local $1) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 408) - ) - (get_local $5) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 416) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 424) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 428) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 432) - ) - (i32.const 0) - ) - (i32.store offset=440 - (get_local $0) - (get_local $3) - ) - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy - (i32.add - (get_local $0) - (i32.const 444) - ) - (i32.add - (get_local $0) - (i32.const 240) - ) - (get_local $2) - ) - (call $eosio_assert - (i32.ne - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 448) - ) - ) - ) - (i32.const 0) - ) - (i32.const 720) - ) - (drop - (call $memcpy - (get_local $4) - (i32.load - (get_local $3) - ) - (i32.const 232) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio14exchange_stateC2Ev (param $0 i32) (result i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store offset=40 - (get_local $0) - (i64.const 0) - ) - (i32.store offset=32 - (get_local $0) - (i32.const 0) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 48) - ) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$5 - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 64) - ) - (i32.const 500) - ) - (drop - (call $_ZN5eosio12margin_stateC2Ev - (i32.add - (get_local $0) - (i32.const 72) - ) - ) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 144) - ) - ) - (i64.const 1398362884) - ) - (i64.store offset=136 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$10 - (block $label$11 - (loop $label$12 - (br_if $label$11 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$13 - (br_if $label$13 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$14 - (br_if $label$11 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$14 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$12 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$10) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 160) - ) - (i32.const 500) - ) - (drop - (call $_ZN5eosio12margin_stateC2Ev - (i32.add - (get_local $0) - (i32.const 168) - ) - ) - ) - (get_local $0) - ) - (func $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy (param $0 i32) (param $1 i32) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - ) - (tee_local $3 - (i32.load offset=24 - (get_local $1) - ) - ) - ) - ) - (set_local $4 - (i32.sub - (i32.const 0) - (get_local $3) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i64.eq - (i64.shr_u - (i64.load - (i32.add - (i32.load - (get_local $6) - ) - (i32.const 16) - ) - ) - (i64.const 8) - ) - (get_local $2) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $5 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $5) - (get_local $4) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (br_if $label$2 - (i32.eq - (get_local $7) - (get_local $3) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=232 - (tee_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (get_local $1) - ) - (i32.const 224) - ) - (i32.store offset=4 - (get_local $0) - (get_local $6) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (return) - ) - (block $label$3 - (br_if $label$3 - (i32.le_s - (tee_local $6 - (call $db_find_i64 - (i64.load - (get_local $1) - ) - (i64.load offset=8 - (get_local $1) - ) - (i64.const -7949128877345865728) - (get_local $2) - ) - ) - (i32.const -1) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=232 - (tee_local $6 - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE31load_object_by_primary_iteratorEl - (get_local $1) - (get_local $6) - ) - ) - ) - (get_local $1) - ) - (i32.const 224) - ) - (i32.store offset=4 - (get_local $0) - (get_local $6) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (return) - ) - (i32.store offset=4 - (get_local $0) - (i32.const 0) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - ) - (func $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (set_local $8 - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $9) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $2 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $2) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i32.eq - (i32.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $4 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $4) - (get_local $3) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - (set_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i32.xor - (i32.shr_u - (tee_local $6 - (call $db_get_i64 - (get_local $1) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 31) - ) - (i32.const 1) - ) - (i32.const 656) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.lt_u - (get_local $6) - (i32.const 513) - ) - ) - (set_local $4 - (call $malloc - (get_local $6) - ) - ) - (br $label$4) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (get_local $9) - (i32.and - (i32.add - (get_local $6) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $db_get_i64 - (get_local $1) - (get_local $4) - (get_local $6) - ) - ) - (i32.store offset=36 - (get_local $8) - (get_local $4) - ) - (i32.store offset=32 - (get_local $8) - (get_local $4) - ) - (i32.store offset=40 - (get_local $8) - (i32.add - (get_local $4) - (get_local $6) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.lt_u - (get_local $6) - (i32.const 513) - ) - ) - (call $free - (get_local $4) - ) - ) - (set_local $4 - (call $_ZN5eosio14exchange_stateC2Ev - (tee_local $6 - (call $_Znwj - (i32.const 248) - ) - ) - ) - ) - (i32.store offset=232 - (get_local $6) - (get_local $0) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_stateE - (i32.add - (get_local $8) - (i32.const 32) - ) - (get_local $4) - ) - ) - (i32.store offset=236 - (get_local $6) - (get_local $1) - ) - (i32.store offset=24 - (get_local $8) - (get_local $6) - ) - (i64.store offset=16 - (get_local $8) - (tee_local $5 - (i64.shr_u - (i64.load offset=16 - (get_local $6) - ) - (i64.const 8) - ) - ) - ) - (i32.store offset=12 - (get_local $8) - (tee_local $7 - (i32.load offset=236 - (get_local $6) - ) - ) - ) - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ge_u - (tee_local $4 - (i32.load - (tee_local $1 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $4) - (get_local $5) - ) - (i32.store offset=16 - (get_local $4) - (get_local $7) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $4) - (get_local $6) - ) - (i32.store - (get_local $1) - (i32.add - (get_local $4) - (i32.const 24) - ) - ) - (br $label$7) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497615196363685888ENS1_14exchange_stateEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 12) - ) - ) - ) - (set_local $4 - (i32.load offset=24 - (get_local $8) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $4) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 48) - ) - ) - (get_local $6) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_stateE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 3) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_state9connectorE - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_state9connectorE - (get_local $0) - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (i32.add - (get_local $1) - (i32.const 136) - ) - ) - ) - (func $_ZNSt3__16vectorIN5eosio11multi_indexILy10497615196363685888ENS1_14exchange_stateEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.add - (tee_local $4 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 24) - ) - ) - (i32.const 1) - ) - ) - (i32.const 178956971) - ) - ) - (set_local $7 - (i32.const 178956970) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $6 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $6) - ) - (i32.const 24) - ) - ) - (i32.const 89478484) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $5) - (tee_local $7 - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $5) - ) - ) - ) - ) - ) - ) - (set_local $6 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $5 - (i32.load - (get_local $1) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $6) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - (get_local $5) - ) - (i64.store offset=8 - (get_local $1) - (i64.load - (get_local $2) - ) - ) - (i32.store offset=16 - (get_local $1) - (i32.load - (get_local $3) - ) - ) - (set_local $4 - (i32.add - (get_local $6) - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (loop $label$6 - (set_local $3 - (i32.load - (tee_local $2 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -24) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -8) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -12) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -16) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const -24) - ) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$6 - (i32.ne - (get_local $7) - (get_local $2) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $6 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $5) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $6) - ) - ) - (loop $label$8 - (set_local $1 - (i32.load - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $6) - (get_local $7) - ) - ) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_14exchange_state9connectorE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 3) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 40) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 48) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 56) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 64) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 72) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 80) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 88) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio12margin_stateC2Ev (param $0 i32) (result i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (i64.store offset=8 - (get_local $0) - (i64.const 1398362884) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load offset=8 - (get_local $0) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - (i64.const 1398362884) - ) - (i64.store offset=24 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$5 - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store offset=56 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=48 - (get_local $0) - (i64.const 9218868437227405311) - ) - (get_local $0) - ) - (func $_ZN5eosio12market_state11margin_callENS_15extended_symbolE (param $0 i32) (param $1 i32) - (block $label$0 - (br_if $label$0 - (i64.ne - (i64.load - (get_local $1) - ) - (i64.load - (i32.add - (get_local $0) - (i32.const 56) - ) - ) - ) - ) - (br_if $label$0 - (i64.ne - (i64.load offset=8 - (get_local $1) - ) - (i64.load - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - ) - (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE - (get_local $0) - (i32.add - (get_local $0) - (i32.const 48) - ) - (i32.add - (get_local $0) - (i32.const 280) - ) - ) - (return) - ) - (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE - (get_local $0) - (i32.add - (get_local $0) - (i32.const 144) - ) - (i32.add - (get_local $0) - (i32.const 320) - ) - ) - ) - (func $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 f64) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 288) - ) - ) - ) - (i32.store offset=272 - (get_local $9) - (get_local $2) - ) - (i64.store offset=240 - (get_local $9) - (i64.const 0) - ) - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE11lower_boundERKy - (i32.add - (get_local $9) - (i32.const 264) - ) - (i32.add - (get_local $9) - (i32.const 272) - ) - (i32.add - (get_local $9) - (i32.const 240) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $2 - (i32.load offset=268 - (get_local $9) - ) - ) - ) - ) - (i64.store - (tee_local $3 - (i32.add - (i32.add - (get_local $9) - (i32.const 216) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 48) - ) - ) - ) - (i64.store - (tee_local $4 - (i32.add - (i32.add - (get_local $9) - (i32.const 216) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 40) - ) - ) - ) - (i64.store offset=216 - (get_local $9) - (i64.load offset=32 - (get_local $2) - ) - ) - (set_local $7 - (i64.load - (i32.add - (get_local $2) - (i32.const 24) - ) - ) - ) - (i64.store offset=200 - (get_local $9) - (i64.load - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - (i64.store offset=208 - (get_local $9) - (get_local $7) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 80) - ) - (i32.const 16) - ) - (i64.load - (get_local $3) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 80) - ) - (i32.const 8) - ) - (i64.load - (get_local $4) - ) - ) - (i64.store offset=80 - (get_local $9) - (i64.load offset=216 - (get_local $9) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 64) - ) - (i32.const 8) - ) - (i64.load offset=208 - (get_local $9) - ) - ) - (i64.store offset=64 - (get_local $9) - (i64.load offset=200 - (get_local $9) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $9) - (i32.const 240) - ) - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (i32.add - (get_local $9) - (i32.const 80) - ) - (i32.add - (get_local $9) - (i32.const 64) - ) - ) - (call $eosio_assert - (i64.ge_s - (tee_local $7 - (i64.load offset=240 - (get_local $9) - ) - ) - (i64.load offset=8 - (i32.load offset=268 - (get_local $9) - ) - ) - ) - (i32.const 736) - ) - (call $eosio_assert - (i64.eq - (tee_local $5 - (i64.load offset=256 - (get_local $9) - ) - ) - (i64.load - (i32.add - (tee_local $2 - (i32.load offset=268 - (get_local $9) - ) - ) - (i32.const 24) - ) - ) - ) - (i32.const 800) - ) - (call $eosio_assert - (i64.eq - (i64.load - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - (tee_local $6 - (i64.load offset=248 - (get_local $9) - ) - ) - ) - (i32.const 816) - ) - (call $eosio_assert - (i64.gt_s - (tee_local $7 - (i64.sub - (get_local $7) - (i64.load offset=8 - (get_local $2) - ) - ) - ) - (i64.const -4611686018427387904) - ) - (i32.const 864) - ) - (call $eosio_assert - (i64.lt_s - (get_local $7) - (i64.const 4611686018427387904) - ) - (i32.const 896) - ) - (i64.store offset=160 - (get_local $9) - (get_local $6) - ) - (i64.store offset=152 - (get_local $9) - (get_local $7) - ) - (i64.store offset=168 - (get_local $9) - (get_local $5) - ) - (i64.store offset=136 - (get_local $9) - (i64.load - (i32.add - (tee_local $2 - (i32.load offset=268 - (get_local $9) - ) - ) - (i32.const 40) - ) - ) - ) - (i64.store offset=144 - (get_local $9) - (i64.load - (i32.add - (get_local $2) - (i32.const 48) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $9) - (i32.const 40) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (i32.add - (get_local $9) - (i32.const 152) - ) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $9) - (i32.const 40) - ) - (i32.const 16) - ) - (i32.load offset=168 - (get_local $9) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 40) - ) - (i32.const 8) - ) - (i64.load offset=160 - (get_local $9) - ) - ) - (i64.store offset=40 - (get_local $9) - (i64.load offset=152 - (get_local $9) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 24) - ) - (i32.const 8) - ) - (i64.load offset=144 - (get_local $9) - ) - ) - (i64.store offset=24 - (get_local $9) - (i64.load offset=136 - (get_local $9) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $9) - (i32.const 176) - ) - (get_local $3) - (i32.add - (get_local $9) - (i32.const 40) - ) - (i32.add - (get_local $9) - (i32.const 24) - ) - ) - (set_local $7 - (i64.load - (i32.load offset=268 - (get_local $9) - ) - ) - ) - (i64.store - (tee_local $2 - (i32.add - (i32.add - (get_local $9) - (i32.const 112) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $9) - (i32.const 176) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (tee_local $3 - (i32.add - (i32.add - (get_local $9) - (i32.const 112) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $9) - (i32.const 176) - ) - (i32.const 8) - ) - ) - ) - (i32.store offset=112 - (get_local $9) - (i32.load offset=176 - (get_local $9) - ) - ) - (i32.store offset=116 - (get_local $9) - (i32.load offset=180 - (get_local $9) - ) - ) - (set_local $0 - (i32.load offset=440 - (get_local $0) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 16) - ) - (i64.load - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 8) - ) - (i64.load - (get_local $3) - ) - ) - (i64.store - (get_local $9) - (i64.load offset=112 - (get_local $9) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $0) - (get_local $7) - (get_local $9) - (get_local $9) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - (i64.sub - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (i32.load offset=268 - (get_local $9) - ) - ) - ) - ) - (i64.store offset=280 - (get_local $9) - (tee_local $7 - (i64.load offset=264 - (get_local $9) - ) - ) - ) - (call $eosio_assert - (i32.ne - (tee_local $2 - (i32.wrap/i64 - (i64.shr_u - (get_local $7) - (i64.const 32) - ) - ) - ) - (i32.const 0) - ) - (i32.const 928) - ) - (drop - (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE14const_iteratorppEv - (i32.add - (get_local $9) - (i32.const 280) - ) - ) - ) - (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ - (i32.load offset=272 - (get_local $9) - ) - (get_local $2) - ) - (i64.store offset=280 - (get_local $9) - (i64.const 0) - ) - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE11lower_boundERKy - (i32.add - (get_local $9) - (i32.const 104) - ) - (i32.add - (get_local $9) - (i32.const 272) - ) - (i32.add - (get_local $9) - (i32.const 280) - ) - ) - (i64.store offset=264 - (get_local $9) - (tee_local $7 - (i64.load offset=104 - (get_local $9) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.eqz - (tee_local $2 - (i32.wrap/i64 - (i64.shr_u - (get_local $7) - (i64.const 32) - ) - ) - ) - ) - ) - (set_local $8 - (f64.load offset=56 - (get_local $2) - ) - ) - (br $label$1) - ) - (set_local $8 - (f64.const 18446744073709551615) - ) - ) - (f64.store - (i32.add - (get_local $1) - (i32.const 80) - ) - (get_local $8) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 288) - ) - ) - ) - (func $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE11lower_boundERKy (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $10) - (i64.const 0) - ) - (i64.store - (get_local $10) - (i64.load - (get_local $2) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.lt_s - (tee_local $3 - (call $db_idx64_lowerbound - (i64.load - (tee_local $8 - (i32.load - (get_local $1) - ) - ) - ) - (i64.load offset=8 - (get_local $8) - ) - (i64.const -7949197150146002944) - (get_local $10) - (i32.add - (get_local $10) - (i32.const 8) - ) - ) - ) - (i32.const 0) - ) - ) - (set_local $5 - (i64.load offset=8 - (get_local $10) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $9 - (i32.load - (i32.add - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - (i32.const 28) - ) - ) - ) - (tee_local $6 - (i32.load offset=24 - (get_local $4) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $9) - (i32.const -24) - ) - ) - (set_local $7 - (i32.sub - (i32.const 0) - (get_local $6) - ) - ) - (loop $label$2 - (br_if $label$1 - (i64.eq - (i64.load - (i32.load - (get_local $2) - ) - ) - (get_local $5) - ) - ) - (set_local $9 - (get_local $2) - ) - (set_local $2 - (tee_local $8 - (i32.add - (get_local $2) - (i32.const -24) - ) - ) - ) - (br_if $label$2 - (i32.ne - (i32.add - (get_local $8) - (get_local $7) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.eq - (get_local $9) - (get_local $6) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $2 - (i32.load - (i32.add - (get_local $9) - (i32.const -24) - ) - ) - ) - ) - (get_local $4) - ) - (i32.const 224) - ) - (br $label$3) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $2 - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $4) - (call $db_find_i64 - (i64.load - (get_local $4) - ) - (i64.load offset=8 - (get_local $4) - ) - (i64.const -7949197150146002944) - (get_local $5) - ) - ) - ) - ) - (get_local $4) - ) - (i32.const 224) - ) - ) - (i32.store - (i32.add - (get_local $2) - (i32.const 72) - ) - (get_local $3) - ) - ) - (i32.store offset=4 - (get_local $0) - (get_local $2) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5indexILy4729653573519933440ES6_Ly0ELb0EE14const_iteratorppEv (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=4 - (get_local $0) - ) - (i32.const 0) - ) - (i32.const 1152) - ) - (block $label$0 - (br_if $label$0 - (i32.ne - (tee_local $7 - (i32.load offset=72 - (tee_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - ) - (i32.const -1) - ) - ) - (set_local $7 - (call $db_idx64_find_primary - (i64.load - (tee_local $7 - (i32.load - (i32.load - (get_local $0) - ) - ) - ) - ) - (i64.load offset=8 - (get_local $7) - ) - (i64.const -7949197150146002944) - (i32.add - (get_local $9) - (i32.const 8) - ) - (i64.load - (get_local $6) - ) - ) - ) - (i32.store offset=72 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (get_local $7) - ) - ) - (i64.store offset=8 - (get_local $9) - (i64.const 0) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.le_s - (tee_local $1 - (call $db_idx64_next - (get_local $7) - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - ) - (i32.const -1) - ) - ) - (set_local $3 - (i64.load offset=8 - (get_local $9) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $8 - (i32.load - (i32.add - (tee_local $2 - (i32.load - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 28) - ) - ) - ) - (tee_local $4 - (i32.load offset=24 - (get_local $2) - ) - ) - ) - ) - (set_local $7 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - (set_local $5 - (i32.sub - (i32.const 0) - (get_local $4) - ) - ) - (loop $label$6 - (br_if $label$5 - (i64.eq - (i64.load - (i32.load - (get_local $7) - ) - ) - (get_local $3) - ) - ) - (set_local $8 - (get_local $7) - ) - (set_local $7 - (tee_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - (br_if $label$6 - (i32.ne - (i32.add - (get_local $6) - (get_local $5) - ) - (i32.const -24) - ) - ) - ) - ) - (br_if $label$3 - (i32.eq - (get_local $8) - (get_local $4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $7 - (i32.load - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - (br $label$2) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.const 0) - ) - (br $label$1) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $7 - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $2) - (call $db_find_i64 - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (get_local $3) - ) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $7) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 72) - ) - (get_local $1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ (param $0 i32) (param $1 i32) - (local $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (get_local $1) - ) - (get_local $0) - ) - (i32.const 976) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $0) - ) - (call $current_receiver) - ) - (i32.const 1024) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (tee_local $5 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (tee_local $3 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $2 - (i64.load - (get_local $1) - ) - ) - (set_local $6 - (i32.sub - (i32.const 0) - (get_local $3) - ) - ) - (set_local $8 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i64.eq - (i64.load - (i32.load - (get_local $8) - ) - ) - (get_local $2) - ) - ) - (set_local $7 - (get_local $8) - ) - (set_local $8 - (tee_local $4 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $4) - (get_local $6) - ) - (i32.const -24) - ) - ) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $7) - (get_local $3) - ) - (i32.const 1088) - ) - (set_local $8 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (tee_local $4 - (i32.load - (get_local $5) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $4) - ) - ) - (set_local $7 - (get_local $8) - ) - (loop $label$4 - (set_local $6 - (i32.load - (tee_local $8 - (i32.add - (get_local $7) - (i32.const 24) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (set_local $4 - (i32.load - (get_local $7) - ) - ) - (i32.store - (get_local $7) - (get_local $6) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (get_local $4) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - ) - (i64.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const 32) - ) - ) - ) - (set_local $7 - (get_local $8) - ) - (br_if $label$4 - (i32.ne - (i32.add - (get_local $8) - (get_local $3) - ) - (i32.const -24) - ) - ) - ) - (br_if $label$2 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (get_local $8) - ) - ) - ) - (loop $label$6 - (set_local $4 - (i32.load - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (block $label$7 - (br_if $label$7 - (i32.eqz - (get_local $4) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (br_if $label$6 - (i32.ne - (get_local $8) - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 28) - ) - (get_local $8) - ) - (call $db_remove_i64 - (i32.load offset=68 - (get_local $1) - ) - ) - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.gt_s - (tee_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 72) - ) - ) - ) - (i32.const -1) - ) - ) - (br_if $label$8 - (i32.lt_s - (tee_local $7 - (call $db_idx64_find_primary - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - (i64.const -7949197150146002944) - (i32.add - (get_local $9) - (i32.const 8) - ) - (i64.load - (get_local $1) - ) - ) - ) - (i32.const 0) - ) - ) - ) - (call $db_idx64_remove - (get_local $7) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - ) - (func $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store offset=44 - (tee_local $8 - (get_local $9) - ) - (get_local $1) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $2 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $2) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i32.eq - (i32.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $4 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $4) - (get_local $3) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - (set_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i32.xor - (i32.shr_u - (tee_local $6 - (call $db_get_i64 - (get_local $1) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 31) - ) - (i32.const 1) - ) - (i32.const 656) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.lt_u - (get_local $6) - (i32.const 513) - ) - ) - (set_local $4 - (call $malloc - (get_local $6) - ) - ) - (br $label$4) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (get_local $9) - (i32.and - (i32.add - (get_local $6) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $db_get_i64 - (get_local $1) - (get_local $4) - (get_local $6) - ) - ) - (i32.store offset=36 - (get_local $8) - (get_local $4) - ) - (i32.store offset=32 - (get_local $8) - (get_local $4) - ) - (i32.store offset=40 - (get_local $8) - (i32.add - (get_local $4) - (get_local $6) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.lt_u - (get_local $6) - (i32.const 513) - ) - ) - (call $free - (get_local $4) - ) - ) - (i32.store offset=8 - (get_local $8) - (get_local $0) - ) - (i32.store offset=12 - (get_local $8) - (i32.add - (get_local $8) - (i32.const 32) - ) - ) - (i32.store offset=16 - (get_local $8) - (i32.add - (get_local $8) - (i32.const 44) - ) - ) - (drop - (call $_ZN5eosio15margin_positionC2Ev - (tee_local $6 - (call $_Znwj - (i32.const 80) - ) - ) - ) - ) - (i32.store offset=64 - (get_local $6) - (get_local $0) - ) - (call $_ZZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorElENKUlRT_E_clINS8_4itemEEEDaSA_ - (i32.add - (get_local $8) - (i32.const 8) - ) - (get_local $6) - ) - (i32.store offset=24 - (get_local $8) - (get_local $6) - ) - (i64.store offset=8 - (get_local $8) - (tee_local $5 - (i64.load - (get_local $6) - ) - ) - ) - (i32.store offset=4 - (get_local $8) - (tee_local $7 - (i32.load offset=68 - (get_local $6) - ) - ) - ) - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ge_u - (tee_local $4 - (i32.load - (tee_local $1 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $4) - (get_local $5) - ) - (i32.store offset=16 - (get_local $4) - (get_local $7) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $4) - (get_local $6) - ) - (i32.store - (get_local $1) - (i32.add - (get_local $4) - (i32.const 24) - ) - ) - (br $label$7) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497546923563548672ENS1_15margin_positionEJNS1_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS3_yXadL_ZNKS3_8get_callEvEEEEEEEE8item_ptrENS_9allocatorISB_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINSA_4itemENS_14default_deleteISH_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.add - (get_local $8) - (i32.const 4) - ) - ) - ) - (set_local $4 - (i32.load offset=24 - (get_local $8) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $4) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 48) - ) - ) - (get_local $6) - ) - (func $_ZN5eosio15margin_positionC2Ev (param $0 i32) (result i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 40) - ) - ) - (i64.const 1398362884) - ) - (i64.store offset=32 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$5 - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store offset=56 - (get_local $0) - (i64.const 0) - ) - (get_local $0) - ) - (func $_ZZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorElENKUlRT_E_clINS8_4itemEEEDaSA_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $3 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $3 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $3 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $3 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $3 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 40) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $3 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 48) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $3 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 56) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $2 - (i32.load - (i32.load offset=8 - (get_local $0) - ) - ) - ) - (i32.store offset=72 - (get_local $1) - (i32.const -1) - ) - (i32.store offset=68 - (get_local $1) - (get_local $2) - ) - ) - (func $_ZNSt3__16vectorIN5eosio11multi_indexILy10497546923563548672ENS1_15margin_positionEJNS1_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS3_yXadL_ZNKS3_8get_callEvEEEEEEEE8item_ptrENS_9allocatorISB_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINSA_4itemENS_14default_deleteISH_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.add - (tee_local $4 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 24) - ) - ) - (i32.const 1) - ) - ) - (i32.const 178956971) - ) - ) - (set_local $7 - (i32.const 178956970) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $6 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $6) - ) - (i32.const 24) - ) - ) - (i32.const 89478484) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $5) - (tee_local $7 - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $5) - ) - ) - ) - ) - ) - ) - (set_local $6 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $5 - (i32.load - (get_local $1) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $6) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - (get_local $5) - ) - (i64.store offset=8 - (get_local $1) - (i64.load - (get_local $2) - ) - ) - (i32.store offset=16 - (get_local $1) - (i32.load - (get_local $3) - ) - ) - (set_local $4 - (i32.add - (get_local $6) - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (loop $label$6 - (set_local $3 - (i32.load - (tee_local $2 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -24) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -8) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -12) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -16) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const -24) - ) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$6 - (i32.ne - (get_local $7) - (get_local $2) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $6 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $5) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $6) - ) - ) - (loop $label$8 - (set_local $1 - (i32.load - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $6) - (get_local $7) - ) - ) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $_ZNK5eosio12market_state13initial_stateEv (param $0 i32) (result i32) - (i32.load - (i32.add - (get_local $0) - (i32.const 448) - ) - ) - ) - (func $_ZN5eosio12market_state4lendEyRKNS_14extended_assetE (param $0 i32) (param $1 i64) (param $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i32) - (local $6 i64) - (local $7 f64) - (local $8 f64) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i64.store offset=32 - (get_local $9) - (tee_local $3 - (i64.load offset=8 - (get_local $2) - ) - ) - ) - (set_local $5 - (i32.load offset=440 - (get_local $0) - ) - ) - (set_local $4 - (i64.load offset=16 - (get_local $2) - ) - ) - (set_local $6 - (i64.load - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 8) - ) - (get_local $3) - ) - (i64.store offset=24 - (get_local $9) - (tee_local $6 - (i64.sub - (i64.const 0) - (get_local $6) - ) - ) - ) - (i64.store offset=40 - (get_local $9) - (get_local $4) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 16) - ) - (get_local $4) - ) - (i64.store - (get_local $9) - (get_local $6) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $5) - (get_local $1) - (get_local $9) - (get_local $9) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.ne - (get_local $3) - (i64.load - (i32.add - (get_local $0) - (i32.const 56) - ) - ) - ) - ) - (br_if $label$5 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - ) - (set_local $4 - (i64.load - (get_local $2) - ) - ) - (br_if $label$4 - (i64.lt_s - (tee_local $3 - (i64.load - (i32.add - (get_local $0) - (i32.const 80) - ) - ) - ) - (i64.const 1) - ) - ) - (set_local $8 - (f64.add - (tee_local $8 - (f64.load - (i32.add - (get_local $0) - (i32.const 136) - ) - ) - ) - (f64.div - (f64.mul - (get_local $8) - (tee_local $7 - (f64.convert_s/i64 - (get_local $4) - ) - ) - ) - (f64.convert_s/i64 - (get_local $3) - ) - ) - ) - ) - (br $label$3) - ) - (block $label$6 - (br_if $label$6 - (i64.ne - (get_local $3) - (i64.load - (i32.add - (get_local $0) - (i32.const 152) - ) - ) - ) - ) - (br_if $label$6 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $0) - (i32.const 160) - ) - ) - ) - ) - (set_local $4 - (i64.load - (get_local $2) - ) - ) - (br_if $label$2 - (i64.lt_s - (tee_local $3 - (i64.load - (i32.add - (get_local $0) - (i32.const 176) - ) - ) - ) - (i64.const 1) - ) - ) - (set_local $8 - (f64.add - (tee_local $8 - (f64.load - (i32.add - (get_local $0) - (i32.const 232) - ) - ) - ) - (f64.div - (f64.mul - (get_local $8) - (tee_local $7 - (f64.convert_s/i64 - (get_local $4) - ) - ) - ) - (f64.convert_s/i64 - (get_local $3) - ) - ) - ) - ) - (br $label$1) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1184) - ) - (br $label$0) - ) - (set_local $8 - (f64.add - (tee_local $7 - (f64.convert_s/i64 - (get_local $4) - ) - ) - (f64.load - (i32.add - (get_local $0) - (i32.const 136) - ) - ) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 80) - ) - (i64.add - (get_local $3) - (get_local $4) - ) - ) - (f64.store - (i32.add - (get_local $0) - (i32.const 136) - ) - (get_local $8) - ) - (call $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd - (get_local $9) - (get_local $1) - (i32.add - (get_local $0) - (i32.const 360) - ) - (get_local $7) - ) - (br $label$0) - ) - (set_local $8 - (f64.add - (tee_local $7 - (f64.convert_s/i64 - (get_local $4) - ) - ) - (f64.load - (i32.add - (get_local $0) - (i32.const 232) - ) - ) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 176) - ) - (i64.add - (get_local $3) - (get_local $4) - ) - ) - (f64.store - (i32.add - (get_local $0) - (i32.const 232) - ) - (get_local $8) - ) - (call $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd - (get_local $9) - (get_local $1) - (i32.add - (get_local $0) - (i32.const 400) - ) - (get_local $7) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - ) - (func $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd (param $0 i32) (param $1 i64) (param $2 i32) (param $3 f64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $9 - (i32.load - (i32.add - (get_local $2) - (i32.const 28) - ) - ) - ) - (tee_local $4 - (i32.load offset=24 - (get_local $2) - ) - ) - ) - ) - (set_local $8 - (i32.add - (get_local $9) - (i32.const -24) - ) - ) - (set_local $5 - (i32.sub - (i32.const 0) - (get_local $4) - ) - ) - (loop $label$1 - (br_if $label$0 - (i64.eq - (i64.load - (i32.load - (get_local $8) - ) - ) - (get_local $1) - ) - ) - (set_local $9 - (get_local $8) - ) - (set_local $8 - (tee_local $6 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $6) - (get_local $5) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (get_local $9) - (get_local $4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=16 - (tee_local $8 - (i32.load - (i32.add - (get_local $9) - (i32.const -24) - ) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - (br_if $label$4 - (get_local $8) - ) - (br $label$3) - ) - (br_if $label$3 - (i32.lt_s - (tee_local $8 - (call $db_find_i64 - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -8282898168966807552) - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=16 - (tee_local $8 - (call $_ZNK5eosio11multi_indexILy10163845904742744064ENS_13loan_positionEJEE31load_object_by_primary_iteratorEl - (get_local $2) - (get_local $8) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 352) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=16 - (get_local $8) - ) - (get_local $2) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $2) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (f64.store offset=8 - (get_local $8) - (tee_local $3 - (f64.add - (f64.load offset=8 - (get_local $8) - ) - (get_local $3) - ) - ) - ) - (set_local $1 - (i64.load - (get_local $8) - ) - ) - (call $eosio_assert - (f64.ge - (get_local $3) - (f64.const 0) - ) - (i32.const 1216) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (i64.load - (get_local $8) - ) - ) - (i32.const 544) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $10) - (i32.const 16) - ) - (get_local $8) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.or - (i32.add - (get_local $10) - (i32.const 16) - ) - (i32.const 8) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $db_update_i64 - (i32.load offset=20 - (get_local $8) - ) - (i64.const 0) - (i32.add - (get_local $10) - (i32.const 16) - ) - (i32.const 16) - ) - (br_if $label$2 - (i64.lt_u - (get_local $1) - (i64.load offset=16 - (get_local $2) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (select - (i64.const -2) - (i64.add - (get_local $1) - (i64.const 1) - ) - (i64.gt_u - (get_local $1) - (i64.const -3) - ) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $2) - ) - (call $current_receiver) - ) - (i32.const 288) - ) - (i32.store offset=16 - (tee_local $8 - (call $_Znwj - (i32.const 32) - ) - ) - (get_local $2) - ) - (f64.store offset=8 - (get_local $8) - (get_local $3) - ) - (i64.store - (get_local $8) - (get_local $1) - ) - (call $eosio_assert - (f64.ge - (get_local $3) - (f64.const 0) - ) - (i32.const 1216) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $10) - (i32.const 16) - ) - (get_local $8) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.or - (i32.add - (get_local $10) - (i32.const 16) - ) - (i32.const 8) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=20 - (get_local $8) - (tee_local $9 - (call $db_store_i64 - (i64.load offset=8 - (get_local $2) - ) - (i64.const -8282898168966807552) - (get_local $1) - (tee_local $7 - (i64.load - (get_local $8) - ) - ) - (i32.add - (get_local $10) - (i32.const 16) - ) - (i32.const 16) - ) - ) - ) - (block $label$6 - (br_if $label$6 - (i64.lt_u - (get_local $7) - (i64.load offset=16 - (get_local $2) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (select - (i64.const -2) - (i64.add - (get_local $7) - (i64.const 1) - ) - (i64.gt_u - (get_local $7) - (i64.const -3) - ) - ) - ) - ) - (i32.store offset=8 - (get_local $10) - (get_local $8) - ) - (i64.store offset=16 - (get_local $10) - (tee_local $1 - (i64.load - (get_local $8) - ) - ) - ) - (i32.store offset=4 - (get_local $10) - (get_local $9) - ) - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ge_u - (tee_local $6 - (i32.load - (tee_local $5 - (i32.add - (get_local $2) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $6) - (get_local $1) - ) - (i32.store offset=16 - (get_local $6) - (get_local $9) - ) - (i32.store offset=8 - (get_local $10) - (i32.const 0) - ) - (i32.store - (get_local $6) - (get_local $8) - ) - (i32.store - (get_local $5) - (i32.add - (get_local $6) - (i32.const 24) - ) - ) - (br $label$7) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10163845904742744064ENS1_13loan_positionEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $2) - (i32.const 24) - ) - (i32.add - (get_local $10) - (i32.const 8) - ) - (i32.add - (get_local $10) - (i32.const 16) - ) - (i32.add - (get_local $10) - (i32.const 4) - ) - ) - ) - (set_local $8 - (i32.load offset=8 - (get_local $10) - ) - ) - (i32.store offset=8 - (get_local $10) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $8) - ) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - ) - (func $_ZNK5eosio11multi_indexILy10163845904742744064ENS_13loan_positionEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (set_local $8 - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $9) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $2 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $2) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i32.eq - (i32.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $4 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $4) - (get_local $3) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - (set_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i32.xor - (i32.shr_u - (tee_local $4 - (call $db_get_i64 - (get_local $1) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 31) - ) - (i32.const 1) - ) - (i32.const 656) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.le_u - (get_local $4) - (i32.const 512) - ) - ) - (drop - (call $db_get_i64 - (get_local $1) - (tee_local $7 - (call $malloc - (get_local $4) - ) - ) - (get_local $4) - ) - ) - (call $free - (get_local $7) - ) - (br $label$4) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (get_local $9) - (i32.and - (i32.add - (get_local $4) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - (drop - (call $db_get_i64 - (get_local $1) - (get_local $7) - (get_local $4) - ) - ) - ) - (i32.store offset=16 - (tee_local $6 - (call $_Znwj - (i32.const 32) - ) - ) - (get_local $0) - ) - (call $eosio_assert - (i32.gt_u - (get_local $4) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $6) - (get_local $7) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (i32.and - (get_local $4) - (i32.const -8) - ) - (i32.const 8) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $6) - (i32.const 8) - ) - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=20 - (get_local $6) - (get_local $1) - ) - (i32.store offset=24 - (get_local $8) - (get_local $6) - ) - (i64.store offset=16 - (get_local $8) - (tee_local $5 - (i64.load - (get_local $6) - ) - ) - ) - (i32.store offset=12 - (get_local $8) - (tee_local $7 - (i32.load offset=20 - (get_local $6) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.ge_u - (tee_local $4 - (i32.load - (tee_local $1 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $4) - (get_local $5) - ) - (i32.store offset=16 - (get_local $4) - (get_local $7) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $4) - (get_local $6) - ) - (i32.store - (get_local $1) - (i32.add - (get_local $4) - (i32.const 24) - ) - ) - (br $label$6) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10163845904742744064ENS1_13loan_positionEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 12) - ) - ) - ) - (set_local $4 - (i32.load offset=24 - (get_local $8) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $4) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 32) - ) - ) - (get_local $6) - ) - (func $_ZNSt3__16vectorIN5eosio11multi_indexILy10163845904742744064ENS1_13loan_positionEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.add - (tee_local $4 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 24) - ) - ) - (i32.const 1) - ) - ) - (i32.const 178956971) - ) - ) - (set_local $7 - (i32.const 178956970) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $6 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $6) - ) - (i32.const 24) - ) - ) - (i32.const 89478484) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $5) - (tee_local $7 - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $5) - ) - ) - ) - ) - ) - ) - (set_local $6 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $5 - (i32.load - (get_local $1) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $6) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - (get_local $5) - ) - (i64.store offset=8 - (get_local $1) - (i64.load - (get_local $2) - ) - ) - (i32.store offset=16 - (get_local $1) - (i32.load - (get_local $3) - ) - ) - (set_local $4 - (i32.add - (get_local $6) - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (loop $label$6 - (set_local $3 - (i32.load - (tee_local $2 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -24) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -8) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -12) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -16) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const -24) - ) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$6 - (i32.ne - (get_local $7) - (get_local $2) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $6 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $5) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $6) - ) - ) - (loop $label$8 - (set_local $1 - (i32.load - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $6) - (get_local $7) - ) - ) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE (param $0 i32) (param $1 i64) (param $2 f64) (param $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i32) - (local $7 f64) - (local $8 f64) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (call $eosio_assert - (f64.gt - (get_local $2) - (f64.const 0) - ) - (i32.const 1232) - ) - (call $_ZN5eosio12market_state18adjust_lend_sharesEyRNS_11multi_indexILy10163845904742744064ENS_13loan_positionEJEEEd - (get_local $9) - (get_local $1) - (i32.add - (get_local $0) - (i32.const 360) - ) - (f64.neg - (get_local $2) - ) - ) - (call $prints - (i32.const 1264) - ) - (call $_ZNK5eosio11symbol_type5printEb - (get_local $3) - (i32.const 1) - ) - (call $prints - (i32.const 1280) - ) - (call $printn - (i64.load offset=8 - (get_local $3) - ) - ) - (set_local $5 - (i64.load offset=8 - (get_local $3) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i64.ne - (tee_local $4 - (i64.load - (get_local $3) - ) - ) - (i64.load - (i32.add - (get_local $0) - (i32.const 56) - ) - ) - ) - ) - (br_if $label$1 - (i64.ne - (get_local $5) - (i64.load - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - ) - (i64.store - (tee_local $6 - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $0) - (i32.const 120) - ) - ) - ) - (i64.store offset=96 - (get_local $9) - (i64.load - (i32.add - (get_local $0) - (i32.const 112) - ) - ) - ) - (call $prints - (i32.const 1296) - ) - (call $printdf - (get_local $2) - ) - (call $prints - (i32.const 1312) - ) - (call $printdf - (f64.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 136) - ) - ) - ) - ) - (call $prints - (i32.const 1344) - ) - (f64.store - (get_local $3) - (tee_local $8 - (f64.sub - (tee_local $7 - (f64.load - (get_local $3) - ) - ) - (get_local $2) - ) - ) - ) - (i64.store - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 80) - ) - ) - (i64.sub - (tee_local $5 - (i64.load - (get_local $3) - ) - ) - (tee_local $5 - (i64.trunc_s/f64 - (f64.div - (f64.mul - (f64.convert_s/i64 - (get_local $5) - ) - (get_local $2) - ) - (get_local $7) - ) - ) - ) - ) - ) - (call $eosio_assert - (f64.ge - (get_local $8) - (f64.const 0) - ) - (i32.const 1216) - ) - (call $eosio_assert - (i32.xor - (i32.wrap/i64 - (i64.shr_u - (i64.load - (get_local $3) - ) - (i64.const 63) - ) - ) - (i32.const 1) - ) - (i32.const 1216) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 92) - ) - (i32.load - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (tee_local $3 - (i32.add - (i32.add - (get_local $9) - (i32.const 72) - ) - (i32.const 16) - ) - ) - (i32.load - (get_local $6) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $9) - (i32.const 72) - ) - (i32.const 12) - ) - (i32.load offset=100 - (get_local $9) - ) - ) - (i64.store offset=72 - (get_local $9) - (get_local $5) - ) - (i32.store offset=80 - (get_local $9) - (i32.load offset=96 - (get_local $9) - ) - ) - (set_local $0 - (i32.load offset=440 - (get_local $0) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 8) - ) - (i64.load offset=80 - (get_local $9) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 16) - ) - (i64.load - (get_local $3) - ) - ) - (i64.store - (get_local $9) - (i64.load offset=72 - (get_local $9) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $0) - (get_local $1) - (get_local $9) - (get_local $9) - ) - (br $label$0) - ) - (block $label$2 - (br_if $label$2 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $0) - (i32.const 152) - ) - ) - ) - ) - (br_if $label$2 - (i64.ne - (get_local $5) - (i64.load - (i32.add - (get_local $0) - (i32.const 160) - ) - ) - ) - ) - (i64.store - (tee_local $6 - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $0) - (i32.const 216) - ) - ) - ) - (i64.store offset=96 - (get_local $9) - (i64.load - (i32.add - (get_local $0) - (i32.const 208) - ) - ) - ) - (call $prints - (i32.const 1296) - ) - (call $printdf - (get_local $2) - ) - (call $prints - (i32.const 1312) - ) - (call $printdf - (f64.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 232) - ) - ) - ) - ) - (call $prints - (i32.const 1344) - ) - (f64.store - (get_local $3) - (tee_local $8 - (f64.sub - (tee_local $7 - (f64.load - (get_local $3) - ) - ) - (get_local $2) - ) - ) - ) - (i64.store - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 176) - ) - ) - (i64.sub - (tee_local $5 - (i64.load - (get_local $3) - ) - ) - (tee_local $5 - (i64.trunc_s/f64 - (f64.div - (f64.mul - (f64.convert_s/i64 - (get_local $5) - ) - (get_local $2) - ) - (get_local $7) - ) - ) - ) - ) - ) - (call $eosio_assert - (f64.ge - (get_local $8) - (f64.const 0) - ) - (i32.const 1216) - ) - (call $eosio_assert - (i32.xor - (i32.wrap/i64 - (i64.shr_u - (i64.load - (get_local $3) - ) - (i64.const 63) - ) - ) - (i32.const 1) - ) - (i32.const 1216) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 68) - ) - (i32.load - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (tee_local $3 - (i32.add - (i32.add - (get_local $9) - (i32.const 48) - ) - (i32.const 16) - ) - ) - (i32.load - (get_local $6) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $9) - (i32.const 48) - ) - (i32.const 12) - ) - (i32.load offset=100 - (get_local $9) - ) - ) - (i64.store offset=48 - (get_local $9) - (get_local $5) - ) - (i32.store offset=56 - (get_local $9) - (i32.load offset=96 - (get_local $9) - ) - ) - (set_local $0 - (i32.load offset=440 - (get_local $0) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 24) - ) - (i32.const 8) - ) - (i64.load offset=56 - (get_local $9) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 24) - ) - (i32.const 16) - ) - (i64.load - (get_local $3) - ) - ) - (i64.store offset=24 - (get_local $9) - (i64.load offset=48 - (get_local $9) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $0) - (get_local $1) - (i32.add - (get_local $9) - (i32.const 24) - ) - (get_local $9) - ) - (br $label$0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1184) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 112) - ) - ) - ) - (func $_ZNK5eosio11symbol_type5printEb (param $0 i32) (param $1 i32) - (local $2 i64) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (call $printui - (i64.load8_u - (get_local $0) - ) - ) - (call $prints - (i32.const 1360) - ) - ) - (i32.store8 offset=15 - (get_local $3) - (tee_local $0 - (i32.wrap/i64 - (i64.shr_u - (tee_local $2 - (i64.load - (get_local $0) - ) - ) - (i64.const 8) - ) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 255) - ) - ) - ) - (call $prints_l - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - (i32.store8 offset=15 - (get_local $3) - (tee_local $0 - (i32.wrap/i64 - (i64.shr_u - (get_local $2) - (i64.const 16) - ) - ) - ) - ) - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 255) - ) - ) - ) - (call $prints_l - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - (i32.store8 offset=15 - (get_local $3) - (tee_local $0 - (i32.wrap/i64 - (i64.shr_u - (get_local $2) - (i64.const 24) - ) - ) - ) - ) - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 255) - ) - ) - ) - (call $prints_l - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - (i32.store8 offset=15 - (get_local $3) - (tee_local $0 - (i32.wrap/i64 - (i64.shr_u - (get_local $2) - (i64.const 32) - ) - ) - ) - ) - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 255) - ) - ) - ) - (call $prints_l - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - (i32.store8 offset=15 - (get_local $3) - (tee_local $0 - (i32.wrap/i64 - (i64.shr_u - (get_local $2) - (i64.const 40) - ) - ) - ) - ) - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 255) - ) - ) - ) - (call $prints_l - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - (i32.store8 offset=15 - (get_local $3) - (tee_local $0 - (i32.wrap/i64 - (i64.shr_u - (get_local $2) - (i64.const 48) - ) - ) - ) - ) - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 255) - ) - ) - ) - (call $prints_l - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - (i32.store8 offset=15 - (get_local $3) - (tee_local $0 - (i32.wrap/i64 - (i64.shr_u - (get_local $2) - (i64.const 56) - ) - ) - ) - ) - (br_if $label$1 - (i32.eqz - (get_local $0) - ) - ) - (call $prints_l - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosio12market_state12cover_marginEyRKNS_14extended_assetE (param $0 i32) (param $1 i64) (param $2 i32) - (local $3 i64) - (local $4 i64) - (set_local $4 - (i64.load offset=16 - (get_local $2) - ) - ) - (block $label$0 - (br_if $label$0 - (i64.ne - (tee_local $3 - (i64.load offset=8 - (get_local $2) - ) - ) - (i64.load - (i32.add - (get_local $0) - (i32.const 56) - ) - ) - ) - ) - (br_if $label$0 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - ) - (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE - (get_local $0) - (get_local $1) - (i32.add - (get_local $0) - (i32.const 280) - ) - (i32.add - (get_local $0) - (i32.const 48) - ) - (get_local $2) - ) - (return) - ) - (block $label$1 - (br_if $label$1 - (i64.ne - (get_local $3) - (i64.load - (i32.add - (get_local $0) - (i32.const 152) - ) - ) - ) - ) - (br_if $label$1 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $0) - (i32.const 160) - ) - ) - ) - ) - (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE - (get_local $0) - (get_local $1) - (i32.add - (get_local $0) - (i32.const 320) - ) - (i32.add - (get_local $0) - (i32.const 144) - ) - (get_local $2) - ) - (return) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1376) - ) - ) - (func $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i64) - (local $13 i64) - (local $14 i64) - (local $15 f64) - (local $16 i32) - (local $17 i32) - (local $18 f64) - (local $19 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $19 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 704) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $17 - (i32.load - (i32.add - (get_local $2) - (i32.const 28) - ) - ) - ) - (tee_local $10 - (i32.load offset=24 - (get_local $2) - ) - ) - ) - ) - (set_local $16 - (i32.add - (get_local $17) - (i32.const -24) - ) - ) - (set_local $5 - (i32.sub - (i32.const 0) - (get_local $10) - ) - ) - (loop $label$1 - (br_if $label$0 - (i64.eq - (i64.load - (i32.load - (get_local $16) - ) - ) - (get_local $1) - ) - ) - (set_local $17 - (get_local $16) - ) - (set_local $16 - (tee_local $6 - (i32.add - (get_local $16) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $6) - (get_local $5) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $17) - (get_local $10) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $16 - (i32.load - (i32.add - (get_local $17) - (i32.const -24) - ) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - (br $label$2) - ) - (set_local $16 - (i32.const 0) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $6 - (call $db_find_i64 - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $16 - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $2) - (get_local $6) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - ) - (call $eosio_assert - (tee_local $7 - (i32.ne - (get_local $16) - (i32.const 0) - ) - ) - (i32.const 1408) - ) - (call $eosio_assert - (i64.ge_s - (i64.load offset=8 - (get_local $16) - ) - (i64.load - (get_local $4) - ) - ) - (i32.const 1440) - ) - (drop - (call $memcpy - (i32.add - (get_local $19) - (i32.const 360) - ) - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (i32.const 232) - ) - ) - (i64.store - (tee_local $8 - (i32.add - (i32.add - (get_local $19) - (i32.const 312) - ) - (i32.const 16) - ) - ) - (i64.load - (tee_local $17 - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - ) - (i64.store - (tee_local $9 - (i32.add - (i32.add - (get_local $19) - (i32.const 312) - ) - (i32.const 8) - ) - ) - (i64.load - (tee_local $5 - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - ) - ) - (i64.store offset=312 - (get_local $19) - (i64.load - (get_local $4) - ) - ) - (set_local $14 - (i64.load - (tee_local $10 - (i32.add - (get_local $16) - (i32.const 48) - ) - ) - ) - ) - (i64.store offset=296 - (get_local $19) - (i64.load - (tee_local $11 - (i32.add - (get_local $16) - (i32.const 40) - ) - ) - ) - ) - (i64.store offset=304 - (get_local $19) - (get_local $14) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 120) - ) - (i32.const 16) - ) - (i64.load - (get_local $8) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 120) - ) - (i32.const 8) - ) - (i64.load - (get_local $9) - ) - ) - (i64.store offset=120 - (get_local $19) - (i64.load offset=312 - (get_local $19) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 104) - ) - (i32.const 8) - ) - (i64.load offset=304 - (get_local $19) - ) - ) - (i64.store offset=104 - (get_local $19) - (i64.load offset=296 - (get_local $19) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $19) - (i32.const 336) - ) - (i32.add - (get_local $19) - (i32.const 360) - ) - (i32.add - (get_local $19) - (i32.const 120) - ) - (i32.add - (get_local $19) - (i32.const 104) - ) - ) - (i64.store - (tee_local $8 - (i32.add - (i32.add - (get_local $19) - (i32.const 248) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $19) - (i32.const 336) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (tee_local $9 - (i32.add - (i32.add - (get_local $19) - (i32.const 248) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $19) - (i32.const 336) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=248 - (get_local $19) - (i64.load offset=336 - (get_local $19) - ) - ) - (set_local $14 - (i64.load - (get_local $17) - ) - ) - (i64.store offset=232 - (get_local $19) - (i64.load - (get_local $5) - ) - ) - (i64.store offset=240 - (get_local $19) - (get_local $14) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 80) - ) - (i32.const 16) - ) - (i64.load - (get_local $8) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 80) - ) - (i32.const 8) - ) - (i64.load - (get_local $9) - ) - ) - (i64.store offset=80 - (get_local $19) - (i64.load offset=248 - (get_local $19) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 64) - ) - (i32.const 8) - ) - (i64.load offset=240 - (get_local $19) - ) - ) - (i64.store offset=64 - (get_local $19) - (i64.load offset=232 - (get_local $19) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $19) - (i32.const 272) - ) - (get_local $6) - (i32.add - (get_local $19) - (i32.const 80) - ) - (i32.add - (get_local $19) - (i32.const 64) - ) - ) - (call $eosio_assert - (i64.ge_s - (tee_local $14 - (i64.load offset=272 - (get_local $19) - ) - ) - (i64.load - (get_local $4) - ) - ) - (i32.const 1488) - ) - (call $eosio_assert - (i64.eq - (tee_local $12 - (i64.load offset=288 - (get_local $19) - ) - ) - (i64.load - (get_local $17) - ) - ) - (i32.const 800) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $5) - ) - (tee_local $13 - (i64.load offset=280 - (get_local $19) - ) - ) - ) - (i32.const 816) - ) - (call $eosio_assert - (i64.gt_s - (tee_local $14 - (i64.sub - (get_local $14) - (i64.load - (get_local $4) - ) - ) - ) - (i64.const -4611686018427387904) - ) - (i32.const 864) - ) - (call $eosio_assert - (i64.lt_s - (get_local $14) - (i64.const 4611686018427387904) - ) - (i32.const 896) - ) - (i64.store offset=192 - (get_local $19) - (get_local $13) - ) - (i64.store offset=184 - (get_local $19) - (get_local $14) - ) - (i64.store offset=200 - (get_local $19) - (get_local $12) - ) - (i64.store offset=176 - (get_local $19) - (i64.load - (get_local $10) - ) - ) - (i64.store offset=168 - (get_local $19) - (i64.load - (get_local $11) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 40) - ) - (i32.const 8) - ) - (i64.load offset=192 - (get_local $19) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $19) - (i32.const 40) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (i32.add - (get_local $19) - (i32.const 184) - ) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $19) - (i32.const 40) - ) - (i32.const 16) - ) - (i32.load offset=200 - (get_local $19) - ) - ) - (i64.store offset=40 - (get_local $19) - (i64.load offset=184 - (get_local $19) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $19) - (i32.const 24) - ) - (i32.const 8) - ) - (i64.load offset=176 - (get_local $19) - ) - ) - (i64.store offset=24 - (get_local $19) - (i64.load offset=168 - (get_local $19) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $19) - (i32.const 208) - ) - (get_local $6) - (i32.add - (get_local $19) - (i32.const 40) - ) - (i32.add - (get_local $19) - (i32.const 24) - ) - ) - (i64.store offset=336 - (get_local $19) - (tee_local $14 - (i64.sub - (i64.load offset=336 - (get_local $19) - ) - (i64.load offset=208 - (get_local $19) - ) - ) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.ne - (i64.load offset=8 - (get_local $16) - ) - (i64.load - (get_local $4) - ) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $10) - ) - (i64.load offset=352 - (get_local $19) - ) - ) - (i32.const 800) - ) - (set_local $13 - (i64.load offset=32 - (get_local $16) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=344 - (get_local $19) - ) - (tee_local $12 - (i64.load - (get_local $11) - ) - ) - ) - (i32.const 816) - ) - (call $eosio_assert - (i64.gt_s - (tee_local $14 - (i64.sub - (get_local $13) - (get_local $14) - ) - ) - (i64.const -4611686018427387904) - ) - (i32.const 864) - ) - (call $eosio_assert - (i64.lt_s - (get_local $14) - (i64.const 4611686018427387904) - ) - (i32.const 896) - ) - (set_local $13 - (i64.load - (get_local $10) - ) - ) - (call $eosio_assert - (get_local $7) - (i32.const 928) - ) - (call $eosio_assert - (get_local $7) - (i32.const 1152) - ) - (block $label$6 - (br_if $label$6 - (i32.lt_s - (tee_local $6 - (call $db_next_i64 - (i32.load offset=68 - (get_local $16) - ) - (i32.add - (get_local $19) - (i32.const 592) - ) - ) - ) - (i32.const 0) - ) - ) - (drop - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $2) - (get_local $6) - ) - ) - ) - (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ - (get_local $2) - (get_local $16) - ) - (set_local $16 - (i32.const 0) - ) - (block $label$7 - (br_if $label$7 - (i32.lt_s - (tee_local $6 - (call $db_lowerbound_i64 - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (i64.const 0) - ) - ) - (i32.const 0) - ) - ) - (set_local $16 - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $2) - (get_local $6) - ) - ) - ) - (i64.store offset=152 - (get_local $19) - (get_local $12) - ) - (set_local $6 - (i32.load offset=440 - (get_local $0) - ) - ) - (i64.store - (i32.add - (get_local $19) - (i32.const 8) - ) - (get_local $12) - ) - (i64.store offset=160 - (get_local $19) - (get_local $13) - ) - (i64.store - (i32.add - (get_local $19) - (i32.const 16) - ) - (get_local $13) - ) - (i64.store offset=144 - (get_local $19) - (get_local $14) - ) - (i64.store - (get_local $19) - (get_local $14) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $6) - (get_local $1) - (get_local $19) - (get_local $19) - ) - (br $label$4) - ) - (call $eosio_assert - (get_local $7) - (i32.const 352) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (get_local $16) - ) - (get_local $2) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $2) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (i64.store offset=32 - (get_local $16) - (tee_local $14 - (i64.sub - (i64.load offset=32 - (get_local $16) - ) - (get_local $14) - ) - ) - ) - (i64.store offset=680 - (get_local $19) - (i64.trunc_u/f64 - (f64.mul - (f64.load - (tee_local $6 - (i32.add - (get_local $16) - (i32.const 56) - ) - ) - ) - (f64.const 1e6) - ) - ) - ) - (set_local $1 - (i64.load - (get_local $16) - ) - ) - (i64.store offset=8 - (get_local $16) - (tee_local $12 - (i64.sub - (i64.load offset=8 - (get_local $16) - ) - (i64.load - (get_local $4) - ) - ) - ) - ) - (f64.store - (get_local $6) - (f64.div - (f64.convert_s/i64 - (get_local $12) - ) - (f64.convert_s/i64 - (get_local $14) - ) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 544) - ) - (i32.store offset=672 - (get_local $19) - (i32.add - (i32.add - (get_local $19) - (i32.const 592) - ) - (i32.const 64) - ) - ) - (i32.store offset=668 - (get_local $19) - (i32.add - (get_local $19) - (i32.const 592) - ) - ) - (i32.store offset=664 - (get_local $19) - (i32.add - (get_local $19) - (i32.const 592) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE - (i32.add - (get_local $19) - (i32.const 664) - ) - (get_local $16) - ) - ) - (call $db_update_i64 - (i32.load offset=68 - (get_local $16) - ) - (i64.const 0) - (i32.add - (get_local $19) - (i32.const 592) - ) - (i32.const 64) - ) - (block $label$8 - (br_if $label$8 - (i64.lt_u - (get_local $1) - (i64.load offset=16 - (get_local $2) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (select - (i64.const -2) - (i64.add - (get_local $1) - (i64.const 1) - ) - (i64.gt_u - (get_local $1) - (i64.const -3) - ) - ) - ) - ) - (i64.store offset=696 - (get_local $19) - (i64.trunc_u/f64 - (f64.mul - (f64.load - (get_local $6) - ) - (f64.const 1e6) - ) - ) - ) - (br_if $label$4 - (i32.eqz - (call $memcmp - (i32.add - (get_local $19) - (i32.const 680) - ) - (i32.add - (get_local $19) - (i32.const 696) - ) - (i32.const 8) - ) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.gt_s - (tee_local $6 - (i32.load - (tee_local $17 - (i32.add - (get_local $16) - (i32.const 72) - ) - ) - ) - ) - (i32.const -1) - ) - ) - (i32.store - (get_local $17) - (tee_local $6 - (call $db_idx64_find_primary - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (i32.add - (get_local $19) - (i32.const 688) - ) - (get_local $1) - ) - ) - ) - ) - (call $db_idx64_update - (get_local $6) - (i64.const 0) - (i32.add - (get_local $19) - (i32.const 696) - ) - ) - ) - (i64.store - (tee_local $6 - (i32.add - (get_local $3) - (i32.const 56) - ) - ) - (i64.sub - (i64.load - (get_local $6) - ) - (i64.load - (get_local $4) - ) - ) - ) - (block $label$10 - (block $label$11 - (block $label$12 - (br_if $label$12 - (i32.eqz - (get_local $16) - ) - ) - (br_if $label$11 - (i32.eqz - (i32.or - (f64.ge - (tee_local $18 - (f64.load offset=56 - (get_local $16) - ) - ) - (tee_local $15 - (f64.load - (tee_local $16 - (i32.add - (get_local $3) - (i32.const 80) - ) - ) - ) - ) - ) - (i32.or - (f64.ne - (get_local $18) - (get_local $18) - ) - (f64.ne - (get_local $15) - (get_local $15) - ) - ) - ) - ) - ) - (br $label$10) - ) - (set_local $16 - (i32.add - (get_local $3) - (i32.const 80) - ) - ) - (set_local $18 - (f64.const 1797693134862315708145274e284) - ) - ) - (f64.store - (get_local $16) - (get_local $18) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $19) - (i32.const 704) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 40) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 48) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 56) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio12market_state13update_marginEyRKNS_14extended_assetES3_ (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) - (local $4 i64) - (local $5 i64) - (set_local $5 - (i64.load offset=16 - (get_local $2) - ) - ) - (block $label$0 - (br_if $label$0 - (i64.ne - (tee_local $4 - (i64.load offset=8 - (get_local $2) - ) - ) - (i64.load - (i32.add - (get_local $0) - (i32.const 56) - ) - ) - ) - ) - (br_if $label$0 - (i64.ne - (get_local $5) - (i64.load - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - ) - (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ - (get_local $0) - (get_local $1) - (i32.add - (get_local $0) - (i32.const 280) - ) - (i32.add - (get_local $0) - (i32.const 48) - ) - (get_local $2) - (get_local $3) - ) - (return) - ) - (block $label$1 - (br_if $label$1 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $0) - (i32.const 152) - ) - ) - ) - ) - (br_if $label$1 - (i64.ne - (get_local $5) - (i64.load - (i32.add - (get_local $0) - (i32.const 160) - ) - ) - ) - ) - (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ - (get_local $0) - (get_local $1) - (i32.add - (get_local $0) - (i32.const 320) - ) - (i32.add - (get_local $0) - (i32.const 144) - ) - (get_local $2) - (get_local $3) - ) - (return) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1376) - ) - ) - (func $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i64) - (local $10 f64) - (local $11 i64) - (local $12 f64) - (local $13 i32) - (local $14 i32) - (local $15 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $15 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $14 - (i32.load - (i32.add - (get_local $2) - (i32.const 28) - ) - ) - ) - (tee_local $6 - (i32.load offset=24 - (get_local $2) - ) - ) - ) - ) - (set_local $13 - (i32.add - (get_local $14) - (i32.const -24) - ) - ) - (set_local $7 - (i32.sub - (i32.const 0) - (get_local $6) - ) - ) - (loop $label$1 - (br_if $label$0 - (i64.eq - (i64.load - (i32.load - (get_local $13) - ) - ) - (get_local $1) - ) - ) - (set_local $14 - (get_local $13) - ) - (set_local $13 - (tee_local $8 - (i32.add - (get_local $13) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $8) - (get_local $7) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.eq - (get_local $14) - (get_local $6) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $8 - (i32.load - (i32.add - (get_local $14) - (i32.const -24) - ) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - (br_if $label$7 - (get_local $8) - ) - (br $label$6) - ) - (br_if $label$6 - (i32.lt_s - (tee_local $13 - (call $db_find_i64 - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (tee_local $8 - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $2) - (get_local $13) - ) - ) - ) - (get_local $2) - ) - (i32.const 224) - ) - ) - (br_if $label$5 - (i64.ne - (i64.load offset=8 - (get_local $8) - ) - (i64.sub - (i64.const 0) - (i64.load - (get_local $4) - ) - ) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=32 - (get_local $8) - ) - (i64.sub - (i64.const 0) - (i64.load - (get_local $5) - ) - ) - ) - (i32.const 1584) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 928) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1152) - ) - (set_local $13 - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.lt_s - (tee_local $14 - (call $db_next_i64 - (i32.load offset=68 - (get_local $8) - ) - (get_local $15) - ) - ) - (i32.const 0) - ) - ) - (drop - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $2) - (get_local $14) - ) - ) - ) - (call $_ZN5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE5eraseERKS1_ - (get_local $2) - (get_local $8) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $8 - (call $db_lowerbound_i64 - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (i64.const 0) - ) - ) - (i32.const 0) - ) - ) - (set_local $13 - (call $_ZNK5eosio11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS1_yXadL_ZNKS1_8get_callEvEEEEEEEE31load_object_by_primary_iteratorEl - (get_local $2) - (get_local $8) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i64.gt_s - (i64.load - (get_local $4) - ) - (i64.const 0) - ) - (i32.const 1520) - ) - (call $eosio_assert - (i64.gt_s - (i64.load - (get_local $5) - ) - (i64.const 0) - ) - (i32.const 1552) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $2) - ) - (call $current_receiver) - ) - (i32.const 288) - ) - (set_local $8 - (call $_ZN5eosio15margin_positionC2Ev - (tee_local $13 - (call $_Znwj - (i32.const 80) - ) - ) - ) - ) - (i32.store offset=64 - (get_local $13) - (get_local $2) - ) - (i64.store - (get_local $13) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $13) - (i32.const 28) - ) - (i32.load - (i32.add - (get_local $4) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (get_local $13) - (i32.const 24) - ) - (i32.load - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $13) - (i32.const 20) - ) - (i32.load - (i32.add - (get_local $4) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $13) - (i32.const 16) - ) - (i32.load - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - ) - (i32.store - (i32.add - (get_local $13) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $4) - (i32.const 4) - ) - ) - ) - (i32.store offset=8 - (get_local $13) - (i32.load - (get_local $4) - ) - ) - (i64.store - (i32.add - (get_local $13) - (i32.const 48) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $13) - (i32.const 40) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i64.store offset=32 - (get_local $13) - (i64.load - (get_local $5) - ) - ) - (f64.store offset=56 - (get_local $13) - (f64.div - (f64.convert_s/i64 - (i64.load offset=8 - (get_local $13) - ) - ) - (f64.convert_s/i64 - (i64.load offset=32 - (get_local $13) - ) - ) - ) - ) - (i32.store offset=80 - (get_local $15) - (i32.add - (get_local $15) - (i32.const 64) - ) - ) - (i32.store offset=76 - (get_local $15) - (get_local $15) - ) - (i32.store offset=72 - (get_local $15) - (get_local $15) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE - (i32.add - (get_local $15) - (i32.const 72) - ) - (get_local $8) - ) - ) - (i32.store offset=68 - (get_local $13) - (call $db_store_i64 - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (get_local $1) - (tee_local $9 - (i64.load - (get_local $13) - ) - ) - (get_local $15) - (i32.const 64) - ) - ) - (block $label$10 - (br_if $label$10 - (i64.lt_u - (get_local $9) - (i64.load offset=16 - (get_local $2) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (select - (i64.const -2) - (i64.add - (get_local $9) - (i64.const 1) - ) - (i64.gt_u - (get_local $9) - (i64.const -3) - ) - ) - ) - ) - (set_local $9 - (i64.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (set_local $11 - (i64.load - (get_local $13) - ) - ) - (i64.store offset=104 - (get_local $15) - (i64.trunc_u/f64 - (f64.mul - (f64.load - (i32.add - (get_local $13) - (i32.const 56) - ) - ) - (f64.const 1e6) - ) - ) - ) - (i32.store offset=72 - (get_local $13) - (call $db_idx64_store - (get_local $9) - (i64.const -7949197150146002944) - (get_local $1) - (get_local $11) - (i32.add - (get_local $15) - (i32.const 104) - ) - ) - ) - (i32.store offset=72 - (get_local $15) - (get_local $13) - ) - (i64.store - (get_local $15) - (tee_local $1 - (i64.load - (get_local $13) - ) - ) - ) - (i32.store offset=104 - (get_local $15) - (tee_local $14 - (i32.load - (i32.add - (get_local $13) - (i32.const 68) - ) - ) - ) - ) - (br_if $label$4 - (i32.ge_u - (tee_local $8 - (i32.load - (i32.add - (get_local $2) - (i32.const 28) - ) - ) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $8) - (get_local $1) - ) - (i32.store offset=16 - (get_local $8) - (get_local $14) - ) - (i32.store offset=72 - (get_local $15) - (i32.const 0) - ) - (i32.store - (get_local $8) - (get_local $13) - ) - (i32.store - (i32.add - (get_local $2) - (i32.const 28) - ) - (i32.add - (get_local $8) - (i32.const 24) - ) - ) - (br $label$3) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 352) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=64 - (get_local $8) - ) - (get_local $2) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $2) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (i64.store offset=88 - (get_local $15) - (i64.trunc_u/f64 - (f64.mul - (f64.load - (tee_local $13 - (i32.add - (get_local $8) - (i32.const 56) - ) - ) - ) - (f64.const 1e6) - ) - ) - ) - (set_local $1 - (i64.load - (get_local $8) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $4) - ) - (i64.load - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - (i32.const 1632) - ) - (i64.store offset=8 - (get_local $8) - (tee_local $9 - (i64.add - (i64.load offset=8 - (get_local $8) - ) - (i64.load - (get_local $4) - ) - ) - ) - ) - (call $eosio_assert - (i64.gt_s - (get_local $9) - (i64.const -4611686018427387904) - ) - (i32.const 1680) - ) - (call $eosio_assert - (i64.lt_s - (i64.load offset=8 - (get_local $8) - ) - (i64.const 4611686018427387904) - ) - (i32.const 1712) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $5) - ) - (i64.load - (i32.add - (get_local $8) - (i32.const 40) - ) - ) - ) - (i32.const 1632) - ) - (i64.store offset=32 - (get_local $8) - (tee_local $9 - (i64.add - (i64.load offset=32 - (get_local $8) - ) - (i64.load - (get_local $5) - ) - ) - ) - ) - (call $eosio_assert - (i64.gt_s - (get_local $9) - (i64.const -4611686018427387904) - ) - (i32.const 1680) - ) - (call $eosio_assert - (i64.lt_s - (i64.load offset=32 - (get_local $8) - ) - (i64.const 4611686018427387904) - ) - (i32.const 1712) - ) - (f64.store - (get_local $13) - (f64.div - (f64.convert_s/i64 - (i64.load offset=8 - (get_local $8) - ) - ) - (f64.convert_s/i64 - (i64.load offset=32 - (get_local $8) - ) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (i64.load - (get_local $8) - ) - ) - (i32.const 544) - ) - (i32.store offset=80 - (get_local $15) - (i32.add - (get_local $15) - (i32.const 64) - ) - ) - (i32.store offset=76 - (get_local $15) - (get_local $15) - ) - (i32.store offset=72 - (get_local $15) - (get_local $15) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_15margin_positionE - (i32.add - (get_local $15) - (i32.const 72) - ) - (get_local $8) - ) - ) - (call $db_update_i64 - (i32.load offset=68 - (get_local $8) - ) - (i64.const 0) - (get_local $15) - (i32.const 64) - ) - (block $label$11 - (br_if $label$11 - (i64.lt_u - (get_local $1) - (i64.load offset=16 - (get_local $2) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (select - (i64.const -2) - (i64.add - (get_local $1) - (i64.const 1) - ) - (i64.gt_u - (get_local $1) - (i64.const -3) - ) - ) - ) - ) - (i64.store offset=104 - (get_local $15) - (i64.trunc_u/f64 - (f64.mul - (f64.load - (get_local $13) - ) - (f64.const 1e6) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (call $memcmp - (i32.add - (get_local $15) - (i32.const 88) - ) - (i32.add - (get_local $15) - (i32.const 104) - ) - (i32.const 8) - ) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.gt_s - (tee_local $13 - (i32.load - (tee_local $14 - (i32.add - (get_local $8) - (i32.const 72) - ) - ) - ) - ) - (i32.const -1) - ) - ) - (i32.store - (get_local $14) - (tee_local $13 - (call $db_idx64_find_primary - (i64.load - (get_local $2) - ) - (i64.load offset=8 - (get_local $2) - ) - (i64.const -7949197150146002944) - (i32.add - (get_local $15) - (i32.const 96) - ) - (get_local $1) - ) - ) - ) - ) - (call $db_idx64_update - (get_local $13) - (i64.const 0) - (i32.add - (get_local $15) - (i32.const 104) - ) - ) - ) - (set_local $13 - (get_local $8) - ) - (br $label$2) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497546923563548672ENS1_15margin_positionEJNS1_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS3_yXadL_ZNKS3_8get_callEvEEEEEEEE8item_ptrENS_9allocatorISB_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINSA_4itemENS_14default_deleteISH_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $2) - (i32.const 24) - ) - (i32.add - (get_local $15) - (i32.const 72) - ) - (get_local $15) - (i32.add - (get_local $15) - (i32.const 104) - ) - ) - ) - (set_local $8 - (i32.load offset=72 - (get_local $15) - ) - ) - (i32.store offset=72 - (get_local $15) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $8) - ) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $4) - ) - (i64.load - (i32.add - (get_local $3) - (i32.const 64) - ) - ) - ) - (i32.const 1632) - ) - (i64.store - (tee_local $8 - (i32.add - (get_local $3) - (i32.const 56) - ) - ) - (tee_local $1 - (i64.add - (i64.load - (get_local $8) - ) - (i64.load - (get_local $4) - ) - ) - ) - ) - (call $eosio_assert - (i64.gt_s - (get_local $1) - (i64.const -4611686018427387904) - ) - (i32.const 1680) - ) - (call $eosio_assert - (i64.lt_s - (i64.load - (get_local $8) - ) - (i64.const 4611686018427387904) - ) - (i32.const 1712) - ) - (call $eosio_assert - (i64.le_s - (i64.load - (get_local $8) - ) - (i64.load offset=32 - (get_local $3) - ) - ) - (i32.const 1744) - ) - (block $label$14 - (block $label$15 - (br_if $label$15 - (i32.eqz - (get_local $13) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.or - (f64.ge - (tee_local $10 - (f64.load offset=56 - (get_local $13) - ) - ) - (tee_local $12 - (f64.load - (tee_local $13 - (i32.add - (get_local $3) - (i32.const 80) - ) - ) - ) - ) - ) - (i32.or - (f64.ne - (get_local $10) - (get_local $10) - ) - (f64.ne - (get_local $12) - (get_local $12) - ) - ) - ) - ) - (f64.store - (get_local $13) - (get_local $10) - ) - ) - (call $eosio_assert - (i32.xor - (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $3) - ) - (i32.const 1) - ) - (i32.const 1792) - ) - (br $label$14) - ) - (i64.store - (i32.add - (get_local $3) - (i32.const 80) - ) - (i64.const 9218868437227405311) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $15) - (i32.const 112) - ) - ) - ) - (func $_ZN5eosio12market_state4saveEv (param $0 i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 240) - ) - ) - ) - (call $eosio_assert - (i32.ne - (tee_local $2 - (i32.load - (i32.add - (get_local $0) - (i32.const 448) - ) - ) - ) - (i32.const 0) - ) - (i32.const 352) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=232 - (get_local $2) - ) - (i32.add - (get_local $0) - (i32.const 240) - ) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=240 - (get_local $0) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (set_local $1 - (i64.load - (tee_local $3 - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - ) - (drop - (call $memcpy - (get_local $2) - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.const 232) - ) - ) - (call $eosio_assert - (i64.eq - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.shr_u - (i64.load - (get_local $3) - ) - (i64.const 8) - ) - ) - (i32.const 544) - ) - (i32.store offset=232 - (get_local $4) - (i32.add - (get_local $4) - (i32.const 220) - ) - ) - (i32.store offset=228 - (get_local $4) - (get_local $4) - ) - (i32.store offset=224 - (get_local $4) - (get_local $4) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_stateE - (i32.add - (get_local $4) - (i32.const 224) - ) - (get_local $2) - ) - ) - (call $db_update_i64 - (i32.load offset=236 - (get_local $2) - ) - (i64.const 0) - (get_local $4) - (i32.const 220) - ) - (block $label$0 - (br_if $label$0 - (i64.lt_u - (get_local $1) - (i64.load - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 256) - ) - ) - ) - ) - ) - (i64.store - (get_local $0) - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $4) - (i32.const 240) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_stateE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 3) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_state9connectorE - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_state9connectorE - (get_local $0) - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (i32.add - (get_local $1) - (i32.const 136) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_state9connectorE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 3) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 40) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 48) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 56) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 64) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 72) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 80) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 88) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio8exchange7depositEyNS_14extended_assetE (type $FUNCSIG$viji) (param $0 i32) (param $1 i64) (param $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 128) - ) - ) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (i64.load - (get_local $2) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $8 - (i64.shr_u - (i64.load offset=8 - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $6 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $8) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $4 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $4 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $4) - (i32.const 1840) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 16) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 8) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i32.store offset=108 - (get_local $11) - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (i32.store offset=104 - (get_local $11) - (i32.load - (get_local $2) - ) - ) - (set_local $3 - (i64.load - (get_local $0) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=88 - (get_local $11) - (i64.const 0) - ) - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.ge_u - (tee_local $6 - (call $strlen - (i32.const 1872) - ) - ) - (i32.const -16) - ) - ) - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.ge_u - (get_local $6) - (i32.const 11) - ) - ) - (i32.store8 offset=88 - (get_local $11) - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (set_local $4 - (i32.or - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.const 1) - ) - ) - (br_if $label$8 - (get_local $6) - ) - (br $label$7) - ) - (set_local $4 - (call $_Znwj - (tee_local $5 - (i32.and - (i32.add - (get_local $6) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=88 - (get_local $11) - (i32.or - (get_local $5) - (i32.const 1) - ) - ) - (i32.store offset=96 - (get_local $11) - (get_local $4) - ) - (i32.store offset=92 - (get_local $11) - (get_local $6) - ) - ) - (drop - (call $memcpy - (get_local $4) - (i32.const 1872) - (get_local $6) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $4) - (get_local $6) - ) - (i32.const 0) - ) - (set_local $8 - (i64.const 0) - ) - (set_local $7 - (i64.const 59) - ) - (set_local $6 - (i32.const 1888) - ) - (set_local $9 - (i64.const 0) - ) - (loop $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_if $label$15 - (i64.gt_u - (get_local $8) - (i64.const 5) - ) - ) - (br_if $label$14 - (i32.gt_u - (i32.and - (i32.add - (tee_local $4 - (i32.load8_s - (get_local $6) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 165) - ) - ) - (br $label$13) - ) - (set_local $10 - (i64.const 0) - ) - (br_if $label$12 - (i64.le_u - (get_local $8) - (i64.const 11) - ) - ) - (br $label$11) - ) - (set_local $4 - (select - (i32.add - (get_local $4) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $4) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $10 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $4) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $10 - (i64.shl - (i64.and - (get_local $10) - (i64.const 31) - ) - (i64.and - (get_local $7) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (set_local $8 - (i64.add - (get_local $8) - (i64.const 1) - ) - ) - (set_local $9 - (i64.or - (get_local $10) - (get_local $9) - ) - ) - (br_if $label$10 - (i64.ne - (tee_local $7 - (i64.add - (get_local $7) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=24 - (get_local $11) - (i64.load offset=104 - (get_local $11) - ) - ) - (call $_ZN5eosio8currency15inline_transferEyyNS_14extended_assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy - (get_local $1) - (get_local $3) - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.add - (get_local $11) - (i32.const 88) - ) - (get_local $9) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (i32.and - (i32.load8_u offset=88 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=96 - (get_local $11) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i64.store offset=64 - (get_local $11) - (i64.load - (get_local $2) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 48) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=48 - (get_local $11) - (i64.const 0) - ) - (br_if $label$5 - (i32.ge_u - (tee_local $6 - (call $strlen - (i32.const 1872) - ) - ) - (i32.const -16) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (block $label$17 - (block $label$18 - (block $label$19 - (br_if $label$19 - (i32.ge_u - (get_local $6) - (i32.const 11) - ) - ) - (i32.store8 offset=48 - (get_local $11) - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (set_local $4 - (i32.or - (i32.add - (get_local $11) - (i32.const 48) - ) - (i32.const 1) - ) - ) - (br_if $label$18 - (get_local $6) - ) - (br $label$17) - ) - (set_local $4 - (call $_Znwj - (tee_local $0 - (i32.and - (i32.add - (get_local $6) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=48 - (get_local $11) - (i32.or - (get_local $0) - (i32.const 1) - ) - ) - (i32.store offset=56 - (get_local $11) - (get_local $4) - ) - (i32.store offset=52 - (get_local $11) - (get_local $6) - ) - ) - (drop - (call $memcpy - (get_local $4) - (i32.const 1872) - (get_local $6) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $4) - (get_local $6) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 8) - ) - ) - ) - (i64.store - (get_local $11) - (i64.load offset=64 - (get_local $11) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $2) - (get_local $1) - (get_local $11) - (get_local $6) - ) - (block $label$20 - (br_if $label$20 - (i32.eqz - (i32.and - (i32.load8_u offset=48 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=56 - (get_local $11) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 128) - ) - ) - (return) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $11) - (i32.const 88) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $11) - (i32.const 48) - ) - ) - (unreachable) - ) - (func $_ZN5eosio8currency15inline_transferEyyNS_14extended_assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy (param $0 i64) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i64) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i64) - (local $12 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $12 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (set_local $5 - (i64.load offset=16 - (get_local $2) - ) - ) - (set_local $9 - (i64.const 0) - ) - (set_local $8 - (i64.const 59) - ) - (set_local $7 - (i32.const 1904) - ) - (set_local $10 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $9) - (i64.const 7) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $6 - (i32.load8_s - (get_local $7) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $11 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $9) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $6 - (select - (i32.add - (get_local $6) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $6) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $11 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $6) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $11 - (i64.shl - (i64.and - (get_local $11) - (i64.const 31) - ) - (i64.and - (get_local $8) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (set_local $9 - (i64.add - (get_local $9) - (i64.const 1) - ) - ) - (set_local $10 - (i64.or - (get_local $11) - (get_local $10) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $8 - (i64.add - (get_local $8) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 28) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 24) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (i64.store offset=16 - (get_local $12) - (get_local $1) - ) - (i64.store offset=8 - (get_local $12) - (get_local $0) - ) - (i32.store offset=24 - (get_local $12) - (i32.load - (get_local $2) - ) - ) - (drop - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 32) - ) - (get_local $3) - ) - ) - (i64.store offset=64 - (get_local $12) - (get_local $10) - ) - (i64.store offset=56 - (get_local $12) - (get_local $5) - ) - (i64.store - (tee_local $7 - (call $_Znwj - (i32.const 16) - ) - ) - (get_local $0) - ) - (i64.store offset=8 - (get_local $7) - (get_local $4) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 32) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 24) - ) - (tee_local $6 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 20) - ) - (get_local $6) - ) - (i32.store offset=72 - (get_local $12) - (get_local $7) - ) - (i32.store offset=84 - (get_local $12) - (i32.const 0) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 36) - ) - (i32.const 0) - ) - (set_local $7 - (i32.add - (tee_local $6 - (select - (i32.load - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 36) - ) - ) - (i32.shr_u - (tee_local $7 - (i32.load8_u offset=40 - (get_local $12) - ) - ) - (i32.const 1) - ) - (i32.and - (get_local $7) - (i32.const 1) - ) - ) - ) - (i32.const 32) - ) - ) - (set_local $9 - (i64.extend_u/i32 - (get_local $6) - ) - ) - (set_local $6 - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 28) - ) - ) - (loop $label$6 - (set_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $9 - (i64.shr_u - (get_local $9) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.eqz - (get_local $7) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $6) - (get_local $7) - ) - (set_local $6 - (i32.load - (i32.add - (get_local $12) - (i32.const 88) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $12) - (i32.const 84) - ) - ) - ) - (br $label$7) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $7 - (i32.const 0) - ) - ) - (i32.store offset=100 - (get_local $12) - (get_local $7) - ) - (i32.store offset=96 - (get_local $12) - (get_local $7) - ) - (i32.store offset=104 - (get_local $12) - (get_local $6) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency8transferE - (i32.add - (get_local $12) - (i32.const 96) - ) - (i32.add - (get_local $12) - (i32.const 8) - ) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (i32.and - (i32.load8_u - (i32.add - (get_local $12) - (i32.const 40) - ) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $12) - (i32.const 48) - ) - ) - ) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.add - (get_local $12) - (i32.const 56) - ) - ) - (call $send_inline - (tee_local $7 - (i32.load offset=8 - (get_local $12) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $12) - ) - (get_local $7) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $7 - (i32.load offset=8 - (get_local $12) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $12) - (get_local $7) - ) - (call $_ZdlPv - (get_local $7) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (tee_local $7 - (i32.load offset=84 - (get_local $12) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 88) - ) - (get_local $7) - ) - (call $_ZdlPv - (get_local $7) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $7 - (i32.load offset=72 - (get_local $12) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 76) - ) - (get_local $7) - ) - (call $_ZdlPv - (get_local $7) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $12) - (i32.const 112) - ) - ) - ) - (func $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (i32.sub - (tee_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (get_local $1) - ) - ) - (br_if $label$2 - (i32.le_s - (tee_local $4 - (i32.add - (tee_local $3 - (i32.sub - (get_local $6) - (tee_local $5 - (i32.load - (get_local $0) - ) - ) - ) - ) - (get_local $1) - ) - ) - (i32.const -1) - ) - ) - (set_local $6 - (i32.const 2147483647) - ) - (block $label$5 - (br_if $label$5 - (i32.gt_u - (tee_local $2 - (i32.sub - (get_local $2) - (get_local $5) - ) - ) - (i32.const 1073741822) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $6 - (select - (get_local $4) - (tee_local $6 - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $6) - (get_local $4) - ) - ) - ) - ) - ) - ) - (set_local $2 - (call $_Znwj - (get_local $6) - ) - ) - (br $label$1) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$6 - (i32.store8 - (get_local $6) - (i32.const 0) - ) - (i32.store - (get_local $0) - (tee_local $6 - (i32.add - (i32.load - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$6 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - (br $label$0) - ) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $2 - (i32.const 0) - ) - (br $label$1) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $4 - (i32.add - (get_local $2) - (get_local $6) - ) - ) - (set_local $6 - (tee_local $5 - (i32.add - (get_local $2) - (get_local $3) - ) - ) - ) - (loop $label$7 - (i32.store8 - (get_local $6) - (i32.const 0) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$7 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - ) - (set_local $5 - (i32.sub - (get_local $5) - (tee_local $2 - (i32.sub - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $1 - (i32.load - (get_local $0) - ) - ) - ) - ) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.lt_s - (get_local $2) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $1) - (get_local $2) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $5) - ) - (i32.store - (get_local $3) - (get_local $6) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - (return) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency8transferE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE - (get_local $0) - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - (func $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=8 - (get_local $0) - (i32.const 0) - ) - (i64.store align=4 - (get_local $0) - (i64.const 0) - ) - (set_local $5 - (i32.const 16) - ) - (set_local $2 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - (set_local $6 - (i64.extend_u/i32 - (i32.shr_s - (tee_local $4 - (i32.sub - (tee_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - ) - (tee_local $3 - (i32.load offset=16 - (get_local $1) - ) - ) - ) - ) - (i32.const 4) - ) - ) - ) - (loop $label$0 - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $3) - (get_local $7) - ) - ) - (set_local $5 - (i32.add - (i32.and - (get_local $4) - (i32.const -16) - ) - (get_local $5) - ) - ) - ) - (set_local $5 - (i32.sub - (i32.sub - (tee_local $7 - (i32.load offset=28 - (get_local $1) - ) - ) - (get_local $5) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - (set_local $6 - (i64.extend_u/i32 - (i32.sub - (get_local $3) - (get_local $7) - ) - ) - ) - (loop $label$2 - (set_local $5 - (i32.add - (get_local $5) - (i32.const -1) - ) - ) - (br_if $label$2 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (set_local $7 - (i32.const 0) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.eqz - (get_local $5) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $0) - (i32.sub - (i32.const 0) - (get_local $5) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $5 - (i32.load - (get_local $0) - ) - ) - (br $label$3) - ) - (set_local $5 - (i32.const 0) - ) - ) - (i32.store - (get_local $8) - (get_local $5) - ) - (i32.store offset=8 - (get_local $8) - (get_local $7) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $7) - (get_local $5) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $1) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $7) - (tee_local $0 - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (get_local $0) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $8) - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE - (call $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE - (get_local $8) - (get_local $2) - ) - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $4 - (i64.extend_u/i32 - (i32.shr_s - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - (i32.const 4) - ) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$0 - (set_local $3 - (i32.wrap/i64 - (get_local $4) - ) - ) - (i32.store8 offset=15 - (get_local $7) - (i32.or - (i32.shl - (tee_local $6 - (i64.ne - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $3) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $5) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $6) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $6 - (i32.load - (get_local $1) - ) - ) - (tee_local $1 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$2 - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $5) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $3) - ) - (get_local $6) - (i32.const 8) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $5) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $3) - ) - (i32.add - (get_local $6) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (br_if $label$2 - (i32.ne - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $7 - (i64.extend_u/i32 - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $2 - (i32.wrap/i64 - (get_local $7) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $3 - (i64.ne - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $2) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $5) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $5) - (tee_local $6 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $3) - ) - ) - (call $eosio_assert - (i32.ge_s - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $6) - ) - (tee_local $5 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - ) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (get_local $2) - (get_local $5) - ) - ) - (i32.store - (get_local $6) - (i32.add - (i32.load - (get_local $6) - ) - (get_local $5) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $7 - (i64.extend_u/i32 - (select - (i32.load offset=4 - (get_local $1) - ) - (i32.shr_u - (tee_local $5 - (i32.load8_u - (get_local $1) - ) - ) - (i32.const 1) - ) - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $2 - (i32.wrap/i64 - (get_local $7) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $3 - (i64.ne - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $2) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (get_local $5) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $5) - (tee_local $6 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $3) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $5 - (select - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (i32.shr_u - (tee_local $5 - (i32.load8_u - (get_local $1) - ) - ) - (i32.const 1) - ) - (tee_local $2 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (set_local $3 - (i32.load offset=8 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.ge_s - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $6) - ) - (get_local $5) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (select - (get_local $3) - (i32.add - (get_local $1) - (i32.const 1) - ) - (get_local $2) - ) - (get_local $5) - ) - ) - (i32.store - (get_local $6) - (i32.add - (i32.load - (get_local $6) - ) - (get_local $5) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio8exchange8withdrawEyNS_14extended_assetE (type $FUNCSIG$viji) (param $0 i32) (param $1 i64) (param $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (call $require_auth - (get_local $1) - ) - (set_local $9 - (i64.load offset=8 - (get_local $2) - ) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (tee_local $6 - (i64.load - (get_local $2) - ) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $7 - (i64.shr_u - (get_local $9) - (i64.const 8) - ) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $7) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $4 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $4 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $4) - (i32.const 1840) - ) - (call $eosio_assert - (i32.xor - (i32.wrap/i64 - (i64.shr_u - (get_local $6) - (i64.const 63) - ) - ) - (i32.const 1) - ) - (i32.const 1920) - ) - (i64.store offset=96 - (get_local $10) - (get_local $9) - ) - (set_local $7 - (i64.load offset=16 - (get_local $2) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.const 8) - ) - (get_local $9) - ) - (i64.store offset=104 - (get_local $10) - (get_local $7) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.const 16) - ) - (get_local $7) - ) - (i64.store offset=88 - (get_local $10) - (tee_local $7 - (i64.sub - (i64.const 0) - (get_local $6) - ) - ) - ) - (i64.store offset=24 - (get_local $10) - (get_local $7) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (i32.add - (get_local $0) - (i32.const 16) - ) - (get_local $1) - (i32.add - (get_local $10) - (i32.const 24) - ) - (get_local $5) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 16) - ) - (i32.load offset=16 - (get_local $2) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 8) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i32.store offset=68 - (get_local $10) - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (i32.store offset=64 - (get_local $10) - (i32.load - (get_local $2) - ) - ) - (set_local $3 - (i64.load - (get_local $0) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 48) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=48 - (get_local $10) - (i64.const 0) - ) - (block $label$5 - (br_if $label$5 - (i32.ge_u - (tee_local $5 - (call $strlen - (i32.const 1968) - ) - ) - (i32.const -16) - ) - ) - (block $label$6 - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ge_u - (get_local $5) - (i32.const 11) - ) - ) - (i32.store8 offset=48 - (get_local $10) - (i32.shl - (get_local $5) - (i32.const 1) - ) - ) - (set_local $2 - (i32.or - (i32.add - (get_local $10) - (i32.const 48) - ) - (i32.const 1) - ) - ) - (br_if $label$7 - (get_local $5) - ) - (br $label$6) - ) - (set_local $2 - (call $_Znwj - (tee_local $4 - (i32.and - (i32.add - (get_local $5) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=48 - (get_local $10) - (i32.or - (get_local $4) - (i32.const 1) - ) - ) - (i32.store offset=56 - (get_local $10) - (get_local $2) - ) - (i32.store offset=52 - (get_local $10) - (get_local $5) - ) - ) - (drop - (call $memcpy - (get_local $2) - (i32.const 1968) - (get_local $5) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $2) - (get_local $5) - ) - (i32.const 0) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 1888) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$9 - (block $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (br_if $label$14 - (i64.gt_u - (get_local $7) - (i64.const 5) - ) - ) - (br_if $label$13 - (i32.gt_u - (i32.and - (i32.add - (tee_local $2 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 165) - ) - ) - (br $label$12) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$11 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$10) - ) - (set_local $2 - (select - (i32.add - (get_local $2) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $2) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$9 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 8) - ) - ) - ) - (i64.store - (get_local $10) - (i64.load offset=64 - (get_local $10) - ) - ) - (call $_ZN5eosio8currency15inline_transferEyyNS_14extended_assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy - (get_local $3) - (get_local $1) - (get_local $10) - (i32.add - (get_local $10) - (i32.const 48) - ) - (get_local $8) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (i32.and - (i32.load8_u offset=48 - (get_local $10) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=56 - (get_local $10) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 112) - ) - ) - (return) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $10) - (i32.const 48) - ) - ) - (unreachable) - ) - (func $_ZN5eosio8exchange2onERKNS0_5tradeE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i64) - (local $14 i64) - (local $15 i64) - (local $16 i64) - (local $17 i32) - (local $18 i32) - (local $19 i32) - (local $20 i32) - (local $21 i32) - (local $22 i32) - (local $23 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $23 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 1008) - ) - ) - ) - (call $require_auth - (i64.load - (get_local $1) - ) - ) - (set_local $3 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - (set_local $21 - (i32.const 0) - ) - (set_local $22 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (i64.load offset=16 - (get_local $1) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $4 - (i64.shr_u - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (i64.const 8) - ) - ) - (set_local $20 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $4) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $20 - (i32.add - (get_local $20) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $22 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $20 - (i32.add - (get_local $20) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $22 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $22) - (i32.const 1984) - ) - (call $eosio_assert - (i64.gt_s - (i64.load - (get_local $3) - ) - (i64.const 0) - ) - (i32.const 2016) - ) - (block $label$5 - (br_if $label$5 - (i64.gt_u - (i64.add - (i64.load offset=40 - (get_local $1) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $4 - (i64.shr_u - (i64.load - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - (i64.const 8) - ) - ) - (set_local $20 - (i32.const 0) - ) - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $4) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $20 - (i32.add - (get_local $20) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $21 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $20 - (i32.add - (get_local $20) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $21 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $21) - (i32.const 2048) - ) - (call $eosio_assert - (i32.xor - (i32.wrap/i64 - (i64.shr_u - (i64.load - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (i64.const 63) - ) - ) - (i32.const 1) - ) - (i32.const 2080) - ) - (call $eosio_assert - (i32.or - (i64.ne - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (tee_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - ) - ) - (i64.ne - (i64.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - (tee_local $5 - (i64.load - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - ) - ) - ) - (i32.const 192) - ) - (i64.store offset=552 - (get_local $23) - (i64.shr_u - (i64.load offset=8 - (get_local $1) - ) - (i64.const 8) - ) - ) - (set_local $13 - (i64.load - (get_local $0) - ) - ) - (set_local $20 - (call $_ZN5eosio14exchange_stateC2Ev - (i32.add - (i32.add - (get_local $23) - (i32.const 552) - ) - (i32.const 8) - ) - ) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 808) - ) - (i64.const -1) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 816) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 824) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 800) - ) - (tee_local $14 - (i64.load offset=552 - (get_local $23) - ) - ) - ) - (i64.store offset=792 - (get_local $23) - (get_local $13) - ) - (i64.store offset=832 - (get_local $23) - (get_local $13) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 840) - ) - (tee_local $16 - (i64.or - (tee_local $15 - (i64.shl - (get_local $14) - (i64.const 4) - ) - ) - (i64.const 1) - ) - ) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 848) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 856) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 860) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 864) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $23) - (i32.const 868) - ) - (i32.const 0) - ) - (i64.store offset=872 - (get_local $23) - (get_local $13) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 880) - ) - (tee_local $15 - (i64.or - (get_local $15) - (i64.const 2) - ) - ) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 888) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 896) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 900) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 904) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $23) - (i32.const 908) - ) - (i32.const 0) - ) - (i64.store offset=912 - (get_local $23) - (get_local $13) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 920) - ) - (get_local $16) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 928) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 936) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 940) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 944) - ) - (i32.const 0) - ) - (i64.store offset=952 - (get_local $23) - (get_local $13) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 960) - ) - (get_local $15) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 968) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 976) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 980) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 984) - ) - (i32.const 0) - ) - (i32.store offset=992 - (get_local $23) - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy - (i32.add - (get_local $23) - (i32.const 996) - ) - (i32.add - (get_local $23) - (i32.const 792) - ) - (get_local $14) - ) - (call $eosio_assert - (i32.ne - (i32.load - (tee_local $21 - (i32.add - (get_local $23) - (i32.const 1000) - ) - ) - ) - (i32.const 0) - ) - (i32.const 720) - ) - (drop - (call $memcpy - (i32.add - (get_local $23) - (i32.const 320) - ) - (tee_local $2 - (call $memcpy - (get_local $20) - (i32.load - (get_local $21) - ) - (i32.const 232) - ) - ) - (i32.const 232) - ) - ) - (i64.store - (tee_local $20 - (i32.add - (i32.add - (get_local $23) - (i32.const 272) - ) - (i32.const 16) - ) - ) - (i64.load - (tee_local $17 - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - ) - (i64.store - (tee_local $21 - (i32.add - (i32.add - (get_local $23) - (i32.const 272) - ) - (i32.const 8) - ) - ) - (i64.load - (tee_local $18 - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - ) - (i64.store offset=272 - (get_local $23) - (i64.load - (get_local $3) - ) - ) - (i64.store offset=256 - (get_local $23) - (get_local $4) - ) - (i64.store offset=264 - (get_local $23) - (get_local $5) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 104) - ) - (i32.const 8) - ) - (i64.load - (get_local $21) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 104) - ) - (i32.const 16) - ) - (i64.load - (get_local $20) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 88) - ) - (i32.const 8) - ) - (i64.load offset=264 - (get_local $23) - ) - ) - (i64.store offset=104 - (get_local $23) - (i64.load offset=272 - (get_local $23) - ) - ) - (i64.store offset=88 - (get_local $23) - (i64.load offset=256 - (get_local $23) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $23) - (i32.const 296) - ) - (i32.add - (get_local $23) - (i32.const 320) - ) - (i32.add - (get_local $23) - (i32.const 104) - ) - (i32.add - (get_local $23) - (i32.const 88) - ) - ) - (set_local $12 - (i32.add - (get_local $23) - (i32.const 456) - ) - ) - (set_local $11 - (i32.add - (get_local $23) - (i32.const 872) - ) - ) - (set_local $10 - (i32.add - (get_local $23) - (i32.const 696) - ) - ) - (set_local $9 - (i32.add - (get_local $23) - (i32.const 832) - ) - ) - (set_local $8 - (i32.add - (i32.add - (get_local $23) - (i32.const 552) - ) - (i32.const 48) - ) - ) - (set_local $7 - (i32.add - (i32.add - (get_local $23) - (i32.const 320) - ) - (i32.const 40) - ) - ) - (set_local $19 - (i32.add - (get_local $23) - (i32.const 616) - ) - ) - (block $label$10 - (loop $label$11 - (block $label$12 - (br_if $label$12 - (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE - (i32.add - (get_local $23) - (i32.const 320) - ) - (get_local $7) - ) - ) - (br_if $label$10 - (i32.eqz - (call $_ZNK5eosio14exchange_state20requires_margin_callERKNS0_9connectorE - (i32.add - (get_local $23) - (i32.const 320) - ) - (get_local $12) - ) - ) - ) - ) - (block $label$13 - (block $label$14 - (br_if $label$14 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 552) - ) - (i32.const 56) - ) - ) - ) - ) - (br_if $label$14 - (i64.ne - (get_local $5) - (i64.load - (get_local $19) - ) - ) - ) - (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE - (i32.add - (get_local $23) - (i32.const 552) - ) - (get_local $8) - (get_local $9) - ) - (br $label$13) - ) - (call $_ZN5eosio12market_state11margin_callERNS_14exchange_state9connectorERNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS5_yXadL_ZNKS5_8get_callEvEEEEEEEEE - (i32.add - (get_local $23) - (i32.const 552) - ) - (get_local $10) - (get_local $11) - ) - ) - (drop - (call $memcpy - (i32.add - (get_local $23) - (i32.const 320) - ) - (get_local $2) - (i32.const 232) - ) - ) - (i64.store - (tee_local $20 - (i32.add - (i32.add - (get_local $23) - (i32.const 232) - ) - (i32.const 16) - ) - ) - (i64.load - (get_local $17) - ) - ) - (i64.store - (tee_local $21 - (i32.add - (i32.add - (get_local $23) - (i32.const 232) - ) - (i32.const 8) - ) - ) - (i64.load - (get_local $18) - ) - ) - (i64.store offset=232 - (get_local $23) - (i64.load - (get_local $3) - ) - ) - (i64.store offset=216 - (get_local $23) - (get_local $4) - ) - (i64.store - (tee_local $22 - (i32.add - (i32.add - (get_local $23) - (i32.const 216) - ) - (i32.const 8) - ) - ) - (get_local $5) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 16) - ) - (i32.const 8) - ) - (i64.load - (get_local $21) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 16) - ) - (i32.const 16) - ) - (i64.load - (get_local $20) - ) - ) - (i64.store - (i32.add - (get_local $23) - (i32.const 8) - ) - (i64.load - (get_local $22) - ) - ) - (i64.store offset=16 - (get_local $23) - (i64.load offset=232 - (get_local $23) - ) - ) - (i64.store - (get_local $23) - (i64.load offset=216 - (get_local $23) - ) - ) - (call $_ZN5eosio14exchange_state7convertENS_14extended_assetENS_15extended_symbolE - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.add - (get_local $23) - (i32.const 320) - ) - (i32.add - (get_local $23) - (i32.const 16) - ) - (get_local $23) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 296) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 296) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=296 - (get_local $23) - (i64.load offset=128 - (get_local $23) - ) - ) - (br $label$11) - ) - ) - (drop - (call $memcpy - (get_local $2) - (i32.add - (get_local $23) - (i32.const 320) - ) - (i32.const 232) - ) - ) - (call $printn - (i64.load - (get_local $1) - ) - ) - (call $prints - (i32.const 2128) - ) - (call $_ZNK5eosio5asset5printEv - (get_local $3) - ) - (call $prints - (i32.const 1280) - ) - (call $printn - (i64.load - (tee_local $20 - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - ) - (call $prints - (i32.const 2144) - ) - (call $_ZNK5eosio5asset5printEv - (i32.add - (get_local $23) - (i32.const 296) - ) - ) - (call $prints - (i32.const 1280) - ) - (call $printn - (i64.load offset=312 - (get_local $23) - ) - ) - (call $prints - (i32.const 1344) - ) - (block $label$15 - (br_if $label$15 - (i64.eqz - (tee_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - ) - ) - ) - (call $eosio_assert - (i64.le_s - (get_local $4) - (i64.load offset=296 - (get_local $23) - ) - ) - (i32.const 2160) - ) - ) - (i64.store offset=200 - (get_local $23) - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (i64.store offset=192 - (get_local $23) - (i64.sub - (i64.const 0) - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - ) - (set_local $4 - (i64.load - (get_local $1) - ) - ) - (i64.store offset=208 - (get_local $23) - (i64.load - (get_local $20) - ) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 136) - ) - (i32.const 0) - ) - (i64.store offset=128 - (get_local $23) - (i64.const 0) - ) - (block $label$16 - (block $label$17 - (block $label$18 - (br_if $label$18 - (i32.ge_u - (tee_local $20 - (call $strlen - (i32.const 2176) - ) - ) - (i32.const -16) - ) - ) - (block $label$19 - (block $label$20 - (block $label$21 - (br_if $label$21 - (i32.ge_u - (get_local $20) - (i32.const 11) - ) - ) - (i32.store8 offset=128 - (get_local $23) - (i32.shl - (get_local $20) - (i32.const 1) - ) - ) - (set_local $21 - (i32.or - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.const 1) - ) - ) - (br_if $label$20 - (get_local $20) - ) - (br $label$19) - ) - (set_local $21 - (call $_Znwj - (tee_local $22 - (i32.and - (i32.add - (get_local $20) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=128 - (get_local $23) - (i32.or - (get_local $22) - (i32.const 1) - ) - ) - (i32.store offset=136 - (get_local $23) - (get_local $21) - ) - (i32.store offset=132 - (get_local $23) - (get_local $20) - ) - ) - (drop - (call $memcpy - (get_local $21) - (i32.const 2176) - (get_local $20) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $21) - (get_local $20) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 64) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 192) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 64) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 192) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=64 - (get_local $23) - (i64.load offset=192 - (get_local $23) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $6) - (get_local $4) - (i32.add - (get_local $23) - (i32.const 64) - ) - (get_local $23) - ) - (block $label$22 - (br_if $label$22 - (i32.eqz - (i32.and - (i32.load8_u offset=128 - (get_local $23) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=136 - (get_local $23) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $23) - (i32.const 168) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (i32.add - (get_local $23) - (i32.const 296) - ) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $23) - (i32.const 168) - ) - (i32.const 16) - ) - (i32.load - (i32.add - (i32.add - (get_local $23) - (i32.const 296) - ) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $23) - (i32.const 168) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $23) - (i32.const 296) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $23) - (i32.const 168) - ) - (i32.const 8) - ) - (i32.load - (i32.add - (i32.add - (get_local $23) - (i32.const 296) - ) - (i32.const 8) - ) - ) - ) - (i32.store offset=172 - (get_local $23) - (i32.load offset=300 - (get_local $23) - ) - ) - (i32.store offset=168 - (get_local $23) - (i32.load offset=296 - (get_local $23) - ) - ) - (set_local $4 - (i64.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=128 - (get_local $23) - (i64.const 0) - ) - (br_if $label$17 - (i32.ge_u - (tee_local $20 - (call $strlen - (i32.const 2192) - ) - ) - (i32.const -16) - ) - ) - (block $label$23 - (block $label$24 - (block $label$25 - (br_if $label$25 - (i32.ge_u - (get_local $20) - (i32.const 11) - ) - ) - (i32.store8 offset=128 - (get_local $23) - (i32.shl - (get_local $20) - (i32.const 1) - ) - ) - (set_local $21 - (i32.or - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.const 1) - ) - ) - (br_if $label$24 - (get_local $20) - ) - (br $label$23) - ) - (set_local $21 - (call $_Znwj - (tee_local $22 - (i32.and - (i32.add - (get_local $20) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=128 - (get_local $23) - (i32.or - (get_local $22) - (i32.const 1) - ) - ) - (i32.store offset=136 - (get_local $23) - (get_local $21) - ) - (i32.store offset=132 - (get_local $23) - (get_local $20) - ) - ) - (drop - (call $memcpy - (get_local $21) - (i32.const 2192) - (get_local $20) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $21) - (get_local $20) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 40) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 168) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 40) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 168) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=40 - (get_local $23) - (i64.load offset=168 - (get_local $23) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $6) - (get_local $4) - (i32.add - (get_local $23) - (i32.const 40) - ) - (get_local $23) - ) - (block $label$26 - (br_if $label$26 - (i32.eqz - (i32.and - (i32.load8_u offset=128 - (get_local $23) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=136 - (get_local $23) - ) - ) - ) - (block $label$27 - (br_if $label$27 - (i64.eq - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 552) - ) - (i32.const 16) - ) - ) - (i64.load offset=8 - (tee_local $20 - (i32.load - (i32.add - (get_local $23) - (i32.const 1000) - ) - ) - ) - ) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load - (i32.add - (get_local $23) - (i32.const 584) - ) - ) - (i64.load - (i32.add - (get_local $20) - (i32.const 24) - ) - ) - ) - (i32.const 800) - ) - (set_local $4 - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 552) - ) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load - (i32.add - (get_local $20) - (i32.const 16) - ) - ) - (tee_local $5 - (i64.load - (i32.add - (i32.add - (get_local $23) - (i32.const 552) - ) - (i32.const 24) - ) - ) - ) - ) - (i32.const 816) - ) - (call $eosio_assert - (i64.gt_s - (tee_local $4 - (i64.sub - (get_local $4) - (i64.load - (i32.add - (get_local $20) - (i32.const 8) - ) - ) - ) - ) - (i64.const -4611686018427387904) - ) - (i32.const 864) - ) - (call $eosio_assert - (i64.lt_s - (get_local $4) - (i64.const 4611686018427387904) - ) - (i32.const 896) - ) - (i64.store - (i32.add - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.const 16) - ) - (get_local $5) - ) - (i64.store align=4 - (i32.add - (get_local $23) - (i32.const 156) - ) - (i64.const 0) - ) - (i64.store offset=136 - (get_local $23) - (get_local $4) - ) - (i32.store offset=152 - (get_local $23) - (i32.const 0) - ) - (i64.store offset=128 - (get_local $23) - (i64.load - (get_local $0) - ) - ) - (set_local $21 - (i32.add - (i32.add - (get_local $23) - (i32.const 128) - ) - (i32.const 24) - ) - ) - (br_if $label$16 - (i32.ge_u - (tee_local $20 - (call $strlen - (i32.const 2208) - ) - ) - (i32.const -16) - ) - ) - (set_local $22 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (block $label$28 - (block $label$29 - (block $label$30 - (br_if $label$30 - (i32.ge_u - (get_local $20) - (i32.const 11) - ) - ) - (i32.store8 - (i32.add - (get_local $23) - (i32.const 152) - ) - (i32.shl - (get_local $20) - (i32.const 1) - ) - ) - (set_local $21 - (i32.add - (get_local $21) - (i32.const 1) - ) - ) - (br_if $label$29 - (get_local $20) - ) - (br $label$28) - ) - (set_local $21 - (call $_Znwj - (tee_local $3 - (i32.and - (i32.add - (get_local $20) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 152) - ) - (i32.or - (get_local $3) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 160) - ) - (get_local $21) - ) - (i32.store - (i32.add - (get_local $23) - (i32.const 156) - ) - (get_local $20) - ) - ) - (drop - (call $memcpy - (get_local $21) - (i32.const 2208) - (get_local $20) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $21) - (get_local $20) - ) - (i32.const 0) - ) - (call $_ZN5eosio8currency14issue_currencyERKNS0_5issueE - (get_local $22) - (i32.add - (get_local $23) - (i32.const 128) - ) - ) - (br_if $label$27 - (i32.eqz - (i32.and - (i32.load8_u - (i32.add - (get_local $23) - (i32.const 152) - ) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $23) - (i32.const 160) - ) - ) - ) - ) - (call $_ZN5eosio12market_state4saveEv - (i32.add - (get_local $23) - (i32.const 552) - ) - ) - (drop - (call $_ZN5eosio12market_stateD2Ev - (i32.add - (get_local $23) - (i32.const 552) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $23) - (i32.const 1008) - ) - ) - (return) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $23) - (i32.const 128) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $23) - (i32.const 128) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $21) - ) - (unreachable) - ) - (func $_ZNK5eosio5asset5printEv (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i32) - (set_local $10 - (tee_local $2 - (i32.load offset=4 - (i32.const 0) - ) - ) - ) - (set_local $7 - (i64.const 1) - ) - (block $label$0 - (br_if $label$0 - (tee_local $5 - (i64.eqz - (tee_local $8 - (i64.load8_u offset=8 - (get_local $0) - ) - ) - ) - ) - ) - (set_local $9 - (i64.add - (get_local $8) - (i64.const 1) - ) - ) - (set_local $7 - (i64.const 1) - ) - (loop $label$1 - (set_local $7 - (i64.mul - (get_local $7) - (i64.const 10) - ) - ) - (br_if $label$1 - (i64.gt_s - (tee_local $9 - (i64.add - (get_local $9) - (i64.const -1) - ) - ) - (i64.const 1) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $2) - (i32.and - (i32.add - (i32.wrap/i64 - (i64.add - (get_local $8) - (i64.const 1) - ) - ) - (i32.const 15) - ) - (i32.const 1008) - ) - ) - ) - ) - (i32.store8 - (tee_local $6 - (i32.add - (get_local $2) - (tee_local $3 - (i32.wrap/i64 - (get_local $8) - ) - ) - ) - ) - (i32.const 0) - ) - (set_local $4 - (i64.load - (get_local $0) - ) - ) - (block $label$2 - (br_if $label$2 - (get_local $5) - ) - (set_local $8 - (i64.add - (get_local $8) - (i64.const 1) - ) - ) - (set_local $9 - (i64.rem_s - (get_local $4) - (get_local $7) - ) - ) - (set_local $0 - (i32.add - (get_local $6) - (i32.const -1) - ) - ) - (loop $label$3 - (i64.store8 - (get_local $0) - (i64.add - (i64.rem_s - (get_local $9) - (i64.const 10) - ) - (i64.const 48) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const -1) - ) - ) - (set_local $9 - (i64.div_s - (get_local $9) - (i64.const 10) - ) - ) - (br_if $label$3 - (i64.gt_s - (tee_local $8 - (i64.add - (get_local $8) - (i64.const -1) - ) - ) - (i64.const 1) - ) - ) - ) - ) - (call $printi - (i64.div_s - (get_local $4) - (get_local $7) - ) - ) - (call $prints - (i32.const 2352) - ) - (call $prints_l - (get_local $2) - (get_local $3) - ) - (call $prints - (i32.const 2368) - ) - (call $_ZNK5eosio11symbol_type5printEb - (get_local $1) - (i32.const 0) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $10) - ) - ) - (func $_ZN5eosio8currency14issue_currencyERKNS0_5issueE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 80) - ) - ) - ) - (set_local $6 - (i64.load - (tee_local $3 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 72) - ) - (i32.const 0) - ) - (i64.store offset=56 - (get_local $7) - (i64.const -1) - ) - (i64.store offset=64 - (get_local $7) - (i64.const 0) - ) - (i64.store offset=40 - (get_local $7) - (i64.load - (get_local $0) - ) - ) - (i64.store offset=48 - (get_local $7) - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - ) - (set_local $2 - (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc - (i32.add - (get_local $7) - (i32.const 40) - ) - (get_local $6) - (i32.const 2224) - ) - ) - (i32.store offset=32 - (get_local $7) - (get_local $1) - ) - (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_14issue_currencyERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ - (i32.add - (get_local $7) - (i32.const 40) - ) - (get_local $2) - (i64.const 0) - (i32.add - (get_local $7) - (i32.const 32) - ) - ) - (i32.store - (tee_local $4 - (i32.add - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 12) - ) - ) - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - ) - (i32.store - (tee_local $5 - (i32.add - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.load - (get_local $3) - ) - ) - (i32.store offset=20 - (get_local $7) - (i32.load - (i32.add - (get_local $1) - (i32.const 12) - ) - ) - ) - (i32.store offset=16 - (get_local $7) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i64.load offset=32 - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 12) - ) - (i32.load - (get_local $4) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.load - (get_local $5) - ) - ) - (i32.store offset=4 - (get_local $7) - (i32.load offset=20 - (get_local $7) - ) - ) - (i32.store - (get_local $7) - (i32.load offset=16 - (get_local $7) - ) - ) - (call $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy - (get_local $0) - (get_local $6) - (get_local $7) - (get_local $2) - (get_local $6) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $0 - (i32.load offset=64 - (get_local $7) - ) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.eq - (tee_local $1 - (i32.load - (tee_local $3 - (i32.add - (get_local $7) - (i32.const 68) - ) - ) - ) - ) - (get_local $0) - ) - ) - (loop $label$3 - (set_local $2 - (i32.load - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (block $label$4 - (br_if $label$4 - (i32.eqz - (get_local $2) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$3 - (i32.ne - (get_local $0) - (get_local $1) - ) - ) - ) - (set_local $1 - (i32.load - (i32.add - (get_local $7) - (i32.const 64) - ) - ) - ) - (br $label$1) - ) - (set_local $1 - (get_local $0) - ) - ) - (i32.store - (get_local $3) - (get_local $0) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 80) - ) - ) - ) - (func $_ZN5eosio12market_stateD2Ev (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 424) - ) - ) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.eq - (tee_local $4 - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 428) - ) - ) - ) - ) - (get_local $1) - ) - ) - (loop $label$3 - (set_local $2 - (i32.load - (tee_local $4 - (i32.add - (get_local $4) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (block $label$4 - (br_if $label$4 - (i32.eqz - (get_local $2) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$3 - (i32.ne - (get_local $1) - (get_local $4) - ) - ) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $0) - (i32.const 424) - ) - ) - ) - (br $label$1) - ) - (set_local $4 - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (get_local $1) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 384) - ) - ) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.eq - (tee_local $4 - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 388) - ) - ) - ) - ) - (get_local $1) - ) - ) - (loop $label$8 - (set_local $2 - (i32.load - (tee_local $4 - (i32.add - (get_local $4) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $2) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $1) - (get_local $4) - ) - ) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $0) - (i32.const 384) - ) - ) - ) - (br $label$6) - ) - (set_local $4 - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (get_local $1) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 344) - ) - ) - ) - ) - ) - (block $label$11 - (block $label$12 - (br_if $label$12 - (i32.eq - (tee_local $4 - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 348) - ) - ) - ) - ) - (get_local $1) - ) - ) - (loop $label$13 - (set_local $2 - (i32.load - (tee_local $4 - (i32.add - (get_local $4) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (get_local $2) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$13 - (i32.ne - (get_local $1) - (get_local $4) - ) - ) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $0) - (i32.const 344) - ) - ) - ) - (br $label$11) - ) - (set_local $4 - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (get_local $1) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 304) - ) - ) - ) - ) - ) - (block $label$16 - (block $label$17 - (br_if $label$17 - (i32.eq - (tee_local $4 - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 308) - ) - ) - ) - ) - (get_local $1) - ) - ) - (loop $label$18 - (set_local $2 - (i32.load - (tee_local $4 - (i32.add - (get_local $4) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (block $label$19 - (br_if $label$19 - (i32.eqz - (get_local $2) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$18 - (i32.ne - (get_local $1) - (get_local $4) - ) - ) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $0) - (i32.const 304) - ) - ) - ) - (br $label$16) - ) - (set_local $4 - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (get_local $1) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (block $label$20 - (br_if $label$20 - (i32.eqz - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 264) - ) - ) - ) - ) - ) - (block $label$21 - (block $label$22 - (br_if $label$22 - (i32.eq - (tee_local $4 - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 268) - ) - ) - ) - ) - (get_local $1) - ) - ) - (loop $label$23 - (set_local $2 - (i32.load - (tee_local $4 - (i32.add - (get_local $4) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (block $label$24 - (br_if $label$24 - (i32.eqz - (get_local $2) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$23 - (i32.ne - (get_local $1) - (get_local $4) - ) - ) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $0) - (i32.const 264) - ) - ) - ) - (br $label$21) - ) - (set_local $4 - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (get_local $1) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (get_local $0) - ) - (func $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc (param $0 i32) (param $1 i64) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $3 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (set_local $4 - (i32.sub - (i32.const 0) - (get_local $3) - ) - ) - (loop $label$1 - (br_if $label$0 - (i64.eq - (i64.shr_u - (i64.load offset=8 - (i32.load - (get_local $6) - ) - ) - (i64.const 8) - ) - (get_local $1) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $5 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $5) - (get_local $4) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $3) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=48 - (tee_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (get_local $0) - ) - (i32.const 224) - ) - (br $label$2) - ) - (set_local $6 - (i32.const 0) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $5 - (call $db_find_i64 - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - (i64.const -4157508551318700032) - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=48 - (tee_local $6 - (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE31load_object_by_primary_iteratorEl - (get_local $0) - (get_local $5) - ) - ) - ) - (get_local $0) - ) - (i32.const 224) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $6) - (i32.const 0) - ) - (get_local $2) - ) - (get_local $6) - ) - (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_14issue_currencyERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $6 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=48 - (get_local $1) - ) - (get_local $0) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $0) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (i64.store - (get_local $1) - (tee_local $4 - (i64.add - (i64.load - (get_local $1) - ) - (i64.load offset=8 - (i32.load - (get_local $3) - ) - ) - ) - ) - ) - (set_local $5 - (i64.load offset=8 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.xor - (i32.wrap/i64 - (i64.shr_u - (get_local $4) - (i64.const 63) - ) - ) - (i32.const 1) - ) - (i32.const 1216) - ) - (call $eosio_assert - (i64.eq - (tee_local $4 - (i64.shr_u - (get_local $5) - (i64.const 8) - ) - ) - (i64.shr_u - (i64.load offset=8 - (get_local $1) - ) - (i64.const 8) - ) - ) - (i32.const 544) - ) - (i32.store offset=56 - (get_local $6) - (i32.add - (get_local $6) - (i32.const 45) - ) - ) - (i32.store offset=52 - (get_local $6) - (get_local $6) - ) - (i32.store offset=48 - (get_local $6) - (get_local $6) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE - (i32.add - (get_local $6) - (i32.const 48) - ) - (get_local $1) - ) - ) - (call $db_update_i64 - (i32.load offset=52 - (get_local $1) - ) - (get_local $2) - (get_local $6) - (i32.const 45) - ) - (block $label$0 - (br_if $label$0 - (i64.lt_u - (get_local $4) - (i64.load offset=16 - (get_local $0) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 64) - ) - ) - ) - (func $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i64) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 56) - ) - (i32.const 0) - ) - (i64.store offset=40 - (get_local $7) - (i64.const -1) - ) - (i64.store offset=48 - (get_local $7) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $7) - (tee_local $5 - (i64.load - (get_local $0) - ) - ) - ) - (i64.store offset=32 - (get_local $7) - (get_local $1) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.le_s - (tee_local $0 - (call $db_find_i64 - (get_local $5) - (get_local $1) - (i64.const 3607749779137757184) - (i64.shr_u - (i64.load offset=8 - (get_local $2) - ) - (i64.const 8) - ) - ) - ) - (i32.const -1) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=20 - (tee_local $0 - (call $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE31load_object_by_primary_iteratorEl - (i32.add - (get_local $7) - (i32.const 24) - ) - (get_local $0) - ) - ) - ) - (i32.add - (get_local $7) - (i32.const 24) - ) - ) - (i32.const 224) - ) - (call $eosio_assert - (select - (i32.load8_u offset=17 - (get_local $0) - ) - (i32.const 1) - (i32.load8_u offset=44 - (get_local $3) - ) - ) - (i32.const 2304) - ) - (i32.store offset=8 - (get_local $7) - (get_local $2) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 352) - ) - (call $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E0_EEvRKS2_yOS9_ - (i32.add - (get_local $7) - (i32.const 24) - ) - (get_local $0) - (i64.const 0) - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - (br_if $label$1 - (tee_local $3 - (i32.load offset=48 - (get_local $7) - ) - ) - ) - (br $label$0) - ) - (call $eosio_assert - (i32.xor - (i32.load8_u offset=44 - (get_local $3) - ) - (i32.const 1) - ) - (i32.const 2256) - ) - (i32.store offset=16 - (get_local $7) - (get_local $2) - ) - (call $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.add - (get_local $7) - (i32.const 24) - ) - (get_local $4) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.load offset=48 - (get_local $7) - ) - ) - ) - ) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.eq - (tee_local $2 - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const 52) - ) - ) - ) - ) - (get_local $3) - ) - ) - (loop $label$5 - (set_local $0 - (i32.load - (tee_local $2 - (i32.add - (get_local $2) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (block $label$6 - (br_if $label$6 - (i32.eqz - (get_local $0) - ) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (br_if $label$5 - (i32.ne - (get_local $3) - (get_local $2) - ) - ) - ) - (set_local $2 - (i32.load - (i32.add - (get_local $7) - (i32.const 48) - ) - ) - ) - (br $label$3) - ) - (set_local $2 - (get_local $3) - ) - ) - (i32.store - (get_local $6) - (get_local $3) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 64) - ) - ) - ) - (func $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i64.store offset=40 - (get_local $7) - (get_local $2) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $1) - ) - (call $current_receiver) - ) - (i32.const 288) - ) - (i32.store offset=20 - (get_local $7) - (get_local $3) - ) - (i32.store offset=16 - (get_local $7) - (get_local $1) - ) - (i32.store offset=24 - (get_local $7) - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - (i64.store offset=8 - (tee_local $4 - (call $_Znwj - (i32.const 32) - ) - ) - (i64.const 1398362884) - ) - (i64.store - (get_local $4) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $2 - (i64.const 5462355) - ) - (set_local $3 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $2) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $2 - (i64.shr_u - (get_local $2) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $2 - (i64.shr_u - (get_local $2) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $3 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $6 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $3 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $6 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 80) - ) - (i32.store offset=20 - (get_local $4) - (get_local $1) - ) - (i32.store16 offset=16 - (get_local $4) - (i32.const 256) - ) - (call $_ZZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ENKUlSA_E_clINS3_4itemEEEDaSA_ - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $4) - ) - (i32.store offset=32 - (get_local $7) - (get_local $4) - ) - (i64.store offset=16 - (get_local $7) - (tee_local $2 - (i64.shr_u - (i64.load - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - (i64.const 8) - ) - ) - ) - (i32.store offset=12 - (get_local $7) - (tee_local $6 - (i32.load offset=24 - (get_local $4) - ) - ) - ) - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.ge_u - (tee_local $3 - (i32.load - (tee_local $5 - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $3) - (get_local $2) - ) - (i32.store offset=16 - (get_local $3) - (get_local $6) - ) - (i32.store offset=32 - (get_local $7) - (i32.const 0) - ) - (i32.store - (get_local $3) - (get_local $4) - ) - (i32.store - (get_local $5) - (i32.add - (get_local $3) - (i32.const 24) - ) - ) - (br $label$5) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy3607749779137757184ENS1_8currency7accountEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.add - (get_local $7) - (i32.const 32) - ) - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store offset=4 - (get_local $0) - (get_local $4) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (set_local $3 - (i32.load offset=32 - (get_local $7) - ) - ) - (i32.store offset=32 - (get_local $7) - (i32.const 0) - ) - (block $label$7 - (br_if $label$7 - (i32.eqz - (get_local $3) - ) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 48) - ) - ) - ) - (func $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (local $9 i32) - (set_local $8 - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $9) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $2 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $2) - ) - ) - (set_local $5 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i32.eq - (i32.load - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - (set_local $6 - (get_local $5) - ) - (set_local $5 - (tee_local $4 - (i32.add - (get_local $5) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $4) - (get_local $3) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $6) - (get_local $2) - ) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i32.xor - (i32.shr_u - (tee_local $5 - (call $db_get_i64 - (get_local $1) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 31) - ) - (i32.const 1) - ) - (i32.const 656) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.lt_u - (get_local $5) - (i32.const 513) - ) - ) - (set_local $4 - (call $malloc - (get_local $5) - ) - ) - (br $label$4) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (get_local $9) - (i32.and - (i32.add - (get_local $5) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $db_get_i64 - (get_local $1) - (get_local $4) - (get_local $5) - ) - ) - (i32.store offset=36 - (get_local $8) - (get_local $4) - ) - (i32.store offset=32 - (get_local $8) - (get_local $4) - ) - (i32.store offset=40 - (get_local $8) - (i32.add - (get_local $4) - (get_local $5) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.lt_u - (get_local $5) - (i32.const 513) - ) - ) - (call $free - (get_local $4) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.store offset=8 - (tee_local $4 - (call $_Znwj - (i32.const 32) - ) - ) - (i64.const 1398362884) - ) - (i64.store - (get_local $4) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $7 - (i64.const 5462355) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$7 - (block $label$8 - (loop $label$9 - (br_if $label$8 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $7) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$10 - (br_if $label$10 - (i64.ne - (i64.and - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$11 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$11 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $6 - (i32.const 1) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$7) - ) - ) - (set_local $6 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 80) - ) - (i32.store offset=20 - (get_local $4) - (get_local $0) - ) - (i32.store16 offset=16 - (get_local $4) - (i32.const 256) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency7accountE - (i32.add - (get_local $8) - (i32.const 32) - ) - (get_local $4) - ) - ) - (i32.store offset=24 - (get_local $4) - (get_local $1) - ) - (i32.store offset=24 - (get_local $8) - (get_local $4) - ) - (i64.store offset=16 - (get_local $8) - (tee_local $7 - (i64.shr_u - (i64.load - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - (i64.const 8) - ) - ) - ) - (i32.store offset=12 - (get_local $8) - (tee_local $6 - (i32.load offset=24 - (get_local $4) - ) - ) - ) - (block $label$12 - (block $label$13 - (br_if $label$13 - (i32.ge_u - (tee_local $5 - (i32.load - (tee_local $1 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $5) - (get_local $7) - ) - (i32.store offset=16 - (get_local $5) - (get_local $6) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $5) - (get_local $4) - ) - (i32.store - (get_local $1) - (i32.add - (get_local $5) - (i32.const 24) - ) - ) - (br $label$12) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy3607749779137757184ENS1_8currency7accountEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ - (get_local $3) - (i32.add - (get_local $8) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 12) - ) - ) - ) - (set_local $5 - (i32.load offset=24 - (get_local $8) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $5) - ) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 48) - ) - ) - (get_local $4) - ) - (func $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E0_EEvRKS2_yOS9_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) - (local $4 i64) - (local $5 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $5 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - (get_local $0) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $0) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (i64.store - (get_local $1) - (i64.add - (i64.load - (get_local $1) - ) - (i64.load - (i32.load - (get_local $3) - ) - ) - ) - ) - (set_local $4 - (i64.load offset=8 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 544) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $1) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.or - (get_local $5) - (i32.const 8) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store8 offset=31 - (get_local $5) - (i32.load8_u offset=16 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $5) - (i32.const 16) - ) - (i32.add - (get_local $5) - (i32.const 31) - ) - (i32.const 1) - ) - ) - (i32.store8 offset=31 - (get_local $5) - (i32.load8_u offset=17 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $5) - (i32.const 17) - ) - (i32.add - (get_local $5) - (i32.const 31) - ) - (i32.const 1) - ) - ) - (call $db_update_i64 - (i32.load offset=24 - (get_local $1) - ) - (get_local $2) - (get_local $5) - (i32.const 18) - ) - (block $label$0 - (br_if $label$0 - (i64.lt_u - (tee_local $2 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.load offset=16 - (get_local $0) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.add - (get_local $2) - (i64.const 1) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $5) - (i32.const 32) - ) - ) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency7accountE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 14) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=16 - (get_local $1) - (i32.ne - (i32.load8_u offset=14 - (get_local $3) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store8 offset=17 - (get_local $1) - (i32.ne - (i32.load8_u offset=15 - (get_local $3) - ) - (i32.const 0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZNSt3__16vectorIN5eosio11multi_indexILy3607749779137757184ENS1_8currency7accountEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.add - (tee_local $4 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 24) - ) - ) - (i32.const 1) - ) - ) - (i32.const 178956971) - ) - ) - (set_local $7 - (i32.const 178956970) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $6 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $6) - ) - (i32.const 24) - ) - ) - (i32.const 89478484) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $5) - (tee_local $7 - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $5) - ) - ) - ) - ) - ) - ) - (set_local $6 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $5 - (i32.load - (get_local $1) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $6) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - (get_local $5) - ) - (i64.store offset=8 - (get_local $1) - (i64.load - (get_local $2) - ) - ) - (i32.store offset=16 - (get_local $1) - (i32.load - (get_local $3) - ) - ) - (set_local $4 - (i32.add - (get_local $6) - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (loop $label$6 - (set_local $3 - (i32.load - (tee_local $2 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -24) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -8) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -12) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -16) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const -24) - ) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$6 - (i32.ne - (get_local $7) - (get_local $2) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $6 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $5) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $6) - ) - ) - (loop $label$8 - (set_local $1 - (i32.load - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $6) - (get_local $7) - ) - ) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $_ZZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE7emplaceIZNS1_11add_balanceEyNS_5assetERKNS1_14currency_statsEyEUlRT_E_EENS3_14const_iteratorEyOS9_ENKUlSA_E_clINS3_4itemEEEDaSA_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $6 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (set_local $2 - (i32.load - (get_local $0) - ) - ) - (i64.store - (get_local $1) - (i64.load - (tee_local $4 - (i32.load - (i32.load offset=4 - (get_local $0) - ) - ) - ) - ) - ) - (i64.store - (tee_local $5 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (get_local $6) - (get_local $1) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.or - (get_local $6) - (i32.const 8) - ) - (get_local $5) - (i32.const 8) - ) - ) - (i32.store8 offset=31 - (get_local $6) - (i32.load8_u offset=16 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $6) - (i32.const 16) - ) - (i32.add - (get_local $6) - (i32.const 31) - ) - (i32.const 1) - ) - ) - (i32.store8 offset=31 - (get_local $6) - (i32.load8_u offset=17 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $6) - (i32.const 17) - ) - (i32.add - (get_local $6) - (i32.const 31) - ) - (i32.const 1) - ) - ) - (i32.store offset=24 - (get_local $1) - (call $db_store_i64 - (i64.load offset=8 - (get_local $2) - ) - (i64.const 3607749779137757184) - (i64.load - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $3 - (i64.shr_u - (i64.load - (get_local $5) - ) - (i64.const 8) - ) - ) - (get_local $6) - (i32.const 18) - ) - ) - (block $label$0 - (br_if $label$0 - (i64.lt_u - (get_local $3) - (i64.load offset=16 - (get_local $2) - ) - ) - ) - (i64.store - (i32.add - (get_local $2) - (i32.const 16) - ) - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 32) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (i32.store8 offset=11 - (get_local $3) - (i32.load8_u offset=40 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $3) - (i32.const 11) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=12 - (get_local $3) - (i32.load8_u offset=41 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $3) - (i32.const 12) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=13 - (get_local $3) - (i32.load8_u offset=42 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $3) - (i32.const 13) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=14 - (get_local $3) - (i32.load8_u offset=43 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $3) - (i32.const 14) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=15 - (get_local $3) - (i32.load8_u offset=44 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 0) - ) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE31load_object_by_primary_iteratorEl (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (set_local $8 - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $9) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $2 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $2) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$1 - (br_if $label$0 - (i32.eq - (i32.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $4 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $4) - (get_local $3) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - (set_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - (br $label$2) - ) - (call $eosio_assert - (i32.xor - (i32.shr_u - (tee_local $6 - (call $db_get_i64 - (get_local $1) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 31) - ) - (i32.const 1) - ) - (i32.const 656) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.lt_u - (get_local $6) - (i32.const 513) - ) - ) - (set_local $4 - (call $malloc - (get_local $6) - ) - ) - (br $label$4) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (get_local $9) - (i32.and - (i32.add - (get_local $6) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $db_get_i64 - (get_local $1) - (get_local $4) - (get_local $6) - ) - ) - (i32.store offset=36 - (get_local $8) - (get_local $4) - ) - (i32.store offset=32 - (get_local $8) - (get_local $4) - ) - (i32.store offset=40 - (get_local $8) - (i32.add - (get_local $4) - (get_local $6) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.lt_u - (get_local $6) - (i32.const 513) - ) - ) - (call $free - (get_local $4) - ) - ) - (set_local $4 - (call $_ZN5eosio8currency14currency_statsC2Ev - (tee_local $6 - (call $_Znwj - (i32.const 64) - ) - ) - ) - ) - (i32.store offset=48 - (get_local $6) - (get_local $0) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency14currency_statsE - (i32.add - (get_local $8) - (i32.const 32) - ) - (get_local $4) - ) - ) - (i32.store offset=52 - (get_local $6) - (get_local $1) - ) - (i32.store offset=24 - (get_local $8) - (get_local $6) - ) - (i64.store offset=16 - (get_local $8) - (tee_local $5 - (i64.shr_u - (i64.load offset=8 - (get_local $6) - ) - (i64.const 8) - ) - ) - ) - (i32.store offset=12 - (get_local $8) - (tee_local $7 - (i32.load offset=52 - (get_local $6) - ) - ) - ) - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ge_u - (tee_local $4 - (i32.load - (tee_local $1 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $4) - (get_local $5) - ) - (i32.store offset=16 - (get_local $4) - (get_local $7) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $4) - (get_local $6) - ) - (i32.store - (get_local $1) - (i32.add - (get_local $4) - (i32.const 24) - ) - ) - (br $label$7) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy14289235522390851584ENS1_8currency14currency_statsEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 24) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 12) - ) - ) - ) - (set_local $4 - (i32.load offset=24 - (get_local $8) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (br_if $label$2 - (i32.eqz - (get_local $4) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 48) - ) - ) - (get_local $6) - ) - (func $_ZN5eosio8currency14currency_statsC2Ev (param $0 i32) (result i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (i64.store offset=8 - (get_local $0) - (i64.const 1398362884) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load offset=8 - (get_local $0) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 1398362884) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$5 - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i32.store8 offset=44 - (get_local $0) - (i32.const 0) - ) - (i32.store offset=40 - (get_local $0) - (i32.const 65793) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency14currency_statsE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 11) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=40 - (get_local $1) - (i32.ne - (i32.load8_u offset=11 - (get_local $3) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 12) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=41 - (get_local $1) - (i32.ne - (i32.load8_u offset=12 - (get_local $3) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 13) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=42 - (get_local $1) - (i32.ne - (i32.load8_u offset=13 - (get_local $3) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 14) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (i32.store8 offset=43 - (get_local $1) - (i32.ne - (i32.load8_u offset=14 - (get_local $3) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store8 offset=44 - (get_local $1) - (i32.ne - (i32.load8_u offset=15 - (get_local $3) - ) - (i32.const 0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZNSt3__16vectorIN5eosio11multi_indexILy14289235522390851584ENS1_8currency14currency_statsEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.add - (tee_local $4 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 24) - ) - ) - (i32.const 1) - ) - ) - (i32.const 178956971) - ) - ) - (set_local $7 - (i32.const 178956970) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $6 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $6) - ) - (i32.const 24) - ) - ) - (i32.const 89478484) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $5) - (tee_local $7 - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $5) - ) - ) - ) - ) - ) - ) - (set_local $6 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $5 - (i32.load - (get_local $1) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $6) - (i32.mul - (get_local $4) - (i32.const 24) - ) - ) - ) - (get_local $5) - ) - (i64.store offset=8 - (get_local $1) - (i64.load - (get_local $2) - ) - ) - (i32.store offset=16 - (get_local $1) - (i32.load - (get_local $3) - ) - ) - (set_local $4 - (i32.add - (get_local $6) - (i32.mul - (get_local $7) - (i32.const 24) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (loop $label$6 - (set_local $3 - (i32.load - (tee_local $2 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -24) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -8) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -12) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const -16) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const -24) - ) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$6 - (i32.ne - (get_local $7) - (get_local $2) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $6 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $5) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $6) - ) - ) - (loop $label$8 - (set_local $1 - (i32.load - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $6) - (get_local $7) - ) - ) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $_ZN5eosio8exchange2onERKNS0_8upmarginE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 576) - ) - ) - ) - (call $require_auth - (i64.load - (get_local $1) - ) - ) - (set_local $9 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (i64.load offset=16 - (get_local $1) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $6 - (i64.shr_u - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (i64.const 8) - ) - ) - (set_local $7 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $6) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $8 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $8 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $8) - (i32.const 2384) - ) - (set_local $2 - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - (block $label$5 - (br_if $label$5 - (i64.gt_u - (i64.add - (i64.load offset=40 - (get_local $1) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $6 - (i64.shr_u - (i64.load - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - (i64.const 8) - ) - ) - (set_local $7 - (i32.const 0) - ) - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $6) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $9 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $9 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $9) - (i32.const 2416) - ) - (i64.store offset=120 - (get_local $10) - (i64.shr_u - (i64.load offset=8 - (get_local $1) - ) - (i64.const 8) - ) - ) - (set_local $6 - (i64.load - (get_local $0) - ) - ) - (set_local $7 - (call $_ZN5eosio14exchange_stateC2Ev - (i32.add - (get_local $10) - (i32.const 128) - ) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 376) - ) - (i64.const -1) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 384) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 392) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 368) - ) - (tee_local $3 - (i64.load offset=120 - (get_local $10) - ) - ) - ) - (i64.store offset=360 - (get_local $10) - (get_local $6) - ) - (i64.store offset=400 - (get_local $10) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 408) - ) - (tee_local $5 - (i64.or - (tee_local $4 - (i64.shl - (get_local $3) - (i64.const 4) - ) - ) - (i64.const 1) - ) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 416) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 424) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 428) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 432) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $10) - (i32.const 436) - ) - (i32.const 0) - ) - (i64.store offset=440 - (get_local $10) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 448) - ) - (tee_local $4 - (i64.or - (get_local $4) - (i64.const 2) - ) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 456) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 464) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 468) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 472) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $10) - (i32.const 476) - ) - (i32.const 0) - ) - (i64.store offset=480 - (get_local $10) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 488) - ) - (get_local $5) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 496) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 504) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 508) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 512) - ) - (i32.const 0) - ) - (i64.store offset=520 - (get_local $10) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 528) - ) - (get_local $4) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 536) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 544) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 548) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 552) - ) - (i32.const 0) - ) - (i32.store offset=560 - (get_local $10) - (tee_local $8 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy - (i32.add - (get_local $10) - (i32.const 564) - ) - (i32.add - (get_local $10) - (i32.const 360) - ) - (get_local $3) - ) - (call $eosio_assert - (i32.ne - (i32.load - (tee_local $9 - (i32.add - (get_local $10) - (i32.const 568) - ) - ) - ) - (i32.const 0) - ) - (i32.const 720) - ) - (drop - (call $memcpy - (get_local $7) - (i32.load - (get_local $9) - ) - (i32.const 232) - ) - ) - (call $eosio_assert - (i64.ne - (i64.or - (i64.load - (get_local $2) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i64.const 0) - ) - (i32.const 2448) - ) - (call $eosio_assert - (i32.or - (i64.ne - (i64.load - (tee_local $7 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - ) - (i64.ne - (i64.load - (tee_local $9 - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - ) - ) - (i32.const 2464) - ) - (set_local $6 - (i64.load - (get_local $9) - ) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.ne - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 120) - ) - (i32.const 56) - ) - ) - (tee_local $3 - (i64.load - (get_local $7) - ) - ) - ) - ) - (br_if $label$11 - (i64.ne - (i64.load - (i32.add - (get_local $10) - (i32.const 184) - ) - ) - (get_local $6) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2480) - ) - (br $label$10) - ) - (call $eosio_assert - (i32.and - (i64.eq - (i64.load - (i32.add - (get_local $10) - (i32.const 272) - ) - ) - (get_local $3) - ) - (i64.eq - (i64.load - (i32.add - (get_local $10) - (i32.const 280) - ) - ) - (get_local $6) - ) - ) - (i32.const 2480) - ) - ) - (set_local $6 - (i64.load - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - ) - (block $label$12 - (block $label$13 - (br_if $label$13 - (i64.ne - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 120) - ) - (i32.const 56) - ) - ) - (tee_local $3 - (i64.load - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - ) - ) - ) - (br_if $label$13 - (i64.ne - (i64.load - (i32.add - (get_local $10) - (i32.const 184) - ) - ) - (get_local $6) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2480) - ) - (br $label$12) - ) - (call $eosio_assert - (i32.and - (i64.eq - (i64.load - (i32.add - (get_local $10) - (i32.const 272) - ) - ) - (get_local $3) - ) - (i64.eq - (i64.load - (i32.add - (get_local $10) - (i32.const 280) - ) - ) - (get_local $6) - ) - ) - (i32.const 2480) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - (set_local $6 - (i64.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - (set_local $3 - (i64.load - (get_local $1) - ) - ) - (block $label$14 - (block $label$15 - (br_if $label$15 - (i64.ne - (tee_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const 176) - ) - ) - ) - ) - (br_if $label$15 - (i64.ne - (get_local $6) - (i64.load - (i32.add - (get_local $10) - (i32.const 184) - ) - ) - ) - ) - (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ - (i32.add - (get_local $10) - (i32.const 120) - ) - (get_local $3) - (i32.add - (get_local $10) - (i32.const 400) - ) - (i32.add - (get_local $10) - (i32.const 168) - ) - (get_local $7) - (get_local $2) - ) - (br $label$14) - ) - (block $label$16 - (br_if $label$16 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $10) - (i32.const 272) - ) - ) - ) - ) - (br_if $label$16 - (i64.ne - (get_local $6) - (i64.load - (i32.add - (get_local $10) - (i32.const 280) - ) - ) - ) - ) - (call $_ZN5eosio12market_state13adjust_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetESG_ - (i32.add - (get_local $10) - (i32.const 120) - ) - (get_local $3) - (i32.add - (get_local $10) - (i32.const 440) - ) - (i32.add - (get_local $10) - (i32.const 264) - ) - (get_local $7) - (get_local $2) - ) - (br $label$14) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1376) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 96) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 20) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 96) - ) - (i32.const 16) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 96) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 96) - ) - (i32.const 8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=96 - (get_local $10) - (i32.load - (get_local $7) - ) - ) - (i32.store offset=100 - (get_local $10) - (i32.load - (i32.add - (get_local $7) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i64.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 80) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=80 - (get_local $10) - (i64.const 0) - ) - (block $label$17 - (block $label$18 - (br_if $label$18 - (i32.ge_u - (tee_local $7 - (call $strlen - (i32.const 2512) - ) - ) - (i32.const -16) - ) - ) - (block $label$19 - (block $label$20 - (block $label$21 - (br_if $label$21 - (i32.ge_u - (get_local $7) - (i32.const 11) - ) - ) - (i32.store8 offset=80 - (get_local $10) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - (set_local $9 - (i32.or - (i32.add - (get_local $10) - (i32.const 80) - ) - (i32.const 1) - ) - ) - (br_if $label$20 - (get_local $7) - ) - (br $label$19) - ) - (set_local $9 - (call $_Znwj - (tee_local $0 - (i32.and - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=80 - (get_local $10) - (i32.or - (get_local $0) - (i32.const 1) - ) - ) - (i32.store offset=88 - (get_local $10) - (get_local $9) - ) - (i32.store offset=84 - (get_local $10) - (get_local $7) - ) - ) - (drop - (call $memcpy - (get_local $9) - (i32.const 2512) - (get_local $7) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $9) - (get_local $7) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 32) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 96) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 32) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 96) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=32 - (get_local $10) - (i64.load offset=96 - (get_local $10) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $8) - (get_local $6) - (i32.add - (get_local $10) - (i32.const 32) - ) - (get_local $10) - ) - (block $label$22 - (br_if $label$22 - (i32.eqz - (i32.and - (i32.load8_u offset=80 - (get_local $10) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=88 - (get_local $10) - ) - ) - ) - (i64.store offset=64 - (get_local $10) - (i64.load - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - ) - (i64.store offset=56 - (get_local $10) - (i64.sub - (i64.const 0) - (i64.load - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - ) - ) - (set_local $6 - (i64.load - (get_local $1) - ) - ) - (i64.store offset=72 - (get_local $10) - (i64.load - (i32.add - (get_local $1) - (i32.const 56) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $10) - (i32.const 80) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=80 - (get_local $10) - (i64.const 0) - ) - (br_if $label$17 - (i32.ge_u - (tee_local $7 - (call $strlen - (i32.const 2528) - ) - ) - (i32.const -16) - ) - ) - (block $label$23 - (block $label$24 - (block $label$25 - (br_if $label$25 - (i32.ge_u - (get_local $7) - (i32.const 11) - ) - ) - (i32.store8 offset=80 - (get_local $10) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - (set_local $1 - (i32.or - (i32.add - (get_local $10) - (i32.const 80) - ) - (i32.const 1) - ) - ) - (br_if $label$24 - (get_local $7) - ) - (br $label$23) - ) - (set_local $1 - (call $_Znwj - (tee_local $9 - (i32.and - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=80 - (get_local $10) - (i32.or - (get_local $9) - (i32.const 1) - ) - ) - (i32.store offset=88 - (get_local $10) - (get_local $1) - ) - (i32.store offset=84 - (get_local $10) - (get_local $7) - ) - ) - (drop - (call $memcpy - (get_local $1) - (i32.const 2528) - (get_local $7) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $1) - (get_local $7) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 8) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 56) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 8) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 56) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=8 - (get_local $10) - (i64.load offset=56 - (get_local $10) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $8) - (get_local $6) - (i32.add - (get_local $10) - (i32.const 8) - ) - (get_local $10) - ) - (block $label$26 - (br_if $label$26 - (i32.eqz - (i32.and - (i32.load8_u offset=80 - (get_local $10) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=88 - (get_local $10) - ) - ) - ) - (call $_ZN5eosio12market_state4saveEv - (i32.add - (get_local $10) - (i32.const 120) - ) - ) - (drop - (call $_ZN5eosio12market_stateD2Ev - (i32.add - (get_local $10) - (i32.const 120) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 576) - ) - ) - (return) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $10) - (i32.const 80) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $10) - (i32.const 80) - ) - ) - (unreachable) - ) - (func $_ZN5eosio8exchange2onERKNS0_11covermarginE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 464) - ) - ) - ) - (call $require_auth - (i64.load - (get_local $1) - ) - ) - (set_local $2 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - (set_local $8 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (i64.load offset=16 - (get_local $1) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $6 - (i64.shr_u - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (i64.const 8) - ) - ) - (set_local $7 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $6) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $8 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $8 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $8) - (i32.const 2544) - ) - (call $eosio_assert - (i64.gt_s - (i64.load - (get_local $2) - ) - (i64.const 0) - ) - (i32.const 2576) - ) - (i64.store offset=8 - (get_local $9) - (i64.shr_u - (i64.load offset=8 - (get_local $1) - ) - (i64.const 8) - ) - ) - (set_local $6 - (i64.load - (get_local $0) - ) - ) - (set_local $7 - (call $_ZN5eosio14exchange_stateC2Ev - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 264) - ) - (i64.const -1) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 272) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 280) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 256) - ) - (tee_local $3 - (i64.load offset=8 - (get_local $9) - ) - ) - ) - (i64.store offset=248 - (get_local $9) - (get_local $6) - ) - (i64.store offset=288 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 296) - ) - (tee_local $5 - (i64.or - (tee_local $4 - (i64.shl - (get_local $3) - (i64.const 4) - ) - ) - (i64.const 1) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 304) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 312) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 316) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 320) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $9) - (i32.const 324) - ) - (i32.const 0) - ) - (i64.store offset=328 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 336) - ) - (tee_local $4 - (i64.or - (get_local $4) - (i64.const 2) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 344) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 352) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 356) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 360) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $9) - (i32.const 364) - ) - (i32.const 0) - ) - (i64.store offset=368 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 376) - ) - (get_local $5) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 384) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 392) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 396) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 400) - ) - (i32.const 0) - ) - (i64.store offset=408 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 416) - ) - (get_local $4) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 424) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 432) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 436) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 440) - ) - (i32.const 0) - ) - (i32.store offset=448 - (get_local $9) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy - (i32.add - (get_local $9) - (i32.const 452) - ) - (i32.add - (get_local $9) - (i32.const 248) - ) - (get_local $3) - ) - (call $eosio_assert - (i32.ne - (i32.load - (tee_local $8 - (i32.add - (get_local $9) - (i32.const 456) - ) - ) - ) - (i32.const 0) - ) - (i32.const 720) - ) - (drop - (call $memcpy - (get_local $7) - (i32.load - (get_local $8) - ) - (i32.const 232) - ) - ) - (set_local $6 - (i64.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - (set_local $3 - (i64.load - (get_local $1) - ) - ) - (block $label$5 - (block $label$6 - (br_if $label$6 - (i64.ne - (tee_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (i64.load - (i32.add - (get_local $9) - (i32.const 64) - ) - ) - ) - ) - (br_if $label$6 - (i64.ne - (get_local $6) - (i64.load - (i32.add - (get_local $9) - (i32.const 72) - ) - ) - ) - ) - (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE - (i32.add - (get_local $9) - (i32.const 8) - ) - (get_local $3) - (i32.add - (get_local $9) - (i32.const 288) - ) - (i32.add - (get_local $9) - (i32.const 56) - ) - (get_local $2) - ) - (br $label$5) - ) - (block $label$7 - (br_if $label$7 - (i64.ne - (get_local $4) - (i64.load - (i32.add - (get_local $9) - (i32.const 160) - ) - ) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $6) - (i64.load - (i32.add - (get_local $9) - (i32.const 168) - ) - ) - ) - ) - (call $_ZN5eosio12market_state12cover_marginEyRNS_11multi_indexILy10497546923563548672ENS_15margin_positionEJNS_10indexed_byILy4729653573519933440EN5boost11multi_index13const_mem_funIS2_yXadL_ZNKS2_8get_callEvEEEEEEEEERNS_14exchange_state9connectorERKNS_14extended_assetE - (i32.add - (get_local $9) - (i32.const 8) - ) - (get_local $3) - (i32.add - (get_local $9) - (i32.const 328) - ) - (i32.add - (get_local $9) - (i32.const 152) - ) - (get_local $2) - ) - (br $label$5) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1376) - ) - ) - (call $_ZN5eosio12market_state4saveEv - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosio12market_stateD2Ev - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 464) - ) - ) - ) - (func $_ZN5eosio8exchange7createxEyNS_5assetEmNS_14extended_assetES2_ (type $FUNCSIG$vijiiii) (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) (param $4 i32) (param $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i64) - (local $12 i32) - (local $13 i32) - (local $14 i64) - (local $15 i32) - (local $16 i32) - (local $17 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $17 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 464) - ) - ) - ) - (call $require_auth - (get_local $1) - ) - (set_local $16 - (i32.const 0) - ) - (set_local $13 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (tee_local $6 - (i64.load - (get_local $2) - ) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $14 - (i64.shr_u - (i64.load offset=8 - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $15 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $14) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $13 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $13 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $13) - (i32.const 2608) - ) - (call $eosio_assert - (i64.gt_s - (get_local $6) - (i64.const 0) - ) - (i32.const 2640) - ) - (block $label$5 - (br_if $label$5 - (i64.gt_u - (i64.add - (tee_local $6 - (i64.load - (get_local $4) - ) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $14 - (i64.shr_u - (i64.load offset=8 - (get_local $4) - ) - (i64.const 8) - ) - ) - (set_local $15 - (i32.const 0) - ) - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $14) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $16 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $16 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $16) - (i32.const 2672) - ) - (call $eosio_assert - (i64.gt_s - (get_local $6) - (i64.const 0) - ) - (i32.const 2704) - ) - (set_local $6 - (i64.load offset=8 - (get_local $5) - ) - ) - (set_local $13 - (i32.const 0) - ) - (set_local $16 - (i32.const 0) - ) - (block $label$10 - (br_if $label$10 - (i64.gt_u - (i64.add - (tee_local $7 - (i64.load - (get_local $5) - ) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $14 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (set_local $15 - (i32.const 0) - ) - (block $label$11 - (loop $label$12 - (br_if $label$11 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $14) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$13 - (br_if $label$13 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$14 - (br_if $label$11 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$14 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $16 - (i32.const 1) - ) - (br_if $label$12 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$10) - ) - ) - (set_local $16 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $16) - (i32.const 2736) - ) - (call $eosio_assert - (i64.gt_s - (get_local $7) - (i64.const 0) - ) - (i32.const 2768) - ) - (call $eosio_assert - (i32.or - (i64.ne - (tee_local $14 - (i64.load offset=8 - (get_local $4) - ) - ) - (get_local $6) - ) - (i64.ne - (tee_local $7 - (i64.load offset=16 - (get_local $4) - ) - ) - (tee_local $8 - (i64.load offset=16 - (get_local $5) - ) - ) - ) - ) - (i32.const 2800) - ) - (i64.store offset=216 - (get_local $17) - (get_local $7) - ) - (i64.store offset=208 - (get_local $17) - (get_local $14) - ) - (call $prints - (i32.const 2848) - ) - (call $_ZNK5eosio11symbol_type5printEb - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 1) - ) - (call $prints - (i32.const 1280) - ) - (call $printn - (i64.load offset=216 - (get_local $17) - ) - ) - (i64.store offset=216 - (get_local $17) - (get_local $8) - ) - (i64.store offset=208 - (get_local $17) - (get_local $6) - ) - (call $prints - (i32.const 2864) - ) - (call $_ZNK5eosio11symbol_type5printEb - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 1) - ) - (call $prints - (i32.const 1280) - ) - (call $printn - (i64.load offset=216 - (get_local $17) - ) - ) - (set_local $9 - (i64.load offset=8 - (get_local $2) - ) - ) - (call $prints - (i32.const 2880) - ) - (call $printui - (tee_local $10 - (i64.shr_u - (get_local $9) - (i64.const 8) - ) - ) - ) - (call $prints - (i32.const 2896) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 200) - ) - (i32.const 0) - ) - (i64.store offset=176 - (get_local $17) - (get_local $10) - ) - (i64.store offset=184 - (get_local $17) - (i64.const -1) - ) - (i64.store offset=192 - (get_local $17) - (i64.const 0) - ) - (i64.store offset=168 - (get_local $17) - (tee_local $11 - (i64.load - (get_local $0) - ) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.lt_s - (tee_local $15 - (call $db_find_i64 - (get_local $11) - (get_local $10) - (i64.const -7949128877345865728) - (get_local $10) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=232 - (tee_local $13 - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE31load_object_by_primary_iteratorEl - (i32.add - (get_local $17) - (i32.const 168) - ) - (get_local $15) - ) - ) - ) - (i32.add - (get_local $17) - (i32.const 168) - ) - ) - (i32.const 224) - ) - ) - (call $eosio_assert - (i32.eqz - (get_local $13) - ) - (i32.const 2912) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=168 - (get_local $17) - ) - (call $current_receiver) - ) - (i32.const 288) - ) - (set_local $16 - (call $_ZN5eosio14exchange_stateC2Ev - (tee_local $15 - (call $_Znwj - (i32.const 248) - ) - ) - ) - ) - (i32.store offset=232 - (get_local $15) - (i32.add - (get_local $17) - (i32.const 168) - ) - ) - (i64.store - (get_local $15) - (get_local $1) - ) - (i64.store - (tee_local $13 - (i32.add - (i32.add - (get_local $17) - (i32.const 432) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i64.store offset=432 - (get_local $17) - (i64.load - (get_local $2) - ) - ) - (set_local $10 - (i64.load - (get_local $0) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 8) - ) - (tee_local $11 - (i64.load - (get_local $13) - ) - ) - ) - (i64.store - (tee_local $13 - (i32.add - (i32.add - (get_local $17) - (i32.const 448) - ) - (i32.const 8) - ) - ) - (get_local $11) - ) - (i64.store offset=208 - (get_local $17) - (tee_local $11 - (i64.load offset=432 - (get_local $17) - ) - ) - ) - (i64.store offset=448 - (get_local $17) - (get_local $11) - ) - (i64.store offset=24 - (get_local $15) - (get_local $10) - ) - (i64.store offset=16 - (get_local $15) - (i64.load - (get_local $13) - ) - ) - (i64.store offset=8 - (get_local $15) - (i64.load offset=448 - (get_local $17) - ) - ) - (i64.store - (i32.add - (get_local $15) - (i32.const 56) - ) - (i64.load - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $15) - (i32.const 48) - ) - (i64.load - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - ) - (i64.store offset=40 - (get_local $15) - (i64.load - (get_local $4) - ) - ) - (i64.store - (i32.add - (get_local $15) - (i32.const 152) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $15) - (i32.const 144) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i64.store offset=136 - (get_local $15) - (i64.load - (get_local $5) - ) - ) - (i64.store offset=104 - (get_local $15) - (get_local $14) - ) - (i64.store offset=112 - (get_local $15) - (get_local $7) - ) - (i64.store offset=80 - (get_local $15) - (get_local $14) - ) - (i64.store offset=88 - (get_local $15) - (get_local $7) - ) - (i64.store offset=200 - (get_local $15) - (get_local $6) - ) - (i64.store offset=208 - (get_local $15) - (get_local $8) - ) - (i64.store offset=176 - (get_local $15) - (get_local $6) - ) - (i64.store offset=184 - (get_local $15) - (get_local $8) - ) - (i32.store offset=456 - (get_local $17) - (i32.add - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 220) - ) - ) - (i32.store offset=452 - (get_local $17) - (i32.add - (get_local $17) - (i32.const 208) - ) - ) - (i32.store offset=448 - (get_local $17) - (i32.add - (get_local $17) - (i32.const 208) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_14exchange_stateE - (i32.add - (get_local $17) - (i32.const 448) - ) - (get_local $16) - ) - ) - (i32.store offset=236 - (get_local $15) - (tee_local $13 - (call $db_store_i64 - (i64.load - (i32.add - (i32.add - (get_local $17) - (i32.const 168) - ) - (i32.const 8) - ) - ) - (i64.const -7949128877345865728) - (get_local $1) - (tee_local $14 - (i64.shr_u - (i64.load offset=16 - (get_local $15) - ) - (i64.const 8) - ) - ) - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 220) - ) - ) - ) - (block $label$16 - (br_if $label$16 - (i64.lt_u - (get_local $14) - (i64.load - (tee_local $16 - (i32.add - (i32.add - (get_local $17) - (i32.const 168) - ) - (i32.const 16) - ) - ) - ) - ) - ) - (i64.store - (get_local $16) - (i64.add - (get_local $14) - (i64.const 1) - ) - ) - ) - (i32.store offset=448 - (get_local $17) - (get_local $15) - ) - (i64.store offset=208 - (get_local $17) - (tee_local $14 - (i64.shr_u - (i64.load - (i32.add - (get_local $15) - (i32.const 16) - ) - ) - (i64.const 8) - ) - ) - ) - (i32.store offset=432 - (get_local $17) - (get_local $13) - ) - (block $label$17 - (block $label$18 - (br_if $label$18 - (i32.ge_u - (tee_local $16 - (i32.load - (tee_local $12 - (i32.add - (get_local $17) - (i32.const 196) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $17) - (i32.const 200) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $16) - (get_local $14) - ) - (i32.store offset=16 - (get_local $16) - (get_local $13) - ) - (i32.store offset=448 - (get_local $17) - (i32.const 0) - ) - (i32.store - (get_local $16) - (get_local $15) - ) - (i32.store - (get_local $12) - (i32.add - (get_local $16) - (i32.const 24) - ) - ) - (br $label$17) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy10497615196363685888ENS1_14exchange_stateEJEE8item_ptrENS_9allocatorIS5_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS4_4itemENS_14default_deleteISB_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $17) - (i32.const 192) - ) - (i32.add - (get_local $17) - (i32.const 448) - ) - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.add - (get_local $17) - (i32.const 432) - ) - ) - ) - (set_local $16 - (i32.load offset=448 - (get_local $17) - ) - ) - (set_local $15 - (i32.const 0) - ) - (i32.store offset=448 - (get_local $17) - (i32.const 0) - ) - (block $label$19 - (br_if $label$19 - (i32.eqz - (get_local $16) - ) - ) - (call $_ZdlPv - (get_local $16) - ) - ) - (i64.store - (tee_local $16 - (i32.add - (get_local $17) - (i32.const 224) - ) - ) - (get_local $9) - ) - (i64.store offset=216 - (get_local $17) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $17) - (i64.load - (get_local $0) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $13 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $14 - (i64.shr_u - (i64.load - (get_local $16) - ) - (i64.const 8) - ) - ) - (block $label$20 - (block $label$21 - (loop $label$22 - (br_if $label$21 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $14) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$23 - (br_if $label$23 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$24 - (br_if $label$21 - (i64.ne - (i64.and - (tee_local $14 - (i64.shr_u - (get_local $14) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$24 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $16 - (i32.const 1) - ) - (br_if $label$22 - (i32.lt_s - (tee_local $15 - (i32.add - (get_local $15) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$20) - ) - ) - (set_local $16 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $16) - (i32.const 80) - ) - (i32.store8 offset=234 - (get_local $17) - (i32.const 0) - ) - (i32.store16 offset=232 - (get_local $17) - (i32.const 0) - ) - (call $_ZN5eosio8currency15create_currencyERKNS0_6createE - (get_local $13) - (i32.add - (get_local $17) - (i32.const 208) - ) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 228) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 224) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (i64.store offset=208 - (get_local $17) - (i64.load - (get_local $0) - ) - ) - (i32.store offset=216 - (get_local $17) - (i32.load - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 240) - ) - (i32.const 0) - ) - (i64.store offset=232 - (get_local $17) - (i64.const 0) - ) - (set_local $16 - (i32.add - (get_local $17) - (i32.const 232) - ) - ) - (block $label$25 - (block $label$26 - (block $label$27 - (block $label$28 - (br_if $label$28 - (i32.ge_u - (tee_local $15 - (call $strlen - (i32.const 2944) - ) - ) - (i32.const -16) - ) - ) - (block $label$29 - (block $label$30 - (block $label$31 - (br_if $label$31 - (i32.ge_u - (get_local $15) - (i32.const 11) - ) - ) - (i32.store8 - (i32.add - (get_local $17) - (i32.const 232) - ) - (i32.shl - (get_local $15) - (i32.const 1) - ) - ) - (set_local $16 - (i32.add - (get_local $16) - (i32.const 1) - ) - ) - (br_if $label$30 - (get_local $15) - ) - (br $label$29) - ) - (set_local $16 - (call $_Znwj - (tee_local $12 - (i32.and - (i32.add - (get_local $15) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 232) - ) - (i32.or - (get_local $12) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 240) - ) - (get_local $16) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 236) - ) - (get_local $15) - ) - ) - (drop - (call $memcpy - (get_local $16) - (i32.const 2944) - (get_local $15) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $16) - (get_local $15) - ) - (i32.const 0) - ) - (call $_ZN5eosio8currency14issue_currencyERKNS0_5issueE - (get_local $13) - (i32.add - (get_local $17) - (i32.const 208) - ) - ) - (block $label$32 - (br_if $label$32 - (i32.eqz - (i32.and - (i32.load8_u - (i32.add - (get_local $17) - (i32.const 232) - ) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $17) - (i32.const 240) - ) - ) - ) - ) - (i64.store - (tee_local $15 - (i32.add - (i32.add - (get_local $17) - (i32.const 128) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i64.store offset=128 - (get_local $17) - (i64.load - (get_local $2) - ) - ) - (set_local $14 - (i64.load - (get_local $0) - ) - ) - (i64.store - (tee_local $2 - (i32.add - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 8) - ) - ) - (tee_local $6 - (i64.load - (get_local $15) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 144) - ) - (i32.const 8) - ) - (get_local $6) - ) - (i64.store offset=208 - (get_local $17) - (tee_local $6 - (i64.load offset=128 - (get_local $17) - ) - ) - ) - (i64.store offset=144 - (get_local $17) - (get_local $6) - ) - (i64.store offset=160 - (get_local $17) - (get_local $14) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (i64.store offset=208 - (get_local $17) - (i64.const 0) - ) - (br_if $label$27 - (i32.ge_u - (tee_local $15 - (call $strlen - (i32.const 2976) - ) - ) - (i32.const -16) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (block $label$33 - (block $label$34 - (block $label$35 - (br_if $label$35 - (i32.ge_u - (get_local $15) - (i32.const 11) - ) - ) - (i32.store8 offset=208 - (get_local $17) - (i32.shl - (get_local $15) - (i32.const 1) - ) - ) - (set_local $0 - (i32.or - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 1) - ) - ) - (br_if $label$34 - (get_local $15) - ) - (br $label$33) - ) - (set_local $0 - (call $_Znwj - (tee_local $16 - (i32.and - (i32.add - (get_local $15) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=208 - (get_local $17) - (i32.or - (get_local $16) - (i32.const 1) - ) - ) - (i32.store offset=216 - (get_local $17) - (get_local $0) - ) - (i32.store offset=212 - (get_local $17) - (get_local $15) - ) - ) - (drop - (call $memcpy - (get_local $0) - (i32.const 2976) - (get_local $15) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $0) - (get_local $15) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 56) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $17) - (i32.const 144) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 56) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $17) - (i32.const 144) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=56 - (get_local $17) - (i64.load offset=144 - (get_local $17) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $2) - (get_local $1) - (i32.add - (get_local $17) - (i32.const 56) - ) - (get_local $17) - ) - (block $label$36 - (br_if $label$36 - (i32.eqz - (i32.and - (i32.load8_u offset=208 - (get_local $17) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=216 - (get_local $17) - ) - ) - ) - (i64.store offset=104 - (get_local $17) - (i64.sub - (i64.const 0) - (i64.load - (get_local $4) - ) - ) - ) - (i64.store offset=112 - (get_local $17) - (i64.load - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - ) - (i64.store offset=120 - (get_local $17) - (i64.load - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=208 - (get_local $17) - (i64.const 0) - ) - (br_if $label$26 - (i32.ge_u - (tee_local $15 - (call $strlen - (i32.const 3008) - ) - ) - (i32.const -16) - ) - ) - (block $label$37 - (block $label$38 - (block $label$39 - (br_if $label$39 - (i32.ge_u - (get_local $15) - (i32.const 11) - ) - ) - (i32.store8 offset=208 - (get_local $17) - (i32.shl - (get_local $15) - (i32.const 1) - ) - ) - (set_local $4 - (i32.or - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 1) - ) - ) - (br_if $label$38 - (get_local $15) - ) - (br $label$37) - ) - (set_local $4 - (call $_Znwj - (tee_local $0 - (i32.and - (i32.add - (get_local $15) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=208 - (get_local $17) - (i32.or - (get_local $0) - (i32.const 1) - ) - ) - (i32.store offset=216 - (get_local $17) - (get_local $4) - ) - (i32.store offset=212 - (get_local $17) - (get_local $15) - ) - ) - (drop - (call $memcpy - (get_local $4) - (i32.const 3008) - (get_local $15) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $4) - (get_local $15) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 32) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $17) - (i32.const 104) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 32) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $17) - (i32.const 104) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=32 - (get_local $17) - (i64.load offset=104 - (get_local $17) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $2) - (get_local $1) - (i32.add - (get_local $17) - (i32.const 32) - ) - (get_local $17) - ) - (block $label$40 - (br_if $label$40 - (i32.eqz - (i32.and - (i32.load8_u offset=208 - (get_local $17) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=216 - (get_local $17) - ) - ) - ) - (i64.store offset=80 - (get_local $17) - (i64.sub - (i64.const 0) - (i64.load - (get_local $5) - ) - ) - ) - (i64.store offset=88 - (get_local $17) - (i64.load - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i64.store offset=96 - (get_local $17) - (i64.load - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=208 - (get_local $17) - (i64.const 0) - ) - (br_if $label$25 - (i32.ge_u - (tee_local $15 - (call $strlen - (i32.const 3008) - ) - ) - (i32.const -16) - ) - ) - (block $label$41 - (block $label$42 - (block $label$43 - (br_if $label$43 - (i32.ge_u - (get_local $15) - (i32.const 11) - ) - ) - (i32.store8 offset=208 - (get_local $17) - (i32.shl - (get_local $15) - (i32.const 1) - ) - ) - (set_local $4 - (i32.or - (i32.add - (get_local $17) - (i32.const 208) - ) - (i32.const 1) - ) - ) - (br_if $label$42 - (get_local $15) - ) - (br $label$41) - ) - (set_local $4 - (call $_Znwj - (tee_local $5 - (i32.and - (i32.add - (get_local $15) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=208 - (get_local $17) - (i32.or - (get_local $5) - (i32.const 1) - ) - ) - (i32.store offset=216 - (get_local $17) - (get_local $4) - ) - (i32.store offset=212 - (get_local $17) - (get_local $15) - ) - ) - (drop - (call $memcpy - (get_local $4) - (i32.const 3008) - (get_local $15) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $4) - (get_local $15) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 8) - ) - (i32.const 16) - ) - (i64.load - (i32.add - (i32.add - (get_local $17) - (i32.const 80) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $17) - (i32.const 8) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $17) - (i32.const 80) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=8 - (get_local $17) - (i64.load offset=80 - (get_local $17) - ) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (get_local $2) - (get_local $1) - (i32.add - (get_local $17) - (i32.const 8) - ) - (get_local $17) - ) - (block $label$44 - (br_if $label$44 - (i32.eqz - (i32.and - (i32.load8_u offset=208 - (get_local $17) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=216 - (get_local $17) - ) - ) - ) - (block $label$45 - (br_if $label$45 - (i32.eqz - (tee_local $4 - (i32.load offset=192 - (get_local $17) - ) - ) - ) - ) - (block $label$46 - (block $label$47 - (br_if $label$47 - (i32.eq - (tee_local $15 - (i32.load - (tee_local $5 - (i32.add - (get_local $17) - (i32.const 196) - ) - ) - ) - ) - (get_local $4) - ) - ) - (loop $label$48 - (set_local $2 - (i32.load - (tee_local $15 - (i32.add - (get_local $15) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $15) - (i32.const 0) - ) - (block $label$49 - (br_if $label$49 - (i32.eqz - (get_local $2) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$48 - (i32.ne - (get_local $4) - (get_local $15) - ) - ) - ) - (set_local $15 - (i32.load - (i32.add - (get_local $17) - (i32.const 192) - ) - ) - ) - (br $label$46) - ) - (set_local $15 - (get_local $4) - ) - ) - (i32.store - (get_local $5) - (get_local $4) - ) - (call $_ZdlPv - (get_local $15) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $17) - (i32.const 464) - ) - ) - (return) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $16) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $17) - (i32.const 208) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $17) - (i32.const 208) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $17) - (i32.const 208) - ) - ) - (unreachable) - ) - (func $_ZN5eosio8currency15create_currencyERKNS0_6createE (param $0 i32) (param $1 i32) - (local $2 i64) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $6 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (set_local $5 - (i32.const 0) - ) - (set_local $4 - (tee_local $2 - (i64.shr_u - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - (i64.const 8) - ) - ) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $4) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (set_local $5 - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $6) - (i32.const 56) - ) - (i32.const 0) - ) - (i64.store offset=40 - (get_local $6) - (i64.const -1) - ) - (i64.store offset=48 - (get_local $6) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $6) - (tee_local $4 - (i64.load - (get_local $0) - ) - ) - ) - (i64.store offset=32 - (get_local $6) - (get_local $2) - ) - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.lt_s - (tee_local $3 - (call $db_find_i64 - (get_local $4) - (get_local $2) - (i64.const -4157508551318700032) - (get_local $2) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=48 - (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE31load_object_by_primary_iteratorEl - (i32.add - (get_local $6) - (i32.const 24) - ) - (get_local $3) - ) - ) - (i32.add - (get_local $6) - (i32.const 24) - ) - ) - (i32.const 224) - ) - (br $label$5) - ) - (set_local $5 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 3040) - ) - (set_local $4 - (i64.load - (get_local $1) - ) - ) - (i32.store offset=16 - (get_local $6) - (get_local $1) - ) - (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOS8_ - (i32.add - (get_local $6) - (i32.const 8) - ) - (i32.add - (get_local $6) - (i32.const 24) - ) - (get_local $4) - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (block $label$7 - (br_if $label$7 - (i32.eqz - (tee_local $1 - (i32.load offset=48 - (get_local $6) - ) - ) - ) - ) - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.eq - (tee_local $5 - (i32.load - (tee_local $0 - (i32.add - (get_local $6) - (i32.const 52) - ) - ) - ) - ) - (get_local $1) - ) - ) - (loop $label$10 - (set_local $3 - (i32.load - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $5) - (i32.const 0) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $3) - ) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (br_if $label$10 - (i32.ne - (get_local $1) - (get_local $5) - ) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $6) - (i32.const 48) - ) - ) - ) - (br $label$8) - ) - (set_local $5 - (get_local $1) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 64) - ) - ) - ) - (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOS8_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i64.store offset=40 - (get_local $7) - (get_local $2) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $1) - ) - (call $current_receiver) - ) - (i32.const 288) - ) - (i32.store offset=20 - (get_local $7) - (get_local $3) - ) - (i32.store offset=16 - (get_local $7) - (get_local $1) - ) - (i32.store offset=24 - (get_local $7) - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - (drop - (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE4itemC2IZNS3_7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOSA_EUlSB_E_EEPKS3_SE_ - (tee_local $3 - (call $_Znwj - (i32.const 64) - ) - ) - (get_local $1) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - (i32.store offset=32 - (get_local $7) - (get_local $3) - ) - (i64.store offset=16 - (get_local $7) - (tee_local $2 - (i64.shr_u - (i64.load offset=8 - (get_local $3) - ) - (i64.const 8) - ) - ) - ) - (i32.store offset=12 - (get_local $7) - (tee_local $4 - (i32.load offset=52 - (get_local $3) - ) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.load - (tee_local $6 - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - ) - ) - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - ) - (i64.store offset=8 - (get_local $5) - (get_local $2) - ) - (i32.store offset=16 - (get_local $5) - (get_local $4) - ) - (i32.store offset=32 - (get_local $7) - (i32.const 0) - ) - (i32.store - (get_local $5) - (get_local $3) - ) - (i32.store - (get_local $6) - (i32.add - (get_local $5) - (i32.const 24) - ) - ) - (br $label$0) - ) - (call $_ZNSt3__16vectorIN5eosio11multi_indexILy14289235522390851584ENS1_8currency14currency_statsEJEE8item_ptrENS_9allocatorIS6_EEE24__emplace_back_slow_pathIJNS_10unique_ptrINS5_4itemENS_14default_deleteISC_EEEERyRlEEEvDpOT_ - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.add - (get_local $7) - (i32.const 32) - ) - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store offset=4 - (get_local $0) - (get_local $3) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (set_local $1 - (i32.load offset=32 - (get_local $7) - ) - ) - (i32.store offset=32 - (get_local $7) - (i32.const 0) - ) - (block $label$2 - (br_if $label$2 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 48) - ) - ) - ) - (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE4itemC2IZNS3_7emplaceIZNS1_15create_currencyERKNS1_6createEEUlRT_E_EENS3_14const_iteratorEyOSA_EUlSB_E_EEPKS3_SE_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (set_local $5 - (call $_ZN5eosio8currency14currency_statsC2Ev - (get_local $0) - ) - ) - (i32.store offset=48 - (get_local $0) - (get_local $1) - ) - (i64.store offset=8 - (get_local $0) - (i64.load - (i32.add - (i32.load - (tee_local $1 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - (i32.const 16) - ) - ) - ) - (set_local $3 - (i32.load - (get_local $2) - ) - ) - (i64.store offset=16 - (get_local $0) - (i64.load offset=8 - (tee_local $6 - (i32.load - (get_local $1) - ) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i64.load - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - ) - (i64.store offset=32 - (get_local $0) - (i64.load - (i32.load - (get_local $1) - ) - ) - ) - (i32.store8 offset=40 - (get_local $0) - (i32.ne - (i32.load8_u offset=24 - (i32.load - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (i32.store8 offset=41 - (get_local $0) - (i32.ne - (i32.load8_u offset=25 - (i32.load - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (i32.store8 offset=42 - (get_local $0) - (i32.ne - (i32.load8_u offset=26 - (i32.load - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (i32.store offset=56 - (get_local $7) - (i32.add - (get_local $7) - (i32.const 45) - ) - ) - (i32.store offset=52 - (get_local $7) - (get_local $7) - ) - (i32.store offset=48 - (get_local $7) - (get_local $7) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE - (i32.add - (get_local $7) - (i32.const 48) - ) - (get_local $5) - ) - ) - (i32.store offset=52 - (get_local $0) - (call $db_store_i64 - (i64.load offset=8 - (get_local $3) - ) - (i64.const -4157508551318700032) - (i64.load - (i32.load offset=8 - (get_local $2) - ) - ) - (tee_local $4 - (i64.shr_u - (i64.load offset=8 - (get_local $0) - ) - (i64.const 8) - ) - ) - (get_local $7) - (i32.const 45) - ) - ) - (block $label$0 - (br_if $label$0 - (i64.lt_u - (get_local $4) - (i64.load offset=16 - (get_local $3) - ) - ) - ) - (i64.store - (i32.add - (get_local $3) - (i32.const 16) - ) - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 64) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio8exchange4lendEyNS_11symbol_typeENS_14extended_assetE (type $FUNCSIG$vijji) (param $0 i32) (param $1 i64) (param $2 i64) (param $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 464) - ) - ) - ) - (call $require_auth - (get_local $1) - ) - (set_local $8 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (tee_local $4 - (i64.load - (get_local $3) - ) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $6 - (i64.shr_u - (i64.load offset=8 - (get_local $3) - ) - (i64.const 8) - ) - ) - (set_local $7 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $6) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $8 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $8 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $8) - (i32.const 1840) - ) - (call $eosio_assert - (i64.gt_s - (get_local $4) - (i64.const 0) - ) - (i32.const 3088) - ) - (i64.store offset=8 - (get_local $9) - (i64.shr_u - (get_local $2) - (i64.const 8) - ) - ) - (set_local $6 - (i64.load - (get_local $0) - ) - ) - (set_local $7 - (call $_ZN5eosio14exchange_stateC2Ev - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 264) - ) - (i64.const -1) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 272) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 280) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 256) - ) - (tee_local $2 - (i64.load offset=8 - (get_local $9) - ) - ) - ) - (i64.store offset=248 - (get_local $9) - (get_local $6) - ) - (i64.store offset=288 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 296) - ) - (tee_local $5 - (i64.or - (tee_local $4 - (i64.shl - (get_local $2) - (i64.const 4) - ) - ) - (i64.const 1) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 304) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 312) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 316) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 320) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $9) - (i32.const 324) - ) - (i32.const 0) - ) - (i64.store offset=328 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 336) - ) - (tee_local $4 - (i64.or - (get_local $4) - (i64.const 2) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 344) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 352) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 356) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 360) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $9) - (i32.const 364) - ) - (i32.const 0) - ) - (i64.store offset=368 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 376) - ) - (get_local $5) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 384) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 392) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 396) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 400) - ) - (i32.const 0) - ) - (i64.store offset=408 - (get_local $9) - (get_local $6) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 416) - ) - (get_local $4) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 424) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 432) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 436) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 440) - ) - (i32.const 0) - ) - (i32.store offset=448 - (get_local $9) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy - (i32.add - (get_local $9) - (i32.const 452) - ) - (i32.add - (get_local $9) - (i32.const 248) - ) - (get_local $2) - ) - (call $eosio_assert - (i32.ne - (i32.load - (tee_local $8 - (i32.add - (get_local $9) - (i32.const 456) - ) - ) - ) - (i32.const 0) - ) - (i32.const 720) - ) - (drop - (call $memcpy - (get_local $7) - (i32.load - (get_local $8) - ) - (i32.const 232) - ) - ) - (call $_ZN5eosio12market_state4lendEyRKNS_14extended_assetE - (i32.add - (get_local $9) - (i32.const 8) - ) - (get_local $1) - (get_local $3) - ) - (call $_ZN5eosio12market_state4saveEv - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosio12market_stateD2Ev - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 464) - ) - ) - ) - (func $_ZN5eosio8exchange6unlendEyNS_11symbol_typeEdNS_15extended_symbolE (type $FUNCSIG$vijjdi) (param $0 i32) (param $1 i64) (param $2 i64) (param $3 f64) (param $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 464) - ) - ) - ) - (call $require_auth - (get_local $1) - ) - (call $eosio_assert - (f64.gt - (get_local $3) - (f64.const 0) - ) - (i32.const 3120) - ) - (i64.store offset=8 - (get_local $9) - (i64.shr_u - (get_local $2) - (i64.const 8) - ) - ) - (set_local $2 - (i64.load - (get_local $0) - ) - ) - (set_local $5 - (call $_ZN5eosio14exchange_stateC2Ev - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 264) - ) - (i64.const -1) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 272) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 280) - ) - (i32.const 0) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 256) - ) - (tee_local $6 - (i64.load offset=8 - (get_local $9) - ) - ) - ) - (i64.store offset=248 - (get_local $9) - (get_local $2) - ) - (i64.store offset=288 - (get_local $9) - (get_local $2) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 296) - ) - (tee_local $8 - (i64.or - (tee_local $7 - (i64.shl - (get_local $6) - (i64.const 4) - ) - ) - (i64.const 1) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 304) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 312) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 316) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 320) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $9) - (i32.const 324) - ) - (i32.const 0) - ) - (i64.store offset=328 - (get_local $9) - (get_local $2) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 336) - ) - (tee_local $7 - (i64.or - (get_local $7) - (i64.const 2) - ) - ) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 344) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 352) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 356) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 360) - ) - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $9) - (i32.const 364) - ) - (i32.const 0) - ) - (i64.store offset=368 - (get_local $9) - (get_local $2) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 376) - ) - (get_local $8) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 384) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 392) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 396) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 400) - ) - (i32.const 0) - ) - (i64.store offset=408 - (get_local $9) - (get_local $2) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 416) - ) - (get_local $7) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 424) - ) - (i64.const -1) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 432) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 436) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 440) - ) - (i32.const 0) - ) - (i32.store offset=448 - (get_local $9) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (call $_ZNK5eosio11multi_indexILy10497615196363685888ENS_14exchange_stateEJEE4findEy - (i32.add - (get_local $9) - (i32.const 452) - ) - (i32.add - (get_local $9) - (i32.const 248) - ) - (get_local $6) - ) - (call $eosio_assert - (i32.ne - (i32.load - (tee_local $0 - (i32.add - (get_local $9) - (i32.const 456) - ) - ) - ) - (i32.const 0) - ) - (i32.const 720) - ) - (drop - (call $memcpy - (get_local $5) - (i32.load - (get_local $0) - ) - (i32.const 232) - ) - ) - (call $_ZN5eosio12market_state6unlendEydRKNS_15extended_symbolE - (i32.add - (get_local $9) - (i32.const 8) - ) - (get_local $1) - (get_local $3) - (get_local $4) - ) - (call $_ZN5eosio12market_state4saveEv - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosio12market_stateD2Ev - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 464) - ) - ) - ) - (func $_ZN5eosio8exchange2onERKNS_8currency8transferEy (param $0 i32) (param $1 i32) (param $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i64) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $12 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (block $label$0 - (br_if $label$0 - (i64.ne - (tee_local $8 - (i64.load - (get_local $0) - ) - ) - (get_local $2) - ) - ) - (call $_ZN5eosio8currency2onERKNS0_8transferE - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $1) - ) - (set_local $8 - (i64.load - (get_local $0) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i64.ne - (i64.load offset=8 - (get_local $1) - ) - (get_local $8) - ) - ) - (set_local $4 - (i64.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (set_local $10 - (i32.const 0) - ) - (block $label$2 - (br_if $label$2 - (i64.gt_u - (i64.add - (tee_local $3 - (i64.load offset=16 - (get_local $1) - ) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $8 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (set_local $9 - (i32.const 0) - ) - (block $label$3 - (loop $label$4 - (br_if $label$3 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $8) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$5 - (br_if $label$5 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$6 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$6 - (i32.lt_s - (tee_local $9 - (i32.add - (get_local $9) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $10 - (i32.const 1) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $9 - (i32.add - (get_local $9) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$2) - ) - ) - (set_local $10 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $10) - (i32.const 3152) - ) - (call $eosio_assert - (i64.ne - (get_local $3) - (i64.const 0) - ) - (i32.const 3184) - ) - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i64.lt_s - (get_local $3) - (i64.const 1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3232) - ) - (set_local $11 - (i32.add - (get_local $1) - (i32.const 36) - ) - ) - (set_local $10 - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - (br $label$8) - ) - (set_local $9 - (i32.const 1) - ) - (set_local $10 - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - (set_local $6 - (i32.const 0) - ) - (block $label$10 - (br_if $label$10 - (i32.ne - (tee_local $5 - (call $strlen - (i32.const 1968) - ) - ) - (select - (i32.load - (tee_local $11 - (i32.add - (get_local $1) - (i32.const 36) - ) - ) - ) - (i32.shr_u - (tee_local $7 - (i32.load8_u offset=32 - (get_local $1) - ) - ) - (i32.const 1) - ) - (i32.and - (get_local $7) - (i32.const 1) - ) - ) - ) - ) - (set_local $6 - (i32.eqz - (call $_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEjjPKcj - (get_local $10) - (i32.const 0) - (i32.const -1) - (i32.const 1968) - (get_local $5) - ) - ) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 3232) - ) - (br_if $label$7 - (i64.lt_s - (get_local $3) - (i64.const 0) - ) - ) - ) - (set_local $9 - (i32.const 0) - ) - (br_if $label$7 - (i32.ne - (tee_local $6 - (call $strlen - (i32.const 1872) - ) - ) - (select - (i32.load - (get_local $11) - ) - (i32.shr_u - (tee_local $11 - (i32.load8_u - (get_local $10) - ) - ) - (i32.const 1) - ) - (i32.and - (get_local $11) - (i32.const 1) - ) - ) - ) - ) - (set_local $9 - (i32.eqz - (call $_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEjjPKcj - (get_local $10) - (i32.const 0) - (i32.const -1) - (i32.const 1872) - (get_local $6) - ) - ) - ) - ) - (call $eosio_assert - (get_local $9) - (i32.const 3280) - ) - (i64.store offset=32 - (get_local $12) - (get_local $4) - ) - (set_local $8 - (i64.load - (get_local $1) - ) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 8) - ) - (get_local $4) - ) - (i64.store offset=40 - (get_local $12) - (get_local $2) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 16) - ) - (get_local $2) - ) - (i64.store offset=24 - (get_local $12) - (get_local $3) - ) - (i64.store - (get_local $12) - (get_local $3) - ) - (call $_ZN5eosio17exchange_accounts14adjust_balanceEyNS_14extended_assetERKNSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEE - (i32.add - (get_local $0) - (i32.const 16) - ) - (get_local $8) - (get_local $12) - (get_local $9) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $12) - (i32.const 48) - ) - ) - ) - (func $_ZN5eosio8currency2onERKNS0_8transferE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i64) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (call $require_auth - (i64.load - (get_local $1) - ) - ) - (set_local $8 - (i64.load - (tee_local $10 - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - ) - (set_local $9 - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 0) - ) - (i64.store offset=88 - (get_local $11) - (i64.const -1) - ) - (i64.store offset=96 - (get_local $11) - (i64.const 0) - ) - (i64.store offset=72 - (get_local $11) - (i64.load - (get_local $0) - ) - ) - (i64.store offset=80 - (get_local $11) - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - ) - (set_local $2 - (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc - (i32.add - (get_local $11) - (i32.const 72) - ) - (get_local $8) - (i32.const 2224) - ) - ) - (call $require_recipient - (i64.load offset=8 - (get_local $1) - ) - ) - (set_local $3 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (i64.load offset=16 - (get_local $1) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $8 - (i64.shr_u - (i64.load - (get_local $10) - ) - (i64.const 8) - ) - ) - (set_local $10 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $8) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $10 - (i32.add - (get_local $10) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $9 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $10 - (i32.add - (get_local $10) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $9 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $9) - (i32.const 1840) - ) - (call $eosio_assert - (i64.gt_s - (i64.load - (get_local $3) - ) - (i64.const 0) - ) - (i32.const 3328) - ) - (i32.store - (tee_local $10 - (i32.add - (i32.add - (get_local $11) - (i32.const 56) - ) - (i32.const 12) - ) - ) - (i32.load - (tee_local $9 - (i32.add - (get_local $3) - (i32.const 12) - ) - ) - ) - ) - (i32.store - (tee_local $5 - (i32.add - (i32.add - (get_local $11) - (i32.const 56) - ) - (i32.const 8) - ) - ) - (i32.load - (tee_local $4 - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - ) - (i32.store offset=60 - (get_local $11) - (i32.load - (tee_local $6 - (i32.add - (get_local $3) - (i32.const 4) - ) - ) - ) - ) - (i32.store offset=56 - (get_local $11) - (i32.load - (get_local $3) - ) - ) - (set_local $8 - (i64.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.const 12) - ) - (i32.load - (get_local $10) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.const 8) - ) - (i32.load - (get_local $5) - ) - ) - (i32.store offset=28 - (get_local $11) - (i32.load offset=60 - (get_local $11) - ) - ) - (i32.store offset=24 - (get_local $11) - (i32.load offset=56 - (get_local $11) - ) - ) - (call $_ZN5eosio8currency11sub_balanceEyNS_5assetERKNS0_14currency_statsE - (get_local $0) - (get_local $8) - (i32.add - (get_local $11) - (i32.const 24) - ) - (get_local $2) - ) - (i32.store - (i32.add - (i32.add - (get_local $11) - (i32.const 40) - ) - (i32.const 12) - ) - (i32.load - (get_local $9) - ) - ) - (i32.store - (tee_local $10 - (i32.add - (i32.add - (get_local $11) - (i32.const 40) - ) - (i32.const 8) - ) - ) - (i32.load - (get_local $4) - ) - ) - (i32.store offset=44 - (get_local $11) - (i32.load - (get_local $6) - ) - ) - (i32.store offset=40 - (get_local $11) - (i32.load - (get_local $3) - ) - ) - (set_local $8 - (i64.load - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - (set_local $7 - (i64.load - (get_local $1) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.const 8) - ) - (i64.load - (get_local $10) - ) - ) - (i64.store offset=8 - (get_local $11) - (i64.load offset=40 - (get_local $11) - ) - ) - (call $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy - (get_local $0) - (get_local $8) - (i32.add - (get_local $11) - (i32.const 8) - ) - (get_local $2) - (get_local $7) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (tee_local $3 - (i32.load offset=96 - (get_local $11) - ) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.eq - (tee_local $10 - (i32.load - (tee_local $9 - (i32.add - (get_local $11) - (i32.const 100) - ) - ) - ) - ) - (get_local $3) - ) - ) - (loop $label$8 - (set_local $1 - (i32.load - (tee_local $10 - (i32.add - (get_local $10) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $10) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $3) - (get_local $10) - ) - ) - ) - (set_local $10 - (i32.load - (i32.add - (get_local $11) - (i32.const 96) - ) - ) - ) - (br $label$6) - ) - (set_local $10 - (get_local $3) - ) - ) - (i32.store - (get_local $9) - (get_local $3) - ) - (call $_ZdlPv - (get_local $10) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 112) - ) - ) - ) - (func $_ZN5eosio8currency11sub_balanceEyNS_5assetERKNS0_14currency_statsE (param $0 i32) (param $1 i64) (param $2 i32) (param $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $6 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store - (i32.add - (get_local $6) - (i32.const 40) - ) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $6) - (get_local $1) - ) - (i64.store offset=24 - (get_local $6) - (i64.const -1) - ) - (i64.store offset=32 - (get_local $6) - (i64.const 0) - ) - (i64.store offset=8 - (get_local $6) - (i64.load - (get_local $0) - ) - ) - (call $eosio_assert - (i64.ge_s - (i64.load - (tee_local $0 - (call $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE3getEyPKc - (i32.add - (get_local $6) - (i32.const 8) - ) - (i64.shr_u - (i64.load offset=8 - (get_local $2) - ) - (i64.const 8) - ) - (i32.const 2224) - ) - ) - ) - (i64.load - (get_local $2) - ) - ) - (i32.const 3360) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (call $has_auth - (get_local $1) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (set_local $4 - (i32.const 1) - ) - (block $label$2 - (br_if $label$2 - (i32.eqz - (i32.load8_u offset=40 - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.xor - (i32.load8_u offset=16 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (call $eosio_assert - (get_local $4) - (i32.const 3392) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (i32.load8_u - (i32.add - (get_local $3) - (i32.const 40) - ) - ) - ) - ) - (set_local $5 - (i32.xor - (i32.load8_u offset=43 - (get_local $3) - ) - (i32.const 1) - ) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 3424) - ) - (call $eosio_assert - (select - (i32.load8_u offset=17 - (get_local $0) - ) - (i32.const 1) - (i32.load8_u offset=44 - (get_local $3) - ) - ) - (i32.const 3472) - ) - (br $label$0) - ) - (block $label$4 - (br_if $label$4 - (i32.eqz - (call $has_auth - (i64.load offset=32 - (get_local $3) - ) - ) - ) - ) - (call $eosio_assert - (i32.load8_u offset=41 - (get_local $3) - ) - (i32.const 3504) - ) - (br $label$0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 3536) - ) - ) - (i32.store - (get_local $6) - (get_local $2) - ) - (call $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11sub_balanceEyNS_5assetERKNS1_14currency_statsEEUlRT_E_EEvRKS2_yOS9_ - (i32.add - (get_local $6) - (i32.const 8) - ) - (get_local $0) - (get_local $1) - (get_local $6) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (tee_local $0 - (i32.load offset=32 - (get_local $6) - ) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.eq - (tee_local $2 - (i32.load - (tee_local $5 - (i32.add - (get_local $6) - (i32.const 36) - ) - ) - ) - ) - (get_local $0) - ) - ) - (loop $label$8 - (set_local $3 - (i32.load - (tee_local $2 - (i32.add - (get_local $2) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $2) - (i32.const 0) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $3) - ) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $0) - (get_local $2) - ) - ) - ) - (set_local $2 - (i32.load - (i32.add - (get_local $6) - (i32.const 32) - ) - ) - ) - (br $label$6) - ) - (set_local $2 - (get_local $0) - ) - ) - (i32.store - (get_local $5) - (get_local $0) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 48) - ) - ) - ) - (func $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE3getEyPKc (param $0 i32) (param $1 i64) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (tee_local $3 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (set_local $4 - (i32.sub - (i32.const 0) - (get_local $3) - ) - ) - (loop $label$1 - (br_if $label$0 - (i64.eq - (i64.shr_u - (i64.load offset=8 - (i32.load - (get_local $6) - ) - ) - (i64.const 8) - ) - (get_local $1) - ) - ) - (set_local $7 - (get_local $6) - ) - (set_local $6 - (tee_local $5 - (i32.add - (get_local $6) - (i32.const -24) - ) - ) - ) - (br_if $label$1 - (i32.ne - (i32.add - (get_local $5) - (get_local $4) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $3) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load - (i32.add - (tee_local $6 - (i32.load - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - ) - (i32.const 20) - ) - ) - (get_local $0) - ) - (i32.const 224) - ) - (br $label$2) - ) - (set_local $6 - (i32.const 0) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $5 - (call $db_find_i64 - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - (i64.const 3607749779137757184) - (get_local $1) - ) - ) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=20 - (tee_local $6 - (call $_ZNK5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE31load_object_by_primary_iteratorEl - (get_local $0) - (get_local $5) - ) - ) - ) - (get_local $0) - ) - (i32.const 224) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $6) - (i32.const 0) - ) - (get_local $2) - ) - (get_local $6) - ) - (func $_ZN5eosio11multi_indexILy3607749779137757184ENS_8currency7accountEJEE6modifyIZNS1_11sub_balanceEyNS_5assetERKNS1_14currency_statsEEUlRT_E_EEvRKS2_yOS9_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) - (local $4 i64) - (local $5 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $5 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - (get_local $0) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $0) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (i64.store - (get_local $1) - (i64.sub - (i64.load - (get_local $1) - ) - (i64.load - (i32.load - (get_local $3) - ) - ) - ) - ) - (set_local $4 - (i64.load offset=8 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 544) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $1) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.or - (get_local $5) - (i32.const 8) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store8 offset=31 - (get_local $5) - (i32.load8_u offset=16 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $5) - (i32.const 16) - ) - (i32.add - (get_local $5) - (i32.const 31) - ) - (i32.const 1) - ) - ) - (i32.store8 offset=31 - (get_local $5) - (i32.load8_u offset=17 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 608) - ) - (drop - (call $memcpy - (i32.add - (get_local $5) - (i32.const 17) - ) - (i32.add - (get_local $5) - (i32.const 31) - ) - (i32.const 1) - ) - ) - (call $db_update_i64 - (i32.load offset=24 - (get_local $1) - ) - (get_local $2) - (get_local $5) - (i32.const 18) - ) - (block $label$0 - (br_if $label$0 - (i64.lt_u - (tee_local $2 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.load offset=16 - (get_local $0) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.add - (get_local $2) - (i64.const 1) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $5) - (i32.const 32) - ) - ) - ) - (func $_ZN5eosio8exchange5applyEyy (param $0 i32) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 160) - ) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 1904) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $6) - (i64.const 7) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i64.ne - (get_local $7) - (get_local $2) - ) - ) - (call $_ZN5eosio18unpack_action_dataINS_8currency8transferEEET_v - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - (call $_ZN5eosio8exchange2onERKNS_8currency8transferEy - (get_local $0) - (i32.add - (get_local $9) - (i32.const 48) - ) - (get_local $1) - ) - (br_if $label$6 - (i32.eqz - (i32.and - (i32.load8_u offset=80 - (get_local $9) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $9) - (i32.const 88) - ) - ) - ) - (br $label$6) - ) - (br_if $label$6 - (i64.ne - (i64.load - (get_local $0) - ) - (get_local $1) - ) - ) - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_if $label$15 - (i64.gt_s - (get_local $2) - (i64.const -2039333636196532225) - ) - ) - (br_if $label$14 - (i64.gt_s - (get_local $2) - (i64.const -3106734271092490241) - ) - ) - (br_if $label$12 - (i64.eq - (get_local $2) - (i64.const -8455912920667127808) - ) - ) - (br_if $label$8 - (i64.ne - (get_local $2) - (i64.const -3617352573452812288) - ) - ) - (call $_ZN5eosio18unpack_action_dataINS_8exchange5tradeEEET_v - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - (call $_ZN5eosio8exchange2onERKNS0_5tradeE - (get_local $0) - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - (br $label$6) - ) - (br_if $label$13 - (i64.gt_s - (get_local $2) - (i64.const 5031766168059248639) - ) - ) - (br_if $label$11 - (i64.eq - (get_local $2) - (i64.const -2039333636196532224) - ) - ) - (br_if $label$8 - (i64.ne - (get_local $2) - (i64.const 4987362516454843904) - ) - ) - (call $_ZN5eosio18unpack_action_dataINS_8exchange11covermarginEEET_v - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - (call $_ZN5eosio8exchange2onERKNS0_11covermarginE - (get_local $0) - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - (br $label$6) - ) - (br_if $label$10 - (i64.eq - (get_local $2) - (i64.const -3106734271092490240) - ) - ) - (br_if $label$8 - (i64.ne - (get_local $2) - (i64.const -3070210634466459648) - ) - ) - (call $_ZN5eosio18unpack_action_dataINS_8exchange8upmarginEEET_v - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - (call $_ZN5eosio8exchange2onERKNS0_8upmarginE - (get_local $0) - (i32.add - (get_local $9) - (i32.const 48) - ) - ) - (br $label$6) - ) - (br_if $label$9 - (i64.eq - (get_local $2) - (i64.const 5380477996647841792) - ) - ) - (br_if $label$8 - (i64.ne - (get_local $2) - (i64.const 5031766168059248640) - ) - ) - (i32.store offset=156 - (get_local $9) - (i32.const 0) - ) - (i32.store offset=152 - (get_local $9) - (i32.const 1) - ) - (i64.store offset=8 align=4 - (get_local $9) - (i64.load offset=152 - (get_local $9) - ) - ) - (drop - (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_5assetEmNS_14extended_assetES3_EEEbPT_MT0_FvDpT1_E - (get_local $0) - (i32.add - (get_local $9) - (i32.const 8) - ) - ) - ) - (br $label$8) - ) - (i32.store offset=132 - (get_local $9) - (i32.const 0) - ) - (i32.store offset=128 - (get_local $9) - (i32.const 2) - ) - (i64.store offset=32 align=4 - (get_local $9) - (i64.load offset=128 - (get_local $9) - ) - ) - (drop - (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeENS_14extended_assetEEEEbPT_MT0_FvDpT1_E - (get_local $0) - (i32.add - (get_local $9) - (i32.const 32) - ) - ) - ) - (br $label$8) - ) - (i32.store offset=140 - (get_local $9) - (i32.const 0) - ) - (i32.store offset=136 - (get_local $9) - (i32.const 3) - ) - (i64.store offset=24 align=4 - (get_local $9) - (i64.load offset=136 - (get_local $9) - ) - ) - (drop - (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_14extended_assetEEEEbPT_MT0_FvDpT1_E - (get_local $0) - (i32.add - (get_local $9) - (i32.const 24) - ) - ) - ) - (br $label$8) - ) - (i32.store offset=124 - (get_local $9) - (i32.const 0) - ) - (i32.store offset=120 - (get_local $9) - (i32.const 4) - ) - (i64.store offset=40 align=4 - (get_local $9) - (i64.load offset=120 - (get_local $9) - ) - ) - (drop - (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeEdNS_15extended_symbolEEEEbPT_MT0_FvDpT1_E - (get_local $0) - (i32.add - (get_local $9) - (i32.const 40) - ) - ) - ) - (br $label$8) - ) - (i32.store offset=148 - (get_local $9) - (i32.const 0) - ) - (i32.store offset=144 - (get_local $9) - (i32.const 5) - ) - (i64.store offset=16 align=4 - (get_local $9) - (i64.load offset=144 - (get_local $9) - ) - ) - (drop - (call $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_14extended_assetEEEEbPT_MT0_FvDpT1_E - (get_local $0) - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - ) - ) - (drop - (call $_ZN5eosio8currency5applyEyy - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $1) - (get_local $2) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 160) - ) - ) - ) - (func $_ZN5eosio18unpack_action_dataINS_8currency8transferEEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (set_local $6 - (tee_local $4 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $4) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $2 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $4) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $2) - (get_local $1) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i64.const 1398362884) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $3 - (i64.const 5462355) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$2 - (block $label$3 - (loop $label$4 - (br_if $label$3 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $3) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$5 - (br_if $label$5 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$6 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$6 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$2) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 80) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 40) - ) - (i32.const 0) - ) - (i64.store offset=32 align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store offset=4 - (get_local $6) - (get_local $2) - ) - (i32.store - (get_local $6) - (get_local $2) - ) - (i32.store offset=8 - (get_local $6) - (i32.add - (get_local $2) - (get_local $1) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency8transferE - (get_local $6) - (get_local $0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_5assetEmNS_14extended_assetES3_EEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (set_local $10 - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 336) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $8) - ) - (set_local $2 - (i32.load offset=4 - (get_local $1) - ) - ) - (set_local $9 - (i32.load - (get_local $1) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (call $action_data_size) - ) - ) - ) - (br_if $label$2 - (i32.lt_u - (get_local $1) - (i32.const 513) - ) - ) - (set_local $8 - (call $malloc - (get_local $1) - ) - ) - (br $label$1) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (get_local $8) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $8) - (get_local $1) - ) - ) - ) - (call $_ZN5eosio6unpackINSt3__15tupleIJyNS_5assetEmNS_14extended_assetES4_EEEEET_PKcj - (i32.add - (get_local $10) - (i32.const 64) - ) - (get_local $8) - (get_local $1) - ) - (block $label$4 - (br_if $label$4 - (i32.lt_u - (get_local $1) - (i32.const 513) - ) - ) - (call $free - (get_local $8) - ) - ) - (i64.store - (tee_local $1 - (i32.add - (i32.add - (get_local $10) - (i32.const 192) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 16) - ) - ) - ) - (set_local $3 - (i64.load offset=64 - (get_local $10) - ) - ) - (i64.store offset=192 - (get_local $10) - (i64.load offset=72 - (get_local $10) - ) - ) - (set_local $8 - (i32.load offset=88 - (get_local $10) - ) - ) - (i64.store - (tee_local $4 - (i32.add - (i32.add - (get_local $10) - (i32.const 168) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const 112) - ) - ) - ) - (i64.store - (tee_local $5 - (i32.add - (i32.add - (get_local $10) - (i32.const 168) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const 104) - ) - ) - ) - (i64.store offset=168 - (get_local $10) - (i64.load offset=96 - (get_local $10) - ) - ) - (i64.store - (tee_local $6 - (i32.add - (i32.add - (get_local $10) - (i32.const 144) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const 136) - ) - ) - ) - (i64.store - (tee_local $7 - (i32.add - (i32.add - (get_local $10) - (i32.const 144) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $10) - (i32.const 128) - ) - ) - ) - (i64.store offset=144 - (get_local $10) - (i64.load offset=120 - (get_local $10) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 248) - ) - (i32.const 16) - ) - (i64.load - (get_local $6) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 248) - ) - (i32.const 8) - ) - (i64.load - (get_local $7) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 224) - ) - (i32.const 16) - ) - (i64.load - (get_local $4) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 224) - ) - (i32.const 8) - ) - (i64.load - (get_local $5) - ) - ) - (i64.store offset=248 - (get_local $10) - (i64.load offset=144 - (get_local $10) - ) - ) - (i64.store offset=224 - (get_local $10) - (i64.load offset=168 - (get_local $10) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 8) - ) - (i64.load - (get_local $1) - ) - ) - (i64.store offset=208 - (get_local $10) - (i64.load offset=192 - (get_local $10) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.shr_s - (get_local $2) - (i32.const 1) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (i32.and - (get_local $2) - (i32.const 1) - ) - ) - ) - (set_local $9 - (i32.load - (i32.add - (i32.load - (get_local $1) - ) - (get_local $9) - ) - ) - ) - ) - (i64.store - (tee_local $2 - (i32.add - (i32.add - (get_local $10) - (i32.const 320) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 8) - ) - ) - ) - (i64.store - (tee_local $0 - (i32.add - (i32.add - (get_local $10) - (i32.const 296) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 224) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (tee_local $4 - (i32.add - (i32.add - (get_local $10) - (i32.const 296) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 224) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=320 - (get_local $10) - (i64.load offset=208 - (get_local $10) - ) - ) - (i64.store offset=296 - (get_local $10) - (i64.load offset=224 - (get_local $10) - ) - ) - (i64.store - (tee_local $5 - (i32.add - (i32.add - (get_local $10) - (i32.const 272) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 248) - ) - (i32.const 16) - ) - ) - ) - (i64.store - (tee_local $6 - (i32.add - (i32.add - (get_local $10) - (i32.const 272) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (i32.add - (get_local $10) - (i32.const 248) - ) - (i32.const 8) - ) - ) - ) - (i64.store offset=272 - (get_local $10) - (i64.load offset=248 - (get_local $10) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 48) - ) - (i32.const 8) - ) - (i64.load - (get_local $2) - ) - ) - (i64.store offset=48 - (get_local $10) - (i64.load offset=320 - (get_local $10) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.const 16) - ) - (i64.load - (get_local $0) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.const 8) - ) - (i64.load - (get_local $4) - ) - ) - (i64.store offset=24 - (get_local $10) - (i64.load offset=296 - (get_local $10) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 16) - ) - (i64.load - (get_local $5) - ) - ) - (i64.store - (i32.add - (get_local $10) - (i32.const 8) - ) - (i64.load - (get_local $6) - ) - ) - (i64.store - (get_local $10) - (i64.load offset=272 - (get_local $10) - ) - ) - (call_indirect (type $FUNCSIG$vijiiii) - (get_local $1) - (get_local $3) - (i32.add - (get_local $10) - (i32.const 48) - ) - (get_local $8) - (i32.add - (get_local $10) - (i32.const 24) - ) - (get_local $10) - (get_local $9) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 336) - ) - ) - (i32.const 1) - ) - (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_14extended_assetEEEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (local $8 i64) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (set_local $11 - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 128) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $9) - ) - (set_local $2 - (i32.load offset=4 - (get_local $1) - ) - ) - (set_local $10 - (i32.load - (get_local $1) - ) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $7 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $3 - (call $action_data_size) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.lt_u - (get_local $3) - (i32.const 513) - ) - ) - (set_local $7 - (call $malloc - (get_local $3) - ) - ) - (br $label$1) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (get_local $9) - (i32.and - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $7) - (get_local $3) - ) - ) - ) - (i64.store - (tee_local $4 - (i32.add - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 40) - ) - (i64.const 1398362884) - ) - (i64.store offset=24 - (get_local $11) - (i64.const 0) - ) - (i64.store offset=32 - (get_local $11) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $8 - (i64.const 5462355) - ) - (block $label$3 - (loop $label$4 - (set_local $9 - (i32.const 0) - ) - (br_if $label$3 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $8) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$5 - (br_if $label$5 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$6 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$6 - (i32.lt_s - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $9 - (i32.const 1) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (call $eosio_assert - (get_local $9) - (i32.const 80) - ) - (call $eosio_assert - (i32.gt_u - (get_local $3) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $11) - (i32.const 24) - ) - (get_local $7) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (tee_local $9 - (i32.and - (get_local $3) - (i32.const -8) - ) - ) - (i32.const 8) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (tee_local $1 - (i32.add - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $9) - (i32.const 16) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (i32.add - (get_local $11) - (i32.const 24) - ) - (i32.const 16) - ) - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $9) - (i32.const 24) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $4) - (i32.add - (get_local $7) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (block $label$7 - (br_if $label$7 - (i32.lt_u - (get_local $3) - (i32.const 513) - ) - ) - (call $free - (get_local $7) - ) - ) - (i64.store - (tee_local $9 - (i32.add - (i32.add - (get_local $11) - (i32.const 56) - ) - (i32.const 16) - ) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i64.store - (tee_local $7 - (i32.add - (i32.add - (get_local $11) - (i32.const 56) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - (set_local $8 - (i64.load offset=24 - (get_local $11) - ) - ) - (i64.store offset=56 - (get_local $11) - (i64.load - (get_local $1) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 80) - ) - (i32.const 16) - ) - (i64.load - (get_local $9) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 80) - ) - (i32.const 8) - ) - (i64.load - (get_local $7) - ) - ) - (i64.store offset=80 - (get_local $11) - (i64.load offset=56 - (get_local $11) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.shr_s - (get_local $2) - (i32.const 1) - ) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.eqz - (i32.and - (get_local $2) - (i32.const 1) - ) - ) - ) - (set_local $10 - (i32.load - (i32.add - (i32.load - (get_local $1) - ) - (get_local $10) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 16) - ) - (tee_local $5 - (i64.load - (i32.add - (i32.add - (get_local $11) - (i32.const 80) - ) - (i32.const 16) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 8) - ) - (tee_local $6 - (i64.load - (i32.add - (i32.add - (get_local $11) - (i32.const 80) - ) - (i32.const 8) - ) - ) - ) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 16) - ) - (get_local $5) - ) - (i64.store - (i32.add - (get_local $11) - (i32.const 8) - ) - (get_local $6) - ) - (i64.store offset=104 - (get_local $11) - (tee_local $5 - (i64.load offset=80 - (get_local $11) - ) - ) - ) - (i64.store - (get_local $11) - (get_local $5) - ) - (call_indirect (type $FUNCSIG$viji) - (get_local $1) - (get_local $8) - (get_local $11) - (get_local $10) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 128) - ) - ) - (i32.const 1) - ) - (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeENS_14extended_assetEEEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (set_local $9 - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 144) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $7) - ) - (set_local $2 - (i32.load offset=4 - (get_local $1) - ) - ) - (set_local $8 - (i32.load - (get_local $1) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (call $action_data_size) - ) - ) - ) - (br_if $label$2 - (i32.lt_u - (get_local $1) - (i32.const 513) - ) - ) - (set_local $7 - (call $malloc - (get_local $1) - ) - ) - (br $label$1) - ) - (set_local $7 - (i32.const 0) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (get_local $7) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $7) - (get_local $1) - ) - ) - ) - (call $_ZN5eosio6unpackINSt3__15tupleIJyNS_11symbol_typeENS_14extended_assetEEEEEET_PKcj - (i32.add - (get_local $9) - (i32.const 32) - ) - (get_local $7) - (get_local $1) - ) - (block $label$4 - (br_if $label$4 - (i32.lt_u - (get_local $1) - (i32.const 513) - ) - ) - (call $free - (get_local $7) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $9) - (i32.const 72) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (get_local $9) - (i32.const 68) - ) - ) - ) - (i32.store - (tee_local $1 - (i32.add - (i32.add - (get_local $9) - (i32.const 72) - ) - (i32.const 16) - ) - ) - (i32.load - (i32.add - (get_local $9) - (i32.const 64) - ) - ) - ) - (set_local $4 - (i64.load offset=40 - (get_local $9) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 84) - ) - (i32.load - (i32.add - (get_local $9) - (i32.const 60) - ) - ) - ) - (i32.store - (tee_local $7 - (i32.add - (i32.add - (get_local $9) - (i32.const 72) - ) - (i32.const 8) - ) - ) - (i32.load - (i32.add - (get_local $9) - (i32.const 56) - ) - ) - ) - (set_local $3 - (i64.load offset=32 - (get_local $9) - ) - ) - (i32.store offset=72 - (get_local $9) - (i32.load offset=48 - (get_local $9) - ) - ) - (i32.store offset=76 - (get_local $9) - (i32.load - (i32.add - (i32.add - (get_local $9) - (i32.const 32) - ) - (i32.const 20) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 16) - ) - (i64.load - (get_local $1) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 8) - ) - (i64.load - (get_local $7) - ) - ) - (i64.store offset=96 - (get_local $9) - (i64.load offset=72 - (get_local $9) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.shr_s - (get_local $2) - (i32.const 1) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (i32.and - (get_local $2) - (i32.const 1) - ) - ) - ) - (set_local $8 - (i32.load - (i32.add - (i32.load - (get_local $1) - ) - (get_local $8) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 120) - ) - (i32.const 16) - ) - (tee_local $5 - (i64.load - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 16) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 120) - ) - (i32.const 8) - ) - (tee_local $6 - (i64.load - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 8) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 8) - ) - (i32.const 16) - ) - (get_local $5) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 8) - ) - (i32.const 8) - ) - (get_local $6) - ) - (i64.store offset=120 - (get_local $9) - (tee_local $5 - (i64.load offset=96 - (get_local $9) - ) - ) - ) - (i64.store offset=8 - (get_local $9) - (get_local $5) - ) - (call_indirect (type $FUNCSIG$vijji) - (get_local $1) - (get_local $3) - (get_local $4) - (i32.add - (get_local $9) - (i32.const 8) - ) - (get_local $8) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 144) - ) - ) - (i32.const 1) - ) - (func $_ZN5eosio14execute_actionINS_8exchangeES1_JyNS_11symbol_typeEdNS_15extended_symbolEEEEbPT_MT0_FvDpT1_E (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 f64) - (local $7 i64) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (set_local $9 - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $10) - ) - (set_local $2 - (i32.load offset=4 - (get_local $1) - ) - ) - (set_local $8 - (i32.load - (get_local $1) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $3 - (call $action_data_size) - ) - ) - ) - (br_if $label$2 - (i32.lt_u - (get_local $3) - (i32.const 513) - ) - ) - (set_local $1 - (call $malloc - (get_local $3) - ) - ) - (br $label$1) - ) - (set_local $1 - (i32.const 0) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $1 - (i32.sub - (get_local $10) - (i32.and - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $1) - (get_local $3) - ) - ) - ) - (i64.store - (tee_local $10 - (i32.add - (get_local $9) - (i32.const 56) - ) - ) - (i64.const 0) - ) - (i64.store offset=40 - (get_local $9) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $9) - (i64.const 0) - ) - (i64.store offset=48 - (get_local $9) - (i64.const 0) - ) - (i32.store offset=100 - (get_local $9) - (get_local $1) - ) - (i32.store offset=96 - (get_local $9) - (get_local $1) - ) - (i32.store offset=104 - (get_local $9) - (i32.add - (get_local $1) - (get_local $3) - ) - ) - (i32.store offset=64 - (get_local $9) - (i32.add - (get_local $9) - (i32.const 96) - ) - ) - (i32.store offset=80 - (get_local $9) - (i32.add - (get_local $9) - (i32.const 24) - ) - ) - (call $_ZN5boost6fusion6detail17for_each_unrolledILi4EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio11symbol_typeEdNS8_15extended_symbolEEEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_dSA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ - (i32.add - (get_local $9) - (i32.const 80) - ) - (i32.add - (get_local $9) - (i32.const 64) - ) - ) - (block $label$4 - (br_if $label$4 - (i32.lt_u - (get_local $3) - (i32.const 513) - ) - ) - (call $free - (get_local $1) - ) - ) - (set_local $5 - (i64.load offset=32 - (get_local $9) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 76) - ) - (i32.load - (i32.add - (get_local $9) - (i32.const 60) - ) - ) - ) - (i32.store - (tee_local $1 - (i32.add - (i32.add - (get_local $9) - (i32.const 64) - ) - (i32.const 8) - ) - ) - (i32.load - (get_local $10) - ) - ) - (set_local $4 - (i64.load offset=24 - (get_local $9) - ) - ) - (i32.store offset=64 - (get_local $9) - (i32.load offset=48 - (get_local $9) - ) - ) - (i32.store offset=68 - (get_local $9) - (i32.load - (i32.add - (get_local $9) - (i32.const 52) - ) - ) - ) - (set_local $6 - (f64.load - (i32.add - (get_local $9) - (i32.const 40) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 80) - ) - (i32.const 8) - ) - (i64.load - (get_local $1) - ) - ) - (i64.store offset=80 - (get_local $9) - (i64.load offset=64 - (get_local $9) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.shr_s - (get_local $2) - (i32.const 1) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (i32.and - (get_local $2) - (i32.const 1) - ) - ) - ) - (set_local $8 - (i32.load - (i32.add - (i32.load - (get_local $1) - ) - (get_local $8) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.const 8) - ) - (tee_local $7 - (i64.load - (i32.add - (i32.add - (get_local $9) - (i32.const 80) - ) - (i32.const 8) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $9) - (i32.const 8) - ) - (i32.const 8) - ) - (get_local $7) - ) - (i64.store offset=96 - (get_local $9) - (tee_local $7 - (i64.load offset=80 - (get_local $9) - ) - ) - ) - (i64.store offset=8 - (get_local $9) - (get_local $7) - ) - (call_indirect (type $FUNCSIG$vijjdi) - (get_local $1) - (get_local $4) - (get_local $5) - (get_local $6) - (i32.add - (get_local $9) - (i32.const 8) - ) - (get_local $8) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 112) - ) - ) - (i32.const 1) - ) - (func $_ZN5eosio18unpack_action_dataINS_8exchange5tradeEEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (set_local $4 - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $2) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $3 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (get_local $2) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $3) - (get_local $1) - ) - ) - (set_local $2 - (call $_ZN5eosio8exchange5tradeC2Ev - (get_local $0) - ) - ) - (i32.store offset=4 - (get_local $4) - (get_local $3) - ) - (i32.store - (get_local $4) - (get_local $3) - ) - (i32.store offset=8 - (get_local $4) - (i32.add - (get_local $3) - (get_local $1) - ) - ) - (i32.store offset=16 - (get_local $4) - (get_local $4) - ) - (i32.store offset=28 - (get_local $4) - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - (i32.store offset=24 - (get_local $4) - (get_local $2) - ) - (i32.store offset=32 - (get_local $4) - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - (i32.store offset=36 - (get_local $4) - (i32.add - (get_local $2) - (i32.const 40) - ) - ) - (i32.store offset=40 - (get_local $4) - (i32.add - (get_local $2) - (i32.const 64) - ) - ) - (i32.store offset=44 - (get_local $4) - (i32.add - (get_local $2) - (i32.const 68) - ) - ) - (call $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_RmRhEEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange5tradeELPv0EEERT_SN_RT0_EUlSN_E_JLj0ELj1ELj2ELj3ELj4ELj5EEEEvSN_OSO_NSt3__116integer_sequenceIjJXspT1_EEEENSS_17integral_constantIbLb0EEE - (i32.add - (get_local $4) - (i32.const 24) - ) - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $4) - (i32.const 48) - ) - ) - ) - (func $_ZN5eosio18unpack_action_dataINS_8exchange8upmarginEEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (set_local $3 - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $2) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $2 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $2) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $2) - (get_local $1) - ) - ) - (set_local $0 - (call $_ZN5eosio8exchange8upmarginC2Ev - (get_local $0) - ) - ) - (i32.store offset=12 - (get_local $3) - (get_local $2) - ) - (i32.store offset=8 - (get_local $3) - (get_local $2) - ) - (i32.store offset=16 - (get_local $3) - (i32.add - (get_local $2) - (get_local $1) - ) - ) - (i32.store offset=24 - (get_local $3) - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - (i32.store offset=36 - (get_local $3) - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (i32.store offset=32 - (get_local $3) - (get_local $0) - ) - (i32.store offset=40 - (get_local $3) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (i32.store offset=44 - (get_local $3) - (i32.add - (get_local $0) - (i32.const 40) - ) - ) - (call $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_EEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange8upmarginELPv0EEERT_SL_RT0_EUlSL_E_JLj0ELj1ELj2ELj3EEEEvSL_OSM_NSt3__116integer_sequenceIjJXspT1_EEEENSQ_17integral_constantIbLb0EEE - (i32.add - (get_local $3) - (i32.const 32) - ) - (i32.add - (get_local $3) - (i32.const 24) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 48) - ) - ) - ) - (func $_ZN5eosio18unpack_action_dataINS_8exchange11covermarginEEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (set_local $3 - (tee_local $2 - (i32.load offset=4 - (i32.const 0) - ) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $2 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $2) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $2) - (get_local $1) - ) - ) - (call $_ZN5eosio6unpackINS_8exchange11covermarginEEET_PKcj - (get_local $0) - (get_local $2) - (get_local $1) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $3) - ) - ) - (func $_ZN5eosio8currency5applyEyy (param $0 i32) (param $1 i64) (param $2 i64) (result i32) - (local $3 i32) - (local $4 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (set_local $3 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i64.ne - (i64.load - (get_local $0) - ) - (get_local $1) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i64.eq - (get_local $2) - (i64.const -3617168760277827584) - ) - ) - (br_if $label$1 - (i64.eq - (get_local $2) - (i64.const 5031766152489992192) - ) - ) - (br_if $label$0 - (i64.ne - (get_local $2) - (i64.const 8516769789752901632) - ) - ) - (call $prints - (i32.const 3568) - ) - (call $_ZN5eosio18unpack_action_dataINS_8currency5issueEEET_v - (get_local $4) - ) - (call $_ZN5eosio8currency2onERKNS0_5issueE - (get_local $0) - (get_local $4) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$0 - (i32.eqz - (i32.and - (i32.load8_u offset=24 - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $4) - (i32.const 32) - ) - ) - ) - (br $label$0) - ) - (call $prints - (i32.const 3584) - ) - (call $_ZN5eosio18unpack_action_dataINS_8currency8transferEEET_v - (get_local $4) - ) - (call $_ZN5eosio8currency2onERKNS0_8transferE - (get_local $0) - (get_local $4) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$0 - (i32.eqz - (i32.and - (i32.load8_u offset=32 - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $4) - (i32.const 40) - ) - ) - ) - (br $label$0) - ) - (call $prints - (i32.const 3600) - ) - (call $_ZN5eosio18unpack_action_dataINS_8currency6createEEET_v - (get_local $4) - ) - (call $require_auth - (i64.load - (get_local $4) - ) - ) - (call $_ZN5eosio8currency15create_currencyERKNS0_6createE - (get_local $0) - (get_local $4) - ) - (set_local $3 - (i32.const 1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $4) - (i32.const 48) - ) - ) - (get_local $3) - ) - (func $_ZN5eosio18unpack_action_dataINS_8currency5issueEEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (set_local $6 - (tee_local $4 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $4) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $2 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $4) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $2) - (get_local $1) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.const 1398362884) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $3 - (i64.const 5462355) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$2 - (block $label$3 - (loop $label$4 - (br_if $label$3 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $3) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$5 - (br_if $label$5 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$6 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$6 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$2) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 80) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (i32.const 0) - ) - (i64.store offset=24 align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store - (get_local $6) - (get_local $2) - ) - (i32.store offset=8 - (get_local $6) - (tee_local $4 - (i32.add - (get_local $2) - (get_local $1) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (get_local $1) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $2) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (get_local $4) - (tee_local $5 - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $5) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (get_local $4) - (tee_local $5 - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 16) - ) - (get_local $5) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $6) - (i32.add - (get_local $2) - (i32.const 24) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE - (get_local $6) - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosio8currency2onERKNS0_5issueE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i32) - (local $12 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $12 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 128) - ) - ) - ) - (set_local $8 - (i64.load - (tee_local $11 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 88) - ) - (i32.const 32) - ) - (i32.const 0) - ) - (i64.store offset=104 - (get_local $12) - (i64.const -1) - ) - (i64.store offset=112 - (get_local $12) - (i64.const 0) - ) - (i64.store offset=88 - (get_local $12) - (i64.load - (get_local $0) - ) - ) - (i64.store offset=96 - (get_local $12) - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - ) - (call $require_auth - (i64.load offset=32 - (tee_local $2 - (call $_ZNK5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE3getEyPKc - (i32.add - (get_local $12) - (i32.const 88) - ) - (get_local $8) - (i32.const 2224) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (block $label$0 - (br_if $label$0 - (i64.gt_u - (i64.add - (i64.load offset=8 - (get_local $1) - ) - (i64.const 4611686018427387903) - ) - (i64.const 9223372036854775806) - ) - ) - (set_local $8 - (i64.shr_u - (i64.load - (get_local $11) - ) - (i64.const 8) - ) - ) - (set_local $11 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $8) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $11 - (i32.add - (get_local $11) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $6 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $11 - (i32.add - (get_local $11) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $6 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 1840) - ) - (call $eosio_assert - (i64.gt_s - (i64.load - (get_local $5) - ) - (i64.const 0) - ) - (i32.const 3616) - ) - (i32.store offset=80 - (get_local $12) - (get_local $1) - ) - (call $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_2onERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ - (i32.add - (get_local $12) - (i32.const 88) - ) - (get_local $2) - (i64.const 0) - (i32.add - (get_local $12) - (i32.const 80) - ) - ) - (set_local $8 - (i64.load - (tee_local $11 - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - ) - (i64.store - (tee_local $6 - (i32.add - (i32.add - (get_local $12) - (i32.const 64) - ) - (i32.const 8) - ) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i64.store offset=64 - (get_local $12) - (i64.load - (get_local $5) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $12) - (i32.const 16) - ) - (i32.const 8) - ) - (i64.load - (get_local $6) - ) - ) - (i32.store offset=16 - (get_local $12) - (i32.load offset=64 - (get_local $12) - ) - ) - (i32.store offset=20 - (get_local $12) - (i32.load offset=68 - (get_local $12) - ) - ) - (call $_ZN5eosio8currency11add_balanceEyNS_5assetERKNS0_14currency_statsEy - (get_local $0) - (get_local $8) - (i32.add - (get_local $12) - (i32.const 16) - ) - (get_local $2) - (get_local $8) - ) - (block $label$5 - (br_if $label$5 - (i64.eq - (tee_local $3 - (i64.load - (get_local $1) - ) - ) - (tee_local $4 - (i64.load - (get_local $11) - ) - ) - ) - ) - (i64.store - (i32.add - (i32.add - (get_local $12) - (i32.const 48) - ) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i64.store offset=48 - (get_local $12) - (i64.load - (get_local $5) - ) - ) - (drop - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ - (i32.add - (get_local $12) - (i32.const 32) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - (set_local $8 - (i64.const 0) - ) - (set_local $7 - (i64.const 59) - ) - (set_local $11 - (i32.const 1888) - ) - (set_local $9 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $8) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $11) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $10 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $8) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $10 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $10 - (i64.shl - (i64.and - (get_local $10) - (i64.const 31) - ) - (i64.and - (get_local $7) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $11 - (i32.add - (get_local $11) - (i32.const 1) - ) - ) - (set_local $8 - (i64.add - (get_local $8) - (i64.const 1) - ) - ) - (set_local $9 - (i64.or - (get_local $10) - (get_local $9) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $7 - (i64.add - (get_local $7) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store - (i32.add - (get_local $12) - (i32.const 8) - ) - (i64.load - (i32.add - (i32.add - (get_local $12) - (i32.const 48) - ) - (i32.const 8) - ) - ) - ) - (i64.store - (get_local $12) - (i64.load offset=48 - (get_local $12) - ) - ) - (call $_ZN5eosio8currency15inline_transferEyyNS_5assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy - (get_local $0) - (get_local $4) - (get_local $3) - (get_local $12) - (i32.add - (get_local $12) - (i32.const 32) - ) - (get_local $9) - ) - (br_if $label$5 - (i32.eqz - (i32.and - (i32.load8_u offset=32 - (get_local $12) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=40 - (get_local $12) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $5 - (i32.load offset=112 - (get_local $12) - ) - ) - ) - ) - (block $label$13 - (block $label$14 - (br_if $label$14 - (i32.eq - (tee_local $11 - (i32.load - (tee_local $6 - (i32.add - (get_local $12) - (i32.const 116) - ) - ) - ) - ) - (get_local $5) - ) - ) - (loop $label$15 - (set_local $1 - (i32.load - (tee_local $11 - (i32.add - (get_local $11) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (get_local $11) - (i32.const 0) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (br_if $label$15 - (i32.ne - (get_local $5) - (get_local $11) - ) - ) - ) - (set_local $11 - (i32.load - (i32.add - (get_local $12) - (i32.const 112) - ) - ) - ) - (br $label$13) - ) - (set_local $11 - (get_local $5) - ) - ) - (i32.store - (get_local $6) - (get_local $5) - ) - (call $_ZdlPv - (get_local $11) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $12) - (i32.const 128) - ) - ) - ) - (func $_ZN5eosio18unpack_action_dataINS_8currency6createEEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (set_local $6 - (tee_local $4 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $4) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $2 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $4) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $2) - (get_local $1) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.const 1398362884) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $3 - (i64.const 5462355) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$2 - (block $label$3 - (loop $label$4 - (br_if $label$3 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $3) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$5 - (br_if $label$5 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$6 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$6 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$2) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 80) - ) - (i32.store8 offset=26 - (get_local $0) - (i32.const 1) - ) - (i32.store16 offset=24 - (get_local $0) - (i32.const 257) - ) - (i32.store offset=4 - (get_local $6) - (get_local $2) - ) - (i32.store - (get_local $6) - (get_local $2) - ) - (i32.store offset=8 - (get_local $6) - (i32.add - (get_local $2) - (get_local $1) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency6createE - (get_local $6) - (get_local $0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency6createE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 25) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 26) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 1) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio11multi_indexILy14289235522390851584ENS_8currency14currency_statsEJEE6modifyIZNS1_2onERKNS1_5issueEEUlRT_E_EEvRKS2_yOS8_ (param $0 i32) (param $1 i32) (param $2 i64) (param $3 i32) - (local $4 i64) - (local $5 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $5 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=48 - (get_local $1) - ) - (get_local $0) - ) - (i32.const 400) - ) - (call $eosio_assert - (i64.eq - (i64.load - (get_local $0) - ) - (call $current_receiver) - ) - (i32.const 448) - ) - (i64.store - (get_local $1) - (i64.add - (i64.load - (get_local $1) - ) - (i64.load offset=8 - (i32.load - (get_local $3) - ) - ) - ) - ) - (set_local $4 - (i64.load offset=8 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 544) - ) - (i32.store offset=56 - (get_local $5) - (i32.add - (get_local $5) - (i32.const 45) - ) - ) - (i32.store offset=52 - (get_local $5) - (get_local $5) - ) - (i32.store offset=48 - (get_local $5) - (get_local $5) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency14currency_statsE - (i32.add - (get_local $5) - (i32.const 48) - ) - (get_local $1) - ) - ) - (call $db_update_i64 - (i32.load offset=52 - (get_local $1) - ) - (get_local $2) - (get_local $5) - (i32.const 45) - ) - (block $label$0 - (br_if $label$0 - (i64.lt_u - (tee_local $2 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.load offset=16 - (get_local $0) - ) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.add - (get_local $2) - (i64.const 1) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $5) - (i32.const 64) - ) - ) - ) - (func $_ZN5eosio8currency15inline_transferEyyNS_5assetENSt3__112basic_stringIcNS2_11char_traitsIcEENS2_9allocatorIcEEEEy (param $0 i32) (param $1 i64) (param $2 i64) (param $3 i32) (param $4 i32) (param $5 i64) - (local $6 i64) - (local $7 i32) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i64) - (local $12 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $12 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (set_local $6 - (i64.load - (get_local $0) - ) - ) - (set_local $9 - (i64.const 0) - ) - (set_local $8 - (i64.const 59) - ) - (set_local $0 - (i32.const 1904) - ) - (set_local $10 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $9) - (i64.const 7) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $7 - (i32.load8_s - (get_local $0) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $11 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $9) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $7 - (select - (i32.add - (get_local $7) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $7) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $11 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $7) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $11 - (i64.shl - (i64.and - (get_local $11) - (i64.const 31) - ) - (i64.and - (get_local $8) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $9 - (i64.add - (get_local $9) - (i64.const 1) - ) - ) - (set_local $10 - (i64.or - (get_local $11) - (get_local $10) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $8 - (i64.add - (get_local $8) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 28) - ) - (i32.load - (i32.add - (get_local $3) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 24) - ) - (i32.load - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 20) - ) - (i32.load - (i32.add - (get_local $3) - (i32.const 4) - ) - ) - ) - (i64.store offset=16 - (get_local $12) - (get_local $2) - ) - (i64.store offset=8 - (get_local $12) - (get_local $1) - ) - (i32.store offset=24 - (get_local $12) - (i32.load - (get_local $3) - ) - ) - (drop - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 32) - ) - (get_local $4) - ) - ) - (i64.store offset=64 - (get_local $12) - (get_local $10) - ) - (i64.store offset=56 - (get_local $12) - (get_local $6) - ) - (i64.store - (tee_local $0 - (call $_Znwj - (i32.const 16) - ) - ) - (get_local $1) - ) - (i64.store offset=8 - (get_local $0) - (get_local $5) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 32) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 24) - ) - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 20) - ) - (get_local $7) - ) - (i32.store offset=72 - (get_local $12) - (get_local $0) - ) - (i32.store offset=84 - (get_local $12) - (i32.const 0) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 36) - ) - (i32.const 0) - ) - (set_local $0 - (i32.add - (tee_local $7 - (select - (i32.load - (i32.add - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.const 36) - ) - ) - (i32.shr_u - (tee_local $0 - (i32.load8_u offset=40 - (get_local $12) - ) - ) - (i32.const 1) - ) - (i32.and - (get_local $0) - (i32.const 1) - ) - ) - ) - (i32.const 32) - ) - ) - (set_local $9 - (i64.extend_u/i32 - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 28) - ) - ) - (loop $label$6 - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $9 - (i64.shr_u - (get_local $9) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.eqz - (get_local $0) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $0) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $12) - (i32.const 88) - ) - ) - ) - (set_local $0 - (i32.load - (i32.add - (get_local $12) - (i32.const 84) - ) - ) - ) - (br $label$7) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - ) - (i32.store offset=100 - (get_local $12) - (get_local $0) - ) - (i32.store offset=96 - (get_local $12) - (get_local $0) - ) - (i32.store offset=104 - (get_local $12) - (get_local $7) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_8currency8transferE - (i32.add - (get_local $12) - (i32.const 96) - ) - (i32.add - (get_local $12) - (i32.const 8) - ) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (i32.and - (i32.load8_u - (i32.add - (get_local $12) - (i32.const 40) - ) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $12) - (i32.const 48) - ) - ) - ) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $12) - (i32.const 8) - ) - (i32.add - (get_local $12) - (i32.const 56) - ) - ) - (call $send_inline - (tee_local $0 - (i32.load offset=8 - (get_local $12) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $12) - ) - (get_local $0) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $0 - (i32.load offset=8 - (get_local $12) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $12) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (tee_local $0 - (i32.load offset=84 - (get_local $12) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 88) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $0 - (i32.load offset=72 - (get_local $12) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 76) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $12) - (i32.const 112) - ) - ) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i32.store offset=24 - (get_local $7) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $7) - (i64.const 0) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE - (get_local $0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ne - (tee_local $5 - (i32.load offset=20 - (get_local $7) - ) - ) - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - ) - (br_if $label$7 - (i32.and - (i32.load8_u - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.store16 - (get_local $1) - (i32.const 0) - ) - (set_local $4 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (br $label$6) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (br_if $label$0 - (i32.ge_u - (tee_local $2 - (i32.sub - (get_local $5) - (get_local $4) - ) - ) - (i32.const -16) - ) - ) - (br_if $label$5 - (i32.ge_u - (get_local $2) - (i32.const 11) - ) - ) - (i32.store8 - (get_local $7) - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - (set_local $6 - (i32.or - (get_local $7) - (i32.const 1) - ) - ) - (br_if $label$4 - (get_local $2) - ) - (br $label$3) - ) - (i32.store8 - (i32.load offset=8 - (get_local $1) - ) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $1) - (i32.const 0) - ) - (set_local $4 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj - (get_local $1) - (i32.const 0) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (br_if $label$2 - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - (br $label$1) - ) - (set_local $6 - (call $_Znwj - (tee_local $5 - (i32.and - (i32.add - (get_local $2) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.or - (get_local $5) - (i32.const 1) - ) - ) - (i32.store offset=8 - (get_local $7) - (get_local $6) - ) - (i32.store offset=4 - (get_local $7) - (get_local $2) - ) - ) - (set_local $3 - (get_local $2) - ) - (set_local $5 - (get_local $6) - ) - (loop $label$9 - (i32.store8 - (get_local $5) - (i32.load8_u - (get_local $4) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (br_if $label$9 - (tee_local $3 - (i32.add - (get_local $3) - (i32.const -1) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (get_local $2) - ) - ) - ) - (i32.store8 - (get_local $6) - (i32.const 0) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.and - (i32.load8_u - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.store16 - (get_local $1) - (i32.const 0) - ) - (br $label$10) - ) - (i32.store8 - (i32.load offset=8 - (get_local $1) - ) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $1) - (i32.const 0) - ) - ) - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj - (get_local $1) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i64.store align=4 - (get_local $1) - (i64.load - (get_local $7) - ) - ) - (br_if $label$1 - (i32.eqz - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $7) - (get_local $4) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 32) - ) - ) - (return - (get_local $0) - ) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $7) - ) - (unreachable) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.const 704) - ) - (set_local $4 - (i32.load8_u - (tee_local $5 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $7 - (i32.and - (get_local $7) - (i32.const 255) - ) - ) - ) - ) - (get_local $6) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.le_u - (tee_local $3 - (i32.wrap/i64 - (get_local $6) - ) - ) - (tee_local $2 - (i32.sub - (tee_local $7 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $1) - (i32.sub - (get_local $3) - (get_local $2) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - (set_local $4 - (i32.load - (get_local $1) - ) - ) - (br $label$1) - ) - (br_if $label$1 - (i32.ge_u - (get_local $3) - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (tee_local $7 - (i32.add - (get_local $4) - (get_local $3) - ) - ) - ) - ) - (call $eosio_assert - (i32.ge_u - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $5) - ) - (tee_local $5 - (i32.sub - (get_local $7) - (get_local $4) - ) - ) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $4) - (i32.load - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (get_local $5) - ) - ) - (i32.store - (get_local $7) - (i32.add - (i32.load - (get_local $7) - ) - (get_local $5) - ) - ) - (get_local $0) - ) - (func $_ZN5eosio6unpackINS_8exchange11covermarginEEET_PKcj (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $3 - (i64.const 5462355) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $3) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 80) - ) - (call $eosio_assert - (i32.gt_u - (get_local $2) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $1) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (tee_local $4 - (i32.and - (get_local $2) - (i32.const -8) - ) - ) - (i32.const 8) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $4) - (i32.const 16) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 16) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $4) - (i32.const 24) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $4) - (i32.const 32) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 32) - ) - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.const 8) - ) - ) - ) - (func $_ZN5eosio8exchange8upmarginC2Ev (param $0 i32) (result i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 48) - ) - ) - (i64.const 1398362884) - ) - (i64.store offset=40 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$5 - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (get_local $0) - ) - (func $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_EEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange8upmarginELPv0EEERT_SL_RT0_EUlSL_E_JLj0ELj1ELj2ELj3EEEEvSL_OSM_NSt3__116integer_sequenceIjJXspT1_EEEENSQ_17integral_constantIbLb0EEE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (set_local $3 - (i32.load - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $3 - (i32.load offset=4 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $3 - (i32.load offset=8 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $4) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $4) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $0 - (i32.load offset=12 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $0) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $1 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $1) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $1 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $1) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (func $_ZN5eosio8exchange5tradeC2Ev (param $0 i32) (result i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i64.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 48) - ) - ) - (i64.const 1398362884) - ) - (i64.store offset=40 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $1 - (i64.shr_u - (i64.load - (get_local $2) - ) - (i64.const 8) - ) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$5 - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $1) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $1 - (i64.shr_u - (get_local $1) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $3 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 80) - ) - (i32.store8 offset=68 - (get_local $0) - (i32.const 1) - ) - (i32.store offset=64 - (get_local $0) - (i32.const 0) - ) - (get_local $0) - ) - (func $_ZN5boost3pfr6detail19for_each_field_implINS1_14sequence_tuple5tupleIJRyRN5eosio11symbol_typeERNS6_14extended_assetESA_RmRhEEEZNS6_rsINS6_10datastreamIPKcEENS6_8exchange5tradeELPv0EEERT_SN_RT0_EUlSN_E_JLj0ELj1ELj2ELj3ELj4ELj5EEEEvSN_OSO_NSt3__116integer_sequenceIjJXspT1_EEEENSS_17integral_constantIbLb0EEE (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (set_local $3 - (i32.load - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $3 - (i32.load offset=4 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $3 - (i32.load offset=8 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $4) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $4) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $3 - (i32.load offset=12 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $4) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $2) - ) - (get_local $4) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $3) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $3 - (i32.load offset=16 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 3) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 4) - ) - ) - (set_local $0 - (i32.load offset=20 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $0) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 1) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 1) - ) - ) - ) - (func $_ZN5boost6fusion6detail17for_each_unrolledILi4EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio11symbol_typeEdNS8_15extended_symbolEEEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_dSA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (set_local $3 - (i32.load - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $2) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $2) - (i32.add - (i32.load offset=4 - (get_local $2) - ) - (i32.const 8) - ) - ) - (set_local $2 - (i32.load - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $0 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $2) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $0 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $2) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $1 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $2) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $1) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $1) - (tee_local $0 - (i32.add - (i32.load offset=4 - (get_local $1) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $1) - ) - (get_local $0) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $2) - (i32.const 32) - ) - (i32.load offset=4 - (get_local $1) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $1) - (i32.add - (i32.load offset=4 - (get_local $1) - ) - (i32.const 8) - ) - ) - ) - (func $_ZN5eosio6unpackINSt3__15tupleIJyNS_11symbol_typeENS_14extended_assetEEEEEET_PKcj (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (i64.store - (get_local $0) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $4 - (i64.const 5462355) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $4) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $6 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $6 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 80) - ) - (call $eosio_assert - (i32.gt_u - (get_local $2) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $1) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (tee_local $5 - (i32.and - (get_local $2) - (i32.const -8) - ) - ) - (i32.const 8) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $5) - (i32.const 16) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 16) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $5) - (i32.const 24) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $5) - (i32.const 32) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $3) - (i32.add - (get_local $1) - (i32.const 32) - ) - (i32.const 8) - ) - ) - ) - (func $_ZN5eosio6unpackINSt3__15tupleIJyNS_5assetEmNS_14extended_assetES4_EEEEET_PKcj (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i64) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $6 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $3 - (i64.const 5462355) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $3) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$3 - (br_if $label$3 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$4 - (br_if $label$1 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$4 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$0) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 80) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 48) - ) - (i64.const 0) - ) - (i32.store offset=24 - (get_local $0) - (i32.const 0) - ) - (i64.store offset=32 - (get_local $0) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 40) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $3 - (i64.const 5462355) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$5 - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $3) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$8 - (br_if $label$8 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$9 - (br_if $label$6 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$9 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (br_if $label$7 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$5) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 80) - ) - (i64.store offset=56 - (get_local $0) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 72) - ) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 64) - ) - (i64.const 1398362884) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 16) - ) - (set_local $3 - (i64.const 5462355) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$10 - (block $label$11 - (loop $label$12 - (br_if $label$11 - (i32.gt_u - (i32.add - (i32.shl - (i32.wrap/i64 - (get_local $3) - ) - (i32.const 24) - ) - (i32.const -1073741825) - ) - (i32.const 452984830) - ) - ) - (block $label$13 - (br_if $label$13 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (loop $label$14 - (br_if $label$11 - (i64.ne - (i64.and - (tee_local $3 - (i64.shr_u - (get_local $3) - (i64.const 8) - ) - ) - (i64.const 255) - ) - (i64.const 0) - ) - ) - (br_if $label$14 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - ) - ) - (set_local $5 - (i32.const 1) - ) - (br_if $label$12 - (i32.lt_s - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 7) - ) - ) - (br $label$10) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $5) - (i32.const 80) - ) - (i32.store offset=4 - (get_local $6) - (get_local $1) - ) - (i32.store - (get_local $6) - (get_local $1) - ) - (i32.store offset=8 - (get_local $6) - (i32.add - (get_local $1) - (get_local $2) - ) - ) - (i32.store offset=16 - (get_local $6) - (get_local $6) - ) - (i32.store offset=24 - (get_local $6) - (get_local $0) - ) - (call $_ZN5boost6fusion6detail17for_each_unrolledILi5EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio5assetEmNS8_14extended_assetESA_EEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_mSA_SA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ - (i32.add - (get_local $6) - (i32.const 24) - ) - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $6) - (i32.const 32) - ) - ) - ) - (func $_ZN5boost6fusion6detail17for_each_unrolledILi5EE4callINS0_18std_tuple_iteratorINSt3__15tupleIJyN5eosio5assetEmNS8_14extended_assetESA_EEELi0EEEZNS8_rsINS8_10datastreamIPKcEEJyS9_mSA_SA_EEERT_SJ_RNS7_IJDpT0_EEEEUlSJ_E_EEvRKSI_RKT0_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (set_local $2 - (i32.load - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $3) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $2) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (set_local $0 - (i32.load - (get_local $0) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $3) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $3) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $3) - ) - ) - (i32.const 3) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $3) - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $3) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 32) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $3) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 40) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $3) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 48) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (i32.load offset=4 - (get_local $3) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 56) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (tee_local $1 - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $3) - ) - (get_local $1) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 64) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (tee_local $1 - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $3) - ) - (get_local $1) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 72) - ) - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $3) - (i32.add - (i32.load offset=4 - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_8currency8transferE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 7) - ) - (i32.const 688) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $0) - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 8) - ) - ) - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__112basic_stringIcNS7_11char_traitsIcEENS7_9allocatorIcEEEE - (get_local $0) - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - (func $apply (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i64.store - (i32.add - (get_local $3) - (i32.const 32) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $3) - (i32.const 40) - ) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $3) - (get_local $0) - ) - (i64.store offset=8 - (get_local $3) - (get_local $0) - ) - (i64.store offset=24 - (get_local $3) - (get_local $0) - ) - (call $_ZN5eosio8exchange5applyEyy - (i32.add - (get_local $3) - (i32.const 8) - ) - (get_local $1) - (get_local $2) - ) - (call $eosio_exit - (i32.const 0) - ) - (unreachable) - ) - (func $_Znwj (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (block $label$0 - (br_if $label$0 - (tee_local $0 - (call $malloc - (tee_local $1 - (select - (get_local $0) - (i32.const 1) - (get_local $0) - ) - ) - ) - ) - ) - (loop $label$1 - (set_local $0 - (i32.const 0) - ) - (br_if $label$0 - (i32.eqz - (tee_local $2 - (i32.load offset=3648 - (i32.const 0) - ) - ) - ) - ) - (call_indirect (type $FUNCSIG$v) - (get_local $2) - ) - (br_if $label$1 - (i32.eqz - (tee_local $0 - (call $malloc - (get_local $1) - ) - ) - ) - ) - ) - ) - (get_local $0) - ) - (func $_ZdlPv (param $0 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $0) - ) - ) - (call $free - (get_local $0) - ) - ) - ) - (func $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv (param $0 i32) - (call $abort) - (unreachable) - ) - (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (br_if $label$0 - (i32.ge_u - (get_local $1) - (i32.const -16) - ) - ) - (set_local $2 - (i32.const 10) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.and - (tee_local $5 - (i32.load8_u - (get_local $0) - ) - ) - (i32.const 1) - ) - ) - ) - (set_local $2 - (i32.add - (i32.and - (tee_local $5 - (i32.load - (get_local $0) - ) - ) - (i32.const -2) - ) - (i32.const -1) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - (set_local $3 - (i32.shr_u - (i32.and - (get_local $5) - (i32.const 254) - ) - (i32.const 1) - ) - ) - (br $label$2) - ) - (set_local $3 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (set_local $4 - (i32.const 10) - ) - (block $label$4 - (br_if $label$4 - (i32.lt_u - (tee_local $1 - (select - (get_local $3) - (get_local $1) - (i32.gt_u - (get_local $3) - (get_local $1) - ) - ) - ) - (i32.const 11) - ) - ) - (set_local $4 - (i32.add - (i32.and - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const -16) - ) - (i32.const -1) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eq - (get_local $4) - (get_local $2) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.ne - (get_local $4) - (i32.const 10) - ) - ) - (set_local $6 - (i32.const 1) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (br $label$6) - ) - (set_local $1 - (call $_Znwj - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.gt_u - (get_local $4) - (get_local $2) - ) - ) - (br_if $label$5 - (i32.eqz - (get_local $1) - ) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.and - (tee_local $5 - (i32.load8_u - (get_local $0) - ) - ) - (i32.const 1) - ) - ) - (set_local $7 - (i32.const 1) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$6) - ) - (set_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (set_local $6 - (i32.const 1) - ) - (set_local $7 - (i32.const 1) - ) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - (set_local $5 - (i32.shr_u - (i32.and - (get_local $5) - (i32.const 254) - ) - (i32.const 1) - ) - ) - (br $label$10) - ) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - (drop - (call $memcpy - (get_local $1) - (get_local $2) - (get_local $5) - ) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (get_local $7) - ) - ) - (i32.store offset=4 - (get_local $0) - (get_local $3) - ) - (i32.store offset=8 - (get_local $0) - (get_local $1) - ) - (i32.store - (get_local $0) - (i32.or - (i32.add - (get_local $4) - (i32.const 1) - ) - (i32.const 1) - ) - ) - (return) - ) - (i32.store8 - (get_local $0) - (i32.shl - (get_local $3) - (i32.const 1) - ) - ) - ) - (return) - ) - (call $abort) - (unreachable) - ) - (func $_ZNKSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7compareEjjPKcj (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (param $4 i32) (result i32) - (local $5 i32) - (local $6 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (tee_local $5 - (i32.and - (tee_local $6 - (i32.load8_u - (get_local $0) - ) - ) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i32.shr_u - (get_local $6) - (i32.const 1) - ) - ) - (br $label$0) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (block $label$2 - (br_if $label$2 - (i32.eq - (get_local $4) - (i32.const -1) - ) - ) - (br_if $label$2 - (i32.lt_u - (get_local $6) - (get_local $1) - ) - ) - (set_local $6 - (select - (tee_local $6 - (i32.sub - (get_local $6) - (get_local $1) - ) - ) - (get_local $2) - (i32.lt_u - (get_local $6) - (get_local $2) - ) - ) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (get_local $5) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (br $label$3) - ) - (set_local $0 - (i32.load offset=8 - (get_local $0) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (tee_local $2 - (select - (get_local $4) - (get_local $6) - (tee_local $5 - (i32.gt_u - (get_local $6) - (get_local $4) - ) - ) - ) - ) - ) - ) - (br_if $label$5 - (i32.eqz - (tee_local $1 - (call $memcmp - (i32.add - (get_local $0) - (get_local $1) - ) - (get_local $3) - (get_local $2) - ) - ) - ) - ) - (return - (get_local $1) - ) - ) - (return - (select - (i32.const -1) - (get_local $5) - (i32.lt_u - (get_local $6) - (get_local $4) - ) - ) - ) - ) - (call $abort) - (unreachable) - ) - (func $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv (param $0 i32) - (call $abort) - (unreachable) - ) - (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (i64.store align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.and - (i32.load8_u - (get_local $1) - ) - (i32.const 1) - ) - ) - (i64.store align=4 - (get_local $0) - (i64.load align=4 - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (i32.load - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - (return - (get_local $0) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $3 - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.const -16) - ) - ) - (set_local $2 - (i32.load offset=8 - (get_local $1) - ) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (get_local $3) - (i32.const 11) - ) - ) - (i32.store8 - (get_local $0) - (i32.shl - (get_local $3) - (i32.const 1) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (br_if $label$3 - (get_local $3) - ) - (br $label$2) - ) - (set_local $1 - (call $_Znwj - (tee_local $4 - (i32.and - (i32.add - (get_local $3) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (get_local $0) - (i32.or - (get_local $4) - (i32.const 1) - ) - ) - (i32.store offset=8 - (get_local $0) - (get_local $1) - ) - (i32.store offset=4 - (get_local $0) - (get_local $3) - ) - ) - (drop - (call $memcpy - (get_local $1) - (get_local $2) - (get_local $3) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $1) - (get_local $3) - ) - (i32.const 0) - ) - (return - (get_local $0) - ) - ) - (call $abort) - (unreachable) - ) - (func $pow (param $0 f64) (param $1 f64) (result f64) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 f64) - (local $11 i64) - (local $12 f64) - (local $13 f64) - (local $14 f64) - (local $15 f64) - (local $16 f64) - (local $17 f64) - (local $18 f64) - (local $19 i32) - (local $20 f64) - (local $21 f64) - (set_local $21 - (f64.const 1) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (i32.or - (tee_local $8 - (i32.and - (tee_local $5 - (i32.wrap/i64 - (i64.shr_u - (tee_local $4 - (i64.reinterpret/f64 - (get_local $1) - ) - ) - (i64.const 32) - ) - ) - ) - (i32.const 2147483647) - ) - ) - (tee_local $6 - (i32.wrap/i64 - (get_local $4) - ) - ) - ) - ) - ) - (set_local $2 - (i32.wrap/i64 - (i64.shr_u - (tee_local $11 - (i64.reinterpret/f64 - (get_local $0) - ) - ) - (i64.const 32) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (tee_local $3 - (i32.wrap/i64 - (get_local $11) - ) - ) - ) - (br_if $label$0 - (i32.eq - (get_local $2) - (i32.const 1072693248) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $7 - (i32.and - (get_local $2) - (i32.const 2147483647) - ) - ) - (i32.const 2146435072) - ) - ) - (br_if $label$3 - (i32.and - (i32.ne - (get_local $3) - (i32.const 0) - ) - (i32.eq - (get_local $7) - (i32.const 2146435072) - ) - ) - ) - (br_if $label$3 - (i32.gt_u - (get_local $8) - (i32.const 2146435072) - ) - ) - (br_if $label$2 - (i32.eqz - (get_local $6) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $8) - (i32.const 2146435072) - ) - ) - ) - (return - (f64.add - (get_local $0) - (get_local $1) - ) - ) - ) - (set_local $19 - (i32.const 0) - ) - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.gt_s - (get_local $2) - (i32.const -1) - ) - ) - (set_local $19 - (i32.const 2) - ) - (br_if $label$7 - (i32.gt_u - (get_local $8) - (i32.const 1128267775) - ) - ) - (set_local $19 - (i32.const 0) - ) - (br_if $label$7 - (i32.lt_u - (get_local $8) - (i32.const 1072693248) - ) - ) - (br_if $label$6 - (i32.lt_s - (i32.add - (tee_local $9 - (i32.shr_u - (get_local $8) - (i32.const 20) - ) - ) - (i32.const -1023) - ) - (i32.const 21) - ) - ) - (set_local $19 - (select - (i32.sub - (i32.const 2) - (i32.and - (tee_local $9 - (i32.shr_u - (get_local $6) - (tee_local $19 - (i32.sub - (i32.const 1075) - (get_local $9) - ) - ) - ) - ) - (i32.const 1) - ) - ) - (i32.const 0) - (i32.eq - (i32.shl - (get_local $9) - (get_local $19) - ) - (get_local $6) - ) - ) - ) - ) - (br_if $label$5 - (i32.eqz - (get_local $6) - ) - ) - (br $label$4) - ) - (set_local $19 - (i32.const 0) - ) - (br_if $label$4 - (get_local $6) - ) - (set_local $19 - (select - (i32.sub - (i32.const 2) - (i32.and - (tee_local $19 - (i32.shr_u - (get_local $8) - (tee_local $6 - (i32.sub - (i32.const 1043) - (get_local $9) - ) - ) - ) - ) - (i32.const 1) - ) - ) - (i32.const 0) - (i32.eq - (i32.shl - (get_local $19) - (get_local $6) - ) - (get_local $8) - ) - ) - ) - ) - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.ne - (get_local $8) - (i32.const 2146435072) - ) - ) - (br_if $label$0 - (i32.eqz - (i32.or - (i32.add - (get_local $7) - (i32.const -1072693248) - ) - (get_local $3) - ) - ) - ) - (br_if $label$10 - (i32.lt_u - (get_local $7) - (i32.const 1072693248) - ) - ) - (return - (select - (get_local $1) - (f64.const 0) - (i32.gt_s - (get_local $5) - (i32.const -1) - ) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.ne - (get_local $8) - (i32.const 1072693248) - ) - ) - (br_if $label$8 - (i32.le_s - (get_local $5) - (i32.const -1) - ) - ) - (return - (get_local $0) - ) - ) - (br_if $label$9 - (i32.ne - (get_local $5) - (i32.const 1073741824) - ) - ) - (return - (f64.mul - (get_local $0) - (get_local $0) - ) - ) - ) - (return - (select - (f64.const 0) - (f64.neg - (get_local $1) - ) - (i32.gt_s - (get_local $5) - (i32.const -1) - ) - ) - ) - ) - (br_if $label$4 - (i32.lt_s - (get_local $2) - (i32.const 0) - ) - ) - (br_if $label$4 - (i32.ne - (get_local $5) - (i32.const 1071644672) - ) - ) - (return - (call $sqrt - (get_local $0) - ) - ) - ) - (return - (f64.div - (f64.const 1) - (get_local $0) - ) - ) - ) - (set_local $21 - (call $fabs - (get_local $0) - ) - ) - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (block $label$17 - (br_if $label$17 - (get_local $3) - ) - (br_if $label$16 - (i32.eqz - (get_local $7) - ) - ) - (br_if $label$16 - (i32.eq - (i32.or - (get_local $7) - (i32.const 1073741824) - ) - (i32.const 2146435072) - ) - ) - ) - (set_local $10 - (f64.const 1) - ) - (br_if $label$13 - (i32.gt_s - (get_local $2) - (i32.const -1) - ) - ) - (br_if $label$15 - (i32.eq - (get_local $19) - (i32.const 1) - ) - ) - (br_if $label$13 - (get_local $19) - ) - (return - (f64.div - (tee_local $1 - (f64.sub - (get_local $0) - (get_local $0) - ) - ) - (get_local $1) - ) - ) - ) - (set_local $21 - (select - (f64.div - (f64.const 1) - (get_local $21) - ) - (get_local $21) - (i32.lt_s - (get_local $5) - (i32.const 0) - ) - ) - ) - (br_if $label$0 - (i32.gt_s - (get_local $2) - (i32.const -1) - ) - ) - (br_if $label$14 - (i32.eqz - (i32.or - (get_local $19) - (i32.add - (get_local $7) - (i32.const -1072693248) - ) - ) - ) - ) - (return - (select - (f64.neg - (get_local $21) - ) - (get_local $21) - (i32.eq - (get_local $19) - (i32.const 1) - ) - ) - ) - ) - (set_local $10 - (f64.const -1) - ) - (br $label$13) - ) - (return - (f64.div - (tee_local $1 - (f64.sub - (get_local $21) - (get_local $21) - ) - ) - (get_local $1) - ) - ) - ) - (block $label$18 - (block $label$19 - (block $label$20 - (block $label$21 - (block $label$22 - (block $label$23 - (block $label$24 - (block $label$25 - (block $label$26 - (block $label$27 - (br_if $label$27 - (i32.lt_u - (get_local $8) - (i32.const 1105199105) - ) - ) - (br_if $label$26 - (i32.lt_u - (get_local $8) - (i32.const 1139802113) - ) - ) - (br_if $label$23 - (i32.gt_u - (get_local $7) - (i32.const 1072693247) - ) - ) - (return - (select - (f64.const inf) - (f64.const 0) - (i32.lt_s - (get_local $5) - (i32.const 0) - ) - ) - ) - ) - (set_local $8 - (i32.const 0) - ) - (br_if $label$25 - (i32.gt_u - (get_local $7) - (i32.const 1048575) - ) - ) - (set_local $7 - (i32.wrap/i64 - (i64.shr_u - (i64.reinterpret/f64 - (tee_local $21 - (f64.mul - (get_local $21) - (f64.const 9007199254740992) - ) - ) - ) - (i64.const 32) - ) - ) - ) - (set_local $5 - (i32.const -53) - ) - (br $label$24) - ) - (br_if $label$22 - (i32.gt_u - (get_local $7) - (i32.const 1072693246) - ) - ) - (return - (f64.mul - (tee_local $1 - (select - (f64.const 1.e+300) - (f64.const 1e-300) - (i32.lt_s - (get_local $5) - (i32.const 0) - ) - ) - ) - (f64.mul - (get_local $1) - (get_local $10) - ) - ) - ) - ) - (set_local $5 - (i32.const 0) - ) - ) - (set_local $2 - (i32.or - (tee_local $6 - (i32.and - (get_local $7) - (i32.const 1048575) - ) - ) - (i32.const 1072693248) - ) - ) - (set_local $5 - (i32.add - (i32.add - (i32.shr_s - (get_local $7) - (i32.const 20) - ) - (get_local $5) - ) - (i32.const -1023) - ) - ) - (br_if $label$20 - (i32.lt_u - (get_local $6) - (i32.const 235663) - ) - ) - (br_if $label$21 - (i32.ge_u - (get_local $6) - (i32.const 767610) - ) - ) - (set_local $8 - (i32.const 1) - ) - (br $label$20) - ) - (return - (select - (f64.const inf) - (f64.const 0) - (i32.gt_s - (get_local $5) - (i32.const 0) - ) - ) - ) - ) - (br_if $label$19 - (i32.lt_u - (get_local $7) - (i32.const 1072693249) - ) - ) - (return - (f64.mul - (tee_local $1 - (select - (f64.const 1.e+300) - (f64.const 1e-300) - (i32.gt_s - (get_local $5) - (i32.const 0) - ) - ) - ) - (f64.mul - (get_local $1) - (get_local $10) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const -1048576) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - (set_local $20 - (f64.sub - (f64.sub - (f64.sub - (tee_local $0 - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (f64.add - (tee_local $20 - (f64.convert_s/i32 - (get_local $5) - ) - ) - (f64.add - (tee_local $18 - (f64.load - (i32.add - (tee_local $6 - (i32.shl - (get_local $8) - (i32.const 3) - ) - ) - (i32.const 3696) - ) - ) - ) - (f64.add - (tee_local $12 - (f64.mul - (tee_local $0 - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (f64.add - (tee_local $14 - (f64.mul - (tee_local $0 - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (tee_local $21 - (f64.mul - (tee_local $14 - (f64.sub - (tee_local $12 - (f64.reinterpret/i64 - (i64.or - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 32) - ) - (i64.and - (i64.reinterpret/f64 - (get_local $21) - ) - (i64.const 4294967295) - ) - ) - ) - ) - (tee_local $13 - (f64.load - (i32.add - (get_local $6) - (i32.const 3664) - ) - ) - ) - ) - ) - (tee_local $15 - (f64.div - (f64.const 1) - (f64.add - (get_local $13) - (get_local $12) - ) - ) - ) - ) - ) - ) - (i64.const -4294967296) - ) - ) - ) - (tee_local $0 - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (f64.add - (f64.add - (tee_local $17 - (f64.mul - (get_local $0) - (get_local $0) - ) - ) - (f64.const 3) - ) - (tee_local $13 - (f64.add - (f64.mul - (f64.add - (get_local $21) - (get_local $0) - ) - (tee_local $12 - (f64.mul - (get_local $15) - (f64.sub - (f64.sub - (get_local $14) - (f64.mul - (get_local $0) - (tee_local $16 - (f64.reinterpret/i64 - (i64.shl - (i64.extend_u/i32 - (i32.add - (i32.add - (i32.or - (i32.shr_s - (get_local $2) - (i32.const 1) - ) - (i32.const 536870912) - ) - (i32.shl - (get_local $8) - (i32.const 18) - ) - ) - (i32.const 524288) - ) - ) - (i64.const 32) - ) - ) - ) - ) - ) - (f64.mul - (get_local $0) - (f64.sub - (get_local $12) - (f64.sub - (get_local $16) - (get_local $13) - ) - ) - ) - ) - ) - ) - ) - (f64.mul - (f64.mul - (tee_local $0 - (f64.mul - (get_local $21) - (get_local $21) - ) - ) - (get_local $0) - ) - (f64.add - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.const 0.20697501780033842) - ) - (f64.const 0.23066074577556175) - ) - ) - (f64.const 0.272728123808534) - ) - ) - (f64.const 0.33333332981837743) - ) - ) - (f64.const 0.4285714285785502) - ) - ) - (f64.const 0.5999999999999946) - ) - ) - ) - ) - ) - ) - (i64.const -4294967296) - ) - ) - ) - ) - ) - (tee_local $21 - (f64.add - (f64.mul - (get_local $12) - (get_local $0) - ) - (f64.mul - (get_local $21) - (f64.sub - (get_local $13) - (f64.sub - (f64.add - (get_local $0) - (f64.const -3) - ) - (get_local $17) - ) - ) - ) - ) - ) - ) - ) - (i64.const -4294967296) - ) - ) - ) - (f64.const 0.9617967009544373) - ) - ) - (tee_local $13 - (f64.add - (f64.load - (i32.add - (get_local $6) - (i32.const 3680) - ) - ) - (f64.add - (f64.mul - (f64.sub - (get_local $21) - (f64.sub - (get_local $0) - (get_local $14) - ) - ) - (f64.const 0.9617966939259756) - ) - (f64.mul - (get_local $0) - (f64.const -7.028461650952758e-09) - ) - ) - ) - ) - ) - ) - ) - ) - (i64.const -4294967296) - ) - ) - ) - (get_local $20) - ) - (get_local $18) - ) - (get_local $12) - ) - ) - (br $label$18) - ) - (set_local $20 - (f64.sub - (tee_local $0 - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (f64.add - (tee_local $21 - (f64.mul - (tee_local $0 - (f64.add - (get_local $21) - (f64.const -1) - ) - ) - (f64.const 1.4426950216293335) - ) - ) - (tee_local $13 - (f64.add - (f64.mul - (get_local $0) - (f64.const 1.9259629911266175e-08) - ) - (f64.mul - (f64.mul - (f64.mul - (get_local $0) - (get_local $0) - ) - (f64.sub - (f64.const 0.5) - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.const -0.25) - ) - (f64.const 0.3333333333333333) - ) - ) - ) - ) - (f64.const -1.4426950408889634) - ) - ) - ) - ) - ) - (i64.const -4294967296) - ) - ) - ) - (get_local $21) - ) - ) - ) - (set_local $8 - (i32.wrap/i64 - (tee_local $4 - (i64.reinterpret/f64 - (tee_local $0 - (f64.add - (tee_local $21 - (f64.mul - (tee_local $12 - (f64.reinterpret/i64 - (i64.and - (get_local $4) - (i64.const -4294967296) - ) - ) - ) - (get_local $0) - ) - ) - (tee_local $1 - (f64.add - (f64.mul - (f64.sub - (get_local $1) - (get_local $12) - ) - (get_local $0) - ) - (f64.mul - (f64.sub - (get_local $13) - (get_local $20) - ) - (get_local $1) - ) - ) - ) - ) - ) - ) - ) - ) - ) - (block $label$28 - (block $label$29 - (block $label$30 - (block $label$31 - (block $label$32 - (br_if $label$32 - (i32.lt_s - (tee_local $2 - (i32.wrap/i64 - (i64.shr_u - (get_local $4) - (i64.const 32) - ) - ) - ) - (i32.const 1083179008) - ) - ) - (br_if $label$31 - (i32.eqz - (i32.or - (i32.add - (get_local $2) - (i32.const -1083179008) - ) - (get_local $8) - ) - ) - ) - (return - (f64.mul - (f64.mul - (get_local $10) - (f64.const 1.e+300) - ) - (f64.const 1.e+300) - ) - ) - ) - (br_if $label$29 - (i32.lt_u - (i32.and - (get_local $2) - (i32.const 2147482624) - ) - (i32.const 1083231232) - ) - ) - (br_if $label$30 - (i32.eqz - (i32.or - (i32.add - (get_local $2) - (i32.const 1064252416) - ) - (get_local $8) - ) - ) - ) - (return - (f64.mul - (f64.mul - (get_local $10) - (f64.const 1e-300) - ) - (f64.const 1e-300) - ) - ) - ) - (br_if $label$29 - (i32.or - (f64.le - (tee_local $12 - (f64.add - (get_local $1) - (f64.const 8.008566259537294e-17) - ) - ) - (tee_local $0 - (f64.sub - (get_local $0) - (get_local $21) - ) - ) - ) - (i32.or - (f64.ne - (get_local $12) - (get_local $12) - ) - (f64.ne - (get_local $0) - (get_local $0) - ) - ) - ) - ) - (return - (f64.mul - (f64.mul - (get_local $10) - (f64.const 1.e+300) - ) - (f64.const 1.e+300) - ) - ) - ) - (br_if $label$28 - (i32.eqz - (i32.or - (f64.gt - (get_local $1) - (tee_local $0 - (f64.sub - (get_local $0) - (get_local $21) - ) - ) - ) - (i32.or - (f64.ne - (get_local $1) - (get_local $1) - ) - (f64.ne - (get_local $0) - (get_local $0) - ) - ) - ) - ) - ) - ) - (block $label$33 - (block $label$34 - (br_if $label$34 - (i32.lt_u - (tee_local $8 - (i32.and - (get_local $2) - (i32.const 2147483647) - ) - ) - (i32.const 1071644673) - ) - ) - (set_local $2 - (select - (i32.sub - (i32.const 0) - (tee_local $5 - (i32.shr_u - (i32.or - (i32.and - (tee_local $8 - (i32.add - (i32.shr_u - (i32.const 1048576) - (i32.add - (i32.shr_u - (get_local $8) - (i32.const 20) - ) - (i32.const -1022) - ) - ) - (get_local $2) - ) - ) - (i32.const 1048575) - ) - (i32.const 1048576) - ) - (i32.sub - (i32.const 1043) - (tee_local $6 - (i32.and - (i32.shr_u - (get_local $8) - (i32.const 20) - ) - (i32.const 2047) - ) - ) - ) - ) - ) - ) - (get_local $5) - (i32.lt_s - (get_local $2) - (i32.const 0) - ) - ) - ) - (set_local $21 - (f64.sub - (get_local $21) - (f64.reinterpret/i64 - (i64.shl - (i64.extend_u/i32 - (i32.and - (get_local $8) - (i32.xor - (i32.shr_u - (i32.const 1048575) - (i32.add - (get_local $6) - (i32.const -1023) - ) - ) - (i32.const -1) - ) - ) - ) - (i64.const 32) - ) - ) - ) - ) - (br $label$33) - ) - (set_local $2 - (i32.const 0) - ) - ) - (block $label$35 - (br_if $label$35 - (i32.le_s - (i32.shr_s - (tee_local $8 - (i32.add - (i32.wrap/i64 - (i64.shr_u - (tee_local $4 - (i64.reinterpret/f64 - (tee_local $1 - (f64.sub - (f64.const 1) - (f64.sub - (f64.sub - (f64.div - (f64.mul - (tee_local $1 - (f64.add - (tee_local $12 - (f64.mul - (tee_local $0 - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (f64.add - (get_local $1) - (get_local $21) - ) - ) - (i64.const -4294967296) - ) - ) - ) - (f64.const 0.6931471824645996) - ) - ) - (tee_local $21 - (f64.add - (f64.mul - (f64.sub - (get_local $1) - (f64.sub - (get_local $0) - (get_local $21) - ) - ) - (f64.const 0.6931471805599453) - ) - (f64.mul - (get_local $0) - (f64.const -1.904654299957768e-09) - ) - ) - ) - ) - ) - (tee_local $0 - (f64.sub - (get_local $1) - (f64.mul - (tee_local $0 - (f64.mul - (get_local $1) - (get_local $1) - ) - ) - (f64.add - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.add - (f64.mul - (get_local $0) - (f64.const 4.1381367970572385e-08) - ) - (f64.const -1.6533902205465252e-06) - ) - ) - (f64.const 6.613756321437934e-05) - ) - ) - (f64.const -2.7777777777015593e-03) - ) - ) - (f64.const 0.16666666666666602) - ) - ) - ) - ) - ) - (f64.add - (get_local $0) - (f64.const -2) - ) - ) - (f64.add - (tee_local $0 - (f64.sub - (get_local $21) - (f64.sub - (get_local $1) - (get_local $12) - ) - ) - ) - (f64.mul - (get_local $1) - (get_local $0) - ) - ) - ) - (get_local $1) - ) - ) - ) - ) - ) - (i64.const 32) - ) - ) - (i32.shl - (get_local $2) - (i32.const 20) - ) - ) - ) - (i32.const 20) - ) - (i32.const 0) - ) - ) - (return - (f64.mul - (get_local $10) - (f64.reinterpret/i64 - (i64.or - (i64.shl - (i64.extend_u/i32 - (get_local $8) - ) - (i64.const 32) - ) - (i64.and - (get_local $4) - (i64.const 4294967295) - ) - ) - ) - ) - ) - ) - (return - (f64.mul - (get_local $10) - (call $scalbn - (get_local $1) - (get_local $2) - ) - ) - ) - ) - (return - (f64.mul - (f64.mul - (get_local $10) - (f64.const 1e-300) - ) - (f64.const 1e-300) - ) - ) - ) - (get_local $21) - ) - (func $sqrt (param $0 f64) (result f64) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (block $label$0 - (br_if $label$0 - (i32.ne - (i32.and - (tee_local $7 - (i32.wrap/i64 - (i64.shr_u - (tee_local $1 - (i64.reinterpret/f64 - (get_local $0) - ) - ) - (i64.const 32) - ) - ) - ) - (i32.const 2146435072) - ) - (i32.const 2146435072) - ) - ) - (return - (f64.add - (f64.mul - (get_local $0) - (get_local $0) - ) - (get_local $0) - ) - ) - ) - (set_local $2 - (i32.wrap/i64 - (get_local $1) - ) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.le_s - (get_local $7) - (i32.const 0) - ) - ) - (br_if $label$3 - (tee_local $8 - (i32.wrap/i64 - (i64.shr_u - (get_local $1) - (i64.const 52) - ) - ) - ) - ) - (set_local $8 - (i32.const 1) - ) - (set_local $9 - (get_local $2) - ) - (br $label$4) - ) - (br_if $label$2 - (i32.eqz - (i32.or - (i32.and - (get_local $7) - (i32.const 2147483647) - ) - (get_local $2) - ) - ) - ) - (br_if $label$1 - (i32.lt_s - (get_local $7) - (i32.const 0) - ) - ) - (set_local $8 - (i32.const 1) - ) - (loop $label$6 - (set_local $8 - (i32.add - (get_local $8) - (i32.const -21) - ) - ) - (set_local $7 - (i32.shr_u - (get_local $2) - (i32.const 11) - ) - ) - (set_local $2 - (tee_local $9 - (i32.shl - (get_local $2) - (i32.const 21) - ) - ) - ) - (br_if $label$6 - (i32.eqz - (get_local $7) - ) - ) - ) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$7 - (br_if $label$7 - (i32.and - (get_local $7) - (i32.const 1048576) - ) - ) - (set_local $5 - (i32.const 0) - ) - (loop $label$8 - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (br_if $label$8 - (i32.eqz - (i32.and - (tee_local $7 - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - (i32.const 1048576) - ) - ) - ) - ) - ) - (set_local $2 - (i32.shl - (get_local $9) - (get_local $5) - ) - ) - (set_local $8 - (i32.sub - (get_local $8) - (get_local $5) - ) - ) - (set_local $7 - (i32.or - (i32.shr_u - (get_local $9) - (i32.sub - (i32.const 32) - (get_local $5) - ) - ) - (get_local $7) - ) - ) - ) - (set_local $7 - (i32.or - (i32.and - (get_local $7) - (i32.const 1048575) - ) - (i32.const 1048576) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (i32.and - (tee_local $10 - (i32.add - (get_local $8) - (i32.const -1023) - ) - ) - (i32.const 1) - ) - ) - ) - (set_local $7 - (i32.or - (i32.shl - (get_local $7) - (i32.const 1) - ) - (i32.shr_u - (get_local $2) - (i32.const 31) - ) - ) - ) - (set_local $2 - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - ) - (set_local $7 - (i32.or - (i32.shr_u - (get_local $2) - (i32.const 31) - ) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i32.const 0) - ) - (set_local $9 - (i32.const 2097152) - ) - (set_local $8 - (i32.const 0) - ) - (loop $label$10 - (set_local $6 - (get_local $5) - ) - (block $label$11 - (br_if $label$11 - (i32.lt_s - (get_local $7) - (tee_local $5 - (i32.add - (get_local $9) - (get_local $8) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $9) - (get_local $4) - ) - ) - (set_local $7 - (i32.sub - (get_local $7) - (get_local $5) - ) - ) - (set_local $8 - (i32.add - (get_local $5) - (get_local $9) - ) - ) - ) - (set_local $7 - (i32.or - (i32.shl - (get_local $7) - (i32.const 1) - ) - (i32.and - (i32.shr_u - (get_local $2) - (i32.const 30) - ) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (set_local $2 - (get_local $6) - ) - (br_if $label$10 - (tee_local $9 - (i32.shr_u - (get_local $9) - (i32.const 1) - ) - ) - ) - ) - (set_local $3 - (i32.shr_u - (get_local $10) - (i32.const 1) - ) - ) - (set_local $9 - (i32.const -2147483648) - ) - (set_local $10 - (i32.const 0) - ) - (set_local $2 - (i32.const 0) - ) - (loop $label$12 - (set_local $6 - (i32.add - (get_local $2) - (get_local $9) - ) - ) - (block $label$13 - (block $label$14 - (br_if $label$14 - (i32.gt_s - (get_local $7) - (get_local $8) - ) - ) - (br_if $label$13 - (i32.ne - (get_local $7) - (get_local $8) - ) - ) - (br_if $label$13 - (i32.lt_u - (get_local $5) - (get_local $6) - ) - ) - ) - (set_local $7 - (i32.add - (i32.sub - (get_local $7) - (get_local $8) - ) - (select - (i32.const -1) - (i32.const 0) - (i32.lt_u - (get_local $5) - (get_local $6) - ) - ) - ) - ) - (set_local $8 - (i32.add - (i32.and - (i32.lt_s - (get_local $6) - (i32.const 0) - ) - (i32.gt_s - (tee_local $2 - (i32.add - (get_local $6) - (get_local $9) - ) - ) - (i32.const -1) - ) - ) - (get_local $8) - ) - ) - (set_local $10 - (i32.add - (get_local $10) - (get_local $9) - ) - ) - (set_local $5 - (i32.sub - (get_local $5) - (get_local $6) - ) - ) - ) - (set_local $7 - (i32.or - (i32.shr_u - (get_local $5) - (i32.const 31) - ) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i32.shl - (get_local $5) - (i32.const 1) - ) - ) - (br_if $label$12 - (tee_local $9 - (i32.shr_u - (get_local $9) - (i32.const 1) - ) - ) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (i32.or - (get_local $5) - (get_local $7) - ) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eq - (get_local $10) - (i32.const -1) - ) - ) - (set_local $10 - (i32.add - (i32.and - (get_local $10) - (i32.const 1) - ) - (get_local $10) - ) - ) - (br $label$15) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $10 - (i32.const 0) - ) - ) - (set_local $0 - (f64.reinterpret/i64 - (i64.or - (i64.shl - (i64.extend_u/i32 - (i32.add - (i32.add - (i32.shl - (get_local $3) - (i32.const 20) - ) - (i32.shr_s - (get_local $4) - (i32.const 1) - ) - ) - (i32.const 1071644672) - ) - ) - (i64.const 32) - ) - (i64.extend_u/i32 - (i32.or - (i32.shr_u - (get_local $10) - (i32.const 1) - ) - (i32.shl - (get_local $4) - (i32.const 31) - ) - ) - ) - ) - ) - ) - ) - (return - (get_local $0) - ) - ) - (f64.div - (tee_local $0 - (f64.sub - (get_local $0) - (get_local $0) - ) - ) - (get_local $0) - ) - ) - (func $fabs (param $0 f64) (result f64) - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (get_local $0) - ) - (i64.const 9223372036854775807) - ) - ) - ) - (func $scalbn (param $0 f64) (param $1 i32) (result f64) - (local $2 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.lt_s - (get_local $1) - (i32.const 1024) - ) - ) - (set_local $0 - (f64.mul - (get_local $0) - (f64.const 8988465674311579538646525e283) - ) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $2 - (i32.add - (get_local $1) - (i32.const -1023) - ) - ) - (i32.const 1024) - ) - ) - (set_local $1 - (select - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -2046) - ) - ) - (i32.const 1023) - (i32.lt_s - (get_local $1) - (i32.const 1023) - ) - ) - ) - (set_local $0 - (f64.mul - (get_local $0) - (f64.const 8988465674311579538646525e283) - ) - ) - (br $label$0) - ) - (br_if $label$0 - (i32.gt_s - (get_local $1) - (i32.const -1023) - ) - ) - (set_local $0 - (f64.mul - (get_local $0) - (f64.const 2.004168360008973e-292) - ) - ) - (br_if $label$1 - (i32.gt_s - (tee_local $2 - (i32.add - (get_local $1) - (i32.const 969) - ) - ) - (i32.const -1023) - ) - ) - (set_local $1 - (select - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1938) - ) - ) - (i32.const -1022) - (i32.gt_s - (get_local $1) - (i32.const -1022) - ) - ) - ) - (set_local $0 - (f64.mul - (get_local $0) - (f64.const 2.004168360008973e-292) - ) - ) - (br $label$0) - ) - (set_local $1 - (get_local $2) - ) - (br $label$0) - ) - (set_local $1 - (get_local $2) - ) - ) - (f64.mul - (get_local $0) - (f64.reinterpret/i64 - (i64.shl - (i64.extend_u/i32 - (i32.add - (get_local $1) - (i32.const 1023) - ) - ) - (i64.const 52) - ) - ) - ) - ) - (func $memcmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $2) - ) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.ne - (tee_local $3 - (i32.load8_u - (get_local $0) - ) - ) - (tee_local $4 - (i32.load8_u - (get_local $1) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (br_if $label$2 - (tee_local $2 - (i32.add - (get_local $2) - (i32.const -1) - ) - ) - ) - (br $label$0) - ) - ) - (set_local $5 - (i32.sub - (get_local $3) - (get_local $4) - ) - ) - ) - (get_local $5) - ) - (func $strlen (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (set_local $2 - (get_local $0) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 3) - ) - ) - ) - (set_local $2 - (get_local $0) - ) - (loop $label$2 - (br_if $label$0 - (i32.eqz - (i32.load8_u - (get_local $2) - ) - ) - ) - (br_if $label$2 - (i32.and - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 3) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const -4) - ) - ) - (loop $label$3 - (br_if $label$3 - (i32.eqz - (i32.and - (i32.and - (i32.xor - (tee_local $1 - (i32.load - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - ) - (i32.const -1) - ) - (i32.add - (get_local $1) - (i32.const -16843009) - ) - ) - (i32.const -2139062144) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (i32.and - (get_local $1) - (i32.const 255) - ) - ) - ) - (loop $label$4 - (br_if $label$4 - (i32.load8_u - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (i32.sub - (get_local $2) - (get_local $0) - ) - ) - (func $malloc (param $0 i32) (result i32) - (call $_ZN5eosio14memory_manager6mallocEm - (i32.const 3712) - (get_local $0) - ) - ) - (func $_ZN5eosio14memory_manager6mallocEm (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (block $label$1 - (br_if $label$1 - (tee_local $13 - (i32.load offset=8384 - (get_local $0) - ) - ) - ) - (set_local $13 - (i32.const 16) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8384) - ) - (i32.const 16) - ) - ) - (set_local $2 - (select - (i32.sub - (i32.add - (get_local $1) - (i32.const 8) - ) - (tee_local $2 - (i32.and - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.const 7) - ) - ) - ) - (get_local $1) - (get_local $2) - ) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (tee_local $10 - (i32.load offset=8388 - (get_local $0) - ) - ) - (get_local $13) - ) - ) - (set_local $1 - (i32.add - (i32.add - (get_local $0) - (i32.mul - (get_local $10) - (i32.const 12) - ) - ) - (i32.const 8192) - ) - ) - (block $label$5 - (br_if $label$5 - (get_local $10) - ) - (br_if $label$5 - (i32.load - (tee_local $13 - (i32.add - (get_local $0) - (i32.const 8196) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 8192) - ) - (i32.store - (get_local $13) - (get_local $0) - ) - ) - (set_local $10 - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - (loop $label$6 - (block $label$7 - (br_if $label$7 - (i32.gt_u - (i32.add - (tee_local $13 - (i32.load offset=8 - (get_local $1) - ) - ) - (get_local $10) - ) - (i32.load - (get_local $1) - ) - ) - ) - (i32.store - (tee_local $13 - (i32.add - (i32.load offset=4 - (get_local $1) - ) - (get_local $13) - ) - ) - (i32.or - (i32.and - (i32.load - (get_local $13) - ) - (i32.const -2147483648) - ) - (get_local $2) - ) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (i32.add - (i32.load - (get_local $1) - ) - (get_local $10) - ) - ) - (i32.store - (get_local $13) - (i32.or - (i32.load - (get_local $13) - ) - (i32.const -2147483648) - ) - ) - (br_if $label$3 - (tee_local $1 - (i32.add - (get_local $13) - (i32.const 4) - ) - ) - ) - ) - (br_if $label$6 - (tee_local $1 - (call $_ZN5eosio14memory_manager16next_active_heapEv - (get_local $0) - ) - ) - ) - ) - ) - (set_local $4 - (i32.sub - (i32.const 2147483644) - (get_local $2) - ) - ) - (set_local $11 - (i32.add - (get_local $0) - (i32.const 8392) - ) - ) - (set_local $12 - (i32.add - (get_local $0) - (i32.const 8384) - ) - ) - (set_local $13 - (tee_local $3 - (i32.load offset=8392 - (get_local $0) - ) - ) - ) - (loop $label$8 - (call $eosio_assert - (i32.eq - (i32.load - (i32.add - (tee_local $1 - (i32.add - (get_local $0) - (i32.mul - (get_local $13) - (i32.const 12) - ) - ) - ) - (i32.const 8200) - ) - ) - (i32.load - (tee_local $5 - (i32.add - (get_local $1) - (i32.const 8192) - ) - ) - ) - ) - (i32.const 12112) - ) - (set_local $13 - (i32.add - (tee_local $6 - (i32.load - (i32.add - (get_local $1) - (i32.const 8196) - ) - ) - ) - (i32.const 4) - ) - ) - (loop $label$9 - (set_local $7 - (i32.add - (get_local $6) - (i32.load - (get_local $5) - ) - ) - ) - (set_local $1 - (i32.and - (tee_local $9 - (i32.load - (tee_local $8 - (i32.add - (get_local $13) - (i32.const -4) - ) - ) - ) - ) - (i32.const 2147483647) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.lt_s - (get_local $9) - (i32.const 0) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.ge_u - (get_local $1) - (get_local $2) - ) - ) - (loop $label$12 - (br_if $label$11 - (i32.ge_u - (tee_local $10 - (i32.add - (get_local $13) - (get_local $1) - ) - ) - (get_local $7) - ) - ) - (br_if $label$11 - (i32.lt_s - (tee_local $10 - (i32.load - (get_local $10) - ) - ) - (i32.const 0) - ) - ) - (br_if $label$12 - (i32.lt_u - (tee_local $1 - (i32.add - (i32.add - (get_local $1) - (i32.and - (get_local $10) - (i32.const 2147483647) - ) - ) - (i32.const 4) - ) - ) - (get_local $2) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.or - (select - (get_local $1) - (get_local $2) - (i32.lt_u - (get_local $1) - (get_local $2) - ) - ) - (i32.and - (get_local $9) - (i32.const -2147483648) - ) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.le_u - (get_local $1) - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $13) - (get_local $2) - ) - (i32.and - (i32.add - (get_local $4) - (get_local $1) - ) - (i32.const 2147483647) - ) - ) - ) - (br_if $label$2 - (i32.ge_u - (get_local $1) - (get_local $2) - ) - ) - ) - (br_if $label$9 - (i32.lt_u - (tee_local $13 - (i32.add - (i32.add - (get_local $13) - (get_local $1) - ) - (i32.const 4) - ) - ) - (get_local $7) - ) - ) - ) - (set_local $1 - (i32.const 0) - ) - (i32.store - (get_local $11) - (tee_local $13 - (select - (i32.const 0) - (tee_local $13 - (i32.add - (i32.load - (get_local $11) - ) - (i32.const 1) - ) - ) - (i32.eq - (get_local $13) - (i32.load - (get_local $12) - ) - ) - ) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $13) - (get_local $3) - ) - ) - ) - ) - (return - (get_local $1) - ) - ) - (i32.store - (get_local $8) - (i32.or - (i32.load - (get_local $8) - ) - (i32.const -2147483648) - ) - ) - (return - (get_local $13) - ) - ) - (i32.const 0) - ) - (func $_ZN5eosio14memory_manager16next_active_heapEv (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (set_local $1 - (i32.load offset=8388 - (get_local $0) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.load8_u offset=12198 - (i32.const 0) - ) - ) - ) - (set_local $7 - (i32.load offset=12200 - (i32.const 0) - ) - ) - (br $label$0) - ) - (set_local $7 - (current_memory) - ) - (i32.store8 offset=12198 - (i32.const 0) - (i32.const 1) - ) - (i32.store offset=12200 - (i32.const 0) - (tee_local $7 - (i32.shl - (get_local $7) - (i32.const 16) - ) - ) - ) - ) - (set_local $3 - (get_local $7) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.le_u - (tee_local $2 - (i32.shr_u - (i32.add - (get_local $7) - (i32.const 65535) - ) - (i32.const 16) - ) - ) - (tee_local $8 - (current_memory) - ) - ) - ) - (drop - (grow_memory - (i32.sub - (get_local $2) - (get_local $8) - ) - ) - ) - (set_local $8 - (i32.const 0) - ) - (br_if $label$4 - (i32.ne - (get_local $2) - (current_memory) - ) - ) - (set_local $3 - (i32.load offset=12200 - (i32.const 0) - ) - ) - ) - (set_local $8 - (i32.const 0) - ) - (i32.store offset=12200 - (i32.const 0) - (get_local $3) - ) - (br_if $label$4 - (i32.lt_s - (get_local $7) - (i32.const 0) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.mul - (get_local $1) - (i32.const 12) - ) - ) - ) - (set_local $7 - (i32.sub - (i32.sub - (i32.add - (get_local $7) - (select - (i32.const 65536) - (i32.const 131072) - (tee_local $6 - (i32.lt_u - (tee_local $8 - (i32.and - (get_local $7) - (i32.const 65535) - ) - ) - (i32.const 64513) - ) - ) - ) - ) - (select - (get_local $8) - (i32.and - (get_local $7) - (i32.const 131071) - ) - (get_local $6) - ) - ) - (get_local $7) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.load8_u offset=12198 - (i32.const 0) - ) - ) - (set_local $3 - (current_memory) - ) - (i32.store8 offset=12198 - (i32.const 0) - (i32.const 1) - ) - (i32.store offset=12200 - (i32.const 0) - (tee_local $3 - (i32.shl - (get_local $3) - (i32.const 16) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 8192) - ) - ) - (br_if $label$3 - (i32.lt_s - (get_local $7) - (i32.const 0) - ) - ) - (set_local $6 - (get_local $3) - ) - (block $label$7 - (br_if $label$7 - (i32.le_u - (tee_local $8 - (i32.shr_u - (i32.add - (i32.add - (tee_local $5 - (i32.and - (i32.add - (get_local $7) - (i32.const 7) - ) - (i32.const -8) - ) - ) - (get_local $3) - ) - (i32.const 65535) - ) - (i32.const 16) - ) - ) - (tee_local $4 - (current_memory) - ) - ) - ) - (drop - (grow_memory - (i32.sub - (get_local $8) - (get_local $4) - ) - ) - ) - (br_if $label$3 - (i32.ne - (get_local $8) - (current_memory) - ) - ) - (set_local $6 - (i32.load offset=12200 - (i32.const 0) - ) - ) - ) - (i32.store offset=12200 - (i32.const 0) - (i32.add - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$3 - (i32.eq - (get_local $3) - (i32.const -1) - ) - ) - (br_if $label$2 - (i32.eq - (i32.add - (tee_local $6 - (i32.load - (i32.add - (tee_local $1 - (i32.add - (get_local $0) - (i32.mul - (get_local $1) - (i32.const 12) - ) - ) - ) - (i32.const 8196) - ) - ) - ) - (tee_local $8 - (i32.load - (get_local $2) - ) - ) - ) - (get_local $3) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.eq - (get_local $8) - (tee_local $1 - (i32.load - (tee_local $5 - (i32.add - (get_local $1) - (i32.const 8200) - ) - ) - ) - ) - ) - ) - (i32.store - (tee_local $6 - (i32.add - (get_local $6) - (get_local $1) - ) - ) - (i32.or - (i32.and - (i32.load - (get_local $6) - ) - (i32.const -2147483648) - ) - (i32.add - (i32.sub - (i32.const -4) - (get_local $1) - ) - (get_local $8) - ) - ) - ) - (i32.store - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.store - (get_local $6) - (i32.and - (i32.load - (get_local $6) - ) - (i32.const 2147483647) - ) - ) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 8388) - ) - ) - (tee_local $2 - (i32.add - (i32.load - (get_local $2) - ) - (i32.const 1) - ) - ) - ) - (i32.store - (i32.add - (tee_local $0 - (i32.add - (get_local $0) - (i32.mul - (get_local $2) - (i32.const 12) - ) - ) - ) - (i32.const 8196) - ) - (get_local $3) - ) - (i32.store - (tee_local $8 - (i32.add - (get_local $0) - (i32.const 8192) - ) - ) - (get_local $7) - ) - ) - (return - (get_local $8) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eq - (tee_local $8 - (i32.load - (get_local $2) - ) - ) - (tee_local $7 - (i32.load - (tee_local $1 - (i32.add - (tee_local $3 - (i32.add - (get_local $0) - (i32.mul - (get_local $1) - (i32.const 12) - ) - ) - ) - (i32.const 8200) - ) - ) - ) - ) - ) - ) - (i32.store - (tee_local $3 - (i32.add - (i32.load - (i32.add - (get_local $3) - (i32.const 8196) - ) - ) - (get_local $7) - ) - ) - (i32.or - (i32.and - (i32.load - (get_local $3) - ) - (i32.const -2147483648) - ) - (i32.add - (i32.sub - (i32.const -4) - (get_local $7) - ) - (get_local $8) - ) - ) - ) - (i32.store - (get_local $1) - (i32.load - (get_local $2) - ) - ) - (i32.store - (get_local $3) - (i32.and - (i32.load - (get_local $3) - ) - (i32.const 2147483647) - ) - ) - ) - (i32.store offset=8384 - (get_local $0) - (tee_local $3 - (i32.add - (i32.load - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 8388) - ) - ) - ) - (i32.const 1) - ) - ) - ) - (i32.store - (get_local $7) - (get_local $3) - ) - (return - (i32.const 0) - ) - ) - (i32.store - (get_local $2) - (i32.add - (get_local $8) - (get_local $7) - ) - ) - (get_local $2) - ) - (func $free (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (get_local $0) - ) - ) - (br_if $label$1 - (i32.lt_s - (tee_local $2 - (i32.load offset=12096 - (i32.const 0) - ) - ) - (i32.const 1) - ) - ) - (set_local $3 - (i32.const 11904) - ) - (set_local $1 - (i32.add - (i32.mul - (get_local $2) - (i32.const 12) - ) - (i32.const 11904) - ) - ) - (loop $label$2 - (br_if $label$1 - (i32.eqz - (tee_local $2 - (i32.load - (i32.add - (get_local $3) - (i32.const 4) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.gt_u - (i32.add - (get_local $2) - (i32.const 4) - ) - (get_local $0) - ) - ) - (br_if $label$0 - (i32.gt_u - (i32.add - (get_local $2) - (i32.load - (get_local $3) - ) - ) - (get_local $0) - ) - ) - ) - (br_if $label$2 - (i32.lt_u - (tee_local $3 - (i32.add - (get_local $3) - (i32.const 12) - ) - ) - (get_local $1) - ) - ) - ) - ) - (return) - ) - (i32.store - (tee_local $3 - (i32.add - (get_local $0) - (i32.const -4) - ) - ) - (i32.and - (i32.load - (get_local $3) - ) - (i32.const 2147483647) - ) - ) - ) - (func $__wasm_nullptr (type $FUNCSIG$v) - (unreachable) - ) -) diff --git a/tests/test_contracts/reject_all.wasm b/tests/test_contracts/reject_all.wasm new file mode 100755 index 0000000000000000000000000000000000000000..ee794557a9838a2f86cff0881e430244f95223c8 GIT binary patch literal 1013 zcmY*YF>ljA6n^i{j@?|M-qeBV5;~L>i7=9@1QkLI?H@?2)U9HYIIT_9GQ>gZn1K3FN%WtJmaD-i=sdv zya3$_1s53|ayFY0YBMpe$#`7=(C>XLiPGPKk!J0YR)VR(XAds51VB1Y=}kIkkv&+SC!JT_dc{4LxnL;V#+YQByRevb2g9HBKDcFcz-5)nwrI)dguXa#b0rI?Tmw zXgzB~xFZ^%LBFvf=(>zUJ7NwW4-gk!B}je5z)PxJCtVZpY&Wf%Y<=&o4iJ__4XuWUX!x9R2;`>*DO&d7-(<4FT7>VdNbd zUMp=^lYJ?5E$I~_txncS9SNMqY&l_z4Xwk1=xW&(_NDjO$?Kp+4OVb3>}q1C2iOZR zU9P=b7=Z4}(D}B(lXAMBr3!X6OmIx0_R$18EeXhpVp~7CgRNA#B@ADw%B8A=Dmzt% z)1@l9%G{|^sagdXsj@P_KPWe?2xkR;N-J2mxNJH;u;JEq%WzUP;V256LT{N_KOAx%@7q)pN! zt>7RHQXV3s8DRKCWeC2CAR6B&DiOoO|xgO&Zj( z;TwwPo^$rzYp=cb+H0@9_S$P(Eq&W;%d+ed`^bwd>mtj({37S_%lWYDB4^hwi+}K# z+J%4kbxS|iMK+StyDrB+JYSB~44)-mTAo;t5BRl_2YFGPAX(te`2S@VAfpJ=_%Hfp z0alkKxLvyl0QsaWpk2<|F2BeHWWum712Fr|&Z9MJ-L|fsHO?ZO>uUV-nK)4N2PaEK--bbo^ILL-P>f>2GV^+}6^+qqohP&Cdt5^!2s%_BZ#owRZ1p>uv6AyVN>F z^P7bBp0;h9mNhK3a{TO>{C!(mmg$#5>C5ty8YX-@Y1wl9HoLW@tF>)w^QN}VZN0s1 zo2)|#?}*kdZLOWnJ#D?)+WY#5cgv3cE#1BCZ)#yHta;3oZ{2|sUH#4d?c3TcTkzPl zv3YZQ*QVz7hLzSVewl?Y?VB!XSlQgy-;L%K_;C(CZtZ?!Tkpp19m&jje3xueKF_QL zeA>|is2KcL+twzXX=RxX}d%zkdfDR<)0dTS+;zYRl~fR*rkaIX8Y!3QlGvk%)aKW z3R83TZMF^~5PjQWs;HGJcC^QJ_&qx|Zf$Q(P*_;P2hlf4qYd{fG4*qQZ%bF7jtu?m zB{}{TtTo@;wtYu?Z<}zSHlUFFwA^x-ZBFzJ0NQ)n!Ip*+z2zfiUSAtHuB;c^ySBD> zwP}kBk{k~PpP)VYmduqZjk63M;{nE((#Yy>>FMrk-ng|JBdKf0HXZN>CBOFcwry^| z#7Ke!Eg}K&puN{lr_*kYW#v-obSed5ox;OH{NkVa(U-(u$ya(mG+TO3JmpeWHvSLa z7v@rjqO$bDTz28YT+Kp!$S$-FO{H0;0>r`^V6zZ;Qu2?*@DE@3H+ATtH8rW4n)KmE zWU_}Inm)89m9l#*bg*sN*>^8~i%qWX?!DBpUeWwlZQGm9S+-2%P2Y}fAmwY9HCt;Z zBtXRupy*oHbk2FNZC=)p9HMPI+qSN= z&O8Q1mM!aV!+=#zT(&C7vR&Q1+gi4++i9&kdP2sNrPQV!+qPY5$|B$TMHBKhBmwq! zH!nrDzt~T`$kwp36B*AdPJp*k>TTUzs`UJcm9C81-__mU-rBbA(n~M3UKdP&RZgaz z)`eBFn7L$g%htX&VD!I^oB(B+$GelU0JBuPfzu{3{O`q; z8J255RZ1G<{j1|9$s0{lkPB^)yS+k(|8KIsjB;~^0Mx&pNY(~LQKw-}G|2XUgl3Ao zh{a_qB$qrxnj*^^q_N2?rYRKZeaO%}RfcwCxJam;gs{9+$qwddsUr=NIh0Z2$pCpa zO3x(ooRowDX^u>-Q{mEu44bCHrH`H4HdT&I%&~c@9NU@WVxfK#R~>ND9>~aTJzGir zEr*wy-G6CMTOUZkACaO+Z%>d#(^s}`Y3Xgo2usBQy3x1G8bs}Y`qI_cPhE>yw+a7E$f{h^vT0L06%yp@ zngpbDS>KM0m@`DJMAmK@024r-B3VUi?TKb*|Eqv`U~x`Iw(hK+q`i{I~3}!J|lru zy+*}5rjc27Z)Dzi;#81z#A@aU)i;t_lj5Q{8r>f7FX6N@X>MgolRK*5(rHv+mL90! zP1DG2)-}leH`B;%mNCeE*)(zkHWxj}{pM-VUDr6seEBr!u9+jU?3xBLW(@`S1NL+X zUtYr%b`54@4BoA6UDjLVg$nhy9_vbhW*Dut_tKvJ?&ZqJ38mAlDw@qiw%cBYt}id6 zL#j%dXnwrPPD~qG(K2PiL?JZqYI|WNaD`3v66x32A|iF7FmUuml}=>2cB(8;MUmyL zc49I%P;_31Rb%A3t{Nb%2FmMJ%E-6b3Dv*=T254(ySim5ggn<*t1JQ&=la`8aslB4 zthd{VS=!Wha*T5#<2&qER?>0VDMsBebw^z@XeZPz19Me*R@3u;SFQF^&SlLJ$Q!El zb~2*@c;nPqvh5Mbo2JH+Sq;#?w?#lFS!DTgQ+bJ05!{>Yghr*UUmj_0rQ8Pe|Fw@I zRdxEsgxTI@m{=FETpV*Md#Am!`L9lC?e4i$c;JH8j;8Zo+rOe2%J$B-R;>BYZawd{ zOPfz=*@}fwi@dMHKkF7Hn~sab+Gp7^S#HJi+Pk%d6Z4&%$k*Jqt*8G|U~}uVa&K+v zy_lNAZT9hO;zZb|Bw=IF?&uZ8_jZ*a6Y?)#k<70vMRaC6N6q^tEhBU2#N{B$e865( z6|d#m8ObtOSfaoO?GvgOP{xquM}o#Ev1jTMiOi82b%#yaU4>W;()dIPQL#TXNgI}} zO45qYMkoK6irR_9U0w;_^fnhXpR~iONUhLX5=ddhv|oHNG!B@#x_g_qv~+EP{voJ- z%09a)kmU_#B+2-xD2N56S!gax)UwX{%=DX~Y{+KZqq1Q_+n243Oc68_b#YPjS&p|V z-LU*5Ayb?`i4?2&oPAo=ax0W~tCfTKv1e1>S^xmnZ zLYy@k;ScCcF|qTOL*egl+q`3Ib4w4`XAi0PotUwq%pRqgAD&b`cD21RGA07(KTb9* zSE-zCF3R3JHlmdbtArpCFfvRnfDc)pKt`=neZvcU4n56!XlTZ(;0JG(O1avcX%jq_6Od#WXBIqsW4sc&o9W;BwGEq(2+ z;JxqL>6V_Jt(RK=X{R=~Z0xgsXQ%nQ*?Qj2QuC)R{r6&WD2zyr&4?EycJl19R~gj_ByZZWmYLAw9fKsE&t%gk=>^c?D3eg*p)vyf2DV` zZQHv-E41pJR5)&R7Oe&+<=2LV^#FTVV1-BcOZhTt$=j2bzK-c@8gJ?K;eaiP1x*{2 zwWjFrnk#D^B{qOzxwRi2>5RS{&daEY9;d>9hH@iL@a{R+WUG=BVOuT2Z`kfE)*>~uk+n7)u{sh@mcP(nSVT)+6OIBH(&tICe-<8( z@2GdIu%`npud^Gix@_aAb(wJ7sY~M}=dN|)|AK5|=6@BeAbq@L6`k<5T^->*dwY1; zIR!g#!VlOTbxz*#P^tzwz1J6(&FmlZROZ)z%7USJ2g4dH+*t(MExuxERa2GKk)er>(8vgmXK=}rJ!C6KI6)PZj3j9~3j0+(O~>2={Kuqoq#pmwo4 zPxxY{vqDN(A=e?~^IxrO3-qm;#)oatiX$bo{3GV$XGk)WNa=zNo(*c3SUDM!W0Jx` z$uT*YCh&S|PBbP*^aBB`E7&LxDhKHX2ZO`^h0Sh37t}M6qw)A;nvBn3TZZz}w(VjF zQ^5G>>AEx$Qy9hIZbz_PSadmRhco_RY*65aSESAcOxGW9>QZ^zV*z}f-GS~01j+|+ z1d8*szYx-i1Kw)1PIi5Wka-<^qA&^gM0{DH`~+@C(Qa^Z0GB-{972`gmsFVZi}L{x z4;^5~QWD;gQ&IsV^w}Ulv+(4fjh}@b{%b&MaIGYHUvypjatA^yuot_zI>)eCE*wwS zrSOt=*WzymjfC*P7?t*>C~DlKs6pFB)VOFo9#y!wN#O#aOsnY#Qz+*>>bNeZ9cNcSeyz)f=qz>{x;h8RkDpXWo$I3e0tYCZ9gY$q z7mvj(W<1c|4YH`Nm?giZ!hP2EAj1iynCZXUG%Cz?)Mb#C-6^t7SRlQpi1C0bAsO)l zXq}LV#mrw|7=SH75eYyHvb4XW=l}taXs+kbCEmpp z0M})JJR4Ia(tsON2?g;*Nt80r9mNdWF(E65#iY5j7z;&Id={FAn!PI>HwBv7hNc+) zn0|rC1e&HN&@>&Ti5rkUMb2#Oce;OGF&O@+J8EjS?+hOCGTi~zJDd;uTa zbC5p;`DynTGborkdqFX?t^gsQ@qcbZMS*+}UbWEOnb2Bo0SN(5LQ1FF7$QZxVC7RD z1T3^6NCS!+%m1|v&T)baMTx_vr-f?_m<%9*afBBWRyh$6K>M*)Tq8>AJ+a*&N_1(}Xd!a^L}n7Po4 zBp1g53Zc)zH=K>V8VeJDt-o}>=UHf^tIyBOgFwq9bm&3!P7P;?kg|-nl4z54gk$e`Uw9BwBQKU z`^PAZYeFnxULVv@2e^Pe0y0@7lg07mBmG-wtA(!R_>Z zke`J{FLrzUIx3kXri7&B^976paMa;U8c!y9`8*d*DXhC(uDhriK^ZEsQjk(z!=W-{ zCzT-^qm1h=>aZvUVHfKfwo#4jq-q5DVn@0L#!rU2hMUxq&{EFjDXzOX+(b)qsU^9p zB~>Ddb;*oCG`kxzXevZ=GXzmt$tDqnkj+Btv%=vlnDJ1u$54&(ns82S-V^rFVQan2 zB_%V$i)QDSK9@ka9WsGMYVx%&OAspg2@})*Jl?SVxf3`em#29xUiQ~ud8h^e(E&K) zFNJdBZ{QrZ6q7!FR&oh&3g=1rMD;*se|)Dh1@SZj@g(!;LS1Z07C@$sU}-J@Rs$9$ z%M4!TCKBWMGMmqp*mgKuS8d{RX|0!o}MRO*f_56c{=(P!noz7>feNN@m zo`2$m+%9zHaI`ke_@@B=SP~G|DwPxNjMfZvj>>^y(y%hUB&I6jD&&W5w#syXsIHuR z#kN-yUJD~hiMMrVT*6eUpU*>?EG35gG$_`+*&KPJR);JazdX_Ul>vRy;gBcRuW~&q z)0iXQPs6yBi50$S8<*0t!dEgbWvK9F0vM~PN2RIorDL;Lw$d!7m_t>iS*#NC>6*p< zOqh#V%xZj6jGZ>56c!e=Wf=2VZ0w?Kh-*tXyli`zii~DlSt0=o1*CZ+YOZnOT^AT_ zb6hY&v8UnG5|gS}^KHmKDAG10A6GJBKJiQDe43if9!I7TCU{uVVsn1B!kjP2qElcB zQS<>uEHevfg}~|=CVhn`CjBHltnso`&tcjJI{`~TNtk!csy!`s^e4mMzO zSZA1hO*rU5xX~0O#$J5ID!XWvk~s6`Iy4m!)ZPmqj^7ld{MSO_1v&lb?QvWO1}_@D zW3xBvQUjlum}soH8||X`CpIpETB$vCG!&#rEwEivF%xF{(OWPh_O7;Oi+zmv!dfo) zidjz#FIig0)$}RmI<8oynHk+cp>ltQ zEzckpcZ!NGi3OvNAr=jkG;l`5O7lGz(+P$jd?20F#tAwBwp#aSkyA>k?a+at@4N)b zGXw?W4aXA9Z+uJBl2Bp-nEXDMbDUl2%OO2p8logdbXcWzjhkHcW*S9HIRMhSW;ga) zlhRt(;ut3sCs6E8iZLIlKF=H|%qPw>*#xqN%#~Bij6t@Nsxy`!U@tw1Yyc@T3Moz_ zc1>VyC~%`+hu+NR3&GbjE%3bma3DKUmxtq?e=J(zLW^?3fxPTdr^?2qtK-t9*~}_8 zn^|Huv(#*shT$mMq63}8UBODOB`N+Qvl(W|G|gsCtVQ9A4Ov--jX!EpF0JOfF@rhO zq8y_|rTi5!vV$)HWW{D44(0vB_+*D8PgA7z5`p1Y41tWE+;JN#FML%;@22@=oP;*Y+Y2WirXIw);R zptLk*3xFpM_#qD1fk;%1H>vv0XZAkmME(i>2~pLkE_yZ(Qr%MNiW~AG58}}^JgcfG zNO3_mLqtJ+jO@ru3E9!=$Yy68Wi7v6W`(ip2#W{UjAMoI>d4kkpSl~=MR z?O>)bPH5QqDR6CyrCh|f*bAN=4KlDYw-GUe0#R9OPNXd5Cby|9*+idgh83Tkl5qkX zh~?8Nwxu|&Ce_^pPEI(O#3?PPxQ+Qg7OQyPH%*){`?F2y#@SbL{alW4bv+;=q7x2P zL%1-55gx9F@T{4Kuy>60D$BCg_{Yl(g6E!*==u5QmY-yvz2(-K$cBGoYy3r$)x6Id ziQebj@a({CZ}{LD=H0tCIp3BhH#4E`TceX4=Cjg7d(XhyvdQlDM?XJu+ZS&61@dyz z+x_GXSO4_BTb?~Ep7$0f=Dq0I*N4Qs_hr{k#b%TMjxnk_!Lt|23>=d<#rhlt;mB-% zpA8MT2c9(ifZ=L|9^GnOJlOrKEgw3U46? z`y!g)#|iVI1az4Te!TD61URf;#!SM&l0Kq8 zmeZesd0I|?#`I_KFfFG)^PT;>3rY_F+g)I>qHB`0B;)#&@btS#Z?_$BZTF}JX5v|w9u{lpO&HtAo7{A}2}oZXx}6Xx?uMByN582Z2>>h9)3HGwEbth*r`JVN}xZ9#ij=^N8l$cUyw z;Oo{z88z*gn#LDJ$Zy>3_Oqz|18HkP3E>`!K{TfA0Y-EZ+Kwb?J64^x&Wxk2L9~*# z2MWmf z4-}%4&~`LQ+wtnOmF4P;qOC!+lC}p5(Mf1KfKz(V19XZQ3aZM4(q{EckqHLTO4=SM zL?@x`aFVv8)oCksp&7-u2GL5|9wmKV z$b^yVw5^$OI+#JUlC}p5(Mf1KnxySOu`1t+HFJ70VY=4Lsn!l$;J}H*tjoAcE81$! zj3)+zXeDhA6rw`gB%)?rR*d;J6OP2RMJr(FC!z6JlE#CJs_=1a zc%NZ39#Uk>X?$RjorK22ixPZ17SmV_bVgbns71|0OJXD^#$)=<2t+5L?ZD9q+72BZ z@oyQ*2TFmNoVEs0@a~L2bQ0PQCuutt(>5{39oXSEIeo_!*>c(Nia%C)`J*P}NoYKH z40arbJ@}T0pQ^fI#!lW4j-UzH4I0A_kT#BTudLbvF*#1$ zxUaC^{aGC4jC;~<8@my&Okh4-9dp@@m{FJy3?VYnND}q2mkjD7J_1lBQ6H?Y$}b|h zX9Cq@#x{uJAVflPyNw45QHi}#?g1KP;K*2?;OLR+v=x)djH0bUw34<53ekzQ#ld%Y zc!IXx@fIZBIG*q`vRHlwj@38)88}Yg@B?p3u`Z4)W(ERxE z-fAaY9pQsP4+DZcQ6ZFmN*<42eHuQQbhnIr9^pDN_MyYo`9mBX2T!EGB^({?aHs@f z0$54o;$D0UyhE+f(u(7s!KFZP+(xuG2Vr{{W(HY!u7<&;c$kDE1zsIah&TdtYFM(K z&KWqh6gVAxKW_a3909>oQKFBS@FqDpJxF9VhN{6#&Vwd!H>riIDo@eO>ksGc2ruaP zFdWC$Toa@bOX;#k_QPZ1t*=v zD2I&?Z@EhRnj3drwfll_7`%c^%)p%J$;mSjQX;ymM;2YOT) zI!~5z3@#H~m?Kfm#xit~MSP*u9s5&GVjS+50Psx$0i^N7S!;`1uBnZ0PF6Rrd7_4! zEOy+c!R00DNxP@aan*eELRBP~qEs;e>f$Pf6IFmRraUsoIYu=HkxXPLBilH#B*?aA z8dMXykZl|YkHHmXkWaw_Yc>7juPKtL%mw zr_&8!2^=zj6CC@XM6z)u8B^^j)rnbZaAhKm;rU=f_A|HkMaBt`(Q%x2xtKvDnK)s|3-q{A0bbfN)qmPeQoSDoEIVwft*Iw}I6YadxU^zer?g zmF%FOf}cP?o&LwFl=(qfnI0pqmE}&Ih!LomXu*|@2xUBiYzZR%-E@dZ;V!Z}E#zz5 zn5=h9>pcRq5OOEGzl&^#p7X@VGmBr{Y4A`=@RML=p}AVUg7G9;ix>^71}PGDM* zOhsyv)C5Uh)C`=4=pRGniSjRwq;NN<^sh#Zn4~7p6qDV9(#lg5ATQn{QZ0gI>Mr# zmj-HFk+Nf#(<@tI8v|m%mcYZh8XRF%O8Uk-hz4X(;G@19L>wNPS909EYVsJznfED(X4H<^C<{)>__n?aR(J4rEY6YoArdP$7 zRAGo!31fVEFb2OwG$V3V0vYseG*U0^Bt)W;YjM3@A82oaQVwFIKzC0~N#so-2u}UE0(*rWRH)1jL_5OIQ zp@L!~2(ww8VrAoTOzJQctAsH=Js5)zBq>%2WaxouAu=LBB8pW48J!-GaRE}|v11Yf zJhJ>*;ggVoKDb!qHtD*tij=b;+y)+mh%_Q15_5wOPOCY?4@P~b;$eSPa8N~6j7+bJ zv5G1-C0Y@Wr(`q8hEW~klh#o-poSlcnqgRQf9+t$MRklkG%Zq%#dRpD&aBdDL!5Ka zX_&kaR2GqN`*3PaXClj=jd^U`0O3^3E^VIzNU5CgJ$b=A%r=sepHyZNx-uodMNg

zCnc z_@HwtFcCaILiDug!H@AgEq?N2JWq?CP$w`pbxlFxhN>7B$}rw9Lo`JA79unoqK86^ zWkdW_h_P&lpHO2=;eNXmdu$Ammk{(C!Jxunge>`xXpS)B58L4(>%+l^IlAmRXk<9> z7~Wwc@UXi!umh`OvBi%lqt6?{Vdh00jOqnAMpMJau_OG>ap|Ba4?I%WV`vi-XiD^7 z#)>Ms67-&-voM%2jCk@h4kLy0sC0?L4C}uOzf|4?F^#hBdEQTL6VO}&S|RYb1WT9u z3!vv^8J*fHMSBM_NY63Gd?MsKb_k-7?^zA`PA@#3UCp9KiS5OBVn7yA>>cQ$64yN| zN76N}J2oZ|`(L&~|lp+OF5|RAfX~aQGCw64UpruG4v~2i2o}67`J@RTIk!473sOi?juO>KH z{}x*#uSWRpMyxn+_|0L&Xjtzi_$0`Iff==nIOGbVmAi-s%6VeqE+RUaTXWc%!pZE= zXBc!l%%daGhxi5OunQRdj29T>r9ar;Jl>2C*il0VAssQ@kTbv&`W^|sCg9sbz^W&} zdHloJknh3b1+0Nw^NJFR9n8vna;8{nM$rEa0=@|7s5Y=PJS%HV6v20M3|Zm@3M@NB zP*y=Yk%m*)X#Or$}`WWzB_2K@a_V!Fp}3If}~K8AfHoc-n%GK{~+t7AAJ7G3k) zNZa7|o__LMuhH$M&wc-6-@W6B>wjc-&&W3}Q#3NF+O<8MNJOfX^hQgW|J zoQ8W%oakN?5Fdkgq3&>E@DnXwvj9XFnWOZ)%SP~`=vs&i24FX3NpgWQGei;ZY#=k!@)8g4 zXL;WW)EKb6cml|@lN{a%Mj8!o^He#wzxu+Dhd;c(!Hvy)6^fi{A#aic9P^k&807!} zCVCHvjBN(;OchhqBp@9S)`G$cGczOrwGQN={=pv+x{MJDNr)OeG#>LY3c714hD8aP zjX69K=aSdqM8QCf!vXatn)j&n5Clhfkzp&9h?H?vg@O_Z8b**!iUZCSC=4kgB$w@J z1iXAt2H`v_=lfd7RkWQKzELCuwIUAihACg{UoKKpVgpNsqYu;QCJGl!WaWxhEpHp+ zO&siR+ybNmhbAxEk}1w+Tiu|NbJzm=Hr6Ln)F*1o^a+L+ zX8(ykQOg@`=7IC^LFPq#pgw`%E&-mPPar|`iP`|)76KOZ3Et@J!dSwm{J$!n-uow(PybDFDJKh|pE-ZDru4+8AHVCWpN!tM zbBa~a%VMb{mR?>rnG2Pp&{QG~{`3bgX2!bd{r|((O%Lq8=3n<~6nR-3l*GYFiM@c> zuNOKr?&F}J1k_jm4BROAR%obLZ$;6Wr%~$k_2F`Zgn=^u=X-SfC1o2U?Bc%Yak{46AjtF3@P z4bCF{sSonFFK=Y`=>vPh(?AzrKd;2ks<`lJ@e>NNJ-iyy0LDr>dR&RMFjl@f*x<6X zr1M7O@&#p1?_SI>hy#6SqJuo@JGds3 z<{h!5gC9E34Y3(L!(}h{K_cmkpPGtN}A>r;3dQ(<|o1g$K>K<$z|Zw0O?{4Mpc#%xWT9++)9IAL;<}? z$HG0TAYqp7WVk$qwU9#5CBxuC+BHBoSQnL4b|;5uxJ5|C1jVPA6Qd>Y3502L#!5m% zWt0ZErL+hy+_kK-4fAwxpTi{~f4FEaFM12IKUtX(xl@fdSZ^?2-v<(V>t#p(iKuPIB^fIY@$d ze!`_vIlZq8MfAe-lbpHx%>%=_a3j^5dBrS6;obWwgdW1SKE|3yZhMgpBy9Z+(L9X%8Al$dY#sn z8nx*EnMSRYMu9asmeEtZl5G+K8y1kBN}HZSC&?}d$QwFBVeIHkhr$rx5YA;3w!9Cx z(0VIQuj-x^XG^eb3O9&Hx4vfG8KjaH`{+pC`+4#~r!7s6y zC-{{vtt;UtB8fBuQ&PtOPtj>Z#yceeCv~Y&T%P2{K7fr}2TZf&u0sQpYKQa#Ku}4n z%o=$aD1~S{L?uER+<=&c+`}b^_!ap9S%h6m0IJJy{R0x3bITCK*C`20K3Rtt8jTW5eF{57U&{9Gh+K;SL0+PO0J`0cL^H~%&Di9~65%y9|J98fX@5MXe5 z4P0Y59s7slOb1Tq{^7XOfwOi0a8lEOvu*!y($j&{wSPF7>A>kOgVW$l=&dZF(2|fv zC#~#IE!c~V0m3AUkOWIYJ%1XUB`JT!JU8;*e98UbuuqZ3&*(5<~#_ABW&zj-I02nJdux zb%CLB2B@elAu5HH5o`%uGHNmYphTy!B}@j3D=M`mAjj(ywf(i$hMB<&XR?{sYa76;gcND}L} zye;BegHumqd}7Y>_47*nMAq*#%;GvJNeNmxV(WK0jIH0|U7K*SrLPzzC8ZfOOxk5G zfR7M}pSWRV6EuomfW)tt=4o-Lr#>oh=W!-fk?!LQ2qk{? z)0n|i<+}kX*$v>)0zgd8;PBm(-GEebHy{PuRkR!M-#vr>c@g~+&EOYJoWU`@Zvk7C z&EWX935FX{&hZ!A`)Ms0bVbGjcQF{Vz}8FTn}?*0gIQoLdU^S~Wh>vb6}dmG$Ac$Y8!=vqlcvq_G%D zaWUdTD8WD#Ek(e+XI-;)&g3sdHHY*+yh8}V(NL1;)9GZ(IYZhRp2mq0KPNv6dC z=!y-PZs2}r=;MazI1OK3iftdfK59GKCvC_j`VVWgYW*i`w3*X?BW#1WJLlGv*=@$* zS2{;$`$8}$e1zTzoPFnn!*~qhH+=kj4qu`1jL2_;v)BASjNhP;PB&;HKPo+bT`Z7uhy|Wx6BSl1Ih+7UT;>JX9;?CsYw>?rf{;3g zkuk6{qFbogrl&y&p3TNHVoopz;}0B9e+4hx7x}uf5_mqp3oAu@6xRquuIQ-4fT01b zMvB$d8dv-R#w~WZojNKLv&zP8LB}m3U0TK3@^M=$|oaJx>?A9ahs1F5)@G|C=vB55ETYJ0Eqg#>);fU zKop$@rl<{k?qJWMr5vy5R^h{7mV9Mz``9cOZv|=++%}++2wTIPlC8mm36p&#iE{$z zu}~ZNL4bMGPHN4|9PS*?HMSqwO2mQzX}ozAMNkF)Kvx*T7OOccTQ7!EK=X^9-ool8 zGTv#kA|#0mfK)y=@XX#PQUa!+fy4^T#{^iHv5Sxk1KCs&mR_Zty%hOm@KE^?rbbC% zSCrPI0x!~k^kWPdDMsZV7onvvRNt8sj;rTv4nbS~7XD1$^)D;`FDw5q+I;s1EC2US zrTo)2j7TsTd>revF0;kI^-p2a`dAuf-Bcok$uOMJO$d`;!zuSZyN*5(e5{4DK9&dYP~g_R z?w-NjI)3Dri(nW)bV_XUU7%0U)nAWQkjqt&gVN%#7uhdhV34g;hpQmFd=+HNDv0;K zqZDoih*v=f5h%Ktom>UclQ3EZMOO*B@hS*k9InzFfWay#1!vs!ZWu9KE-qYSy?}*8 z{cjG5ah{ox;@uyyt8$Y%y(Vb*TiVq5o zgh%?H!;Sx69GoxoA#zh3I60?+WFE^G`{pxrJ2-wz=v=|zSh|olc6%A$ve?08w!WC9+Q3!?xGQq8d zSRo)4?D7UHU?kqtbgoF9%1+0`;30lioVLX2H(;(Z}< zm5fs$R zKpCix*#FXvud++Quow$w7A^FFmxf# zv$CkN?!t%#u?13MK~1Y3j!pqzpfQ*rr>h3C`uQIio*^2ImUT{v0gbMw$g>S{#Qjh@ zgqd>=-txrM%LD9?2spWj-nZcH>K}#E_V_tM&(ItHSD5w9!p+>nYPzd(20Bo;J*IYJ z;aeuyQ+@#L;T_x&|Kv*$dC#k{8h`!SXAbp`@y@kn$qe3mYLz~ z#$A`;1n(6CW5b`h?KAKBh1Dbnmje6EjltE8!8HJOLZb5n)As}4*<0g3XNUZSVzXM9 zL8B*3BYQFe^)#|4gR@T~`|JcVOB1+L_Y=mgKpuh6!O2FknofbTaMaU42vN{c!L+H9 zj2?ZZiy(x_gLG^Jjyb2e>)qi$X5$xa!ijNFX2T+n4nTva4v9S6Uru+zwW7##n@9=t z5Kxv{4o+_I+?F{PN@IK>cT zaY7l@q%fH9gJk(gbr)$3&Qknf4YLYWLs@qHZ(`rPCa8g7jeq7z8JzVZ1RP?AI8i2r zKDG~+6CL#7lij5TF^~{*zwN)Gh}hEf-+-A*pyF6j1V^{uP0lFsP}E3r=plT;3U!$s zc%%eOAtZ{c)F20GG;H;G@1RnQeFTonUtYXDALay*+0 zq9_0fbHbqt$qau2{a)AHvPScH(v@}M2g@d2dVzqtVfLJGC_~4pz(wn@u;QIGSb^I( z#}*}tey6D@Z035*_GF81m7Vgw)se%Pr6X#i;GxQ6eq@jg4TmZ41y{M~P#P&{!{rf4 z8Z$~qB;DjO#Cl!zvHQ$9O*&3s?x;7X8{?qjv^AqmiDP~^uZl|8J#yeTS+RqPb76)K z&PCFI@Z^KO>Y2aJu+G#8$1+o=tXZ2F&kQ;1sSf7K?O=s934j;XNRNg8gXh%!+{8N!pw>BMDK7es&Q@<<71z_y_oI4 zTh|ZSFw5bV3bQ+SdOiX2K((@!OuVfaG| z2+csKuTXc_(I^c7xpFWOlWIkruqeZYt%qzC9KfK{BN#YDqy&`nlF}mRJx=(BZ2}|B zHbmABJAi|agf_A?4ux<6uE`}sh{Z_FIARNcaGCANO;nV2pk0VLl`;Z2!Ibb_tUa-% z!au%$B!A|?%@TJ^(GudCNn}uiOOWu8IP8o{F~oMG0PY2j#1KRa#1KAE3?)U3qe8?E zFWC-JmOIOc9?BOanRBu@svIZ4ZskDANHHQsz)7P{wf6W6OjAZHn)1;Fc5NKlcnBnp z7AC8$L97MBK@WqCYAF5;Vk?MtCVUq0C|@K|J_oraEMuJ&4*VVMGq@=14+XL=25}XF zGGUoih6jkUA2bjVhPdEP2ZPBzpz=q688ToVy3IY+t^$YrSA{CVmbnvcpmU;4bcPL_ z&yHDt6r2$Q=Oe$}^NGK~oHda^JaS(JBRPo=OEEC2cZkubf%NFzAG!LnKMK;ALQ>-$ z4S0-VKM^s`r&SP>X%^RA1F^;KpuHg+H{e7S5q0E`0yl7jvgD_K_^anJVyYlECB=>< z#f}BVZuFnGU$yV4@1F2~!a)Vu_>DW|zo*x{cm$7QdyhkVZ})#^pLtZ{4f)&O^U$fS z;SfP5X&2scgNA4*`eaT($fi&wpv;=W7Dz zIM*u22(iK;y+77R+3=Clmr5Zq5uH>okcoH_vZHoA`SK!~Vj z(3N5PE6ss?3P)@GeKvIL9?X841XMjvg;1F=r>(}e8YLKxsMDmON-ASzA-YM?Wke_{ zS1yw2n405O$2=B=BPzGDM{&3oJWJV~f$qqY)dFn{=>40Gc?hBgM(ORGU4Z;N*^h??TjF%AAt2K<^}e%|@*;Y+Y^>{~#ttXl zD1pLSa9-5u@)*9;ra~GXv0j;O2+h$c2&F+!kPq?RXaW}0QoT?#hLHz6kR=a*VEhk^ zWq1IKE%3lx@`6OeQ3l9iKLmM{3moYnstY;pVv5QNnh8sQ38Vt7OUMNXrxSBQeTbze3Gb0zhXJ02oR~`^+p^#K?x^%G8}KjR^tSuR>erU zSiPYH0`_IX(F9VWu_P#@-U}qsevyKoLkX$VVx(4;kU~X@6f{5@5KGj;hWD>)&_c>S zN+XU8?zApqbMj|G_JAcYl9z`myuS(*C}I-Q`ciJB?}O4;lwbF)HQO10_R|nTFjh>uXFJA4Air(a71_zo=>Nd0qYm8R|-ew zk04|hl^hxRNIg~Sv^DwYJaEs}A#M+nPC>5fZRSIjgWBd<8zCAC#lVFw`C=KZCusOZ_MKx{^0Q%0zKYcqj^-zyhaH)Qcm#f2a5sK%>l*0@!NxYjc=AsUVq`{3*V2Lwv=d5DgUHD;b#DBmGbNVc zPhwPv3T2_WFh5chQwxE-!37y80Qv_x|34&LC)dUS;^M-T5ZXIoNx;wcqO+iwVt)LI zk~AT`Kxc0a)&>2#H%Kpl9OtOfy)4W)h%m(~-LOau+|D}7T^nQoC7>PWtO7JJAZ5a^ zn8}f)il^8~f8FUBbog~+IPpD;4 z?EoYuEC;a200~1(KGJZEgUaTK!2>`g%l|QtAW^>~F=+u3Vu}q%h$-39{?jor)mCE_ ztxgIoHT)FaPLK_hfvo^WRS<-x4zX_OP1v-3LGu(_5@qmsZ3s86UA5)r1PC04$WGN}-SxY`7`6k)ERxfk6A zk4|R657brM2nf>-av)CKx`L}o_>m-vbnIeDKxG&9In?Z+W~Az;I>=hEK|bvvCmW2p z4xi+f!T1B)jYPmF8uS_goixNJb#&@y(y4W>*xaHo;#>uGbukYJA%Xt_3qo1vJ@yToc1(1b&o!BmkX|*gSO%qD?19v_M|iW3V`3 zZ*V&R07(s47#ApH5J?&?W^4~)5Jaq6kHv`;v_#AQn0kb$fZ^SdvTMrZP%XKy7FVH| zp~FWVI?)sE_0gg8Lkt~$Oku@kQS#zhMvwdm6eE$OK&}6yXb>UDGe}{E4CzKQG1U|~ zQHl?BaMWcuYG_Cx8eDqm7w5}Z!rClAFz&fU2!)-XCS^l0y8u>TWP#j_k~G1BJQGc9 zA;jWb@G{0cE?Yz2$&1;Z&thaC=n(}PqBUZJSp^!!CbU*UqDmWS`V?j;0ih1{f$K$} zxRCSVf&gG3%nB|{%jh0_Pl*Ev0HTd-D1{))2`li6hUlcxQtG9mhnDdTz$hi9oQMp8 zNugbWso4!oBpFRHM>^&RC5Ni<-N2-uhrnbxfk_!G50FQU#zA?+PDL$HcS4-+RYpj8 zYshdiZZXbLoZ65)F(Z>e(UPQw`VvWMfW&&$`@gA#iIN`k8qyAj(8Nc%KH#z2r4Z6V zw6x_b`2uSrlPIjl!^L!`A;aWkGK5n$T+X;!oY_m8Op*bUjQ~+(%rk+2 z(Q83InJ|!pqXLMV`4Af^ec~bWAmWS0)Nz?7SRJRd4p>Jf_t0-iJTwvte7q=0~i~U3!rmk z$nKayXlp{f^E&X`QpW?6 zFna|W)SqPJbH>HY9`#oSI>C8r>}MBukyVVR|X zO+a%+M@u?rE6sIjn(M&G>{Cu2Tu5^MLydsP*$>-3vS$jk&^#FM8ktF%$k))e5QAcGpVt84=cv!Xa}a!F;S^OQpQ% zbR5Fu2qw(!;7lXjg(kyfgLxmYGO{xa1CGw>NXp5VfHw*VSCwXU-sS-6%lOw^Is;=v zoN6;Mz?ev51r%+rM}pz;l$)yzFkFy<$Hs8}1=q5F>G@zmxU;uK6Eg!;>E8&cuf!M4 zO8hy@KDUF@2=JY|+nM|qmFD7l~xuzlz&6!uWMfc`V{Em5QDg{c-@37wN{ zMykd^hYRuC^ErouPvO%$RoZ0ko6hqyk|Y&Mjv4o#@;$arUJM+P`xP zcuQ7LfLJz;MOMIe$eGqSuYj!-CZ-TPC!ANJ@imitSDYPXzAMk5o6%!MPO`?sXHwr4 z2e*h|$%#2}TD~jM=rg`6LNcQSl}N_5YRPxyKOJZ&(HI1?ffumi5SA!9WDxaTfovzv zF24|SD&gEpPSJUVo4~lm2c=;ahLVFk;S2a?(|v`zn)VJdb>JBH6%1BW7Q-|XI{nlg zva;R>H{y|ESjUwNYp4~}4YJe?C{qB_Mk$UD82HqmMZE9SpT)01K1w@ef!0CyBGQp^ zU~1R~Eao#~*P#tZ8=gV4I_qpUQJq^bip6#+$y8P#CduXyTm0czl9fM7$f%c%LGR74X4TK#a zjO8!F6#WFAGB@##vRYXGDL>`@;H7nGiQ`!t{wFrTM9kNQR;Tg0o4@<%zvXKabPU-0ak?z;ABHEafLBBV;Klv|?o$Jg z{^|q6U;DxPcU>se{&Rfw{DqjuoyNU!h`_rH{?fBd6&zWYv-&Z-}a)3xf~-1nJ*J0!iSu+ZO`Kb%0n_|_+W zr@@pJ$nYaS9KJmPFef{H)esq^s^@C@we^TF-R5!-yTGexp{p-JLdQ)M(-=1GUARqYIUBA3DLEi^r z`fH)mMchq=!~Au5`kFNUFz!Un^w~##X*zX7p@8(g*X(^#DcMw*=U*=Sqm5sUds;Ky z{j1+S{$bOTvry=B!vohV<(dkImQ$cgPoB6T9AHn*BR?iu(RCvYyhzxZ$96Jr54<+a?$NZrW|rU9kYw( z{N%5{XxOKzFxUT^{2|Qrv6vk+)Ab*{<*xUd?myVSBu}rN#<92~O{OnA^}_F^qnio` z`JLGAL#DmI`L7S$CFE-=%!aPvDk=v-ekGYFNxBe{UxvYa>=F7qutVryn4j(WTe&-E zg+mpfXezIa)N-2$fF%4-b zw}1$afd$uAc5ue?-;BK&e}GFJzk?FUY5ZW!wGdCD?704K;C*34a!oj%jzls(iCQMd z%bc|o{tPlwc3%Tjb2+O<2YozJcJR~r9b6rTINZ-|95+02``tK8K~;|jLZR>&>y5dV z0S-^QX=G$9ks6I9g4%S-_16P5YoD3_1y19~pWFM~cfNVgZz)YUAADi-mtVb-6Tn}J zT>kLx?|tN2zN%P$Jh}&4Ma|>i{POL)H8aQC6VdC2!jX8r@4I(?LsB;s0=zyxe$Qj_ z+Eh3;_if|z+i=EtfPc2 zVO>5FHZ$(X3h$0RXkjp&OZ;!S_kBP8?boijd7YyB;P0=#|s@!=YKCBtvD6 zpK*>xpYyL_oBrwAn|}AU5()Q2f!MSKaSRnj_=c~2c2qKNC@ezRM+e^V6M1bayc$(P zpN>d}_5RZNxJx)~?h;P(E@7y#&|{*@g!5;!`n$jM)OA1k$gSTP1WDP2pV_-_^k;@4 z*@ySU?^@-}kG%88n!cfMG}3?nwqN|}=Z4|Vf=5h9WtY5mTJpsY$4(Dd#VLswKO8*+ zaeU&WR4E8vGp>q@de#^!Q4E&D49ejxA7V_&^?USG0d(AZ^LHHlh zs{;Mj&|B`2)D4AtWd7LSe)(#VsZE75{V&@2b%b#5d-i-;rH69Q=i_%RH1^ejM>Tyz zVKMUWfikA=O@&wa*V^Kd*ZA$*Kk&V`l<@dY^r~fsZg|(zlDeUAEI>T`@Xz(Nsn8hc zO#exno_tQ@=byR#i{Cc00$J$`@w*m%*YAG+U7a;H6plmsN8(wesSt+a1^-y+NXLc) z7(((eXdd#7g#OlOk)chE*BlD#s_);k=j|$Mjz{KS{@r(faozA|Kk??K!dn0Pc0MG8 zcl`36J-aEhW zGxC#`|3r+xmj7h@-c&dP8u&4dPd;CVzq|Zn=&0y4{`i;wGW2`lD+O>{JUJ+U>t6W# zn>4+taC&k$HDEnkyTlsBp`yOk{7H;E*jK~xhbXY=_SpEvXew5aH$M06zc=&eY5x0c zxI%65z8XW&?U z)1QIk^bJ4ajoLWypGF=ktUdd_`IVoOLz@Z>)oAC_wbp6e9Sb}y_RzN<8dm|>R5;1M z#ui`J#wQ}ZO*1|Hz^{ILHHTPJVWpujCmqwq({U*1trTtacWrz;R%^8E3%~uyXClF~ z!W4!eWNA(w=F9z7M|eM{26Rr*U(UpF>~*@-Vq9wDrkkk7z>SY83^tj-{{yGvtbL@) z6xmBBNiRJVsVj=bvmg2AZ;2>tDlGSJwc&URRPT#*3eEJjA3lAxO0lNGGM)TIH-M); zCtI$U5;}n@5cmr?qtA)q69 zrg?@QdGGsWZfz=@P>p$J(=`~gT`a}4*vIaB;u8_`EJ;d_)l*0T0kaxsu;gx3!j77zlNVlIkoki87n z@8||SMmDIajBJ3lTO8Q{PRjmX8@|U7`b$LUFM-fs0{7!rS(dfNKVG^W&pjj2^YhOw zKgm4jkAWiy1E#~t_$9T(2~3m=_(EfZmajYz3n5;4j8D1pSd(0N49i4zR9SDHHbrkD zf`VbAA}-8J#*)whSIE~@{eEg5TY`y6banD&R&s7zoqU;9HnpuTdz)1@wPEH;sIs$o zR6sF`^gB#m>LZhRMx;s|_2Pf16FCm=2PAY+A8u!^ij9 zr`oad@A$`=A!El+mVaD0%tL9%(Ksa{N#qzrQx!P|xkd3caOX37AH*4;XhCyALSV(u z5Lo&QTbBQjO=FcJ_bD4TDJo9K>nw#I*q{7Oc{rO_G6*7l#0)YxC4-bLO^0P^Iwz{} zb2bc9)0P&nUsYq0(_qpvE%=5Fqn3I8f(_di_-o)qv?l%;T#81)+*O6yX3;smvYm+8 z5w~;Xq3JKdWgyge{_S=iPWA~_ZAiWplHA#ld?}PMXG7Urp^Q19C?r_5kf(u-^H`Ew zWQ8}!#KeP{?M%ou{2N>2FA@$h@3Tgt_c=E_J8;_@K6r+Chf&T@^kk zed7-|5ULP&HBS&&;giu+dMa#Wcpt{D6wW^I>i~lmro8vqa1&QYcB5&xG`?iet)S6NpjY;3;L zQ3Xef)DH<5iyPPkrx^O6;XoHRhq*V$JzH#KBSJ++oMJL?ijlZg89K#a>sp;+0@#<% zaPk6G9gI@288GYxuPn!BZmrkTd4rUT4=0J!4bXyPo_bb@YmmW-`PD}U{`;sN=!lPw zqEiZ(A?TQZ8D;3qg`d`g$!>r%M??d`6zwEt5~~B|0Muuyrh`&3OG?1KfIHj9uR>#W zRHsBDR!5NDQ-m)7x&bFB@PlS_hV^lz4hF9ApS2@5hdK#4fsb+;7>tK-)?xkDB1py% zC*UdgTEbVG#NGmbBT@clA3q-HIiYfK!jqL{{=)YAC1!?{5%+$Rs9a(P15QAtkjP@&jU_PYd^x} z1H?}CvmZ%I$_D92G87yzOh2*{#lKcMD&9#3ps<#vSqiH@SzTYzJQaYun~w4>m0 z=c1#;yHCa&ois{v#JIkQ5HYSVWf!)C=H|k7TxLbSu)HTyIJiY=s{e^-Dyk@h(+3El zE-+apNca|z2IRt63AtKAY!`Kb(Y+R2LW)=&C`A{THRpi2c%I8u514GZ2Mmge2TV#l zU~=?;;bBl)eEc)&;7bn}%w8Y|&!R_OF*u3KBj)gm$)Od(zo-X1UhWl>qr+RmD+b=( z%)*nb(rG9z^%;*FIuuV)U&#xHv6u+QCCQ|AlEzRd6OCp_6&(Bqrs%I69)iq?wm2)Cqg6SEWEQ7JQi`>UyCwTy;wjU|62SQmpBs=sT>1Dae$;R>h~S_mwh!zC$pWWj z_HTq6TFKt4v&p-eI{X260wD{DqYj=hZpn9O5&A$IVdLxwV4|sL1QXcK9EA}vRS-Gx z$TJn=RJHOkGV75jrh5ODo|4DvO^6^vK}?|#qj32|Q%po|Cw%IWTUOL%0Tx{+>ACRZ zPd#!NIgG4ef^law7&p2-3*kz~svLI>MZo3I55_lKh|jqCxelsEBxZCbH4AHnA*r}R z;$XXa+eHz8z@}6SImhHkP7_6l2UF`2MToqW<`Z~}eDz{#1O$3#l)13#uz^ajY8HB+i^F{h&h7c-fpHfiM?o+V!BoOntVc}{;I z&pQ>Nq@}CSNehY$_{K9P?ppAOMcsAeCLBqJ-+kcBu`rM&9ivF(Zx*8vjOxv{2!UhE z@~^~+s?#s8|j!-wtsoQ#&#+4S>?&3)sW9cS`g* zvQG*df`9?#8PgVM9N6ao-OxK5nW@6zC%Kv*y((J(@uaDZ+HmLsfOox@=u z-GPrBYc}A*dyr!igJ0B)7*!w-_d_kuf)d@;fB|48D!*6aE*&nor->GlAtFg8P*V<| z@T)i(#QdGxSTuYz7uU&&k;g9C5%Ttp`DHGLckPTI=6?x!^!ZK@rbnsiG@` z1+|opVF2u6M{;l!#v&RHnaoC&(3KA3GYCa0BEi+rA93vwHC+w;!9@iRlQ8HyX-u5u zFiG49HVL{M8qVnMe8Mo1!z8Gg4LQgPtS^Ywi>?a$tSj&HKq>3<;-s40{zdO$2Qdo` zI;f&AbR|HHs~u_M74y1vR&+9&NRyfjk_g2VE)mpdfEr0r%<>oubi?%p!x(HC_=h44 zy(G{e7yym*UJuWzETmQ%_FNaNk2-@)fwye)5%Ur_2E$WgCQ4P|6>r&{+bZ*?Xshsp z?*m~gXID=PlzG&~WQ00Be=5?Gy{XN7wa^u+S7aJ;Xk>^!9y=WYC8$c==>0>-V6D?_bt z_DgswmuhgqDw?+m~i3t}cmxxHbrHYo5Q4j1zItsOK;phEz)mLJ32crD^= z0Wbj^B(m>Ni9naA8@29QqJq&=ECjWv4Vgu*U~B~i6z0(cOEl0+wg-+36FEKrnj-;4 z6l5uvWGRqfJkE+Hzr|rtKuqS(W29gu)Cq;n3Li!@>)7LLZ(W{bcsMM&bp>G=9PGf% zZim;R0jx%lSCtL>QIGMgsV%KTB9s?!AqflDo~gs3I3T4q7xKv0hC>~wAVcaX>P`UORt(_vq^X1M}sDuEhI zUnrI7m+sw=#$_v{-`F#9#1_+_TrrQqsJifF?*~LU5W?Lk%lTUC*xw32Bvd8 zAUZZnBLRN)V8NY5XAS0PuFjxrb*{Bwkb&NSj~HTQ6#9gCJLe(j!J%q)OLAm6gEhAimBDxPYm!M$JsT{i?xB6K0N`?(SpbRA`M zLYLk$#{ytPVH8E&he6_N8**qvify1ii#7!KfRo)3{)oLn#g+%rh(4sA2q;A#49F2g zwt%^SKNyd&B0z!woN}k0yj0JP zmIb-$5MX z@8!LPVQrW6pysws zfx!tCw|4L7>SxsmG{8cw-Cg}{m-IJp?rm#p-qh0Hf-WZ5maSX6--wd!U3l$UVzLFy zM)c7N02xbpMfAh66(>yH34`e<-_$)Y66c$m{Nrh_kmNo#H{%t~?%LV1wS7}y2sQ{m z-RM)I;TbPY9z&VojCW`S;YwXOn(}p~2OF0L!-r-eAS;{h$ z^=7pj?11AA>F=zUX1}0@k*t^DV=bOXv);V^-j=RDrLy*RiNUhoAs2SFY~0!w^mhj> zn>GcTw|2MmpMZjcIj^|0t+##ir9oRa*sQswudl7QKWJ^~3O2UkXRGq)NX|RDr?-74 zSoY#J4A!3Zpl?g}j;){@`W-n<*8}8u&O557w|mo$*0$a$GY-{whi}?AWtNc|uc%E5 z`r5iSOSKqRue@l07`vO``Wsd@_fv8X6ucvQc5H0!Z{OC&EO_49-l}xww|Zt8DtL?fw}54KKyr2U z2M}LvkWsxALI*iV3*IaGxAhQ`$t;is%6P$ZTQ;)JS>CKxOOOWNb@lh*+u$rO)wcO! zRyNCX$oIpuyiCi+)=kn#d2W>F(OF*2vhDmYq&y#+1v zAY5SL%T|0EobAm@eqx6W&Gu%OePh=RW3BrCcXlnnO;u@_+R|1|k+uXZl(x4o5)hSrTxkv@f6J zcNlt9HMKELYHG!NQcB04h6bI9cWT{st*gh{X16HhO8E>l5{DiLOT$zQhTMD;CAp~? zj5#wcAJ1SOwVBT01HdQ z3<6A91u)-aNufptqXU;TtewHo3lV9UiNVkd{#zx5ni&ke5R!(iWia%Dw?L9x2ZNy( z0@5%GgP|9~(l9H7p%;8pB!$`-480JPhS>#}3cV1KhB+9Fjz&`@g?2I+dLbkYb21ou z!CNTF&Bb8og@827&0y$-ur$oWVCV(kG)bY4G8lRxC=KgkF!Vx18rIEV=mmd~q|hD# zrbaJ>q+z`bhF^cBOz87EK;4K6plui9}4!x2-#(!)C1k8#!1_zbw8U5hAUIe;G7StJDj`LQ(G-F3ND0X@M)6*b z6eq?D5G3$(B)dIE5#UHkVhV;qk`PC3HVx5)IU-C!M_4clLLzS|8E1|bz`d_D=FMSt zkD-t(SW3v+SP2R*C1r^<9D-4KWhAF#s0byNk@CcpA{>=jM#fu2Whk|bR3xSq1F76{ za*I`5h?2`mWn$_$B$ZuGCd3tDUkwc}#PK0qPNt87sS3IJDoAb|*Bbib8(ylUBSi&~ zkAknV8X1QxU`gAn(WvSBmfp0q&>L^1M6ckMDfnIlA-%s6BA*ZQy-HP!j*Ejw`kF##f#Aha9CKvhH+w&mN=T=^w{V?XHhVpLG`i0 zwE5GCjIkW576Kk}GFGEeqW64qa_a~X)**+0oTO7!P);U|Kna*IU{v(QoCu>5Jgfji zYBX(aI-O3Bt6je$HVRSIV9qXL4}hS8j8iIy2to=XTc(JW(9jP|_5m4D5RK8?4Xa0o zU6_SJoB*O8HXQ^dbatzQcbZ+WMD8-XO`HoSn>LTN4Hgh~BP^nIW-BaaP~Z$QSCS2- z)tik*16_k8WZ<1i=8G8AR{uOTW|9UeE~C=owm2=+s-LIDZE;$}aT%2svq+7o6>;k)QP0Vk-9u>u+FBjBB3XY6dX?-r*mp*@9lAR zkCScnSlnhubZHAKSQivvFiWH?EUT~+-cII;3gdJb4VPLR=)7~t1U-aQ^aif2hr@P4 zp>Gbk2?I0!IfNHUh|?2^Xh@K0Xmr}GoE<`iJVXdN9^xcMk4-Qk-U!c@Az?#&RS>3% zMIPKHr@adzjW*8UbkbmB0KSZ&)zT)ZqXuDt9|-!)R##Qg$x;<5mPXZ6Oe85M2=G#r zPnnDppujYNq!`c%Fd-$GrqzO>+~x#&BO;BDr}LI zCPIrMNijl;d}>lC#E3W(4^bjI46|?@4I>BCsEbER617Tl2(~CfAr_Yj9)$#!qi>>W z6eJ13S4^N9yNxttjT#w+QlVeL{Z<2<>K36pUT`W>?`@8R5n<4|3{~uz0h~B)<0w1;__)llV3Xv zc801Ub7C(JLJ4=Yd-6M*(oS5`Xy$*h`e0dkAe|rBdTZ~FH*C(VurA(!1i&Zx^Qb{&?|YP;MA0wmF2P*PgJqo+v-F z?DD0z-aONqb70l-o$9-OIDTbdx2CDS@$hm`ZWt-H)%)%kGXM0Un%yt*y+{A9aV zX_Wb2e!uML{p(&CxAU7X?{58Md+FxBnezJv_thS4EFbvs^09^YE-2SGUbtoE_P^fu z>OFgQfmXl>jU+F8q(&g9vt$HEY>b-c@)K*Y7f8&;Z&#AK$ zPd#__nnHF%Hg8i`&j*)x{bskb@8E&MPx%U#7b$iw8FTHNy0Gty<8R&B@Zl#jzBzn) z`pPw1&#&5W_r;sRgTq*(EhES}_t)>#y}WZ*=fHlgW$dcWEBD@n1{&cW<^QDD> zDZA7+pV7CzUc5DL<1@b1tuOt7t2_OB=e}*zGpt`4H~g{XmR~`yIv%ez?N?AH+xSNI zwead~z5N+WH*WhNu;JT>$qmp1s&buXhry~>)>g$#7(t4B{{wYPcjP>EZmi!T|NQFq zQ*D=T1GBt8f`VEGie>hB1N|M#8|&_SVf&K3ul;gX_OTzpkin4@wDTav>ddFFEIIl8 zdFPSGe^5v!>(j@v7E$u55Xvz<21gEU+kiT~PEe z;d}vp28VEG1IJso-IylZ{=?P3^x5C8kRQ~X)Azr4&z>!Ph28fbX$1oSO#Cp>H9eHg zKe7Hy&AKZ`j(xjQvHVl3H|taG+*tD9q|eu1-Cz2N<>E(+LmxM;e)7A(PwNX#Zdmu# z9NpW>V~aJtkH1={>b)*M)eJg)81D+I6_m+#5yiT5mL=i}`u)DNv7CWRwIGhGp zVU2vRz;6YR5-||M2qRG;Ko!uu6Vbk~Xzv!PvvBXLfrD0fpMm@@F-}Mgh)c%+m>*!n z8ykQ!HEpbjUTd&A+&w88905v&h$y;yZns%_gf)cSCd$k3KbuAh#c&hv;<}u6TRW^E zg&kID1O|to0bxMQjBeNq`2oYEi8twi!1r7lkqZQJ7ZH6TAX<%a-sY;MI10gcrhFCgTiZhf84G(0QG`j`c3^z*J zWpqZK^kvzKPF47(Ng`hl>ZuFugxFI$}m(jqxJx+9b1WKy9U~hOR zA%rRkAdaD2oX2K?i3Vuz)En(i+;xXv8zPk+TP)qk!n@p@#|5??av+CW$fyBeOGQ|= zC(Y^L0i-c1hV#CVM#i?;?Q{zt|HeISlm&lh(hY97fdhg`CPpA}x*mj^EV^HgcW_cK zt)iRK;b;}TgR^pJl@Pkw%&6!c98ya%X-W->!YaKTQY27uI8v76rm?)Z=-ICz6+y6J z;nBGP1P8p5Z0J~HWC+AFSxL?VZfKZJ<8<;pPz2|oQao%d!5y4gO0ph>BrW<-z)_@R zJRJ|XSeXyXa-tlIDOWh+ljOSGdPojIrj09SEo%l|0VvMo9S*83oT>@iPdw@bM@*7T z2ZWDs*9uPCBNa == DUMMY_ACTION_DEFAULT_A\00") - (data (i32.const 240) "dummy13->b == DUMMY_ACTION_DEFAULT_B\00") - (data (i32.const 288) "dummy13->c == DUMMY_ACTION_DEFAULT_C\00") - (data (i32.const 336) "get_action failed\00") - (data (i32.const 368) "testapi\00") - (data (i32.const 384) "incorrect permission actor\00") - (data (i32.const 416) "active\00") - (data (i32.const 432) "incorrect permission name\00") - (data (i32.const 464) "pack_size does not match get_action size\00") - (data (i32.const 512) "expected testapi account\00") - (data (i32.const 544) "get_context_free_data() not allowed in non-context free action\00") - (data (i32.const 608) "dum13.a == DUMMY_ACTION_DEFAULT_A\00") - (data (i32.const 656) "dum13.b == DUMMY_ACTION_DEFAULT_B\00") - (data (i32.const 704) "dum13.c == DUMMY_ACTION_DEFAULT_C\00") - (data (i32.const 752) "dummy_action\00") - (data (i32.const 768) "Invalid name\00") - (data (i32.const 784) "Invalid account\00") - (data (i32.const 800) "read\00") - (data (i32.const 816) "get_action size failed\00") - (data (i32.const 848) "get\00") - (data (i32.const 864) "size determination failed\00") - (data (i32.const 896) "get_context_free_data failed\00") - (data (i32.const 928) "invalid value\00") - (data (i32.const 944) "test\00") - (data (i32.const 960) "test\n\00") - (data (i32.const 976) "transaction_size failed\00") - (data (i32.const 1008) "Unable to add float.\00") - (data (i32.const 1040) "verify eosio_assert can be called\00") - (data (i32.const 1088) "privileged_api should not be allowed\00") - (data (i32.const 1136) "producer_api should not be allowed\00") - (data (i32.const 1184) "db_api should not be allowed\00") - (data (i32.const 1216) "action send should not be allowed\00") - (data (i32.const 1264) "authorization_api should not be allowed\00") - (data (i32.const 1312) "system_api should not be allowed\00") - (data (i32.const 1360) "hello\00") - (data (i32.const 1376) "transaction_api should not be allowed\00") - (data (i32.const 1424) "write\00") - (data (i32.const 1440) "cf_action\00") - (data (i32.const 1456) "acc1\00") - (data (i32.const 1472) "acc2\00") - (data (i32.const 1488) "Should\'ve failed\00") - (data (i32.const 1520) "require_auth\00") - (data (i32.const 1536) "acc3\00") - (data (i32.const 1552) "acc4\00") - (data (i32.const 1568) "test_action::assert_false\00") - (data (i32.const 1600) "test_action::assert_true\00") - (data (i32.const 1632) "total == sizeof(uint64_t)\00") - (data (i32.const 1664) "pub_time == publication_time()\00") - (data (i32.const 1696) "the current receiver does not match\00") - (data (i32.const 1744) "tmp == current_time()\00") - (data (i32.const 1776) "ab\00") - (data (i32.const 1792) "c\00test_prints\00") - (data (i32.const 1808) "efg\00") - (data (i32.const 1824) "\n\00") - (data (i32.const 1840) "abcde\00") - (data (i32.const 1856) "abBde\00") - (data (i32.const 1872) "1q1q1qAA\00") - (data (i32.const 1888) "AAAAAA\00") - (data (i32.const 1904) "abcdefghijk\00") - (data (i32.const 1920) "abcdefghijkl\00") - (data (i32.const 1936) "abcdefghijkl1\00") - (data (i32.const 1952) "abcdefghijkl12\00") - (data (i32.const 1968) "abcdefghijkl123\00") - (data (i32.const 1984) "cvalue\00") - (data (i32.const 2000) "value\00") - (data (i32.const 2016) "int64_t size != 8\00") - (data (i32.const 2048) "uint64_t size != 8\00") - (data (i32.const 2080) "uint32_t size != 4\00") - (data (i32.const 2112) "int32_t size != 4\00") - (data (i32.const 2144) "uint128_t size != 16\00") - (data (i32.const 2176) "int128_t size != 16\00") - (data (i32.const 2208) "uint8_t size != 1\00") - (data (i32.const 2240) "account_name size != 8\00") - (data (i32.const 2272) "table_name size != 8\00") - (data (i32.const 2304) "time size != 4\00") - (data (i32.const 2320) "key256 size != 32\00") - (data (i32.const 2352) "eosio::char_to_symbol(\'1\') != 1\00") - (data (i32.const 2400) "eosio::char_to_symbol(\'2\') != 2\00") - (data (i32.const 2448) "eosio::char_to_symbol(\'3\') != 3\00") - (data (i32.const 2496) "eosio::char_to_symbol(\'4\') != 4\00") - (data (i32.const 2544) "eosio::char_to_symbol(\'5\') != 5\00") - (data (i32.const 2592) "eosio::char_to_symbol(\'a\') != 6\00") - (data (i32.const 2640) "eosio::char_to_symbol(\'b\') != 7\00") - (data (i32.const 2688) "eosio::char_to_symbol(\'c\') != 8\00") - (data (i32.const 2736) "eosio::char_to_symbol(\'d\') != 9\00") - (data (i32.const 2784) "eosio::char_to_symbol(\'e\') != 10\00") - (data (i32.const 2832) "eosio::char_to_symbol(\'f\') != 11\00") - (data (i32.const 2880) "eosio::char_to_symbol(\'g\') != 12\00") - (data (i32.const 2928) "eosio::char_to_symbol(\'h\') != 13\00") - (data (i32.const 2976) "eosio::char_to_symbol(\'i\') != 14\00") - (data (i32.const 3024) "eosio::char_to_symbol(\'j\') != 15\00") - (data (i32.const 3072) "eosio::char_to_symbol(\'k\') != 16\00") - (data (i32.const 3120) "eosio::char_to_symbol(\'l\') != 17\00") - (data (i32.const 3168) "eosio::char_to_symbol(\'m\') != 18\00") - (data (i32.const 3216) "eosio::char_to_symbol(\'n\') != 19\00") - (data (i32.const 3264) "eosio::char_to_symbol(\'o\') != 20\00") - (data (i32.const 3312) "eosio::char_to_symbol(\'p\') != 21\00") - (data (i32.const 3360) "eosio::char_to_symbol(\'q\') != 22\00") - (data (i32.const 3408) "eosio::char_to_symbol(\'r\') != 23\00") - (data (i32.const 3456) "eosio::char_to_symbol(\'s\') != 24\00") - (data (i32.const 3504) "eosio::char_to_symbol(\'t\') != 25\00") - (data (i32.const 3552) "eosio::char_to_symbol(\'u\') != 26\00") - (data (i32.const 3600) "eosio::char_to_symbol(\'v\') != 27\00") - (data (i32.const 3648) "eosio::char_to_symbol(\'w\') != 28\00") - (data (i32.const 3696) "eosio::char_to_symbol(\'x\') != 29\00") - (data (i32.const 3744) "eosio::char_to_symbol(\'y\') != 30\00") - (data (i32.const 3792) "eosio::char_to_symbol(\'z\') != 31\00") - (data (i32.const 3840) "a\00") - (data (i32.const 3856) "eosio::string_to_name(a)\00") - (data (i32.const 3888) "ba\00") - (data (i32.const 3904) "eosio::string_to_name(ba)\00") - (data (i32.const 3936) "cba\00") - (data (i32.const 3952) "eosio::string_to_name(cba)\00") - (data (i32.const 3984) "dcba\00") - (data (i32.const 4000) "eosio::string_to_name(dcba)\00") - (data (i32.const 4032) "edcba\00") - (data (i32.const 4048) "eosio::string_to_name(edcba)\00") - (data (i32.const 4080) "fedcba\00") - (data (i32.const 4096) "eosio::string_to_name(fedcba)\00") - (data (i32.const 4128) "gfedcba\00") - (data (i32.const 4144) "eosio::string_to_name(gfedcba)\00") - (data (i32.const 4176) "hgfedcba\00") - (data (i32.const 4192) "eosio::string_to_name(hgfedcba)\00") - (data (i32.const 4224) "ihgfedcba\00") - (data (i32.const 4240) "eosio::string_to_name(ihgfedcba)\00") - (data (i32.const 4288) "jihgfedcba\00") - (data (i32.const 4304) "eosio::string_to_name(jihgfedcba)\00") - (data (i32.const 4352) "kjihgfedcba\00") - (data (i32.const 4368) "eosio::string_to_name(kjihgfedcba)\00") - (data (i32.const 4416) "lkjihgfedcba\00") - (data (i32.const 4432) "eosio::string_to_name(lkjihgfedcba)\00") - (data (i32.const 4480) "mlkjihgfedcba\00") - (data (i32.const 4496) "eosio::string_to_name(mlkjihgfedcba)\00") - (data (i32.const 4544) "mlkjihgfedcba1\00") - (data (i32.const 4560) "mlkjihgfedcba2\00") - (data (i32.const 4576) "eosio::string_to_name(mlkjihgfedcba2)\00") - (data (i32.const 4624) "mlkjihgfedcba55\00") - (data (i32.const 4640) "mlkjihgfedcba14\00") - (data (i32.const 4656) "eosio::string_to_name(mlkjihgfedcba14)\00") - (data (i32.const 4704) "azAA34\00") - (data (i32.const 4720) "azBB34\00") - (data (i32.const 4736) "eosio::string_to_name N(azBB34)\00") - (data (i32.const 4768) "AZaz12Bc34\00") - (data (i32.const 4784) "eosio::string_to_name AZaz12Bc34\00") - (data (i32.const 4832) "AAAAAAAAAAAAAAA\00") - (data (i32.const 4848) "BBBBBBBBBBBBBDDDDDFFFGG\00") - (data (i32.const 4880) "eosio::string_to_name BBBBBBBBBBBBBDDDDDFFFGG\00") - (data (i32.const 4928) "eosio::name != N(azAA34)\00") - (data (i32.const 4960) "eosio::name != N(0)\00") - (data (i32.const 4992) "AA11\00") - (data (i32.const 5008) "eosio::name != N(AA11)\00") - (data (i32.const 5040) "11\00") - (data (i32.const 5056) "eosio::name != N(11)\00") - (data (i32.const 5088) "22\00") - (data (i32.const 5104) "eosio::name != N(22)\00") - (data (i32.const 5136) "AAAbbcccdd\00") - (data (i32.const 5152) "eosio::name == eosio::name\00") - (data (i32.const 5184) "11bbcccdd\00") - (data (i32.const 5200) "N(11bbcccdd) == tmp\00") - (data (i32.const 5232) "fixed_point128 instances comparison with same number of decimals\00") - (data (i32.const 5312) "fixed_point128 instances with different number of decimals\00") - (data (i32.const 5376) "fixed_point64 instances comparison with same number of decimals\00") - (data (i32.const 5440) "fixed_point64 instances with different number of decimals\00") - (data (i32.const 5504) "fixed_point32 instances comparison with same number of decimals\00") - (data (i32.const 5568) "fixed_point32 instances with different number of decimals\00") - (data (i32.const 5632) "fixed_point32 instances addition with zero decmimals\00") - (data (i32.const 5696) "fixed_point64 instances addition with zero decmimals\00") - (data (i32.const 5760) "fixed_point64 instances subtraction with zero decmimals\00") - (data (i32.const 5824) "fixed_point32 instances subtraction with zero decmimals\00") - (data (i32.const 5888) "fixed_point64 instances multiplication result in fixed_point128\00") - (data (i32.const 5952) "fixed_point32 instances multiplication result in fixed_point64\00") - (data (i32.const 6016) "divide by zero\00") - (data (i32.const 6032) ".\00") - (data (i32.const 6048) "fixed_point64 instances division result from operator and function and compare in fixed_point128\00") - (data (i32.const 6160) "should\'ve thrown an error\00") - (data (i32.const 6192) "__multi3 result should be -3000\00") - (data (i32.const 6224) "__multi3 result should be 900\00") - (data (i32.const 6256) "__multi3 result should be 10000\00") - (data (i32.const 6288) "__multi3 result should be 100\00") - (data (i32.const 6320) "__multi3 result should be -30\00") - (data (i32.const 6352) "__divti3 result should be 0\00") - (data (i32.const 6384) "__divti3 result should be -3\00") - (data (i32.const 6416) "__divti3 result should be 1\00") - (data (i32.const 6448) "__divti3 result should be 33\00") - (data (i32.const 6480) "__divti3 result should be 100\00") - (data (i32.const 6512) "__divti3 result should be -30\00") - (data (i32.const 6544) "Should have eosio_asserted\00") - (data (i32.const 6576) "__udivti3 result should be 0\00") - (data (i32.const 6608) "__udivti3 result should be 1\00") - (data (i32.const 6640) "__lshlti3 result should be 1\00") - (data (i32.const 6672) "__lshlti3 result should be 2\00") - (data (i32.const 6704) "__lshlti3 result should be 2^31\00") - (data (i32.const 6736) "__lshlti3 result should be 2^63\00") - (data (i32.const 6768) "__lshlti3 result should be 2^64\00") - (data (i32.const 6800) "__lshlti3 result should be 2^127\00") - (data (i32.const 6848) "__lshlti3 result should be 2^128\00") - (data (i32.const 6896) "__ashlti3 result should be 1\00") - (data (i32.const 6928) "__ashlti3 result should be 2\00") - (data (i32.const 6960) "__ashlti3 result should be 2^31\00") - (data (i32.const 6992) "__ashlti3 result should be 2^63\00") - (data (i32.const 7024) "__ashlti3 result should be 2^64\00") - (data (i32.const 7056) "__ashlti3 result should be 2^127\00") - (data (i32.const 7104) "__ashlti3 result should be 2^128\00") - (data (i32.const 7152) "__lshrti3 result should be 2^127\00") - (data (i32.const 7200) "__lshrti3 result should be 2^126\00") - (data (i32.const 7248) "__lshrti3 result should be 2^64\00") - (data (i32.const 7280) "__lshrti3 result should be 2^63\00") - (data (i32.const 7312) "__lshrti3 result should be 2^31\00") - (data (i32.const 7344) "__lshrti3 result should be 2^0\00") - (data (i32.const 7376) "__ashrti3 result should be -2^127\00") - (data (i32.const 7424) "__ashrti3 result should be -2^126\00") - (data (i32.const 7472) "__ashrti3 result should be -2^125\00") - (data (i32.const 7520) "__ashrti3 result should be -2^63\00") - (data (i32.const 7568) "__ashrti3 result should be -2^31\00") - (data (i32.const 7616) "__ashrti3 result should be -2^0\00") - (data (i32.const 7648) "__modti3 result should be -30\00") - (data (i32.const 7680) "__modti3 result should be 30\00") - (data (i32.const 7712) "__modti3 result should be 10\00") - (data (i32.const 7744) "__modti3 result should be 0\00") - (data (i32.const 7776) "should have thrown an error\00") - (data (i32.const 7808) "public key does not match\00") - (data (i32.const 7840) "abc\00") - (data (i32.const 7856) "\a9\99>6G\06\81j\ba>%qxP\c2l\9c\d0\d8\9d") - (data (i32.const 7888) "sha1 test1\00") - (data (i32.const 7904) "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq\00") - (data (i32.const 7968) "\84\98>D\1c;\d2n\ba\aeJ\a1\f9Q)\e5\e5Fp\f1") - (data (i32.const 8000) "sha1 test3\00") - (data (i32.const 8016) "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu\00") - (data (i32.const 8144) "\a4\9b$F\a0,d[\f4\19\f9\95\b6p\91%:\04\a2Y") - (data (i32.const 8176) "sha1 test4\00") - (data (i32.const 8192) "message digest\00") - (data (i32.const 8208) "\c1\"R\ce\da\8b\e8\99M_\a0)\nG#\1c\1d\16\aa\e3") - (data (i32.const 8240) "sha1 test5\00") - (data (i32.const 8256) "\bax\16\bf\8f\01\cf\eaAA@\de]\ae\"#\b0\03a\a3\96\17z\9c\b4\10\ffa\f2\00\15\ad") - (data (i32.const 8288) "sha256 test1\00") - (data (i32.const 8304) "$\8dja\d2\068\b8\e5\c0&\93\0c>`9\a3<\e4Yd\ff!g\f6\ec\ed\d4\19\db\06\c1") - (data (i32.const 8336) "sha256 test3\00") - (data (i32.const 8352) "\cf[\16\a7x\af\83\80\03l\e5\9e{\04\927\0b$\9b\11\e8\f0zQ\af\acE\03z\fe\e9\d1") - (data (i32.const 8384) "sha256 test4\00") - (data (i32.const 8400) "\f7\84oU\cf#\e1N\eb\ea\b5\b4\e1U\0c\ad[P\9e3H\fb\c4\ef\a3\a1A=9<\b6P") - (data (i32.const 8432) "sha256 test5\00") - (data (i32.const 8448) "\dd\af5\a1\93az\ba\ccAsI\ae A1\12\e6\faN\89\a9~\a2\n\9e\ee\e6KU\d3\9a!\92\99*\'O\c1\a86\ba<#\a3\fe\eb\bdEMD#d<\e8\0e*\9a\c9O\a5L\a4\9f") - (data (i32.const 8512) "sha512 test1\00") - (data (i32.const 8528) " J\8f\c6\dd\a8/\n\0c\ed{\eb\8e\08\a4\16W\c1n\f4h\b2(\a8\'\9b\e31\a7\03\c35\96\fd\15\c1;\1b\07\f9\aa\1d;\eaWx\9c\a01\ad\85\c7\a7\1d\d7\03T\ecc\128\ca4E") - (data (i32.const 8592) "sha512 test3\00") - (data (i32.const 8608) "\8e\95\9bu\da\e3\13\da\8c\f4\f7(\14\fc\14?\8fwy\c6\eb\9f\7f\a1r\99\ae\ad\b6\88\90\18P\1d(\9eI\00\f7\e43\1b\99\de\c4\b5C:\c7\d3)\ee\b6\dd&T^\96\e5[\87K\e9\t") - (data (i32.const 8672) "sha512 test4\00") - (data (i32.const 8688) "\10}\bf8\9d\9e\9fq\a3\a9_l\05[\92Q\bcRh\c2\be\16\d6\c14\92\eaE\b0\19\9f3\t\e1dU\ab\1e\96\11\8e\8a\90]U\97\b7 8\dd\b3r\a8\98&\04m\e6f\87\bbB\0e|") - (data (i32.const 8752) "sha512 test5\00") - (data (i32.const 8768) "\8e\b2\08\f7\e0]\98z\9b\04J\8e\98\c6\b0\87\f1Z\0b\fc") - (data (i32.const 8800) "ripemd160 test1\00") - (data (i32.const 8816) "\12\a0S8J\9c\0c\88\e4\05\a0l\'\dc\f4\9a\dab\eb+") - (data (i32.const 8848) "ripemd160 test3\00") - (data (i32.const 8864) "o?\a3\9bkP<8O\91\9aI\a7\aa\\,\08\bd\fbE") - (data (i32.const 8896) "ripemd160 test4\00") - (data (i32.const 8912) "]\06\89\efI\d2\fa\e5r\b8\81\b1#\a8_\fa!Y_6") - (data (i32.const 8944) "ripemd160 test5\00") - (data (i32.const 8976) "\da9\a3\ee^kK\0d2U\bf\ef\95`\18\90\af\d8\07\t") - (data (i32.const 9008) "sha1 test2\00") - (data (i32.const 9024) "\e3\b0\c4B\98\fc\1c\14\9a\fb\f4\c8\99o\b9$\'\aeA\e4d\9b\93L\a4\95\99\1bxR\b8U") - (data (i32.const 9056) "sha256 test2\00") - (data (i32.const 9072) "\cf\83\e15~\ef\b8\bd\f1T(P\d6m\80\07\d6 \e4\05\0bW\15\dc\83\f4\a9!\d3l\e9\ceG\d0\d1<]\85\f2\b0\ff\83\18\d2\87~\ec/c\b91\bdGAz\81\a582z\f9\'\da>") - (data (i32.const 9136) "sha512 test2\00") - (data (i32.const 9152) "\9c\11\85\a5\c5\e9\fcTa(\08\97~\e8\f5H\b2%\8d1") - (data (i32.const 9184) "ripemd160 test2\00") - (data (i32.const 9200) "should have failed\00") - (data (i32.const 9232) "producers.len != 21\00") - (data (i32.const 9264) "Active producer\00") - (data (i32.const 9280) "EwfUD\12\cd\11\ab\12\aeQt") - (data (i32.const 17488) "send_message_large() should\'ve thrown an error\00") - (data (i32.const 17536) "tapos_block_prefix does not match\00") - (data (i32.const 17584) "tapos_block_num does not match\00") - (data (i32.const 17616) "read_transaction failed\00") - (data (i32.const 17648) "size: \00") - (data (i32.const 17664) "transaction size does not match\00") - (data (i32.const 17696) "EwfUD\12\cd\11\ab\12\aeQt") - (data (i32.const 17712) "send_transaction_empty() should\'ve thrown an error\00") - (data (i32.const 17776) "transaction should only have one action\00") - (data (i32.const 17824) "transaction has wrong code\00") - (data (i32.const 17856) "transaction has wrong name\00") - (data (i32.const 17888) "action should only have one authorization\00") - (data (i32.const 17936) "action\'s authorization has wrong actor\00") - (data (i32.const 17984) "action\'s authorization has wrong permission\00") - (data (i32.const 18032) "send_transaction_large() should\'ve thrown an error\00") - (data (i32.const 18096) "deferred executed\n\00") - (data (i32.const 18128) "transaction was not found\00") - (data (i32.const 18160) "transaction was canceled, whild should not be found\00") - (data (i32.const 18224) "context free actions cannot have authorizations\00") - (data (i32.const 18272) "dummy\00") - (data (i32.const 18288) "send_cfa_action_fail() should\'ve thrown an error\00") - (data (i32.const 18352) "test_transaction\00") - (data (i32.const 18384) "table\00") - (data (i32.const 18400) "newfeature\00") - (data (i32.const 18416) "we should not have new features unless hardfork\00") - (data (i32.const 18464) "unexpected last used permission time\00") - (data (i32.const 18512) "unexpected account creation time\00") - (data (i32.const 18560) "bool\00") - (data (i32.const 18576) "int8\00") - (data (i32.const 18592) "uint8\00") - (data (i32.const 18608) "int16\00") - (data (i32.const 18624) "uint16\00") - (data (i32.const 18640) "int32\00") - (data (i32.const 18656) "uint32\00") - (data (i32.const 18672) "int64\00") - (data (i32.const 18688) "uint64\00") - (data (i32.const 18704) "float\00") - (data (i32.const 18720) "double\00") - (data (i32.const 18728) "\01\00\00\00\00\00\00\0082\8f\fc\c1\c0\f3?") - (data (i32.const 18752) "struct\00") - (data (i32.const 18760) "\n\00\00\00\14\00\00\00") - (data (i32.const 18768) "StaticArray\00") - (data (i32.const 18784) "string\00") - (data (i32.const 18800) "vector\00") - (data (i32.const 18816) "empty vector\00") - (data (i32.const 18832) "\n\00\00\00\14\00\00\00\1e\00\00\00") - (data (i32.const 18848) "std::array\00") - (data (i32.const 18864) "apple\00") - (data (i32.const 18880) "cat\00") - (data (i32.const 18896) "panda\00") - (data (i32.const 18912) "map\00") - (data (i32.const 18928) "tuple\00") - (data (i32.const 18944) "eosio\00") - (data (i32.const 18960) "onerror\00") - (data (i32.const 18976) "onerror called\n\00") - (data (i32.const 18992) "Unknown Test\00") - (data (i32.const 27408) "malloc_from_freed was designed to only be called after _heap was completely allocated\00") - (export "memory" (memory $0)) - (export "_ZeqRK11checksum256S1_" (func $_ZeqRK11checksum256S1_)) - (export "_ZeqRK11checksum160S1_" (func $_ZeqRK11checksum160S1_)) - (export "_ZneRK11checksum160S1_" (func $_ZneRK11checksum160S1_)) - (export "now" (func $now)) - (export "_ZN5eosio12require_authERKNS_16permission_levelE" (func $_ZN5eosio12require_authERKNS_16permission_levelE)) - (export "_ZN11test_action18read_action_normalEv" (func $_ZN11test_action18read_action_normalEv)) - (export "_ZN11test_action17test_dummy_actionEv" (func $_ZN11test_action17test_dummy_actionEv)) - (export "_ZN11test_action16read_action_to_0Ev" (func $_ZN11test_action16read_action_to_0Ev)) - (export "_ZN11test_action18read_action_to_64kEv" (func $_ZN11test_action18read_action_to_64kEv)) - (export "_ZN11test_action14test_cf_actionEv" (func $_ZN11test_action14test_cf_actionEv)) - (export "_ZN11test_action14require_noticeEyyy" (func $_ZN11test_action14require_noticeEyyy)) - (export "_ZN11test_action12require_authEv" (func $_ZN11test_action12require_authEv)) - (export "_ZN11test_action12assert_falseEv" (func $_ZN11test_action12assert_falseEv)) - (export "_ZN11test_action11assert_trueEv" (func $_ZN11test_action11assert_trueEv)) - (export "_ZN11test_action14assert_true_cfEv" (func $_ZN11test_action14assert_true_cfEv)) - (export "_ZN11test_action10test_abortEv" (func $_ZN11test_action10test_abortEv)) - (export "_ZN11test_action21test_publication_timeEv" (func $_ZN11test_action21test_publication_timeEv)) - (export "_ZN11test_action21test_current_receiverEyyy" (func $_ZN11test_action21test_current_receiverEyyy)) - (export "_ZN11test_action17test_current_timeEv" (func $_ZN11test_action17test_current_timeEv)) - (export "_ZN11test_action16test_assert_codeEv" (func $_ZN11test_action16test_assert_codeEv)) - (export "_ZN10test_print13test_prints_lEv" (func $_ZN10test_print13test_prints_lEv)) - (export "_ZN10test_print11test_printsEv" (func $_ZN10test_print11test_printsEv)) - (export "_ZN10test_print11test_printiEv" (func $_ZN10test_print11test_printiEv)) - (export "_ZN10test_print12test_printuiEv" (func $_ZN10test_print12test_printuiEv)) - (export "_ZN10test_print14test_printi128Ev" (func $_ZN10test_print14test_printi128Ev)) - (export "_ZN10test_print15test_printui128Ev" (func $_ZN10test_print15test_printui128Ev)) - (export "_ZN10test_print11test_printnEv" (func $_ZN10test_print11test_printnEv)) - (export "_ZN10test_print12test_printsfEv" (func $_ZN10test_print12test_printsfEv)) - (export "_ZN10test_print12test_printdfEv" (func $_ZN10test_print12test_printdfEv)) - (export "_ZN10test_print12test_printqfEv" (func $_ZN10test_print12test_printqfEv)) - (export "_ZN10test_print17test_print_simpleEv" (func $_ZN10test_print17test_print_simpleEv)) - (export "_ZN10test_types10types_sizeEv" (func $_ZN10test_types10types_sizeEv)) - (export "_ZN10test_types14char_to_symbolEv" (func $_ZN10test_types14char_to_symbolEv)) - (export "_ZN10test_types14string_to_nameEv" (func $_ZN10test_types14string_to_nameEv)) - (export "_ZN10test_types10name_classEv" (func $_ZN10test_types10name_classEv)) - (export "_ZN15test_fixedpoint16create_instancesEv" (func $_ZN15test_fixedpoint16create_instancesEv)) - (export "_ZN15test_fixedpoint13test_additionEv" (func $_ZN15test_fixedpoint13test_additionEv)) - (export "_ZN15test_fixedpoint16test_subtractionEv" (func $_ZN15test_fixedpoint16test_subtractionEv)) - (export "_ZN15test_fixedpoint19test_multiplicationEv" (func $_ZN15test_fixedpoint19test_multiplicationEv)) - (export "_ZN15test_fixedpoint13test_divisionEv" (func $_ZN15test_fixedpoint13test_divisionEv)) - (export "_ZN15test_fixedpoint18test_division_by_0Ev" (func $_ZN15test_fixedpoint18test_division_by_0Ev)) - (export "_Zli5_ULLLPKc" (func $_Zli5_ULLLPKc)) - (export "_Zli4_LLLPKc" (func $_Zli4_LLLPKc)) - (export "_ZN22test_compiler_builtins11test_multi3Ev" (func $_ZN22test_compiler_builtins11test_multi3Ev)) - (export "_ZN22test_compiler_builtins11test_divti3Ev" (func $_ZN22test_compiler_builtins11test_divti3Ev)) - (export "_ZN22test_compiler_builtins16test_divti3_by_0Ev" (func $_ZN22test_compiler_builtins16test_divti3_by_0Ev)) - (export "_ZN22test_compiler_builtins12test_udivti3Ev" (func $_ZN22test_compiler_builtins12test_udivti3Ev)) - (export "_ZN22test_compiler_builtins17test_udivti3_by_0Ev" (func $_ZN22test_compiler_builtins17test_udivti3_by_0Ev)) - (export "_ZN22test_compiler_builtins12test_lshlti3Ev" (func $_ZN22test_compiler_builtins12test_lshlti3Ev)) - (export "_ZN22test_compiler_builtins12test_ashlti3Ev" (func $_ZN22test_compiler_builtins12test_ashlti3Ev)) - (export "_ZN22test_compiler_builtins12test_lshrti3Ev" (func $_ZN22test_compiler_builtins12test_lshrti3Ev)) - (export "_ZN22test_compiler_builtins12test_ashrti3Ev" (func $_ZN22test_compiler_builtins12test_ashrti3Ev)) - (export "_ZN22test_compiler_builtins11test_modti3Ev" (func $_ZN22test_compiler_builtins11test_modti3Ev)) - (export "_ZN22test_compiler_builtins16test_modti3_by_0Ev" (func $_ZN22test_compiler_builtins16test_modti3_by_0Ev)) - (export "_ZN22test_compiler_builtins12test_umodti3Ev" (func $_ZN22test_compiler_builtins12test_umodti3Ev)) - (export "_ZN22test_compiler_builtins17test_umodti3_by_0Ev" (func $_ZN22test_compiler_builtins17test_umodti3_by_0Ev)) - (export "my_strlen" (func $my_strlen)) - (export "my_memcmp" (func $my_memcmp)) - (export "_ZN11test_crypto28test_recover_key_assert_trueEv" (func $_ZN11test_crypto28test_recover_key_assert_trueEv)) - (export "_ZN11test_crypto29test_recover_key_assert_falseEv" (func $_ZN11test_crypto29test_recover_key_assert_falseEv)) - (export "_ZN11test_crypto16test_recover_keyEv" (func $_ZN11test_crypto16test_recover_keyEv)) - (export "_ZN11test_crypto9test_sha1Ev" (func $_ZN11test_crypto9test_sha1Ev)) - (export "_ZN11test_crypto11test_sha256Ev" (func $_ZN11test_crypto11test_sha256Ev)) - (export "_ZN11test_crypto11test_sha512Ev" (func $_ZN11test_crypto11test_sha512Ev)) - (export "_ZN11test_crypto14test_ripemd160Ev" (func $_ZN11test_crypto14test_ripemd160Ev)) - (export "_ZN11test_crypto11sha256_nullEv" (func $_ZN11test_crypto11sha256_nullEv)) - (export "_ZN11test_crypto12sha1_no_dataEv" (func $_ZN11test_crypto12sha1_no_dataEv)) - (export "_ZN11test_crypto14sha256_no_dataEv" (func $_ZN11test_crypto14sha256_no_dataEv)) - (export "_ZN11test_crypto14sha512_no_dataEv" (func $_ZN11test_crypto14sha512_no_dataEv)) - (export "_ZN11test_crypto17ripemd160_no_dataEv" (func $_ZN11test_crypto17ripemd160_no_dataEv)) - (export "_ZN11test_crypto19assert_sha256_falseEv" (func $_ZN11test_crypto19assert_sha256_falseEv)) - (export "_ZN11test_crypto18assert_sha256_trueEv" (func $_ZN11test_crypto18assert_sha256_trueEv)) - (export "_ZN11test_crypto17assert_sha1_falseEv" (func $_ZN11test_crypto17assert_sha1_falseEv)) - (export "_ZN11test_crypto16assert_sha1_trueEv" (func $_ZN11test_crypto16assert_sha1_trueEv)) - (export "_ZN11test_crypto19assert_sha512_falseEv" (func $_ZN11test_crypto19assert_sha512_falseEv)) - (export "_ZN11test_crypto18assert_sha512_trueEv" (func $_ZN11test_crypto18assert_sha512_trueEv)) - (export "_ZN11test_crypto22assert_ripemd160_falseEv" (func $_ZN11test_crypto22assert_ripemd160_falseEv)) - (export "_ZN11test_crypto21assert_ripemd160_trueEv" (func $_ZN11test_crypto21assert_ripemd160_trueEv)) - (export "_ZN10test_chain16test_activeprodsEv" (func $_ZN10test_chain16test_activeprodsEv)) - (export "_Z9copy_dataPcjRNSt3__16vectorIcNS0_9allocatorIcEEEE" (func $_Z9copy_dataPcjRNSt3__16vectorIcNS0_9allocatorIcEEEE)) - (export "_ZN16test_transaction11send_actionEv" (func $_ZN16test_transaction11send_actionEv)) - (export "_ZN16test_transaction17send_action_emptyEv" (func $_ZN16test_transaction17send_action_emptyEv)) - (export "_ZN16test_transaction17send_action_largeEv" (func $_ZN16test_transaction17send_action_largeEv)) - (export "_ZN16test_transaction19send_action_recurseEv" (func $_ZN16test_transaction19send_action_recurseEv)) - (export "_ZN16test_transaction23send_action_inline_failEv" (func $_ZN16test_transaction23send_action_inline_failEv)) - (export "_ZN16test_transaction23test_tapos_block_prefixEv" (func $_ZN16test_transaction23test_tapos_block_prefixEv)) - (export "_ZN16test_transaction20test_tapos_block_numEv" (func $_ZN16test_transaction20test_tapos_block_numEv)) - (export "_ZN16test_transaction21test_read_transactionEv" (func $_ZN16test_transaction21test_read_transactionEv)) - (export "_ZN16test_transaction21test_transaction_sizeEv" (func $_ZN16test_transaction21test_transaction_sizeEv)) - (export "_ZN16test_transaction16send_transactionEyyy" (func $_ZN16test_transaction16send_transactionEyyy)) - (export "_ZN16test_transaction18send_action_senderEyyy" (func $_ZN16test_transaction18send_action_senderEyyy)) - (export "_ZN16test_transaction22send_transaction_emptyEyyy" (func $_ZN16test_transaction22send_transaction_emptyEyyy)) - (export "_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy" (func $_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy)) - (export "_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE" (func $_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE)) - (export "_ZN16test_transaction22send_transaction_largeEyyy" (func $_ZN16test_transaction22send_transaction_largeEyyy)) - (export "_ZN16test_transaction14deferred_printEv" (func $_ZN16test_transaction14deferred_printEv)) - (export "_ZN16test_transaction25send_deferred_transactionEyyy" (func $_ZN16test_transaction25send_deferred_transactionEyyy)) - (export "_ZN16test_transaction33send_deferred_transaction_replaceEyyy" (func $_ZN16test_transaction33send_deferred_transaction_replaceEyyy)) - (export "_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv" (func $_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv)) - (export "_ZN16test_transaction35cancel_deferred_transaction_successEv" (func $_ZN16test_transaction35cancel_deferred_transaction_successEv)) - (export "_ZN16test_transaction37cancel_deferred_transaction_not_foundEv" (func $_ZN16test_transaction37cancel_deferred_transaction_not_foundEv)) - (export "_ZN16test_transaction14send_cf_actionEv" (func $_ZN16test_transaction14send_cf_actionEv)) - (export "_ZN16test_transaction19send_cf_action_failEv" (func $_ZN16test_transaction19send_cf_action_failEv)) - (export "_ZN16test_transaction12stateful_apiEv" (func $_ZN16test_transaction12stateful_apiEv)) - (export "_ZN16test_transaction16context_free_apiEv" (func $_ZN16test_transaction16context_free_apiEv)) - (export "_ZN16test_transaction11new_featureEv" (func $_ZN16test_transaction11new_featureEv)) - (export "_ZN16test_transaction18active_new_featureEv" (func $_ZN16test_transaction18active_new_featureEv)) - (export "_ZN14test_checktime14checktime_passEv" (func $_ZN14test_checktime14checktime_passEv)) - (export "_ZN14test_checktime17checktime_failureEv" (func $_ZN14test_checktime17checktime_failureEv)) - (export "_ZN14test_checktime22checktime_sha1_failureEv" (func $_ZN14test_checktime22checktime_sha1_failureEv)) - (export "_ZN14test_checktime29checktime_assert_sha1_failureEv" (func $_ZN14test_checktime29checktime_assert_sha1_failureEv)) - (export "_ZN14test_checktime24checktime_sha256_failureEv" (func $_ZN14test_checktime24checktime_sha256_failureEv)) - (export "_ZN14test_checktime31checktime_assert_sha256_failureEv" (func $_ZN14test_checktime31checktime_assert_sha256_failureEv)) - (export "_ZN14test_checktime24checktime_sha512_failureEv" (func $_ZN14test_checktime24checktime_sha512_failureEv)) - (export "_ZN14test_checktime31checktime_assert_sha512_failureEv" (func $_ZN14test_checktime31checktime_assert_sha512_failureEv)) - (export "_ZN14test_checktime27checktime_ripemd160_failureEv" (func $_ZN14test_checktime27checktime_ripemd160_failureEv)) - (export "_ZN14test_checktime34checktime_assert_ripemd160_failureEv" (func $_ZN14test_checktime34checktime_assert_ripemd160_failureEv)) - (export "_ZN15test_permission19check_authorizationEyyy" (func $_ZN15test_permission19check_authorizationEyyy)) - (export "_ZN15test_permission25test_permission_last_usedEyyy" (func $_ZN15test_permission25test_permission_last_usedEyyy)) - (export "_ZN15test_permission26test_account_creation_timeEyyy" (func $_ZN15test_permission26test_account_creation_timeEyyy)) - (export "_ZN15test_datastream10test_basicEv" (func $_ZN15test_datastream10test_basicEv)) - (export "apply" (func $apply)) - (export "fabs" (func $fabs)) - (export "fabsf" (func $fabsf)) - (export "memccpy" (func $memccpy)) - (export "memcmp" (func $memcmp)) - (export "strlen" (func $strlen)) - (export "malloc" (func $malloc)) - (export "free" (func $free)) - (func $_ZeqRK11checksum256S1_ (param $0 i32) (param $1 i32) (result i32) - (i32.eqz - (call $memcmp - (get_local $0) - (get_local $1) - (i32.const 32) - ) - ) - ) - (func $_ZeqRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) - (i32.eqz - (call $memcmp - (get_local $0) - (get_local $1) - (i32.const 32) - ) - ) - ) - (func $_ZneRK11checksum160S1_ (param $0 i32) (param $1 i32) (result i32) - (i32.ne - (call $memcmp - (get_local $0) - (get_local $1) - (i32.const 32) - ) - (i32.const 0) - ) - ) - (func $now (result i32) - (i32.wrap/i64 - (i64.div_u - (call $current_time) - (i64.const 1000000) - ) - ) - ) - (func $_ZN5eosio12require_authERKNS_16permission_levelE (param $0 i32) - (call $require_auth2 - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (func $_ZN11test_action18read_action_normalEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (call $eosio_assert - (i32.eq - (call $action_data_size) - (i32.const 13) - ) - (i32.const 32) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (get_local $0) - (i32.const 30) - ) - (i32.const 13) - ) - (i32.const 80) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (get_local $0) - (i32.const 100) - ) - (i32.const 13) - ) - (i32.const 96) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (get_local $0) - (i32.const 5) - ) - (i32.const 5) - ) - (i32.const 128) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (get_local $0) - (i32.const 13) - ) - (i32.const 13) - ) - (i32.const 144) - ) - (call $eosio_assert - (i32.eq - (i32.load8_u - (get_local $0) - ) - (i32.const 69) - ) - (i32.const 192) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=1 align=1 - (get_local $0) - ) - (i64.const -6119884940280240521) - ) - (i32.const 240) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=9 align=1 - (get_local $0) - ) - (i32.const 1951510034) - ) - (i32.const 288) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 112) - ) - ) - ) - (func $_ZN11test_action17test_dummy_actionEv - (local $0 i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 176) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (tee_local $0 - (call $get_action - (i32.const 1) - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 64) - ) - (call $get_action - (i32.const 1) - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 64) - ) - (i32.const 0) - ) - ) - ) - (i32.const 0) - ) - (i32.const 336) - ) - (call $_ZN5eosio10get_actionEmm - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.const 1) - (i32.const 0) - ) - (set_local $1 - (i64.load - (i32.add - (i32.load - (i32.add - (get_local $10) - (i32.const 44) - ) - ) - (i32.const -16) - ) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $2 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $2 - (select - (i32.add - (get_local $2) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $2) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (get_local $8) - ) - (i32.const 384) - ) - (set_local $1 - (i64.load - (i32.add - (i32.load - (i32.add - (get_local $10) - (i32.const 44) - ) - ) - (i32.const -8) - ) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 416) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $7) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $2 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $2 - (select - (i32.add - (get_local $2) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $2) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (get_local $8) - ) - (i32.const 432) - ) - (set_local $5 - (i32.const 16) - ) - (set_local $7 - (i64.extend_u/i32 - (i32.shr_s - (tee_local $4 - (i32.sub - (tee_local $2 - (i32.load - (i32.add - (get_local $10) - (i32.const 44) - ) - ) - ) - (tee_local $3 - (i32.load - (i32.add - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.const 16) - ) - ) - ) - ) - ) - (i32.const 4) - ) - ) - ) - (loop $label$12 - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (br_if $label$12 - (i64.ne - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eq - (get_local $3) - (get_local $2) - ) - ) - (set_local $5 - (i32.add - (i32.and - (get_local $4) - (i32.const -16) - ) - (get_local $5) - ) - ) - ) - (set_local $5 - (i32.sub - (i32.sub - (i32.add - (get_local $0) - (tee_local $2 - (i32.load offset=52 - (get_local $10) - ) - ) - ) - (get_local $5) - ) - (tee_local $0 - (i32.load - (i32.add - (get_local $10) - (i32.const 56) - ) - ) - ) - ) - ) - (set_local $7 - (i64.extend_u/i32 - (i32.sub - (get_local $0) - (get_local $2) - ) - ) - ) - (loop $label$14 - (set_local $5 - (i32.add - (get_local $5) - (i32.const -1) - ) - ) - (br_if $label$14 - (i64.ne - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (call $eosio_assert - (i32.eqz - (get_local $5) - ) - (i32.const 464) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 368) - ) - (set_local $1 - (i64.load offset=24 - (get_local $10) - ) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$15 - (block $label$16 - (block $label$17 - (block $label$18 - (block $label$19 - (block $label$20 - (br_if $label$20 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$19 - (i32.gt_u - (i32.and - (i32.add - (tee_local $2 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 165) - ) - ) - (br $label$18) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$17 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$16) - ) - (set_local $2 - (select - (i32.add - (get_local $2) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $2) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$15 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (get_local $8) - ) - (i32.const 512) - ) - (call $_ZN5eosio6action7data_asI12dummy_actionEET_v - (i32.add - (get_local $10) - (i32.const 8) - ) - (i32.add - (get_local $10) - (i32.const 24) - ) - ) - (block $label$21 - (block $label$22 - (block $label$23 - (br_if $label$23 - (i64.ne - (i64.load offset=9 align=1 - (get_local $10) - ) - (i64.const 200) - ) - ) - (drop - (call $get_context_free_data - (i32.const 0) - (i32.const 0) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 544) - ) - (br_if $label$22 - (tee_local $5 - (i32.load offset=52 - (get_local $10) - ) - ) - ) - (br $label$21) - ) - (call $eosio_assert - (i32.eq - (i32.load8_u offset=8 - (get_local $10) - ) - (i32.const 69) - ) - (i32.const 608) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=9 align=1 - (get_local $10) - ) - (i64.const -6119884940280240521) - ) - (i32.const 656) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=17 align=1 - (get_local $10) - ) - (i32.const 1951510034) - ) - (i32.const 704) - ) - (br_if $label$21 - (i32.eqz - (tee_local $5 - (i32.load offset=52 - (get_local $10) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 56) - ) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (block $label$24 - (br_if $label$24 - (i32.eqz - (tee_local $5 - (i32.load offset=40 - (get_local $10) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 44) - ) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 176) - ) - ) - ) - (func $_ZN5eosio10get_actionEmm (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (set_local $5 - (tee_local $4 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $4) - ) - (call $eosio_assert - (i32.gt_s - (tee_local $3 - (call $get_action - (get_local $1) - (get_local $2) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 0) - ) - (i32.const 816) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (get_local $3) - (i32.const 513) - ) - ) - (set_local $4 - (call $malloc - (get_local $3) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (get_local $4) - (i32.and - (i32.add - (get_local $3) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (call $eosio_assert - (i32.eq - (get_local $3) - (call $get_action - (get_local $1) - (get_local $2) - (get_local $4) - (get_local $3) - ) - ) - (i32.const 336) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i32.store - (get_local $5) - (get_local $4) - ) - (i32.store offset=8 - (get_local $5) - (tee_local $1 - (i32.add - (get_local $4) - (get_local $3) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (get_local $3) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $4) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (get_local $1) - (tee_local $3 - (i32.add - (get_local $4) - (i32.const 8) - ) - ) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $3) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $5) - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE - (call $_ZN5eosiorsINS_10datastreamIPKcEENS_16permission_levelEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE - (get_local $5) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosio6action7data_asI12dummy_actionEET_v (param $0 i32) (param $1 i32) - (local $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (set_local $2 - (i64.load offset=8 - (get_local $1) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $8 - (i64.const 59) - ) - (set_local $4 - (i32.const 752) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$0 - (set_local $6 - (i64.const 0) - ) - (block $label$1 - (br_if $label$1 - (i64.gt_u - (get_local $7) - (i64.const 11) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$2) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.extend_u/i32 - (i32.and - (get_local $3) - (i32.const 31) - ) - ) - (i64.and - (get_local $8) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $8 - (i64.add - (get_local $8) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $5) - ) - (i32.const 768) - ) - (set_local $2 - (i64.load - (get_local $1) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $4 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$8 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$7) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$6 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$5) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $8) - (get_local $5) - ) - ) - (br_if $label$4 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $5) - ) - (i32.const 784) - ) - (call $eosio_assert - (i32.ne - (tee_local $3 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - (tee_local $4 - (i32.load offset=28 - (get_local $1) - ) - ) - ) - ) - (i32.const 0) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $4) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.add - (get_local $3) - (i32.const -1) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 1) - ) - (i32.add - (get_local $4) - (i32.const 1) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.add - (get_local $3) - (i32.const -9) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 9) - ) - (i32.add - (get_local $4) - (i32.const 9) - ) - (i32.const 4) - ) - ) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEENS_16permission_levelEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (set_local $7 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $5 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $7) - (i32.load - (get_local $2) - ) - ) - (i32.const 848) - ) - (set_local $4 - (i32.load8_u - (tee_local $7 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $6 - (i32.and - (get_local $6) - (i32.const 255) - ) - ) - ) - ) - (get_local $5) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.le_u - (tee_local $4 - (i32.wrap/i64 - (get_local $5) - ) - ) - (tee_local $6 - (i32.shr_s - (i32.sub - (tee_local $2 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $7 - (i32.load - (get_local $1) - ) - ) - ) - (i32.const 4) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIN5eosio16permission_levelENS_9allocatorIS2_EEE8__appendEj - (get_local $1) - (i32.sub - (get_local $4) - (get_local $6) - ) - ) - (br_if $label$2 - (i32.ne - (tee_local $7 - (i32.load - (get_local $1) - ) - ) - (tee_local $2 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (br $label$1) - ) - (block $label$4 - (br_if $label$4 - (i32.ge_u - (get_local $4) - (get_local $6) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (tee_local $2 - (i32.add - (get_local $7) - (i32.shl - (get_local $4) - (i32.const 4) - ) - ) - ) - ) - ) - (br_if $label$1 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - ) - (set_local $6 - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - (loop $label$5 - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $6) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $7) - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (get_local $3) - ) - (get_local $6) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - ) - (br_if $label$5 - (i32.ne - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $2) - ) - ) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.const 848) - ) - (set_local $4 - (i32.load8_u - (tee_local $5 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $7 - (i32.and - (get_local $7) - (i32.const 255) - ) - ) - ) - ) - (get_local $6) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.le_u - (tee_local $3 - (i32.wrap/i64 - (get_local $6) - ) - ) - (tee_local $2 - (i32.sub - (tee_local $7 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $1) - (i32.sub - (get_local $3) - (get_local $2) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - (set_local $4 - (i32.load - (get_local $1) - ) - ) - (br $label$1) - ) - (br_if $label$1 - (i32.ge_u - (get_local $3) - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (tee_local $7 - (i32.add - (get_local $4) - (get_local $3) - ) - ) - ) - ) - (call $eosio_assert - (i32.ge_u - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $5) - ) - (tee_local $5 - (i32.sub - (get_local $7) - (get_local $4) - ) - ) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $4) - (i32.load - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (get_local $5) - ) - ) - (i32.store - (get_local $7) - (i32.add - (i32.load - (get_local $7) - ) - (get_local $5) - ) - ) - (get_local $0) - ) - (func $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (i32.sub - (tee_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (get_local $1) - ) - ) - (br_if $label$2 - (i32.le_s - (tee_local $4 - (i32.add - (tee_local $3 - (i32.sub - (get_local $6) - (tee_local $5 - (i32.load - (get_local $0) - ) - ) - ) - ) - (get_local $1) - ) - ) - (i32.const -1) - ) - ) - (set_local $6 - (i32.const 2147483647) - ) - (block $label$5 - (br_if $label$5 - (i32.gt_u - (tee_local $2 - (i32.sub - (get_local $2) - (get_local $5) - ) - ) - (i32.const 1073741822) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $6 - (select - (get_local $4) - (tee_local $6 - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $6) - (get_local $4) - ) - ) - ) - ) - ) - ) - (set_local $2 - (call $_Znwj - (get_local $6) - ) - ) - (br $label$1) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$6 - (i32.store8 - (get_local $6) - (i32.const 0) - ) - (i32.store - (get_local $0) - (tee_local $6 - (i32.add - (i32.load - (get_local $0) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$6 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - (br $label$0) - ) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $2 - (i32.const 0) - ) - (br $label$1) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $4 - (i32.add - (get_local $2) - (get_local $6) - ) - ) - (set_local $6 - (tee_local $5 - (i32.add - (get_local $2) - (get_local $3) - ) - ) - ) - (loop $label$7 - (i32.store8 - (get_local $6) - (i32.const 0) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$7 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - ) - (set_local $5 - (i32.sub - (get_local $5) - (tee_local $2 - (i32.sub - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $1 - (i32.load - (get_local $0) - ) - ) - ) - ) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.lt_s - (get_local $2) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $1) - (get_local $2) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $5) - ) - (i32.store - (get_local $3) - (get_local $6) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - (return) - ) - ) - (func $_ZNSt3__16vectorIN5eosio16permission_levelENS_9allocatorIS2_EEE8__appendEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (i32.shr_s - (i32.sub - (tee_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $7 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (i32.const 4) - ) - (get_local $1) - ) - ) - (br_if $label$2 - (i32.ge_u - (tee_local $4 - (i32.add - (tee_local $3 - (i32.shr_s - (i32.sub - (get_local $7) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 4) - ) - ) - (get_local $1) - ) - ) - (i32.const 268435456) - ) - ) - (set_local $5 - (i32.const 268435455) - ) - (block $label$5 - (br_if $label$5 - (i32.gt_u - (i32.shr_s - (tee_local $2 - (i32.sub - (get_local $2) - (get_local $6) - ) - ) - (i32.const 4) - ) - (i32.const 134217726) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $5 - (select - (get_local $4) - (tee_local $5 - (i32.shr_s - (get_local $2) - (i32.const 3) - ) - ) - (i32.lt_u - (get_local $5) - (get_local $4) - ) - ) - ) - ) - ) - (br_if $label$1 - (i32.ge_u - (get_local $5) - (i32.const 268435456) - ) - ) - ) - (set_local $2 - (call $_Znwj - (i32.shl - (get_local $5) - (i32.const 4) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - (br $label$0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.add - (get_local $7) - (i32.shl - (get_local $1) - (i32.const 4) - ) - ) - ) - (return) - ) - (set_local $5 - (i32.const 0) - ) - (set_local $2 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (call $abort) - (unreachable) - ) - (set_local $4 - (i32.sub - (tee_local $3 - (i32.add - (get_local $2) - (i32.shl - (get_local $3) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.sub - (get_local $7) - (get_local $6) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $3) - (i32.shl - (get_local $1) - (i32.const 4) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $2) - (i32.shl - (get_local $5) - (i32.const 4) - ) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.lt_s - (get_local $7) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $4) - (get_local $6) - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $4) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $5) - ) - (block $label$7 - (br_if $label$7 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $_ZN11test_action16read_action_to_0Ev - (drop - (call $read_action_data - (i32.const 0) - (call $action_data_size) - ) - ) - ) - (func $_ZN11test_action18read_action_to_64kEv - (drop - (call $read_action_data - (i32.const 65534) - (call $action_data_size) - ) - ) - ) - (func $_ZN11test_action14test_cf_actionEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 144) - ) - ) - ) - (call $_ZN5eosio10get_actionEmm - (i32.add - (get_local $9) - (i32.const 104) - ) - (i32.const 0) - (i32.const 0) - ) - (call $_ZN5eosio6action7data_asI9cf_actionEET_v - (i32.add - (get_local $9) - (i32.const 96) - ) - (i32.add - (get_local $9) - (i32.const 104) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $2 - (i32.add - (i32.load offset=96 - (get_local $9) - ) - (i32.const -100) - ) - ) - (i32.const 111) - ) - ) - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (br_table $label$16 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$3 $label$15 $label$14 $label$13 $label$12 $label$11 $label$10 $label$9 $label$8 $label$7 $label$6 $label$5 $label$4 $label$16 - (get_local $2) - ) - ) - (call $eosio_assert - (i32.gt_s - (tee_local $0 - (call $get_context_free_data - (i32.load offset=100 - (get_local $9) - ) - (i32.const 0) - (i32.const 0) - ) - ) - (i32.const 0) - ) - (i32.const 864) - ) - (i32.store offset=88 - (get_local $9) - (i32.const 0) - ) - (i64.store offset=80 - (get_local $9) - (i64.const 0) - ) - (set_local $2 - (i32.const 0) - ) - (block $label$17 - (br_if $label$17 - (i32.eqz - (get_local $0) - ) - ) - (br_if $label$0 - (i32.le_s - (get_local $0) - (i32.const -1) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 88) - ) - (i32.add - (tee_local $2 - (call $_Znwj - (get_local $0) - ) - ) - (get_local $0) - ) - ) - (i32.store offset=80 - (get_local $9) - (get_local $2) - ) - (i32.store offset=84 - (get_local $9) - (get_local $2) - ) - (set_local $1 - (get_local $0) - ) - (loop $label$18 - (i32.store8 - (get_local $2) - (i32.const 0) - ) - (i32.store offset=84 - (get_local $9) - (tee_local $2 - (i32.add - (i32.load offset=84 - (get_local $9) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$18 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - ) - (set_local $2 - (i32.load offset=80 - (get_local $9) - ) - ) - ) - (call $eosio_assert - (i32.eq - (call $get_context_free_data - (i32.load offset=100 - (get_local $9) - ) - (get_local $2) - (get_local $0) - ) - (i32.sub - (i32.load offset=84 - (get_local $9) - ) - (i32.load offset=80 - (get_local $9) - ) - ) - ) - (i32.const 896) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=84 - (get_local $9) - ) - (tee_local $2 - (i32.load offset=80 - (get_local $9) - ) - ) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $9) - (get_local $2) - (i32.const 4) - ) - ) - (i32.store offset=76 - (get_local $9) - (tee_local $2 - (i32.load - (get_local $9) - ) - ) - ) - (call $eosio_assert - (i32.eq - (get_local $2) - (i32.load offset=96 - (get_local $9) - ) - ) - (i32.const 928) - ) - (i32.store8 - (i32.add - (i32.add - (get_local $9) - (i32.const 68) - ) - (i32.const 4) - ) - (i32.load8_u offset=948 - (i32.const 0) - ) - ) - (i32.store offset=68 - (get_local $9) - (i32.load offset=944 align=1 - (i32.const 0) - ) - ) - (call $sha256 - (i32.add - (get_local $9) - (i32.const 68) - ) - (i32.const 5) - (get_local $9) - ) - (call $assert_sha256 - (i32.add - (get_local $9) - (i32.const 68) - ) - (i32.const 5) - (get_local $9) - ) - (drop - (call $action_data_size) - ) - (call $prints - (i32.const 960) - ) - (i32.store offset=64 - (get_local $9) - (i32.const 42) - ) - (drop - (call $memccpy - (i32.add - (get_local $9) - (i32.const 76) - ) - (i32.add - (get_local $9) - (i32.const 64) - ) - (i32.const 4) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.ne - (call $transaction_size) - (i32.const 0) - ) - (i32.const 976) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1008) - ) - (call $__divti3 - (i32.add - (get_local $9) - (i32.const 48) - ) - (i64.const 2) - (i64.const 2) - (i64.const 2) - (i64.const 2) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1040) - ) - (br_if $label$3 - (i32.eqz - (tee_local $2 - (i32.load offset=80 - (get_local $9) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $9) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (drop - (call $is_privileged - (i64.load offset=112 - (get_local $9) - ) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1088) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (drop - (call $get_active_producers - (i32.const 0) - (i32.const 0) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1136) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$19 - (block $label$20 - (block $label$21 - (block $label$22 - (block $label$23 - (block $label$24 - (br_if $label$24 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$23 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$22) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$21 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$20) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$19 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$25 - (block $label$26 - (block $label$27 - (block $label$28 - (block $label$29 - (block $label$30 - (br_if $label$30 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$29 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$28) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$27 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$26) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $6) - (get_local $7) - ) - ) - (br_if $label$25 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$31 - (block $label$32 - (block $label$33 - (block $label$34 - (block $label$35 - (block $label$36 - (br_if $label$36 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$35 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$34) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$33 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$32) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $6) - (get_local $8) - ) - ) - (br_if $label$31 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (drop - (call $db_store_i64 - (get_local $5) - (get_local $7) - (get_local $8) - (i64.const 0) - (i32.const 944) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1184) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (set_local $4 - (i64.const 0) - ) - (i64.store - (get_local $9) - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$37 - (block $label$38 - (block $label$39 - (block $label$40 - (block $label$41 - (block $label$42 - (br_if $label$42 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$41 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$40) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$39 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$38) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$37 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$43 - (block $label$44 - (block $label$45 - (block $label$46 - (block $label$47 - (block $label$48 - (br_if $label$48 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$47 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$46) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$45 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$44) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $6) - (get_local $7) - ) - ) - (br_if $label$43 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$49 - (block $label$50 - (block $label$51 - (block $label$52 - (block $label$53 - (block $label$54 - (br_if $label$54 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$53 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$52) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$51 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$50) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $6) - (get_local $8) - ) - ) - (br_if $label$49 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (drop - (call $db_idx64_store - (get_local $5) - (get_local $7) - (get_local $8) - (i64.const 0) - (get_local $9) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1184) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$55 - (block $label$56 - (block $label$57 - (block $label$58 - (block $label$59 - (block $label$60 - (br_if $label$60 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$59 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$58) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$57 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$56) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$55 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$61 - (block $label$62 - (block $label$63 - (block $label$64 - (block $label$65 - (block $label$66 - (br_if $label$66 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$65 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$64) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$63 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$62) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $6) - (get_local $7) - ) - ) - (br_if $label$61 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$67 - (block $label$68 - (block $label$69 - (block $label$70 - (block $label$71 - (block $label$72 - (br_if $label$72 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$71 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$70) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$69 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$68) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $6) - (get_local $8) - ) - ) - (br_if $label$67 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (drop - (call $db_find_i64 - (get_local $5) - (get_local $7) - (get_local $8) - (i64.const 1) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1184) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 24) - ) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $9) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $9) - (i64.const 0) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $9) - (i32.const 48) - ) - (get_local $9) - ) - (call $send_inline - (tee_local $2 - (i32.load offset=48 - (get_local $9) - ) - ) - (i32.sub - (i32.load offset=52 - (get_local $9) - ) - (get_local $2) - ) - ) - (block $label$73 - (br_if $label$73 - (i32.eqz - (tee_local $2 - (i32.load offset=48 - (get_local $9) - ) - ) - ) - ) - (i32.store offset=52 - (get_local $9) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1216) - ) - (block $label$74 - (br_if $label$74 - (i32.eqz - (tee_local $2 - (i32.load - (i32.add - (get_local $9) - (i32.const 28) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 32) - ) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $2 - (i32.load - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 20) - ) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 944) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$75 - (block $label$76 - (block $label$77 - (block $label$78 - (block $label$79 - (block $label$80 - (br_if $label$80 - (i64.gt_u - (get_local $4) - (i64.const 3) - ) - ) - (br_if $label$79 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$78) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$77 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$76) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$75 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $require_auth - (get_local $5) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1264) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (drop - (call $current_time) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1312) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (drop - (call $current_time) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1312) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (drop - (call $publication_time) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1312) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (call $send_inline - (i32.const 1360) - (i32.const 6) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1376) - ) - (br_if $label$2 - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - (br $label$1) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$81 - (block $label$82 - (block $label$83 - (block $label$84 - (block $label$85 - (block $label$86 - (br_if $label$86 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$85 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$84) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$83 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$82) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$81 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $4 - (i64.const 0) - ) - (i64.store offset=8 - (get_local $9) - (i64.const 0) - ) - (i64.store - (get_local $9) - (get_local $5) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$87 - (block $label$88 - (block $label$89 - (block $label$90 - (block $label$91 - (block $label$92 - (br_if $label$92 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$91 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$90) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$89 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$88) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$87 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $send_deferred - (get_local $9) - (get_local $5) - (i32.const 1360) - (i32.const 6) - (i32.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1376) - ) - ) - (br_if $label$1 - (i32.eqz - (tee_local $2 - (i32.load offset=132 - (get_local $9) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 136) - ) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (block $label$93 - (br_if $label$93 - (i32.eqz - (tee_local $2 - (i32.load offset=120 - (get_local $9) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 124) - ) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 144) - ) - ) - (return) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $9) - (i32.const 80) - ) - ) - (unreachable) - ) - (func $_ZN5eosio6action7data_asI9cf_actionEET_v (param $0 i32) (param $1 i32) - (local $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (set_local $2 - (i64.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 1440) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $6) - (i64.const 8) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $7) - ) - (i32.const 768) - ) - (set_local $2 - (i64.load - (get_local $1) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 368) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $6) - (i64.const 6) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $7) - ) - (i32.const 784) - ) - (i64.store align=4 - (get_local $0) - (i64.const 100) - ) - (call $eosio_assert - (i32.gt_u - (tee_local $3 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - (tee_local $4 - (i32.load offset=28 - (get_local $1) - ) - ) - ) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $4) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.ne - (i32.and - (get_local $3) - (i32.const -4) - ) - (i32.const 4) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.add - (get_local $4) - (i32.const 4) - ) - (i32.const 4) - ) - ) - ) - (func $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=8 - (get_local $0) - (i32.const 0) - ) - (i64.store align=4 - (get_local $0) - (i64.const 0) - ) - (set_local $5 - (i32.const 16) - ) - (set_local $2 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - (set_local $6 - (i64.extend_u/i32 - (i32.shr_s - (tee_local $4 - (i32.sub - (tee_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - ) - (tee_local $3 - (i32.load offset=16 - (get_local $1) - ) - ) - ) - ) - (i32.const 4) - ) - ) - ) - (loop $label$0 - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $3) - (get_local $7) - ) - ) - (set_local $5 - (i32.add - (i32.and - (get_local $4) - (i32.const -16) - ) - (get_local $5) - ) - ) - ) - (set_local $5 - (i32.sub - (i32.sub - (tee_local $7 - (i32.load offset=28 - (get_local $1) - ) - ) - (get_local $5) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - (set_local $6 - (i64.extend_u/i32 - (i32.sub - (get_local $3) - (get_local $7) - ) - ) - ) - (loop $label$2 - (set_local $5 - (i32.add - (get_local $5) - (i32.const -1) - ) - ) - (br_if $label$2 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (set_local $7 - (i32.const 0) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.eqz - (get_local $5) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $0) - (i32.sub - (i32.const 0) - (get_local $5) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $5 - (i32.load - (get_local $0) - ) - ) - (br $label$3) - ) - (set_local $5 - (i32.const 0) - ) - ) - (i32.store - (get_local $8) - (get_local $5) - ) - (i32.store offset=8 - (get_local $8) - (get_local $7) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $7) - (get_local $5) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $1) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $7) - (tee_local $0 - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $0) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $8) - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE - (call $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE - (get_local $8) - (get_local $2) - ) - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $4 - (i64.extend_u/i32 - (i32.shr_s - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - (i32.const 4) - ) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$0 - (set_local $3 - (i32.wrap/i64 - (get_local $4) - ) - ) - (i32.store8 offset=15 - (get_local $7) - (i32.or - (i32.shl - (tee_local $6 - (i64.ne - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $3) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $5) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $6) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $6 - (i32.load - (get_local $1) - ) - ) - (tee_local $1 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$2 - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $5) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $3) - ) - (get_local $6) - (i32.const 8) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $5) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $3) - ) - (i32.add - (get_local $6) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 8) - ) - ) - ) - (br_if $label$2 - (i32.ne - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (get_local $1) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $7 - (i64.extend_u/i32 - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $2 - (i32.wrap/i64 - (get_local $7) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $3 - (i64.ne - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $2) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $5) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $5) - (tee_local $6 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $3) - ) - ) - (call $eosio_assert - (i32.ge_s - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $6) - ) - (tee_local $5 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (tee_local $2 - (i32.load - (get_local $1) - ) - ) - ) - ) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (get_local $2) - (get_local $5) - ) - ) - (i32.store - (get_local $6) - (i32.add - (i32.load - (get_local $6) - ) - (get_local $5) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN11test_action14require_noticeEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 368) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $6) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 1456) - ) - (set_local $9 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $6) - (i64.const 3) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $9 - (i64.or - (get_local $8) - (get_local $9) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (block $label$12 - (block $label$13 - (block $label$14 - (br_if $label$14 - (i64.ne - (get_local $7) - (get_local $0) - ) - ) - (call $require_recipient - (get_local $9) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 1472) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$15 - (block $label$16 - (block $label$17 - (block $label$18 - (block $label$19 - (block $label$20 - (br_if $label$20 - (i64.gt_u - (get_local $6) - (i64.const 3) - ) - ) - (br_if $label$19 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$18) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$17 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$16) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$15 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $require_recipient - (get_local $7) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 1456) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$21 - (block $label$22 - (block $label$23 - (block $label$24 - (block $label$25 - (block $label$26 - (br_if $label$26 - (i64.gt_u - (get_local $6) - (i64.const 3) - ) - ) - (br_if $label$25 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$24) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$23 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$22) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$21 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 1472) - ) - (set_local $9 - (i64.const 0) - ) - (loop $label$27 - (block $label$28 - (block $label$29 - (block $label$30 - (block $label$31 - (block $label$32 - (br_if $label$32 - (i64.gt_u - (get_local $6) - (i64.const 3) - ) - ) - (br_if $label$31 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$30) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$29 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$28) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $9 - (i64.or - (get_local $8) - (get_local $9) - ) - ) - (br_if $label$27 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $require_recipient - (get_local $7) - ) - (call $require_recipient - (get_local $9) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1488) - ) - (br $label$13) - ) - (br_if $label$12 - (i64.eq - (get_local $9) - (get_local $0) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 1472) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$33 - (block $label$34 - (block $label$35 - (block $label$36 - (block $label$37 - (block $label$38 - (br_if $label$38 - (i64.gt_u - (get_local $6) - (i64.const 3) - ) - ) - (br_if $label$37 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$36) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$35 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$34) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$33 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (br_if $label$12 - (i64.eq - (get_local $7) - (get_local $0) - ) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1488) - ) - ) - ) - (func $_ZN11test_action12require_authEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (call $prints - (i32.const 1520) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1536) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 3) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $require_auth - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1552) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $3) - (i64.const 3) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $require_auth - (get_local $4) - ) - ) - (func $_ZN11test_action12assert_falseEv - (call $eosio_assert - (i32.const 0) - (i32.const 1568) - ) - ) - (func $_ZN11test_action11assert_trueEv - (call $eosio_assert - (i32.const 1) - (i32.const 1600) - ) - ) - (func $_ZN11test_action14assert_true_cfEv - (call $eosio_assert - (i32.const 1) - (i32.const 1600) - ) - ) - (func $_ZN11test_action10test_abortEv - (call $abort) - (unreachable) - ) - (func $_ZN11test_action21test_publication_timeEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 1632) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $0) - ) - (call $publication_time) - ) - (i32.const 1664) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN11test_action21test_current_receiverEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $3) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $3) - ) - (get_local $0) - ) - (i32.const 1696) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - (func $_ZN11test_action17test_current_timeEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 1632) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $0) - ) - (call $current_time) - ) - (i32.const 1744) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN11test_action16test_assert_codeEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 1632) - ) - (call $eosio_assert_code - (i32.const 0) - (i64.load offset=8 - (get_local $0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN10test_print13test_prints_lEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store16 offset=14 - (get_local $0) - (i32.const 25185) - ) - (call $prints_l - (i32.add - (get_local $0) - (i32.const 14) - ) - (i32.const 2) - ) - (call $prints_l - (i32.add - (get_local $0) - (i32.const 14) - ) - (i32.const 1) - ) - (call $prints_l - (i32.add - (get_local $0) - (i32.const 14) - ) - (i32.const 0) - ) - (call $prints_l - (i32.const 944) - (i32.const 4) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN10test_print11test_printsEv - (call $prints - (i32.const 1776) - ) - (call $prints - (i32.const 0) - ) - (call $prints - (i32.const 1792) - ) - (call $prints - (i32.const 0) - ) - (call $prints - (i32.const 1808) - ) - (call $prints - (i32.const 0) - ) - ) - (func $_ZN10test_print11test_printiEv - (call $printi - (i64.const 0) - ) - (call $printi - (i64.const 556644) - ) - (call $printi - (i64.const -1) - ) - ) - (func $_ZN10test_print12test_printuiEv - (call $printui - (i64.const 0) - ) - (call $printui - (i64.const 556644) - ) - (call $printui - (i64.const -1) - ) - ) - (func $_ZN10test_print14test_printi128Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (i64.store offset=56 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=48 - (get_local $0) - (i64.const 1) - ) - (i64.store offset=40 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=32 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $0) - (i64.const -9223372036854775808) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -1) - ) - (i64.store - (get_local $0) - (i64.const -87654323456) - ) - (call $printi128 - (i32.add - (get_local $0) - (i32.const 48) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printi128 - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printi128 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printi128 - (get_local $0) - ) - (call $prints - (i32.const 1824) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - (func $_ZN10test_print15test_printui128Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i64.store offset=40 - (get_local $0) - (i64.const -1) - ) - (i64.store offset=32 - (get_local $0) - (i64.const -1) - ) - (i64.store offset=24 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 87654323456) - ) - (call $printui128 - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printui128 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printui128 - (get_local $0) - ) - (call $prints - (i32.const 1824) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 48) - ) - ) - ) - (func $_ZN10test_print11test_printnEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1840) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 4) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1856) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $3) - (i64.const 4) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1872) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (block $label$17 - (br_if $label$17 - (i64.gt_u - (get_local $3) - (i64.const 7) - ) - ) - (br_if $label$16 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$15) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$14 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$13) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$12 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (call $printn - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1888) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$18 - (block $label$19 - (block $label$20 - (block $label$21 - (block $label$22 - (block $label$23 - (br_if $label$23 - (i64.gt_u - (get_local $3) - (i64.const 5) - ) - ) - (br_if $label$22 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$21) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$20 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$19) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$18 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1904) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$24 - (block $label$25 - (block $label$26 - (block $label$27 - (block $label$28 - (block $label$29 - (br_if $label$29 - (i64.gt_u - (get_local $3) - (i64.const 10) - ) - ) - (br_if $label$28 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$27) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$26 - (i64.eq - (get_local $3) - (i64.const 11) - ) - ) - (br $label$25) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$24 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (i64.const 13) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $1 - (i32.const 1920) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$30 - (set_local $2 - (i64.const 0) - ) - (block $label$31 - (br_if $label$31 - (i64.gt_u - (get_local $3) - (i64.const 11) - ) - ) - (block $label$32 - (block $label$33 - (br_if $label$33 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$32) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $2 - (i64.shl - (i64.extend_u/i32 - (i32.and - (get_local $0) - (i32.const 31) - ) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $2) - (get_local $4) - ) - ) - (br_if $label$30 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1936) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$34 - (set_local $5 - (i64.const 0) - ) - (block $label$35 - (block $label$36 - (br_if $label$36 - (i64.gt_u - (get_local $3) - (i64.const 12) - ) - ) - (block $label$37 - (block $label$38 - (br_if $label$38 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$37) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$36 - (i64.gt_u - (get_local $3) - (i64.const 11) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - (br $label$35) - ) - (set_local $5 - (i64.and - (get_local $5) - (i64.const 15) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$34 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1952) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$39 - (set_local $5 - (i64.const 0) - ) - (block $label$40 - (block $label$41 - (br_if $label$41 - (i64.gt_u - (get_local $3) - (i64.const 13) - ) - ) - (block $label$42 - (block $label$43 - (br_if $label$43 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$42) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$41 - (i64.gt_u - (get_local $3) - (i64.const 11) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - (br $label$40) - ) - (set_local $5 - (i64.and - (get_local $5) - (i64.const 15) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$39 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 1968) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$44 - (set_local $5 - (i64.const 0) - ) - (block $label$45 - (block $label$46 - (br_if $label$46 - (i64.gt_u - (get_local $3) - (i64.const 14) - ) - ) - (block $label$47 - (block $label$48 - (br_if $label$48 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$47) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$46 - (i64.gt_u - (get_local $3) - (i64.const 11) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - (br $label$45) - ) - (set_local $5 - (i64.and - (get_local $5) - (i64.const 15) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$44 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $printn - (get_local $4) - ) - ) - (func $_ZN10test_print12test_printsfEv - (call $printsf - (f32.const 0.5) - ) - (call $prints - (i32.const 1824) - ) - (call $printsf - (f32.const -3.75) - ) - (call $prints - (i32.const 1824) - ) - (call $printsf - (f32.const 6.666666649834951e-07) - ) - (call $prints - (i32.const 1824) - ) - ) - (func $_ZN10test_print12test_printdfEv - (call $printdf - (f64.const 0.5) - ) - (call $prints - (i32.const 1824) - ) - (call $printdf - (f64.const -3.75) - ) - (call $prints - (i32.const 1824) - ) - (call $printdf - (f64.const 6.666666666666666e-07) - ) - (call $prints - (i32.const 1824) - ) - ) - (func $_ZN10test_print12test_printqfEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 48) - ) - ) - ) - (i64.store offset=40 - (get_local $0) - (i64.const 4611123068473966592) - ) - (i64.store offset=32 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $0) - (i64.const -4611439727822766080) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 4605605624503281953) - ) - (i64.store - (get_local $0) - (i64.const 1865728291273748996) - ) - (call $printqf - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printqf - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printqf - (get_local $0) - ) - (call $prints - (i32.const 1824) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 48) - ) - ) - ) - (func $_ZN10test_print17test_print_simpleEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i32.store - (i32.add - (get_local $3) - (i32.const 24) - ) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $3) - (i64.const 0) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $0 - (call $strlen - (i32.const 1984) - ) - ) - (i32.const -16) - ) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (get_local $0) - (i32.const 11) - ) - ) - (i32.store8 offset=16 - (get_local $3) - (i32.shl - (get_local $0) - (i32.const 1) - ) - ) - (set_local $2 - (tee_local $1 - (i32.or - (i32.add - (get_local $3) - (i32.const 16) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$3 - (get_local $0) - ) - (br $label$2) - ) - (set_local $2 - (call $_Znwj - (tee_local $1 - (i32.and - (i32.add - (get_local $0) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=16 - (get_local $3) - (i32.or - (get_local $1) - (i32.const 1) - ) - ) - (i32.store offset=24 - (get_local $3) - (get_local $2) - ) - (i32.store offset=20 - (get_local $3) - (get_local $0) - ) - (set_local $1 - (i32.or - (i32.add - (get_local $3) - (i32.const 16) - ) - (i32.const 1) - ) - ) - ) - (drop - (call $memcpy - (get_local $2) - (i32.const 1984) - (get_local $0) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $2) - (get_local $0) - ) - (i32.const 0) - ) - (call $prints_l - (select - (i32.load offset=24 - (get_local $3) - ) - (get_local $1) - (tee_local $2 - (i32.and - (tee_local $0 - (i32.load8_u offset=16 - (get_local $3) - ) - ) - (i32.const 1) - ) - ) - ) - (select - (i32.load offset=20 - (get_local $3) - ) - (i32.shr_u - (get_local $0) - (i32.const 1) - ) - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $3) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store - (get_local $3) - (i64.const 0) - ) - (br_if $label$0 - (i32.ge_u - (tee_local $0 - (call $strlen - (i32.const 2000) - ) - ) - (i32.const -16) - ) - ) - (block $label$5 - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.ge_u - (get_local $0) - (i32.const 11) - ) - ) - (i32.store8 - (get_local $3) - (i32.shl - (get_local $0) - (i32.const 1) - ) - ) - (set_local $2 - (tee_local $1 - (i32.or - (get_local $3) - (i32.const 1) - ) - ) - ) - (br_if $label$6 - (get_local $0) - ) - (br $label$5) - ) - (set_local $2 - (call $_Znwj - (tee_local $1 - (i32.and - (i32.add - (get_local $0) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (get_local $3) - (i32.or - (get_local $1) - (i32.const 1) - ) - ) - (i32.store offset=8 - (get_local $3) - (get_local $2) - ) - (i32.store offset=4 - (get_local $3) - (get_local $0) - ) - (set_local $1 - (i32.or - (get_local $3) - (i32.const 1) - ) - ) - ) - (drop - (call $memcpy - (get_local $2) - (i32.const 2000) - (get_local $0) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $2) - (get_local $0) - ) - (i32.const 0) - ) - (call $prints_l - (select - (i32.load offset=8 - (get_local $3) - ) - (get_local $1) - (tee_local $2 - (i32.and - (tee_local $0 - (i32.load8_u - (get_local $3) - ) - ) - (i32.const 1) - ) - ) - ) - (select - (i32.load offset=4 - (get_local $3) - ) - (i32.shr_u - (get_local $0) - (i32.const 1) - ) - (get_local $2) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.eqz - (i32.and - (i32.load8_u - (get_local $3) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (i32.and - (i32.load8_u offset=16 - (get_local $3) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $3) - (i32.const 24) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 32) - ) - ) - (return) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $3) - ) - (unreachable) - ) - (func $_ZN10test_types10types_sizeEv - (call $eosio_assert - (i32.const 1) - (i32.const 2016) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2048) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2080) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2112) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2144) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2176) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2208) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2240) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2272) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2304) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2320) - ) - ) - (func $_ZN10test_types14char_to_symbolEv - (call $eosio_assert - (i32.const 1) - (i32.const 2352) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2400) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2448) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2496) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2544) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2592) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2640) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2688) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2736) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2784) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2832) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2880) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2928) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 2976) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3024) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3072) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3120) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3168) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3216) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3264) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3312) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3360) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3408) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3456) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3504) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3552) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3600) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3648) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3696) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3744) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 3792) - ) - ) - (func $_ZN10test_types14string_to_nameEv - (local $0 i32) - (local $1 i64) - (local $2 i64) - (local $3 i64) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3840) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i64.eq - (get_local $1) - (i64.const 0) - ) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$1) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$4) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3840) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i64.eq - (get_local $1) - (i64.const 0) - ) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$7) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$10) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 3856) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3888) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (block $label$17 - (br_if $label$17 - (i64.gt_u - (get_local $1) - (i64.const 1) - ) - ) - (br_if $label$16 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$15) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$14 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$13) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$12 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3888) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$18 - (block $label$19 - (block $label$20 - (block $label$21 - (block $label$22 - (block $label$23 - (br_if $label$23 - (i64.gt_u - (get_local $1) - (i64.const 1) - ) - ) - (br_if $label$22 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$21) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$20 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$19) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$18 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 3904) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3936) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$24 - (block $label$25 - (block $label$26 - (block $label$27 - (block $label$28 - (block $label$29 - (br_if $label$29 - (i64.gt_u - (get_local $1) - (i64.const 2) - ) - ) - (br_if $label$28 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$27) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$26 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$25) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$24 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3936) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$30 - (block $label$31 - (block $label$32 - (block $label$33 - (block $label$34 - (block $label$35 - (br_if $label$35 - (i64.gt_u - (get_local $1) - (i64.const 2) - ) - ) - (br_if $label$34 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$33) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$32 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$31) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$30 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 3952) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3984) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$36 - (block $label$37 - (block $label$38 - (block $label$39 - (block $label$40 - (block $label$41 - (br_if $label$41 - (i64.gt_u - (get_local $1) - (i64.const 3) - ) - ) - (br_if $label$40 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$39) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$38 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$37) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$36 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 3984) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$42 - (block $label$43 - (block $label$44 - (block $label$45 - (block $label$46 - (block $label$47 - (br_if $label$47 - (i64.gt_u - (get_local $1) - (i64.const 3) - ) - ) - (br_if $label$46 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$45) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$44 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$43) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$42 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4000) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4032) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$48 - (block $label$49 - (block $label$50 - (block $label$51 - (block $label$52 - (block $label$53 - (br_if $label$53 - (i64.gt_u - (get_local $1) - (i64.const 4) - ) - ) - (br_if $label$52 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$51) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$50 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$49) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$48 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4032) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$54 - (block $label$55 - (block $label$56 - (block $label$57 - (block $label$58 - (block $label$59 - (br_if $label$59 - (i64.gt_u - (get_local $1) - (i64.const 4) - ) - ) - (br_if $label$58 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$57) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$56 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$55) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$54 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4048) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4080) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$60 - (block $label$61 - (block $label$62 - (block $label$63 - (block $label$64 - (block $label$65 - (br_if $label$65 - (i64.gt_u - (get_local $1) - (i64.const 5) - ) - ) - (br_if $label$64 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$63) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$62 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$61) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$60 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4080) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$66 - (block $label$67 - (block $label$68 - (block $label$69 - (block $label$70 - (block $label$71 - (br_if $label$71 - (i64.gt_u - (get_local $1) - (i64.const 5) - ) - ) - (br_if $label$70 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$69) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$68 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$67) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$66 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4096) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4128) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$72 - (block $label$73 - (block $label$74 - (block $label$75 - (block $label$76 - (block $label$77 - (br_if $label$77 - (i64.gt_u - (get_local $1) - (i64.const 6) - ) - ) - (br_if $label$76 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$75) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$74 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$73) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$72 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4128) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$78 - (block $label$79 - (block $label$80 - (block $label$81 - (block $label$82 - (block $label$83 - (br_if $label$83 - (i64.gt_u - (get_local $1) - (i64.const 6) - ) - ) - (br_if $label$82 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$81) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$80 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$79) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$78 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4144) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4176) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$84 - (block $label$85 - (block $label$86 - (block $label$87 - (block $label$88 - (block $label$89 - (br_if $label$89 - (i64.gt_u - (get_local $1) - (i64.const 7) - ) - ) - (br_if $label$88 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$87) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$86 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$85) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$84 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4176) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$90 - (block $label$91 - (block $label$92 - (block $label$93 - (block $label$94 - (block $label$95 - (br_if $label$95 - (i64.gt_u - (get_local $1) - (i64.const 7) - ) - ) - (br_if $label$94 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$93) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$92 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$91) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$90 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4192) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4224) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$96 - (block $label$97 - (block $label$98 - (block $label$99 - (block $label$100 - (block $label$101 - (br_if $label$101 - (i64.gt_u - (get_local $1) - (i64.const 8) - ) - ) - (br_if $label$100 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$99) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$98 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$97) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$96 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4224) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$102 - (block $label$103 - (block $label$104 - (block $label$105 - (block $label$106 - (block $label$107 - (br_if $label$107 - (i64.gt_u - (get_local $1) - (i64.const 8) - ) - ) - (br_if $label$106 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$105) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$104 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$103) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$102 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4240) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4288) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$108 - (block $label$109 - (block $label$110 - (block $label$111 - (block $label$112 - (block $label$113 - (br_if $label$113 - (i64.gt_u - (get_local $1) - (i64.const 9) - ) - ) - (br_if $label$112 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$111) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$110 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$109) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$108 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4288) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$114 - (block $label$115 - (block $label$116 - (block $label$117 - (block $label$118 - (block $label$119 - (br_if $label$119 - (i64.gt_u - (get_local $1) - (i64.const 9) - ) - ) - (br_if $label$118 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$117) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$116 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$115) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$114 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4304) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4352) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$120 - (block $label$121 - (block $label$122 - (block $label$123 - (block $label$124 - (block $label$125 - (br_if $label$125 - (i64.gt_u - (get_local $1) - (i64.const 10) - ) - ) - (br_if $label$124 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$123) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$122 - (i64.eq - (get_local $1) - (i64.const 11) - ) - ) - (br $label$121) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$120 - (i64.ne - (tee_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (i64.const 13) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4352) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$126 - (block $label$127 - (block $label$128 - (block $label$129 - (block $label$130 - (block $label$131 - (br_if $label$131 - (i64.gt_u - (get_local $1) - (i64.const 10) - ) - ) - (br_if $label$130 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$129) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$128 - (i64.eq - (get_local $1) - (i64.const 11) - ) - ) - (br $label$127) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$126 - (i64.ne - (tee_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (i64.const 13) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4368) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $4 - (i32.const 4416) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$132 - (set_local $5 - (i64.const 0) - ) - (block $label$133 - (br_if $label$133 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (block $label$134 - (block $label$135 - (br_if $label$135 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$134) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.extend_u/i32 - (i32.and - (get_local $0) - (i32.const 31) - ) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $5) - (get_local $2) - ) - ) - (br_if $label$132 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $4 - (i32.const 4416) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$136 - (set_local $5 - (i64.const 0) - ) - (block $label$137 - (br_if $label$137 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (block $label$138 - (block $label$139 - (br_if $label$139 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$138) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.extend_u/i32 - (i32.and - (get_local $0) - (i32.const 31) - ) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $5) - (get_local $3) - ) - ) - (br_if $label$136 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4432) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4480) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$140 - (set_local $6 - (i64.const 0) - ) - (block $label$141 - (block $label$142 - (br_if $label$142 - (i64.gt_u - (get_local $1) - (i64.const 12) - ) - ) - (block $label$143 - (block $label$144 - (br_if $label$144 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$143) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$142 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$141) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$140 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4480) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$145 - (set_local $6 - (i64.const 0) - ) - (block $label$146 - (block $label$147 - (br_if $label$147 - (i64.gt_u - (get_local $1) - (i64.const 12) - ) - ) - (block $label$148 - (block $label$149 - (br_if $label$149 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$148) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$147 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$146) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$145 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4496) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4544) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$150 - (set_local $6 - (i64.const 0) - ) - (block $label$151 - (block $label$152 - (br_if $label$152 - (i64.gt_u - (get_local $1) - (i64.const 13) - ) - ) - (block $label$153 - (block $label$154 - (br_if $label$154 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$153) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$152 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$151) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$150 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4560) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$155 - (set_local $6 - (i64.const 0) - ) - (block $label$156 - (block $label$157 - (br_if $label$157 - (i64.gt_u - (get_local $1) - (i64.const 13) - ) - ) - (block $label$158 - (block $label$159 - (br_if $label$159 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$158) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$157 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$156) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$155 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4576) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4624) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$160 - (set_local $6 - (i64.const 0) - ) - (block $label$161 - (block $label$162 - (br_if $label$162 - (i64.gt_u - (get_local $1) - (i64.const 14) - ) - ) - (block $label$163 - (block $label$164 - (br_if $label$164 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$163) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$162 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$161) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$160 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4640) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$165 - (set_local $6 - (i64.const 0) - ) - (block $label$166 - (block $label$167 - (br_if $label$167 - (i64.gt_u - (get_local $1) - (i64.const 14) - ) - ) - (block $label$168 - (block $label$169 - (br_if $label$169 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$168) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$167 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$166) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$165 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4656) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4704) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$170 - (block $label$171 - (block $label$172 - (block $label$173 - (block $label$174 - (block $label$175 - (br_if $label$175 - (i64.gt_u - (get_local $1) - (i64.const 5) - ) - ) - (br_if $label$174 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$173) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$172 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$171) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$170 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4720) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$176 - (block $label$177 - (block $label$178 - (block $label$179 - (block $label$180 - (block $label$181 - (br_if $label$181 - (i64.gt_u - (get_local $1) - (i64.const 5) - ) - ) - (br_if $label$180 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$179) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$178 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$177) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$176 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4736) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4768) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$182 - (block $label$183 - (block $label$184 - (block $label$185 - (block $label$186 - (block $label$187 - (br_if $label$187 - (i64.gt_u - (get_local $1) - (i64.const 9) - ) - ) - (br_if $label$186 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$185) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$184 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$183) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$182 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4768) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$188 - (block $label$189 - (block $label$190 - (block $label$191 - (block $label$192 - (block $label$193 - (br_if $label$193 - (i64.gt_u - (get_local $1) - (i64.const 9) - ) - ) - (br_if $label$192 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$191) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$190 - (i64.le_u - (get_local $1) - (i64.const 11) - ) - ) - (br $label$189) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$188 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4784) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4832) - ) - (set_local $2 - (i64.const 0) - ) - (loop $label$194 - (set_local $6 - (i64.const 0) - ) - (block $label$195 - (block $label$196 - (br_if $label$196 - (i64.gt_u - (get_local $1) - (i64.const 14) - ) - ) - (block $label$197 - (block $label$198 - (br_if $label$198 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$197) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$196 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$195) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $2 - (i64.or - (get_local $6) - (get_local $2) - ) - ) - (br_if $label$194 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $1 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 4848) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$199 - (set_local $6 - (i64.const 0) - ) - (block $label$200 - (block $label$201 - (br_if $label$201 - (i64.gt_u - (get_local $1) - (i64.const 22) - ) - ) - (block $label$202 - (block $label$203 - (br_if $label$203 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$202) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$201 - (i64.gt_u - (get_local $1) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - (br $label$200) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $1 - (i64.add - (get_local $1) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$199 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $2) - (get_local $3) - ) - (i32.const 4880) - ) - ) - (func $_ZN10test_types10name_classEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 4704) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 5) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $4) - (i64.const 4017212585601400832) - ) - (i32.const 4928) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 4960) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 4992) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $3) - (i64.const 3) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $4) - (i64.const 580542139465728) - ) - (i32.const 5008) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 5040) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (block $label$17 - (br_if $label$17 - (i64.gt_u - (get_local $3) - (i64.const 1) - ) - ) - (br_if $label$16 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$15) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$14 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$13) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$12 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $4) - (i64.const 594475150812905472) - ) - (i32.const 5056) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 5088) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$18 - (block $label$19 - (block $label$20 - (block $label$21 - (block $label$22 - (block $label$23 - (br_if $label$23 - (i64.gt_u - (get_local $3) - (i64.const 1) - ) - ) - (br_if $label$22 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$21) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$20 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$19) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$18 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $4) - (i64.const 1188950301625810944) - ) - (i32.const 5104) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 5136) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$24 - (block $label$25 - (block $label$26 - (block $label$27 - (block $label$28 - (block $label$29 - (br_if $label$29 - (i64.gt_u - (get_local $3) - (i64.const 9) - ) - ) - (br_if $label$28 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$27) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$26 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$25) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$24 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 5136) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$30 - (block $label$31 - (block $label$32 - (block $label$33 - (block $label$34 - (block $label$35 - (br_if $label$35 - (i64.gt_u - (get_local $3) - (i64.const 9) - ) - ) - (br_if $label$34 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$33) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$32 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$31) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $5) - (get_local $6) - ) - ) - (br_if $label$30 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $4) - (get_local $6) - ) - (i32.const 5152) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 5184) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$36 - (block $label$37 - (block $label$38 - (block $label$39 - (block $label$40 - (block $label$41 - (br_if $label$41 - (i64.gt_u - (get_local $3) - (i64.const 8) - ) - ) - (br_if $label$40 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$39) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$38 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$37) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$36 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 5184) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$42 - (block $label$43 - (block $label$44 - (block $label$45 - (block $label$46 - (block $label$47 - (br_if $label$47 - (i64.gt_u - (get_local $3) - (i64.const 8) - ) - ) - (br_if $label$46 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$45) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$44 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$43) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $5) - (get_local $6) - ) - ) - (br_if $label$42 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $6) - (get_local $4) - ) - (i32.const 5200) - ) - ) - (func $_ZN15test_fixedpoint16create_instancesEv - (call $eosio_assert - (i32.const 1) - (i32.const 5232) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5312) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5376) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5440) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5504) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5568) - ) - ) - (func $_ZN15test_fixedpoint13test_additionEv - (call $eosio_assert - (i32.const 1) - (i32.const 5632) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5696) - ) - ) - (func $_ZN15test_fixedpoint16test_subtractionEv - (call $eosio_assert - (i32.const 1) - (i32.const 5760) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5760) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5824) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5824) - ) - ) - (func $_ZN15test_fixedpoint19test_multiplicationEv - (call $eosio_assert - (i32.const 1) - (i32.const 5888) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5952) - ) - ) - (func $_ZN15test_fixedpoint13test_divisionEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6016) - ) - (i64.store offset=24 - (get_local $0) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $0) - (i64.const 30030) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 128977867898880) - ) - (call $printui128 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (call $prints - (i32.const 6032) - ) - (call $printui128 - (get_local $0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6048) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 6048) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN15test_fixedpoint18test_division_by_0Ev - (call $eosio_assert - (i32.const 0) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6160) - ) - ) - (func $_Zli5_ULLLPKc (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $1 - (i32.load8_u - (tee_local $6 - (i32.add - (get_local $1) - (select - (select - (i32.const 2) - (i32.const 1) - (tee_local $2 - (i32.eq - (i32.load8_u - (get_local $1) - ) - (i32.const 45) - ) - ) - ) - (get_local $2) - (i32.eq - (i32.load8_u - (i32.add - (get_local $1) - (get_local $2) - ) - ) - (i32.const 43) - ) - ) - ) - ) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (set_local $5 - (i32.add - (get_local $8) - (i32.const 8) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$2 - (call $__multi3 - (get_local $8) - (get_local $7) - (get_local $3) - (i64.const 10) - (i64.const 0) - ) - (set_local $3 - (i64.add - (i64.add - (i64.shr_s - (tee_local $3 - (i64.extend_s/i32 - (i32.add - (i32.shr_s - (i32.shl - (get_local $1) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const -48) - ) - ) - ) - (i64.const 63) - ) - (i64.load - (get_local $5) - ) - ) - (select - (i64.const 1) - (i64.extend_u/i32 - (i64.lt_u - (tee_local $7 - (i64.add - (get_local $3) - (tee_local $4 - (i64.load - (get_local $8) - ) - ) - ) - ) - (get_local $3) - ) - ) - (i64.lt_u - (get_local $7) - (get_local $4) - ) - ) - ) - ) - (set_local $1 - (i32.load8_u - (get_local $6) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (get_local $1) - ) - (br $label$0) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $3 - (i64.const 0) - ) - ) - (i64.store - (get_local $0) - (select - (i64.sub - (i64.const 0) - (get_local $7) - ) - (get_local $7) - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (select - (i64.sub - (i64.sub - (i64.const 0) - (get_local $3) - ) - (i64.extend_u/i32 - (i64.ne - (get_local $7) - (i64.const 0) - ) - ) - ) - (get_local $3) - (get_local $2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - (func $_Zli4_LLLPKc (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $1 - (i32.load8_u - (tee_local $6 - (i32.add - (get_local $1) - (select - (select - (i32.const 2) - (i32.const 1) - (tee_local $2 - (i32.eq - (i32.load8_u - (get_local $1) - ) - (i32.const 45) - ) - ) - ) - (get_local $2) - (i32.eq - (i32.load8_u - (i32.add - (get_local $1) - (get_local $2) - ) - ) - (i32.const 43) - ) - ) - ) - ) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (set_local $5 - (i32.add - (get_local $8) - (i32.const 8) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$2 - (call $__multi3 - (get_local $8) - (get_local $7) - (get_local $3) - (i64.const 10) - (i64.const 0) - ) - (set_local $3 - (i64.add - (i64.add - (i64.shr_s - (tee_local $3 - (i64.extend_s/i32 - (i32.add - (i32.shr_s - (i32.shl - (get_local $1) - (i32.const 24) - ) - (i32.const 24) - ) - (i32.const -48) - ) - ) - ) - (i64.const 63) - ) - (i64.load - (get_local $5) - ) - ) - (select - (i64.const 1) - (i64.extend_u/i32 - (i64.lt_u - (tee_local $7 - (i64.add - (get_local $3) - (tee_local $4 - (i64.load - (get_local $8) - ) - ) - ) - ) - (get_local $3) - ) - ) - (i64.lt_u - (get_local $7) - (get_local $4) - ) - ) - ) - ) - (set_local $1 - (i32.load8_u - (get_local $6) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (get_local $1) - ) - (br $label$0) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $3 - (i64.const 0) - ) - ) - (i64.store - (get_local $0) - (select - (i64.sub - (i64.const 0) - (get_local $7) - ) - (get_local $7) - (get_local $2) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (select - (i64.sub - (i64.sub - (i64.const 0) - (get_local $3) - ) - (i64.extend_u/i32 - (i64.ne - (get_local $7) - (i64.const 0) - ) - ) - ) - (get_local $3) - (get_local $2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins11test_multi3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__multi3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -3000) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 6192) - ) - (call $__multi3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const -30) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -3000) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 6192) - ) - (call $__multi3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const -30) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 900) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6224) - ) - (call $__multi3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 10000) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6256) - ) - (call $__multi3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 100) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6288) - ) - (call $__multi3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i64.const -30) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -30) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 6320) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins11test_divti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__divti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6352) - ) - (call $__divti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const -30) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -3) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 6384) - ) - (call $__divti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const -30) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 1) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6416) - ) - (call $__divti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 1) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6416) - ) - (call $__divti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 3333) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6352) - ) - (call $__divti3 - (get_local $0) - (i64.const 3333) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 33) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6448) - ) - (call $__divti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 1) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 100) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6480) - ) - (call $__divti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const 1) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -30) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 6512) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins16test_divti3_by_0Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__divti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6544) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins12test_udivti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__udivti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 2951479051793528258) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const 184467440737095516) - ) - ) - ) - (i32.const 6576) - ) - (call $__udivti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const -30) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6576) - ) - (call $__udivti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const -30) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 1) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6608) - ) - (call $__udivti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 1) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6416) - ) - (call $__udivti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 3333) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6352) - ) - (call $__udivti3 - (get_local $0) - (i64.const 3333) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 33) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6448) - ) - (call $__udivti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 1) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 100) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6480) - ) - (call $__udivti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const 1) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -30) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 6512) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins17test_udivti3_by_0Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__udivti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6544) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins12test_lshlti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__lshlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 1) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6640) - ) - (call $__lshlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 2) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6672) - ) - (call $__lshlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 31) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 2147483648) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6704) - ) - (call $__lshlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 63) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6736) - ) - (call $__lshlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 64) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const 1) - ) - ) - ) - (i32.const 6768) - ) - (call $__lshlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 127) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - ) - ) - (i32.const 6800) - ) - (call $__lshlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 128) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6848) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins12test_ashlti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__ashlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 1) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6896) - ) - (call $__ashlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 2) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6928) - ) - (call $__ashlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 31) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 2147483648) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6960) - ) - (call $__ashlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 63) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 6992) - ) - (call $__ashlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 64) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const 1) - ) - ) - ) - (i32.const 7024) - ) - (call $__ashlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 127) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - ) - ) - (i32.const 7056) - ) - (call $__ashlti3 - (get_local $0) - (i64.const 1) - (i64.const 0) - (i32.const 128) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7104) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins12test_lshrti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__lshrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - ) - ) - (i32.const 7152) - ) - (call $__lshrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const 4611686018427387904) - ) - ) - ) - (i32.const 7200) - ) - (call $__lshrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 63) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const 1) - ) - ) - ) - (i32.const 7248) - ) - (call $__lshrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 64) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7280) - ) - (call $__lshrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 96) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 2147483648) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7312) - ) - (call $__lshrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 127) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 1) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7344) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins12test_ashrti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__ashrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - ) - ) - (i32.const 7376) - ) - (call $__ashrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -4611686018427387904) - ) - ) - ) - (i32.const 7424) - ) - (call $__ashrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 2) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -2305843009213693952) - ) - ) - ) - (i32.const 7472) - ) - (call $__ashrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 64) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -9223372036854775808) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 7520) - ) - (call $__ashrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 95) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -4294967296) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 7568) - ) - (call $__ashrti3 - (get_local $0) - (i64.const 0) - (i64.const -9223372036854775808) - (i32.const 127) - ) - (call $eosio_assert - (i64.eq - (i64.and - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - (i64.const -1) - ) - (i32.const 7616) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins11test_modti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__modti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -30) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 7648) - ) - (call $__modti3 - (get_local $0) - (i64.const 30) - (i64.const 0) - (i64.const -100) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 30) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7680) - ) - (call $__modti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const -100) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -30) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 7648) - ) - (call $__modti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 30) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 10) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7712) - ) - (call $__modti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const -100) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7744) - ) - (call $__modti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7744) - ) - (call $__modti3 - (get_local $0) - (i64.const 0) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7744) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins16test_modti3_by_0Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__modti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7776) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins12test_umodti3Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__umodti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -30) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 7648) - ) - (call $__umodti3 - (get_local $0) - (i64.const 30) - (i64.const 0) - (i64.const -100) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 30) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7680) - ) - (call $__umodti3 - (get_local $0) - (i64.const -30) - (i64.const -1) - (i64.const -100) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const -30) - ) - (i64.xor - (i64.load offset=8 - (get_local $0) - ) - (i64.const -1) - ) - ) - ) - (i32.const 7648) - ) - (call $__umodti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 30) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.xor - (i64.load - (get_local $0) - ) - (i64.const 10) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7712) - ) - (call $__umodti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const -100) - (i64.const -1) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7744) - ) - (call $__umodti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7744) - ) - (call $__umodti3 - (get_local $0) - (i64.const 0) - (i64.const 0) - (i64.const 100) - (i64.const 0) - ) - (call $eosio_assert - (i64.eqz - (i64.or - (i64.load - (get_local $0) - ) - (i64.load offset=8 - (get_local $0) - ) - ) - ) - (i32.const 7744) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN22test_compiler_builtins17test_umodti3_by_0Ev - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 0) - ) - (call $__umodti3 - (get_local $0) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7776) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $my_strlen (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (set_local $3 - (i32.const -1) - ) - (loop $label$0 - (set_local $2 - (i32.add - (get_local $0) - (get_local $3) - ) - ) - (set_local $3 - (tee_local $1 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (i32.load8_u - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - ) - ) - (get_local $1) - ) - (func $my_memcmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (get_local $2) - ) - ) - (set_local $3 - (i32.const 0) - ) - (loop $label$2 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (get_local $3) - ) - ) - (i32.load8_u - (i32.add - (get_local $1) - (get_local $3) - ) - ) - ) - ) - (br_if $label$2 - (i32.lt_u - (tee_local $3 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - (get_local $2) - ) - ) - ) - (return - (i32.const 1) - ) - ) - (return - (i32.const 1) - ) - ) - (i32.const 0) - ) - (func $_ZN11test_crypto28test_recover_key_assert_trueEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 144) - ) - ) - ) - (drop - (call $read_action_data - (get_local $0) - (i32.const 144) - ) - ) - (call $assert_recover_key - (get_local $0) - (i32.add - (get_local $0) - (i32.const 66) - ) - (i32.const 66) - (i32.add - (get_local $0) - (i32.const 32) - ) - (i32.const 34) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 144) - ) - ) - ) - (func $_ZN11test_crypto29test_recover_key_assert_falseEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 144) - ) - ) - ) - (drop - (call $read_action_data - (get_local $0) - (i32.const 144) - ) - ) - (call $assert_recover_key - (get_local $0) - (i32.add - (get_local $0) - (i32.const 66) - ) - (i32.const 66) - (i32.add - (get_local $0) - (i32.const 32) - ) - (i32.const 34) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7776) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 144) - ) - ) - ) - (func $_ZN11test_crypto16test_recover_keyEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 192) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $2) - (i32.const 48) - ) - (i32.const 144) - ) - ) - (drop - (call $recover_key - (i32.add - (get_local $2) - (i32.const 48) - ) - (i32.add - (i32.add - (get_local $2) - (i32.const 48) - ) - (i32.const 66) - ) - (i32.const 66) - (i32.add - (get_local $2) - (i32.const 8) - ) - (i32.const 34) - ) - ) - (set_local $0 - (i32.add - (get_local $2) - (i32.const 80) - ) - ) - (set_local $1 - (i32.const 0) - ) - (loop $label$0 - (block $label$1 - (br_if $label$1 - (i32.eq - (i32.load8_u - (i32.add - (i32.add - (get_local $2) - (i32.const 8) - ) - (get_local $1) - ) - ) - (i32.load8_u - (i32.add - (get_local $0) - (get_local $1) - ) - ) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7808) - ) - ) - (br_if $label$0 - (i32.ne - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (i32.const 34) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 192) - ) - ) - ) - (func $_ZN11test_crypto9test_sha1Ev - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha1 - (i32.const 7840) - (i32.const 3) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 7856) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 7888) - ) - (call $sha1 - (i32.const 7904) - (i32.const 56) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$2 - (loop $label$3 - (br_if $label$2 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 7968) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$3 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8000) - ) - (call $sha1 - (i32.const 8016) - (i32.const 112) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$4 - (loop $label$5 - (br_if $label$4 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8144) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$5 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8176) - ) - (call $sha1 - (i32.const 8192) - (i32.const 14) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8208) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$7 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8240) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto11test_sha256Ev - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha256 - (i32.const 7840) - (i32.const 3) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8256) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8288) - ) - (call $sha256 - (i32.const 7904) - (i32.const 56) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$2 - (loop $label$3 - (br_if $label$2 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8304) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$3 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8336) - ) - (call $sha256 - (i32.const 8016) - (i32.const 112) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$4 - (loop $label$5 - (br_if $label$4 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8352) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$5 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8384) - ) - (call $sha256 - (i32.const 8192) - (i32.const 14) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8400) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$7 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8432) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto11test_sha512Ev - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $sha512 - (i32.const 7840) - (i32.const 3) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8448) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 63) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8512) - ) - (call $sha512 - (i32.const 7904) - (i32.const 56) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$2 - (loop $label$3 - (br_if $label$2 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8528) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$3 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 63) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8592) - ) - (call $sha512 - (i32.const 8016) - (i32.const 112) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$4 - (loop $label$5 - (br_if $label$4 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8608) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$5 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 63) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8672) - ) - (call $sha512 - (i32.const 8192) - (i32.const 14) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8688) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$7 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 63) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8752) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 64) - ) - ) - ) - (func $_ZN11test_crypto14test_ripemd160Ev - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $ripemd160 - (i32.const 7840) - (i32.const 3) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8768) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8800) - ) - (call $ripemd160 - (i32.const 7904) - (i32.const 56) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$2 - (loop $label$3 - (br_if $label$2 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8816) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$3 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8848) - ) - (call $ripemd160 - (i32.const 8016) - (i32.const 112) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$4 - (loop $label$5 - (br_if $label$4 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8864) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$5 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8896) - ) - (call $ripemd160 - (i32.const 8192) - (i32.const 14) - (get_local $2) - ) - (set_local $1 - (i32.const 0) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$6 - (loop $label$7 - (br_if $label$6 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8912) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$7 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 8944) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto11sha256_nullEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha256 - (i32.const 0) - (i32.const 100) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto12sha1_no_dataEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (set_local $1 - (i32.const 0) - ) - (call $sha1 - (i32.const 8960) - (i32.const 0) - (get_local $2) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 8976) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 9008) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto14sha256_no_dataEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (set_local $1 - (i32.const 0) - ) - (call $sha256 - (i32.const 8960) - (i32.const 0) - (get_local $2) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 9024) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 9056) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto14sha512_no_dataEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (set_local $1 - (i32.const 0) - ) - (call $sha512 - (i32.const 8960) - (i32.const 0) - (get_local $2) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 9072) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 63) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 9136) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 64) - ) - ) - ) - (func $_ZN11test_crypto17ripemd160_no_dataEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (set_local $1 - (i32.const 0) - ) - (call $ripemd160 - (i32.const 8960) - (i32.const 0) - (get_local $2) - ) - (set_local $0 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (br_if $label$0 - (i32.ne - (i32.load8_u - (i32.add - (get_local $0) - (i32.const 9152) - ) - ) - (i32.load8_u - (i32.add - (get_local $2) - (get_local $0) - ) - ) - ) - ) - (br_if $label$1 - (i32.le_u - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $1 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $1) - (i32.const 9184) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $2) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto19assert_sha256_falseEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha256 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (i32.store8 - (get_local $0) - (i32.xor - (i32.load8_u - (get_local $0) - ) - (i32.const -1) - ) - ) - (call $assert_sha256 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto18assert_sha256_trueEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha256 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $assert_sha256 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $sha256 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $assert_sha256 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $sha256 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $assert_sha256 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $sha256 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (call $assert_sha256 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto17assert_sha1_falseEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha1 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (i32.store8 - (get_local $0) - (i32.xor - (i32.load8_u - (get_local $0) - ) - (i32.const -1) - ) - ) - (call $assert_sha1 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto16assert_sha1_trueEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha1 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $assert_sha1 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $sha1 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $assert_sha1 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $sha1 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $assert_sha1 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $sha1 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (call $assert_sha1 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto19assert_sha512_falseEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $sha512 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (i32.store8 - (get_local $0) - (i32.xor - (i32.load8_u - (get_local $0) - ) - (i32.const -1) - ) - ) - (call $assert_sha512 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - (func $_ZN11test_crypto18assert_sha512_trueEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $sha512 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $assert_sha512 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $sha512 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $assert_sha512 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $sha512 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $assert_sha512 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $sha512 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (call $assert_sha512 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - (func $_ZN11test_crypto22assert_ripemd160_falseEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $ripemd160 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (i32.store8 - (get_local $0) - (i32.xor - (i32.load8_u - (get_local $0) - ) - (i32.const -1) - ) - ) - (call $assert_ripemd160 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN11test_crypto21assert_ripemd160_trueEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $ripemd160 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $assert_ripemd160 - (i32.const 7840) - (i32.const 3) - (get_local $0) - ) - (call $ripemd160 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $assert_ripemd160 - (i32.const 7904) - (i32.const 56) - (get_local $0) - ) - (call $ripemd160 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $assert_ripemd160 - (i32.const 8016) - (i32.const 112) - (get_local $0) - ) - (call $ripemd160 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (call $assert_ripemd160 - (i32.const 8192) - (i32.const 14) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN10test_chain16test_activeprodsEv - (local $0 i32) - (local $1 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $1 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 352) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $1) - (i32.const 176) - ) - (i32.const 169) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load8_u offset=176 - (get_local $1) - ) - (i32.const 21) - ) - (i32.const 9232) - ) - (set_local $0 - (i32.const 1) - ) - (drop - (call $get_active_producers - (i32.or - (get_local $1) - (i32.const 1) - ) - (i32.const 168) - ) - ) - (loop $label$0 - (call $eosio_assert - (i64.eq - (i64.load align=1 - (i32.add - (get_local $1) - (get_local $0) - ) - ) - (i64.load align=1 - (i32.add - (i32.add - (get_local $1) - (i32.const 176) - ) - (get_local $0) - ) - ) - ) - (i32.const 9264) - ) - (br_if $label$0 - (i32.ne - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (i32.const 169) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $1) - (i32.const 352) - ) - ) - ) - (func $_Z9copy_dataPcjRNSt3__16vectorIcNS0_9allocatorIcEEEE (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (set_local $4 - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - (loop $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (tee_local $3 - (i32.load - (get_local $5) - ) - ) - (i32.load - (get_local $4) - ) - ) - ) - (i32.store8 - (get_local $3) - (i32.load8_u - (get_local $0) - ) - ) - (i32.store - (get_local $5) - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - (br $label$2) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (get_local $2) - (get_local $0) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (br_if $label$1 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - ) - ) - ) - (func $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.le_s - (tee_local $7 - (i32.add - (tee_local $3 - (i32.sub - (tee_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (tee_local $4 - (i32.load - (get_local $0) - ) - ) - ) - ) - (i32.const 1) - ) - ) - (i32.const -1) - ) - ) - (set_local $6 - (i32.const 2147483647) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $2 - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $4) - ) - ) - (i32.const 1073741822) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $6 - (select - (get_local $7) - (tee_local $6 - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $6) - (get_local $7) - ) - ) - ) - ) - ) - ) - (set_local $7 - (call $_Znwj - (get_local $6) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $4 - (i32.load - (get_local $0) - ) - ) - (br $label$0) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $7 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (i32.store8 - (tee_local $3 - (i32.add - (get_local $7) - (get_local $3) - ) - ) - (i32.load8_u - (get_local $1) - ) - ) - (set_local $1 - (i32.sub - (get_local $3) - (tee_local $5 - (i32.sub - (get_local $5) - (get_local $4) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (get_local $6) - ) - ) - (set_local $7 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - (block $label$4 - (br_if $label$4 - (i32.lt_s - (get_local $5) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $1) - (get_local $4) - (get_local $5) - ) - ) - (set_local $4 - (i32.load - (get_local $0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $7) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $6) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (get_local $4) - ) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - ) - (func $_ZN16test_transaction11send_actionEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 96) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $7) - (i32.const 92) - ) - (i32.load8_u offset=9292 - (i32.const 0) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 88) - ) - (i32.load offset=9288 align=1 - (i32.const 0) - ) - ) - (i64.store offset=80 - (get_local $7) - (i64.load offset=9280 align=1 - (i32.const 0) - ) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 368) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 416) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $3) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $5) - (get_local $6) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 - (get_local $7) - (get_local $6) - ) - (i64.store offset=8 - (get_local $7) - (get_local $4) - ) - (i32.store - (i32.add - (tee_local $1 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.load offset=12 - (get_local $7) - ) - ) - (i32.store offset=24 - (get_local $7) - (get_local $1) - ) - (i32.store - (get_local $1) - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.store offset=32 - (get_local $7) - (tee_local $0 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=16 - (get_local $7) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (set_local $1 - (call $_ZN5eosio6actionC2I17test_dummy_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (i32.add - (get_local $7) - (i32.const 40) - ) - (i32.add - (get_local $7) - (i32.const 24) - ) - (i32.add - (get_local $7) - (i32.const 80) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $0 - (i32.load offset=24 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $7) - (i32.const 8) - ) - (get_local $1) - ) - (call $send_inline - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $7) - ) - (get_local $0) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $0 - (i32.load offset=28 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 32) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (tee_local $0 - (i32.load offset=16 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 20) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 96) - ) - ) - ) - (func $_ZN5eosio6actionC2I17test_dummy_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $5 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -3841127010667593728) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -8665432478272688454) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $4) - (i32.load offset=8 - (get_local $1) - ) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $5) - (i32.const 0) - ) - (i64.store - (get_local $5) - (i64.const 0) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $5) - (i32.const 13) - ) - (call $eosio_assert - (i32.gt_s - (tee_local $4 - (i32.sub - (i32.load offset=4 - (get_local $5) - ) - (tee_local $1 - (i32.load - (get_local $5) - ) - ) - ) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $1) - (get_local $2) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.add - (get_local $4) - (i32.const -1) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 1) - ) - (i32.add - (get_local $2) - (i32.const 1) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.add - (get_local $4) - (i32.const -9) - ) - (i32.const 3) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 9) - ) - (i32.add - (get_local $2) - (i32.const 9) - ) - (i32.const 4) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $1 - (i32.load offset=28 - (get_local $0) - ) - ) - ) - ) - (i32.store - (get_local $3) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 28) - ) - (i64.const 0) - ) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 28) - ) - (i64.load - (get_local $5) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction17send_action_emptyEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 96) - ) - ) - ) - (i32.store offset=88 - (get_local $7) - (i32.const 0) - ) - (set_local $3 - (i64.const 0) - ) - (i64.store offset=80 - (get_local $7) - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 368) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 416) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $3) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $5) - (get_local $6) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 - (get_local $7) - (get_local $6) - ) - (i64.store offset=8 - (get_local $7) - (get_local $4) - ) - (i32.store - (i32.add - (tee_local $1 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.load offset=12 - (get_local $7) - ) - ) - (i32.store offset=24 - (get_local $7) - (get_local $1) - ) - (i32.store - (get_local $1) - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.store offset=32 - (get_local $7) - (tee_local $0 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=16 - (get_local $7) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (set_local $1 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311596421349198EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (i32.add - (get_local $7) - (i32.const 40) - ) - (i32.add - (get_local $7) - (i32.const 24) - ) - (i32.add - (get_local $7) - (i32.const 80) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $0 - (i32.load offset=24 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $7) - (i32.const 8) - ) - (get_local $1) - ) - (call $send_inline - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $7) - ) - (get_local $0) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $0 - (i32.load offset=28 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 32) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (tee_local $0 - (i32.load offset=16 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 20) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (tee_local $1 - (i32.load offset=80 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $7) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 96) - ) - ) - ) - (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311596421349198EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -3841127010667593728) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -8665432477288202418) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $6) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $7) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $1 - (i32.load - (get_local $2) - ) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.sub - (get_local $4) - (get_local $1) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $3) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $2) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $1) - (get_local $4) - ) - ) - (loop $label$2 - (i32.store8 offset=15 - (get_local $7) - (i32.load8_u - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $5) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $6) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - ) - (i64.store align=4 - (get_local $6) - (i64.load - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction17send_action_largeEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 96) - ) - ) - ) - (set_local $2 - (i32.const 0) - ) - (i32.store offset=88 - (get_local $10) - (i32.const 0) - ) - (i64.store offset=80 - (get_local $10) - (i64.const 0) - ) - (set_local $1 - (i32.add - (get_local $10) - (i32.const 88) - ) - ) - (set_local $3 - (i32.const 0) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (set_local $0 - (i32.add - (get_local $4) - (i32.const 9296) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $3) - (get_local $2) - ) - ) - (i32.store8 - (get_local $3) - (i32.load8_u - (get_local $0) - ) - ) - (i32.store offset=84 - (get_local $10) - (i32.add - (i32.load offset=84 - (get_local $10) - ) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (i32.const 8191) - ) - ) - (br $label$0) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $10) - (i32.const 80) - ) - (get_local $0) - ) - (br_if $label$0 - (i32.eq - (get_local $4) - (i32.const 8191) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $2 - (i32.load - (get_local $1) - ) - ) - (set_local $3 - (i32.load offset=84 - (get_local $10) - ) - ) - (br $label$1) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 368) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i64.gt_u - (get_local $6) - (i64.const 6) - ) - ) - (br_if $label$8 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$7) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$6 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$5) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$4 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 416) - ) - (set_local $9 - (i64.const 0) - ) - (loop $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_if $label$15 - (i64.gt_u - (get_local $6) - (i64.const 5) - ) - ) - (br_if $label$14 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$13) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$12 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$11) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $9 - (i64.or - (get_local $8) - (get_local $9) - ) - ) - (br_if $label$10 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 - (get_local $10) - (get_local $9) - ) - (i64.store offset=8 - (get_local $10) - (get_local $7) - ) - (i32.store - (i32.add - (tee_local $4 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $10) - (i32.const 8) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 4) - ) - (i32.load offset=12 - (get_local $10) - ) - ) - (i32.store offset=24 - (get_local $10) - (get_local $4) - ) - (i32.store - (get_local $4) - (i32.load offset=8 - (get_local $10) - ) - ) - (i32.store offset=32 - (get_local $10) - (tee_local $3 - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 8) - ) - (i32.load offset=16 - (get_local $10) - ) - ) - (i32.store offset=28 - (get_local $10) - (get_local $3) - ) - (set_local $4 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (i32.add - (get_local $10) - (i32.const 40) - ) - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.add - (get_local $10) - (i32.const 80) - ) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (tee_local $3 - (i32.load offset=24 - (get_local $10) - ) - ) - ) - ) - (i32.store offset=28 - (get_local $10) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $10) - (i32.const 8) - ) - (get_local $4) - ) - (call $send_inline - (tee_local $3 - (i32.load offset=8 - (get_local $10) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $10) - ) - (get_local $3) - ) - ) - (block $label$17 - (br_if $label$17 - (i32.eqz - (tee_local $3 - (i32.load offset=8 - (get_local $10) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $10) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 17488) - ) - (block $label$18 - (br_if $label$18 - (i32.eqz - (tee_local $3 - (i32.load offset=28 - (get_local $4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 32) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (block $label$19 - (br_if $label$19 - (i32.eqz - (tee_local $3 - (i32.load offset=16 - (get_local $4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 20) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (block $label$20 - (br_if $label$20 - (i32.eqz - (tee_local $4 - (i32.load offset=80 - (get_local $10) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $10) - (get_local $4) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 96) - ) - ) - ) - (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -3841127010667593728) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -8665432478272688454) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $6) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $7) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $1 - (i32.load - (get_local $2) - ) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.sub - (get_local $4) - (get_local $1) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $3) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $2) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $1) - (get_local $4) - ) - ) - (loop $label$2 - (i32.store8 offset=15 - (get_local $7) - (i32.load8_u - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $5) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $6) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - ) - (i64.store align=4 - (get_local $6) - (i64.load - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction19send_action_recurseEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 1120) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 96) - ) - (i32.const 1024) - ) - ) - (set_local $2 - (i32.const 0) - ) - (i32.store offset=88 - (get_local $10) - (i32.const 0) - ) - (i64.store offset=80 - (get_local $10) - (i64.const 0) - ) - (set_local $1 - (i32.add - (get_local $10) - (i32.const 88) - ) - ) - (set_local $3 - (i32.const 0) - ) - (set_local $4 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (set_local $0 - (i32.add - (i32.add - (get_local $10) - (i32.const 96) - ) - (get_local $4) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $3) - (get_local $2) - ) - ) - (i32.store8 - (get_local $3) - (i32.load8_u - (get_local $0) - ) - ) - (i32.store offset=84 - (get_local $10) - (i32.add - (i32.load offset=84 - (get_local $10) - ) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (i32.const 1023) - ) - ) - (br $label$0) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $10) - (i32.const 80) - ) - (get_local $0) - ) - (br_if $label$0 - (i32.eq - (get_local $4) - (i32.const 1023) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $2 - (i32.load - (get_local $1) - ) - ) - (set_local $3 - (i32.load offset=84 - (get_local $10) - ) - ) - (br $label$1) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 368) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i64.gt_u - (get_local $6) - (i64.const 6) - ) - ) - (br_if $label$8 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$7) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$6 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$5) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $8) - (get_local $7) - ) - ) - (br_if $label$4 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $5 - (i64.const 59) - ) - (set_local $4 - (i32.const 416) - ) - (set_local $9 - (i64.const 0) - ) - (loop $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_if $label$15 - (i64.gt_u - (get_local $6) - (i64.const 5) - ) - ) - (br_if $label$14 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $4) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$13) - ) - (set_local $8 - (i64.const 0) - ) - (br_if $label$12 - (i64.le_u - (get_local $6) - (i64.const 11) - ) - ) - (br $label$11) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $8 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $8 - (i64.shl - (i64.and - (get_local $8) - (i64.const 31) - ) - (i64.and - (get_local $5) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (set_local $6 - (i64.add - (get_local $6) - (i64.const 1) - ) - ) - (set_local $9 - (i64.or - (get_local $8) - (get_local $9) - ) - ) - (br_if $label$10 - (i64.ne - (tee_local $5 - (i64.add - (get_local $5) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 - (get_local $10) - (get_local $9) - ) - (i64.store offset=8 - (get_local $10) - (get_local $7) - ) - (i32.store - (i32.add - (tee_local $4 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $10) - (i32.const 8) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 4) - ) - (i32.load offset=12 - (get_local $10) - ) - ) - (i32.store offset=24 - (get_local $10) - (get_local $4) - ) - (i32.store - (get_local $4) - (i32.load offset=8 - (get_local $10) - ) - ) - (i32.store offset=32 - (get_local $10) - (tee_local $3 - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 8) - ) - (i32.load offset=16 - (get_local $10) - ) - ) - (i32.store offset=28 - (get_local $10) - (get_local $3) - ) - (set_local $4 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730571693710178EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (i32.add - (get_local $10) - (i32.const 40) - ) - (i32.add - (get_local $10) - (i32.const 24) - ) - (i32.add - (get_local $10) - (i32.const 80) - ) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (tee_local $3 - (i32.load offset=24 - (get_local $10) - ) - ) - ) - ) - (i32.store offset=28 - (get_local $10) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $10) - (i32.const 8) - ) - (get_local $4) - ) - (call $send_inline - (tee_local $3 - (i32.load offset=8 - (get_local $10) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $10) - ) - (get_local $3) - ) - ) - (block $label$17 - (br_if $label$17 - (i32.eqz - (tee_local $3 - (i32.load offset=8 - (get_local $10) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $10) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (block $label$18 - (br_if $label$18 - (i32.eqz - (tee_local $3 - (i32.load offset=28 - (get_local $4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 32) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (block $label$19 - (br_if $label$19 - (i32.eqz - (tee_local $3 - (i32.load offset=16 - (get_local $4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 20) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (block $label$20 - (br_if $label$20 - (i32.eqz - (tee_local $4 - (i32.load offset=80 - (get_local $10) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $10) - (get_local $4) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 1120) - ) - ) - ) - (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730571693710178EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -3841127010667593728) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -696013502015841438) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $6) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $7) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $1 - (i32.load - (get_local $2) - ) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.sub - (get_local $4) - (get_local $1) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $3) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $2) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $1) - (get_local $4) - ) - ) - (loop $label$2 - (i32.store8 offset=15 - (get_local $7) - (i32.load8_u - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $5) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $6) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - ) - (i64.store align=4 - (get_local $6) - (i64.load - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction23send_action_inline_failEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 96) - ) - ) - ) - (i32.store offset=88 - (get_local $7) - (i32.const 0) - ) - (set_local $3 - (i64.const 0) - ) - (i64.store offset=80 - (get_local $7) - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 368) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 416) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $3) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $5) - (get_local $6) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 - (get_local $7) - (get_local $6) - ) - (i64.store offset=8 - (get_local $7) - (get_local $4) - ) - (i32.store - (i32.add - (tee_local $1 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.load offset=12 - (get_local $7) - ) - ) - (i32.store offset=24 - (get_local $7) - (get_local $1) - ) - (i32.store - (get_local $1) - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.store offset=32 - (get_local $7) - (tee_local $0 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=16 - (get_local $7) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (set_local $1 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (i32.add - (get_local $7) - (i32.const 40) - ) - (i32.add - (get_local $7) - (i32.const 24) - ) - (i32.add - (get_local $7) - (i32.const 80) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $0 - (i32.load offset=24 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $7) - (i32.const 8) - ) - (get_local $1) - ) - (call $send_inline - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $7) - ) - (get_local $0) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $0 - (i32.load offset=28 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 32) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (tee_local $0 - (i32.load offset=16 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 20) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (tee_local $1 - (i32.load offset=80 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $7) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 96) - ) - ) - ) - (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -3841127010667593728) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -8665432478290165179) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $6) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $7) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $1 - (i32.load - (get_local $2) - ) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.sub - (get_local $4) - (get_local $1) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $3) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $2) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $1) - (get_local $4) - ) - ) - (loop $label$2 - (i32.store8 offset=15 - (get_local $7) - (i32.load8_u - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $5) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $6) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - ) - (i64.store align=4 - (get_local $6) - (i64.load - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction23test_tapos_block_prefixEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $0) - (i32.const 12) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=12 - (get_local $0) - ) - (call $tapos_block_prefix) - ) - (i32.const 17536) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN16test_transaction20test_tapos_block_numEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $0) - (i32.const 12) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=12 - (get_local $0) - ) - (call $tapos_block_num) - ) - (i32.const 17584) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN16test_transaction21test_read_transactionEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $1 - (i32.sub - (get_local $3) - (i32.and - (i32.add - (tee_local $0 - (call $transaction_size) - ) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - (call $eosio_assert - (i32.eq - (get_local $0) - (tee_local $2 - (call $read_transaction - (get_local $1) - (get_local $0) - ) - ) - ) - (i32.const 17616) - ) - (call $sha256 - (get_local $1) - (get_local $2) - (tee_local $0 - (get_local $3) - ) - ) - (call $printhex - (get_local $0) - (i32.const 32) - ) - (drop - (get_local $3) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN16test_transaction21test_transaction_sizeEv - (local $0 i32) - (local $1 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $1 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=12 - (get_local $1) - (i32.const 0) - ) - (drop - (call $read_action_data - (i32.add - (get_local $1) - (i32.const 12) - ) - (i32.const 4) - ) - ) - (set_local $0 - (call $transaction_size) - ) - (call $prints - (i32.const 17648) - ) - (call $printui - (i64.extend_u/i32 - (get_local $0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=12 - (get_local $1) - ) - (call $transaction_size) - ) - (i32.const 17664) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (func $_ZN16test_transaction16send_transactionEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i64) - (local $12 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $12 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 128) - ) - ) - ) - (set_local $4 - (i32.const 0) - ) - (i32.store8 - (i32.add - (i32.add - (get_local $12) - (i32.const 96) - ) - (i32.const 12) - ) - (i32.load8_u offset=17708 - (i32.const 0) - ) - ) - (i32.store - (i32.add - (i32.add - (get_local $12) - (i32.const 96) - ) - (i32.const 8) - ) - (i32.load offset=17704 align=1 - (i32.const 0) - ) - ) - (i64.store offset=96 align=4 - (get_local $12) - (i64.load offset=17696 align=1 - (i32.const 0) - ) - ) - (i32.store offset=88 - (get_local $12) - (i32.const 0) - ) - (i64.store offset=80 - (get_local $12) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (set_local $6 - (i32.const 0) - ) - (block $label$0 - (loop $label$1 - (set_local $3 - (i32.add - (i32.add - (get_local $12) - (i32.const 96) - ) - (get_local $6) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $5) - (get_local $4) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u - (get_local $3) - ) - ) - (i32.store offset=84 - (get_local $12) - (i32.add - (i32.load offset=84 - (get_local $12) - ) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $6) - (i32.const 12) - ) - ) - (br $label$0) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $12) - (i32.const 80) - ) - (get_local $3) - ) - (br_if $label$0 - (i32.eq - (get_local $6) - (i32.const 12) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (set_local $4 - (i32.load - (i32.add - (i32.add - (get_local $12) - (i32.const 80) - ) - (i32.const 8) - ) - ) - ) - (set_local $5 - (i32.load offset=84 - (get_local $12) - ) - ) - (br $label$1) - ) - ) - (set_local $8 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 44) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 48) - ) - (i32.const 0) - ) - (i32.store offset=28 - (get_local $12) - (i32.const 0) - ) - (i32.store8 offset=32 - (get_local $12) - (i32.const 0) - ) - (i32.store offset=36 - (get_local $12) - (i32.const 0) - ) - (i32.store offset=40 - (get_local $12) - (i32.const 0) - ) - (i32.store offset=16 - (get_local $12) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $8) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=52 - (get_local $12) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 56) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 60) - ) - (i32.const 0) - ) - (i32.store offset=64 - (get_local $12) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 68) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 72) - ) - (i32.const 0) - ) - (set_local $4 - (i32.add - (get_local $12) - (i32.const 52) - ) - ) - (set_local $8 - (i64.const 0) - ) - (set_local $7 - (i64.const 59) - ) - (set_local $6 - (i32.const 368) - ) - (set_local $9 - (i64.const 0) - ) - (loop $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i64.gt_u - (get_local $8) - (i64.const 6) - ) - ) - (br_if $label$8 - (i32.gt_u - (i32.and - (i32.add - (tee_local $5 - (i32.load8_s - (get_local $6) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 165) - ) - ) - (br $label$7) - ) - (set_local $10 - (i64.const 0) - ) - (br_if $label$6 - (i64.le_u - (get_local $8) - (i64.const 11) - ) - ) - (br $label$5) - ) - (set_local $5 - (select - (i32.add - (get_local $5) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $5) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $10 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $5) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $10 - (i64.shl - (i64.and - (get_local $10) - (i64.const 31) - ) - (i64.and - (get_local $7) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (set_local $8 - (i64.add - (get_local $8) - (i64.const 1) - ) - ) - (set_local $9 - (i64.or - (get_local $10) - (get_local $9) - ) - ) - (br_if $label$4 - (i64.ne - (tee_local $7 - (i64.add - (get_local $7) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $8 - (i64.const 0) - ) - (set_local $7 - (i64.const 59) - ) - (set_local $6 - (i32.const 416) - ) - (set_local $11 - (i64.const 0) - ) - (loop $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_if $label$15 - (i64.gt_u - (get_local $8) - (i64.const 5) - ) - ) - (br_if $label$14 - (i32.gt_u - (i32.and - (i32.add - (tee_local $5 - (i32.load8_s - (get_local $6) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 165) - ) - ) - (br $label$13) - ) - (set_local $10 - (i64.const 0) - ) - (br_if $label$12 - (i64.le_u - (get_local $8) - (i64.const 11) - ) - ) - (br $label$11) - ) - (set_local $5 - (select - (i32.add - (get_local $5) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $5) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $10 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $5) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $10 - (i64.shl - (i64.and - (get_local $10) - (i64.const 31) - ) - (i64.and - (get_local $7) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (set_local $8 - (i64.add - (get_local $8) - (i64.const 1) - ) - ) - (set_local $11 - (i64.or - (get_local $10) - (get_local $11) - ) - ) - (br_if $label$10 - (i64.ne - (tee_local $7 - (i64.add - (get_local $7) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=8 - (get_local $12) - (get_local $11) - ) - (i64.store - (get_local $12) - (get_local $9) - ) - (i32.store - (i32.add - (tee_local $6 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $12) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $6) - (i32.const 4) - ) - (i32.load offset=4 - (get_local $12) - ) - ) - (i32.store offset=112 - (get_local $12) - (get_local $6) - ) - (i32.store - (get_local $6) - (i32.load - (get_local $12) - ) - ) - (i32.store offset=120 - (get_local $12) - (tee_local $5 - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $6) - (i32.const 8) - ) - (i32.load offset=8 - (get_local $12) - ) - ) - (i32.store offset=116 - (get_local $12) - (get_local $5) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEEvDpOT_ - (get_local $4) - (i32.add - (get_local $12) - (i32.const 112) - ) - (i32.add - (get_local $12) - (i32.const 80) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (tee_local $6 - (i32.load offset=112 - (get_local $12) - ) - ) - ) - ) - (i32.store offset=116 - (get_local $12) - (get_local $6) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - (i64.store offset=8 - (get_local $12) - (i64.const 0) - ) - (i64.store - (get_local $12) - (i64.const 0) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $12) - (i32.const 112) - ) - (i32.add - (get_local $12) - (i32.const 16) - ) - ) - (call $send_deferred - (get_local $12) - (get_local $0) - (tee_local $6 - (i32.load offset=112 - (get_local $12) - ) - ) - (i32.sub - (i32.load offset=116 - (get_local $12) - ) - (get_local $6) - ) - (i32.const 0) - ) - (block $label$17 - (br_if $label$17 - (i32.eqz - (tee_local $6 - (i32.load offset=112 - (get_local $12) - ) - ) - ) - ) - (i32.store offset=116 - (get_local $12) - (get_local $6) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $12) - (i32.const 16) - ) - ) - ) - (block $label$18 - (br_if $label$18 - (i32.eqz - (tee_local $6 - (i32.load offset=80 - (get_local $12) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $12) - (get_local $6) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $12) - (i32.const 128) - ) - ) - ) - (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $6 - (i32.add - (tee_local $9 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $8 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 40) - ) - ) - (i32.const 1) - ) - ) - (i32.const 107374183) - ) - ) - (set_local $7 - (i32.const 107374182) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $8 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $8) - ) - (i32.const 40) - ) - ) - (i32.const 53687090) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $6) - (tee_local $7 - (i32.shl - (get_local $8) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $6) - ) - ) - ) - ) - ) - ) - (set_local $8 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $3 - (i32.add - (get_local $8) - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $8 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (tee_local $9 - (i32.add - (get_local $8) - (i32.mul - (get_local $9) - (i32.const 40) - ) - ) - ) - (get_local $1) - (get_local $2) - ) - ) - (i32.const 40) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $5 - (i32.sub - (i32.const 0) - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const -20) - ) - ) - (loop $label$6 - (i64.store - (i32.add - (get_local $8) - (i32.const -32) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -12) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -20) - ) - ) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -16) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const -4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -20) - ) - (i32.load - (get_local $7) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $1 - (i32.add - (get_local $7) - (i32.const 4) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -12) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $8 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (set_local $8 - (tee_local $9 - (i32.add - (get_local $9) - (i32.const -40) - ) - ) - ) - (br_if $label$6 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $5) - ) - (i32.const -20) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $1 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $9) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $4) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $3) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $1) - ) - ) - (set_local $9 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$8 - (block $label$9 - (br_if $label$9 - (i32.eqz - (tee_local $8 - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $8 - (i32.load - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 4) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$8 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $9) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - ) - (func $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $4 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $3 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $0) - (i32.const 0) - ) - (i64.store align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIjEEEERT_S4_RKNS_11transactionE - (get_local $4) - (get_local $1) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $2 - (i32.load - (get_local $4) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $0) - (get_local $2) - ) - (set_local $3 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $0 - (i32.load - (get_local $0) - ) - ) - (br $label$0) - ) - (set_local $0 - (i32.const 0) - ) - ) - (i32.store offset=4 - (get_local $4) - (get_local $0) - ) - (i32.store - (get_local $4) - (get_local $0) - ) - (i32.store offset=8 - (get_local $4) - (get_local $3) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_18transaction_headerE - (get_local $4) - (get_local $1) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEENSt3__15tupleIJtNS4_6vectorIcNS4_9allocatorIcEEEEEEEEERT_SC_RKNS6_IT0_NS7_ISD_EEEE - (call $_ZN5eosiolsINS_10datastreamIPcEENS_6actionEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE - (call $_ZN5eosiolsINS_10datastreamIPcEENS_6actionEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE - (get_local $4) - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - (i32.add - (get_local $1) - (i32.const 36) - ) - ) - (i32.add - (get_local $1) - (i32.const 48) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosio11transactionD2Ev (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $1 - (i32.load offset=48 - (get_local $0) - ) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.eq - (tee_local $5 - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 52) - ) - ) - ) - ) - (get_local $1) - ) - ) - (set_local $2 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const -12) - ) - ) - (loop $label$3 - (block $label$4 - (br_if $label$4 - (i32.eqz - (tee_local $3 - (i32.load - (get_local $5) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 4) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (br_if $label$3 - (i32.ne - (i32.add - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -16) - ) - ) - (get_local $2) - ) - (i32.const -12) - ) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $0) - (i32.const 48) - ) - ) - ) - (br $label$1) - ) - (set_local $5 - (get_local $1) - ) - ) - (i32.store - (get_local $4) - (get_local $1) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (tee_local $1 - (i32.load offset=36 - (get_local $0) - ) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.eq - (tee_local $5 - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 40) - ) - ) - ) - ) - (get_local $1) - ) - ) - (set_local $2 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const -24) - ) - ) - (loop $label$8 - (block $label$9 - (br_if $label$9 - (i32.eqz - (tee_local $3 - (i32.load - (i32.add - (get_local $5) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 16) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $3 - (i32.load - (get_local $5) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 4) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (br_if $label$8 - (i32.ne - (i32.add - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -40) - ) - ) - (get_local $2) - ) - (i32.const -24) - ) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $0) - (i32.const 36) - ) - ) - ) - (br $label$6) - ) - (set_local $5 - (get_local $1) - ) - ) - (i32.store - (get_local $4) - (get_local $1) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (tee_local $1 - (i32.load offset=24 - (get_local $0) - ) - ) - ) - ) - (block $label$12 - (block $label$13 - (br_if $label$13 - (i32.eq - (tee_local $5 - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - (get_local $1) - ) - ) - (set_local $2 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const -24) - ) - ) - (loop $label$14 - (block $label$15 - (br_if $label$15 - (i32.eqz - (tee_local $3 - (i32.load - (i32.add - (get_local $5) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 16) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (tee_local $3 - (i32.load - (get_local $5) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 4) - ) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (br_if $label$14 - (i32.ne - (i32.add - (tee_local $5 - (i32.add - (get_local $5) - (i32.const -40) - ) - ) - (get_local $2) - ) - (i32.const -24) - ) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - ) - (br $label$12) - ) - (set_local $5 - (get_local $1) - ) - ) - (i32.store - (get_local $4) - (get_local $1) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIjEEEERT_S4_RKNS_11transactionE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i64) - (i32.store - (get_local $0) - (i32.add - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - (i32.const 10) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 11) - ) - ) - (set_local $8 - (i64.load32_u offset=12 - (get_local $1) - ) - ) - (loop $label$0 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - (set_local $8 - (i64.load32_u offset=20 - (get_local $1) - ) - ) - (loop $label$1 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$1 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.div_s - (i32.sub - (tee_local $2 - (i32.load - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - ) - (tee_local $7 - (i32.load offset=24 - (get_local $1) - ) - ) - ) - (i32.const 40) - ) - ) - ) - (loop $label$2 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - (loop $label$4 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.shr_s - (tee_local $5 - (i32.sub - (tee_local $3 - (i32.load - (i32.add - (get_local $7) - (i32.const 20) - ) - ) - ) - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - ) - (i32.const 4) - ) - ) - ) - (loop $label$5 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$5 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.eq - (get_local $4) - (get_local $3) - ) - ) - (set_local $6 - (i32.add - (i32.and - (get_local $5) - (i32.const -16) - ) - (get_local $6) - ) - ) - ) - (set_local $6 - (i32.sub - (i32.add - (get_local $6) - (tee_local $3 - (i32.load - (i32.add - (get_local $7) - (i32.const 32) - ) - ) - ) - ) - (tee_local $4 - (i32.load offset=28 - (get_local $7) - ) - ) - ) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.sub - (get_local $3) - (get_local $4) - ) - ) - ) - (loop $label$7 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$7 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (br_if $label$4 - (i32.ne - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - (get_local $2) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.div_s - (i32.sub - (tee_local $2 - (i32.load - (i32.add - (get_local $1) - (i32.const 40) - ) - ) - ) - (tee_local $7 - (i32.load offset=36 - (get_local $1) - ) - ) - ) - (i32.const 40) - ) - ) - ) - (loop $label$8 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$8 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - (block $label$9 - (br_if $label$9 - (i32.eq - (get_local $7) - (get_local $2) - ) - ) - (loop $label$10 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.shr_s - (tee_local $5 - (i32.sub - (tee_local $3 - (i32.load - (i32.add - (get_local $7) - (i32.const 20) - ) - ) - ) - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - ) - (i32.const 4) - ) - ) - ) - (loop $label$11 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$11 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eq - (get_local $4) - (get_local $3) - ) - ) - (set_local $6 - (i32.add - (i32.and - (get_local $5) - (i32.const -16) - ) - (get_local $6) - ) - ) - ) - (set_local $6 - (i32.sub - (i32.add - (get_local $6) - (tee_local $3 - (i32.load - (i32.add - (get_local $7) - (i32.const 32) - ) - ) - ) - ) - (tee_local $4 - (i32.load offset=28 - (get_local $7) - ) - ) - ) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.sub - (get_local $3) - (get_local $4) - ) - ) - ) - (loop $label$13 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$13 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (br_if $label$10 - (i32.ne - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - (get_local $2) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.shr_s - (i32.sub - (tee_local $5 - (i32.load - (i32.add - (get_local $1) - (i32.const 52) - ) - ) - ) - (tee_local $7 - (i32.load offset=48 - (get_local $1) - ) - ) - ) - (i32.const 4) - ) - ) - ) - (loop $label$14 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$14 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - (block $label$15 - (br_if $label$15 - (i32.eq - (get_local $7) - (get_local $5) - ) - ) - (loop $label$16 - (set_local $6 - (i32.sub - (i32.add - (i32.add - (get_local $6) - (tee_local $3 - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - ) - (i32.const 2) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $7) - ) - ) - ) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.sub - (get_local $3) - (get_local $4) - ) - ) - ) - (loop $label$17 - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$17 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (br_if $label$16 - (i32.ne - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $5) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $6) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNS_18transaction_headerE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 3) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (get_local $1) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $4) - ) - (i32.const 1) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.const 2) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 2) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $4) - ) - (i32.const 3) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load offset=4 - (get_local $0) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $5 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i64.load32_u offset=12 - (get_local $1) - ) - ) - (loop $label$0 - (set_local $4 - (i32.wrap/i64 - (get_local $6) - ) - ) - (i32.store8 offset=14 - (get_local $7) - (i32.or - (i32.shl - (tee_local $2 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $4) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $5) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.add - (get_local $7) - (i32.const 14) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $4) - (tee_local $5 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $2) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $5) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $4) - (tee_local $5 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i64.load32_u offset=20 - (get_local $1) - ) - ) - (loop $label$1 - (set_local $2 - (i32.wrap/i64 - (get_local $6) - ) - ) - (i32.store8 offset=15 - (get_local $7) - (i32.or - (i32.shl - (tee_local $1 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $2) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $3) - ) - (get_local $5) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $4) - (tee_local $5 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$1 - (get_local $1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEENS_6actionEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $5 - (i64.extend_u/i32 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - (i32.const 40) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $7 - (i32.wrap/i64 - (get_local $5) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $2 - (i64.ne - (tee_local $5 - (i64.shr_u - (get_local $5) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $7) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $3) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $2) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $7 - (i32.load - (get_local $1) - ) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$2 - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $6) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (get_local $7) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $6) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $4) - ) - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE - (call $_ZN5eosiolsINS_10datastreamIPcEENS_16permission_levelEEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE - (get_local $0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (i32.add - (get_local $7) - (i32.const 28) - ) - ) - ) - (br_if $label$1 - (i32.eq - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - (get_local $3) - ) - ) - (set_local $6 - (i32.load - (get_local $4) - ) - ) - (br $label$2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEENSt3__15tupleIJtNS4_6vectorIcNS4_9allocatorIcEEEEEEEEERT_SC_RKNS6_IT0_NS7_ISD_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $5 - (i64.extend_u/i32 - (i32.shr_s - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$0 - (set_local $4 - (i32.wrap/i64 - (get_local $5) - ) - ) - (i32.store8 offset=15 - (get_local $7) - (i32.or - (i32.shl - (tee_local $2 - (i64.ne - (tee_local $5 - (i64.shr_u - (get_local $5) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $4) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $3) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $2) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - (tee_local $2 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$2 - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $3) - ) - (get_local $6) - ) - (i32.const 1) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (get_local $4) - (i32.const 2) - ) - ) - (i32.store - (get_local $6) - (i32.add - (i32.load - (get_local $6) - ) - (i32.const 2) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__16vectorIcNS6_9allocatorIcEEEE - (get_local $0) - (i32.add - (get_local $4) - (i32.const 4) - ) - ) - ) - (br_if $label$1 - (i32.eq - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - (get_local $2) - ) - ) - (set_local $6 - (i32.load - (get_local $6) - ) - ) - (br $label$2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction18send_action_senderEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 128) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 8) - ) - ) - (i32.store offset=96 - (get_local $11) - (i32.const 0) - ) - (i64.store offset=88 - (get_local $11) - (i64.const 0) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.add - (get_local $11) - (i32.const 104) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $5 - (i32.load offset=92 - (get_local $11) - ) - ) - (i32.load offset=96 - (get_local $11) - ) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u offset=105 - (get_local $11) - ) - ) - (i32.store offset=92 - (get_local $11) - (tee_local $5 - (i32.add - (i32.load offset=92 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (br $label$0) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.or - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 1) - ) - ) - (set_local $5 - (i32.load offset=92 - (get_local $11) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $5) - (i32.load - (i32.add - (get_local $11) - (i32.const 96) - ) - ) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u offset=106 - (get_local $11) - ) - ) - (i32.store offset=92 - (get_local $11) - (tee_local $5 - (i32.add - (i32.load offset=92 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (br $label$2) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.or - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 2) - ) - ) - (set_local $5 - (i32.load offset=92 - (get_local $11) - ) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (get_local $5) - (i32.load - (i32.add - (get_local $11) - (i32.const 96) - ) - ) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u offset=107 - (get_local $11) - ) - ) - (i32.store offset=92 - (get_local $11) - (tee_local $5 - (i32.add - (i32.load offset=92 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (br $label$4) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.or - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 3) - ) - ) - (set_local $5 - (i32.load offset=92 - (get_local $11) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $5) - (i32.load - (i32.add - (get_local $11) - (i32.const 96) - ) - ) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u offset=108 - (get_local $11) - ) - ) - (i32.store offset=92 - (get_local $11) - (tee_local $5 - (i32.add - (i32.load offset=92 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (br $label$6) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.or - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 4) - ) - ) - (set_local $5 - (i32.load offset=92 - (get_local $11) - ) - ) - ) - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.eq - (get_local $5) - (i32.load - (i32.add - (get_local $11) - (i32.const 96) - ) - ) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u offset=109 - (get_local $11) - ) - ) - (i32.store offset=92 - (get_local $11) - (tee_local $5 - (i32.add - (i32.load offset=92 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (br $label$8) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.or - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 5) - ) - ) - (set_local $5 - (i32.load offset=92 - (get_local $11) - ) - ) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.eq - (get_local $5) - (i32.load - (i32.add - (get_local $11) - (i32.const 96) - ) - ) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u offset=110 - (get_local $11) - ) - ) - (i32.store offset=92 - (get_local $11) - (tee_local $5 - (i32.add - (i32.load offset=92 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (br $label$10) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.or - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 6) - ) - ) - (set_local $5 - (i32.load offset=92 - (get_local $11) - ) - ) - ) - (block $label$12 - (block $label$13 - (br_if $label$13 - (i32.eq - (get_local $5) - (i32.load - (i32.add - (get_local $11) - (i32.const 96) - ) - ) - ) - ) - (i32.store8 - (get_local $5) - (i32.load8_u offset=111 - (get_local $11) - ) - ) - (i32.store offset=92 - (get_local $11) - (i32.add - (i32.load offset=92 - (get_local $11) - ) - (i32.const 1) - ) - ) - (br $label$12) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.or - (i32.add - (get_local $11) - (i32.const 104) - ) - (i32.const 7) - ) - ) - ) - (set_local $7 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 52) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 56) - ) - (i32.const 0) - ) - (i32.store offset=36 - (get_local $11) - (i32.const 0) - ) - (i32.store8 offset=40 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=44 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=48 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=24 - (get_local $11) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $7) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=60 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 68) - ) - (i32.const 0) - ) - (i32.store offset=72 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 76) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 80) - ) - (i32.const 0) - ) - (set_local $4 - (i32.add - (get_local $11) - (i32.const 60) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$14 - (block $label$15 - (block $label$16 - (block $label$17 - (block $label$18 - (block $label$19 - (br_if $label$19 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$18 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$17) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$16 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$15) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$14 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 416) - ) - (set_local $10 - (i64.const 0) - ) - (loop $label$20 - (block $label$21 - (block $label$22 - (block $label$23 - (block $label$24 - (block $label$25 - (br_if $label$25 - (i64.gt_u - (get_local $7) - (i64.const 5) - ) - ) - (br_if $label$24 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$23) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$22 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$21) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $10 - (i64.or - (get_local $9) - (get_local $10) - ) - ) - (br_if $label$20 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=8 - (get_local $11) - (get_local $10) - ) - (i64.store - (get_local $11) - (get_local $8) - ) - (i32.store - (i32.add - (tee_local $5 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $11) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 4) - ) - (i32.load offset=4 - (get_local $11) - ) - ) - (i32.store offset=112 - (get_local $11) - (get_local $5) - ) - (i32.store - (get_local $5) - (i32.load - (get_local $11) - ) - ) - (i32.store offset=120 - (get_local $11) - (tee_local $3 - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 8) - ) - (i32.load offset=8 - (get_local $11) - ) - ) - (i32.store offset=116 - (get_local $11) - (get_local $3) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEEvDpOT_ - (get_local $4) - (i32.add - (get_local $11) - (i32.const 112) - ) - (i32.add - (get_local $11) - (i32.const 88) - ) - ) - (block $label$26 - (br_if $label$26 - (i32.eqz - (tee_local $5 - (i32.load offset=112 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=116 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i64.store offset=8 - (get_local $11) - (i64.const 0) - ) - (i64.store - (get_local $11) - (i64.const 0) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $11) - (i32.const 112) - ) - (i32.add - (get_local $11) - (i32.const 24) - ) - ) - (call $send_deferred - (get_local $11) - (get_local $0) - (tee_local $5 - (i32.load offset=112 - (get_local $11) - ) - ) - (i32.sub - (i32.load offset=116 - (get_local $11) - ) - (get_local $5) - ) - (i32.const 0) - ) - (block $label$27 - (br_if $label$27 - (i32.eqz - (tee_local $5 - (i32.load offset=112 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=116 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $11) - (i32.const 24) - ) - ) - ) - (block $label$28 - (br_if $label$28 - (i32.eqz - (tee_local $5 - (i32.load offset=88 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=92 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 128) - ) - ) - ) - (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $6 - (i32.add - (tee_local $9 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $8 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 40) - ) - ) - (i32.const 1) - ) - ) - (i32.const 107374183) - ) - ) - (set_local $7 - (i32.const 107374182) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $8 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $8) - ) - (i32.const 40) - ) - ) - (i32.const 53687090) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $6) - (tee_local $7 - (i32.shl - (get_local $8) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $6) - ) - ) - ) - ) - ) - ) - (set_local $8 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $3 - (i32.add - (get_local $8) - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $8 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (tee_local $9 - (i32.add - (get_local $8) - (i32.mul - (get_local $9) - (i32.const 40) - ) - ) - ) - (get_local $1) - (get_local $2) - ) - ) - (i32.const 40) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $5 - (i32.sub - (i32.const 0) - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const -20) - ) - ) - (loop $label$6 - (i64.store - (i32.add - (get_local $8) - (i32.const -32) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -12) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -20) - ) - ) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -16) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const -4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -20) - ) - (i32.load - (get_local $7) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $1 - (i32.add - (get_local $7) - (i32.const 4) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -12) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $8 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (set_local $8 - (tee_local $9 - (i32.add - (get_local $9) - (i32.const -40) - ) - ) - ) - (br_if $label$6 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $5) - ) - (i32.const -20) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $1 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $9) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $4) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $3) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $1) - ) - ) - (set_local $9 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$8 - (block $label$9 - (br_if $label$9 - (i32.eqz - (tee_local $8 - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $8 - (i32.load - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 4) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$8 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $9) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - ) - (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311597322538353EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -3841127010667593728) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -8665432476387013263) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $6) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $7) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $1 - (i32.load - (get_local $2) - ) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.sub - (get_local $4) - (get_local $1) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $3) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $2) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $1) - (get_local $4) - ) - ) - (loop $label$2 - (i32.store8 offset=15 - (get_local $7) - (i32.load8_u - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $5) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $6) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - ) - (i64.store align=4 - (get_local $6) - (i64.load - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction22send_transaction_emptyEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $5 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 96) - ) - ) - ) - (set_local $4 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 44) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 48) - ) - (i32.const 0) - ) - (i32.store offset=28 - (get_local $5) - (i32.const 0) - ) - (i32.store8 offset=32 - (get_local $5) - (i32.const 0) - ) - (i32.store offset=36 - (get_local $5) - (i32.const 0) - ) - (i32.store offset=40 - (get_local $5) - (i32.const 0) - ) - (i32.store offset=16 - (get_local $5) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $4) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=52 - (get_local $5) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 56) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 60) - ) - (i32.const 0) - ) - (i32.store offset=64 - (get_local $5) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 68) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 72) - ) - (i32.const 0) - ) - (i64.store offset=8 - (get_local $5) - (i64.const 0) - ) - (i64.store - (get_local $5) - (i64.const 0) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $5) - (i32.const 80) - ) - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - (call $send_deferred - (get_local $5) - (get_local $0) - (tee_local $3 - (i32.load offset=80 - (get_local $5) - ) - ) - (i32.sub - (i32.load offset=84 - (get_local $5) - ) - (get_local $3) - ) - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.load offset=80 - (get_local $5) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $5) - (get_local $3) - ) - (call $_ZdlPv - (get_local $3) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 17712) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $5) - (i32.const 96) - ) - ) - ) - (func $_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (set_local $7 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 60) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 0) - ) - (i32.store offset=44 - (get_local $11) - (i32.const 0) - ) - (i32.store8 offset=48 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=52 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=56 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=32 - (get_local $11) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $7) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=68 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 72) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 76) - ) - (i32.const 0) - ) - (i32.store offset=80 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 84) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.const 0) - ) - (i32.store offset=24 - (get_local $11) - (i32.const 0) - ) - (set_local $7 - (i64.const 0) - ) - (i64.store offset=16 - (get_local $11) - (i64.const 0) - ) - (set_local $3 - (i32.add - (get_local $11) - (i32.const 68) - ) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $4 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $4 - (select - (i32.add - (get_local $4) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $4) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $4) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 416) - ) - (set_local $10 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $7) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $4 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $4 - (select - (i32.add - (get_local $4) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $4) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $4) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $10 - (i64.or - (get_local $9) - (get_local $10) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=8 - (get_local $11) - (get_local $10) - ) - (i64.store - (get_local $11) - (get_local $8) - ) - (i32.store - (i32.add - (tee_local $5 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $11) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 4) - ) - (i32.load offset=4 - (get_local $11) - ) - ) - (i32.store offset=96 - (get_local $11) - (get_local $5) - ) - (i32.store - (get_local $5) - (i32.load - (get_local $11) - ) - ) - (i32.store offset=104 - (get_local $11) - (tee_local $4 - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 8) - ) - (i32.load offset=8 - (get_local $11) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $4) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEEvDpOT_ - (get_local $3) - (i32.add - (get_local $11) - (i32.const 96) - ) - (i32.add - (get_local $11) - (i32.const 16) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i64.store offset=8 - (get_local $11) - (i64.const 0) - ) - (i64.store - (get_local $11) - (i64.const 0) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $11) - (i32.const 96) - ) - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - (call $send_deferred - (get_local $11) - (get_local $0) - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - (i32.sub - (i32.load offset=100 - (get_local $11) - ) - (get_local $5) - ) - (i32.const 0) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $5 - (i32.load offset=16 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 112) - ) - ) - ) - (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $6 - (i32.add - (tee_local $9 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $8 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 40) - ) - ) - (i32.const 1) - ) - ) - (i32.const 107374183) - ) - ) - (set_local $7 - (i32.const 107374182) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $8 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $8) - ) - (i32.const 40) - ) - ) - (i32.const 53687090) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $6) - (tee_local $7 - (i32.shl - (get_local $8) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $6) - ) - ) - ) - ) - ) - ) - (set_local $8 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $3 - (i32.add - (get_local $8) - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $8 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595419386437EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (tee_local $9 - (i32.add - (get_local $8) - (i32.mul - (get_local $9) - (i32.const 40) - ) - ) - ) - (get_local $1) - (get_local $2) - ) - ) - (i32.const 40) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $5 - (i32.sub - (i32.const 0) - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const -20) - ) - ) - (loop $label$6 - (i64.store - (i32.add - (get_local $8) - (i32.const -32) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -12) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -20) - ) - ) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -16) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const -4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -20) - ) - (i32.load - (get_local $7) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $1 - (i32.add - (get_local $7) - (i32.const 4) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -12) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $8 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (set_local $8 - (tee_local $9 - (i32.add - (get_local $9) - (i32.const -40) - ) - ) - ) - (br_if $label$6 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $5) - ) - (i32.const -20) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $1 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $9) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $4) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $3) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $1) - ) - ) - (set_local $9 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$8 - (block $label$9 - (br_if $label$9 - (i32.eqz - (tee_local $8 - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $8 - (i32.load - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 4) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$8 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $9) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - ) - (func $_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE (param $0 i32) - (local $1 i64) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (call $eosio_assert - (i32.eq - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 40) - ) - ) - (i32.load offset=36 - (get_local $0) - ) - ) - (i32.const 40) - ) - (i32.const 17776) - ) - (set_local $1 - (i64.load - (i32.load offset=36 - (get_local $0) - ) - ) - ) - (set_local $5 - (i64.const 0) - ) - (set_local $4 - (i64.const 59) - ) - (set_local $3 - (i32.const 368) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $5) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $2 - (i32.load8_s - (get_local $3) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $7 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $5) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $2 - (select - (i32.add - (get_local $2) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $2) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $7 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $7 - (i64.shl - (i64.and - (get_local $7) - (i64.const 31) - ) - (i64.and - (get_local $4) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - (set_local $5 - (i64.add - (get_local $5) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $7) - (get_local $6) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $4 - (i64.add - (get_local $4) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (get_local $6) - ) - (i32.const 17824) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 36) - ) - ) - ) - ) - (i64.const -8665432478290165179) - ) - (i32.const 17856) - ) - (call $eosio_assert - (i32.eq - (i32.sub - (i32.load - (i32.add - (tee_local $2 - (i32.load - (get_local $3) - ) - ) - (i32.const 20) - ) - ) - (i32.load offset=16 - (get_local $2) - ) - ) - (i32.const 16) - ) - (i32.const 17888) - ) - (set_local $1 - (i64.load - (i32.load offset=16 - (i32.load - (get_local $3) - ) - ) - ) - ) - (set_local $5 - (i64.const 0) - ) - (set_local $4 - (i64.const 59) - ) - (set_local $3 - (i32.const 368) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $5) - (i64.const 6) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $2 - (i32.load8_s - (get_local $3) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $7 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $5) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $2 - (select - (i32.add - (get_local $2) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $2) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $7 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $7 - (i64.shl - (i64.and - (get_local $7) - (i64.const 31) - ) - (i64.and - (get_local $4) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - (set_local $5 - (i64.add - (get_local $5) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $7) - (get_local $6) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $4 - (i64.add - (get_local $4) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (get_local $6) - ) - (i32.const 17936) - ) - (set_local $1 - (i64.load offset=8 - (i32.load offset=16 - (i32.load - (i32.add - (get_local $0) - (i32.const 36) - ) - ) - ) - ) - ) - (set_local $5 - (i64.const 0) - ) - (set_local $4 - (i64.const 59) - ) - (set_local $3 - (i32.const 416) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (block $label$17 - (br_if $label$17 - (i64.gt_u - (get_local $5) - (i64.const 5) - ) - ) - (br_if $label$16 - (i32.gt_u - (i32.and - (i32.add - (tee_local $2 - (i32.load8_s - (get_local $3) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 165) - ) - ) - (br $label$15) - ) - (set_local $7 - (i64.const 0) - ) - (br_if $label$14 - (i64.le_u - (get_local $5) - (i64.const 11) - ) - ) - (br $label$13) - ) - (set_local $2 - (select - (i32.add - (get_local $2) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $2) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $7 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $2) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $7 - (i64.shl - (i64.and - (get_local $7) - (i64.const 31) - ) - (i64.and - (get_local $4) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 1) - ) - ) - (set_local $5 - (i64.add - (get_local $5) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $7) - (get_local $6) - ) - ) - (br_if $label$12 - (i64.ne - (tee_local $4 - (i64.add - (get_local $4) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i64.eq - (get_local $1) - (get_local $6) - ) - (i32.const 17984) - ) - ) - (func $_ZN16test_transaction22send_transaction_largeEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i64) - (local $13 i64) - (local $14 i64) - (local $15 i64) - (local $16 i64) - (local $17 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $17 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 1136) - ) - ) - ) - (set_local $13 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 1100) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (i32.add - (get_local $17) - (i32.const 1072) - ) - (i32.const 32) - ) - (i32.const 0) - ) - (i32.store offset=1084 - (get_local $17) - (i32.const 0) - ) - (i32.store8 offset=1088 - (get_local $17) - (i32.const 0) - ) - (i32.store offset=1092 - (get_local $17) - (i32.const 0) - ) - (i32.store offset=1096 - (get_local $17) - (i32.const 0) - ) - (i32.store offset=1072 - (get_local $17) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $13) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=1108 - (get_local $17) - (i32.const 0) - ) - (i32.store - (tee_local $5 - (i32.add - (i32.add - (get_local $17) - (i32.const 1072) - ) - (i32.const 40) - ) - ) - (i32.const 0) - ) - (i32.store - (tee_local $6 - (i32.add - (get_local $17) - (i32.const 1116) - ) - ) - (i32.const 0) - ) - (i32.store offset=1120 - (get_local $17) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 1124) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $17) - (i32.const 1128) - ) - (i32.const 0) - ) - (set_local $3 - (i32.add - (get_local $17) - (i32.const 1108) - ) - ) - (set_local $7 - (i32.add - (i32.add - (get_local $17) - (i32.const 32) - ) - (i32.const 8) - ) - ) - (set_local $8 - (i32.const 0) - ) - (loop $label$0 - (i32.store - (get_local $7) - (i32.const 0) - ) - (i64.store offset=32 - (get_local $17) - (i64.const 0) - ) - (set_local $9 - (i32.const 0) - ) - (set_local $10 - (i32.const 0) - ) - (set_local $11 - (i32.const 0) - ) - (block $label$1 - (loop $label$2 - (set_local $4 - (i32.add - (i32.add - (get_local $17) - (i32.const 48) - ) - (get_local $11) - ) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.eq - (get_local $10) - (get_local $9) - ) - ) - (i32.store8 - (get_local $10) - (i32.load8_u - (get_local $4) - ) - ) - (i32.store offset=36 - (get_local $17) - (i32.add - (i32.load offset=36 - (get_local $17) - ) - (i32.const 1) - ) - ) - (br_if $label$3 - (i32.ne - (get_local $11) - (i32.const 1023) - ) - ) - (br $label$1) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE21__push_back_slow_pathIRKcEEvOT_ - (i32.add - (get_local $17) - (i32.const 32) - ) - (get_local $4) - ) - (br_if $label$1 - (i32.eq - (get_local $11) - (i32.const 1023) - ) - ) - ) - (set_local $11 - (i32.add - (get_local $11) - (i32.const 1) - ) - ) - (set_local $9 - (i32.load - (get_local $7) - ) - ) - (set_local $10 - (i32.load offset=36 - (get_local $17) - ) - ) - (br $label$2) - ) - ) - (set_local $13 - (i64.const 0) - ) - (set_local $12 - (i64.const 59) - ) - (set_local $11 - (i32.const 368) - ) - (set_local $14 - (i64.const 0) - ) - (loop $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (br_if $label$10 - (i64.gt_u - (get_local $13) - (i64.const 6) - ) - ) - (br_if $label$9 - (i32.gt_u - (i32.and - (i32.add - (tee_local $10 - (i32.load8_s - (get_local $11) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $10 - (i32.add - (get_local $10) - (i32.const 165) - ) - ) - (br $label$8) - ) - (set_local $15 - (i64.const 0) - ) - (br_if $label$7 - (i64.le_u - (get_local $13) - (i64.const 11) - ) - ) - (br $label$6) - ) - (set_local $10 - (select - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $10) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $15 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $10) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $15 - (i64.shl - (i64.and - (get_local $15) - (i64.const 31) - ) - (i64.and - (get_local $12) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $11 - (i32.add - (get_local $11) - (i32.const 1) - ) - ) - (set_local $13 - (i64.add - (get_local $13) - (i64.const 1) - ) - ) - (set_local $14 - (i64.or - (get_local $15) - (get_local $14) - ) - ) - (br_if $label$5 - (i64.ne - (tee_local $12 - (i64.add - (get_local $12) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $13 - (i64.const 0) - ) - (set_local $12 - (i64.const 59) - ) - (set_local $11 - (i32.const 416) - ) - (set_local $16 - (i64.const 0) - ) - (loop $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (br_if $label$16 - (i64.gt_u - (get_local $13) - (i64.const 5) - ) - ) - (br_if $label$15 - (i32.gt_u - (i32.and - (i32.add - (tee_local $10 - (i32.load8_s - (get_local $11) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $10 - (i32.add - (get_local $10) - (i32.const 165) - ) - ) - (br $label$14) - ) - (set_local $15 - (i64.const 0) - ) - (br_if $label$13 - (i64.le_u - (get_local $13) - (i64.const 11) - ) - ) - (br $label$12) - ) - (set_local $10 - (select - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $10) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $15 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $10) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $15 - (i64.shl - (i64.and - (get_local $15) - (i64.const 31) - ) - (i64.and - (get_local $12) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $11 - (i32.add - (get_local $11) - (i32.const 1) - ) - ) - (set_local $13 - (i64.add - (get_local $13) - (i64.const 1) - ) - ) - (set_local $16 - (i64.or - (get_local $15) - (get_local $16) - ) - ) - (br_if $label$11 - (i64.ne - (tee_local $12 - (i64.add - (get_local $12) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store - (tee_local $10 - (i32.add - (get_local $17) - (i32.const 8) - ) - ) - (get_local $16) - ) - (i32.store - (tee_local $9 - (i32.add - (i32.add - (get_local $17) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.const 0) - ) - (i64.store - (get_local $17) - (get_local $14) - ) - (i64.store offset=16 - (get_local $17) - (i64.const 0) - ) - (i32.store - (get_local $9) - (tee_local $4 - (i32.add - (tee_local $11 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $17) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 4) - ) - (i32.load offset=4 - (get_local $17) - ) - ) - (i32.store offset=16 - (get_local $17) - (get_local $11) - ) - (i32.store - (get_local $11) - (i32.load - (get_local $17) - ) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.load - (get_local $10) - ) - ) - (i32.store offset=20 - (get_local $17) - (get_local $4) - ) - (block $label$17 - (block $label$18 - (block $label$19 - (br_if $label$19 - (i32.ge_u - (tee_local $11 - (i32.load - (get_local $5) - ) - ) - (i32.load - (get_local $6) - ) - ) - ) - (drop - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (get_local $11) - (i32.add - (get_local $17) - (i32.const 16) - ) - (i32.add - (get_local $17) - (i32.const 32) - ) - ) - ) - (i32.store - (get_local $5) - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 40) - ) - ) - (br_if $label$18 - (tee_local $11 - (i32.load offset=16 - (get_local $17) - ) - ) - ) - (br $label$17) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy9781311595436863162EEEEEvDpOT_ - (get_local $3) - (i32.add - (get_local $17) - (i32.const 16) - ) - (i32.add - (get_local $17) - (i32.const 32) - ) - ) - (br_if $label$17 - (i32.eqz - (tee_local $11 - (i32.load offset=16 - (get_local $17) - ) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $17) - (get_local $11) - ) - (call $_ZdlPv - (get_local $11) - ) - ) - (block $label$20 - (br_if $label$20 - (i32.eqz - (tee_local $11 - (i32.load offset=32 - (get_local $17) - ) - ) - ) - ) - (i32.store offset=36 - (get_local $17) - (get_local $11) - ) - (call $_ZdlPv - (get_local $11) - ) - ) - (br_if $label$0 - (i32.ne - (tee_local $8 - (i32.add - (get_local $8) - (i32.const 1) - ) - ) - (i32.const 32) - ) - ) - ) - (i64.store offset=56 - (get_local $17) - (i64.const 0) - ) - (i64.store offset=48 - (get_local $17) - (i64.const 0) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (get_local $17) - (i32.add - (get_local $17) - (i32.const 1072) - ) - ) - (call $send_deferred - (i32.add - (get_local $17) - (i32.const 48) - ) - (get_local $0) - (tee_local $11 - (i32.load - (get_local $17) - ) - ) - (i32.sub - (i32.load offset=4 - (get_local $17) - ) - (get_local $11) - ) - (i32.const 0) - ) - (block $label$21 - (br_if $label$21 - (i32.eqz - (tee_local $11 - (i32.load - (get_local $17) - ) - ) - ) - ) - (i32.store offset=4 - (get_local $17) - (get_local $11) - ) - (call $_ZdlPv - (get_local $11) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 18032) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $17) - (i32.const 1072) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $17) - (i32.const 1136) - ) - ) - ) - (func $_ZN16test_transaction14deferred_printEv - (call $prints - (i32.const 18096) - ) - ) - (func $_ZN16test_transaction25send_deferred_transactionEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (set_local $7 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 60) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 0) - ) - (i32.store offset=44 - (get_local $11) - (i32.const 0) - ) - (i32.store8 offset=48 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=52 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=56 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=32 - (get_local $11) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $7) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=68 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 72) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 76) - ) - (i32.const 0) - ) - (i32.store offset=80 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 84) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.const 0) - ) - (i32.store offset=24 - (get_local $11) - (i32.const 0) - ) - (set_local $7 - (i64.const 0) - ) - (i64.store offset=16 - (get_local $11) - (i64.const 0) - ) - (set_local $3 - (i32.add - (get_local $11) - (i32.const 68) - ) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $4 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $4 - (select - (i32.add - (get_local $4) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $4) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $4) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 416) - ) - (set_local $10 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $7) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $4 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $4 - (select - (i32.add - (get_local $4) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $4) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $4) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $10 - (i64.or - (get_local $9) - (get_local $10) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=8 - (get_local $11) - (get_local $10) - ) - (i64.store - (get_local $11) - (get_local $8) - ) - (i32.store - (i32.add - (tee_local $5 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $11) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 4) - ) - (i32.load offset=4 - (get_local $11) - ) - ) - (i32.store offset=96 - (get_local $11) - (get_local $5) - ) - (i32.store - (get_local $5) - (i32.load - (get_local $11) - ) - ) - (i32.store offset=104 - (get_local $11) - (tee_local $4 - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 8) - ) - (i32.load offset=8 - (get_local $11) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $4) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEEvDpOT_ - (get_local $3) - (i32.add - (get_local $11) - (i32.const 96) - ) - (i32.add - (get_local $11) - (i32.const 16) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 52) - ) - (i32.const 2) - ) - (i64.store offset=8 - (get_local $11) - (i64.const 0) - ) - (i64.store - (get_local $11) - (i64.const -1) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $11) - (i32.const 96) - ) - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - (call $send_deferred - (get_local $11) - (get_local $0) - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - (i32.sub - (i32.load offset=100 - (get_local $11) - ) - (get_local $5) - ) - (i32.const 0) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $5 - (i32.load offset=16 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 112) - ) - ) - ) - (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEEvDpOT_ (param $0 i32) (param $1 i32) (param $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $6 - (i32.add - (tee_local $9 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $8 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 40) - ) - ) - (i32.const 1) - ) - ) - (i32.const 107374183) - ) - ) - (set_local $7 - (i32.const 107374182) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $8 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $8) - ) - (i32.const 40) - ) - ) - (i32.const 53687090) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $6) - (tee_local $7 - (i32.shl - (get_local $8) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $6) - ) - ) - ) - ) - ) - ) - (set_local $8 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $3 - (i32.add - (get_local $8) - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $8 - (call $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (tee_local $9 - (i32.add - (get_local $8) - (i32.mul - (get_local $9) - (i32.const 40) - ) - ) - ) - (get_local $1) - (get_local $2) - ) - ) - (i32.const 40) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $5 - (i32.sub - (i32.const 0) - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const -20) - ) - ) - (loop $label$6 - (i64.store - (i32.add - (get_local $8) - (i32.const -32) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -12) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -20) - ) - ) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -16) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const -4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -20) - ) - (i32.load - (get_local $7) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $1 - (i32.add - (get_local $7) - (i32.const 4) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -12) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store - (get_local $2) - (i32.load - (tee_local $8 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (set_local $8 - (tee_local $9 - (i32.add - (get_local $9) - (i32.const -40) - ) - ) - ) - (br_if $label$6 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $5) - ) - (i32.const -20) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $1 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $9) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $4) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $3) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $1) - ) - ) - (set_local $9 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$8 - (block $label$9 - (br_if $label$9 - (i32.eqz - (tee_local $8 - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $8 - (i32.load - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 4) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$8 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $9) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - ) - (func $_ZN5eosio6actionC2I18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -3841127010667593728) - ) - (i64.store offset=8 - (get_local $0) - (i64.const -696013501027893080) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $6) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $7) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $1 - (i32.load - (get_local $2) - ) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.sub - (get_local $4) - (get_local $1) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $3) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $2) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $1) - (get_local $4) - ) - ) - (loop $label$2 - (i32.store8 offset=15 - (get_local $7) - (i32.load8_u - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $5) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $6) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - ) - (i64.store align=4 - (get_local $6) - (i64.load - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction33send_deferred_transaction_replaceEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i64) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 112) - ) - ) - ) - (set_local $7 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 60) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 64) - ) - (i32.const 0) - ) - (i32.store offset=44 - (get_local $11) - (i32.const 0) - ) - (i32.store8 offset=48 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=52 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=56 - (get_local $11) - (i32.const 0) - ) - (i32.store offset=32 - (get_local $11) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $7) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=68 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 72) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 76) - ) - (i32.const 0) - ) - (i32.store offset=80 - (get_local $11) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 84) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 88) - ) - (i32.const 0) - ) - (i32.store offset=24 - (get_local $11) - (i32.const 0) - ) - (set_local $7 - (i64.const 0) - ) - (i64.store offset=16 - (get_local $11) - (i64.const 0) - ) - (set_local $3 - (i32.add - (get_local $11) - (i32.const 68) - ) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 368) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $4 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $4 - (select - (i32.add - (get_local $4) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $4) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $4) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 416) - ) - (set_local $10 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $7) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $4 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $4 - (select - (i32.add - (get_local $4) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $4) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $4) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $10 - (i64.or - (get_local $9) - (get_local $10) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=8 - (get_local $11) - (get_local $10) - ) - (i64.store - (get_local $11) - (get_local $8) - ) - (i32.store - (i32.add - (tee_local $5 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (get_local $11) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 4) - ) - (i32.load offset=4 - (get_local $11) - ) - ) - (i32.store offset=96 - (get_local $11) - (get_local $5) - ) - (i32.store - (get_local $5) - (i32.load - (get_local $11) - ) - ) - (i32.store offset=104 - (get_local $11) - (tee_local $4 - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $5) - (i32.const 8) - ) - (i32.load offset=8 - (get_local $11) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $4) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJNS0_INS1_16permission_levelENS3_IS7_EEEER18test_action_actionILy14605617063041957888ELy17750730572681658536EEEEEvDpOT_ - (get_local $3) - (i32.add - (get_local $11) - (i32.const 96) - ) - (i32.add - (get_local $11) - (i32.const 16) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (i32.store - (i32.add - (get_local $11) - (i32.const 52) - ) - (i32.const 2) - ) - (i64.store offset=8 - (get_local $11) - (i64.const 0) - ) - (i64.store - (get_local $11) - (i64.const -1) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $11) - (i32.const 96) - ) - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - (call $send_deferred - (get_local $11) - (get_local $0) - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - (i32.sub - (i32.load offset=100 - (get_local $11) - ) - (get_local $5) - ) - (i32.const 1) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $5 - (i32.load offset=96 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=100 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $5 - (i32.load offset=16 - (get_local $11) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $11) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $11) - (i32.const 32) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 112) - ) - ) - ) - (func $_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 176) - ) - ) - ) - (set_local $0 - (call $_ZN10dtt_actionC2Ev - (i32.add - (get_local $7) - (i32.const 120) - ) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $7) - (i32.const 120) - ) - (call $action_data_size) - ) - ) - (set_local $4 - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $7) - (i32.const 104) - ) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $7) - (i32.const 112) - ) - (i64.const 0) - ) - (i64.store offset=96 - (get_local $7) - (i64.const 0) - ) - (i64.store offset=80 - (get_local $7) - (i64.load offset=8 - (get_local $0) - ) - ) - (i64.store offset=88 - (get_local $7) - (i64.load offset=16 - (get_local $0) - ) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 - (get_local $7) - (get_local $5) - ) - (i64.store offset=24 - (get_local $7) - (i64.load offset=24 - (get_local $0) - ) - ) - (i64.store - (i32.add - (tee_local $2 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 8) - ) - (i64.load offset=24 - (get_local $7) - ) - ) - (i64.store - (get_local $2) - (i64.load offset=16 - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 100) - ) - (tee_local $1 - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - ) - (i32.store offset=96 - (get_local $7) - (get_local $2) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 104) - ) - (get_local $1) - ) - (set_local $4 - (call $current_time) - ) - (i32.store - (i32.add - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 28) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 48) - ) - (i32.const 0) - ) - (i32.store offset=28 - (get_local $7) - (i32.const 0) - ) - (i32.store8 offset=32 - (get_local $7) - (i32.const 0) - ) - (i32.store offset=36 - (get_local $7) - (i32.const 0) - ) - (i32.store offset=40 - (get_local $7) - (i32.const 0) - ) - (i32.store offset=16 - (get_local $7) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $4) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=52 - (get_local $7) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 56) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 60) - ) - (i32.const 0) - ) - (i32.store offset=64 - (get_local $7) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 68) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 72) - ) - (i32.const 0) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJRS2_EEEvDpOT_ - (i32.add - (get_local $7) - (i32.const 52) - ) - (i32.add - (get_local $7) - (i32.const 80) - ) - ) - (i32.store offset=36 - (get_local $7) - (i32.load offset=32 - (get_local $0) - ) - ) - (i64.store offset=8 - (get_local $7) - (i64.const 0) - ) - (i64.store - (get_local $7) - (i64.const -1) - ) - (drop - (call $cancel_deferred - (get_local $7) - ) - ) - (i64.store offset=8 - (get_local $7) - (i64.const 0) - ) - (i64.store - (get_local $7) - (i64.const -1) - ) - (set_local $4 - (i64.load - (get_local $0) - ) - ) - (call $_ZN5eosio4packINS_11transactionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $7) - (i32.const 160) - ) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (call $send_deferred - (get_local $7) - (get_local $4) - (tee_local $2 - (i32.load offset=160 - (get_local $7) - ) - ) - (i32.sub - (i32.load offset=164 - (get_local $7) - ) - (get_local $2) - ) - (i32.const 1) - ) - (block $label$6 - (br_if $label$6 - (i32.eqz - (tee_local $2 - (i32.load offset=160 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=164 - (get_local $7) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - (block $label$7 - (br_if $label$7 - (i32.eqz - (tee_local $2 - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 80) - ) - (i32.const 28) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 112) - ) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.eqz - (tee_local $2 - (i32.load - (i32.add - (get_local $7) - (i32.const 96) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 100) - ) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 176) - ) - ) - ) - (func $_ZN10dtt_actionC2Ev (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store align=1 - (get_local $0) - (get_local $5) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 368) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $4) - (i64.const 6) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 align=1 - (get_local $0) - (i64.const -696013501027893080) - ) - (i64.store align=1 - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $5) - ) - (set_local $4 - (i64.const 0) - ) - (set_local $3 - (i64.const 59) - ) - (set_local $2 - (i32.const 416) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (block $label$16 - (block $label$17 - (br_if $label$17 - (i64.gt_u - (get_local $4) - (i64.const 5) - ) - ) - (br_if $label$16 - (i32.gt_u - (i32.and - (i32.add - (tee_local $1 - (i32.load8_s - (get_local $2) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 165) - ) - ) - (br $label$15) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$14 - (i64.le_u - (get_local $4) - (i64.const 11) - ) - ) - (br $label$13) - ) - (set_local $1 - (select - (i32.add - (get_local $1) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $1) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $1) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $3) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (set_local $4 - (i64.add - (get_local $4) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$12 - (i64.ne - (tee_local $3 - (i64.add - (get_local $3) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i32.store offset=32 align=1 - (get_local $0) - (i32.const 2) - ) - (i64.store align=1 - (i32.add - (get_local $0) - (i32.const 24) - ) - (get_local $5) - ) - (get_local $0) - ) - (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE24__emplace_back_slow_pathIJRS2_EEEvDpOT_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $5 - (i32.add - (tee_local $9 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $0) - ) - (tee_local $8 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 40) - ) - ) - (i32.const 1) - ) - ) - (i32.const 107374183) - ) - ) - (set_local $7 - (i32.const 107374182) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.gt_u - (tee_local $8 - (i32.div_s - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $8) - ) - (i32.const 40) - ) - ) - (i32.const 53687090) - ) - ) - (br_if $label$2 - (i32.eqz - (tee_local $7 - (select - (get_local $5) - (tee_local $7 - (i32.shl - (get_local $8) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $5) - ) - ) - ) - ) - ) - ) - (set_local $8 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $2 - (i32.add - (get_local $8) - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (set_local $3 - (i32.add - (tee_local $8 - (call $_ZN5eosio6actionC2ERKS0_ - (tee_local $9 - (i32.add - (get_local $8) - (i32.mul - (get_local $9) - (i32.const 40) - ) - ) - ) - (get_local $1) - ) - ) - (i32.const 40) - ) - ) - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.eq - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $7 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $4 - (i32.sub - (i32.const 0) - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (get_local $1) - (i32.const -20) - ) - ) - (loop $label$6 - (i64.store - (i32.add - (get_local $8) - (i32.const -32) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -12) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $7) - (i32.const -20) - ) - ) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - (i64.const 0) - ) - (i32.store - (tee_local $5 - (i32.add - (get_local $8) - (i32.const -16) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const -4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -20) - ) - (i32.load - (get_local $7) - ) - ) - (i32.store - (get_local $5) - (i32.load - (tee_local $1 - (i32.add - (get_local $7) - (i32.const 4) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -12) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store - (tee_local $5 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $6 - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - (i32.store - (get_local $5) - (i32.load - (tee_local $8 - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (set_local $8 - (tee_local $9 - (i32.add - (get_local $9) - (i32.const -40) - ) - ) - ) - (br_if $label$6 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $4) - ) - (i32.const -20) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - (br $label$4) - ) - (set_local $1 - (get_local $7) - ) - ) - (i32.store - (get_local $0) - (get_local $9) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $2) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (get_local $7) - (get_local $1) - ) - ) - (set_local $9 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const -24) - ) - ) - (loop $label$8 - (block $label$9 - (br_if $label$9 - (i32.eqz - (tee_local $8 - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (tee_local $8 - (i32.load - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 4) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$8 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $9) - ) - (i32.const -24) - ) - ) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - ) - (func $_ZN5eosio6actionC2ERKS0_ (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (i64.store - (get_local $0) - (i64.load - (get_local $1) - ) - ) - (i64.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.const 0) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.eqz - (tee_local $5 - (i32.shr_s - (tee_local $4 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - (i32.load offset=16 - (get_local $1) - ) - ) - ) - (i32.const 4) - ) - ) - ) - ) - (br_if $label$1 - (i32.ge_u - (get_local $5) - (i32.const 268435456) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 16) - ) - (tee_local $4 - (call $_Znwj - (get_local $4) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.add - (get_local $4) - (i32.shl - (get_local $5) - (i32.const 4) - ) - ) - ) - (i32.store - (tee_local $5 - (i32.add - (get_local $0) - (i32.const 20) - ) - ) - (get_local $4) - ) - (br_if $label$2 - (i32.lt_s - (tee_local $3 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - (tee_local $2 - (i32.load - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - ) - ) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $4) - (get_local $2) - (get_local $3) - ) - ) - (i32.store - (get_local $5) - (i32.add - (i32.load - (get_local $5) - ) - (get_local $3) - ) - ) - ) - (i64.store offset=28 align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $4 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - (i32.load offset=28 - (get_local $1) - ) - ) - ) - ) - ) - (br_if $label$0 - (i32.le_s - (get_local $4) - (i32.const -1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 28) - ) - (tee_local $5 - (call $_Znwj - (get_local $4) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.add - (get_local $5) - (get_local $4) - ) - ) - (i32.store - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - (get_local $5) - ) - (br_if $label$3 - (i32.lt_s - (tee_local $1 - (i32.sub - (i32.load - (i32.add - (get_local $1) - (i32.const 32) - ) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - ) - ) - ) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $3) - (get_local $1) - ) - ) - (i32.store - (get_local $4) - (i32.add - (i32.load - (get_local $4) - ) - (get_local $1) - ) - ) - ) - (return - (get_local $0) - ) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - (unreachable) - ) - (func $_ZN16test_transaction35cancel_deferred_transaction_successEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -1) - ) - (call $eosio_assert - (i32.ne - (call $cancel_deferred - (get_local $0) - ) - (i32.const 0) - ) - (i32.const 18128) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN16test_transaction37cancel_deferred_transaction_not_foundEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const -1) - ) - (call $eosio_assert - (i32.eqz - (call $cancel_deferred - (get_local $0) - ) - ) - (i32.const 18160) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (func $_ZN16test_transaction14send_cf_actionEv - (local $0 i32) - (local $1 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $1 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (i64.store - (i32.add - (get_local $1) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $1) - (i32.const 40) - ) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $1) - (i64.const 0) - ) - (i64.store offset=8 - (get_local $1) - (i64.const 5666987383162142720) - ) - (i64.store offset=16 - (get_local $1) - (i64.const 6256973794934521856) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 18224) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $1) - (i32.const 48) - ) - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (call $send_context_free_inline - (tee_local $0 - (i32.load offset=48 - (get_local $1) - ) - ) - (i32.sub - (i32.load offset=52 - (get_local $1) - ) - (get_local $0) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (tee_local $0 - (i32.load offset=48 - (get_local $1) - ) - ) - ) - ) - (i32.store offset=52 - (get_local $1) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $0 - (i32.load offset=36 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 40) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$2 - (br_if $label$2 - (i32.eqz - (tee_local $0 - (i32.load - (i32.add - (get_local $1) - (i32.const 24) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 28) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $1) - (i32.const 64) - ) - ) - ) - (func $_ZN16test_transaction19send_cf_action_failEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 96) - ) - ) - ) - (i32.store offset=88 - (get_local $7) - (i32.const 0) - ) - (set_local $3 - (i64.const 0) - ) - (i64.store offset=80 - (get_local $7) - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 18272) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 4) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 416) - ) - (set_local $6 - (i64.const 0) - ) - (loop $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (block $label$11 - (br_if $label$11 - (i64.gt_u - (get_local $3) - (i64.const 5) - ) - ) - (br_if $label$10 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$9) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$8 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$7) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $6 - (i64.or - (get_local $5) - (get_local $6) - ) - ) - (br_if $label$6 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (i64.store offset=16 - (get_local $7) - (get_local $6) - ) - (i64.store offset=8 - (get_local $7) - (get_local $4) - ) - (i32.store - (i32.add - (tee_local $1 - (call $_Znwj - (i32.const 16) - ) - ) - (i32.const 12) - ) - (i32.load - (i32.add - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 12) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.load offset=12 - (get_local $7) - ) - ) - (i32.store offset=24 - (get_local $7) - (get_local $1) - ) - (i32.store - (get_local $1) - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.store offset=32 - (get_local $7) - (tee_local $0 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=16 - (get_local $7) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (set_local $1 - (call $_ZN5eosio6actionC2I18test_action_actionILy5666987383162142720ELy6256973794934521856EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ - (i32.add - (get_local $7) - (i32.const 40) - ) - (i32.add - (get_local $7) - (i32.const 24) - ) - (i32.add - (get_local $7) - (i32.const 80) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $0 - (i32.load offset=24 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=28 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - (i32.load offset=16 - (get_local $1) - ) - ) - (i32.const 18224) - ) - (call $_ZN5eosio4packINS_6actionEEENSt3__16vectorIcNS2_9allocatorIcEEEERKT_ - (i32.add - (get_local $7) - (i32.const 8) - ) - (get_local $1) - ) - (call $send_context_free_inline - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - (i32.sub - (i32.load offset=12 - (get_local $7) - ) - (get_local $0) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $0 - (i32.load offset=8 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=12 - (get_local $7) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 18288) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $0 - (i32.load offset=28 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 32) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$15 - (br_if $label$15 - (i32.eqz - (tee_local $0 - (i32.load offset=16 - (get_local $1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 20) - ) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (block $label$16 - (br_if $label$16 - (i32.eqz - (tee_local $1 - (i32.load offset=80 - (get_local $7) - ) - ) - ) - ) - (i32.store offset=84 - (get_local $7) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 96) - ) - ) - ) - (func $_ZN5eosio6actionC2I18test_action_actionILy5666987383162142720ELy6256973794934521856EEEEONSt3__16vectorINS_16permission_levelENS4_9allocatorIS6_EEEERKT_ (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 24) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $0) - (i32.const 32) - ) - (i64.const 0) - ) - (i64.store - (get_local $0) - (i64.const 5666987383162142720) - ) - (i64.store offset=8 - (get_local $0) - (i64.const 6256973794934521856) - ) - (i32.store offset=16 - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 20) - ) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $6) - (i32.load offset=8 - (get_local $1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $7) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eq - (tee_local $1 - (i32.load - (get_local $2) - ) - ) - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (tee_local $3 - (i32.sub - (get_local $4) - (get_local $1) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $7) - (get_local $3) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $2) - ) - ) - (set_local $5 - (i32.load offset=4 - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $1) - (get_local $4) - ) - ) - (loop $label$2 - (i32.store8 offset=15 - (get_local $7) - (i32.load8_u - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (get_local $5) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $6) - (i32.add - (get_local $7) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $4) - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $1 - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 28) - ) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 32) - ) - (get_local $1) - ) - (call $_ZdlPv - (get_local $1) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - ) - (i64.store align=4 - (get_local $6) - (i64.load - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 36) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN16test_transaction12stateful_apiEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (local $6 i64) - (local $7 i64) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=12 - (get_local $8) - (i32.const 1) - ) - (set_local $2 - (i64.const 0) - ) - (set_local $4 - (i64.const 59) - ) - (set_local $1 - (i32.const 18352) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$0 - (set_local $6 - (i64.const 0) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i64.gt_u - (get_local $2) - (i64.const 15) - ) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$2 - (i64.gt_u - (get_local $2) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $4) - (i64.const 4294967295) - ) - ) - ) - (br $label$1) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $2 - (i64.add - (get_local $2) - (i64.const 1) - ) - ) - (set_local $3 - (i64.or - (get_local $6) - (get_local $3) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $4 - (i64.add - (get_local $4) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $2 - (i64.const 0) - ) - (set_local $4 - (i64.const 59) - ) - (set_local $1 - (i32.const 18384) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (block $label$10 - (br_if $label$10 - (i64.gt_u - (get_local $2) - (i64.const 4) - ) - ) - (br_if $label$9 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$8) - ) - (set_local $6 - (i64.const 0) - ) - (br_if $label$7 - (i64.le_u - (get_local $2) - (i64.const 11) - ) - ) - (br $label$6) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $4) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $2 - (i64.add - (get_local $2) - (i64.const 1) - ) - ) - (set_local $5 - (i64.or - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$5 - (i64.ne - (tee_local $4 - (i64.add - (get_local $4) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (set_local $2 - (i64.const 0) - ) - (set_local $4 - (i64.const 59) - ) - (set_local $1 - (i32.const 18352) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$11 - (set_local $6 - (i64.const 0) - ) - (block $label$12 - (block $label$13 - (br_if $label$13 - (i64.gt_u - (get_local $2) - (i64.const 15) - ) - ) - (block $label$14 - (block $label$15 - (br_if $label$15 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$14) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - (br_if $label$13 - (i64.gt_u - (get_local $2) - (i64.const 11) - ) - ) - (set_local $6 - (i64.shl - (i64.and - (get_local $6) - (i64.const 31) - ) - (i64.and - (get_local $4) - (i64.const 4294967295) - ) - ) - ) - (br $label$12) - ) - (set_local $6 - (i64.and - (get_local $6) - (i64.const 15) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $2 - (i64.add - (get_local $2) - (i64.const 1) - ) - ) - (set_local $7 - (i64.or - (get_local $6) - (get_local $7) - ) - ) - (br_if $label$11 - (i64.ne - (tee_local $4 - (i64.add - (get_local $4) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (drop - (call $db_store_i64 - (get_local $3) - (get_local $5) - (get_local $7) - (i64.const 0) - (i32.add - (get_local $8) - (i32.const 12) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - ) - (func $_ZN16test_transaction16context_free_apiEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 128) - ) - ) - ) - (drop - (call $get_context_free_data - (i32.const 0) - (tee_local $0 - (call $memset - (get_local $0) - (i32.const 0) - (i32.const 128) - ) - ) - (i32.const 128) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 128) - ) - ) - ) - (func $_ZN16test_transaction11new_featureEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 18400) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 9) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i32.eqz - (call $is_feature_active - (get_local $4) - ) - ) - (i32.const 18416) - ) - ) - (func $_ZN16test_transaction18active_new_featureEv - (local $0 i32) - (local $1 i32) - (local $2 i64) - (local $3 i64) - (local $4 i64) - (local $5 i64) - (set_local $3 - (i64.const 0) - ) - (set_local $2 - (i64.const 59) - ) - (set_local $1 - (i32.const 18400) - ) - (set_local $4 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $3) - (i64.const 9) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $0 - (i32.load8_s - (get_local $1) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $5 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $3) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $0 - (select - (i32.add - (get_local $0) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $0) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $5 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $0) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $5 - (i64.shl - (i64.and - (get_local $5) - (i64.const 31) - ) - (i64.and - (get_local $2) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (set_local $4 - (i64.or - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $2 - (i64.add - (get_local $2) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $activate_feature - (get_local $4) - ) - ) - (func $_ZN14test_checktime14checktime_passEv - (call $printi - (i64.const 49995000) - ) - ) - (func $_ZN14test_checktime17checktime_failureEv - (local $0 i64) - (local $1 i64) - (local $2 i64) - (local $3 i64) - (set_local $2 - (i64.const 0) - ) - (set_local $1 - (i64.const 1) - ) - (set_local $3 - (i64.const 0) - ) - (loop $label$0 - (set_local $2 - (i64.add - (i64.and - (tee_local $0 - (get_local $2) - ) - (i64.const 4294967295) - ) - (get_local $3) - ) - ) - (set_local $3 - (i64.add - (get_local $3) - (i64.const 1) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $1 - (i64.add - (get_local $1) - (i64.const -1) - ) - ) - (i64.const 8446744073709551617) - ) - ) - ) - (call $printi - (i64.shr_s - (i64.shl - (i64.sub - (get_local $0) - (get_local $1) - ) - (i64.const 32) - ) - (i64.const 32) - ) - ) - ) - (func $_ZN14test_checktime22checktime_sha1_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha1 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN14test_checktime29checktime_assert_sha1_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $assert_sha1 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN14test_checktime24checktime_sha256_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $sha256 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN14test_checktime31checktime_assert_sha256_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $assert_sha256 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN14test_checktime24checktime_sha512_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $sha512 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - (func $_ZN14test_checktime31checktime_assert_sha512_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $assert_sha512 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 64) - ) - ) - ) - (func $_ZN14test_checktime27checktime_ripemd160_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $ripemd160 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN14test_checktime34checktime_assert_ripemd160_failureEv - (local $0 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $0 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $assert_ripemd160 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (get_local $0) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $0) - (i32.const 32) - ) - ) - ) - (func $_ZN15test_permission19check_authorizationEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i64) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $9 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 64) - ) - ) - ) - (call $_ZN5eosio18unpack_action_dataI14check_auth_msgEET_v - (i32.add - (get_local $9) - (i32.const 16) - ) - ) - (i32.store offset=8 - (get_local $9) - (i32.const 0) - ) - (i64.store - (get_local $9) - (i64.const 0) - ) - (set_local $7 - (i32.const 34) - ) - (set_local $8 - (i64.extend_u/i32 - (i32.div_s - (tee_local $6 - (i32.sub - (tee_local $4 - (i32.load - (i32.add - (get_local $9) - (i32.const 36) - ) - ) - ) - (tee_local $5 - (i32.load offset=32 - (get_local $9) - ) - ) - ) - ) - (i32.const 34) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $9) - (i32.const 32) - ) - ) - (loop $label$0 - (set_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $8 - (i64.shr_u - (get_local $8) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $5) - (get_local $4) - ) - ) - (br_if $label$2 - (tee_local $7 - (i32.add - (i32.sub - (tee_local $4 - (i32.add - (get_local $6) - (i32.const -34) - ) - ) - (i32.rem_u - (get_local $4) - (i32.const 34) - ) - ) - (get_local $7) - ) - ) - ) - (set_local $4 - (i32.const 0) - ) - (set_local $7 - (i32.const 0) - ) - (br $label$1) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const -34) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $9) - (get_local $7) - ) - (set_local $4 - (i32.load offset=4 - (get_local $9) - ) - ) - (set_local $7 - (i32.load - (get_local $9) - ) - ) - ) - (i32.store offset=52 - (get_local $9) - (get_local $7) - ) - (i32.store offset=48 - (get_local $9) - (get_local $7) - ) - (i32.store offset=56 - (get_local $9) - (get_local $4) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEE10public_keyEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE - (i32.add - (get_local $9) - (i32.const 48) - ) - (get_local $3) - ) - ) - (i64.store offset=48 - (get_local $9) - (i64.extend_s/i32 - (call $check_permission_authorization - (i64.load offset=16 - (get_local $9) - ) - (i64.load offset=24 - (get_local $9) - ) - (tee_local $7 - (i32.load - (get_local $9) - ) - ) - (i32.sub - (i32.load offset=4 - (get_local $9) - ) - (get_local $7) - ) - (i32.const 0) - (i32.const 0) - (i64.const 9223372036854775807) - ) - ) - ) - (block $label$4 - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.eq - (tee_local $7 - (call $db_lowerbound_i64 - (get_local $0) - (get_local $0) - (get_local $0) - (i64.const 1) - ) - ) - (i32.const -1) - ) - ) - (call $db_update_i64 - (get_local $7) - (get_local $0) - (i32.add - (get_local $9) - (i32.const 48) - ) - (i32.const 8) - ) - (br_if $label$5 - (tee_local $7 - (i32.load - (get_local $9) - ) - ) - ) - (br $label$4) - ) - (drop - (call $db_store_i64 - (get_local $0) - (get_local $0) - (get_local $0) - (i64.const 1) - (i32.add - (get_local $9) - (i32.const 48) - ) - (i32.const 8) - ) - ) - (br_if $label$4 - (i32.eqz - (tee_local $7 - (i32.load - (get_local $9) - ) - ) - ) - ) - ) - (i32.store offset=4 - (get_local $9) - (get_local $7) - ) - (call $_ZdlPv - (get_local $7) - ) - ) - (block $label$7 - (br_if $label$7 - (i32.eqz - (tee_local $7 - (i32.load offset=32 - (get_local $9) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $9) - (i32.const 36) - ) - (get_local $7) - ) - (call $_ZdlPv - (get_local $7) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $9) - (i32.const 64) - ) - ) - ) - (func $_ZN5eosio18unpack_action_dataI14check_auth_msgEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (set_local $4 - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $3) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $3 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (get_local $3) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $3) - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.const 0) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store - (get_local $4) - (get_local $3) - ) - (i32.store offset=8 - (get_local $4) - (tee_local $2 - (i32.add - (get_local $3) - (get_local $1) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (get_local $1) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $3) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (get_local $2) - (tee_local $1 - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $1) - (i32.const 8) - ) - ) - (i32.store offset=4 - (get_local $4) - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEE10public_keyEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE - (get_local $4) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEE10public_keyEERT_S6_RKNSt3__16vectorIT0_NS7_9allocatorIS9_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 80) - ) - ) - ) - (set_local $6 - (i64.extend_u/i32 - (i32.div_s - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - (i32.const 34) - ) - ) - ) - (set_local $7 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $2 - (i32.wrap/i64 - (get_local $6) - ) - ) - (i32.store8 offset=40 - (get_local $8) - (i32.or - (i32.shl - (tee_local $3 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $2) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $7) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $5) - ) - (i32.add - (get_local $8) - (i32.const 40) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $5) - (tee_local $7 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $3) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $5 - (i32.load - (get_local $1) - ) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$2 - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 6) - ) - (get_local $5) - (i32.const 34) - ) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 40) - ) - (i32.add - (get_local $8) - (i32.const 6) - ) - (i32.const 34) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $7) - ) - (i32.const 33) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $2) - ) - (i32.add - (get_local $8) - (i32.const 40) - ) - (i32.const 34) - ) - ) - (i32.store - (get_local $2) - (tee_local $7 - (i32.add - (i32.load - (get_local $2) - ) - (i32.const 34) - ) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 34) - ) - ) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 80) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEE10public_keyEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.const 848) - ) - (set_local $4 - (i32.load8_u - (tee_local $5 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $7 - (i32.and - (get_local $7) - (i32.const 255) - ) - ) - ) - ) - (get_local $6) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.le_u - (tee_local $5 - (i32.wrap/i64 - (get_local $6) - ) - ) - (tee_local $7 - (i32.div_s - (i32.sub - (tee_local $3 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - ) - (i32.const 34) - ) - ) - ) - ) - (call $_ZNSt3__16vectorI10public_keyNS_9allocatorIS1_EEE8__appendEj - (get_local $1) - (i32.sub - (get_local $5) - (get_local $7) - ) - ) - (br_if $label$2 - (i32.ne - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (br $label$1) - ) - (block $label$4 - (br_if $label$4 - (i32.ge_u - (get_local $5) - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (tee_local $3 - (i32.add - (get_local $4) - (i32.mul - (get_local $5) - (i32.const 34) - ) - ) - ) - ) - ) - (br_if $label$1 - (i32.eq - (get_local $4) - (get_local $3) - ) - ) - ) - (set_local $7 - (i32.load - (tee_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$5 - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $7) - ) - (i32.const 33) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $4) - (i32.load - (get_local $5) - ) - (i32.const 34) - ) - ) - (i32.store - (get_local $5) - (tee_local $7 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 34) - ) - ) - ) - (br_if $label$5 - (i32.ne - (get_local $3) - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 34) - ) - ) - ) - ) - ) - ) - (get_local $0) - ) - (func $_ZNSt3__16vectorI10public_keyNS_9allocatorIS1_EEE8__appendEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (i32.div_s - (i32.sub - (tee_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (i32.const 34) - ) - (get_local $1) - ) - ) - (br_if $label$2 - (i32.ge_u - (tee_local $4 - (i32.add - (tee_local $3 - (i32.div_s - (i32.sub - (get_local $6) - (tee_local $5 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 34) - ) - ) - (get_local $1) - ) - ) - (i32.const 126322568) - ) - ) - (set_local $6 - (i32.const 126322567) - ) - (block $label$5 - (br_if $label$5 - (i32.gt_u - (tee_local $2 - (i32.div_s - (i32.sub - (get_local $2) - (get_local $5) - ) - (i32.const 34) - ) - ) - (i32.const 63161282) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $6 - (select - (get_local $4) - (tee_local $6 - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $6) - (get_local $4) - ) - ) - ) - ) - ) - ) - (set_local $2 - (call $_Znwj - (i32.mul - (get_local $6) - (i32.const 34) - ) - ) - ) - (br $label$1) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$6 - (drop - (call $memset - (get_local $6) - (i32.const 0) - (i32.const 34) - ) - ) - (i32.store - (get_local $0) - (tee_local $6 - (i32.add - (i32.load - (get_local $0) - ) - (i32.const 34) - ) - ) - ) - (br_if $label$6 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - (br $label$0) - ) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $2 - (i32.const 0) - ) - (br $label$1) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $4 - (i32.add - (get_local $2) - (i32.mul - (get_local $6) - (i32.const 34) - ) - ) - ) - (set_local $6 - (tee_local $5 - (i32.add - (get_local $2) - (i32.mul - (get_local $3) - (i32.const 34) - ) - ) - ) - ) - (loop $label$7 - (set_local $6 - (i32.add - (call $memset - (get_local $6) - (i32.const 0) - (i32.const 34) - ) - (i32.const 34) - ) - ) - (br_if $label$7 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.mul - (i32.div_s - (tee_local $2 - (i32.sub - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $1 - (i32.load - (get_local $0) - ) - ) - ) - ) - (i32.const -34) - ) - (i32.const 34) - ) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.lt_s - (get_local $2) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $5) - (get_local $1) - (get_local $2) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $5) - ) - (i32.store - (get_local $3) - (get_local $6) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $4) - ) - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - (return) - ) - ) - (func $_ZN15test_permission25test_permission_last_usedEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - (call $eosio_assert - (i64.eq - (call $get_permission_last_used - (i64.load offset=8 - (get_local $3) - ) - (i64.load offset=16 - (get_local $3) - ) - ) - (i64.load offset=24 - (get_local $3) - ) - ) - (i32.const 18464) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 32) - ) - ) - ) - (func $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (set_local $3 - (tee_local $2 - (i32.load offset=4 - (i32.const 0) - ) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $2 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $2) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $2) - (get_local $1) - ) - ) - (call $eosio_assert - (i32.gt_u - (get_local $1) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $2) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (tee_local $1 - (i32.and - (get_local $1) - (i32.const -8) - ) - ) - (i32.const 8) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 8) - ) - (i32.add - (get_local $2) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.ne - (get_local $1) - (i32.const 16) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $0) - (i32.const 16) - ) - (i32.add - (get_local $2) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $3) - ) - ) - (func $_ZN15test_permission26test_account_creation_timeEyyy (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $3 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - (call $eosio_assert - (i64.eq - (call $get_account_creation_time - (i64.load offset=8 - (get_local $3) - ) - ) - (i64.load offset=24 - (get_local $3) - ) - ) - (i32.const 18512) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 32) - ) - ) - ) - (func $_ZN15test_datastream10test_basicEv - (local $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 160) - ) - ) - ) - (i32.store8 offset=144 - (get_local $8) - (i32.const 1) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.ne - (i32.load8_u offset=144 - (get_local $8) - ) - (i32.const 0) - ) - (i32.const 18560) - ) - (i32.store8 offset=144 - (get_local $8) - (i32.const 0) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.eqz - (i32.load8_u offset=144 - (get_local $8) - ) - ) - (i32.const 18560) - ) - (i32.store8 offset=8 - (get_local $8) - (i32.const 133) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load8_u offset=8 - (get_local $8) - ) - (i32.load8_u offset=144 - (get_local $8) - ) - ) - (i32.const 18576) - ) - (i32.store8 offset=8 - (get_local $8) - (i32.const 127) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 1) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load8_u offset=8 - (get_local $8) - ) - (i32.load8_u offset=144 - (get_local $8) - ) - ) - (i32.const 18592) - ) - (i32.store16 offset=8 - (get_local $8) - (i32.const 53191) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 2) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 2) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load16_u offset=8 - (get_local $8) - ) - (i32.load16_u offset=144 - (get_local $8) - ) - ) - (i32.const 18608) - ) - (i32.store16 offset=8 - (get_local $8) - (i32.const 12345) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 2) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 2) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load16_u offset=8 - (get_local $8) - ) - (i32.load16_u offset=144 - (get_local $8) - ) - ) - (i32.const 18624) - ) - (i32.store offset=8 - (get_local $8) - (i32.const -1234567890) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=8 - (get_local $8) - ) - (i32.load offset=144 - (get_local $8) - ) - ) - (i32.const 18640) - ) - (i32.store offset=8 - (get_local $8) - (i32.const -1060399406) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=8 - (get_local $8) - ) - (i32.load offset=144 - (get_local $8) - ) - ) - (i32.const 18656) - ) - (i64.store offset=8 - (get_local $8) - (i64.const -9223372036854775808) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $8) - ) - (i64.load offset=144 - (get_local $8) - ) - ) - (i32.const 18672) - ) - (i64.store offset=8 - (get_local $8) - (i64.const 9223372036854775807) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=8 - (get_local $8) - ) - (i64.load offset=144 - (get_local $8) - ) - ) - (i32.const 18688) - ) - (i32.store offset=8 - (get_local $8) - (i32.const 1067316150) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (f32.lt - (call $fabsf - (f32.sub - (f32.load offset=8 - (get_local $8) - ) - (f32.load offset=144 - (get_local $8) - ) - ) - ) - (f32.const 1.000000013351432e-10) - ) - (i32.const 18704) - ) - (i64.store offset=8 - (get_local $8) - (i64.const 4599676419421066581) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.add - (get_local $8) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (f64.lt - (call $fabs - (f64.sub - (f64.load offset=8 - (get_local $8) - ) - (f64.load offset=144 - (get_local $8) - ) - ) - ) - (f64.const 1e-20) - ) - (i32.const 18720) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 18728) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (tee_local $7 - (i32.or - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (i32.const 18736) - (i32.const 8) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (tee_local $2 - (i32.add - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 8) - ) - ) - (get_local $7) - (i32.const 8) - ) - ) - (set_local $6 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.ne - (i32.load offset=144 - (get_local $8) - ) - (i32.const 1) - ) - ) - (set_local $6 - (f64.lt - (call $fabs - (f64.sub - (f64.const 1.23456) - (f64.load - (get_local $2) - ) - ) - ) - (f64.const 1e-20) - ) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 18752) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 18760) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $7) - (i32.const 18764) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.or - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 4) - ) - (get_local $7) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.and - (i32.eq - (i32.load offset=144 - (get_local $8) - ) - (i32.const 10) - ) - (i32.eq - (i32.load offset=148 - (get_local $8) - ) - (i32.const 20) - ) - ) - (i32.const 18768) - ) - (i32.store - (i32.add - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $8) - (i64.const 0) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.ge_u - (tee_local $6 - (call $strlen - (i32.const 1360) - ) - ) - (i32.const -16) - ) - ) - (block $label$8 - (block $label$9 - (block $label$10 - (br_if $label$10 - (i32.ge_u - (get_local $6) - (i32.const 11) - ) - ) - (i32.store8 offset=16 - (get_local $8) - (i32.shl - (get_local $6) - (i32.const 1) - ) - ) - (set_local $2 - (i32.or - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 1) - ) - ) - (br_if $label$9 - (get_local $6) - ) - (br $label$8) - ) - (set_local $2 - (call $_Znwj - (tee_local $3 - (i32.and - (i32.add - (get_local $6) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store offset=16 - (get_local $8) - (i32.or - (get_local $3) - (i32.const 1) - ) - ) - (i32.store offset=24 - (get_local $8) - (get_local $2) - ) - (i32.store offset=20 - (get_local $8) - (get_local $6) - ) - ) - (drop - (call $memcpy - (get_local $2) - (i32.const 1360) - (get_local $6) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $2) - (get_local $6) - ) - (i32.const 0) - ) - (call $_ZN8testtypeINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEE3runERKS6_PKc - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 18784) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (i32.and - (i32.load8_u offset=16 - (get_local $8) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load offset=24 - (get_local $8) - ) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $8) - (i64.const 0) - ) - (i64.store align=4 - (tee_local $6 - (call $_Znwj - (i32.const 12) - ) - ) - (i64.const 85899345930) - ) - (i32.store offset=8 - (get_local $6) - (i32.const 30) - ) - (i32.store offset=16 - (get_local $8) - (get_local $6) - ) - (i32.store offset=24 - (get_local $8) - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 12) - ) - ) - ) - (i32.store offset=20 - (get_local $8) - (get_local $6) - ) - (call $_ZN8testtypeINSt3__16vectorIiNS0_9allocatorIiEEEEE3runERKS4_PKc - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 18800) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $6 - (i32.load offset=16 - (get_local $8) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $8) - (get_local $6) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - (set_local $6 - (i32.const 0) - ) - (i32.store offset=24 - (get_local $8) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $8) - (i64.const 0) - ) - (call $_ZN8testtypeINSt3__16vectorIiNS0_9allocatorIiEEEEE3runERKS4_PKc - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 18816) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $2 - (i32.load offset=16 - (get_local $8) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $8) - (get_local $2) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 18832) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (get_local $7) - (i32.const 18836) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (tee_local $2 - (i32.or - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 8) - ) - ) - (i32.const 18840) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.or - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 4) - ) - (get_local $7) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 8) - ) - (get_local $2) - (i32.const 4) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.ne - (i32.load offset=144 - (get_local $8) - ) - (i32.const 10) - ) - ) - (br_if $label$14 - (i32.ne - (i32.load offset=148 - (get_local $8) - ) - (i32.const 20) - ) - ) - (set_local $6 - (i32.eq - (i32.load - (i32.add - (get_local $8) - (i32.const 152) - ) - ) - (i32.const 30) - ) - ) - ) - (call $eosio_assert - (get_local $6) - (i32.const 18848) - ) - (i64.store align=4 - (i32.add - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 8) - ) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $8) - (i64.const 1) - ) - (set_local $6 - (i32.or - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (br_if $label$6 - (i32.ge_u - (tee_local $7 - (call $strlen - (i32.const 18864) - ) - ) - (i32.const -16) - ) - ) - (block $label$15 - (block $label$16 - (block $label$17 - (br_if $label$17 - (i32.ge_u - (get_local $7) - (i32.const 11) - ) - ) - (i32.store8 offset=20 - (get_local $8) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$16 - (get_local $7) - ) - (br $label$15) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 28) - ) - (tee_local $6 - (call $_Znwj - (tee_local $2 - (i32.and - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 24) - ) - (get_local $7) - ) - (i32.store offset=20 - (get_local $8) - (i32.or - (get_local $2) - (i32.const 1) - ) - ) - ) - (drop - (call $memcpy - (get_local $6) - (i32.const 18864) - (get_local $7) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $6) - (get_local $7) - ) - (i32.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $8) - (i32.const 40) - ) - (i64.const 0) - ) - (i64.store offset=32 - (get_local $8) - (i64.const 2) - ) - (set_local $6 - (i32.add - (get_local $8) - (i32.const 36) - ) - ) - (br_if $label$5 - (i32.ge_u - (tee_local $7 - (call $strlen - (i32.const 18880) - ) - ) - (i32.const -16) - ) - ) - (block $label$18 - (block $label$19 - (block $label$20 - (br_if $label$20 - (i32.ge_u - (get_local $7) - (i32.const 11) - ) - ) - (i32.store8 - (i32.add - (get_local $8) - (i32.const 36) - ) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$19 - (get_local $7) - ) - (br $label$18) - ) - (set_local $6 - (call $_Znwj - (tee_local $2 - (i32.and - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 36) - ) - (i32.or - (get_local $2) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 44) - ) - (get_local $6) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 40) - ) - (get_local $7) - ) - ) - (drop - (call $memcpy - (get_local $6) - (i32.const 18880) - (get_local $7) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $6) - (get_local $7) - ) - (i32.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $8) - (i32.const 56) - ) - (i64.const 0) - ) - (i64.store offset=48 - (get_local $8) - (i64.const 3) - ) - (set_local $6 - (i32.add - (get_local $8) - (i32.const 52) - ) - ) - (br_if $label$4 - (i32.ge_u - (tee_local $7 - (call $strlen - (i32.const 18896) - ) - ) - (i32.const -16) - ) - ) - (block $label$21 - (block $label$22 - (block $label$23 - (br_if $label$23 - (i32.ge_u - (get_local $7) - (i32.const 11) - ) - ) - (i32.store8 - (i32.add - (get_local $8) - (i32.const 52) - ) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$22 - (get_local $7) - ) - (br $label$21) - ) - (set_local $6 - (call $_Znwj - (tee_local $2 - (i32.and - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 52) - ) - (i32.or - (get_local $2) - (i32.const 1) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 60) - ) - (get_local $6) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 56) - ) - (get_local $7) - ) - ) - (drop - (call $memcpy - (get_local $6) - (i32.const 18896) - (get_local $7) - ) - ) - ) - (set_local $2 - (i32.const 0) - ) - (i32.store8 - (i32.add - (get_local $6) - (get_local $7) - ) - (i32.const 0) - ) - (i32.store offset=152 - (get_local $8) - (i32.const 0) - ) - (i32.store offset=148 - (get_local $8) - (i32.const 0) - ) - (i32.store offset=144 - (get_local $8) - (tee_local $1 - (i32.or - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 4) - ) - ) - ) - (set_local $0 - (i32.add - (get_local $8) - (i32.const 64) - ) - ) - (set_local $5 - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (set_local $4 - (i32.add - (get_local $8) - (i32.const 152) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $1) - (get_local $1) - ) - ) - (br $label$3) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $6) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $6) - ) - (unreachable) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $6) - ) - (unreachable) - ) - (set_local $9 - (i32.const 21) - ) - (br $label$1) - ) - (set_local $9 - (i32.const 3) - ) - ) - (loop $label$24 - (block $label$25 - (block $label$26 - (block $label$27 - (block $label$28 - (block $label$29 - (block $label$30 - (block $label$31 - (block $label$32 - (block $label$33 - (block $label$34 - (block $label$35 - (block $label$36 - (block $label$37 - (block $label$38 - (block $label$39 - (block $label$40 - (block $label$41 - (block $label$42 - (block $label$43 - (block $label$44 - (block $label$45 - (block $label$46 - (block $label$47 - (block $label$48 - (block $label$49 - (block $label$50 - (block $label$51 - (block $label$52 - (block $label$53 - (block $label$54 - (block $label$55 - (block $label$56 - (block $label$57 - (block $label$58 - (block $label$59 - (block $label$60 - (block $label$61 - (block $label$62 - (block $label$63 - (block $label$64 - (block $label$65 - (block $label$66 - (block $label$67 - (block $label$68 - (block $label$69 - (block $label$70 - (block $label$71 - (block $label$72 - (block $label$73 - (block $label$74 - (block $label$75 - (block $label$76 - (block $label$77 - (block $label$78 - (block $label$79 - (block $label$80 - (block $label$81 - (block $label$82 - (block $label$83 - (block $label$84 - (block $label$85 - (block $label$86 - (block $label$87 - (block $label$88 - (block $label$89 - (block $label$90 - (block $label$91 - (block $label$92 - (block $label$93 - (br_table $label$76 $label$72 $label$93 $label$92 $label$91 $label$87 $label$84 $label$81 $label$79 $label$77 $label$75 $label$74 $label$73 $label$78 $label$82 $label$80 $label$83 $label$86 $label$85 $label$89 $label$88 $label$90 $label$71 $label$70 $label$69 $label$68 $label$67 $label$66 $label$65 $label$64 $label$62 $label$61 $label$60 $label$59 $label$58 $label$63 $label$57 $label$57 - (get_local $9) - ) - ) - (set_local $2 - (i32.load offset=148 - (get_local $8) - ) - ) - (br_if $label$56 - (i32.eq - (i32.load offset=144 - (get_local $8) - ) - (get_local $1) - ) - ) - (set_local $9 - (i32.const 3) - ) - (br $label$24) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$41 - (i32.eqz - (get_local $2) - ) - ) - (set_local $9 - (i32.const 4) - ) - (br $label$24) - ) - (br_if $label$42 - (tee_local $6 - (i32.load offset=4 - (tee_local $7 - (get_local $6) - ) - ) - ) - ) - (br $label$43) - ) - (set_local $7 - (get_local $1) - ) - (br_if $label$33 - (get_local $2) - ) - (br $label$34) - ) - (set_local $6 - (get_local $1) - ) - (set_local $9 - (i32.const 20) - ) - (br $label$24) - ) - (set_local $3 - (i32.eq - (i32.load - (tee_local $7 - (i32.load offset=8 - (get_local $6) - ) - ) - ) - (get_local $6) - ) - ) - (set_local $6 - (get_local $7) - ) - (br_if $label$40 - (get_local $3) - ) - (set_local $9 - (i32.const 5) - ) - (br $label$24) - ) - (br_if $label$39 - (i32.ge_s - (i32.load offset=16 - (get_local $7) - ) - (tee_local $6 - (i32.load - (get_local $5) - ) - ) - ) - ) - (set_local $9 - (i32.const 17) - ) - (br $label$24) - ) - (br_if $label$55 - (i32.eqz - (get_local $2) - ) - ) - (set_local $9 - (i32.const 18) - ) - (br $label$24) - ) - (br_if $label$53 - (i32.load - (tee_local $2 - (i32.add - (get_local $7) - (i32.const 4) - ) - ) - ) - ) - (br $label$54) - ) - (set_local $3 - (get_local $1) - ) - (br_if $label$52 - (get_local $2) - ) - (set_local $9 - (i32.const 16) - ) - (br $label$24) - ) - (set_local $7 - (get_local $1) - ) - (br_if $label$45 - (i32.load - (tee_local $2 - (get_local $1) - ) - ) - ) - (br $label$46) - ) - (set_local $2 - (get_local $7) - ) - (set_local $9 - (i32.const 7) - ) - (br $label$24) - ) - (br_if $label$38 - (i32.ge_s - (get_local $6) - (tee_local $7 - (i32.load offset=16 - (get_local $2) - ) - ) - ) - ) - (set_local $9 - (i32.const 15) - ) - (br $label$24) - ) - (set_local $3 - (get_local $2) - ) - (br_if $label$47 - (tee_local $7 - (i32.load - (get_local $2) - ) - ) - ) - (br $label$48) - ) - (br_if $label$37 - (i32.ge_s - (get_local $7) - (get_local $6) - ) - ) - (set_local $9 - (i32.const 13) - ) - (br $label$24) - ) - (set_local $3 - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - (br_if $label$36 - (tee_local $7 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - (set_local $9 - (i32.const 9) - ) - (br $label$24) - ) - (set_local $7 - (get_local $2) - ) - (br_if $label$50 - (i32.load - (tee_local $2 - (get_local $3) - ) - ) - ) - (br $label$51) - ) - (set_local $7 - (get_local $2) - ) - (br_if $label$49 - (i32.load - (get_local $2) - ) - ) - (set_local $9 - (i32.const 10) - ) - (br $label$24) - ) - (i32.store offset=16 - (tee_local $6 - (call $_Znwj - (i32.const 32) - ) - ) - (i32.load - (get_local $5) - ) - ) - (drop - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ - (i32.add - (get_local $6) - (i32.const 20) - ) - (i32.add - (get_local $5) - (i32.const 4) - ) - ) - ) - (i32.store offset=8 - (get_local $6) - (get_local $7) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store - (get_local $2) - (get_local $6) - ) - (br_if $label$35 - (i32.eqz - (tee_local $7 - (i32.load - (i32.load offset=144 - (get_local $8) - ) - ) - ) - ) - ) - (set_local $9 - (i32.const 11) - ) - (br $label$24) - ) - (i32.store offset=144 - (get_local $8) - (get_local $7) - ) - (set_local $6 - (i32.load - (get_local $2) - ) - ) - (set_local $9 - (i32.const 12) - ) - (br $label$24) - ) - (call $_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_ - (i32.load offset=148 - (get_local $8) - ) - (get_local $6) - ) - (i32.store - (get_local $4) - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - (set_local $9 - (i32.const 1) - ) - (br $label$24) - ) - (br_if $label$44 - (i32.ne - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 16) - ) - ) - (get_local $0) - ) - ) - (set_local $9 - (i32.const 22) - ) - (br $label$24) - ) - (call $_ZN8testtypeINSt3__13mapIiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4lessIiEENS5_INS0_4pairIKiS7_EEEEEEE3runERKSE_PKc - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.const 18912) - ) - (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE - (i32.add - (get_local $8) - (i32.const 144) - ) - (i32.load offset=148 - (get_local $8) - ) - ) - (br_if $label$32 - (i32.eqz - (i32.and - (i32.load8_u - (i32.add - (get_local $8) - (i32.const 52) - ) - ) - (i32.const 1) - ) - ) - ) - (set_local $9 - (i32.const 23) - ) - (br $label$24) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $8) - (i32.const 60) - ) - ) - ) - (set_local $9 - (i32.const 24) - ) - (br $label$24) - ) - (br_if $label$31 - (i32.eqz - (i32.and - (i32.load8_u - (i32.add - (get_local $8) - (i32.const 36) - ) - ) - (i32.const 1) - ) - ) - ) - (set_local $9 - (i32.const 25) - ) - (br $label$24) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $8) - (i32.const 44) - ) - ) - ) - (set_local $9 - (i32.const 26) - ) - (br $label$24) - ) - (br_if $label$30 - (i32.eqz - (i32.and - (i32.load8_u offset=20 - (get_local $8) - ) - (i32.const 1) - ) - ) - ) - (set_local $9 - (i32.const 27) - ) - (br $label$24) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $8) - (i32.const 28) - ) - ) - ) - (set_local $9 - (i32.const 28) - ) - (br $label$24) - ) - (i64.store align=4 - (i32.add - (get_local $8) - (i32.const 24) - ) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $8) - (i64.const 1) - ) - (set_local $6 - (i32.or - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (br_if $label$29 - (i32.gt_u - (tee_local $7 - (call $strlen - (i32.const 7840) - ) - ) - (i32.const -17) - ) - ) - (set_local $9 - (i32.const 29) - ) - (br $label$24) - ) - (br_if $label$28 - (i32.ge_u - (get_local $7) - (i32.const 11) - ) - ) - (set_local $9 - (i32.const 35) - ) - (br $label$24) - ) - (i32.store8 offset=20 - (get_local $8) - (i32.shl - (get_local $7) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$26 - (get_local $7) - ) - (br $label$27) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 28) - ) - (tee_local $6 - (call $_Znwj - (tee_local $2 - (i32.and - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const 24) - ) - (get_local $7) - ) - (i32.store offset=20 - (get_local $8) - (i32.or - (get_local $2) - (i32.const 1) - ) - ) - (set_local $9 - (i32.const 31) - ) - (br $label$24) - ) - (drop - (call $memcpy - (get_local $6) - (i32.const 7840) - (get_local $7) - ) - ) - (set_local $9 - (i32.const 32) - ) - (br $label$24) - ) - (i32.store8 - (i32.add - (get_local $6) - (get_local $7) - ) - (i32.const 0) - ) - (i64.store offset=32 - (get_local $8) - (i64.const 4614688343118974445) - ) - (call $_ZN8testtypeINSt3__15tupleIJiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEdEEEE3runERKS8_PKc - (i32.add - (get_local $8) - (i32.const 16) - ) - (i32.const 18928) - ) - (br_if $label$25 - (i32.eqz - (i32.and - (i32.load8_u offset=20 - (get_local $8) - ) - (i32.const 1) - ) - ) - ) - (set_local $9 - (i32.const 33) - ) - (br $label$24) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $8) - (i32.const 28) - ) - ) - ) - (set_local $9 - (i32.const 34) - ) - (br $label$24) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 160) - ) - ) - (return) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $6) - ) - (unreachable) - ) - (set_local $9 - (i32.const 21) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 16) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 10) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 1) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 7) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 10) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 1) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 1) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 0) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 14) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 10) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 1) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 2) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 5) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 4) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 19) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 20) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 6) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 8) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 9) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 14) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 12) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 16) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 18) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 24) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 26) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 28) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 36) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 30) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 32) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 31) - ) - (br $label$24) - ) - (set_local $9 - (i32.const 34) - ) - (br $label$24) - ) - ) - (func $_ZN8testtypeINSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEE3runERKS6_PKc (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 160) - ) - ) - ) - (i32.store offset=24 - (get_local $8) - (i32.add - (get_local $8) - (i32.const 160) - ) - ) - (i32.store offset=20 - (get_local $8) - (i32.add - (get_local $8) - (i32.const 32) - ) - ) - (i32.store offset=16 - (get_local $8) - (i32.add - (get_local $8) - (i32.const 32) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE - (i32.add - (get_local $8) - (i32.const 16) - ) - (get_local $0) - ) - ) - (i64.store - (get_local $8) - (i64.const 0) - ) - (set_local $7 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $8) - (i32.const 0) - ) - (i32.store offset=20 - (get_local $8) - (i32.load offset=16 - (get_local $8) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE - (i32.add - (get_local $8) - (i32.const 16) - ) - (get_local $8) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.ne - (tee_local $4 - (select - (i32.load offset=4 - (get_local $0) - ) - (tee_local $3 - (i32.shr_u - (tee_local $5 - (i32.load8_u - (get_local $0) - ) - ) - (i32.const 1) - ) - ) - (tee_local $2 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - (select - (i32.load offset=4 - (get_local $8) - ) - (i32.shr_u - (tee_local $5 - (i32.load8_u - (get_local $8) - ) - ) - (i32.const 1) - ) - (tee_local $5 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - ) - (set_local $5 - (select - (i32.load - (i32.add - (get_local $8) - (i32.const 8) - ) - ) - (i32.or - (get_local $8) - (i32.const 1) - ) - (get_local $5) - ) - ) - (set_local $6 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (get_local $2) - ) - (br_if $label$2 - (i32.eqz - (get_local $4) - ) - ) - (set_local $0 - (i32.sub - (i32.const 0) - (get_local $3) - ) - ) - (loop $label$4 - (br_if $label$1 - (i32.ne - (i32.load8_u - (get_local $6) - ) - (i32.load8_u - (get_local $5) - ) - ) - ) - (set_local $7 - (i32.const 1) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$4 - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - ) - (br $label$0) - ) - ) - (br_if $label$2 - (i32.eqz - (get_local $4) - ) - ) - (set_local $7 - (i32.eqz - (call $memcmp - (select - (i32.load offset=8 - (get_local $0) - ) - (get_local $6) - (get_local $2) - ) - (get_local $5) - (get_local $4) - ) - ) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 1) - ) - (br $label$0) - ) - (set_local $7 - (i32.const 0) - ) - ) - (call $eosio_assert - (get_local $7) - (get_local $1) - ) - (block $label$5 - (br_if $label$5 - (i32.eqz - (i32.and - (i32.load8_u - (get_local $8) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $8) - (i32.const 8) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 160) - ) - ) - ) - (func $_ZN8testtypeINSt3__16vectorIiNS0_9allocatorIiEEEEE3runERKS4_PKc (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $5 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 160) - ) - ) - ) - (i32.store offset=24 - (get_local $5) - (i32.add - (get_local $5) - (i32.const 160) - ) - ) - (i32.store offset=20 - (get_local $5) - (i32.add - (get_local $5) - (i32.const 32) - ) - ) - (i32.store offset=16 - (get_local $5) - (i32.add - (get_local $5) - (i32.const 32) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEiEERT_S5_RKNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE - (i32.add - (get_local $5) - (i32.const 16) - ) - (get_local $0) - ) - ) - (i64.store - (get_local $5) - (i64.const 0) - ) - (set_local $4 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $5) - (i32.const 0) - ) - (i32.store offset=20 - (get_local $5) - (i32.load offset=16 - (get_local $5) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPcEEiEERT_S5_RNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE - (i32.add - (get_local $5) - (i32.const 16) - ) - (get_local $5) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.ne - (i32.sub - (tee_local $2 - (i32.load offset=4 - (get_local $0) - ) - ) - (tee_local $0 - (i32.load - (get_local $0) - ) - ) - ) - (i32.sub - (i32.load offset=4 - (get_local $5) - ) - (tee_local $3 - (i32.load - (get_local $5) - ) - ) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (get_local $0) - (get_local $2) - ) - ) - (loop $label$2 - (br_if $label$0 - (i32.ne - (i32.load - (get_local $0) - ) - (i32.load - (get_local $3) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 4) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $2) - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - ) - ) - (set_local $4 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $4) - (get_local $1) - ) - (block $label$3 - (br_if $label$3 - (i32.eqz - (tee_local $0 - (i32.load - (get_local $5) - ) - ) - ) - ) - (i32.store offset=4 - (get_local $5) - (get_local $0) - ) - (call $_ZdlPv - (get_local $0) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $5) - (i32.const 160) - ) - ) - ) - (func $_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_ (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (i32.store8 offset=12 - (get_local $1) - (tee_local $3 - (i32.eq - (get_local $1) - (get_local $0) - ) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (br_if $label$2 - (get_local $3) - ) - (block $label$3 - (block $label$4 - (block $label$5 - (loop $label$6 - (br_if $label$2 - (i32.load8_u offset=12 - (tee_local $2 - (i32.load offset=8 - (get_local $1) - ) - ) - ) - ) - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.eq - (tee_local $4 - (i32.load - (tee_local $3 - (i32.load offset=8 - (get_local $2) - ) - ) - ) - ) - (get_local $2) - ) - ) - (br_if $label$7 - (i32.eqz - (get_local $4) - ) - ) - (br_if $label$7 - (i32.load8_u offset=12 - (get_local $4) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 12) - ) - ) - (br $label$8) - ) - (br_if $label$5 - (i32.eqz - (tee_local $4 - (i32.load offset=4 - (get_local $3) - ) - ) - ) - ) - (br_if $label$5 - (i32.load8_u offset=12 - (get_local $4) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 12) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $2) - (i32.const 12) - ) - (i32.const 1) - ) - (i32.store8 offset=12 - (get_local $3) - (tee_local $2 - (i32.eq - (get_local $3) - (get_local $0) - ) - ) - ) - (i32.store8 - (get_local $4) - (i32.const 1) - ) - (set_local $1 - (get_local $3) - ) - (br_if $label$6 - (i32.eqz - (get_local $2) - ) - ) - (br $label$2) - ) - ) - (br_if $label$4 - (i32.eq - (i32.load - (get_local $2) - ) - (get_local $1) - ) - ) - (set_local $4 - (get_local $2) - ) - (br $label$3) - ) - (br_if $label$1 - (i32.eq - (i32.load - (get_local $2) - ) - (get_local $1) - ) - ) - (i32.store offset=4 - (get_local $2) - (tee_local $1 - (i32.load - (tee_local $4 - (i32.load offset=4 - (get_local $2) - ) - ) - ) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.eqz - (get_local $1) - ) - ) - (i32.store offset=8 - (get_local $1) - (get_local $2) - ) - (set_local $3 - (i32.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - ) - (i32.store offset=8 - (get_local $4) - (get_local $3) - ) - (i32.store - (select - (tee_local $3 - (i32.load - (tee_local $1 - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - ) - (i32.add - (get_local $3) - (i32.const 4) - ) - (i32.eq - (i32.load - (get_local $3) - ) - (get_local $2) - ) - ) - (get_local $4) - ) - (i32.store - (get_local $1) - (get_local $4) - ) - (i32.store - (get_local $4) - (get_local $2) - ) - (set_local $3 - (i32.load offset=8 - (get_local $4) - ) - ) - (br $label$0) - ) - (i32.store - (get_local $2) - (tee_local $1 - (i32.load offset=4 - (tee_local $4 - (i32.load - (get_local $2) - ) - ) - ) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (get_local $1) - ) - ) - (i32.store offset=8 - (get_local $1) - (get_local $2) - ) - (set_local $3 - (i32.load - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - ) - (i32.store offset=8 - (get_local $4) - (get_local $3) - ) - (i32.store - (select - (tee_local $3 - (i32.load - (tee_local $1 - (i32.add - (get_local $2) - (i32.const 8) - ) - ) - ) - ) - (i32.add - (get_local $3) - (i32.const 4) - ) - (i32.eq - (i32.load - (get_local $3) - ) - (get_local $2) - ) - ) - (get_local $4) - ) - (i32.store - (get_local $1) - (get_local $4) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 4) - ) - (get_local $2) - ) - (set_local $3 - (i32.load offset=8 - (get_local $4) - ) - ) - ) - (i32.store8 offset=12 - (get_local $4) - (i32.const 1) - ) - (i32.store8 offset=12 - (get_local $3) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $3) - (tee_local $4 - (i32.load - (tee_local $2 - (i32.load offset=4 - (get_local $3) - ) - ) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (get_local $4) - ) - ) - (i32.store offset=8 - (get_local $4) - (get_local $3) - ) - ) - (i32.store offset=8 - (get_local $2) - (i32.load offset=8 - (get_local $3) - ) - ) - (i32.store - (select - (tee_local $4 - (i32.load offset=8 - (get_local $3) - ) - ) - (i32.add - (get_local $4) - (i32.const 4) - ) - (i32.eq - (i32.load - (get_local $4) - ) - (get_local $3) - ) - ) - (get_local $2) - ) - (i32.store offset=8 - (get_local $3) - (get_local $2) - ) - (i32.store - (get_local $2) - (get_local $3) - ) - ) - (return) - ) - (set_local $4 - (get_local $2) - ) - ) - (i32.store8 offset=12 - (get_local $4) - (i32.const 1) - ) - (i32.store8 offset=12 - (get_local $3) - (i32.const 0) - ) - (i32.store - (get_local $3) - (tee_local $4 - (i32.load offset=4 - (tee_local $2 - (i32.load - (get_local $3) - ) - ) - ) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (get_local $4) - ) - ) - (i32.store offset=8 - (get_local $4) - (get_local $3) - ) - ) - (i32.store offset=8 - (get_local $2) - (i32.load offset=8 - (get_local $3) - ) - ) - (i32.store - (select - (tee_local $4 - (i32.load offset=8 - (get_local $3) - ) - ) - (i32.add - (get_local $4) - (i32.const 4) - ) - (i32.eq - (i32.load - (get_local $4) - ) - (get_local $3) - ) - ) - (get_local $2) - ) - (i32.store offset=8 - (get_local $3) - (get_local $2) - ) - (i32.store - (i32.add - (get_local $2) - (i32.const 4) - ) - (get_local $3) - ) - ) - (func $_ZN8testtypeINSt3__13mapIiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEENS0_4lessIiEENS5_INS0_4pairIKiS7_EEEEEEE3runERKSE_PKc (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 160) - ) - ) - ) - (i32.store offset=24 - (get_local $10) - (i32.add - (get_local $10) - (i32.const 160) - ) - ) - (i32.store offset=20 - (get_local $10) - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - (i32.store offset=16 - (get_local $10) - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RKNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE - (i32.add - (get_local $10) - (i32.const 16) - ) - (get_local $0) - ) - ) - (i32.store - (get_local $10) - (i32.or - (get_local $10) - (i32.const 4) - ) - ) - (set_local $9 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $10) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $10) - (i32.const 0) - ) - (i32.store offset=20 - (get_local $10) - (i32.load offset=16 - (get_local $10) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE - (i32.add - (get_local $10) - (i32.const 16) - ) - (get_local $10) - ) - ) - (block $label$0 - (br_if $label$0 - (i32.ne - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=8 - (get_local $10) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - (set_local $7 - (i32.load - (get_local $10) - ) - ) - (set_local $9 - (i32.const 0) - ) - (loop $label$2 - (br_if $label$0 - (i32.ne - (i32.load offset=16 - (tee_local $3 - (get_local $6) - ) - ) - (i32.load offset=16 - (tee_local $8 - (get_local $7) - ) - ) - ) - ) - (br_if $label$0 - (i32.ne - (tee_local $5 - (select - (i32.load offset=24 - (get_local $3) - ) - (tee_local $4 - (i32.shr_u - (tee_local $0 - (i32.load8_u offset=20 - (get_local $3) - ) - ) - (i32.const 1) - ) - ) - (tee_local $7 - (i32.and - (get_local $0) - (i32.const 1) - ) - ) - ) - ) - (select - (i32.load offset=24 - (get_local $8) - ) - (i32.shr_u - (tee_local $0 - (i32.load8_u offset=20 - (get_local $8) - ) - ) - (i32.const 1) - ) - (tee_local $0 - (i32.and - (get_local $0) - (i32.const 1) - ) - ) - ) - ) - ) - (set_local $0 - (select - (i32.load offset=28 - (get_local $8) - ) - (i32.add - (i32.add - (get_local $8) - (i32.const 20) - ) - (i32.const 1) - ) - (get_local $0) - ) - ) - (set_local $6 - (i32.add - (i32.add - (get_local $3) - (i32.const 20) - ) - (i32.const 1) - ) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (get_local $7) - ) - (br_if $label$3 - (i32.eqz - (get_local $5) - ) - ) - (set_local $7 - (i32.sub - (i32.const 0) - (get_local $4) - ) - ) - (loop $label$5 - (br_if $label$0 - (i32.ne - (i32.load8_u - (get_local $6) - ) - (i32.load8_u - (get_local $0) - ) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - (br_if $label$5 - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - ) - (br $label$3) - ) - ) - (br_if $label$3 - (i32.eqz - (get_local $5) - ) - ) - (br_if $label$0 - (call $memcmp - (select - (i32.load offset=28 - (get_local $3) - ) - (get_local $6) - (get_local $7) - ) - (get_local $0) - (get_local $5) - ) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.eqz - (tee_local $0 - (i32.load offset=4 - (get_local $3) - ) - ) - ) - ) - (loop $label$8 - (br_if $label$8 - (tee_local $0 - (i32.load - (tee_local $6 - (get_local $0) - ) - ) - ) - ) - (br $label$6) - ) - ) - (br_if $label$6 - (i32.eq - (i32.load - (tee_local $6 - (i32.load offset=8 - (get_local $3) - ) - ) - ) - (get_local $3) - ) - ) - (set_local $7 - (i32.add - (get_local $3) - (i32.const 8) - ) - ) - (loop $label$9 - (set_local $7 - (i32.add - (tee_local $0 - (i32.load - (get_local $7) - ) - ) - (i32.const 8) - ) - ) - (br_if $label$9 - (i32.ne - (get_local $0) - (i32.load - (tee_local $6 - (i32.load offset=8 - (get_local $0) - ) - ) - ) - ) - ) - ) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.eqz - (tee_local $0 - (i32.load offset=4 - (get_local $8) - ) - ) - ) - ) - (loop $label$12 - (br_if $label$12 - (tee_local $0 - (i32.load - (tee_local $7 - (get_local $0) - ) - ) - ) - ) - (br $label$10) - ) - ) - (br_if $label$10 - (i32.eq - (i32.load - (tee_local $7 - (i32.load offset=8 - (get_local $8) - ) - ) - ) - (get_local $8) - ) - ) - (set_local $8 - (i32.add - (get_local $8) - (i32.const 8) - ) - ) - (loop $label$13 - (set_local $8 - (i32.add - (tee_local $0 - (i32.load - (get_local $8) - ) - ) - (i32.const 8) - ) - ) - (br_if $label$13 - (i32.ne - (get_local $0) - (i32.load - (tee_local $7 - (i32.load offset=8 - (get_local $0) - ) - ) - ) - ) - ) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $6) - (get_local $2) - ) - ) - ) - ) - (set_local $9 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $9) - (get_local $1) - ) - (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE - (get_local $10) - (i32.load offset=4 - (get_local $10) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 160) - ) - ) - ) - (func $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE (param $0 i32) (param $1 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE - (get_local $0) - (i32.load - (get_local $1) - ) - ) - (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE - (get_local $0) - (i32.load offset=4 - (get_local $1) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.and - (i32.load8_u - (i32.add - (get_local $1) - (i32.const 20) - ) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $1) - (i32.const 28) - ) - ) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - ) - (func $_ZN8testtypeINSt3__15tupleIJiNS0_12basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEEdEEEE3runERKS8_PKc (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $11 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 176) - ) - ) - ) - (i32.store offset=40 - (get_local $11) - (i32.add - (get_local $11) - (i32.const 176) - ) - ) - (i32.store offset=32 - (get_local $11) - (i32.add - (get_local $11) - (i32.const 48) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.add - (get_local $11) - (i32.const 48) - ) - (get_local $0) - (i32.const 4) - ) - ) - (i32.store offset=36 - (get_local $11) - (i32.or - (i32.add - (get_local $11) - (i32.const 48) - ) - (i32.const 4) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE - (i32.add - (get_local $11) - (i32.const 32) - ) - (tee_local $8 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load offset=40 - (get_local $11) - ) - (i32.load offset=36 - (get_local $11) - ) - ) - (i32.const 7) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load offset=36 - (get_local $11) - ) - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - (i32.const 8) - ) - ) - (i64.store - (tee_local $7 - (i32.add - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.const 8) - ) - ) - (i64.const 0) - ) - (i64.store offset=8 - (get_local $11) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $11) - (i64.const 0) - ) - (i32.store offset=36 - (get_local $11) - (tee_local $9 - (i32.load offset=32 - (get_local $11) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=40 - (get_local $11) - ) - (get_local $9) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.load offset=36 - (get_local $11) - ) - (i32.const 4) - ) - ) - (i32.store offset=36 - (get_local $11) - (i32.add - (i32.load offset=36 - (get_local $11) - ) - (i32.const 4) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE - (i32.add - (get_local $11) - (i32.const 32) - ) - (tee_local $3 - (i32.or - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.const 4) - ) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=40 - (get_local $11) - ) - (i32.load offset=36 - (get_local $11) - ) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.const 16) - ) - (i32.load offset=36 - (get_local $11) - ) - (i32.const 8) - ) - ) - (i32.store offset=36 - (get_local $11) - (i32.add - (i32.load offset=36 - (get_local $11) - ) - (i32.const 8) - ) - ) - (set_local $10 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.ne - (i32.load - (get_local $0) - ) - (i32.load offset=8 - (get_local $11) - ) - ) - ) - (br_if $label$0 - (i32.ne - (tee_local $6 - (select - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (tee_local $5 - (i32.shr_u - (tee_local $9 - (i32.load8_u - (get_local $8) - ) - ) - (i32.const 1) - ) - ) - (tee_local $4 - (i32.and - (get_local $9) - (i32.const 1) - ) - ) - ) - ) - (select - (i32.load - (get_local $7) - ) - (i32.shr_u - (tee_local $9 - (i32.load8_u offset=12 - (get_local $11) - ) - ) - (i32.const 1) - ) - (tee_local $7 - (i32.and - (get_local $9) - (i32.const 1) - ) - ) - ) - ) - ) - (set_local $9 - (i32.add - (get_local $8) - (i32.const 1) - ) - ) - (set_local $8 - (select - (i32.load - (i32.add - (i32.add - (get_local $11) - (i32.const 8) - ) - (i32.const 12) - ) - ) - (i32.add - (get_local $3) - (i32.const 1) - ) - (get_local $7) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (get_local $4) - ) - (br_if $label$1 - (i32.eqz - (get_local $6) - ) - ) - (set_local $10 - (i32.const 0) - ) - (set_local $0 - (i32.sub - (i32.const 0) - (get_local $5) - ) - ) - (loop $label$3 - (br_if $label$0 - (i32.ne - (i32.load8_u - (get_local $9) - ) - (i32.load8_u - (get_local $8) - ) - ) - ) - (set_local $8 - (i32.add - (get_local $8) - (i32.const 1) - ) - ) - (set_local $9 - (i32.add - (get_local $9) - (i32.const 1) - ) - ) - (br_if $label$3 - (tee_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - ) - (br $label$1) - ) - ) - (br_if $label$1 - (i32.eqz - (get_local $6) - ) - ) - (br_if $label$0 - (call $memcmp - (select - (i32.load - (i32.add - (get_local $0) - (i32.const 12) - ) - ) - (get_local $9) - (get_local $4) - ) - (get_local $8) - (get_local $6) - ) - ) - ) - (set_local $10 - (f64.eq - (f64.load - (get_local $2) - ) - (f64.load - (i32.add - (get_local $11) - (i32.const 24) - ) - ) - ) - ) - ) - (call $eosio_assert - (get_local $10) - (get_local $1) - ) - (block $label$4 - (br_if $label$4 - (i32.eqz - (i32.and - (i32.load8_u offset=12 - (get_local $11) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (i32.add - (get_local $11) - (i32.const 20) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $11) - (i32.const 176) - ) - ) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i64) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $7 - (i64.extend_u/i32 - (select - (i32.load offset=4 - (get_local $1) - ) - (i32.shr_u - (tee_local $5 - (i32.load8_u - (get_local $1) - ) - ) - (i32.const 1) - ) - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $2 - (i32.wrap/i64 - (get_local $7) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $3 - (i64.ne - (tee_local $7 - (i64.shr_u - (get_local $7) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $2) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $5) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $5) - (tee_local $6 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $3) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $5 - (select - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (i32.shr_u - (tee_local $5 - (i32.load8_u - (get_local $1) - ) - ) - (i32.const 1) - ) - (tee_local $2 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (set_local $3 - (i32.load offset=8 - (get_local $1) - ) - ) - (call $eosio_assert - (i32.ge_s - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $6) - ) - (get_local $5) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (select - (get_local $3) - (i32.add - (get_local $1) - (i32.const 1) - ) - (get_local $2) - ) - (get_local $5) - ) - ) - (i32.store - (get_local $6) - (i32.add - (i32.load - (get_local $6) - ) - (get_local $5) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $7 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 32) - ) - ) - ) - (i32.store offset=24 - (get_local $7) - (i32.const 0) - ) - (i64.store offset=16 - (get_local $7) - (i64.const 0) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__16vectorIcNS6_9allocatorIcEEEE - (get_local $0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - ) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (block $label$8 - (br_if $label$8 - (i32.ne - (tee_local $5 - (i32.load offset=20 - (get_local $7) - ) - ) - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - ) - (br_if $label$7 - (i32.and - (i32.load8_u - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.store16 - (get_local $1) - (i32.const 0) - ) - (set_local $4 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (br $label$6) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.const 0) - ) - (i64.store - (get_local $7) - (i64.const 0) - ) - (br_if $label$0 - (i32.ge_u - (tee_local $2 - (i32.sub - (get_local $5) - (get_local $4) - ) - ) - (i32.const -16) - ) - ) - (br_if $label$5 - (i32.ge_u - (get_local $2) - (i32.const 11) - ) - ) - (i32.store8 - (get_local $7) - (i32.shl - (get_local $2) - (i32.const 1) - ) - ) - (set_local $6 - (i32.or - (get_local $7) - (i32.const 1) - ) - ) - (br_if $label$4 - (get_local $2) - ) - (br $label$3) - ) - (i32.store8 - (i32.load offset=8 - (get_local $1) - ) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $1) - (i32.const 0) - ) - (set_local $4 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj - (get_local $1) - (i32.const 0) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (i64.store align=4 - (get_local $1) - (i64.const 0) - ) - (br_if $label$2 - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - (br $label$1) - ) - (set_local $6 - (call $_Znwj - (tee_local $5 - (i32.and - (i32.add - (get_local $2) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.or - (get_local $5) - (i32.const 1) - ) - ) - (i32.store offset=8 - (get_local $7) - (get_local $6) - ) - (i32.store offset=4 - (get_local $7) - (get_local $2) - ) - ) - (set_local $3 - (get_local $2) - ) - (set_local $5 - (get_local $6) - ) - (loop $label$9 - (i32.store8 - (get_local $5) - (i32.load8_u - (get_local $4) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - (br_if $label$9 - (tee_local $3 - (i32.add - (get_local $3) - (i32.const -1) - ) - ) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (get_local $2) - ) - ) - ) - (i32.store8 - (get_local $6) - (i32.const 0) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.and - (i32.load8_u - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.store16 - (get_local $1) - (i32.const 0) - ) - (br $label$10) - ) - (i32.store8 - (i32.load offset=8 - (get_local $1) - ) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $1) - (i32.const 0) - ) - ) - (call $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj - (get_local $1) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - ) - (i64.store align=4 - (get_local $1) - (i64.load - (get_local $7) - ) - ) - (br_if $label$1 - (i32.eqz - (tee_local $4 - (i32.load offset=16 - (get_local $7) - ) - ) - ) - ) - ) - (i32.store offset=20 - (get_local $7) - (get_local $4) - ) - (call $_ZdlPv - (get_local $4) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $7) - (i32.const 32) - ) - ) - (return - (get_local $0) - ) - ) - (call $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv - (get_local $7) - ) - (unreachable) - ) - (func $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__16vectorIcNS6_9allocatorIcEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.const 848) - ) - (set_local $4 - (i32.load8_u - (tee_local $5 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $7 - (i32.and - (get_local $7) - (i32.const 255) - ) - ) - ) - ) - (get_local $6) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.le_u - (tee_local $3 - (i32.wrap/i64 - (get_local $6) - ) - ) - (tee_local $2 - (i32.sub - (tee_local $7 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIcNS_9allocatorIcEEE8__appendEj - (get_local $1) - (i32.sub - (get_local $3) - (get_local $2) - ) - ) - (set_local $5 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - (set_local $4 - (i32.load - (get_local $1) - ) - ) - (br $label$1) - ) - (br_if $label$1 - (i32.ge_u - (get_local $3) - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (tee_local $7 - (i32.add - (get_local $4) - (get_local $3) - ) - ) - ) - ) - (call $eosio_assert - (i32.ge_u - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $5) - ) - (tee_local $5 - (i32.sub - (get_local $7) - (get_local $4) - ) - ) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $4) - (i32.load - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (get_local $5) - ) - ) - (i32.store - (get_local $7) - (i32.add - (i32.load - (get_local $7) - ) - (get_local $5) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RKNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i64) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $4 - (i64.load32_u offset=8 - (get_local $1) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $7 - (i32.wrap/i64 - (get_local $4) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $3 - (i64.ne - (tee_local $4 - (i64.shr_u - (get_local $4) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $7) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $6) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $5) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $5) - (tee_local $6 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $3) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $7 - (i32.load - (get_local $1) - ) - ) - (tee_local $2 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$2 - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $1) - ) - (get_local $6) - ) - (i32.const 3) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.add - (get_local $7) - (i32.const 16) - ) - (i32.const 4) - ) - ) - (i32.store - (get_local $3) - (i32.add - (i32.load - (get_local $3) - ) - (i32.const 4) - ) - ) - (drop - (call $_ZN5eosiolsINS_10datastreamIPcEEEERT_S5_RKNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE - (get_local $0) - (i32.add - (get_local $7) - (i32.const 20) - ) - ) - ) - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.eqz - (tee_local $6 - (i32.load offset=4 - (get_local $7) - ) - ) - ) - ) - (loop $label$5 - (br_if $label$5 - (tee_local $6 - (i32.load - (tee_local $5 - (get_local $6) - ) - ) - ) - ) - (br $label$3) - ) - ) - (br_if $label$3 - (i32.eq - (i32.load - (tee_local $5 - (i32.load offset=8 - (get_local $7) - ) - ) - ) - (get_local $7) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 8) - ) - ) - (loop $label$6 - (set_local $7 - (i32.add - (tee_local $6 - (i32.load - (get_local $7) - ) - ) - (i32.const 8) - ) - ) - (br_if $label$6 - (i32.ne - (get_local $6) - (i32.load - (tee_local $5 - (i32.load offset=8 - (get_local $6) - ) - ) - ) - ) - ) - ) - ) - (br_if $label$1 - (i32.eq - (get_local $5) - (get_local $2) - ) - ) - (set_local $6 - (i32.load - (get_local $3) - ) - ) - (set_local $7 - (get_local $5) - ) - (br $label$2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPcEEiNSt3__112basic_stringIcNS4_11char_traitsIcEENS4_9allocatorIcEEEEEERT_SC_RNS4_3mapIT0_T1_NS4_4lessISE_EENS8_INS4_4pairIKSE_SF_EEEEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i64) - (local $11 i32) - (local $12 i32) - (local $13 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $13 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (call $_ZNSt3__16__treeINS_12__value_typeIiNS_12basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEEEENS_19__map_value_compareIiS8_NS_4lessIiEELb1EEENS5_IS8_EEE7destroyEPNS_11__tree_nodeIS8_PvEE - (get_local $1) - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.store - (get_local $1) - (tee_local $2 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - (set_local $5 - (i32.const 0) - ) - (i32.store offset=8 - (get_local $1) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $1) - (i32.const 0) - ) - (set_local $6 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $10 - (i64.const 0) - ) - (set_local $9 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $6) - (i32.load - (get_local $9) - ) - ) - (i32.const 848) - ) - (set_local $12 - (i32.load8_u - (tee_local $6 - (i32.load - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - ) - ) - (i32.store - (get_local $7) - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - ) - (set_local $10 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $12) - (i32.const 127) - ) - (tee_local $5 - (i32.and - (get_local $5) - (i32.const 255) - ) - ) - ) - ) - (get_local $10) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $12) - (i32.const 7) - ) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (tee_local $3 - (i32.wrap/i64 - (get_local $10) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (set_local $11 - (i32.const 0) - ) - (loop $label$2 - (i32.store - (tee_local $8 - (i32.add - (get_local $13) - (i32.const 8) - ) - ) - (i32.const 0) - ) - (i64.store - (get_local $13) - (i64.const 0) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (get_local $6) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $13) - (i32.const 12) - ) - (i32.load - (tee_local $9 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.const 4) - ) - ) - (i32.store - (get_local $9) - (i32.add - (i32.load - (get_local $9) - ) - (i32.const 4) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPcEEEERT_S5_RNSt3__112basic_stringIcNS6_11char_traitsIcEENS6_9allocatorIcEEEE - (get_local $0) - (get_local $13) - ) - ) - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.eqz - (tee_local $6 - (i32.load - (get_local $2) - ) - ) - ) - ) - (set_local $5 - (i32.load offset=12 - (get_local $13) - ) - ) - (set_local $7 - (get_local $4) - ) - (loop $label$8 - (block $label$9 - (block $label$10 - (br_if $label$10 - (i32.ge_s - (get_local $5) - (tee_local $12 - (i32.load offset=16 - (get_local $6) - ) - ) - ) - ) - (set_local $7 - (get_local $6) - ) - (br_if $label$9 - (tee_local $12 - (i32.load - (get_local $6) - ) - ) - ) - (br $label$6) - ) - (br_if $label$5 - (i32.ge_s - (get_local $12) - (get_local $5) - ) - ) - (set_local $7 - (i32.add - (get_local $6) - (i32.const 4) - ) - ) - (br_if $label$5 - (i32.eqz - (tee_local $12 - (i32.load offset=4 - (get_local $6) - ) - ) - ) - ) - ) - (set_local $6 - (get_local $12) - ) - (br $label$8) - ) - ) - (set_local $6 - (get_local $2) - ) - (br_if $label$3 - (i32.load - (tee_local $7 - (get_local $2) - ) - ) - ) - (br $label$4) - ) - (set_local $7 - (get_local $6) - ) - ) - (br_if $label$3 - (i32.load - (get_local $7) - ) - ) - ) - (i32.store offset=16 - (tee_local $12 - (call $_Znwj - (i32.const 32) - ) - ) - (i32.load offset=12 - (get_local $13) - ) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 28) - ) - (i32.load - (get_local $8) - ) - ) - (i32.store - (i32.add - (get_local $12) - (i32.const 24) - ) - (i32.load offset=4 - (get_local $13) - ) - ) - (i32.store offset=20 - (get_local $12) - (i32.load - (get_local $13) - ) - ) - (i32.store - (get_local $13) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $13) - (i32.const 0) - ) - (i32.store - (get_local $8) - (i32.const 0) - ) - (i32.store - (get_local $12) - (i32.const 0) - ) - (i32.store offset=4 - (get_local $12) - (i32.const 0) - ) - (i32.store offset=8 - (get_local $12) - (get_local $6) - ) - (i32.store - (get_local $7) - (get_local $12) - ) - (block $label$11 - (br_if $label$11 - (i32.eqz - (tee_local $6 - (i32.load - (i32.load - (get_local $1) - ) - ) - ) - ) - ) - (i32.store - (get_local $1) - (get_local $6) - ) - (set_local $12 - (i32.load - (get_local $7) - ) - ) - ) - (call $_ZNSt3__127__tree_balance_after_insertIPNS_16__tree_node_baseIPvEEEEvT_S5_ - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (get_local $12) - ) - (i32.store - (tee_local $6 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (i32.add - (i32.load - (get_local $6) - ) - (i32.const 1) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (i32.and - (i32.load8_u - (get_local $13) - ) - (i32.const 1) - ) - ) - ) - (call $_ZdlPv - (i32.load - (get_local $8) - ) - ) - ) - (br_if $label$1 - (i32.eq - (tee_local $11 - (i32.add - (get_local $11) - (i32.const 1) - ) - ) - (get_local $3) - ) - ) - (set_local $6 - (i32.load - (get_local $9) - ) - ) - (br $label$2) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $13) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiolsINS_10datastreamIPcEEiEERT_S5_RKNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (local $8 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $8 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (set_local $6 - (i64.extend_u/i32 - (i32.shr_s - (i32.sub - (i32.load offset=4 - (get_local $1) - ) - (i32.load - (get_local $1) - ) - ) - (i32.const 2) - ) - ) - ) - (set_local $7 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (set_local $2 - (i32.wrap/i64 - (get_local $6) - ) - ) - (i32.store8 offset=15 - (get_local $8) - (i32.or - (i32.shl - (tee_local $3 - (i64.ne - (tee_local $6 - (i64.shr_u - (get_local $6) - (i64.const 7) - ) - ) - (i64.const 0) - ) - ) - (i32.const 7) - ) - (i32.and - (get_local $2) - (i32.const 127) - ) - ) - ) - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $7) - ) - (i32.const 0) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (get_local $5) - ) - (i32.add - (get_local $8) - (i32.const 15) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $5) - (tee_local $7 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 1) - ) - ) - ) - (br_if $label$0 - (get_local $3) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.eq - (tee_local $5 - (i32.load - (get_local $1) - ) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$2 - (call $eosio_assert - (i32.gt_s - (i32.sub - (i32.load - (get_local $4) - ) - (get_local $7) - ) - (i32.const 3) - ) - (i32.const 1424) - ) - (drop - (call $memcpy - (i32.load - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (get_local $5) - (i32.const 4) - ) - ) - (i32.store - (get_local $2) - (tee_local $7 - (i32.add - (i32.load - (get_local $2) - ) - (i32.const 4) - ) - ) - ) - (br_if $label$2 - (i32.ne - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 4) - ) - ) - ) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $8) - (i32.const 16) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPcEEiEERT_S5_RNSt3__16vectorIT0_NS6_9allocatorIS8_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.const 848) - ) - (set_local $4 - (i32.load8_u - (tee_local $5 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $7 - (i32.and - (get_local $7) - (i32.const 255) - ) - ) - ) - ) - (get_local $6) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.le_u - (tee_local $5 - (i32.wrap/i64 - (get_local $6) - ) - ) - (tee_local $7 - (i32.shr_s - (i32.sub - (tee_local $3 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - ) - (i32.const 2) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIiNS_9allocatorIiEEE8__appendEj - (get_local $1) - (i32.sub - (get_local $5) - (get_local $7) - ) - ) - (br_if $label$2 - (i32.ne - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - (tee_local $3 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - ) - (br $label$1) - ) - (block $label$4 - (br_if $label$4 - (i32.ge_u - (get_local $5) - (get_local $7) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (tee_local $3 - (i32.add - (get_local $4) - (i32.shl - (get_local $5) - (i32.const 2) - ) - ) - ) - ) - ) - (br_if $label$1 - (i32.eq - (get_local $4) - (get_local $3) - ) - ) - ) - (set_local $7 - (i32.load - (tee_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$5 - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (get_local $2) - ) - (get_local $7) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $4) - (i32.load - (get_local $5) - ) - (i32.const 4) - ) - ) - (i32.store - (get_local $5) - (tee_local $7 - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 4) - ) - ) - ) - (br_if $label$5 - (i32.ne - (get_local $3) - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 4) - ) - ) - ) - ) - ) - ) - (get_local $0) - ) - (func $_ZNSt3__16vectorIiNS_9allocatorIiEEE8__appendEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (i32.shr_s - (i32.sub - (tee_local $7 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $2 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (i32.const 2) - ) - (get_local $1) - ) - ) - (br_if $label$2 - (i32.ge_u - (tee_local $2 - (i32.add - (tee_local $4 - (i32.shr_s - (i32.sub - (get_local $2) - (tee_local $3 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 2) - ) - ) - (get_local $1) - ) - ) - (i32.const 1073741824) - ) - ) - (set_local $6 - (i32.const 1073741823) - ) - (block $label$5 - (br_if $label$5 - (i32.gt_u - (i32.shr_s - (tee_local $7 - (i32.sub - (get_local $7) - (get_local $3) - ) - ) - (i32.const 2) - ) - (i32.const 536870910) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $6 - (select - (get_local $2) - (tee_local $6 - (i32.shr_s - (get_local $7) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $6) - (get_local $2) - ) - ) - ) - ) - ) - (br_if $label$1 - (i32.ge_u - (get_local $6) - (i32.const 1073741824) - ) - ) - ) - (set_local $7 - (call $_Znwj - (i32.shl - (get_local $6) - (i32.const 2) - ) - ) - ) - (br $label$0) - ) - (set_local $6 - (get_local $2) - ) - (set_local $7 - (get_local $1) - ) - (loop $label$6 - (i32.store - (get_local $6) - (i32.const 0) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 4) - ) - ) - (br_if $label$6 - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.add - (get_local $2) - (i32.shl - (get_local $1) - (i32.const 2) - ) - ) - ) - (return) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $7 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (call $abort) - (unreachable) - ) - (set_local $3 - (i32.add - (get_local $7) - (i32.shl - (get_local $6) - (i32.const 2) - ) - ) - ) - (set_local $6 - (tee_local $2 - (i32.add - (get_local $7) - (i32.shl - (get_local $4) - (i32.const 2) - ) - ) - ) - ) - (set_local $7 - (get_local $1) - ) - (loop $label$7 - (i32.store - (get_local $6) - (i32.const 0) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 4) - ) - ) - (br_if $label$7 - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -1) - ) - ) - ) - ) - (set_local $4 - (i32.add - (get_local $2) - (i32.shl - (get_local $1) - (i32.const 2) - ) - ) - ) - (set_local $1 - (i32.sub - (get_local $2) - (tee_local $7 - (i32.sub - (i32.load - (tee_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - ) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.lt_s - (get_local $7) - (i32.const 1) - ) - ) - (drop - (call $memcpy - (get_local $1) - (get_local $6) - (get_local $7) - ) - ) - (set_local $6 - (i32.load - (get_local $0) - ) - ) - ) - (i32.store - (get_local $0) - (get_local $1) - ) - (i32.store - (get_local $5) - (get_local $4) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $3) - ) - (block $label$9 - (br_if $label$9 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $6) - ) - ) - ) - (func $apply (param $0 i64) (param $1 i64) (param $2 i64) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i64) - (local $8 i64) - (local $9 i64) - (local $10 i32) - (i32.store offset=4 - (i32.const 0) - (tee_local $10 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 384) - ) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 18944) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i64.gt_u - (get_local $7) - (i64.const 4) - ) - ) - (br_if $label$4 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$3) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$2 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$1) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$0 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (block $label$6 - (block $label$7 - (block $label$8 - (block $label$9 - (br_if $label$9 - (i64.ne - (get_local $8) - (get_local $1) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 18960) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$10 - (block $label$11 - (block $label$12 - (block $label$13 - (block $label$14 - (block $label$15 - (br_if $label$15 - (i64.gt_u - (get_local $7) - (i64.const 6) - ) - ) - (br_if $label$14 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$13) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$12 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$11) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$10 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (br_if $label$9 - (i64.ne - (get_local $8) - (get_local $2) - ) - ) - (call $_ZN5eosio18unpack_action_dataINS_7onerrorEEET_v - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - (call $prints - (i32.const 18976) - ) - (set_local $3 - (i32.load - (i32.add - (get_local $10) - (i32.const 52) - ) - ) - ) - (set_local $5 - (i32.load offset=48 - (get_local $10) - ) - ) - (set_local $7 - (call $current_time) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 236) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 240) - ) - (i32.const 0) - ) - (i32.store offset=220 - (get_local $10) - (i32.const 0) - ) - (i32.store8 offset=224 - (get_local $10) - (i32.const 0) - ) - (i32.store offset=228 - (get_local $10) - (i32.const 0) - ) - (i32.store offset=232 - (get_local $10) - (i32.const 0) - ) - (i32.store offset=208 - (get_local $10) - (i32.add - (i32.wrap/i64 - (i64.div_u - (get_local $7) - (i64.const 1000000) - ) - ) - (i32.const 60) - ) - ) - (i32.store offset=244 - (get_local $10) - (i32.const 0) - ) - (i32.store - (tee_local $4 - (i32.add - (get_local $10) - (i32.const 248) - ) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 252) - ) - (i32.const 0) - ) - (i32.store offset=256 - (get_local $10) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 260) - ) - (i32.const 0) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 264) - ) - (i32.const 0) - ) - (i32.store offset=20 - (get_local $10) - (get_local $5) - ) - (i32.store offset=16 - (get_local $10) - (get_local $5) - ) - (i32.store offset=24 - (get_local $10) - (get_local $3) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_18transaction_headerE - (i32.add - (get_local $10) - (i32.const 16) - ) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEENSt3__15tupleIJtNS5_6vectorIcNS5_9allocatorIcEEEEEEEEERT_SD_RNS7_IT0_NS8_ISE_EEEE - (call $_ZN5eosiorsINS_10datastreamIPKcEENS_6actionEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE - (call $_ZN5eosiorsINS_10datastreamIPKcEENS_6actionEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE - (i32.add - (get_local $10) - (i32.const 16) - ) - (i32.add - (get_local $10) - (i32.const 232) - ) - ) - (tee_local $3 - (i32.add - (get_local $10) - (i32.const 244) - ) - ) - ) - (i32.add - (get_local $10) - (i32.const 256) - ) - ) - ) - (br_if $label$8 - (i32.eq - (i32.load - (get_local $4) - ) - (tee_local $5 - (i32.load offset=244 - (get_local $10) - ) - ) - ) - ) - (block $label$16 - (br_if $label$16 - (i64.ne - (i64.load offset=8 - (get_local $5) - ) - (i64.const -8665432478290165179) - ) - ) - (call $_ZN16test_transaction26assert_false_error_handlerERKN5eosio11transactionE - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - ) - (drop - (call $_ZN5eosio11transactionD2Ev - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - ) - (br_if $label$6 - (i32.eqz - (tee_local $5 - (i32.load - (i32.add - (get_local $10) - (i32.const 48) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $10) - (i32.const 52) - ) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - (br $label$6) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 1440) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$17 - (block $label$18 - (block $label$19 - (block $label$20 - (block $label$21 - (block $label$22 - (br_if $label$22 - (i64.gt_u - (get_local $7) - (i64.const 8) - ) - ) - (br_if $label$21 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$20) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$19 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$18) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$17 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (block $label$23 - (br_if $label$23 - (i64.ne - (get_local $8) - (get_local $2) - ) - ) - (call $_ZN11test_action14test_cf_actionEv) - (br $label$6) - ) - (block $label$24 - (block $label$25 - (br_if $label$25 - (i64.eq - (get_local $2) - (i64.const -8665432478235101900) - ) - ) - (br_if $label$7 - (i64.eq - (get_local $2) - (i64.const -696013500020145514) - ) - ) - (br_if $label$24 - (i64.ne - (get_local $2) - (i64.const -696013499845391606) - ) - ) - (br $label$7) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1600) - ) - (br $label$6) - ) - (call $require_auth - (get_local $1) - ) - (block $label$26 - (block $label$27 - (block $label$28 - (block $label$29 - (block $label$30 - (block $label$31 - (block $label$32 - (block $label$33 - (block $label$34 - (block $label$35 - (block $label$36 - (block $label$37 - (block $label$38 - (block $label$39 - (block $label$40 - (block $label$41 - (block $label$42 - (block $label$43 - (block $label$44 - (block $label$45 - (block $label$46 - (block $label$47 - (block $label$48 - (block $label$49 - (block $label$50 - (block $label$51 - (block $label$52 - (block $label$53 - (br_if $label$53 - (i64.gt_s - (get_local $2) - (i64.const -6575469300789510042) - ) - ) - (br_if $label$52 - (i64.gt_s - (get_local $2) - (i64.const -8665432477288202419) - ) - ) - (br_if $label$50 - (i64.gt_s - (get_local $2) - (i64.const -8665432478290165180) - ) - ) - (br_if $label$46 - (i64.gt_s - (get_local $2) - (i64.const -8665432478739662526) - ) - ) - (br_if $label$41 - (i64.eq - (get_local $2) - (i64.const -8665432479170847876) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -8665432478848840241) - ) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 1632) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=208 - (get_local $10) - ) - (call $current_time) - ) - (i32.const 1744) - ) - (br $label$6) - ) - (br_if $label$51 - (i64.gt_s - (get_local $2) - (i64.const -6575469299402901114) - ) - ) - (br_if $label$49 - (i64.le_s - (get_local $2) - (i64.const -6575469300549176619) - ) - ) - (br_if $label$45 - (i64.gt_s - (get_local $2) - (i64.const -6575469299641207703) - ) - ) - (br_if $label$40 - (i64.eq - (get_local $2) - (i64.const -6575469300549176618) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -6575469300234199047) - ) - ) - (call $_ZN22test_compiler_builtins11test_divti3Ev) - (br $label$6) - ) - (br_if $label$48 - (i64.le_s - (get_local $2) - (i64.const -8665432476325739330) - ) - ) - (br_if $label$44 - (i64.gt_s - (get_local $2) - (i64.const -6575469302011795920) - ) - ) - (br_if $label$39 - (i64.eq - (get_local $2) - (i64.const -8665432476325739329) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -6575469302268922734) - ) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (call $__divti3 - (i32.add - (get_local $10) - (i32.const 208) - ) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6544) - ) - (br $label$6) - ) - (br_if $label$47 - (i64.le_s - (get_local $2) - (i64.const -5790280401120060142) - ) - ) - (br_if $label$43 - (i64.gt_s - (get_local $2) - (i64.const -5790280400999598625) - ) - ) - (br_if $label$38 - (i64.eq - (get_local $2) - (i64.const -5790280401120060141) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -5790280401000535180) - ) - ) - (call $_ZN10test_types10types_sizeEv) - (br $label$6) - ) - (br_if $label$42 - (i64.gt_s - (get_local $2) - (i64.const -8665432477679290203) - ) - ) - (br_if $label$37 - (i64.eq - (get_local $2) - (i64.const -8665432478290165179) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -8665432478272688454) - ) - ) - (call $_ZN11test_action18read_action_normalEv) - (br $label$6) - ) - (br_if $label$36 - (i64.eq - (get_local $2) - (i64.const -6575469300789510041) - ) - ) - (br_if $label$35 - (i64.eq - (get_local $2) - (i64.const -6575469300788910535) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -6575469300561148988) - ) - ) - (call $_ZN22test_compiler_builtins11test_modti3Ev) - (br $label$6) - ) - (br_if $label$34 - (i64.eq - (get_local $2) - (i64.const -8665432477288202418) - ) - ) - (br_if $label$33 - (i64.eq - (get_local $2) - (i64.const -8665432477185147987) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -8665432476560123846) - ) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 1632) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=208 - (get_local $10) - ) - (call $publication_time) - ) - (i32.const 1664) - ) - (br $label$6) - ) - (br_if $label$32 - (i64.eq - (get_local $2) - (i64.const -6575469299402901113) - ) - ) - (br_if $label$31 - (i64.eq - (get_local $2) - (i64.const -6575469299349951025) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -6575469299199638822) - ) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (call $__umodti3 - (i32.add - (get_local $10) - (i32.const 208) - ) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7776) - ) - (br $label$6) - ) - (br_if $label$30 - (i64.eq - (get_local $2) - (i64.const -8665432478739662525) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -8665432478353100899) - ) - ) - (drop - (call $read_action_data - (i32.const 0) - (call $action_data_size) - ) - ) - (br $label$6) - ) - (br_if $label$29 - (i64.eq - (get_local $2) - (i64.const -6575469299641207702) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -6575469299640583116) - ) - ) - (call $_ZN22test_compiler_builtins12test_ashlti3Ev) - (br $label$6) - ) - (br_if $label$28 - (i64.eq - (get_local $2) - (i64.const -6575469302011795919) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -6575469301755127924) - ) - ) - (call $_ZN22test_compiler_builtins12test_udivti3Ev) - (br $label$6) - ) - (br_if $label$27 - (i64.eq - (get_local $2) - (i64.const -5790280400999598624) - ) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -5790280398527684980) - ) - ) - (call $_ZN10test_types14string_to_nameEv) - (br $label$6) - ) - (br_if $label$26 - (i64.ne - (get_local $2) - (i64.const -8665432477579625276) - ) - ) - (drop - (call $read_action_data - (i32.const 65534) - (call $action_data_size) - ) - ) - (br $label$6) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (call $eosio_assert - (i32.eq - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 8) - ) - (i32.const 8) - ) - (i32.const 1632) - ) - (call $eosio_assert_code - (i32.const 0) - (i64.load offset=208 - (get_local $10) - ) - ) - (br $label$6) - ) - (call $_ZN22test_compiler_builtins11test_multi3Ev) - (br $label$6) - ) - (call $_ZN11test_action12require_authEv) - (br $label$6) - ) - (call $_ZN10test_types10name_classEv) - (br $label$6) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 1568) - ) - (br $label$6) - ) - (call $_ZN22test_compiler_builtins12test_lshrti3Ev) - (br $label$6) - ) - (call $_ZN22test_compiler_builtins12test_lshlti3Ev) - (br $label$6) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 1600) - ) - (br $label$6) - ) - (call $_ZN11test_action14require_noticeEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (call $__udivti3 - (i32.add - (get_local $10) - (i32.const 208) - ) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6544) - ) - (br $label$6) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (call $__modti3 - (i32.add - (get_local $10) - (i32.const 208) - ) - (i64.const 100) - (i64.const 0) - (i64.const 0) - (i64.const 0) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7776) - ) - (br $label$6) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 8) - ) - ) - (call $eosio_assert - (i64.eq - (i64.load offset=208 - (get_local $10) - ) - (get_local $0) - ) - (i32.const 1696) - ) - (br $label$6) - ) - (call $_ZN22test_compiler_builtins12test_ashrti3Ev) - (br $label$6) - ) - (call $_ZN22test_compiler_builtins12test_umodti3Ev) - (br $label$6) - ) - (call $_ZN10test_types14char_to_symbolEv) - (br $label$6) - ) - (br_if $label$7 - (i64.ne - (get_local $2) - (i64.const -8665432477679290202) - ) - ) - (call $abort) - (unreachable) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_out_of_rangeEv - (get_local $3) - ) - (unreachable) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $9 - (i64.const 59) - ) - (set_local $5 - (i32.const 752) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$54 - (set_local $6 - (i64.const 0) - ) - (block $label$55 - (br_if $label$55 - (i64.gt_u - (get_local $7) - (i64.const 11) - ) - ) - (block $label$56 - (block $label$57 - (br_if $label$57 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$56) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $6 - (i64.shl - (i64.extend_u/i32 - (i32.and - (get_local $3) - (i32.const 31) - ) - ) - (i64.and - (get_local $9) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $6) - (get_local $8) - ) - ) - (br_if $label$54 - (i64.ne - (tee_local $9 - (i64.add - (get_local $9) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (block $label$58 - (br_if $label$58 - (i64.ne - (get_local $8) - (get_local $2) - ) - ) - (call $_ZN11test_action17test_dummy_actionEv) - (br $label$6) - ) - (block $label$59 - (block $label$60 - (block $label$61 - (block $label$62 - (block $label$63 - (block $label$64 - (block $label$65 - (block $label$66 - (block $label$67 - (block $label$68 - (block $label$69 - (block $label$70 - (block $label$71 - (block $label$72 - (block $label$73 - (block $label$74 - (block $label$75 - (block $label$76 - (block $label$77 - (block $label$78 - (block $label$79 - (block $label$80 - (block $label$81 - (block $label$82 - (block $label$83 - (block $label$84 - (block $label$85 - (block $label$86 - (block $label$87 - (block $label$88 - (block $label$89 - (block $label$90 - (block $label$91 - (block $label$92 - (block $label$93 - (block $label$94 - (block $label$95 - (block $label$96 - (block $label$97 - (block $label$98 - (block $label$99 - (block $label$100 - (block $label$101 - (block $label$102 - (block $label$103 - (block $label$104 - (block $label$105 - (block $label$106 - (block $label$107 - (block $label$108 - (block $label$109 - (block $label$110 - (block $label$111 - (block $label$112 - (block $label$113 - (block $label$114 - (block $label$115 - (block $label$116 - (block $label$117 - (block $label$118 - (block $label$119 - (block $label$120 - (block $label$121 - (block $label$122 - (block $label$123 - (block $label$124 - (block $label$125 - (block $label$126 - (block $label$127 - (block $label$128 - (block $label$129 - (block $label$130 - (block $label$131 - (block $label$132 - (block $label$133 - (block $label$134 - (block $label$135 - (br_if $label$135 - (i64.le_s - (get_local $2) - (i64.const -5767735918449313230) - ) - ) - (br_if $label$134 - (i64.le_s - (get_local $2) - (i64.const -696013502478964675) - ) - ) - (br_if $label$132 - (i64.gt_s - (get_local $2) - (i64.const -696013501204331988) - ) - ) - (br_if $label$128 - (i64.gt_s - (get_local $2) - (i64.const -696013502015841439) - ) - ) - (br_if $label$120 - (i64.le_s - (get_local $2) - (i64.const -696013502305735711) - ) - ) - (br_if $label$104 - (i64.eq - (get_local $2) - (i64.const -696013502305735710) - ) - ) - (br_if $label$103 - (i64.eq - (get_local $2) - (i64.const -696013502197092929) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013502194763679) - ) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 18400) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$136 - (block $label$137 - (block $label$138 - (block $label$139 - (block $label$140 - (block $label$141 - (br_if $label$141 - (i64.gt_u - (get_local $7) - (i64.const 9) - ) - ) - (br_if $label$140 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$139) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$138 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$137) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$136 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $activate_feature - (get_local $8) - ) - (br $label$6) - ) - (br_if $label$133 - (i64.gt_s - (get_local $2) - (i64.const -7587351443459632866) - ) - ) - (br_if $label$131 - (i64.le_s - (get_local $2) - (i64.const -7587351445379665367) - ) - ) - (br_if $label$127 - (i64.gt_s - (get_local $2) - (i64.const -7587351443887725216) - ) - ) - (br_if $label$119 - (i64.le_s - (get_local $2) - (i64.const -7587351445310893856) - ) - ) - (br_if $label$102 - (i64.eq - (get_local $2) - (i64.const -7587351445310893855) - ) - ) - (br_if $label$101 - (i64.eq - (get_local $2) - (i64.const -7587351445208375855) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351444330131777) - ) - ) - (set_local $3 - (i32.const 0) - ) - (call $sha256 - (i32.const 8960) - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$142 - (loop $label$143 - (br_if $label$142 - (i32.ne - (i32.load8_u - (i32.add - (get_local $5) - (i32.const 9024) - ) - ) - (i32.load8_u - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (get_local $5) - ) - ) - ) - ) - (br_if $label$143 - (i32.le_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 9056) - ) - (br $label$6) - ) - (br_if $label$130 - (i64.le_s - (get_local $2) - (i64.const -4239006003814146663) - ) - ) - (br_if $label$126 - (i64.gt_s - (get_local $2) - (i64.const -696013503128813882) - ) - ) - (br_if $label$118 - (i64.le_s - (get_local $2) - (i64.const -4239006002805448792) - ) - ) - (br_if $label$100 - (i64.eq - (get_local $2) - (i64.const -4239006002805448791) - ) - ) - (br_if $label$99 - (i64.eq - (get_local $2) - (i64.const -696013503327366014) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013503202962952) - ) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $10) - (i64.const -1) - ) - (call $eosio_assert - (i32.ne - (call $cancel_deferred - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (i32.const 0) - ) - (i32.const 18128) - ) - (br $label$6) - ) - (br_if $label$129 - (i64.le_s - (get_local $2) - (i64.const -7078304395291034138) - ) - ) - (br_if $label$125 - (i64.gt_s - (get_local $2) - (i64.const -5767735919218491074) - ) - ) - (br_if $label$117 - (i64.le_s - (get_local $2) - (i64.const -5767735919218491584) - ) - ) - (br_if $label$98 - (i64.eq - (get_local $2) - (i64.const -5767735919218491583) - ) - ) - (br_if $label$97 - (i64.eq - (get_local $2) - (i64.const -5767735919218491512) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -5767735919218491446) - ) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 4611123068473966592) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=40 - (get_local $10) - (i64.const -4611439727822766080) - ) - (i64.store offset=32 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $10) - (i64.const 4605605624503281953) - ) - (i64.store offset=16 - (get_local $10) - (i64.const 1865728291273748996) - ) - (call $printqf - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printqf - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printqf - (i32.add - (get_local $10) - (i32.const 16) - ) - ) - (call $prints - (i32.const 1824) - ) - (br $label$6) - ) - (br_if $label$124 - (i64.gt_s - (get_local $2) - (i64.const -696013500238724021) - ) - ) - (br_if $label$116 - (i64.le_s - (get_local $2) - (i64.const -696013501027893081) - ) - ) - (br_if $label$96 - (i64.eq - (get_local $2) - (i64.const -696013501027893080) - ) - ) - (br_if $label$95 - (i64.eq - (get_local $2) - (i64.const -696013500328286318) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013500268167086) - ) - ) - (i32.store offset=208 - (get_local $10) - (i32.const 0) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 4) - ) - ) - (set_local $5 - (call $transaction_size) - ) - (call $prints - (i32.const 17648) - ) - (call $printui - (i64.extend_u/i32 - (get_local $5) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=208 - (get_local $10) - ) - (call $transaction_size) - ) - (i32.const 17664) - ) - (br $label$6) - ) - (br_if $label$123 - (i64.le_s - (get_local $2) - (i64.const -8022470633028214611) - ) - ) - (br_if $label$115 - (i64.le_s - (get_local $2) - (i64.const -7587351446419414473) - ) - ) - (br_if $label$94 - (i64.eq - (get_local $2) - (i64.const -7587351446419414472) - ) - ) - (br_if $label$93 - (i64.eq - (get_local $2) - (i64.const -7587351446368672234) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351445800925699) - ) - ) - (call $sha512 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha512 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha512 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha512 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha512 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha512 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha512 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha512 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (br_if $label$122 - (i64.le_s - (get_local $2) - (i64.const -4239006005939931649) - ) - ) - (br_if $label$114 - (i64.le_s - (get_local $2) - (i64.const -4239006005058986438) - ) - ) - (br_if $label$92 - (i64.eq - (get_local $2) - (i64.const -4239006005058986437) - ) - ) - (br_if $label$91 - (i64.eq - (get_local $2) - (i64.const -4239006004389140451) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -4239006003864401096) - ) - ) - (call $printi - (i64.const 49995000) - ) - (br $label$6) - ) - (br_if $label$121 - (i64.le_s - (get_local $2) - (i64.const -7587351442891060093) - ) - ) - (br_if $label$113 - (i64.le_s - (get_local $2) - (i64.const -7587351442575377031) - ) - ) - (br_if $label$90 - (i64.eq - (get_local $2) - (i64.const -7587351442575377030) - ) - ) - (br_if $label$89 - (i64.eq - (get_local $2) - (i64.const -7078304397416668495) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7078304396558272662) - ) - ) - (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $eosio_assert - (i64.eq - (call $get_permission_last_used - (i64.load offset=208 - (get_local $10) - ) - (i64.load offset=216 - (get_local $10) - ) - ) - (i64.load offset=224 - (get_local $10) - ) - ) - (i32.const 18464) - ) - (br $label$6) - ) - (br_if $label$112 - (i64.le_s - (get_local $2) - (i64.const -696013501554943132) - ) - ) - (br_if $label$88 - (i64.eq - (get_local $2) - (i64.const -696013501554943131) - ) - ) - (br_if $label$87 - (i64.eq - (get_local $2) - (i64.const -696013501453266856) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013501288626511) - ) - ) - (call $_ZN16test_transaction32send_deferred_tx_with_dtt_actionEv) - (br $label$6) - ) - (br_if $label$111 - (i64.le_s - (get_local $2) - (i64.const -7587351443763769797) - ) - ) - (br_if $label$86 - (i64.eq - (get_local $2) - (i64.const -7587351443763769796) - ) - ) - (br_if $label$85 - (i64.eq - (get_local $2) - (i64.const -7587351443732945056) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351443732941913) - ) - ) - (call $_ZN11test_crypto11test_sha256Ev) - (br $label$6) - ) - (br_if $label$110 - (i64.le_s - (get_local $2) - (i64.const -696013502719373095) - ) - ) - (br_if $label$84 - (i64.eq - (get_local $2) - (i64.const -696013502719373094) - ) - ) - (br_if $label$83 - (i64.eq - (get_local $2) - (i64.const -696013502690195168) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013502688730040) - ) - ) - (call $_ZN16test_transaction22send_transaction_emptyEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (br_if $label$109 - (i64.le_s - (get_local $2) - (i64.const -5767735918831569476) - ) - ) - (br_if $label$82 - (i64.eq - (get_local $2) - (i64.const -5767735918831569475) - ) - ) - (br_if $label$81 - (i64.eq - (get_local $2) - (i64.const -5767735918500807270) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -5767735918449313234) - ) - ) - (call $prints - (i32.const 1776) - ) - (call $prints - (i32.const 0) - ) - (call $prints - (i32.const 1792) - ) - (call $prints - (i32.const 0) - ) - (call $prints - (i32.const 1808) - ) - (call $prints - (i32.const 0) - ) - (br $label$6) - ) - (br_if $label$108 - (i64.le_s - (get_local $2) - (i64.const -696013499845391607) - ) - ) - (br_if $label$80 - (i64.eq - (get_local $2) - (i64.const -696013499845391606) - ) - ) - (br_if $label$79 - (i64.eq - (get_local $2) - (i64.const -696013499608977787) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -187209993639507722) - ) - ) - (call $_ZN15test_datastream10test_basicEv) - (br $label$6) - ) - (br_if $label$107 - (i64.gt_s - (get_local $2) - (i64.const -8022470633505015025) - ) - ) - (br_if $label$78 - (i64.eq - (get_local $2) - (i64.const -8022470634635220200) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -8022470633818130162) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5888) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5952) - ) - (br $label$6) - ) - (br_if $label$106 - (i64.gt_s - (get_local $2) - (i64.const -4239006006334808644) - ) - ) - (br_if $label$77 - (i64.eq - (get_local $2) - (i64.const -5767735918449313229) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -5767735918449313228) - ) - ) - (call $printi - (i64.const 0) - ) - (call $printi - (i64.const 556644) - ) - (call $printi - (i64.const -1) - ) - (br $label$6) - ) - (br_if $label$105 - (i64.gt_s - (get_local $2) - (i64.const -7587351443299599511) - ) - ) - (br_if $label$76 - (i64.eq - (get_local $2) - (i64.const -7587351443459632865) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351443325747446) - ) - ) - (call $ripemd160 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (i32.store8 offset=208 - (get_local $10) - (i32.xor - (i32.load8_u offset=208 - (get_local $10) - ) - (i32.const -1) - ) - ) - (call $assert_ripemd160 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (br $label$6) - ) - (br_if $label$75 - (i64.eq - (get_local $2) - (i64.const -696013502478964674) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013502330537453) - ) - ) - (call $_ZN16test_transaction23send_action_inline_failEv) - (br $label$6) - ) - (br_if $label$74 - (i64.eq - (get_local $2) - (i64.const -7587351445379665366) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351445375451046) - ) - ) - (call $sha256 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha256 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha256 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha256 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha256 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha256 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha256 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha256 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (br_if $label$73 - (i64.eq - (get_local $2) - (i64.const -4239006003814146662) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -4239006002882681946) - ) - ) - (call $ripemd160 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (br_if $label$72 - (i64.eq - (get_local $2) - (i64.const -7078304395291034137) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -5823726059754506790) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 169) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load8_u offset=208 - (get_local $10) - ) - (i32.const 21) - ) - (i32.const 9232) - ) - (set_local $5 - (i32.const 1) - ) - (drop - (call $get_active_producers - (i32.or - (i32.add - (get_local $10) - (i32.const 32) - ) - (i32.const 1) - ) - (i32.const 168) - ) - ) - (loop $label$144 - (call $eosio_assert - (i64.eq - (i64.load align=1 - (i32.add - (i32.add - (get_local $10) - (i32.const 32) - ) - (get_local $5) - ) - ) - (i64.load align=1 - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (get_local $5) - ) - ) - ) - (i32.const 9264) - ) - (br_if $label$144 - (i32.ne - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 8) - ) - ) - (i32.const 169) - ) - ) - (br $label$6) - ) - ) - (br_if $label$71 - (i64.eq - (get_local $2) - (i64.const -696013501204331987) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013501174438164) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=208 - (get_local $10) - ) - (call $tapos_block_prefix) - ) - (i32.const 17536) - ) - (br $label$6) - ) - (br_if $label$70 - (i64.eq - (get_local $2) - (i64.const -8022470633028214610) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -8022470632789685404) - ) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5232) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5312) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5376) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5440) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5504) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5568) - ) - (br $label$6) - ) - (br_if $label$69 - (i64.eq - (get_local $2) - (i64.const -4239006005939931648) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -4239006005769928793) - ) - ) - (call $assert_sha512 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (br_if $label$68 - (i64.eq - (get_local $2) - (i64.const -7587351442891060092) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351442863559481) - ) - ) - (call $_ZN11test_crypto9test_sha1Ev) - (br $label$6) - ) - (br_if $label$67 - (i64.eq - (get_local $2) - (i64.const -696013502015841438) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013501581368598) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 4) - ) - ) - (call $eosio_assert - (i32.eq - (i32.load offset=208 - (get_local $10) - ) - (call $tapos_block_num) - ) - (i32.const 17584) - ) - (br $label$6) - ) - (br_if $label$66 - (i64.eq - (get_local $2) - (i64.const -7587351443887725215) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351443788808834) - ) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 144) - ) - ) - (drop - (call $recover_key - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 66) - ) - (i32.const 66) - (i32.add - (get_local $10) - (i32.const 32) - ) - (i32.const 34) - ) - ) - (set_local $3 - (i32.add - (get_local $10) - (i32.const 240) - ) - ) - (set_local $5 - (i32.const 0) - ) - (loop $label$145 - (block $label$146 - (br_if $label$146 - (i32.eq - (i32.load8_u - (i32.add - (i32.add - (get_local $10) - (i32.const 32) - ) - (get_local $5) - ) - ) - (i32.load8_u - (i32.add - (get_local $3) - (get_local $5) - ) - ) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7808) - ) - ) - (br_if $label$145 - (i32.ne - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 34) - ) - ) - (br $label$6) - ) - ) - (br_if $label$65 - (i64.eq - (get_local $2) - (i64.const -696013503128813881) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013502727104654) - ) - ) - (call $_ZN16test_transaction17send_action_emptyEv) - (br $label$6) - ) - (br_if $label$64 - (i64.eq - (get_local $2) - (i64.const -5767735919218491073) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -5767735918947814449) - ) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $10) - (i64.const 1) - ) - (i64.store offset=40 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=32 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $10) - (i64.const -9223372036854775808) - ) - (i64.store offset=16 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=8 - (get_local $10) - (i64.const -1) - ) - (i64.store - (get_local $10) - (i64.const -87654323456) - ) - (call $printi128 - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printi128 - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printi128 - (i32.add - (get_local $10) - (i32.const 16) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printi128 - (get_local $10) - ) - (call $prints - (i32.const 1824) - ) - (br $label$6) - ) - (br_if $label$63 - (i64.eq - (get_local $2) - (i64.const -696013500238724020) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -696013500020145514) - ) - ) - (drop - (call $memset - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 0) - (i32.const 128) - ) - ) - (drop - (call $get_context_free_data - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 128) - ) - ) - (br $label$6) - ) - (br_if $label$62 - (i64.eq - (get_local $2) - (i64.const -8022470633505015024) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -8022470633369446971) - ) - ) - (call $_ZN15test_fixedpoint13test_divisionEv) - (br $label$6) - ) - (br_if $label$61 - (i64.eq - (get_local $2) - (i64.const -4239006006334808643) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -4239006006118930912) - ) - ) - (call $assert_sha256 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (br_if $label$60 - (i64.eq - (get_local $2) - (i64.const -7587351443299599510) - ) - ) - (br_if $label$59 - (i64.ne - (get_local $2) - (i64.const -7587351442991046735) - ) - ) - (call $sha1 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (i32.store8 offset=208 - (get_local $10) - (i32.xor - (i32.load8_u offset=208 - (get_local $10) - ) - (i32.const -1) - ) - ) - (call $assert_sha1 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (br $label$6) - ) - (call $_ZN16test_transaction16send_transactionEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (call $_ZN16test_transaction19send_cf_action_failEv) - (br $label$6) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 144) - ) - ) - (call $assert_recover_key - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 66) - ) - (i32.const 66) - (i32.add - (get_local $10) - (i32.const 240) - ) - (i32.const 34) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 7776) - ) - (br $label$6) - ) - (call $sha256 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (i32.store8 offset=208 - (get_local $10) - (i32.xor - (i32.load8_u offset=208 - (get_local $10) - ) - (i32.const -1) - ) - ) - (call $assert_sha256 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (br $label$6) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $9 - (i64.const 1) - ) - (set_local $7 - (i64.const 0) - ) - (loop $label$147 - (set_local $6 - (i64.add - (i64.and - (tee_local $8 - (get_local $6) - ) - (i64.const 4294967295) - ) - (get_local $7) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (br_if $label$147 - (i64.ne - (tee_local $9 - (i64.add - (get_local $9) - (i64.const -1) - ) - ) - (i64.const 8446744073709551617) - ) - ) - ) - (call $printi - (i64.shr_s - (i64.shl - (i64.sub - (get_local $8) - (get_local $9) - ) - (i64.const 32) - ) - (i64.const 32) - ) - ) - (br $label$6) - ) - (call $_ZN16test_transaction14send_cf_actionEv) - (br $label$6) - ) - (call $printui - (i64.const 0) - ) - (call $printui - (i64.const 556644) - ) - (call $printui - (i64.const -1) - ) - (br $label$6) - ) - (call $printsf - (f32.const 0.5) - ) - (call $prints - (i32.const 1824) - ) - (call $printsf - (f32.const -3.75) - ) - (call $prints - (i32.const 1824) - ) - (call $printsf - (f32.const 6.666666649834951e-07) - ) - (call $prints - (i32.const 1824) - ) - (br $label$6) - ) - (call $prints - (i32.const 18096) - ) - (br $label$6) - ) - (set_local $7 - (i64.const 0) - ) - (set_local $6 - (i64.const 59) - ) - (set_local $5 - (i32.const 18400) - ) - (set_local $8 - (i64.const 0) - ) - (loop $label$148 - (block $label$149 - (block $label$150 - (block $label$151 - (block $label$152 - (block $label$153 - (br_if $label$153 - (i64.gt_u - (get_local $7) - (i64.const 9) - ) - ) - (br_if $label$152 - (i32.gt_u - (i32.and - (i32.add - (tee_local $3 - (i32.load8_s - (get_local $5) - ) - ) - (i32.const -97) - ) - (i32.const 255) - ) - (i32.const 25) - ) - ) - (set_local $3 - (i32.add - (get_local $3) - (i32.const 165) - ) - ) - (br $label$151) - ) - (set_local $9 - (i64.const 0) - ) - (br_if $label$150 - (i64.le_u - (get_local $7) - (i64.const 11) - ) - ) - (br $label$149) - ) - (set_local $3 - (select - (i32.add - (get_local $3) - (i32.const 208) - ) - (i32.const 0) - (i32.lt_u - (i32.and - (i32.add - (get_local $3) - (i32.const -49) - ) - (i32.const 255) - ) - (i32.const 5) - ) - ) - ) - ) - (set_local $9 - (i64.shr_s - (i64.shl - (i64.extend_u/i32 - (get_local $3) - ) - (i64.const 56) - ) - (i64.const 56) - ) - ) - ) - (set_local $9 - (i64.shl - (i64.and - (get_local $9) - (i64.const 31) - ) - (i64.and - (get_local $6) - (i64.const 4294967295) - ) - ) - ) - ) - (set_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (set_local $7 - (i64.add - (get_local $7) - (i64.const 1) - ) - ) - (set_local $8 - (i64.or - (get_local $9) - (get_local $8) - ) - ) - (br_if $label$148 - (i64.ne - (tee_local $6 - (i64.add - (get_local $6) - (i64.const -5) - ) - ) - (i64.const -6) - ) - ) - ) - (call $eosio_assert - (i32.eqz - (call $is_feature_active - (get_local $8) - ) - ) - (i32.const 18416) - ) - (br $label$6) - ) - (set_local $3 - (i32.const 0) - ) - (call $sha512 - (i32.const 8960) - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$154 - (loop $label$155 - (br_if $label$154 - (i32.ne - (i32.load8_u - (i32.add - (get_local $5) - (i32.const 9072) - ) - ) - (i32.load8_u - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (get_local $5) - ) - ) - ) - ) - (br_if $label$155 - (i32.le_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 63) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 9136) - ) - (br $label$6) - ) - (call $sha512 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (i32.store8 offset=208 - (get_local $10) - (i32.xor - (i32.load8_u offset=208 - (get_local $10) - ) - (i32.const -1) - ) - ) - (call $assert_sha512 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 9200) - ) - (br $label$6) - ) - (call $assert_ripemd160 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (call $sha256 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (call $sha1 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha1 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha1 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha1 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha1 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha1 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $sha1 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_sha1 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (call $_ZN5eosio18unpack_action_dataI29test_permission_last_used_msgEET_v - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $eosio_assert - (i64.eq - (call $get_account_creation_time - (i64.load offset=208 - (get_local $10) - ) - ) - (i64.load offset=224 - (get_local $10) - ) - ) - (i32.const 18512) - ) - (br $label$6) - ) - (call $_ZN16test_transaction21test_read_transactionEv) - (br $label$6) - ) - (call $_ZN16test_transaction11send_actionEv) - (br $label$6) - ) - (call $_ZN11test_crypto14test_ripemd160Ev) - (br $label$6) - ) - (call $_ZN11test_crypto11test_sha512Ev) - (br $label$6) - ) - (call $_ZN16test_transaction17send_action_largeEv) - (br $label$6) - ) - (call $_ZN16test_transaction22send_transaction_largeEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (i32.store16 offset=208 - (get_local $10) - (i32.const 25185) - ) - (call $prints_l - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 2) - ) - (call $prints_l - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 1) - ) - (call $prints_l - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 0) - ) - (call $prints_l - (i32.const 944) - (i32.const 4) - ) - (br $label$6) - ) - (i64.store offset=216 - (get_local $10) - (i64.const -1) - ) - (i64.store offset=208 - (get_local $10) - (i64.const -1) - ) - (i64.store offset=40 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=32 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=24 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=16 - (get_local $10) - (i64.const 87654323456) - ) - (call $printui128 - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printui128 - (i32.add - (get_local $10) - (i32.const 32) - ) - ) - (call $prints - (i32.const 1824) - ) - (call $printui128 - (i32.add - (get_local $10) - (i32.const 16) - ) - ) - (call $prints - (i32.const 1824) - ) - (br $label$6) - ) - (call $_ZN16test_transaction12stateful_apiEv) - (br $label$6) - ) - (call $_ZN16test_transaction38send_transaction_trigger_error_handlerEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5632) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5696) - ) - (br $label$6) - ) - (call $_ZN10test_print11test_printnEv) - (br $label$6) - ) - (set_local $3 - (i32.const 0) - ) - (call $sha1 - (i32.const 8960) - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$156 - (loop $label$157 - (br_if $label$156 - (i32.ne - (i32.load8_u - (i32.add - (get_local $5) - (i32.const 8976) - ) - ) - (i32.load8_u - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (get_local $5) - ) - ) - ) - ) - (br_if $label$157 - (i32.le_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 9008) - ) - (br $label$6) - ) - (call $_ZN16test_transaction25send_deferred_transactionEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (drop - (call $read_action_data - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 144) - ) - ) - (call $assert_recover_key - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (i32.const 66) - ) - (i32.const 66) - (i32.add - (get_local $10) - (i32.const 240) - ) - (i32.const 34) - ) - (br $label$6) - ) - (call $sha512 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (call $_ZN15test_permission19check_authorizationEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (call $_ZN16test_transaction33send_deferred_transaction_replaceEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6016) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 6160) - ) - (br $label$6) - ) - (call $assert_sha1 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (set_local $3 - (i32.const 0) - ) - (call $ripemd160 - (i32.const 8960) - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (set_local $5 - (i32.const 0) - ) - (block $label$158 - (loop $label$159 - (br_if $label$158 - (i32.ne - (i32.load8_u - (i32.add - (get_local $5) - (i32.const 9152) - ) - ) - (i32.load8_u - (i32.add - (i32.add - (get_local $10) - (i32.const 208) - ) - (get_local $5) - ) - ) - ) - ) - (br_if $label$159 - (i32.le_u - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - (i32.const 31) - ) - ) - ) - (set_local $3 - (i32.const 1) - ) - ) - (call $eosio_assert - (get_local $3) - (i32.const 9184) - ) - (br $label$6) - ) - (call $_ZN16test_transaction19send_action_recurseEv) - (br $label$6) - ) - (call $ripemd160 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_ripemd160 - (i32.const 7840) - (i32.const 3) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $ripemd160 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_ripemd160 - (i32.const 7904) - (i32.const 56) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $ripemd160 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_ripemd160 - (i32.const 8016) - (i32.const 112) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $ripemd160 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (call $assert_ripemd160 - (i32.const 8192) - (i32.const 14) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (i64.store offset=216 - (get_local $10) - (i64.const 0) - ) - (i64.store offset=208 - (get_local $10) - (i64.const -1) - ) - (call $eosio_assert - (i32.eqz - (call $cancel_deferred - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - ) - (i32.const 18160) - ) - (br $label$6) - ) - (call $printdf - (f64.const 0.5) - ) - (call $prints - (i32.const 1824) - ) - (call $printdf - (f64.const -3.75) - ) - (call $prints - (i32.const 1824) - ) - (call $printdf - (f64.const 6.666666666666666e-07) - ) - (call $prints - (i32.const 1824) - ) - (br $label$6) - ) - (call $_ZN16test_transaction18send_action_senderEyyy - (get_local $0) - (get_local $7) - (get_local $7) - ) - (br $label$6) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5760) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5760) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5824) - ) - (call $eosio_assert - (i32.const 1) - (i32.const 5824) - ) - (br $label$6) - ) - (call $sha1 - (call $_Znaj - (i32.const 20000000) - ) - (i32.const 20000000) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (call $sha256 - (i32.const 0) - (i32.const 100) - (i32.add - (get_local $10) - (i32.const 208) - ) - ) - (br $label$6) - ) - (call $eosio_assert - (i32.const 0) - (i32.const 18992) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $10) - (i32.const 384) - ) - ) - ) - (func $_ZN5eosio18unpack_action_dataINS_7onerrorEEET_v (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (set_local $3 - (tee_local $2 - (i32.sub - (i32.load offset=4 - (i32.const 0) - ) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (get_local $2) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.lt_u - (tee_local $1 - (call $action_data_size) - ) - (i32.const 513) - ) - ) - (set_local $2 - (call $malloc - (get_local $1) - ) - ) - (br $label$0) - ) - (i32.store offset=4 - (i32.const 0) - (tee_local $2 - (i32.sub - (get_local $2) - (i32.and - (i32.add - (get_local $1) - (i32.const 15) - ) - (i32.const -16) - ) - ) - ) - ) - ) - (drop - (call $read_action_data - (get_local $2) - (get_local $1) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 24) - ) - (i32.const 0) - ) - (i64.store offset=16 align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store offset=8 - (get_local $3) - (i32.add - (get_local $2) - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (get_local $2) - ) - (call $eosio_assert - (i32.gt_u - (get_local $1) - (i32.const 15) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $0) - (get_local $2) - (i32.const 16) - ) - ) - (i32.store offset=4 - (get_local $3) - (i32.add - (get_local $2) - (i32.const 16) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE - (get_local $3) - (i32.add - (get_local $0) - (i32.const 16) - ) - ) - ) - (i32.store offset=4 - (i32.const 0) - (i32.add - (get_local $3) - (i32.const 16) - ) - ) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNS_18transaction_headerE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (i32.load offset=4 - (get_local $0) - ) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $1) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 1) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 2) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $2 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 2) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load offset=8 - (get_local $0) - ) - (get_local $2) - ) - (i32.const 3) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 8) - ) - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - (i32.store offset=4 - (get_local $0) - (tee_local $4 - (i32.add - (i32.load offset=4 - (get_local $0) - ) - (i32.const 4) - ) - ) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $4) - (i32.load - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (i32.const 848) - ) - (set_local $2 - (i32.load8_u - (tee_local $4 - (i32.load - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - ) - ) - (i32.store - (get_local $7) - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $2) - (i32.const 127) - ) - (tee_local $6 - (i32.and - (get_local $6) - (i32.const 255) - ) - ) - ) - ) - (get_local $5) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $2) - (i32.const 7) - ) - ) - ) - (i64.store32 offset=12 - (get_local $1) - (get_local $5) - ) - (call $eosio_assert - (i32.ne - (i32.load - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (get_local $4) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.load - (tee_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (i32.const 1) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 1) - ) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $5 - (i64.const 0) - ) - (loop $label$1 - (call $eosio_assert - (i32.lt_u - (get_local $6) - (i32.load - (get_local $3) - ) - ) - (i32.const 848) - ) - (set_local $2 - (i32.load8_u - (tee_local $6 - (i32.load - (get_local $4) - ) - ) - ) - ) - (i32.store - (get_local $4) - (tee_local $6 - (i32.add - (get_local $6) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $2) - (i32.const 127) - ) - (tee_local $7 - (i32.and - (get_local $7) - (i32.const 255) - ) - ) - ) - ) - (get_local $5) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 7) - ) - ) - (br_if $label$1 - (i32.shr_u - (get_local $2) - (i32.const 7) - ) - ) - ) - (i64.store32 offset=20 - (get_local $1) - (get_local $5) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEENS_6actionEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i64) - (local $6 i32) - (local $7 i32) - (set_local $7 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $5 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $7) - (i32.load - (get_local $2) - ) - ) - (i32.const 848) - ) - (set_local $4 - (i32.load8_u - (tee_local $7 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 1) - ) - ) - ) - (set_local $5 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $6 - (i32.and - (get_local $6) - (i32.const 255) - ) - ) - ) - ) - (get_local $5) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.le_u - (tee_local $4 - (i32.wrap/i64 - (get_local $5) - ) - ) - (tee_local $7 - (i32.div_s - (i32.sub - (tee_local $2 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $6 - (i32.load - (get_local $1) - ) - ) - ) - (i32.const 40) - ) - ) - ) - ) - (call $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE8__appendEj - (get_local $1) - (i32.sub - (get_local $4) - (get_local $7) - ) - ) - (set_local $2 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - (br $label$1) - ) - (br_if $label$1 - (i32.ge_u - (get_local $4) - (get_local $7) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $2) - (tee_local $3 - (i32.add - (get_local $6) - (tee_local $4 - (i32.mul - (get_local $4) - (i32.const 40) - ) - ) - ) - ) - ) - ) - (set_local $6 - (i32.sub - (i32.sub - (i32.const 0) - (get_local $6) - ) - (get_local $4) - ) - ) - (set_local $4 - (i32.add - (get_local $2) - (i32.const -24) - ) - ) - (loop $label$4 - (block $label$5 - (br_if $label$5 - (i32.eqz - (tee_local $7 - (i32.load - (i32.add - (get_local $4) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 16) - ) - (get_local $7) - ) - (call $_ZdlPv - (get_local $7) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.eqz - (tee_local $7 - (i32.load - (get_local $4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 4) - ) - (get_local $7) - ) - (call $_ZdlPv - (get_local $7) - ) - ) - (br_if $label$4 - (i32.ne - (i32.add - (tee_local $4 - (i32.add - (get_local $4) - (i32.const -40) - ) - ) - (get_local $6) - ) - (i32.const -24) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (get_local $3) - ) - (set_local $2 - (get_local $3) - ) - ) - (block $label$7 - (br_if $label$7 - (i32.eq - (tee_local $7 - (i32.load - (get_local $1) - ) - ) - (get_local $2) - ) - ) - (set_local $4 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$8 - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (tee_local $6 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - ) - (i32.load - (get_local $4) - ) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $7) - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (tee_local $3 - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - ) - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (get_local $6) - ) - (get_local $3) - ) - (i32.const 7) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (i32.add - (get_local $7) - (i32.const 8) - ) - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - (i32.store - (get_local $4) - (i32.add - (i32.load - (get_local $4) - ) - (i32.const 8) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE - (call $_ZN5eosiorsINS_10datastreamIPKcEENS_16permission_levelEEERT_S7_RNSt3__16vectorIT0_NS8_9allocatorISA_EEEE - (get_local $0) - (i32.add - (get_local $7) - (i32.const 16) - ) - ) - (i32.add - (get_local $7) - (i32.const 28) - ) - ) - ) - (br_if $label$8 - (i32.ne - (tee_local $7 - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - (get_local $2) - ) - ) - ) - ) - (get_local $0) - ) - (func $_ZN5eosiorsINS_10datastreamIPKcEENSt3__15tupleIJtNS5_6vectorIcNS5_9allocatorIcEEEEEEEEERT_SD_RNS7_IT0_NS8_ISE_EEEE (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i64) - (local $7 i32) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $6 - (i64.const 0) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$0 - (call $eosio_assert - (i32.lt_u - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.const 848) - ) - (set_local $4 - (i32.load8_u - (tee_local $5 - (i32.load - (get_local $3) - ) - ) - ) - ) - (i32.store - (get_local $3) - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - (set_local $6 - (i64.or - (i64.extend_u/i32 - (i32.shl - (i32.and - (get_local $4) - (i32.const 127) - ) - (tee_local $7 - (i32.and - (get_local $7) - (i32.const 255) - ) - ) - ) - ) - (get_local $6) - ) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 7) - ) - ) - (br_if $label$0 - (i32.shr_u - (get_local $4) - (i32.const 7) - ) - ) - ) - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.le_u - (tee_local $4 - (i32.wrap/i64 - (get_local $6) - ) - ) - (tee_local $5 - (i32.shr_s - (i32.sub - (tee_local $7 - (i32.load offset=4 - (get_local $1) - ) - ) - (tee_local $3 - (i32.load - (get_local $1) - ) - ) - ) - (i32.const 4) - ) - ) - ) - ) - (call $_ZNSt3__16vectorINS_5tupleIJtNS0_IcNS_9allocatorIcEEEEEEENS2_IS5_EEE8__appendEj - (get_local $1) - (i32.sub - (get_local $4) - (get_local $5) - ) - ) - (set_local $7 - (i32.load - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - (br $label$1) - ) - (br_if $label$1 - (i32.ge_u - (get_local $4) - (get_local $5) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.eq - (get_local $7) - (tee_local $2 - (i32.add - (get_local $3) - (tee_local $4 - (i32.shl - (get_local $4) - (i32.const 4) - ) - ) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.sub - (i32.const 0) - (get_local $3) - ) - (get_local $4) - ) - ) - (set_local $4 - (i32.add - (get_local $7) - (i32.const -12) - ) - ) - (loop $label$4 - (block $label$5 - (br_if $label$5 - (i32.eqz - (tee_local $5 - (i32.load - (get_local $4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $4) - (i32.const 4) - ) - (get_local $5) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - (br_if $label$4 - (i32.ne - (i32.add - (tee_local $4 - (i32.add - (get_local $4) - (i32.const -16) - ) - ) - (get_local $3) - ) - (i32.const -12) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $1) - (i32.const 4) - ) - (get_local $2) - ) - (set_local $7 - (get_local $2) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.eq - (tee_local $4 - (i32.load - (get_local $1) - ) - ) - (get_local $7) - ) - ) - (set_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (loop $label$7 - (call $eosio_assert - (i32.gt_u - (i32.sub - (i32.load - (get_local $3) - ) - (i32.load - (tee_local $5 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - ) - (i32.const 1) - ) - (i32.const 800) - ) - (drop - (call $memcpy - (get_local $4) - (i32.load - (get_local $5) - ) - (i32.const 2) - ) - ) - (i32.store - (get_local $5) - (i32.add - (i32.load - (get_local $5) - ) - (i32.const 2) - ) - ) - (drop - (call $_ZN5eosiorsINS_10datastreamIPKcEEEERT_S6_RNSt3__16vectorIcNS7_9allocatorIcEEEE - (get_local $0) - (i32.add - (get_local $4) - (i32.const 4) - ) - ) - ) - (br_if $label$7 - (i32.ne - (tee_local $4 - (i32.add - (get_local $4) - (i32.const 16) - ) - ) - (get_local $7) - ) - ) - ) - ) - (get_local $0) - ) - (func $_ZNSt3__16vectorINS_5tupleIJtNS0_IcNS_9allocatorIcEEEEEEENS2_IS5_EEE8__appendEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (i32.shr_s - (i32.sub - (tee_local $8 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $7 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (i32.const 4) - ) - (get_local $1) - ) - ) - (br_if $label$2 - (i32.ge_u - (tee_local $7 - (i32.add - (tee_local $4 - (i32.shr_s - (i32.sub - (get_local $7) - (tee_local $5 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 4) - ) - ) - (get_local $1) - ) - ) - (i32.const 268435456) - ) - ) - (set_local $6 - (i32.const 268435455) - ) - (block $label$5 - (br_if $label$5 - (i32.gt_u - (i32.shr_s - (tee_local $8 - (i32.sub - (get_local $8) - (get_local $5) - ) - ) - (i32.const 4) - ) - (i32.const 134217726) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $6 - (select - (get_local $7) - (tee_local $6 - (i32.shr_s - (get_local $8) - (i32.const 3) - ) - ) - (i32.lt_u - (get_local $6) - (get_local $7) - ) - ) - ) - ) - ) - (br_if $label$1 - (i32.ge_u - (get_local $6) - (i32.const 268435456) - ) - ) - ) - (set_local $8 - (call $_Znwj - (i32.shl - (get_local $6) - (i32.const 4) - ) - ) - ) - (br $label$0) - ) - (set_local $6 - (get_local $7) - ) - (set_local $8 - (get_local $1) - ) - (loop $label$6 - (i32.store16 - (get_local $6) - (i32.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $6) - (i32.const 4) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $6) - (i32.const 12) - ) - (i32.const 0) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (br_if $label$6 - (tee_local $8 - (i32.add - (get_local $8) - (i32.const -1) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (i32.add - (get_local $7) - (i32.shl - (get_local $1) - (i32.const 4) - ) - ) - ) - (return) - ) - (set_local $6 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$0) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (call $abort) - (unreachable) - ) - (set_local $2 - (i32.add - (get_local $8) - (i32.shl - (get_local $6) - (i32.const 4) - ) - ) - ) - (set_local $6 - (tee_local $8 - (i32.add - (get_local $8) - (i32.shl - (get_local $4) - (i32.const 4) - ) - ) - ) - ) - (set_local $7 - (get_local $1) - ) - (loop $label$7 - (i32.store16 - (get_local $6) - (i32.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $6) - (i32.const 4) - ) - (i64.const 0) - ) - (i32.store - (i32.add - (get_local $6) - (i32.const 12) - ) - (i32.const 0) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const 16) - ) - ) - (br_if $label$7 - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -1) - ) - ) - ) - ) - (set_local $3 - (i32.add - (get_local $8) - (i32.shl - (get_local $1) - (i32.const 4) - ) - ) - ) - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.eq - (tee_local $7 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $6 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $4 - (i32.sub - (i32.const 0) - (get_local $6) - ) - ) - (set_local $6 - (i32.add - (get_local $7) - (i32.const -16) - ) - ) - (loop $label$10 - (i32.store16 - (i32.add - (get_local $8) - (i32.const -16) - ) - (i32.load16_u - (get_local $6) - ) - ) - (i64.store align=4 - (tee_local $7 - (i32.add - (get_local $8) - (i32.const -12) - ) - ) - (i64.const 0) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $7) - (i32.load - (tee_local $5 - (i32.add - (get_local $6) - (i32.const 4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $6) - (i32.const 8) - ) - ) - ) - (i32.store - (get_local $1) - (i32.load - (tee_local $7 - (i32.add - (get_local $6) - (i32.const 12) - ) - ) - ) - ) - (i32.store - (get_local $7) - (i32.const 0) - ) - (i64.store align=4 - (get_local $5) - (i64.const 0) - ) - (set_local $8 - (i32.add - (get_local $8) - (i32.const -16) - ) - ) - (br_if $label$10 - (i32.ne - (i32.add - (tee_local $6 - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - (get_local $4) - ) - (i32.const -16) - ) - ) - ) - (set_local $6 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $1 - (i32.load - (get_local $0) - ) - ) - (br $label$8) - ) - (set_local $1 - (get_local $6) - ) - ) - (i32.store - (get_local $0) - (get_local $8) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $3) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $2) - ) - (block $label$11 - (br_if $label$11 - (i32.eq - (get_local $6) - (get_local $1) - ) - ) - (set_local $7 - (i32.sub - (i32.const 0) - (get_local $1) - ) - ) - (set_local $6 - (i32.add - (get_local $6) - (i32.const -12) - ) - ) - (loop $label$12 - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $8 - (i32.load - (get_local $6) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $6) - (i32.const 4) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$12 - (i32.ne - (i32.add - (tee_local $6 - (i32.add - (get_local $6) - (i32.const -16) - ) - ) - (get_local $7) - ) - (i32.const -12) - ) - ) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (get_local $1) - ) - ) - (call $_ZdlPv - (get_local $1) - ) - ) - ) - (func $_ZNSt3__16vectorIN5eosio6actionENS_9allocatorIS2_EEE8__appendEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (i32.div_s - (i32.sub - (tee_local $8 - (i32.load offset=8 - (get_local $0) - ) - ) - (tee_local $7 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (i32.const 40) - ) - (get_local $1) - ) - ) - (br_if $label$2 - (i32.ge_u - (tee_local $6 - (i32.add - (tee_local $5 - (i32.div_s - (i32.sub - (get_local $7) - (tee_local $4 - (i32.load - (get_local $0) - ) - ) - ) - (i32.const 40) - ) - ) - (get_local $1) - ) - ) - (i32.const 107374183) - ) - ) - (set_local $7 - (i32.const 107374182) - ) - (block $label$5 - (br_if $label$5 - (i32.gt_u - (tee_local $8 - (i32.div_s - (i32.sub - (get_local $8) - (get_local $4) - ) - (i32.const 40) - ) - ) - (i32.const 53687090) - ) - ) - (br_if $label$3 - (i32.eqz - (tee_local $7 - (select - (get_local $6) - (tee_local $7 - (i32.shl - (get_local $8) - (i32.const 1) - ) - ) - (i32.lt_u - (get_local $7) - (get_local $6) - ) - ) - ) - ) - ) - ) - (set_local $8 - (call $_Znwj - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (br $label$1) - ) - (set_local $8 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (loop $label$6 - (i64.store - (get_local $7) - (i64.const 0) - ) - (i64.store offset=16 align=4 - (get_local $7) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $7) - (i32.const 24) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $7) - (i32.const 32) - ) - (i64.const 0) - ) - (i32.store - (get_local $8) - (tee_local $7 - (i32.add - (i32.load - (get_local $8) - ) - (i32.const 40) - ) - ) - ) - (br_if $label$6 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - (br $label$0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (set_local $8 - (i32.const 0) - ) - (br $label$1) - ) - (call $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv - (get_local $0) - ) - (unreachable) - ) - (set_local $2 - (i32.add - (get_local $8) - (i32.mul - (get_local $7) - (i32.const 40) - ) - ) - ) - (set_local $7 - (tee_local $8 - (i32.add - (get_local $8) - (i32.mul - (get_local $5) - (i32.const 40) - ) - ) - ) - ) - (loop $label$7 - (i64.store - (get_local $7) - (i64.const 0) - ) - (i64.store offset=16 align=4 - (get_local $7) - (i64.const 0) - ) - (i64.store - (i32.add - (get_local $7) - (i32.const 8) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $7) - (i32.const 24) - ) - (i64.const 0) - ) - (i64.store align=4 - (i32.add - (get_local $7) - (i32.const 32) - ) - (i64.const 0) - ) - (set_local $7 - (i32.add - (get_local $7) - (i32.const 40) - ) - ) - (br_if $label$7 - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -1) - ) - ) - ) - ) - (block $label$8 - (block $label$9 - (br_if $label$9 - (i32.eq - (tee_local $1 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (tee_local $4 - (i32.load - (get_local $0) - ) - ) - ) - ) - (set_local $3 - (i32.sub - (i32.const 0) - (get_local $4) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const -20) - ) - ) - (loop $label$10 - (i64.store - (i32.add - (get_local $8) - (i32.const -32) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const -12) - ) - ) - ) - (i64.store - (i32.add - (get_local $8) - (i32.const -40) - ) - (i64.load - (i32.add - (get_local $1) - (i32.const -20) - ) - ) - ) - (i64.store align=4 - (tee_local $4 - (i32.add - (get_local $8) - (i32.const -24) - ) - ) - (i64.const 0) - ) - (i32.store - (tee_local $5 - (i32.add - (get_local $8) - (i32.const -16) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $4) - (i32.load - (tee_local $6 - (i32.add - (get_local $1) - (i32.const -4) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -20) - ) - (i32.load - (get_local $1) - ) - ) - (i32.store - (get_local $5) - (i32.load - (tee_local $4 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - ) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (i64.store align=4 - (tee_local $4 - (i32.add - (get_local $8) - (i32.const -12) - ) - ) - (i64.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (i32.store - (tee_local $5 - (i32.add - (get_local $8) - (i32.const -4) - ) - ) - (i32.const 0) - ) - (i32.store - (get_local $4) - (i32.load - (tee_local $6 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $8) - (i32.const -8) - ) - (i32.load - (i32.add - (get_local $1) - (i32.const 12) - ) - ) - ) - (i32.store - (get_local $5) - (i32.load - (tee_local $4 - (i32.add - (get_local $1) - (i32.const 16) - ) - ) - ) - ) - (i32.store - (get_local $4) - (i32.const 0) - ) - (i64.store align=4 - (get_local $6) - (i64.const 0) - ) - (set_local $8 - (i32.add - (get_local $8) - (i32.const -40) - ) - ) - (br_if $label$10 - (i32.ne - (i32.add - (tee_local $1 - (i32.add - (get_local $1) - (i32.const -40) - ) - ) - (get_local $3) - ) - (i32.const -20) - ) - ) - ) - (set_local $4 - (i32.load - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - ) - (set_local $5 - (i32.load - (get_local $0) - ) - ) - (br $label$8) - ) - (set_local $5 - (get_local $4) - ) - ) - (i32.store - (get_local $0) - (get_local $8) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 4) - ) - (get_local $7) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8) - ) - (get_local $2) - ) - (block $label$11 - (br_if $label$11 - (i32.eq - (get_local $4) - (get_local $5) - ) - ) - (set_local $1 - (i32.sub - (i32.const 0) - (get_local $5) - ) - ) - (set_local $7 - (i32.add - (get_local $4) - (i32.const -24) - ) - ) - (loop $label$12 - (block $label$13 - (br_if $label$13 - (i32.eqz - (tee_local $8 - (i32.load - (i32.add - (get_local $7) - (i32.const 12) - ) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 16) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (tee_local $8 - (i32.load - (get_local $7) - ) - ) - ) - ) - (i32.store - (i32.add - (get_local $7) - (i32.const 4) - ) - (get_local $8) - ) - (call $_ZdlPv - (get_local $8) - ) - ) - (br_if $label$12 - (i32.ne - (i32.add - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -40) - ) - ) - (get_local $1) - ) - (i32.const -24) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (get_local $5) - ) - ) - (call $_ZdlPv - (get_local $5) - ) - ) - ) - (func $_Znwj (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (block $label$0 - (br_if $label$0 - (tee_local $0 - (call $malloc - (tee_local $1 - (select - (get_local $0) - (i32.const 1) - (get_local $0) - ) - ) - ) - ) - ) - (loop $label$1 - (set_local $0 - (i32.const 0) - ) - (br_if $label$0 - (i32.eqz - (tee_local $2 - (i32.load offset=19008 - (i32.const 0) - ) - ) - ) - ) - (call_indirect (type $FUNCSIG$v) - (get_local $2) - ) - (br_if $label$1 - (i32.eqz - (tee_local $0 - (call $malloc - (get_local $1) - ) - ) - ) - ) - ) - ) - (get_local $0) - ) - (func $_Znaj (param $0 i32) (result i32) - (call $_Znwj - (get_local $0) - ) - ) - (func $_ZdlPv (param $0 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $0) - ) - ) - (call $free - (get_local $0) - ) - ) - ) - (func $_ZNKSt3__121__basic_string_commonILb1EE20__throw_length_errorEv (param $0 i32) - (call $abort) - (unreachable) - ) - (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEE7reserveEj (param $0 i32) (param $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (br_if $label$0 - (i32.ge_u - (get_local $1) - (i32.const -16) - ) - ) - (set_local $2 - (i32.const 10) - ) - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.and - (tee_local $5 - (i32.load8_u - (get_local $0) - ) - ) - (i32.const 1) - ) - ) - ) - (set_local $2 - (i32.add - (i32.and - (tee_local $5 - (i32.load - (get_local $0) - ) - ) - (i32.const -2) - ) - (i32.const -1) - ) - ) - ) - (block $label$2 - (block $label$3 - (br_if $label$3 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - (set_local $3 - (i32.shr_u - (i32.and - (get_local $5) - (i32.const 254) - ) - (i32.const 1) - ) - ) - (br $label$2) - ) - (set_local $3 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (set_local $4 - (i32.const 10) - ) - (block $label$4 - (br_if $label$4 - (i32.lt_u - (tee_local $1 - (select - (get_local $3) - (get_local $1) - (i32.gt_u - (get_local $3) - (get_local $1) - ) - ) - ) - (i32.const 11) - ) - ) - (set_local $4 - (i32.add - (i32.and - (i32.add - (get_local $1) - (i32.const 16) - ) - (i32.const -16) - ) - (i32.const -1) - ) - ) - ) - (block $label$5 - (br_if $label$5 - (i32.eq - (get_local $4) - (get_local $2) - ) - ) - (block $label$6 - (block $label$7 - (br_if $label$7 - (i32.ne - (get_local $4) - (i32.const 10) - ) - ) - (set_local $6 - (i32.const 1) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (set_local $7 - (i32.const 0) - ) - (br $label$6) - ) - (set_local $1 - (call $_Znwj - (i32.add - (get_local $4) - (i32.const 1) - ) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.gt_u - (get_local $4) - (get_local $2) - ) - ) - (br_if $label$5 - (i32.eqz - (get_local $1) - ) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.and - (tee_local $5 - (i32.load8_u - (get_local $0) - ) - ) - (i32.const 1) - ) - ) - (set_local $7 - (i32.const 1) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $6 - (i32.const 0) - ) - (br $label$6) - ) - (set_local $2 - (i32.load offset=8 - (get_local $0) - ) - ) - (set_local $6 - (i32.const 1) - ) - (set_local $7 - (i32.const 1) - ) - ) - (block $label$10 - (block $label$11 - (br_if $label$11 - (i32.and - (get_local $5) - (i32.const 1) - ) - ) - (set_local $5 - (i32.shr_u - (i32.and - (get_local $5) - (i32.const 254) - ) - (i32.const 1) - ) - ) - (br $label$10) - ) - (set_local $5 - (i32.load offset=4 - (get_local $0) - ) - ) - ) - (block $label$12 - (br_if $label$12 - (i32.eqz - (tee_local $5 - (i32.add - (get_local $5) - (i32.const 1) - ) - ) - ) - ) - (drop - (call $memcpy - (get_local $1) - (get_local $2) - (get_local $5) - ) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.eqz - (get_local $6) - ) - ) - (call $_ZdlPv - (get_local $2) - ) - ) - (block $label$14 - (br_if $label$14 - (i32.eqz - (get_local $7) - ) - ) - (i32.store offset=4 - (get_local $0) - (get_local $3) - ) - (i32.store offset=8 - (get_local $0) - (get_local $1) - ) - (i32.store - (get_local $0) - (i32.or - (i32.add - (get_local $4) - (i32.const 1) - ) - (i32.const 1) - ) - ) - (return) - ) - (i32.store8 - (get_local $0) - (i32.shl - (get_local $3) - (i32.const 1) - ) - ) - ) - (return) - ) - (call $abort) - (unreachable) - ) - (func $_ZNKSt3__120__vector_base_commonILb1EE20__throw_length_errorEv (param $0 i32) - (call $abort) - (unreachable) - ) - (func $_ZNKSt3__120__vector_base_commonILb1EE20__throw_out_of_rangeEv (param $0 i32) - (call $abort) - (unreachable) - ) - (func $_ZNSt3__112basic_stringIcNS_11char_traitsIcEENS_9allocatorIcEEEC2ERKS5_ (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (i64.store align=4 - (get_local $0) - (i64.const 0) - ) - (i32.store - (tee_local $3 - (i32.add - (get_local $0) - (i32.const 8) - ) - ) - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.and - (i32.load8_u - (get_local $1) - ) - (i32.const 1) - ) - ) - (i64.store align=4 - (get_local $0) - (i64.load align=4 - (get_local $1) - ) - ) - (i32.store - (get_local $3) - (i32.load - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - ) - (return - (get_local $0) - ) - ) - (block $label$1 - (br_if $label$1 - (i32.ge_u - (tee_local $3 - (i32.load offset=4 - (get_local $1) - ) - ) - (i32.const -16) - ) - ) - (set_local $2 - (i32.load offset=8 - (get_local $1) - ) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (get_local $3) - (i32.const 11) - ) - ) - (i32.store8 - (get_local $0) - (i32.shl - (get_local $3) - (i32.const 1) - ) - ) - (set_local $1 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (br_if $label$3 - (get_local $3) - ) - (br $label$2) - ) - (set_local $1 - (call $_Znwj - (tee_local $4 - (i32.and - (i32.add - (get_local $3) - (i32.const 16) - ) - (i32.const -16) - ) - ) - ) - ) - (i32.store - (get_local $0) - (i32.or - (get_local $4) - (i32.const 1) - ) - ) - (i32.store offset=8 - (get_local $0) - (get_local $1) - ) - (i32.store offset=4 - (get_local $0) - (get_local $3) - ) - ) - (drop - (call $memcpy - (get_local $1) - (get_local $2) - (get_local $3) - ) - ) - ) - (i32.store8 - (i32.add - (get_local $1) - (get_local $3) - ) - (i32.const 0) - ) - (return - (get_local $0) - ) - ) - (call $abort) - (unreachable) - ) - (func $fabs (param $0 f64) (result f64) - (f64.reinterpret/i64 - (i64.and - (i64.reinterpret/f64 - (get_local $0) - ) - (i64.const 9223372036854775807) - ) - ) - ) - (func $fabsf (param $0 f32) (result f32) - (f32.reinterpret/i32 - (i32.and - (i32.reinterpret/f32 - (get_local $0) - ) - (i32.const 2147483647) - ) - ) - ) - (func $memccpy (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32) (result i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (block $label$0 - (block $label$1 - (block $label$2 - (br_if $label$2 - (i32.eqz - (i32.and - (i32.xor - (get_local $1) - (get_local $0) - ) - (i32.const 3) - ) - ) - ) - (set_local $7 - (get_local $3) - ) - (br $label$1) - ) - (set_local $6 - (i32.ne - (tee_local $7 - (i32.and - (get_local $1) - (i32.const 3) - ) - ) - (i32.const 0) - ) - ) - (block $label$3 - (block $label$4 - (block $label$5 - (block $label$6 - (br_if $label$6 - (i32.eqz - (get_local $3) - ) - ) - (br_if $label$5 - (i32.eqz - (get_local $7) - ) - ) - (set_local $4 - (i32.and - (get_local $2) - (i32.const 255) - ) - ) - (loop $label$7 - (i32.store8 - (get_local $0) - (tee_local $7 - (i32.load8_u - (get_local $1) - ) - ) - ) - (br_if $label$0 - (i32.eq - (get_local $7) - (get_local $4) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $7 - (i32.add - (get_local $3) - (i32.const -1) - ) - ) - (set_local $6 - (i32.ne - (tee_local $5 - (i32.and - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (i32.const 3) - ) - ) - (i32.const 0) - ) - ) - (br_if $label$4 - (i32.eq - (get_local $3) - (i32.const 1) - ) - ) - (set_local $3 - (get_local $7) - ) - (br_if $label$7 - (get_local $5) - ) - (br $label$4) - ) - ) - (set_local $7 - (get_local $3) - ) - (br_if $label$0 - (get_local $6) - ) - (br $label$3) - ) - (set_local $7 - (get_local $3) - ) - ) - (br_if $label$0 - (get_local $6) - ) - ) - (br_if $label$1 - (i32.lt_u - (get_local $7) - (i32.const 4) - ) - ) - (set_local $6 - (i32.mul - (i32.and - (get_local $2) - (i32.const 255) - ) - (i32.const 16843009) - ) - ) - (loop $label$8 - (br_if $label$1 - (i32.and - (i32.and - (i32.xor - (tee_local $3 - (i32.xor - (tee_local $5 - (i32.load - (get_local $1) - ) - ) - (get_local $6) - ) - ) - (i32.const -1) - ) - (i32.add - (get_local $3) - (i32.const -16843009) - ) - ) - (i32.const -2139062144) - ) - ) - (i32.store - (get_local $0) - (get_local $5) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 4) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 4) - ) - ) - (br_if $label$8 - (i32.gt_u - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -4) - ) - ) - (i32.const 3) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (get_local $7) - ) - ) - (set_local $5 - (i32.and - (get_local $2) - (i32.const 255) - ) - ) - (loop $label$9 - (i32.store8 - (get_local $0) - (tee_local $3 - (i32.load8_u - (get_local $1) - ) - ) - ) - (br_if $label$0 - (i32.eq - (get_local $3) - (get_local $5) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (br_if $label$9 - (tee_local $7 - (i32.add - (get_local $7) - (i32.const -1) - ) - ) - ) - ) - ) - (select - (i32.add - (get_local $0) - (i32.const 1) - ) - (i32.const 0) - (i32.eq - (i32.load8_u - (get_local $1) - ) - (i32.and - (get_local $2) - (i32.const 255) - ) - ) - ) - ) - (func $memcmp (param $0 i32) (param $1 i32) (param $2 i32) (result i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (set_local $5 - (i32.const 0) - ) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $2) - ) - ) - (block $label$1 - (loop $label$2 - (br_if $label$1 - (i32.ne - (tee_local $3 - (i32.load8_u - (get_local $0) - ) - ) - (tee_local $4 - (i32.load8_u - (get_local $1) - ) - ) - ) - ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 1) - ) - ) - (set_local $0 - (i32.add - (get_local $0) - (i32.const 1) - ) - ) - (br_if $label$2 - (tee_local $2 - (i32.add - (get_local $2) - (i32.const -1) - ) - ) - ) - (br $label$0) - ) - ) - (set_local $5 - (i32.sub - (get_local $3) - (get_local $4) - ) - ) - ) - (get_local $5) - ) - (func $strlen (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (set_local $2 - (get_local $0) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.and - (get_local $0) - (i32.const 3) - ) - ) - ) - (set_local $2 - (get_local $0) - ) - (loop $label$2 - (br_if $label$0 - (i32.eqz - (i32.load8_u - (get_local $2) - ) - ) - ) - (br_if $label$2 - (i32.and - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - (i32.const 3) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const -4) - ) - ) - (loop $label$3 - (br_if $label$3 - (i32.eqz - (i32.and - (i32.and - (i32.xor - (tee_local $1 - (i32.load - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - ) - ) - (i32.const -1) - ) - (i32.add - (get_local $1) - (i32.const -16843009) - ) - ) - (i32.const -2139062144) - ) - ) - ) - ) - (br_if $label$0 - (i32.eqz - (i32.and - (get_local $1) - (i32.const 255) - ) - ) - ) - (loop $label$4 - (br_if $label$4 - (i32.load8_u - (tee_local $2 - (i32.add - (get_local $2) - (i32.const 1) - ) - ) - ) - ) - ) - ) - (i32.sub - (get_local $2) - (get_local $0) - ) - ) - (func $malloc (param $0 i32) (result i32) - (call $_ZN5eosio14memory_manager6mallocEm - (i32.const 19012) - (get_local $0) - ) - ) - (func $_ZN5eosio14memory_manager6mallocEm (param $0 i32) (param $1 i32) (result i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (local $9 i32) - (local $10 i32) - (local $11 i32) - (local $12 i32) - (local $13 i32) - (block $label$0 - (br_if $label$0 - (i32.eqz - (get_local $1) - ) - ) - (block $label$1 - (br_if $label$1 - (tee_local $13 - (i32.load offset=8384 - (get_local $0) - ) - ) - ) - (set_local $13 - (i32.const 16) - ) - (i32.store - (i32.add - (get_local $0) - (i32.const 8384) - ) - (i32.const 16) - ) - ) - (set_local $2 - (select - (i32.sub - (i32.add - (get_local $1) - (i32.const 8) - ) - (tee_local $2 - (i32.and - (i32.add - (get_local $1) - (i32.const 4) - ) - (i32.const 7) - ) - ) - ) - (get_local $1) - (get_local $2) - ) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (br_if $label$4 - (i32.ge_u - (tee_local $10 - (i32.load offset=8388 - (get_local $0) - ) - ) - (get_local $13) - ) - ) - (set_local $1 - (i32.add - (i32.add - (get_local $0) - (i32.mul - (get_local $10) - (i32.const 12) - ) - ) - (i32.const 8192) - ) - ) - (block $label$5 - (br_if $label$5 - (get_local $10) - ) - (br_if $label$5 - (i32.load - (tee_local $13 - (i32.add - (get_local $0) - (i32.const 8196) - ) - ) - ) - ) - (i32.store - (get_local $1) - (i32.const 8192) - ) - (i32.store - (get_local $13) - (get_local $0) - ) - ) - (set_local $10 - (i32.add - (get_local $2) - (i32.const 4) - ) - ) - (loop $label$6 - (block $label$7 - (br_if $label$7 - (i32.gt_u - (i32.add - (tee_local $13 - (i32.load offset=8 - (get_local $1) - ) - ) - (get_local $10) - ) - (i32.load - (get_local $1) - ) - ) - ) - (i32.store - (tee_local $13 - (i32.add - (i32.load offset=4 - (get_local $1) - ) - (get_local $13) - ) - ) - (i32.or - (i32.and - (i32.load - (get_local $13) - ) - (i32.const -2147483648) - ) - (get_local $2) - ) - ) - (i32.store - (tee_local $1 - (i32.add - (get_local $1) - (i32.const 8) - ) - ) - (i32.add - (i32.load - (get_local $1) - ) - (get_local $10) - ) - ) - (i32.store - (get_local $13) - (i32.or - (i32.load - (get_local $13) - ) - (i32.const -2147483648) - ) - ) - (br_if $label$3 - (tee_local $1 - (i32.add - (get_local $13) - (i32.const 4) - ) - ) - ) - ) - (br_if $label$6 - (tee_local $1 - (call $_ZN5eosio14memory_manager16next_active_heapEv - (get_local $0) - ) - ) - ) - ) - ) - (set_local $4 - (i32.sub - (i32.const 2147483644) - (get_local $2) - ) - ) - (set_local $11 - (i32.add - (get_local $0) - (i32.const 8392) - ) - ) - (set_local $12 - (i32.add - (get_local $0) - (i32.const 8384) - ) - ) - (set_local $13 - (tee_local $3 - (i32.load offset=8392 - (get_local $0) - ) - ) - ) - (loop $label$8 - (call $eosio_assert - (i32.eq - (i32.load - (i32.add - (tee_local $1 - (i32.add - (get_local $0) - (i32.mul - (get_local $13) - (i32.const 12) - ) - ) - ) - (i32.const 8200) - ) - ) - (i32.load - (tee_local $5 - (i32.add - (get_local $1) - (i32.const 8192) - ) - ) - ) - ) - (i32.const 27408) - ) - (set_local $13 - (i32.add - (tee_local $6 - (i32.load - (i32.add - (get_local $1) - (i32.const 8196) - ) - ) - ) - (i32.const 4) - ) - ) - (loop $label$9 - (set_local $7 - (i32.add - (get_local $6) - (i32.load - (get_local $5) - ) - ) - ) - (set_local $1 - (i32.and - (tee_local $9 - (i32.load - (tee_local $8 - (i32.add - (get_local $13) - (i32.const -4) - ) - ) - ) - ) - (i32.const 2147483647) - ) - ) - (block $label$10 - (br_if $label$10 - (i32.lt_s - (get_local $9) - (i32.const 0) - ) - ) - (block $label$11 - (br_if $label$11 - (i32.ge_u - (get_local $1) - (get_local $2) - ) - ) - (loop $label$12 - (br_if $label$11 - (i32.ge_u - (tee_local $10 - (i32.add - (get_local $13) - (get_local $1) - ) - ) - (get_local $7) - ) - ) - (br_if $label$11 - (i32.lt_s - (tee_local $10 - (i32.load - (get_local $10) - ) - ) - (i32.const 0) - ) - ) - (br_if $label$12 - (i32.lt_u - (tee_local $1 - (i32.add - (i32.add - (get_local $1) - (i32.and - (get_local $10) - (i32.const 2147483647) - ) - ) - (i32.const 4) - ) - ) - (get_local $2) - ) - ) - ) - ) - (i32.store - (get_local $8) - (i32.or - (select - (get_local $1) - (get_local $2) - (i32.lt_u - (get_local $1) - (get_local $2) - ) - ) - (i32.and - (get_local $9) - (i32.const -2147483648) - ) - ) - ) - (block $label$13 - (br_if $label$13 - (i32.le_u - (get_local $1) - (get_local $2) - ) - ) - (i32.store - (i32.add - (get_local $13) - (get_local $2) - ) - (i32.and - (i32.add - (get_local $4) - (get_local $1) - ) - (i32.const 2147483647) - ) - ) - ) - (br_if $label$2 - (i32.ge_u - (get_local $1) - (get_local $2) - ) - ) - ) - (br_if $label$9 - (i32.lt_u - (tee_local $13 - (i32.add - (i32.add - (get_local $13) - (get_local $1) - ) - (i32.const 4) - ) - ) - (get_local $7) - ) - ) - ) - (set_local $1 - (i32.const 0) - ) - (i32.store - (get_local $11) - (tee_local $13 - (select - (i32.const 0) - (tee_local $13 - (i32.add - (i32.load - (get_local $11) - ) - (i32.const 1) - ) - ) - (i32.eq - (get_local $13) - (i32.load - (get_local $12) - ) - ) - ) - ) - ) - (br_if $label$8 - (i32.ne - (get_local $13) - (get_local $3) - ) - ) - ) - ) - (return - (get_local $1) - ) - ) - (i32.store - (get_local $8) - (i32.or - (i32.load - (get_local $8) - ) - (i32.const -2147483648) - ) - ) - (return - (get_local $13) - ) - ) - (i32.const 0) - ) - (func $_ZN5eosio14memory_manager16next_active_heapEv (param $0 i32) (result i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (local $4 i32) - (local $5 i32) - (local $6 i32) - (local $7 i32) - (local $8 i32) - (set_local $1 - (i32.load offset=8388 - (get_local $0) - ) - ) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (i32.load8_u offset=27494 - (i32.const 0) - ) - ) - ) - (set_local $7 - (i32.load offset=27496 - (i32.const 0) - ) - ) - (br $label$0) - ) - (set_local $7 - (current_memory) - ) - (i32.store8 offset=27494 - (i32.const 0) - (i32.const 1) - ) - (i32.store offset=27496 - (i32.const 0) - (tee_local $7 - (i32.shl - (get_local $7) - (i32.const 16) - ) - ) - ) - ) - (set_local $3 - (get_local $7) - ) - (block $label$2 - (block $label$3 - (block $label$4 - (block $label$5 - (br_if $label$5 - (i32.le_u - (tee_local $2 - (i32.shr_u - (i32.add - (get_local $7) - (i32.const 65535) - ) - (i32.const 16) - ) - ) - (tee_local $8 - (current_memory) - ) - ) - ) - (drop - (grow_memory - (i32.sub - (get_local $2) - (get_local $8) - ) - ) - ) - (set_local $8 - (i32.const 0) - ) - (br_if $label$4 - (i32.ne - (get_local $2) - (current_memory) - ) - ) - (set_local $3 - (i32.load offset=27496 - (i32.const 0) - ) - ) - ) - (set_local $8 - (i32.const 0) - ) - (i32.store offset=27496 - (i32.const 0) - (get_local $3) - ) - (br_if $label$4 - (i32.lt_s - (get_local $7) - (i32.const 0) - ) - ) - (set_local $2 - (i32.add - (get_local $0) - (i32.mul - (get_local $1) - (i32.const 12) - ) - ) - ) - (set_local $7 - (i32.sub - (i32.sub - (i32.add - (get_local $7) - (select - (i32.const 65536) - (i32.const 131072) - (tee_local $6 - (i32.lt_u - (tee_local $8 - (i32.and - (get_local $7) - (i32.const 65535) - ) - ) - (i32.const 64513) - ) - ) - ) - ) - (select - (get_local $8) - (i32.and - (get_local $7) - (i32.const 131071) - ) - (get_local $6) - ) - ) - (get_local $7) - ) - ) - (block $label$6 - (br_if $label$6 - (i32.load8_u offset=27494 - (i32.const 0) - ) - ) - (set_local $3 - (current_memory) - ) - (i32.store8 offset=27494 - (i32.const 0) - (i32.const 1) - ) - (i32.store offset=27496 - (i32.const 0) - (tee_local $3 - (i32.shl - (get_local $3) - (i32.const 16) - ) - ) - ) - ) - (set_local $2 - (i32.add - (get_local $2) - (i32.const 8192) - ) - ) - (br_if $label$3 - (i32.lt_s - (get_local $7) - (i32.const 0) - ) - ) - (set_local $6 - (get_local $3) - ) - (block $label$7 - (br_if $label$7 - (i32.le_u - (tee_local $8 - (i32.shr_u - (i32.add - (i32.add - (tee_local $5 - (i32.and - (i32.add - (get_local $7) - (i32.const 7) - ) - (i32.const -8) - ) - ) - (get_local $3) - ) - (i32.const 65535) - ) - (i32.const 16) - ) - ) - (tee_local $4 - (current_memory) - ) - ) - ) - (drop - (grow_memory - (i32.sub - (get_local $8) - (get_local $4) - ) - ) - ) - (br_if $label$3 - (i32.ne - (get_local $8) - (current_memory) - ) - ) - (set_local $6 - (i32.load offset=27496 - (i32.const 0) - ) - ) - ) - (i32.store offset=27496 - (i32.const 0) - (i32.add - (get_local $6) - (get_local $5) - ) - ) - (br_if $label$3 - (i32.eq - (get_local $3) - (i32.const -1) - ) - ) - (br_if $label$2 - (i32.eq - (i32.add - (tee_local $6 - (i32.load - (i32.add - (tee_local $1 - (i32.add - (get_local $0) - (i32.mul - (get_local $1) - (i32.const 12) - ) - ) - ) - (i32.const 8196) - ) - ) - ) - (tee_local $8 - (i32.load - (get_local $2) - ) - ) - ) - (get_local $3) - ) - ) - (block $label$8 - (br_if $label$8 - (i32.eq - (get_local $8) - (tee_local $1 - (i32.load - (tee_local $5 - (i32.add - (get_local $1) - (i32.const 8200) - ) - ) - ) - ) - ) - ) - (i32.store - (tee_local $6 - (i32.add - (get_local $6) - (get_local $1) - ) - ) - (i32.or - (i32.and - (i32.load - (get_local $6) - ) - (i32.const -2147483648) - ) - (i32.add - (i32.sub - (i32.const -4) - (get_local $1) - ) - (get_local $8) - ) - ) - ) - (i32.store - (get_local $5) - (i32.load - (get_local $2) - ) - ) - (i32.store - (get_local $6) - (i32.and - (i32.load - (get_local $6) - ) - (i32.const 2147483647) - ) - ) - ) - (i32.store - (tee_local $2 - (i32.add - (get_local $0) - (i32.const 8388) - ) - ) - (tee_local $2 - (i32.add - (i32.load - (get_local $2) - ) - (i32.const 1) - ) - ) - ) - (i32.store - (i32.add - (tee_local $0 - (i32.add - (get_local $0) - (i32.mul - (get_local $2) - (i32.const 12) - ) - ) - ) - (i32.const 8196) - ) - (get_local $3) - ) - (i32.store - (tee_local $8 - (i32.add - (get_local $0) - (i32.const 8192) - ) - ) - (get_local $7) - ) - ) - (return - (get_local $8) - ) - ) - (block $label$9 - (br_if $label$9 - (i32.eq - (tee_local $8 - (i32.load - (get_local $2) - ) - ) - (tee_local $7 - (i32.load - (tee_local $1 - (i32.add - (tee_local $3 - (i32.add - (get_local $0) - (i32.mul - (get_local $1) - (i32.const 12) - ) - ) - ) - (i32.const 8200) - ) - ) - ) - ) - ) - ) - (i32.store - (tee_local $3 - (i32.add - (i32.load - (i32.add - (get_local $3) - (i32.const 8196) - ) - ) - (get_local $7) - ) - ) - (i32.or - (i32.and - (i32.load - (get_local $3) - ) - (i32.const -2147483648) - ) - (i32.add - (i32.sub - (i32.const -4) - (get_local $7) - ) - (get_local $8) - ) - ) - ) - (i32.store - (get_local $1) - (i32.load - (get_local $2) - ) - ) - (i32.store - (get_local $3) - (i32.and - (i32.load - (get_local $3) - ) - (i32.const 2147483647) - ) - ) - ) - (i32.store offset=8384 - (get_local $0) - (tee_local $3 - (i32.add - (i32.load - (tee_local $7 - (i32.add - (get_local $0) - (i32.const 8388) - ) - ) - ) - (i32.const 1) - ) - ) - ) - (i32.store - (get_local $7) - (get_local $3) - ) - (return - (i32.const 0) - ) - ) - (i32.store - (get_local $2) - (i32.add - (get_local $8) - (get_local $7) - ) - ) - (get_local $2) - ) - (func $free (param $0 i32) - (local $1 i32) - (local $2 i32) - (local $3 i32) - (block $label$0 - (block $label$1 - (br_if $label$1 - (i32.eqz - (get_local $0) - ) - ) - (br_if $label$1 - (i32.lt_s - (tee_local $2 - (i32.load offset=27396 - (i32.const 0) - ) - ) - (i32.const 1) - ) - ) - (set_local $3 - (i32.const 27204) - ) - (set_local $1 - (i32.add - (i32.mul - (get_local $2) - (i32.const 12) - ) - (i32.const 27204) - ) - ) - (loop $label$2 - (br_if $label$1 - (i32.eqz - (tee_local $2 - (i32.load - (i32.add - (get_local $3) - (i32.const 4) - ) - ) - ) - ) - ) - (block $label$3 - (br_if $label$3 - (i32.gt_u - (i32.add - (get_local $2) - (i32.const 4) - ) - (get_local $0) - ) - ) - (br_if $label$0 - (i32.gt_u - (i32.add - (get_local $2) - (i32.load - (get_local $3) - ) - ) - (get_local $0) - ) - ) - ) - (br_if $label$2 - (i32.lt_u - (tee_local $3 - (i32.add - (get_local $3) - (i32.const 12) - ) - ) - (get_local $1) - ) - ) - ) - ) - (return) - ) - (i32.store - (tee_local $3 - (i32.add - (get_local $0) - (i32.const -4) - ) - ) - (i32.and - (i32.load - (get_local $3) - ) - (i32.const 2147483647) - ) - ) - ) -) From 8bd7f5ef59a4f8627730814617d149fe33615526 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 16 Apr 2019 22:54:13 -0400 Subject: [PATCH 0774/1048] rename preactivate action to activate in both bios and system contracts --- contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp | 2 +- contracts/eosio.bios/src/eosio.bios.cpp | 2 +- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 2 +- contracts/eosio.system/src/eosio.system.cpp | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 44ad2508..b899e591 100755 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -170,7 +170,7 @@ namespace eosio { } [[eosio::action]] - void preactivate( const eosio::checksum256& feature_digest ) { + void activate( const eosio::checksum256& feature_digest ) { require_auth( get_self() ); preactivate_feature( feature_digest ); } diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index abbb6f72..fc8d2ff8 100755 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,3 @@ #include -EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi)(preactivate)(reqactivated) ) +EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi)(activate)(reqactivated) ) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 6f66aa5a..5c1ce5ba 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -361,7 +361,7 @@ namespace eosiosystem { void setacctcpu( name account, std::optional cpu_weight ); [[eosio::action]] - void preactivate( const eosio::checksum256& feature_digest ); + void activate( const eosio::checksum256& feature_digest ); // functions defined in delegate_bandwidth.cpp diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index aa17181f..6cf4fb35 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -277,7 +277,7 @@ namespace eosiosystem { set_resource_limits( account.value, current_ram, current_net, cpu ); } - void system_contract::preactivate( const eosio::checksum256& feature_digest ) { + void system_contract::activate( const eosio::checksum256& feature_digest ) { require_auth( get_self() ); preactivate_feature( feature_digest ); } @@ -468,7 +468,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, // native.hpp (newaccount definition is actually in eosio.system.cpp) (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp - (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu)(preactivate) + (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu)(activate) (rmvproducer)(updtrevision)(bidname)(bidrefund) // rex.cpp (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) From dd385a25a451cda00a77b235c58cff098f52c9ad Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 16 Apr 2019 23:43:52 -0400 Subject: [PATCH 0775/1048] use specific commit for EOSIO dependency --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index d0604ef9..0466b7aa 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=forced-replay +eosio=3aa16e6b572c1fd3169ca435bf0c98072168a0b2 cdt=release/1.6.x From 50e2e529556df4d97ccb2bcd52e1c3619fc1826b Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 17 Apr 2019 10:34:44 -0400 Subject: [PATCH 0776/1048] fix doxygen comments --- .../include/eosio.bios/eosio.bios.hpp | 148 ++++++++++-------- .../include/eosio.system/eosio.system.hpp | 10 +- 2 files changed, 90 insertions(+), 68 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 47a3b2d8..3bdb9148 100755 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -34,21 +34,21 @@ namespace eosio { } } -/** +/** * EOSIO Contracts - * - * @details The design of the EOSIO blockchain calls for a number of smart contracts that are run at a - * privileged permission level in order to support functions such as block producer registration and - * voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart + * + * @details The design of the EOSIO blockchain calls for a number of smart contracts that are run at a + * privileged permission level in order to support functions such as block producer registration and + * voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart * contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. - * - * This repository contains examples of these privileged contracts that are useful when deploying, + * + * This repository contains examples of these privileged contracts that are useful when deploying, * managing, and/or using an EOSIO blockchain. They are provided for reference purposes: * - eosio.bios * - eosio.system * - eosio.msig * - eosio.wrap - * + * * The following unprivileged contract(s) are also part of the system. * - eosio.token */ @@ -60,10 +60,10 @@ namespace eosio { using eosio::ignore; /** - * A weighted permission. - * - * @details Defines a weighted permission, that is a permission which has a weight associated. - * A permission is defined by an account name plus a permission name. The weight is going to be + * A weighted permission. + * + * @details Defines a weighted permission, that is a permission which has a weight associated. + * A permission is defined by an account name plus a permission name. The weight is going to be * used against a threshold, if the weight is equal or greater than the threshold set then authorization * will pass. */ @@ -77,7 +77,7 @@ namespace eosio { /** * Weighted key. - * + * * @details A weighted key is defined by a public key and an associated weight. */ struct key_weight { @@ -90,7 +90,7 @@ namespace eosio { /** * Wait weight. - * + * * @details A wait weight is defined by a number of seconds to wait for and a weight. */ struct wait_weight { @@ -103,7 +103,7 @@ namespace eosio { /** * Blockchain authority. - * + * * @details An authority is defined by: * - a vector of key_weights (a key_weight is a public key plus a weight), * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) @@ -122,7 +122,7 @@ namespace eosio { /** * Blockchain block header. - * + * * @details A block header is defined by: * - a timestamp, * - the producer that created it, @@ -151,10 +151,10 @@ namespace eosio { /** * @defgroup eosiobios eosio.bios * @ingroup eosiocontracts - * - * eosio.bios is a minimalistic system contract that only supplies the actions that are absolutely + * + * eosio.bios is a minimalistic system contract that only supplies the actions that are absolutely * critical to bootstrap a chain and nothing more. - * + * * @{ */ class [[eosio::contract("eosio.bios")]] bios : public contract { @@ -162,15 +162,15 @@ namespace eosio { using contract::contract; /** * @{ - * These actions map one-on-one with the ones defined in + * These actions map one-on-one with the ones defined in * [Native Action Handlers](@ref native_action_handlers) section. * They are present here so they can show up in the abi file and thus user can send them - * to this contract, but they have no specific implementation at this contract level, + * to this contract, but they have no specific implementation at this contract level, * they will execute the implementation at the core level and nothing else. */ /** - * New account action - * + * New account action + * * @details Called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. * @@ -189,9 +189,9 @@ namespace eosio { ignore active){} /** * Update authorization action. - * + * * @details Updates pemission for an account. - * + * * @param account - the account for which the permission is updated, * @param pemission - the permission name which is updated, * @param parem - the parent of the permission which is updated, @@ -205,9 +205,9 @@ namespace eosio { /** * Delete authorization action. - * + * * @details Deletes the authorization for an account's permision. - * + * * @param account - the account for which the permission authorization is deleted, * @param permission - the permission name been deleted. */ @@ -217,16 +217,16 @@ namespace eosio { /** * Link authorization action. - * - * @details Assigns a specific action from a contract to a permission you have created. Five system + * + * @details Assigns a specific action from a contract to a permission you have created. Five system * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. - * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the - * action needed to be authorized (and the contract belonging to), and looks up which permission - * is needed to pass authorization validation. If a link is set, that permission is used for authoraization + * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the + * action needed to be authorized (and the contract belonging to), and looks up which permission + * is needed to pass authorization validation. If a link is set, that permission is used for authoraization * validation otherwise then active is the default, with the exception of `eosio.any`. * `eosio.any` is an implicit permission which exists on every account; you can link actions to `eosio.any` - * and that will make it so linked actions are accessible to any permissions defined for the account. - * + * and that will make it so linked actions are accessible to any permissions defined for the account. + * * @param account - the permission's owner to be linked and the payer of the RAM needed to store this link, * @param code - the owner of the action to be linked, * @param type - the action to be linked, @@ -240,9 +240,9 @@ namespace eosio { /** * Unlink authorization action. - * + * * @details It's doing the reverse of linkauth action, by unlinking the given action. - * + * * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, * @param code - the owner of the action to be unlinked, * @param type - the action to be unlinked. @@ -254,9 +254,9 @@ namespace eosio { /** * Cancel delay action. - * + * * @details Cancels a deferred transaction. - * + * * @param canceling_auth - the permission that authorizes this action, * @param trx_id - the deferred transaction id to be cancelled. */ @@ -265,9 +265,9 @@ namespace eosio { /** * On error action. - * + * * @details Called every time an error occurs while a transaction was processed. - * + * * @param sender_id - the id of the sender, * @param sent_trx - the transaction that failed. */ @@ -276,9 +276,9 @@ namespace eosio { /** * Set code action. - * + * * @details Sets the contract code for an account. - * + * * @param account - the account for which to set the contract code. * @param vmtype - reserved, set it to zero. * @param vmversion - reserved, set it to zero. @@ -286,12 +286,12 @@ namespace eosio { */ [[eosio::action]] void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} - + /** @}*/ /** * Set privilege status for an account. - * + * * @details Allows to set privilege status for an account (turn it on/off). * @param account - the account to set the privileged status for. * @param is_priv - 0 for false, > 0 for true. @@ -304,9 +304,9 @@ namespace eosio { /** * Set the resource limits of an account - * + * * @details Set the resource limits of an account - * + * * @param account - name of the account whose resource limit to be set * @param ram_bytes - ram limit in absolute bytes * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts) @@ -320,10 +320,10 @@ namespace eosio { /** * Set global resource limits. - * + * * @details Not implemented yet. * Set global resource limits - * + * * @param ram - ram limit * @param net - net limit * @param cpu - cpu limit @@ -336,12 +336,12 @@ namespace eosio { /** * Set a new list of active producers, that is, a new producers' schedule. - * - * @details Set a new list of active producers, by proposing a schedule change, once the block that - * contains the proposal becomes irreversible, the schedule is promoted to "pending" - * automatically. Once the block that promotes the schedule is irreversible, the schedule will + * + * @details Set a new list of active producers, by proposing a schedule change, once the block that + * contains the proposal becomes irreversible, the schedule is promoted to "pending" + * automatically. Once the block that promotes the schedule is irreversible, the schedule will * become "active". - * + * * @param schedule - New list of active producers to set */ [[eosio::action]] @@ -358,9 +358,9 @@ namespace eosio { /** * Set the blockchain parameters - * + * * @details Set the blockchain parameters. By tuning these parameters, various degrees of customization can be achieved. - * + * * @param params - New blockchain parameters to set */ [[eosio::action]] @@ -371,10 +371,10 @@ namespace eosio { /** * Check if an account has authorization to access current action. - * - * @details Checks if the account name `from` passed in as param has authorization to access + * + * @details Checks if the account name `from` passed in as param has authorization to access * current action, that is, if it is listed in the action’s allowed permissions vector. - * + * * @param from - the account name to authorize */ [[eosio::action]] @@ -383,14 +383,11 @@ namespace eosio { } /** - * Set abi for contract. - * - * @details Set the abi for contract identified by `account` name. Creates an entry in the abi_hash_table - * index, with `account` name as key, if it is not already present and sets its value with the abi hash. - * Otherwise it is updating the current abi hash value for the existing `account` key. - * - * @param account - the name of the account to set the abi for - * @param abi - the abi hash represented as a vector of characters + * Activates a protocol feature. + * + * @details Activates a protocol feature + * + * @param feature_digest - hash of the protocol feature to activate. */ [[eosio::action]] void activate( const eosio::checksum256& feature_digest ) { @@ -398,11 +395,28 @@ namespace eosio { preactivate_feature( feature_digest ); } + /** + * Asserts that a protocol feature has been activated. + * + * @details Asserts that a protocol feature has been activated + * + * @param feature_digest - hash of the protocol feature to check for activation. + */ [[eosio::action]] void reqactivated( const eosio::checksum256& feature_digest ) { check( is_feature_activated( feature_digest ), "protocol feature is not activated" ); } + /** + * Set abi for contract. + * + * @details Set the abi for contract identified by `account` name. Creates an entry in the abi_hash_table + * index, with `account` name as key, if it is not already present and sets its value with the abi hash. + * Otherwise it is updating the current abi hash value for the existing `account` key. + * + * @param account - the name of the account to set the abi for + * @param abi - the abi hash represented as a vector of characters + */ [[eosio::action]] void setabi( name account, const std::vector& abi ) { abi_hash_table table(_self, _self.value); @@ -421,7 +435,7 @@ namespace eosio { /** * Abi hash structure - * + * * @details Abi hash structure is defined by contract owner and the contract hash. */ struct [[eosio::table]] abi_hash { diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 018527ff..97760999 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -597,6 +597,14 @@ namespace eosiosystem { [[eosio::action]] void setacctcpu( name account, std::optional cpu_weight ); + + /** + * Activates a protocol feature. + * + * @details Activates a protocol feature + * + * @param feature_digest - hash of the protocol feature to activate. + */ [[eosio::action]] void activate( const eosio::checksum256& feature_digest ); @@ -882,7 +890,7 @@ namespace eosiosystem { /** * Closerex action. - * + * * @details Deletes owner records from REX tables and frees used RAM. Owner must not have * an outstanding REX balance. * From cbe6226ca628796620a823b3f4dd31b88ac8af62 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 17 Apr 2019 10:55:40 -0400 Subject: [PATCH 0777/1048] update dependencies on eosio and cdt --- CMakeLists.txt | 4 ++-- dependencies | 2 +- tests/CMakeLists.txt | 6 +++--- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 755cc11b..11c28dab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,8 @@ find_package(eosio.cdt) message(STATUS "Building eosio.contracts v${VERSION_FULL}") -set(EOSIO_CDT_VERSION_MIN "1.5") -set(EOSIO_CDT_VERSION_SOFT_MAX "1.5") +set(EOSIO_CDT_VERSION_MIN "1.6") +set(EOSIO_CDT_VERSION_SOFT_MAX "1.6") #set(EOSIO_CDT_VERSION_HARD_MAX "") ### Check the version of eosio.cdt diff --git a/dependencies b/dependencies index 0466b7aa..af5be3fc 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=3aa16e6b572c1fd3169ca435bf0c98072168a0b2 +eosio=37df54eb8ccc9f020338f8a48ffcf61a376d2431 cdt=release/1.6.x diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9be6df06..b61e088a 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 3.5 ) -set(EOSIO_VERSION_MIN "1.6") -set(EOSIO_VERSION_SOFT_MAX "1.7") +set(EOSIO_VERSION_MIN "1.8") +set(EOSIO_VERSION_SOFT_MAX "1.8") #set(EOSIO_VERSION_HARD_MAX "") find_package(eosio) @@ -38,4 +38,4 @@ foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test s # to run unit_test with all log from blockchain displayed, put "--verbose" after "--", i.e. "unit_test -- --verbose" add_test(NAME ${TRIMMED_SUITE_NAME}_unit_test COMMAND unit_test --run_test=${SUITE_NAME} --report_level=detailed --color_output) endif() -endforeach(TEST_SUITE) \ No newline at end of file +endforeach(TEST_SUITE) From a6d70a31e075ee03a0cdc5b576106ad21b055149 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 18 Apr 2019 11:48:45 -0400 Subject: [PATCH 0778/1048] Change token::issue: tokens can only be issued to issuer account --- contracts/eosio.token/src/eosio.token.cpp | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index cd1e8bb4..3ecebe22 100755 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -39,6 +39,7 @@ void token::issue( name to, asset quantity, string memo ) auto existing = statstable.find( sym.code().raw() ); check( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); const auto& st = *existing; + check( to == st.issuer, "tokens can only be issued to issuer account" ); require_auth( st.issuer ); check( quantity.is_valid(), "invalid quantity" ); @@ -52,12 +53,6 @@ void token::issue( name to, asset quantity, string memo ) }); add_balance( st.issuer, quantity, st.issuer ); - - if( to != st.issuer ) { - SEND_INLINE_ACTION( *this, transfer, { {st.issuer, "active"_n} }, - { st.issuer, to, quantity, memo } - ); - } } void token::retire( asset quantity, string memo ) From 641ed02c1efd5dc487dfe7bcf34de07e76ebbb58 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 18 Apr 2019 16:40:27 -0400 Subject: [PATCH 0779/1048] Fix system contract unit tests --- tests/eosio.system_tester.hpp | 19 +++++++- tests/eosio.system_tests.cpp | 88 +++++++++++++++++------------------ 2 files changed, 60 insertions(+), 47 deletions(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 0af1b9e0..68f09a12 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -762,14 +762,15 @@ class eosio_system_tester : public TESTER { base_tester::push_action(contract, N(create), contract, act ); } - void issue( name to, const asset& amount, name manager = config::system_account_name ) { + void issue( const name& to, const asset& amount, const name& manager = config::system_account_name ) { base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() ("to", to ) ("quantity", amount ) ("memo", "") ); } - void transfer( name from, name to, const asset& amount, name manager = config::system_account_name ) { + + void transfer( const name& from, const name& to, const asset& amount, const name& manager = config::system_account_name ) { base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() ("from", from) ("to", to ) @@ -778,6 +779,20 @@ class eosio_system_tester : public TESTER { ); } + void issue_and_transfer( const name& to, const asset& amount, const name& manager = config::system_account_name ) { + base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() + ("to", manager ) + ("quantity", amount ) + ("memo", "") + ); + base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() + ("from", manager) + ("to", to ) + ("quantity", amount) + ("memo", "") + ); + } + double stake2votes( asset stake ) { auto now = control->pending_block_time().time_since_epoch().count() / 1000000; return stake.get_amount() * pow(2, int64_t((now - (config::block_timestamp_epoch / 1000)) / (86400 * 7))/ double(52) ); // 52 week periods (i.e. ~years) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index cd8e0f63..4b0fa781 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -189,8 +189,7 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "eosio", core_sym::from_string("1000.0000"), config::system_account_name ); - issue( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //eosio stakes for alice with transfer flag @@ -256,8 +255,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "eosio", core_sym::from_string("1000.0000"), config::system_account_name ); - issue( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //eosio stakes for alice with transfer flag @@ -311,7 +309,7 @@ BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("2000.0000"), core_sym::from_string("1000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("10.0000") ) ); @@ -342,7 +340,7 @@ BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), stake( "alice1111111", core_sym::from_string("-0.0001"), core_sym::from_string("0.0000") ) @@ -366,7 +364,7 @@ BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0001"), core_sym::from_string("100.0001") ) ); @@ -397,7 +395,7 @@ BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( unstake_more_than_at_stake, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "alice1111111" ); @@ -429,7 +427,7 @@ BOOST_FIXTURE_TEST_CASE( unstake_more_than_at_stake, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake ( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); @@ -451,7 +449,7 @@ BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { unstake( "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("0.0000") ) ); - issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", "bob111111111", core_sym::from_string("20.0000"), core_sym::from_string("10.0000") ) ); total = get_total_stake( "bob111111111" ); BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["net_weight"].as()); @@ -485,7 +483,7 @@ BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( stake_unstake_separate, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); //everything at once @@ -523,7 +521,7 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_separate, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( adding_stake_partial_unstake, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); @@ -564,7 +562,7 @@ BOOST_FIXTURE_TEST_CASE( adding_stake_partial_unstake, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "alice1111111" ); @@ -653,7 +651,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tester ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); auto total = get_total_stake( "alice1111111" ); @@ -687,7 +685,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tes // Tests for voting BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try { - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); //fc::variant params = producer_parameters_example(1); auto key = fc::crypto::public_key( std::string("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ); @@ -759,7 +757,7 @@ BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { cross_15_percent_threshold(); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() ("producer", "alice1111111") @@ -773,8 +771,8 @@ BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_t BOOST_REQUIRE_EQUAL( 0, prod["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); - issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - issue( "carol1111111", core_sym::from_string("3000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + issue_and_transfer( "carol1111111", core_sym::from_string("3000.0000"), config::system_account_name ); //bob111111111 makes stake BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("11.0000"), core_sym::from_string("0.1111") ) ); @@ -841,7 +839,7 @@ BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_t BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); @@ -850,7 +848,7 @@ BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * bo vote( N(bob111111111), { N(alice1111111) } ) ); //alice1111111 registers as a producer - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() ("producer", "alice1111111") @@ -876,7 +874,7 @@ BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * bo BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try { - issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); @@ -888,12 +886,12 @@ BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try { - issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("100.0000") ), get_voter_info( "bob111111111" ) ); //alice1111111 becomes a producer - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() ("producer", "alice1111111") @@ -914,7 +912,7 @@ BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); fc::variant params = producer_parameters_example(1); vector key = fc::raw::pack( get_public_key( N(alice1111111), "active" ) ); BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() @@ -926,7 +924,7 @@ BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit ); //bob111111111 makes stake - issue( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); @@ -1003,7 +1001,7 @@ BOOST_FIXTURE_TEST_CASE( vote_for_two_producers, eosio_system_tester, * boost::u ); //carol1111111 votes for alice1111111 and bob111111111 - issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("15.0005"), core_sym::from_string("5.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111), N(bob111111111) } ) ); @@ -1021,7 +1019,7 @@ BOOST_FIXTURE_TEST_CASE( vote_for_two_producers, eosio_system_tester, * boost::u BOOST_TEST_REQUIRE( 0 == bob_info["total_votes"].as_double() ); //alice1111111 votes for herself and bob111111111 - issue( "alice1111111", core_sym::from_string("2.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("2.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("1.0000"), core_sym::from_string("1.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(alice1111111), N(bob111111111) } ) ); @@ -1052,7 +1050,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes REQUIRE_MATCHING_OBJECT( voter( "alice1111111" ), get_voter_info( "alice1111111" ) ); //stake and then register as a proxy - issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("200.0002"), core_sym::from_string("100.0001") ) ); BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() ("proxy", "bob111111111") @@ -1074,7 +1072,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", true) ) ); - issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("246.0002"), core_sym::from_string("531.0001") ) ); //check that both proxy flag and stake a correct REQUIRE_MATCHING_OBJECT( proxy( "carol1111111" )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); @@ -1098,7 +1096,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_stake_unstake_keeps_proxy_flag, eosio_system_test ("isproxy", true) ) ); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); //stake @@ -1138,7 +1136,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * ); //accumulate proxied votes - issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), vector(), N(alice1111111) ) ); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); @@ -1177,7 +1175,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); //stake increase by proxy itself affects producers - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); BOOST_REQUIRE_EQUAL( stake2votes(core_sym::from_string("200.0005")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); @@ -2569,7 +2567,7 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); //alice1111111 makes stake and votes - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); @@ -2584,7 +2582,7 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system REQUIRE_MATCHING_OBJECT( proxy( "donald111111" ), get_voter_info( "donald111111" ) ); //bob111111111 chooses alice1111111 as a proxy - issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); @@ -2593,7 +2591,7 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); //carol1111111 chooses alice1111111 as a proxy - issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); @@ -2647,7 +2645,7 @@ BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) tr //bob111111111 chooses alice1111111 as a proxy - issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot vote for producers and proxy at same time"), vote( N(bob111111111), { N(carol1111111) }, "alice1111111" ) ); @@ -2657,7 +2655,7 @@ BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) tr BOOST_FIXTURE_TEST_CASE( select_invalid_proxy, eosio_system_tester ) try { //accumulate proxied votes - issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); //selecting account not registered as a proxy @@ -2678,13 +2676,13 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys ("isproxy", 1) ) ); - issue( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("5.0000"), core_sym::from_string("5.0000") ) ); edump((get_voter_info("alice1111111"))); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //bob111111111 stakes and selects alice1111111 as a proxy - issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); @@ -2734,13 +2732,13 @@ BOOST_FIXTURE_TEST_CASE( proxy_cannot_use_another_proxy, eosio_system_tester ) t ); //proxy should not be able to use a proxy - issue( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account registered as a proxy is not allowed to use a proxy" ), vote( N(bob111111111), vector(), "alice1111111" ) ); //voter that uses a proxy should not be allowed to become a proxy - issue( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); + issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account that uses a proxy is not allowed to become a proxy" ), @@ -2797,7 +2795,7 @@ BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_teste //REQUIRE_EQUAL_OBJECTS(prod1_config, config); // elect 2 producers - issue( "bob111111111", core_sym::from_string("80000.0000"), config::system_account_name ); + issue_and_transfer( "bob111111111", core_sym::from_string("80000.0000"), config::system_account_name ); ilog("stake"); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("40000.0000"), core_sym::from_string("40000.0000") ) ); ilog("start vote"); @@ -4852,8 +4850,8 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { const name b1{ N(b1) }; - issue( alice, core_sym::from_string("20000.0000"), config::system_account_name ); - issue( bob, core_sym::from_string("20000.0000"), config::system_account_name ); + issue_and_transfer( alice, core_sym::from_string("10000.0000"), config::system_account_name ); + issue_and_transfer( bob, core_sym::from_string("20000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), bidname( bob, b1, core_sym::from_string( "0.5000" ) ) ); BOOST_REQUIRE_EQUAL( success(), bidname( alice, b1, core_sym::from_string( "1.0000" ) ) ); @@ -4864,7 +4862,7 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { const asset stake_amount = core_sym::from_string("50000000.0000"); const asset half_stake = core_sym::from_string("25000000.0000"); const asset small_amount = core_sym::from_string("1000.0000"); - issue( b1, stake_amount + stake_amount + stake_amount, config::system_account_name ); + issue_and_transfer( b1, stake_amount + stake_amount + stake_amount, config::system_account_name ); stake( b1, b1, stake_amount, stake_amount ); From 635a64199bfaccc752c2f5dae426e96d1dc94805 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 18 Apr 2019 18:18:44 -0400 Subject: [PATCH 0780/1048] Change add_eosio_test to add_eosio_test_executable --- tests/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9be6df06..7078da99 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -29,7 +29,7 @@ include(CTest) # eliminates DartConfiguration.tcl errors at test runtime enable_testing() # build unit test executable file(GLOB UNIT_TESTS "*.cpp" "*.hpp") # find all unit test suites -add_eosio_test(unit_test ${UNIT_TESTS}) # build unit tests as one executable +add_eosio_test_executable(unit_test ${UNIT_TESTS}) # build unit tests as one executable # mark test suites for execution foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test suite execute_process(COMMAND bash -c "grep -E 'BOOST_AUTO_TEST_SUITE\\s*[(]' ${TEST_SUITE} | grep -vE '//.*BOOST_AUTO_TEST_SUITE\\s*[(]' | cut -d ')' -f 1 | cut -d '(' -f 2" OUTPUT_VARIABLE SUITE_NAME OUTPUT_STRIP_TRAILING_WHITESPACE) # get the test suite name from the *.cpp file @@ -38,4 +38,4 @@ foreach(TEST_SUITE ${UNIT_TESTS}) # create an independent target for each test s # to run unit_test with all log from blockchain displayed, put "--verbose" after "--", i.e. "unit_test -- --verbose" add_test(NAME ${TRIMMED_SUITE_NAME}_unit_test COMMAND unit_test --run_test=${SUITE_NAME} --report_level=detailed --color_output) endif() -endforeach(TEST_SUITE) \ No newline at end of file +endforeach(TEST_SUITE) From 1586d123bea3508bb96082fe4861f040a482b89a Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 18 Apr 2019 19:13:43 -0400 Subject: [PATCH 0781/1048] update eos dependency --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index af5be3fc..df37d2ae 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=37df54eb8ccc9f020338f8a48ffcf61a376d2431 +eosio=ba081a6ae2e8d8f8d6a7cbee7de48904f5f2ecc6 cdt=release/1.6.x From 9b2d76d38ba31550f6d1694ac50bb9adeb002463 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Thu, 18 Apr 2019 19:18:15 -0400 Subject: [PATCH 0782/1048] wrong hash --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index df37d2ae..23f9291f 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=ba081a6ae2e8d8f8d6a7cbee7de48904f5f2ecc6 +eosio=6b2773cd446137ce2b477a8ec534436f1607c78e cdt=release/1.6.x From 905d8b666689457398c4cdf60335b44cc55742e8 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 18 Apr 2019 19:57:10 -0400 Subject: [PATCH 0783/1048] update eosio dependency --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index 23f9291f..bcf78633 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=6b2773cd446137ce2b477a8ec534436f1607c78e +eosio=9dfd8e2e1b2ab9acc9087b5c6a0bb878b4ad1d0f cdt=release/1.6.x From 3e6fbbb090e8b4d674234f548b7498dbccabb50a Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 18 Apr 2019 20:31:17 -0400 Subject: [PATCH 0784/1048] update tests to use new applied_transaction signal --- tests/eosio.msig_tests.cpp | 56 ++++++++++++++++++++++++++++++------ tests/eosio.system_tests.cpp | 14 +++++++-- tests/eosio.wrap_tests.cpp | 18 ++++++++---- 3 files changed, 72 insertions(+), 16 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index c0ae25fd..570fbd1a 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -208,7 +208,11 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_execute, eosio_msig_tester ) try { ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); push_action( N(alice), N(exec), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -290,7 +294,11 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); push_action( N(alice), N(exec), mvo() ("proposer", "alice") @@ -369,7 +377,11 @@ BOOST_FIXTURE_TEST_CASE( big_transaction, eosio_msig_tester ) try { ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); push_action( N(alice), N(exec), mvo() ("proposer", "alice") @@ -485,7 +497,11 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) ); // execute by alice to replace the eosio system contract transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); push_action( N(alice), N(exec), mvo() ("proposer", "alice") @@ -611,7 +627,11 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ); // execute by alice to replace the eosio system contract transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); // execute by another producer different from proposer push_action( N(apple), N(exec), mvo() @@ -709,7 +729,11 @@ BOOST_FIXTURE_TEST_CASE( propose_invalidate_approve, eosio_msig_tester ) try { //successfully execute transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); push_action( N(bob), N(exec), mvo() ("proposer", "alice") @@ -748,7 +772,12 @@ BOOST_FIXTURE_TEST_CASE( approve_execute_old, eosio_msig_tester ) try { ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); + push_action( N(alice), N(exec), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -847,7 +876,11 @@ BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); push_action( N(alice), N(exec), mvo() ("proposer", "alice") @@ -893,7 +926,12 @@ BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); + push_action( N(alice), N(exec), mvo() ("proposer", "alice") ("proposal_name", "first") diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b38d068f..0bafe55d 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -2440,7 +2440,12 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); + BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() ("proposer", "alice1111111") ("proposal_name", "upgrade1") @@ -3197,7 +3202,12 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { } transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); + BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() ("proposer", "alice1111111") ("proposal_name", "setparams1") diff --git a/tests/eosio.wrap_tests.cpp b/tests/eosio.wrap_tests.cpp index 1d9e33d2..4e24a48f 100644 --- a/tests/eosio.wrap_tests.cpp +++ b/tests/eosio.wrap_tests.cpp @@ -166,7 +166,11 @@ BOOST_FIXTURE_TEST_CASE( wrap_exec_direct, eosio_wrap_tester ) try { auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); transaction_trace_ptr trace; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { if (t->scheduled) { trace = t; } } ); + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { trace = t; } + } ); { signed_transaction wrap_trx( wrap_exec( N(alice), trx ), {}, {} ); @@ -214,8 +218,10 @@ BOOST_FIXTURE_TEST_CASE( wrap_with_msig, eosio_wrap_tester ) try { approve( N(carol), N(first), N(prod4) ); vector traces; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { - if (t->scheduled) { + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { traces.push_back( t ); } } ); @@ -328,8 +334,10 @@ BOOST_FIXTURE_TEST_CASE( wrap_with_msig_producers_change, eosio_wrap_tester ) tr approve( N(carol), N(first), N(prod5) ); vector traces; - control->applied_transaction.connect([&]( const transaction_trace_ptr& t) { - if (t->scheduled) { + control->applied_transaction.connect( + [&]( std::tuple p ) { + const auto& t = std::get<0>(p); + if( t->scheduled ) { traces.push_back( t ); } } ); From 35cd20c2ba3fc234f788a393601b6331140eb0b2 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 18 Apr 2019 22:20:26 -0400 Subject: [PATCH 0785/1048] Added ctest error handling to unit tests --- docker/unit-test.sh | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/docker/unit-test.sh b/docker/unit-test.sh index 25d98b64..9348960b 100755 --- a/docker/unit-test.sh +++ b/docker/unit-test.sh @@ -6,5 +6,14 @@ cd /eosio.contracts/build/tests TEST_COUNT=$(ctest -N | grep -i 'Total Tests: ' | cut -d ':' -f 2 | awk '{print $1}') [[ $TEST_COUNT > 0 ]] && echo "$TEST_COUNT tests found." || (echo "ERROR: No tests registered with ctest! Exiting..." && exit 1) echo "$ ctest -j $CPU_CORES --output-on-failure -T Test" +set +e # defer ctest error handling to end ctest -j $CPU_CORES --output-on-failure -T Test -mv /eosio.contracts/build/tests/Testing/$(ls /eosio.contracts/build/tests/Testing/ | grep '20' | tail -n 1)/Test.xml /artifacts/Test.xml \ No newline at end of file +EXIT_STATUS=$? +[[ "$EXIT_STATUS" == 0 ]] && set -e +mv /eosio.contracts/build/tests/Testing/$(ls /eosio.contracts/build/tests/Testing/ | grep '20' | tail -n 1)/Test.xml /artifacts/Test.xml +# ctest error handling +if [[ "$EXIT_STATUS" != 0 ]]; then + echo "Failing due to non-zero exit status from ctest: $EXIT_STATUS" + echo ' ^^^ scroll up for more information ^^^' + exit $EXIT_STATUS +fi \ No newline at end of file From ce3fa3f2e5be8baad09fe3048423eaf417be55f7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 19 Apr 2019 09:56:10 -0400 Subject: [PATCH 0786/1048] Use action wrappers, other small changes --- .../eosio.system/src/delegate_bandwidth.cpp | 53 +++++++------------ contracts/eosio.system/src/eosio.system.cpp | 19 +++---- contracts/eosio.system/src/producer_pay.cpp | 46 ++++++---------- .../include/eosio.token/eosio.token.hpp | 28 +++++----- contracts/eosio.token/src/eosio.token.cpp | 24 ++++----- tests/eosio.token_tests.cpp | 2 + 6 files changed, 71 insertions(+), 101 deletions(-) diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 7f4270cf..5691b545 100755 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -121,20 +121,16 @@ namespace eosiosystem { quant_after_fee.amount -= fee.amount; // quant_after_fee.amount should be > 0 if quant.amount > 1. // If quant.amount == 1, then quant_after_fee.amount == 0 and the next inline transfer will fail causing the buyram action to fail. - - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {payer, active_permission}, {ram_account, active_permission} }, - { payer, ram_account, quant_after_fee, std::string("buy ram") } - ); - - if( fee.amount > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {payer, active_permission} }, - { payer, ramfee_account, fee, std::string("ram fee") } - ); + { + token::transfer_action transfer_act{ token_account, { {payer, active_permission}, {ram_account, active_permission} } }; + transfer_act.send( payer, ram_account, quant_after_fee, "buy ram" ); + } + if ( fee.amount > 0 ) { + token::transfer_action transfer_act{ token_account, { {payer, active_permission} } }; + transfer_act.send( payer, ramfee_account, fee, "ram fee" ); channel_to_rex( ramfee_account, fee ); } - + int64_t bytes_out; const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); @@ -212,19 +208,16 @@ namespace eosiosystem { get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); } - - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {ram_account, active_permission}, {account, active_permission} }, - { ram_account, account, asset(tokens_out), std::string("sell ram") } - ); - + + { + token::transfer_action transfer_act{ token_account, { {ram_account, active_permission}, {account, active_permission} } }; + transfer_act.send( ram_account, account, asset(tokens_out), "sell ram" ); + } auto fee = ( tokens_out.amount + 199 ) / 200; /// .5% fee (round up) // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount - if( fee > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {account, active_permission} }, - { account, ramfee_account, asset(fee, core_symbol()), std::string("sell ram fee") } - ); + if ( fee > 0 ) { + token::transfer_action transfer_act{ token_account, { {account, active_permission} } }; + transfer_act.send( account, ramfee_account, asset(fee, core_symbol()), "sell ram fee" ); channel_to_rex( ramfee_account, asset(fee, core_symbol() )); } } @@ -406,10 +399,8 @@ namespace eosiosystem { auto transfer_amount = net_balance + cpu_balance; if ( 0 < transfer_amount.amount ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {source_stake_from, active_permission} }, - { source_stake_from, stake_account, asset(transfer_amount), std::string("stake bandwidth") } - ); + token::transfer_action transfer_act{ token_account, { {source_stake_from, active_permission} } }; + transfer_act.send( source_stake_from, stake_account, asset(transfer_amount), "stake bandwidth" ); } } @@ -477,12 +468,8 @@ namespace eosiosystem { check( req != refunds_tbl.end(), "refund request not found" ); check( req->request_time + seconds(refund_delay_sec) <= current_time_point(), "refund is not available yet" ); - - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {stake_account, active_permission}, {req->owner, active_permission} }, - { stake_account, req->owner, req->net_amount + req->cpu_amount, std::string("unstake") } - ); - + token::transfer_action transfer_act{ token_account, { {stake_account, active_permission}, {req->owner, active_permission} } }; + transfer_act.send( stake_account, req->owner, req->net_amount + req->cpu_amount, "unstake" ); refunds_tbl.erase( req ); } diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index db44cec3..b9877c3a 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -298,12 +298,8 @@ namespace eosiosystem { check( !is_account( newname ), "account already exists" ); check( bid.symbol == core_symbol(), "asset must be system token" ); check( bid.amount > 0, "insufficient bid" ); - - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {bidder, active_permission} }, - { bidder, names_account, bid, std::string("bid name ")+ newname.to_string() } - ); - + token::transfer_action transfer_act{ token_account, { {bidder, active_permission} } }; + transfer_act.send( bidder, names_account, bid, std::string("bid name ")+ newname.to_string() ); name_bid_table bids(_self, _self.value); print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); auto current = bids.find( newname.value ); @@ -355,10 +351,9 @@ namespace eosiosystem { bid_refund_table refunds_table(_self, newname.value); auto it = refunds_table.find( bidder.value ); check( it != refunds_table.end(), "refund not found" ); - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {names_account, active_permission}, {bidder, active_permission} }, - { names_account, bidder, asset(it->amount), std::string("refund bid on name ")+(name{newname}).to_string() } - ); + + token::transfer_action transfer_act{ token_account, { {names_account, active_permission}, {bidder, active_permission} } }; + transfer_act.send( names_account, bidder, asset(it->amount), std::string("refund bid on name ")+(name{newname}).to_string() ); refunds_table.erase( it ); } @@ -445,8 +440,8 @@ namespace eosiosystem { m.quote.balance.symbol = core; }); - INLINE_ACTION_SENDER(eosio::token, open)( token_account, { _self, active_permission }, - { rex_account, core, _self } ); + token::open_action open_act{ token_account, { {_self, active_permission} } }; + open_act.send( rex_account, core, _self ); } } /// eosio.system diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 05df265a..f4cc894f 100755 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -98,26 +98,16 @@ namespace eosiosystem { auto to_savings = new_tokens - to_producers; auto to_per_block_pay = to_producers / votepay_factor; auto to_per_vote_pay = to_producers - to_per_block_pay; - - INLINE_ACTION_SENDER(eosio::token, issue)( - token_account, { {_self, active_permission} }, - { _self, asset(new_tokens, core_symbol()), std::string("issue tokens for producer pay and savings") } - ); - - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {_self, active_permission} }, - { _self, saving_account, asset(to_savings, core_symbol()), "unallocated inflation" } - ); - - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {_self, active_permission} }, - { _self, bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" } - ); - - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {_self, active_permission} }, - { _self, vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" } - ); + { + token::issue_action issue_act{ token_account, { {_self, active_permission} } }; + issue_act.send( _self, asset(new_tokens, core_symbol()), "issue tokens for producer pay and savings" ); + } + { + token::transfer_action transfer_act{ token_account, { {_self, active_permission} } }; + transfer_act.send( _self, saving_account, asset(to_savings, core_symbol()), "unallocated inflation" ); + transfer_act.send( _self, bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" ); + transfer_act.send( _self, vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" ); + } _gstate.pervote_bucket += to_per_vote_pay; _gstate.perblock_bucket += to_per_block_pay; @@ -186,17 +176,13 @@ namespace eosiosystem { p.unpaid_blocks = 0; }); - if( producer_per_block_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {bpay_account, active_permission}, {owner, active_permission} }, - { bpay_account, owner, asset(producer_per_block_pay, core_symbol()), std::string("producer block pay") } - ); + if ( producer_per_block_pay > 0 ) { + token::transfer_action transfer_act{ token_account, { {bpay_account, active_permission}, {owner, active_permission} } }; + transfer_act.send( bpay_account, owner, asset(producer_per_block_pay, core_symbol()), "producer block pay" ); } - if( producer_per_vote_pay > 0 ) { - INLINE_ACTION_SENDER(eosio::token, transfer)( - token_account, { {vpay_account, active_permission}, {owner, active_permission} }, - { vpay_account, owner, asset(producer_per_vote_pay, core_symbol()), std::string("producer vote pay") } - ); + if ( producer_per_vote_pay > 0 ) { + token::transfer_action transfer_act{ token_account, { {vpay_account, active_permission}, {owner, active_permission} } }; + transfer_act.send( vpay_account, owner, asset(producer_per_vote_pay, core_symbol()), "producer vote pay" ); } } diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index ee01c4d1..ecdcc3b7 100755 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -46,8 +46,8 @@ namespace eosio { * If validation is successful a new entry in statstable for token symbol scope gets created. */ [[eosio::action]] - void create( name issuer, - asset maximum_supply); + void create( const name& issuer, + const asset& maximum_supply); /** * Issue action. * @@ -58,7 +58,7 @@ namespace eosio { * @memo - the memo string that accompanies the token issue transaction. */ [[eosio::action]] - void issue( name to, asset quantity, string memo ); + void issue( const name& to, const asset& quantity, const string& memo ); /** * Retire action. @@ -70,7 +70,7 @@ namespace eosio { * @param memo - the memo string to accompany the transaction. */ [[eosio::action]] - void retire( asset quantity, string memo ); + void retire( const asset& quantity, const string& memo ); /** * Transfer action. @@ -84,10 +84,10 @@ namespace eosio { * @param memo - the memo string to accompany the transaction. */ [[eosio::action]] - void transfer( name from, - name to, - asset quantity, - string memo ); + void transfer( const name& from, + const name& to, + const asset& quantity, + const string& memo ); /** * Open action. * @@ -102,7 +102,7 @@ namespace eosio { * and [here](https://github.com/EOSIO/eosio.contracts/issues/61). */ [[eosio::action]] - void open( name owner, const symbol& symbol, name ram_payer ); + void open( const name& owner, const symbol& symbol, const name& ram_payer ); /** * Close action. @@ -117,7 +117,7 @@ namespace eosio { * @pre If the pair of owner plus symbol exists, the balance has to be zero. */ [[eosio::action]] - void close( name owner, const symbol& symbol ); + void close( const name& owner, const symbol& symbol ); /** * Get supply method. @@ -127,7 +127,7 @@ namespace eosio { * @param token_contract_account - the account to get the supply for, * @param sym_code - the symbol to get the supply for. */ - static asset get_supply( name token_contract_account, symbol_code sym_code ) + static asset get_supply( const name& token_contract_account, const symbol_code& sym_code ) { stats statstable( token_contract_account, sym_code.raw() ); const auto& st = statstable.get( sym_code.raw() ); @@ -144,7 +144,7 @@ namespace eosio { * @param owner - the account for which the token balance is returned, * @param sym_code - the token for which the balance is returned. */ - static asset get_balance( name token_contract_account, name owner, symbol_code sym_code ) + static asset get_balance( const name& token_contract_account, const name& owner, const symbol_code& sym_code ) { accounts accountstable( token_contract_account, owner.value ); const auto& ac = accountstable.get( sym_code.raw() ); @@ -175,8 +175,8 @@ namespace eosio { typedef eosio::multi_index< "accounts"_n, account > accounts; typedef eosio::multi_index< "stat"_n, currency_stats > stats; - void sub_balance( name owner, asset value ); - void add_balance( name owner, asset value, name ram_payer ); + void sub_balance( const name& owner, const asset& value ); + void add_balance( const name& owner, const asset& value, const name& ram_payer ); }; /** @}*/ // end of @defgroup eosiotoken eosio.token } /// namespace eosio diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index 3ecebe22..fd294ac3 100755 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -7,8 +7,8 @@ namespace eosio { -void token::create( name issuer, - asset maximum_supply ) +void token::create( const name& issuer, + const asset& maximum_supply ) { require_auth( _self ); @@ -29,7 +29,7 @@ void token::create( name issuer, } -void token::issue( name to, asset quantity, string memo ) +void token::issue( const name& to, const asset& quantity, const string& memo ) { auto sym = quantity.symbol; check( sym.is_valid(), "invalid symbol name" ); @@ -55,7 +55,7 @@ void token::issue( name to, asset quantity, string memo ) add_balance( st.issuer, quantity, st.issuer ); } -void token::retire( asset quantity, string memo ) +void token::retire( const asset& quantity, const string& memo ) { auto sym = quantity.symbol; check( sym.is_valid(), "invalid symbol name" ); @@ -79,10 +79,10 @@ void token::retire( asset quantity, string memo ) sub_balance( st.issuer, quantity ); } -void token::transfer( name from, - name to, - asset quantity, - string memo ) +void token::transfer( const name& from, + const name& to, + const asset& quantity, + const string& memo ) { check( from != to, "cannot transfer to self" ); require_auth( from ); @@ -105,7 +105,7 @@ void token::transfer( name from, add_balance( to, quantity, payer ); } -void token::sub_balance( name owner, asset value ) { +void token::sub_balance( const name& owner, const asset& value ) { accounts from_acnts( _self, owner.value ); const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" ); @@ -116,7 +116,7 @@ void token::sub_balance( name owner, asset value ) { }); } -void token::add_balance( name owner, asset value, name ram_payer ) +void token::add_balance( const name& owner, const asset& value, const name& ram_payer ) { accounts to_acnts( _self, owner.value ); auto to = to_acnts.find( value.symbol.code().raw() ); @@ -131,7 +131,7 @@ void token::add_balance( name owner, asset value, name ram_payer ) } } -void token::open( name owner, const symbol& symbol, name ram_payer ) +void token::open( const name& owner, const symbol& symbol, const name& ram_payer ) { require_auth( ram_payer ); @@ -150,7 +150,7 @@ void token::open( name owner, const symbol& symbol, name ram_payer ) } } -void token::close( name owner, const symbol& symbol ) +void token::close( const name& owner, const symbol& symbol ) { require_auth( owner ); accounts acnts( _self, owner.value ); diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 8d7d73ff..ba1524b0 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -353,6 +353,8 @@ BOOST_FIXTURE_TEST_CASE( open_tests, eosio_token_tester ) try { auto alice_balance = get_account(N(alice), "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("tokens can only be issued to issuer account"), + issue( N(alice), N(bob), asset::from_string("1000 CERO"), "issue" ) ); BOOST_REQUIRE_EQUAL( success(), issue( N(alice), N(alice), asset::from_string("1000 CERO"), "issue" ) ); alice_balance = get_account(N(alice), "0,CERO"); From b3f1159ed163d577c9ab2ed109957d35f2001e55 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 19 Apr 2019 15:48:55 -0400 Subject: [PATCH 0787/1048] Pass system contract action parameters by const reference --- .../include/eosio.system/eosio.system.hpp | 58 +++++++++---------- .../include/eosio.system/native.hpp | 42 +++++++------- .../eosio.system/src/delegate_bandwidth.cpp | 22 +++---- contracts/eosio.system/src/eosio.system.cpp | 28 ++++----- contracts/eosio.system/src/producer_pay.cpp | 4 +- contracts/eosio.system/src/voting.cpp | 16 ++--- 6 files changed, 85 insertions(+), 85 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 97760999..84cea782 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -535,7 +535,7 @@ namespace eosiosystem { * @param core - the system symbol. */ [[eosio::action]] - void init( unsigned_int version, symbol core ); + void init( unsigned_int version, const symbol& core ); /** * On block action. @@ -549,7 +549,7 @@ namespace eosiosystem { * @param header - the block header produced. */ [[eosio::action]] - void onblock( ignore header ); + void onblock( const ignore& header ); /** * Set account limits action. @@ -562,7 +562,7 @@ namespace eosiosystem { * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). */ [[eosio::action]] - void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); + void setalimits( const name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); /** * Set account RAM limits action. @@ -573,7 +573,7 @@ namespace eosiosystem { * @param ram_bytes - ram limit in absolute bytes. */ [[eosio::action]] - void setacctram( name account, std::optional ram_bytes ); + void setacctram( const name& account, const std::optional& ram_bytes ); /** * Set account NET limits action. @@ -584,7 +584,7 @@ namespace eosiosystem { * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts). */ [[eosio::action]] - void setacctnet( name account, std::optional net_weight ); + void setacctnet( const name& account, const std::optional& net_weight ); /** * Set account CPU limits action. @@ -595,7 +595,7 @@ namespace eosiosystem { * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). */ [[eosio::action]] - void setacctcpu( name account, std::optional cpu_weight ); + void setacctcpu( const name& account, const std::optional& cpu_weight ); /** @@ -626,8 +626,8 @@ namespace eosiosystem { * @post All producers `from` account has voted for will have their votes updated immediately. */ [[eosio::action]] - void delegatebw( name from, name receiver, - asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + void delegatebw( const name& from, const name& receiver, + const asset& stake_net_quantity, const asset& stake_cpu_quantity, bool transfer ); /** * Setrex action. @@ -934,8 +934,8 @@ namespace eosiosystem { * @post Bandwidth and storage for the deferred transaction are billed to `from`. */ [[eosio::action]] - void undelegatebw( name from, name receiver, - asset unstake_net_quantity, asset unstake_cpu_quantity ); + void undelegatebw( const name& from, const name& receiver, + const asset& unstake_net_quantity, const asset& unstake_cpu_quantity ); /** * Buy ram action. @@ -949,7 +949,7 @@ namespace eosiosystem { * @param quant - the quntity of tokens to buy ram with. */ [[eosio::action]] - void buyram( name payer, name receiver, asset quant ); + void buyram( const name& payer, const name& receiver, const asset& quant ); /** * Buy a specific amount of ram bytes action. @@ -962,7 +962,7 @@ namespace eosiosystem { * @param bytes - the quntity of ram to buy specified in bytes. */ [[eosio::action]] - void buyrambytes( name payer, name receiver, uint32_t bytes ); + void buyrambytes( const name& payer, const name& receiver, uint32_t bytes ); /** * Sell ram action. @@ -974,7 +974,7 @@ namespace eosiosystem { * @param bytes - the amount of ram to sell in bytes. */ [[eosio::action]] - void sellram( name account, int64_t bytes ); + void sellram( const name& account, int64_t bytes ); /** * Refund action. @@ -985,7 +985,7 @@ namespace eosiosystem { * @param owner - the owner of the tokens claimed. */ [[eosio::action]] - void refund( name owner ); + void refund( const name& owner ); // functions defined in voting.cpp @@ -1006,7 +1006,7 @@ namespace eosiosystem { * @pre Authority of producer to register */ [[eosio::action]] - void regproducer( const name producer, const public_key& producer_key, const std::string& url, uint16_t location ); + void regproducer( const name& producer, const public_key& producer_key, const std::string& url, uint16_t location ); /** * Unregister producer action. @@ -1015,7 +1015,7 @@ namespace eosiosystem { * @param producer - the block producer account to unregister. */ [[eosio::action]] - void unregprod( const name producer ); + void unregprod( const name& producer ); /** * Set ram action. @@ -1064,7 +1064,7 @@ namespace eosiosystem { * @post New proxy will proxied_vote_weight incremented by new vote weight */ [[eosio::action]] - void voteproducer( const name voter, const name proxy, const std::vector& producers ); + void voteproducer( const name& voter, const name& proxy, const std::vector& producers ); /** * Register proxy action. @@ -1082,7 +1082,7 @@ namespace eosiosystem { * @pre New state must be different than current state */ [[eosio::action]] - void regproxy( const name proxy, bool isproxy ); + void regproxy( const name& proxy, bool isproxy ); /** * Set the blockchain parameters @@ -1102,7 +1102,7 @@ namespace eosiosystem { * @param owner - producer account claiming per-block and per-vote rewards. */ [[eosio::action]] - void claimrewards( const name owner ); + void claimrewards( const name& owner ); /** * Set privilege status for an account. @@ -1112,7 +1112,7 @@ namespace eosiosystem { * @param is_priv - 0 for false, > 0 for true. */ [[eosio::action]] - void setpriv( name account, uint8_t is_priv ); + void setpriv( const name& account, uint8_t is_priv ); /** * Remove producer action. @@ -1121,7 +1121,7 @@ namespace eosiosystem { * @param producer - the producer account to deactivate. */ [[eosio::action]] - void rmvproducer( name producer ); + void rmvproducer( const name& producer ); /** * Update revision action. @@ -1154,7 +1154,7 @@ namespace eosiosystem { * @pre Auction must still be opened. */ [[eosio::action]] - void bidname( name bidder, name newname, asset bid ); + void bidname( const name& bidder, const name& newname, const asset& bid ); /** * Bid refund action. @@ -1165,7 +1165,7 @@ namespace eosiosystem { * @param newname - the name for which the bid was placed and now it gets refunded for. */ [[eosio::action]] - void bidrefund( name bidder, name newname ); + void bidrefund( const name& bidder, const name& newname ); using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; @@ -1279,18 +1279,18 @@ namespace eosiosystem { int64_t update_renewed_loan( Index& idx, const Iterator& itr, int64_t rented_tokens ); // defined in delegate_bandwidth.cpp - void changebw( name from, name receiver, - asset stake_net_quantity, asset stake_cpu_quantity, bool transfer ); + void changebw( name from, const name& receiver, + const asset& stake_net_quantity, const asset& stake_cpu_quantity, bool transfer ); void update_voting_power( const name& voter, const asset& total_update ); // defined in voting.hpp - void update_elected_producers( block_timestamp timestamp ); - void update_votes( const name voter, const name proxy, const std::vector& producers, bool voting ); + void update_elected_producers( const block_timestamp& timestamp ); + void update_votes( const name& voter, const name& proxy, const std::vector& producers, bool voting ); void propagate_weight_change( const voter_info& voter ); double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, - time_point ct, + const time_point& ct, double shares_rate, bool reset_to_zero = false ); - double update_total_votepay_share( time_point ct, + double update_total_votepay_share( const time_point& ct, double additional_shares_delta = 0.0, double shares_rate_delta = 0.0 ); template diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index e3442003..bb1ac566 100755 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -187,10 +187,10 @@ namespace eosiosystem { * an amount equal to the current new account creation fee. */ [[eosio::action]] - void newaccount( name creator, - name name, - ignore owner, - ignore active); + void newaccount( const name& creator, + const name& name, + const ignore& owner, + const ignore& active); /** * Update authorization action. @@ -203,10 +203,10 @@ namespace eosiosystem { * @param aut - the json describing the permission authorization */ [[eosio::action]] - void updateauth( ignore account, - ignore permission, - ignore parent, - ignore auth ) {} + void updateauth( const ignore& account, + const ignore& permission, + const ignore& parent, + const ignore& auth ) {} /** * Delete authorization action. @@ -217,8 +217,8 @@ namespace eosiosystem { * @param permission - the permission name been deleted. */ [[eosio::action]] - void deleteauth( ignore account, - ignore permission ) {} + void deleteauth( const ignore& account, + const ignore& permission ) {} /** * Link authorization action. @@ -238,10 +238,10 @@ namespace eosiosystem { * @param requirement - the permission to be linked. */ [[eosio::action]] - void linkauth( ignore account, - ignore code, - ignore type, - ignore requirement ) {} + void linkauth( const ignore& account, + const ignore& code, + const ignore& type, + const ignore& requirement ) {} /** * Unlink authorization action. @@ -253,9 +253,9 @@ namespace eosiosystem { * @param type - the action to be unlinked. */ [[eosio::action]] - void unlinkauth( ignore account, - ignore code, - ignore type ) {} + void unlinkauth( const ignore& account, + const ignore& code, + const ignore& type ) {} /** * Cancel delay action. @@ -266,7 +266,7 @@ namespace eosiosystem { * @param trx_id - the deferred transaction id to be cancelled. */ [[eosio::action]] - void canceldelay( ignore canceling_auth, ignore trx_id ) {} + void canceldelay( const ignore& canceling_auth, const ignore& trx_id ) {} /** * On error action. @@ -277,7 +277,7 @@ namespace eosiosystem { * @param sent_trx - the transaction that failed. */ [[eosio::action]] - void onerror( ignore sender_id, ignore> sent_trx ) {} + void onerror( const ignore& sender_id, const ignore>& sent_trx ) {} /** * Set abi action. @@ -288,7 +288,7 @@ namespace eosiosystem { * @param abi - the abi content to be set, in the form of a blob binary. */ [[eosio::action]] - void setabi( name account, const std::vector& abi ); + void setabi( const name& account, const std::vector& abi ); /** * Set code action. @@ -301,7 +301,7 @@ namespace eosiosystem { * @param code - the code content to be set, in the form of a blob binary.. */ [[eosio::action]] - void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} + void setcode( const name& account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} /** @}*/ diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 5691b545..85a595d5 100755 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -86,7 +86,7 @@ namespace eosiosystem { /** * This action will buy an exact amount of ram and bill the payer the current market price. */ - void system_contract::buyrambytes( name payer, name receiver, uint32_t bytes ) { + void system_contract::buyrambytes( const name& payer, const name& receiver, uint32_t bytes ) { auto itr = _rammarket.find(ramcore_symbol.raw()); auto tmp = *itr; @@ -104,7 +104,7 @@ namespace eosiosystem { * RAM is a scarce resource whose supply is defined by global properties max_ram_size. RAM is * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. */ - void system_contract::buyram( name payer, name receiver, asset quant ) + void system_contract::buyram( const name& payer, const name& receiver, const asset& quant ) { require_auth( payer ); update_ram_supply(); @@ -172,7 +172,7 @@ namespace eosiosystem { * tomorrow. Overall this will result in the market balancing the supply and demand * for RAM over time. */ - void system_contract::sellram( name account, int64_t bytes ) { + void system_contract::sellram( const name& account, int64_t bytes ) { require_auth( account ); update_ram_supply(); @@ -230,8 +230,8 @@ namespace eosiosystem { check( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } - void system_contract::changebw( name from, name receiver, - const asset stake_net_delta, const asset stake_cpu_delta, bool transfer ) + void system_contract::changebw( name from, const name& receiver, + const asset& stake_net_delta, const asset& stake_cpu_delta, bool transfer ) { require_auth( from ); check( stake_net_delta.amount != 0 || stake_cpu_delta.amount != 0, "should stake non-zero amount" ); @@ -433,9 +433,9 @@ namespace eosiosystem { } } - void system_contract::delegatebw( name from, name receiver, - asset stake_net_quantity, - asset stake_cpu_quantity, bool transfer ) + void system_contract::delegatebw( const name& from, const name& receiver, + const asset& stake_net_quantity, + const asset& stake_cpu_quantity, bool transfer ) { asset zero_asset( 0, core_symbol() ); check( stake_cpu_quantity >= zero_asset, "must stake a positive amount" ); @@ -446,8 +446,8 @@ namespace eosiosystem { changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); } // delegatebw - void system_contract::undelegatebw( name from, name receiver, - asset unstake_net_quantity, asset unstake_cpu_quantity ) + void system_contract::undelegatebw( const name& from, const name& receiver, + const asset& unstake_net_quantity, const asset& unstake_cpu_quantity ) { asset zero_asset( 0, core_symbol() ); check( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); @@ -460,7 +460,7 @@ namespace eosiosystem { } // undelegatebw - void system_contract::refund( const name owner ) { + void system_contract::refund( const name& owner ) { require_auth( owner ); refunds_table refunds_tbl( _self, owner.value ); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index b232a276..711552fd 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -114,12 +114,12 @@ namespace eosiosystem { set_blockchain_parameters( params ); } - void system_contract::setpriv( name account, uint8_t ispriv ) { + void system_contract::setpriv( const name& account, uint8_t ispriv ) { require_auth( _self ); set_privileged( account.value, ispriv ); } - void system_contract::setalimits( name account, int64_t ram, int64_t net, int64_t cpu ) { + void system_contract::setalimits( const name& account, int64_t ram, int64_t net, int64_t cpu ) { require_auth( _self ); user_resources_table userres( _self, account.value ); @@ -137,7 +137,7 @@ namespace eosiosystem { set_resource_limits( account.value, ram, net, cpu ); } - void system_contract::setacctram( name account, std::optional ram_bytes ) { + void system_contract::setacctram( const name& account, const std::optional& ram_bytes ) { require_auth( _self ); int64_t current_ram, current_net, current_cpu; @@ -182,7 +182,7 @@ namespace eosiosystem { set_resource_limits( account.value, ram, current_net, current_cpu ); } - void system_contract::setacctnet( name account, std::optional net_weight ) { + void system_contract::setacctnet( const name& account, const std::optional& net_weight ) { require_auth( _self ); int64_t current_ram, current_net, current_cpu; @@ -226,7 +226,7 @@ namespace eosiosystem { set_resource_limits( account.value, current_ram, net, current_cpu ); } - void system_contract::setacctcpu( name account, std::optional cpu_weight ) { + void system_contract::setacctcpu( const name& account, const std::optional& cpu_weight ) { require_auth( _self ); int64_t current_ram, current_net, current_cpu; @@ -275,7 +275,7 @@ namespace eosiosystem { preactivate_feature( feature_digest ); } - void system_contract::rmvproducer( name producer ) { + void system_contract::rmvproducer( const name& producer ) { require_auth( _self ); auto prod = _producers.find( producer.value ); check( prod != _producers.end(), "producer not found" ); @@ -293,7 +293,7 @@ namespace eosiosystem { _gstate2.revision = revision; } - void system_contract::bidname( name bidder, name newname, asset bid ) { + void system_contract::bidname( const name& bidder, const name& newname, const asset& bid ) { require_auth( bidder ); check( newname.suffix() == newname, "you can only bid on top-level suffix" ); @@ -352,7 +352,7 @@ namespace eosiosystem { } } - void system_contract::bidrefund( name bidder, name newname ) { + void system_contract::bidrefund( const name& bidder, const name& newname ) { bid_refund_table refunds_table(_self, newname.value); auto it = refunds_table.find( bidder.value ); check( it != refunds_table.end(), "refund not found" ); @@ -371,10 +371,10 @@ namespace eosiosystem { * who can create accounts with the creator's name as a suffix. * */ - void native::newaccount( name creator, - name newact, - ignore owner, - ignore active ) { + void native::newaccount( const name& creator, + const name& newact, + const ignore& owner, + const ignore& active ) { if( creator != _self ) { uint64_t tmp = newact.value >> 4; @@ -410,7 +410,7 @@ namespace eosiosystem { set_resource_limits( newact.value, 0, 0, 0 ); } - void native::setabi( name acnt, const std::vector& abi ) { + void native::setabi( const name& acnt, const std::vector& abi ) { eosio::multi_index< "abihash"_n, abi_hash > table(_self, _self.value); auto itr = table.find( acnt.value ); if( itr == table.end() ) { @@ -425,7 +425,7 @@ namespace eosiosystem { } } - void system_contract::init( unsigned_int version, symbol core ) { + void system_contract::init( unsigned_int version, const symbol& core ) { require_auth( _self ); check( version.value == 0, "unsupported version for init action" ); diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index f4cc894f..80b27bfb 100755 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -16,7 +16,7 @@ namespace eosiosystem { const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); const int64_t useconds_per_year = seconds_per_year*1000000ll; - void system_contract::onblock( ignore ) { + void system_contract::onblock( const ignore& ) { using namespace eosio; require_auth(_self); @@ -75,7 +75,7 @@ namespace eosiosystem { } using namespace eosio; - void system_contract::claimrewards( const name owner ) { + void system_contract::claimrewards( const name& owner ) { require_auth( owner ); const auto& prod = _producers.get( owner.value ); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 0530b026..31d1dc98 100755 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -23,7 +23,7 @@ namespace eosiosystem { using eosio::singleton; using eosio::transaction; - void system_contract::regproducer( const name producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { + void system_contract::regproducer( const name& producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { check( url.size() < 512, "url too long" ); check( producer_key != eosio::public_key(), "public key should not be the default value" ); require_auth( producer ); @@ -68,7 +68,7 @@ namespace eosiosystem { } - void system_contract::unregprod( const name producer ) { + void system_contract::unregprod( const name& producer ) { require_auth( producer ); const auto& prod = _producers.get( producer.value, "producer not found" ); @@ -77,7 +77,7 @@ namespace eosiosystem { }); } - void system_contract::update_elected_producers( block_timestamp block_time ) { + void system_contract::update_elected_producers( const block_timestamp& block_time ) { _gstate.last_producer_schedule_update = block_time; auto idx = _producers.get_index<"prototalvote"_n>(); @@ -115,7 +115,7 @@ namespace eosiosystem { return double(staked) * std::pow( 2, weight ); } - double system_contract::update_total_votepay_share( time_point ct, + double system_contract::update_total_votepay_share( const time_point& ct, double additional_shares_delta, double shares_rate_delta ) { @@ -144,7 +144,7 @@ namespace eosiosystem { } double system_contract::update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, - time_point ct, + const time_point& ct, double shares_rate, bool reset_to_zero ) { @@ -166,7 +166,7 @@ namespace eosiosystem { return new_votepay_share; } - void system_contract::voteproducer( const name voter_name, const name proxy, const std::vector& producers ) { + void system_contract::voteproducer( const name& voter_name, const name& proxy, const std::vector& producers ) { require_auth( voter_name ); vote_stake_updater( voter_name ); update_votes( voter_name, proxy, producers, true ); @@ -176,7 +176,7 @@ namespace eosiosystem { } } - void system_contract::update_votes( const name voter_name, const name proxy, const std::vector& producers, bool voting ) { + void system_contract::update_votes( const name& voter_name, const name& proxy, const std::vector& producers, bool voting ) { //validate input if ( proxy ) { check( producers.size() == 0, "cannot vote for producers and proxy at same time" ); @@ -301,7 +301,7 @@ namespace eosiosystem { }); } - void system_contract::regproxy( const name proxy, bool isproxy ) { + void system_contract::regproxy( const name& proxy, bool isproxy ) { require_auth( proxy ); auto pitr = _voters.find( proxy.value ); From 7245b881c79b087189a8f5049dd349205adf9ef0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 19 Apr 2019 16:14:14 -0400 Subject: [PATCH 0788/1048] Update token documentation --- contracts/eosio.token/include/eosio.token/eosio.token.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index ecdcc3b7..ee4c3e0b 100755 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -53,7 +53,7 @@ namespace eosio { * * @details This action issues to `to` account a `quantity` of tokens. * - * @param to - the account to issue tokens to, + * @param to - the account to issue tokens to, it must be the same as the issuer, * @param quntity - the amount of tokens to be issued, * @memo - the memo string that accompanies the token issue transaction. */ From cad0c500785abdefd0b206c3dfa6ce62381af0b5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 19 Apr 2019 16:42:15 -0400 Subject: [PATCH 0789/1048] Changes following @arhag code review --- .../include/eosio.system/exchange_state.hpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index c29bb46b..94509c72 100755 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -32,10 +32,20 @@ namespace eosiosystem { uint64_t primary_key()const { return supply.symbol.raw(); } - asset convert_to_exchange( connector& c, const asset& in ); - asset convert_from_exchange( connector& c, const asset& in ); + asset convert_to_exchange( connector& reserve, const asset& payment ); + asset convert_from_exchange( connector& reserve, const asset& tokens ); asset convert( const asset& from, const symbol& to ); asset direct_convert( const asset& from, const symbol& to ); + /** + * Given two connector balances (inp_reserve and out_reserve), and an incoming amount + * of inp, this function calculates the delta out using Banacor equation. + * + * @param inp - input amount, same units as inp_reserve + * @param inp_reserve - the input connector balance + * @param out_reserve - the output connector balance + * + * @return int64_t - conversion output amount + */ static int64_t get_bancor_output( int64_t inp_reserve, int64_t out_reserve, int64_t inp ); From 088ec8a04b2965791fdd56be727a03b1e9eb7a38 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 19 Apr 2019 18:54:17 -0400 Subject: [PATCH 0790/1048] Changes following code review --- .../include/eosio.system/eosio.system.hpp | 2 +- .../include/eosio.system/native.hpp | 38 +++++++++--------- contracts/eosio.system/src/eosio.system.cpp | 8 ++-- contracts/eosio.system/src/producer_pay.cpp | 2 +- tests/eosio.system_tester.hpp | 40 ++++++++++++------- tests/eosio.system_tests.cpp | 3 +- 6 files changed, 52 insertions(+), 41 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 84cea782..4e40ad41 100755 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -549,7 +549,7 @@ namespace eosiosystem { * @param header - the block header produced. */ [[eosio::action]] - void onblock( const ignore& header ); + void onblock( ignore header ); /** * Set account limits action. diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index bb1ac566..5d77d256 100755 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -187,10 +187,10 @@ namespace eosiosystem { * an amount equal to the current new account creation fee. */ [[eosio::action]] - void newaccount( const name& creator, - const name& name, - const ignore& owner, - const ignore& active); + void newaccount( const name& creator, + const name& name, + ignore owner, + ignore active); /** * Update authorization action. @@ -203,10 +203,10 @@ namespace eosiosystem { * @param aut - the json describing the permission authorization */ [[eosio::action]] - void updateauth( const ignore& account, - const ignore& permission, - const ignore& parent, - const ignore& auth ) {} + void updateauth( ignore account, + ignore permission, + ignore parent, + ignore auth ) {} /** * Delete authorization action. @@ -217,8 +217,8 @@ namespace eosiosystem { * @param permission - the permission name been deleted. */ [[eosio::action]] - void deleteauth( const ignore& account, - const ignore& permission ) {} + void deleteauth( ignore account, + ignore permission ) {} /** * Link authorization action. @@ -238,10 +238,10 @@ namespace eosiosystem { * @param requirement - the permission to be linked. */ [[eosio::action]] - void linkauth( const ignore& account, - const ignore& code, - const ignore& type, - const ignore& requirement ) {} + void linkauth( ignore account, + ignore code, + ignore type, + ignore requirement ) {} /** * Unlink authorization action. @@ -253,9 +253,9 @@ namespace eosiosystem { * @param type - the action to be unlinked. */ [[eosio::action]] - void unlinkauth( const ignore& account, - const ignore& code, - const ignore& type ) {} + void unlinkauth( ignore account, + ignore code, + ignore type ) {} /** * Cancel delay action. @@ -266,7 +266,7 @@ namespace eosiosystem { * @param trx_id - the deferred transaction id to be cancelled. */ [[eosio::action]] - void canceldelay( const ignore& canceling_auth, const ignore& trx_id ) {} + void canceldelay( ignore canceling_auth, ignore trx_id ) {} /** * On error action. @@ -277,7 +277,7 @@ namespace eosiosystem { * @param sent_trx - the transaction that failed. */ [[eosio::action]] - void onerror( const ignore& sender_id, const ignore>& sent_trx ) {} + void onerror( ignore sender_id, ignore> sent_trx ) {} /** * Set abi action. diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 711552fd..1eec7c1a 100755 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -371,10 +371,10 @@ namespace eosiosystem { * who can create accounts with the creator's name as a suffix. * */ - void native::newaccount( const name& creator, - const name& newact, - const ignore& owner, - const ignore& active ) { + void native::newaccount( const name& creator, + const name& newact, + ignore owner, + ignore active ) { if( creator != _self ) { uint64_t tmp = newact.value >> 4; diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 80b27bfb..f2fc0303 100755 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -16,7 +16,7 @@ namespace eosiosystem { const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); const int64_t useconds_per_year = seconds_per_year*1000000ll; - void system_contract::onblock( const ignore& ) { + void system_contract::onblock( ignore ) { using namespace eosio; require_auth(_self); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index b1ad4c99..68baec76 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -54,7 +54,7 @@ class eosio_system_tester : public TESTER { void create_core_token( symbol core_symbol = symbol{CORE_SYM} ) { FC_ASSERT( core_symbol.precision() != 4, "create_core_token assumes precision of core token is 4" ); create_currency( N(eosio.token), config::system_account_name, asset(100000000000000, core_symbol) ); - issue(config::system_account_name, asset(10000000000000, core_symbol) ); + issue( asset(10000000000000, core_symbol) ); BOOST_REQUIRE_EQUAL( asset(10000000000000, core_symbol), get_balance( "eosio", core_symbol ) ); } @@ -752,11 +752,11 @@ class eosio_system_tester : public TESTER { base_tester::push_action(contract, N(create), contract, act ); } - void issue( const name& to, const asset& amount, const name& manager = config::system_account_name ) { + void issue( const asset& amount, const name& manager = config::system_account_name ) { base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() - ("to", to ) + ("to", manager ) ("quantity", amount ) - ("memo", "") + ("memo", "") ); } @@ -770,17 +770,29 @@ class eosio_system_tester : public TESTER { } void issue_and_transfer( const name& to, const asset& amount, const name& manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() - ("to", manager ) - ("quantity", amount ) - ("memo", "") - ); - base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() - ("from", manager) - ("to", to ) - ("quantity", amount) - ("memo", "") + signed_transaction trx; + trx.actions.emplace_back( get_action( N(eosio.token), N(issue), + vector{{manager, config::active_name}}, + mutable_variant_object() + ("to", manager ) + ("quantity", amount ) + ("memo", "") + ) ); + if ( to != manager ) { + trx.actions.emplace_back( get_action( N(eosio.token), N(transfer), + vector{{manager, config::active_name}}, + mutable_variant_object() + ("from", manager) + ("to", to ) + ("quantity", amount ) + ("memo", "") + ) + ); + } + set_transaction_headers( trx ); + trx.sign( get_private_key( manager, "active" ), control->get_chain_id() ); + push_transaction( trx ); } double stake2votes( asset stake ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d01355dc..340bbd10 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -189,7 +189,6 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try { cross_15_percent_threshold(); - issue_and_transfer( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //eosio stakes for alice with transfer flag @@ -4860,7 +4859,7 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { const name b1{ N(b1) }; - issue_and_transfer( alice, core_sym::from_string("10000.0000"), config::system_account_name ); + issue_and_transfer( alice, core_sym::from_string("20000.0000"), config::system_account_name ); issue_and_transfer( bob, core_sym::from_string("20000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), bidname( bob, b1, core_sym::from_string( "0.5000" ) ) ); BOOST_REQUIRE_EQUAL( success(), bidname( alice, b1, core_sym::from_string( "1.0000" ) ) ); From 8a2a6bb309dae941298887ba99f466ccd907245b Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 19 Apr 2019 19:00:14 -0400 Subject: [PATCH 0791/1048] Changes following code review - 2 --- tests/eosio.system_tests.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 340bbd10..cd6bc62c 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -254,11 +254,9 @@ BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { cross_15_percent_threshold(); - issue_and_transfer( "eosio.stake", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); //eosio stakes for alice with transfer flag - transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); From 5e2733f06182c1a5f31df1c3c5a3655b707894ae Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 25 Apr 2019 16:01:31 -0400 Subject: [PATCH 0792/1048] bump version to v1.7.0-rc1 --- CMakeLists.txt | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 11c28dab..1e20245c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 7) set(VERSION_PATCH 0) -set(VERSION_SUFFIX develop) +set(VERSION_SUFFIX rc1) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 0e07153f..dd735544 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.6.0 +## Version : 1.7.0-rc1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. @@ -15,8 +15,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.token) Dependencies: -* [eosio v1.7.x](https://github.com/EOSIO/eos/releases/tag/v1.7.0) -* [eosio.cdt v1.5.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.5.0) +* [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.0-rc1) +* [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.1) To build the contracts and the unit tests: * First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. From 0665d771be1d29bd1884424358b2fad8c573ffb8 Mon Sep 17 00:00:00 2001 From: johndebord Date: Fri, 26 Apr 2019 19:16:41 -0400 Subject: [PATCH 0793/1048] Start of updating contracts to `v1.6.1` --- contracts/eosio.bios/CMakeLists.txt | 2 + .../include/eosio.bios/eosio.bios.hpp | 34 +- .../ricardian/eosio.bios.contracts.md | 149 +++++ contracts/eosio.bios/src/eosio.bios.cpp | 0 contracts/eosio.msig/CMakeLists.txt | 2 + .../ricardian/eosio.msig.contracts.md | 59 ++ contracts/eosio.system/CMakeLists.txt | 2 + .../ricardian/eosio.system.contracts.md | 529 ++++++++++++++++++ contracts/eosio.token/CMakeLists.txt | 2 + .../ricardian/eosio.token.contracts.md | 59 ++ contracts/eosio.wrap/CMakeLists.txt | 2 + .../ricardian/eosio.wrap.contracts.md | 9 + 12 files changed, 832 insertions(+), 17 deletions(-) mode change 100755 => 100644 contracts/eosio.bios/CMakeLists.txt mode change 100755 => 100644 contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp create mode 100644 contracts/eosio.bios/ricardian/eosio.bios.contracts.md mode change 100755 => 100644 contracts/eosio.bios/src/eosio.bios.cpp mode change 100755 => 100644 contracts/eosio.msig/CMakeLists.txt create mode 100644 contracts/eosio.msig/ricardian/eosio.msig.contracts.md mode change 100755 => 100644 contracts/eosio.system/CMakeLists.txt create mode 100644 contracts/eosio.system/ricardian/eosio.system.contracts.md mode change 100755 => 100644 contracts/eosio.token/CMakeLists.txt create mode 100644 contracts/eosio.token/ricardian/eosio.token.contracts.md mode change 100755 => 100644 contracts/eosio.wrap/CMakeLists.txt create mode 100644 contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md diff --git a/contracts/eosio.bios/CMakeLists.txt b/contracts/eosio.bios/CMakeLists.txt old mode 100755 new mode 100644 index b8ce19a5..51e5de8e --- a/contracts/eosio.bios/CMakeLists.txt +++ b/contracts/eosio.bios/CMakeLists.txt @@ -7,3 +7,5 @@ target_include_directories(eosio.bios set_target_properties(eosio.bios PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp old mode 100755 new mode 100644 index 3bdb9148..455ffb8b --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -1,19 +1,19 @@ #pragma once -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include namespace eosio { namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); + bool is_feature_activated( const checksum256* feature_digest ); __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); + void preactivate_feature( const checksum256* feature_digest ); } } } @@ -22,14 +22,14 @@ namespace eosio { bool is_feature_activated( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } void preactivate_feature( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } } @@ -137,9 +137,9 @@ namespace eosio { uint32_t timestamp; name producer; uint16_t confirmed = 0; - capi_checksum256 previous; - capi_checksum256 transaction_mroot; - capi_checksum256 action_mroot; + checksum256 previous; + checksum256 transaction_mroot; + checksum256 action_mroot; uint32_t schedule_version = 0; std::optional new_producers; @@ -261,7 +261,7 @@ namespace eosio { * @param trx_id - the deferred transaction id to be cancelled. */ [[eosio::action]] - void canceldelay( ignore canceling_auth, ignore trx_id ) {} + void canceldelay( ignore canceling_auth, ignore trx_id ) {} /** * On error action. @@ -299,7 +299,7 @@ namespace eosio { [[eosio::action]] void setpriv( name account, uint8_t is_priv ) { require_auth( _self ); - set_privileged( account.value, is_priv ); + set_privileged( account, is_priv ); } /** @@ -315,7 +315,7 @@ namespace eosio { [[eosio::action]] void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { require_auth( _self ); - set_resource_limits( account.value, ram_bytes, net_weight, cpu_weight ); + set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); } /** @@ -440,7 +440,7 @@ namespace eosio { */ struct [[eosio::table]] abi_hash { name owner; - capi_checksum256 hash; + checksum256 hash; uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) diff --git a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md new file mode 100644 index 00000000..75346968 --- /dev/null +++ b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md @@ -0,0 +1,149 @@ +

canceldelay

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

deleteauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

linkauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

newaccount

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

onerror

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

reqauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setabi

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setalimits

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setcode

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setglimits

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setparams

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setpriv

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setprods

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

unlinkauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

updateauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp old mode 100755 new mode 100644 diff --git a/contracts/eosio.msig/CMakeLists.txt b/contracts/eosio.msig/CMakeLists.txt old mode 100755 new mode 100644 index 089587f2..2b85470c --- a/contracts/eosio.msig/CMakeLists.txt +++ b/contracts/eosio.msig/CMakeLists.txt @@ -7,3 +7,5 @@ target_include_directories(eosio.msig set_target_properties(eosio.msig PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +target_compile_options( eosio.msig PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) diff --git a/contracts/eosio.msig/ricardian/eosio.msig.contracts.md b/contracts/eosio.msig/ricardian/eosio.msig.contracts.md new file mode 100644 index 00000000..6e1f55f1 --- /dev/null +++ b/contracts/eosio.msig/ricardian/eosio.msig.contracts.md @@ -0,0 +1,59 @@ +

approve

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

cancel

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

exec

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

invalidate

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

propose

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

unapprove

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt old mode 100755 new mode 100644 index de993ef0..01683ede --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -18,3 +18,5 @@ target_include_directories(rex.results set_target_properties(rex.results PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.rex") + +target_compile_options( eosio.system PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md b/contracts/eosio.system/ricardian/eosio.system.contracts.md new file mode 100644 index 00000000..01198d1f --- /dev/null +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md @@ -0,0 +1,529 @@ +

bidname

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

bidrefund

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

buyram

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

buyrambytes

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

buyrex

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

canceldelay

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

claimrewards

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

closerex

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

cnclrexorder

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

consolidate

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

defcpuloan

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

defnetloan

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

delegatebw

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

deleteauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

deposit

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

fundcpuloan

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

fundnetloan

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

init

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

linkauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

newaccount

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

mvfrsavings

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

mvtosavings

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

onblock

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

onerror

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

refund

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

regproducer

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

regproxy

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

rentcpu

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

rentnet

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

rexexec

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

rmvproducer

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

sellram

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

sellrex

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setabi

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setacctcpu

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setacctnet

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setacctram

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setalimits

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setcode

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setparams

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setpriv

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setram

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setramrate

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

setrex

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

undelegatebw

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

unlinkauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

unregprod

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

unstaketorex

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

updateauth

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

updaterex

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

updtrevision

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

voteproducer

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

withdraw

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY diff --git a/contracts/eosio.token/CMakeLists.txt b/contracts/eosio.token/CMakeLists.txt old mode 100755 new mode 100644 index 25c56b51..406e046f --- a/contracts/eosio.token/CMakeLists.txt +++ b/contracts/eosio.token/CMakeLists.txt @@ -7,3 +7,5 @@ target_include_directories(eosio.token set_target_properties(eosio.token PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) diff --git a/contracts/eosio.token/ricardian/eosio.token.contracts.md b/contracts/eosio.token/ricardian/eosio.token.contracts.md new file mode 100644 index 00000000..8245071a --- /dev/null +++ b/contracts/eosio.token/ricardian/eosio.token.contracts.md @@ -0,0 +1,59 @@ +

close

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

create

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

issue

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

open

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

retire

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY + +

transfer

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY diff --git a/contracts/eosio.wrap/CMakeLists.txt b/contracts/eosio.wrap/CMakeLists.txt old mode 100755 new mode 100644 index 6d064bff..69377ff6 --- a/contracts/eosio.wrap/CMakeLists.txt +++ b/contracts/eosio.wrap/CMakeLists.txt @@ -7,3 +7,5 @@ target_include_directories(eosio.wrap set_target_properties(eosio.wrap PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") + +target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) diff --git a/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md b/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md new file mode 100644 index 00000000..65a62155 --- /dev/null +++ b/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md @@ -0,0 +1,9 @@ +

exec

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY \ No newline at end of file From ebcfa1b1df9133be3985e84c689c3cb1789a974f Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 29 Apr 2019 11:40:35 -0400 Subject: [PATCH 0794/1048] update eosio dependency to release/1.8.x branch --- dependencies | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dependencies b/dependencies index bcf78633..94801f14 100644 --- a/dependencies +++ b/dependencies @@ -1,3 +1,3 @@ # dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=9dfd8e2e1b2ab9acc9087b5c6a0bb878b4ad1d0f +eosio=release/1.8.x cdt=release/1.6.x From 3104ddde5a9fb08b837deabe9368790987c25346 Mon Sep 17 00:00:00 2001 From: johndebord Date: Mon, 29 Apr 2019 14:00:53 -0400 Subject: [PATCH 0795/1048] Finish updating `eosio.bios`, `eosio.msig`, `eosio.token`, and `eosio.wrap` --- contracts/CMakeLists.txt | 2 +- .../include/eosio.bios/eosio.bios.hpp | 11 +++----- .../include/eosio.msig/eosio.msig.hpp | 7 ++--- contracts/eosio.msig/src/eosio.msig.cpp | 26 +++++++++---------- .../include/eosio.token/eosio.token.hpp | 4 +-- contracts/eosio.token/src/eosio.token.cpp | 0 .../include/eosio.wrap/eosio.wrap.hpp | 6 ++--- contracts/eosio.wrap/src/eosio.wrap.cpp | 2 +- 8 files changed, 27 insertions(+), 31 deletions(-) mode change 100755 => 100644 contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp mode change 100755 => 100644 contracts/eosio.msig/src/eosio.msig.cpp mode change 100755 => 100644 contracts/eosio.token/include/eosio.token/eosio.token.hpp mode change 100755 => 100644 contracts/eosio.token/src/eosio.token.cpp mode change 100755 => 100644 contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp mode change 100755 => 100644 contracts/eosio.wrap/src/eosio.wrap.cpp diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt index fb59ebf6..45664ee4 100644 --- a/contracts/CMakeLists.txt +++ b/contracts/CMakeLists.txt @@ -7,6 +7,6 @@ find_package(eosio.cdt) add_subdirectory(eosio.bios) add_subdirectory(eosio.msig) -add_subdirectory(eosio.system) +#add_subdirectory(eosio.system) add_subdirectory(eosio.token) add_subdirectory(eosio.wrap) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 455ffb8b..bb251841 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -348,12 +348,7 @@ namespace eosio { void setprods( std::vector schedule ) { (void)schedule; // schedule argument just forces the deserialization of the action data into vector (necessary check) require_auth( _self ); - - constexpr size_t max_stack_buffer_size = 512; - size_t size = action_data_size(); - char* buffer = (char*)( max_stack_buffer_size < size ? malloc(size) : alloca(size) ); - read_action_data( buffer, size ); - set_proposed_producers(buffer, size); + set_proposed_producers( schedule ); } /** @@ -424,11 +419,11 @@ namespace eosio { if( itr == table.end() ) { table.emplace( account, [&]( auto& row ) { row.owner = account; - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast( abi.data()), abi.size() ); }); } else { table.modify( itr, same_payer, [&]( auto& row ) { - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast( abi.data()), abi.size() ); }); } } diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp old mode 100755 new mode 100644 index bb22cea0..e29f1c89 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -1,7 +1,8 @@ #pragma once -#include -#include -#include +#include +#include +#include +#include namespace eosio { /** diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp old mode 100755 new mode 100644 index 1a9ca4e0..19735567 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -1,7 +1,7 @@ #include -#include -#include -#include +#include +#include +#include namespace eosio { @@ -14,7 +14,7 @@ namespace eosio { * from 1970 until the current time. */ time_point current_time_point() { - const static time_point ct{ microseconds{ static_cast( current_time() ) } }; + const static time_point ct{ current_time_point() }; return ct; } @@ -42,10 +42,10 @@ void multisig::propose( ignore proposer, check( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); auto packed_requested = pack(_requested); - auto res = ::check_transaction_authorization( trx_pos, size, - (const char*)0, 0, - packed_requested.data(), packed_requested.size() - ); + auto res = check_transaction_authorization( trx_pos, size, + (const char*)0, 0, + packed_requested.data(), packed_requested.size() + ); check( res > 0, "transaction authorization failed" ); std::vector pkd_trans; @@ -184,13 +184,13 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { old_apptable.erase(apps); } auto packed_provided_approvals = pack(approvals); - auto res = ::check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), - (const char*)0, 0, - packed_provided_approvals.data(), packed_provided_approvals.size() - ); + auto res = check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), + (const char*)0, 0, + packed_provided_approvals.data(), packed_provided_approvals.size() + ); check( res > 0, "transaction authorization failed" ); - send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer.value, + send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer, prop.packed_transaction.data(), prop.packed_transaction.size() ); proptable.erase(prop); diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp old mode 100755 new mode 100644 index ee4c3e0b..c6cee4d8 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -4,8 +4,8 @@ */ #pragma once -#include -#include +#include +#include #include diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp old mode 100755 new mode 100644 diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp old mode 100755 new mode 100644 index c887df43..9cef06f6 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -1,8 +1,8 @@ #pragma once -#include -#include -#include +#include +#include +#include namespace eosio { /** diff --git a/contracts/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp old mode 100755 new mode 100644 index d8a03446..debbce11 --- a/contracts/eosio.wrap/src/eosio.wrap.cpp +++ b/contracts/eosio.wrap/src/eosio.wrap.cpp @@ -10,7 +10,7 @@ void wrap::exec( ignore, ignore ) { require_auth( executer ); - send_deferred( (uint128_t(executer.value) << 64) | current_time(), executer.value, _ds.pos(), _ds.remaining() ); + send_deferred( (uint128_t(executer.value) << 64) | (uint64_t)current_time_point().time_since_epoch().count(), executer, _ds.pos(), _ds.remaining() ); } } /// namespace eosio From b94b56f5741255d49d1bca033fe3630b06f6f97c Mon Sep 17 00:00:00 2001 From: johndebord Date: Mon, 29 Apr 2019 16:25:54 -0400 Subject: [PATCH 0796/1048] Start of updating contract `eosio.system` --- contracts/CMakeLists.txt | 2 +- .../include/eosio.system/eosio.system.hpp | 9 +++-- .../include/eosio.system/exchange_state.hpp | 2 +- .../include/eosio.system/native.hpp | 35 +++++++++--------- .../include/eosio.system/rex.results.hpp | 6 +-- .../eosio.system/src/delegate_bandwidth.cpp | 37 ++++++++++++------- contracts/eosio.system/src/eosio.system.cpp | 28 +++++++------- contracts/eosio.system/src/exchange_state.cpp | 0 contracts/eosio.system/src/producer_pay.cpp | 0 contracts/eosio.system/src/rex.cpp | 4 +- contracts/eosio.system/src/voting.cpp | 22 +++++------ 11 files changed, 78 insertions(+), 67 deletions(-) mode change 100755 => 100644 contracts/eosio.system/include/eosio.system/eosio.system.hpp mode change 100755 => 100644 contracts/eosio.system/include/eosio.system/exchange_state.hpp mode change 100755 => 100644 contracts/eosio.system/include/eosio.system/native.hpp mode change 100755 => 100644 contracts/eosio.system/src/delegate_bandwidth.cpp mode change 100755 => 100644 contracts/eosio.system/src/eosio.system.cpp mode change 100755 => 100644 contracts/eosio.system/src/exchange_state.cpp mode change 100755 => 100644 contracts/eosio.system/src/producer_pay.cpp mode change 100755 => 100644 contracts/eosio.system/src/voting.cpp diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt index 45664ee4..fb59ebf6 100644 --- a/contracts/CMakeLists.txt +++ b/contracts/CMakeLists.txt @@ -7,6 +7,6 @@ find_package(eosio.cdt) add_subdirectory(eosio.bios) add_subdirectory(eosio.msig) -#add_subdirectory(eosio.system) +add_subdirectory(eosio.system) add_subdirectory(eosio.token) add_subdirectory(eosio.wrap) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp old mode 100755 new mode 100644 index 4e40ad41..44a03fd6 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -5,10 +5,10 @@ #pragma once #include -#include -#include -#include -#include +#include +#include +#include +#include #include #include @@ -38,6 +38,7 @@ namespace eosiosystem { using eosio::microseconds; using eosio::datastream; using eosio::check; + using eosio::unsigned_int; template static inline auto has_field( F flags, E field ) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp old mode 100755 new mode 100644 index 94509c72..d3c5e06a --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -1,6 +1,6 @@ #pragma once -#include +#include namespace eosiosystem { using eosio::asset; diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp old mode 100755 new mode 100644 index 5d77d256..566ed8c9 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -4,23 +4,23 @@ */ #pragma once -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include namespace eosio { namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); + bool is_feature_activated( const eosio::checksum256* feature_digest ); __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); + void preactivate_feature( const eosio::checksum256* feature_digest ); } } } @@ -29,19 +29,20 @@ namespace eosio { bool is_feature_activated( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } void preactivate_feature( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } } namespace eosiosystem { + using eosio::checksum256; using eosio::name; using eosio::permission_level; using eosio::public_key; @@ -127,9 +128,9 @@ namespace eosiosystem { uint32_t timestamp; name producer; uint16_t confirmed = 0; - capi_checksum256 previous; - capi_checksum256 transaction_mroot; - capi_checksum256 action_mroot; + checksum256 previous; + checksum256 transaction_mroot; + checksum256 action_mroot; uint32_t schedule_version = 0; std::optional new_producers; @@ -147,7 +148,7 @@ namespace eosiosystem { */ struct [[eosio::table("abihash"), eosio::contract("eosio.system")]] abi_hash { name owner; - capi_checksum256 hash; + checksum256 hash; uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) @@ -266,7 +267,7 @@ namespace eosiosystem { * @param trx_id - the deferred transaction id to be cancelled. */ [[eosio::action]] - void canceldelay( ignore canceling_auth, ignore trx_id ) {} + void canceldelay( ignore canceling_auth, ignore trx_id ) {} /** * On error action. diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index d1ba0fb0..124ef21c 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -1,8 +1,8 @@ #pragma once -#include -#include -#include +#include +#include +#include using eosio::name; using eosio::asset; diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp old mode 100755 new mode 100644 index 3fe90fad..d9ca1eab --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -4,12 +4,12 @@ */ #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include #include @@ -161,8 +161,11 @@ namespace eosiosystem { auto voter_itr = _voters.find( res_itr->owner.value ); if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { int64_t ram_bytes, net, cpu; - get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); - set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); + // get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); + get_resource_limits( res_itr->owner, ram_bytes, net, cpu ); + + // set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); } } @@ -205,8 +208,10 @@ namespace eosiosystem { auto voter_itr = _voters.find( res_itr->owner.value ); if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { int64_t ram_bytes, net, cpu; - get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); - set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); + // get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); + get_resource_limits( res_itr->owner, ram_bytes, net, cpu ); + // set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); + set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); } { @@ -225,7 +230,7 @@ namespace eosiosystem { void validate_b1_vesting( int64_t stake ) { const int64_t base_time = 1527811200; /// 2018-06-01 const int64_t max_claimable = 100'000'000'0000ll; - const int64_t claimable = int64_t(max_claimable * double(now()-base_time) / (10*seconds_per_year) ); + const int64_t claimable = int64_t(max_claimable * double(current_block_time().to_time_point().time_since_epoch().count()-base_time) / (10*seconds_per_year) ); check( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } @@ -302,9 +307,15 @@ namespace eosiosystem { if( !(net_managed && cpu_managed) ) { int64_t ram_bytes, net, cpu; - get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); + // get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); + get_resource_limits( receiver, ram_bytes, net, cpu ); - set_resource_limits( receiver.value, + // set_resource_limits( receiver.value, + // ram_managed ? ram_bytes : std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), + // net_managed ? net : tot_itr->net_weight.amount, + // cpu_managed ? cpu : tot_itr->cpu_weight.amount ); + + set_resource_limits( receiver, ram_managed ? ram_bytes : std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), net_managed ? net : tot_itr->net_weight.amount, cpu_managed ? cpu : tot_itr->cpu_weight.amount ); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp old mode 100755 new mode 100644 index 1eec7c1a..87f37387 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -1,6 +1,6 @@ #include -#include -#include +#include +#include #include "producer_pay.cpp" #include "delegate_bandwidth.cpp" @@ -37,7 +37,7 @@ namespace eosiosystem { } time_point system_contract::current_time_point() { - const static time_point ct{ microseconds{ static_cast( current_time() ) } }; + const static time_point ct{ current_time_point() }; return ct; } @@ -116,7 +116,7 @@ namespace eosiosystem { void system_contract::setpriv( const name& account, uint8_t ispriv ) { require_auth( _self ); - set_privileged( account.value, ispriv ); + set_privileged( account, ispriv ); } void system_contract::setalimits( const name& account, int64_t ram, int64_t net, int64_t cpu ) { @@ -134,14 +134,14 @@ namespace eosiosystem { check( !(ram_managed || net_managed || cpu_managed), "cannot use setalimits on an account with managed resources" ); } - set_resource_limits( account.value, ram, net, cpu ); + set_resource_limits( account, ram, net, cpu ); } void system_contract::setacctram( const name& account, const std::optional& ram_bytes ) { require_auth( _self ); int64_t current_ram, current_net, current_cpu; - get_resource_limits( account.value, ¤t_ram, ¤t_net, ¤t_cpu ); + get_resource_limits( account, current_ram, current_net, current_cpu ); int64_t ram = 0; @@ -179,14 +179,14 @@ namespace eosiosystem { ram = *ram_bytes; } - set_resource_limits( account.value, ram, current_net, current_cpu ); + set_resource_limits( account, ram, current_net, current_cpu ); } void system_contract::setacctnet( const name& account, const std::optional& net_weight ) { require_auth( _self ); int64_t current_ram, current_net, current_cpu; - get_resource_limits( account.value, ¤t_ram, ¤t_net, ¤t_cpu ); + get_resource_limits( account, current_ram, current_net, current_cpu ); int64_t net = 0; @@ -223,14 +223,14 @@ namespace eosiosystem { net = *net_weight; } - set_resource_limits( account.value, current_ram, net, current_cpu ); + set_resource_limits( account, current_ram, net, current_cpu ); } void system_contract::setacctcpu( const name& account, const std::optional& cpu_weight ) { require_auth( _self ); int64_t current_ram, current_net, current_cpu; - get_resource_limits( account.value, ¤t_ram, ¤t_net, ¤t_cpu ); + get_resource_limits( account, current_ram, current_net, current_cpu ); int64_t cpu = 0; @@ -267,7 +267,7 @@ namespace eosiosystem { cpu = *cpu_weight; } - set_resource_limits( account.value, current_ram, current_net, cpu ); + set_resource_limits( account, current_ram, current_net, cpu ); } void system_contract::activate( const eosio::checksum256& feature_digest ) { @@ -407,7 +407,7 @@ namespace eosiosystem { res.cpu_weight = asset( 0, system_contract::get_core_symbol() ); }); - set_resource_limits( newact.value, 0, 0, 0 ); + set_resource_limits( newact, 0, 0, 0 ); } void native::setabi( const name& acnt, const std::vector& abi ) { @@ -416,11 +416,11 @@ namespace eosiosystem { if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { row.owner= acnt; - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast(abi.data()), abi.size() ); }); } else { table.modify( itr, same_payer, [&]( auto& row ) { - sha256( const_cast(abi.data()), abi.size(), &row.hash ); + sha256( const_cast(abi.data()), abi.size() ); }); } } diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp old mode 100755 new mode 100644 diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp old mode 100755 new mode 100644 diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 06ebc5cc..57bebd3f 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -396,9 +396,9 @@ namespace eosiosystem { if( !(net_managed && cpu_managed) ) { int64_t ram_bytes = 0, net = 0, cpu = 0; - get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); + get_resource_limits( receiver, ram_bytes, net, cpu ); - set_resource_limits( receiver.value, + set_resource_limits( receiver, ram_bytes, net_managed ? net : tot_itr->net_weight.amount, cpu_managed ? cpu : tot_itr->cpu_weight.amount ); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp old mode 100755 new mode 100644 index 31d1dc98..340a5312 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -4,14 +4,14 @@ */ #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include @@ -102,16 +102,14 @@ namespace eosiosystem { for( const auto& item : top_producers ) producers.push_back(item.first); - auto packed_schedule = pack(producers); - - if( set_proposed_producers( packed_schedule.data(), packed_schedule.size() ) >= 0 ) { + if( set_proposed_producers( producers ) >= 0 ) { _gstate.last_producer_schedule_size = static_cast( top_producers.size() ); } } double stake2vote( int64_t staked ) { /// TODO subtract 2080 brings the large numbers closer to this decade - double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); + double weight = int64_t( ( current_block_time().to_time_point().time_since_epoch().count() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } From 10421e16f6ce18945138cd517b82a6189f091738 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 29 Apr 2019 22:08:36 -0400 Subject: [PATCH 0797/1048] Created universal pipeline configuration file --- pipeline.jsonc | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 pipeline.jsonc diff --git a/pipeline.jsonc b/pipeline.jsonc new file mode 100644 index 00000000..eeb1137f --- /dev/null +++ b/pipeline.jsonc @@ -0,0 +1,25 @@ +{ + "eosio-dot-contracts": + { + "pipeline-branch": "master", + "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash + { + "eosio": "release/1.8.x", + "eosio.cdt": "release/1.6.x" + } + }, + "eosio-dot-contracts-dot-beta": + { + "pipeline-branch": "zach-pipeline-config", + "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash + { + "eosio": "release/1.8.x", + "eosio.cdt": "release/1.6.x" + }, + "environment": + { + "TEST": "true", + "DEBUG": "false" + } + } +} \ No newline at end of file From 16200993c11257b88e59c8d41dfcafa96f74065e Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Mon, 29 Apr 2019 22:23:31 -0400 Subject: [PATCH 0798/1048] Removed dependencies file --- dependencies | 3 --- pipeline.jsonc | 5 ----- 2 files changed, 8 deletions(-) delete mode 100644 dependencies diff --git a/dependencies b/dependencies deleted file mode 100644 index 94801f14..00000000 --- a/dependencies +++ /dev/null @@ -1,3 +0,0 @@ -# dependencies to pull for a build of contracts, by branch, tag, or commit hash -eosio=release/1.8.x -cdt=release/1.6.x diff --git a/pipeline.jsonc b/pipeline.jsonc index eeb1137f..4b69f3eb 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -15,11 +15,6 @@ { "eosio": "release/1.8.x", "eosio.cdt": "release/1.6.x" - }, - "environment": - { - "TEST": "true", - "DEBUG": "false" } } } \ No newline at end of file From f3b21382b01627842a78df24d477d245effbe04d Mon Sep 17 00:00:00 2001 From: johndebord Date: Tue, 30 Apr 2019 12:40:00 -0400 Subject: [PATCH 0799/1048] Update contracts; getting ready to squash --- contracts/eosio.msig/src/eosio.msig.cpp | 9 ++++---- .../include/eosio.system/eosio.system.hpp | 4 ++-- contracts/eosio.system/src/eosio.system.cpp | 22 +++++++++++-------- contracts/eosio.system/src/voting.cpp | 2 +- 4 files changed, 21 insertions(+), 16 deletions(-) diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 19735567..90c94fa7 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -13,10 +13,11 @@ namespace eosio { * @details Returns a high resolution time_point which represents the number of microseconds * from 1970 until the current time. */ -time_point current_time_point() { - const static time_point ct{ current_time_point() }; - return ct; -} + +// time_point current_time_point() { +// const static time_point ct{ current_time_point() }; +// return ct; +// } void multisig::propose( ignore proposer, ignore proposal_name, diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 44a03fd6..49679b92 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1238,9 +1238,9 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); - static time_point current_time_point(); + // static time_point current_time_point(); static time_point_sec current_time_point_sec(); - static block_timestamp current_block_time(); + // static block_timestamp current_block_time(); symbol core_symbol()const; void update_ram_supply(); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 87f37387..a5980a7f 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "producer_pay.cpp" #include "delegate_bandwidth.cpp" @@ -36,20 +37,23 @@ namespace eosiosystem { return dp; } - time_point system_contract::current_time_point() { - const static time_point ct{ current_time_point() }; - return ct; - } + // time_point system_contract::current_time_point() { + // const static time_point ct{ current_time_point() }; + // return ct; + // } time_point_sec system_contract::current_time_point_sec() { - const static time_point_sec cts{ current_time_point() }; + // const static time_point_sec cts{ current_time_point().time_since_epoch().count() / 1000000LL }; + const static time_point_sec cts{current_time_point()}; return cts; } - block_timestamp system_contract::current_block_time() { - const static block_timestamp cbt{ current_time_point() }; - return cbt; - } + // uint32_t(t.time_since_epoch().count() / 1000000ll) + + // block_timestamp system_contract::current_block_time() { + // const static block_timestamp cbt{ current_time_point() }; + // return cbt; + // } symbol system_contract::core_symbol()const { const static auto sym = get_core_symbol( _rammarket ); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 340a5312..67fe5f69 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -207,7 +207,7 @@ namespace eosiosystem { new_vote_weight += voter->proxied_vote_weight; } - boost::container::flat_map > producer_deltas; + std::map > producer_deltas; if ( voter->last_vote_weight > 0 ) { if( voter->proxy ) { auto old_proxy = _voters.find( voter->proxy.value ); From 3b5599e30d7ce3646f219de44230536daffe5a64 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Tue, 30 Apr 2019 14:20:56 -0400 Subject: [PATCH 0800/1048] Removed beta-testing pipeline --- pipeline.jsonc | 9 --------- 1 file changed, 9 deletions(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 4b69f3eb..28912b07 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -7,14 +7,5 @@ "eosio": "release/1.8.x", "eosio.cdt": "release/1.6.x" } - }, - "eosio-dot-contracts-dot-beta": - { - "pipeline-branch": "zach-pipeline-config", - "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash - { - "eosio": "release/1.8.x", - "eosio.cdt": "release/1.6.x" - } } } \ No newline at end of file From 40fabaef78e985d36b69202609d08a6d049bd661 Mon Sep 17 00:00:00 2001 From: johndebord Date: Wed, 1 May 2019 15:02:19 -0400 Subject: [PATCH 0801/1048] Updating contracts --- .../include/eosio.system/eosio.system.hpp | 3 +- .../include/eosio.system/native.hpp | 34 +++++++++++-------- .../eosio.system/src/delegate_bandwidth.cpp | 13 +------ contracts/eosio.system/src/eosio.system.cpp | 14 ++------ contracts/eosio.system/src/rex.cpp | 5 +-- contracts/eosio.system/src/voting.cpp | 2 +- 6 files changed, 30 insertions(+), 41 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 49679b92..2dc16f05 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -1239,7 +1240,7 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); // static time_point current_time_point(); - static time_point_sec current_time_point_sec(); + // static time_point_sec current_time_point_sec(); // static block_timestamp current_block_time(); symbol core_symbol()const; void update_ram_supply(); diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 566ed8c9..eaa1be4f 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -13,31 +13,37 @@ #include #include +extern "C" { + struct __attribute__((aligned (16))) capi_checksum160 { uint8_t hash[20]; }; + struct __attribute__((aligned (16))) capi_checksum256 { uint8_t hash[32]; }; + struct __attribute__((aligned (16))) capi_checksum512 { uint8_t hash[64]; }; +} + namespace eosio { namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import)) - bool is_feature_activated( const eosio::checksum256* feature_digest ); + bool is_feature_activated( const ::capi_checksum256* feature_digest ); - __attribute__((eosio_wasm_import)) - void preactivate_feature( const eosio::checksum256* feature_digest ); + __attribute__((eosio_wasm_import)) + void preactivate_feature( const ::capi_checksum256* feature_digest ); } } } - namespace eosio { +namespace eosio { bool is_feature_activated( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); + reinterpret_cast( feature_digest_data.data() ) + ); } - void preactivate_feature( const eosio::checksum256& feature_digest ) { + void preactivate_feature( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); + reinterpret_cast( feature_digest_data.data() ) + ); } } @@ -128,9 +134,9 @@ namespace eosiosystem { uint32_t timestamp; name producer; uint16_t confirmed = 0; - checksum256 previous; - checksum256 transaction_mroot; - checksum256 action_mroot; + checksum256 previous; + checksum256 transaction_mroot; + checksum256 action_mroot; uint32_t schedule_version = 0; std::optional new_producers; @@ -148,7 +154,7 @@ namespace eosiosystem { */ struct [[eosio::table("abihash"), eosio::contract("eosio.system")]] abi_hash { name owner; - checksum256 hash; + checksum256 hash; uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) @@ -267,7 +273,7 @@ namespace eosiosystem { * @param trx_id - the deferred transaction id to be cancelled. */ [[eosio::action]] - void canceldelay( ignore canceling_auth, ignore trx_id ) {} + void canceldelay( ignore canceling_auth, ignore trx_id ) {} /** * On error action. diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index d9ca1eab..69249968 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -161,10 +161,7 @@ namespace eosiosystem { auto voter_itr = _voters.find( res_itr->owner.value ); if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { int64_t ram_bytes, net, cpu; - // get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); get_resource_limits( res_itr->owner, ram_bytes, net, cpu ); - - // set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); } } @@ -208,9 +205,7 @@ namespace eosiosystem { auto voter_itr = _voters.find( res_itr->owner.value ); if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { int64_t ram_bytes, net, cpu; - // get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu ); get_resource_limits( res_itr->owner, ram_bytes, net, cpu ); - // set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); } @@ -230,7 +225,7 @@ namespace eosiosystem { void validate_b1_vesting( int64_t stake ) { const int64_t base_time = 1527811200; /// 2018-06-01 const int64_t max_claimable = 100'000'000'0000ll; - const int64_t claimable = int64_t(max_claimable * double(current_block_time().to_time_point().time_since_epoch().count()-base_time) / (10*seconds_per_year) ); + const int64_t claimable = int64_t(max_claimable * double(current_time_point().time_since_epoch().count()-base_time) / (10*seconds_per_year) ); check( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } @@ -307,14 +302,8 @@ namespace eosiosystem { if( !(net_managed && cpu_managed) ) { int64_t ram_bytes, net, cpu; - // get_resource_limits( receiver.value, &ram_bytes, &net, &cpu ); get_resource_limits( receiver, ram_bytes, net, cpu ); - // set_resource_limits( receiver.value, - // ram_managed ? ram_bytes : std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), - // net_managed ? net : tot_itr->net_weight.amount, - // cpu_managed ? cpu : tot_itr->cpu_weight.amount ); - set_resource_limits( receiver, ram_managed ? ram_bytes : std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), net_managed ? net : tot_itr->net_weight.amount, diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index a5980a7f..d269a08a 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -37,19 +37,11 @@ namespace eosiosystem { return dp; } - // time_point system_contract::current_time_point() { - // const static time_point ct{ current_time_point() }; - // return ct; + // time_point_sec system_contract::current_time_point_sec() { + // const static time_point_sec cts{ current_time_point() }; + // return cts; // } - time_point_sec system_contract::current_time_point_sec() { - // const static time_point_sec cts{ current_time_point().time_since_epoch().count() / 1000000LL }; - const static time_point_sec cts{current_time_point()}; - return cts; - } - - // uint32_t(t.time_since_epoch().count() / 1000000ll) - // block_timestamp system_contract::current_block_time() { // const static block_timestamp cbt{ current_time_point() }; // return cbt; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 57bebd3f..a4142dcc 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -855,7 +855,8 @@ namespace eosiosystem { time_point_sec system_contract::get_rex_maturity() { const uint32_t num_of_maturity_buckets = 5; - static const uint32_t now = current_time_point_sec().utc_seconds; + // static const uint32_t now = current_time_point_sec().utc_seconds; + static const uint32_t now = current_time_point().sec_since_epoch(); static const uint32_t r = now % seconds_per_day; static const time_point_sec rms{ now - r + num_of_maturity_buckets * seconds_per_day }; return rms; @@ -868,7 +869,7 @@ namespace eosiosystem { */ void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) { - const time_point_sec now = current_time_point_sec(); + const time_point_sec now = current_time_point(); _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { rb.matured_rex += rb.rex_maturities.front().second; diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 67fe5f69..ce71f017 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -109,7 +109,7 @@ namespace eosiosystem { double stake2vote( int64_t staked ) { /// TODO subtract 2080 brings the large numbers closer to this decade - double weight = int64_t( ( current_block_time().to_time_point().time_since_epoch().count() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); + double weight = int64_t( (current_time_point().time_since_epoch().count() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } From 836e898e4e7b36f607e7c49fefd1798ba259da76 Mon Sep 17 00:00:00 2001 From: johndebord Date: Wed, 1 May 2019 16:38:04 -0400 Subject: [PATCH 0802/1048] Fix time discrepancy --- contracts/eosio.system/src/voting.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index ce71f017..f40ee9a2 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -109,7 +109,8 @@ namespace eosiosystem { double stake2vote( int64_t staked ) { /// TODO subtract 2080 brings the large numbers closer to this decade - double weight = int64_t( (current_time_point().time_since_epoch().count() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); + double weight = int64_t( (current_time_point().time_since_epoch().count() - (block_timestamp::block_timestamp_epoch / 1)) / (2000000ULL*seconds_per_day * 7) ) / double( 52 ); + // double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } From b6d04c0872734f8e26d30dfec6a23d890af9fef9 Mon Sep 17 00:00:00 2001 From: johndebord Date: Fri, 3 May 2019 17:35:22 -0400 Subject: [PATCH 0803/1048] Finish updating contracts --- .../include/eosio.bios/eosio.bios.hpp | 11 +++- contracts/eosio.bios/src/eosio.bios.cpp | 4 ++ .../include/eosio.msig/eosio.msig.hpp | 6 ++ contracts/eosio.msig/src/eosio.msig.cpp | 21 ++----- .../include/eosio.system/eosio.system.hpp | 25 ++++---- .../include/eosio.system/exchange_state.hpp | 5 ++ .../include/eosio.system/native.hpp | 61 ++++++++++++++----- .../include/eosio.system/rex.results.hpp | 10 ++- .../eosio.system/src/delegate_bandwidth.cpp | 14 ++--- contracts/eosio.system/src/eosio.system.cpp | 22 ++++--- contracts/eosio.system/src/exchange_state.cpp | 4 ++ contracts/eosio.system/src/producer_pay.cpp | 5 +- contracts/eosio.system/src/voting.cpp | 14 ++--- .../include/eosio.token/eosio.token.hpp | 2 +- contracts/eosio.token/src/eosio.token.cpp | 1 - .../include/eosio.wrap/eosio.wrap.hpp | 4 ++ contracts/eosio.wrap/src/eosio.wrap.cpp | 4 ++ 17 files changed, 138 insertions(+), 75 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index bb251841..dd36df42 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -1,4 +1,9 @@ +/** + * @copyright defined in eosio.cdt/LICENSE.txt + */ + #pragma once + #include #include #include @@ -55,9 +60,9 @@ namespace eosio { namespace eosio { + using eosio::ignore; using eosio::permission_level; using eosio::public_key; - using eosio::ignore; /** * A weighted permission. @@ -419,11 +424,11 @@ namespace eosio { if( itr == table.end() ) { table.emplace( account, [&]( auto& row ) { row.owner = account; - sha256( const_cast( abi.data()), abi.size() ); + row.hash = sha256(const_cast(abi.data()), abi.size()); }); } else { table.modify( itr, same_payer, [&]( auto& row ) { - sha256( const_cast( abi.data()), abi.size() ); + row.hash = sha256(const_cast(abi.data()), abi.size()); }); } } diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index fc8d2ff8..cc35446a 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,7 @@ +/** + * @copyright defined in eosio.cdt/LICENSE.txt + */ + #include EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi)(activate)(reqactivated) ) diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index e29f1c89..132b8c0c 100644 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -1,4 +1,9 @@ +/** + * @copyright defined in eosio.cdt/LICENSE.txt + */ + #pragma once + #include #include #include @@ -123,6 +128,7 @@ namespace eosio { using cancel_action = eosio::action_wrapper<"cancel"_n, &multisig::cancel>; using exec_action = eosio::action_wrapper<"exec"_n, &multisig::exec>; using invalidate_action = eosio::action_wrapper<"invalidate"_n, &multisig::invalidate>; + private: struct [[eosio::table]] proposal { name proposal_name; diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 90c94fa7..36567d08 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -1,23 +1,14 @@ -#include +/** + * @copyright defined in eosio.cdt/LICENSE.txt + */ + #include #include #include -namespace eosio { +#include -/** - * @ingroup eosiocontracts - * - * Returns a high resolution time_point - * - * @details Returns a high resolution time_point which represents the number of microseconds - * from 1970 until the current time. - */ - -// time_point current_time_point() { -// const static time_point ct{ current_time_point() }; -// return ct; -// } +namespace eosio { void multisig::propose( ignore proposer, ignore proposal_name, diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 2dc16f05..b03e3679 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1,21 +1,22 @@ /** - * @file * @copyright defined in eos/LICENSE.txt */ + #pragma once -#include #include -#include #include #include #include +#include + #include +#include -#include #include -#include #include +#include +#include #ifdef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX #undef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX @@ -27,18 +28,18 @@ namespace eosiosystem { - using eosio::name; using eosio::asset; + using eosio::block_timestamp; + using eosio::check; + using eosio::const_mem_fun; + using eosio::datastream; + using eosio::indexed_by; + using eosio::microseconds; + using eosio::name; using eosio::symbol; using eosio::symbol_code; - using eosio::indexed_by; - using eosio::const_mem_fun; - using eosio::block_timestamp; using eosio::time_point; using eosio::time_point_sec; - using eosio::microseconds; - using eosio::datastream; - using eosio::check; using eosio::unsigned_int; template diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index d3c5e06a..4c62e108 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -1,8 +1,13 @@ +/** + * @copyright defined in eos/LICENSE.txt + */ + #pragma once #include namespace eosiosystem { + using eosio::asset; using eosio::symbol; diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index eaa1be4f..cb6da0e7 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -1,32 +1,60 @@ /** - * @file * @copyright defined in eos/LICENSE.txt */ + #pragma once #include +#include #include +#include +#include #include #include #include -#include -#include -#include -extern "C" { - struct __attribute__((aligned (16))) capi_checksum160 { uint8_t hash[20]; }; - struct __attribute__((aligned (16))) capi_checksum256 { uint8_t hash[32]; }; - struct __attribute__((aligned (16))) capi_checksum512 { uint8_t hash[64]; }; -} +// extern "C" { +// struct __attribute__((aligned (16))) capi_checksum160 { uint8_t hash[20]; }; +// struct __attribute__((aligned (16))) capi_checksum256 { uint8_t hash[32]; }; +// struct __attribute__((aligned (16))) capi_checksum512 { uint8_t hash[64]; }; +// } + +// namespace eosio { +// namespace internal_use_do_not_use { +// extern "C" { +// __attribute__((eosio_wasm_import)) +// bool is_feature_activated( const ::capi_checksum256* feature_digest ); + +// __attribute__((eosio_wasm_import)) +// void preactivate_feature( const ::capi_checksum256* feature_digest ); +// } +// } +// } + +// namespace eosio { +// bool is_feature_activated( const eosio::checksum256& feature_digest ) { +// auto feature_digest_data = feature_digest.extract_as_byte_array(); +// return internal_use_do_not_use::is_feature_activated( +// reinterpret_cast( feature_digest_data.data() ) +// ); +// } + +// void preactivate_feature( const eosio::checksum256& feature_digest ) { +// auto feature_digest_data = feature_digest.extract_as_byte_array(); +// internal_use_do_not_use::preactivate_feature( +// reinterpret_cast( feature_digest_data.data() ) +// ); +// } +// } namespace eosio { namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); + bool is_feature_activated( const checksum256* feature_digest ); __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); + void preactivate_feature( const checksum256* feature_digest ); } } } @@ -35,24 +63,25 @@ namespace eosio { bool is_feature_activated( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } - void preactivate_feature( const eosio::checksum256& feature_digest ) { + void preactivate_feature( const checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } } namespace eosiosystem { + using eosio::checksum256; + using eosio::ignore; using eosio::name; using eosio::permission_level; using eosio::public_key; - using eosio::ignore; /** * @addtogroup eosiosystem @@ -273,7 +302,7 @@ namespace eosiosystem { * @param trx_id - the deferred transaction id to be cancelled. */ [[eosio::action]] - void canceldelay( ignore canceling_auth, ignore trx_id ) {} + void canceldelay( ignore canceling_auth, ignore trx_id ) {} /** * On error action. diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index 124ef21c..9d5fb6ba 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -1,12 +1,16 @@ +/** + * @copyright defined in eos/LICENSE.txt + */ + #pragma once +#include #include #include -#include -using eosio::name; -using eosio::asset; using eosio::action_wrapper; +using eosio::asset; +using eosio::name; class [[eosio::contract("rex.results")]] rex_results : eosio::contract { public: diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 69249968..9e6872a7 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -1,28 +1,28 @@ /** - * @file * @copyright defined in eos/LICENSE.txt */ -#include -#include #include -#include +#include #include #include +#include #include +#include #include - #include #include namespace eosiosystem { + using eosio::asset; - using eosio::indexed_by; using eosio::const_mem_fun; + using eosio::indexed_by; using eosio::permission_level; using eosio::time_point_sec; + using std::map; using std::pair; @@ -225,7 +225,7 @@ namespace eosiosystem { void validate_b1_vesting( int64_t stake ) { const int64_t base_time = 1527811200; /// 2018-06-01 const int64_t max_claimable = 100'000'000'0000ll; - const int64_t claimable = int64_t(max_claimable * double(current_time_point().time_since_epoch().count()-base_time) / (10*seconds_per_year) ); + const int64_t claimable = int64_t(max_claimable * double(current_time_point().time_since_epoch().count()/1000000 - base_time) / (10*seconds_per_year) ); check( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index d269a08a..fd357ec4 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -1,7 +1,11 @@ -#include -#include +/** + * @copyright defined in eos/LICENSE.txt + */ + #include -#include +#include + +#include #include "producer_pay.cpp" #include "delegate_bandwidth.cpp" @@ -406,17 +410,17 @@ namespace eosiosystem { set_resource_limits( newact, 0, 0, 0 ); } - void native::setabi( const name& acnt, const std::vector& abi ) { + void native::setabi( const name& account, const std::vector& abi ) { eosio::multi_index< "abihash"_n, abi_hash > table(_self, _self.value); - auto itr = table.find( acnt.value ); + auto itr = table.find( account.value ); if( itr == table.end() ) { - table.emplace( acnt, [&]( auto& row ) { - row.owner= acnt; - sha256( const_cast(abi.data()), abi.size() ); + table.emplace( account, [&]( auto& row ) { + row.owner = account; + row.hash = sha256(const_cast(abi.data()), abi.size()); }); } else { table.modify( itr, same_payer, [&]( auto& row ) { - sha256( const_cast(abi.data()), abi.size() ); + row.hash = sha256(const_cast(abi.data()), abi.size()); }); } } diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index 10fd11f8..23adba46 100644 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -1,3 +1,7 @@ +/** + * @copyright defined in eos/LICENSE.txt + */ + #include namespace eosiosystem { diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index f2fc0303..b5aba893 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -1,5 +1,8 @@ -#include +/** + * @copyright defined in eos/LICENSE.txt + */ +#include #include namespace eosiosystem { diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index f40ee9a2..37184cbc 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -1,25 +1,26 @@ /** - * @file * @copyright defined in eos/LICENSE.txt */ -#include -#include #include #include -#include +#include #include #include +#include #include #include + +#include #include #include #include namespace eosiosystem { - using eosio::indexed_by; + using eosio::const_mem_fun; + using eosio::indexed_by; using eosio::singleton; using eosio::transaction; @@ -109,8 +110,7 @@ namespace eosiosystem { double stake2vote( int64_t staked ) { /// TODO subtract 2080 brings the large numbers closer to this decade - double weight = int64_t( (current_time_point().time_since_epoch().count() - (block_timestamp::block_timestamp_epoch / 1)) / (2000000ULL*seconds_per_day * 7) ) / double( 52 ); - // double weight = int64_t( (now() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); + double weight = int64_t( (current_time_point().time_since_epoch().count()/1000000 - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index c6cee4d8..6ffb3f61 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -1,7 +1,7 @@ /** - * @file * @copyright defined in eos/LICENSE.txt */ + #pragma once #include diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index fd294ac3..74d68aa0 100644 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -1,5 +1,4 @@ /** - * @file * @copyright defined in eos/LICENSE.txt */ diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp index 9cef06f6..d66ef909 100644 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -1,3 +1,7 @@ +/** + * @copyright defined in eosio.cdt/LICENSE.txt + */ + #pragma once #include diff --git a/contracts/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp index debbce11..9f10cd52 100644 --- a/contracts/eosio.wrap/src/eosio.wrap.cpp +++ b/contracts/eosio.wrap/src/eosio.wrap.cpp @@ -1,3 +1,7 @@ +/** + * @copyright defined in eosio.cdt/LICENSE.txt + */ + #include namespace eosio { From 88a7f5917dfbc82213fd50735a5c0d6ee5dbfd8c Mon Sep 17 00:00:00 2001 From: johndebord Date: Fri, 3 May 2019 18:00:55 -0400 Subject: [PATCH 0804/1048] Quick fixes --- contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp | 8 ++++---- contracts/eosio.msig/src/eosio.msig.cpp | 8 ++++---- .../eosio.system/include/eosio.system/eosio.system.hpp | 3 --- contracts/eosio.system/include/eosio.system/native.hpp | 4 ++-- contracts/eosio.system/src/eosio.system.cpp | 10 ---------- contracts/eosio.system/src/rex.cpp | 1 - 6 files changed, 10 insertions(+), 24 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index dd36df42..c58554f1 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -142,9 +142,9 @@ namespace eosio { uint32_t timestamp; name producer; uint16_t confirmed = 0; - checksum256 previous; - checksum256 transaction_mroot; - checksum256 action_mroot; + checksum256 previous; + checksum256 transaction_mroot; + checksum256 action_mroot; uint32_t schedule_version = 0; std::optional new_producers; @@ -440,7 +440,7 @@ namespace eosio { */ struct [[eosio::table]] abi_hash { name owner; - checksum256 hash; + checksum256 hash; uint64_t primary_key()const { return owner.value; } EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 36567d08..32b68287 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -36,8 +36,8 @@ void multisig::propose( ignore proposer, auto packed_requested = pack(_requested); auto res = check_transaction_authorization( trx_pos, size, (const char*)0, 0, - packed_requested.data(), packed_requested.size() - ); + packed_requested.data(), packed_requested.size()); + check( res > 0, "transaction authorization failed" ); std::vector pkd_trans; @@ -178,8 +178,8 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { auto packed_provided_approvals = pack(approvals); auto res = check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), (const char*)0, 0, - packed_provided_approvals.data(), packed_provided_approvals.size() - ); + packed_provided_approvals.data(), packed_provided_approvals.size()); + check( res > 0, "transaction authorization failed" ); send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer, diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index b03e3679..20f67723 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1240,9 +1240,6 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); - // static time_point current_time_point(); - // static time_point_sec current_time_point_sec(); - // static block_timestamp current_block_time(); symbol core_symbol()const; void update_ram_supply(); diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index cb6da0e7..a433de08 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -64,14 +64,14 @@ namespace eosio { auto feature_digest_data = feature_digest.extract_as_byte_array(); return internal_use_do_not_use::is_feature_activated( reinterpret_cast( feature_digest_data.data() ) - ); + ); } void preactivate_feature( const checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); internal_use_do_not_use::preactivate_feature( reinterpret_cast( feature_digest_data.data() ) - ); + ); } } diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index fd357ec4..0d86874f 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -41,16 +41,6 @@ namespace eosiosystem { return dp; } - // time_point_sec system_contract::current_time_point_sec() { - // const static time_point_sec cts{ current_time_point() }; - // return cts; - // } - - // block_timestamp system_contract::current_block_time() { - // const static block_timestamp cbt{ current_time_point() }; - // return cbt; - // } - symbol system_contract::core_symbol()const { const static auto sym = get_core_symbol( _rammarket ); return sym; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index a4142dcc..2a0a7b64 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -855,7 +855,6 @@ namespace eosiosystem { time_point_sec system_contract::get_rex_maturity() { const uint32_t num_of_maturity_buckets = 5; - // static const uint32_t now = current_time_point_sec().utc_seconds; static const uint32_t now = current_time_point().sec_since_epoch(); static const uint32_t r = now % seconds_per_day; static const time_point_sec rms{ now - r + num_of_maturity_buckets * seconds_per_day }; From d79c6fc3ed19b3fbb99dbc9b2da95942a6324aa4 Mon Sep 17 00:00:00 2001 From: johndebord Date: Mon, 6 May 2019 18:57:49 -0400 Subject: [PATCH 0805/1048] Code review changes --- .../include/eosio.bios/eosio.bios.hpp | 12 ++--- .../ricardian/eosio.bios.contracts.md | 20 +++++++++ .../include/eosio.system/native.hpp | 45 +++---------------- .../ricardian/eosio.system.contracts.md | 40 +++++++++++++++++ .../eosio.system/src/delegate_bandwidth.cpp | 2 +- contracts/eosio.system/src/eosio.system.cpp | 8 ++-- contracts/eosio.system/src/voting.cpp | 2 +- contracts/eosio.token/CMakeLists.txt | 2 +- contracts/eosio.wrap/CMakeLists.txt | 2 +- 9 files changed, 82 insertions(+), 51 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index c58554f1..f188f843 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -11,14 +11,17 @@ #include #include +// This header is needed until `capi_checksum256` is added to `eosio.cdt` +#include + namespace eosio { namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import)) - bool is_feature_activated( const checksum256* feature_digest ); + bool is_feature_activated( const ::capi_checksum256* feature_digest ); __attribute__((eosio_wasm_import)) - void preactivate_feature( const checksum256* feature_digest ); + void preactivate_feature( const ::capi_checksum256* feature_digest ); } } } @@ -27,14 +30,14 @@ namespace eosio { bool is_feature_activated( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } void preactivate_feature( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } } @@ -351,7 +354,6 @@ namespace eosio { */ [[eosio::action]] void setprods( std::vector schedule ) { - (void)schedule; // schedule argument just forces the deserialization of the action data into vector (necessary check) require_auth( _self ); set_proposed_producers( schedule ); } diff --git a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md index 75346968..6b069ac1 100644 --- a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md +++ b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md @@ -1,3 +1,13 @@ +

activate

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY +

canceldelay

--- @@ -48,6 +58,16 @@ icon: ICON BODY +

reqactivated

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY +

reqauth

--- diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index a433de08..bba20663 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -13,48 +13,17 @@ #include #include -// extern "C" { -// struct __attribute__((aligned (16))) capi_checksum160 { uint8_t hash[20]; }; -// struct __attribute__((aligned (16))) capi_checksum256 { uint8_t hash[32]; }; -// struct __attribute__((aligned (16))) capi_checksum512 { uint8_t hash[64]; }; -// } - -// namespace eosio { -// namespace internal_use_do_not_use { -// extern "C" { -// __attribute__((eosio_wasm_import)) -// bool is_feature_activated( const ::capi_checksum256* feature_digest ); - -// __attribute__((eosio_wasm_import)) -// void preactivate_feature( const ::capi_checksum256* feature_digest ); -// } -// } -// } - -// namespace eosio { -// bool is_feature_activated( const eosio::checksum256& feature_digest ) { -// auto feature_digest_data = feature_digest.extract_as_byte_array(); -// return internal_use_do_not_use::is_feature_activated( -// reinterpret_cast( feature_digest_data.data() ) -// ); -// } - -// void preactivate_feature( const eosio::checksum256& feature_digest ) { -// auto feature_digest_data = feature_digest.extract_as_byte_array(); -// internal_use_do_not_use::preactivate_feature( -// reinterpret_cast( feature_digest_data.data() ) -// ); -// } -// } +// This header is needed until `capi_checksum256` is added to `eosio.cdt` +#include namespace eosio { namespace internal_use_do_not_use { extern "C" { __attribute__((eosio_wasm_import)) - bool is_feature_activated( const checksum256* feature_digest ); + bool is_feature_activated( const ::capi_checksum256* feature_digest ); __attribute__((eosio_wasm_import)) - void preactivate_feature( const checksum256* feature_digest ); + void preactivate_feature( const ::capi_checksum256* feature_digest ); } } } @@ -63,14 +32,14 @@ namespace eosio { bool is_feature_activated( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } - void preactivate_feature( const checksum256& feature_digest ) { + void preactivate_feature( const eosio::checksum256& feature_digest ) { auto feature_digest_data = feature_digest.extract_as_byte_array(); internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) + reinterpret_cast( feature_digest_data.data() ) ); } } diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md b/contracts/eosio.system/ricardian/eosio.system.contracts.md index 01198d1f..405b7fc6 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md @@ -38,6 +38,16 @@ icon: ICON BODY +

buyresult

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY +

buyrex

--- @@ -236,6 +246,16 @@ summary: SUMMARY icon: ICON --- +BODY + +

orderresult

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + BODY

refund

@@ -288,6 +308,16 @@ icon: ICON BODY +

rentresult

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY +

rexexec

--- @@ -318,6 +348,16 @@ icon: ICON BODY +

sellresult

+ +--- +title: TITLE +summary: SUMMARY +icon: ICON +--- + +BODY +

sellrex

--- diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 9e6872a7..d5826b27 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -225,7 +225,7 @@ namespace eosiosystem { void validate_b1_vesting( int64_t stake ) { const int64_t base_time = 1527811200; /// 2018-06-01 const int64_t max_claimable = 100'000'000'0000ll; - const int64_t claimable = int64_t(max_claimable * double(current_time_point().time_since_epoch().count()/1000000 - base_time) / (10*seconds_per_year) ); + const int64_t claimable = int64_t(max_claimable * double(current_time_point().sec_since_epoch() - base_time) / (10*seconds_per_year) ); check( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); } diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 0d86874f..6b756e0b 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -400,12 +400,12 @@ namespace eosiosystem { set_resource_limits( newact, 0, 0, 0 ); } - void native::setabi( const name& account, const std::vector& abi ) { + void native::setabi( const name& acnt, const std::vector& abi ) { eosio::multi_index< "abihash"_n, abi_hash > table(_self, _self.value); - auto itr = table.find( account.value ); + auto itr = table.find( acnt.value ); if( itr == table.end() ) { - table.emplace( account, [&]( auto& row ) { - row.owner = account; + table.emplace( acnt, [&]( auto& row ) { + row.owner = acnt; row.hash = sha256(const_cast(abi.data()), abi.size()); }); } else { diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 37184cbc..ed08ddd2 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -110,7 +110,7 @@ namespace eosiosystem { double stake2vote( int64_t staked ) { /// TODO subtract 2080 brings the large numbers closer to this decade - double weight = int64_t( (current_time_point().time_since_epoch().count()/1000000 - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); + double weight = int64_t( (current_time_point().sec_since_epoch() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); return double(staked) * std::pow( 2, weight ); } diff --git a/contracts/eosio.token/CMakeLists.txt b/contracts/eosio.token/CMakeLists.txt index 406e046f..04efcfd7 100644 --- a/contracts/eosio.token/CMakeLists.txt +++ b/contracts/eosio.token/CMakeLists.txt @@ -8,4 +8,4 @@ set_target_properties(eosio.token PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) +target_compile_options( eosio.token PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) diff --git a/contracts/eosio.wrap/CMakeLists.txt b/contracts/eosio.wrap/CMakeLists.txt index 69377ff6..d19206f0 100644 --- a/contracts/eosio.wrap/CMakeLists.txt +++ b/contracts/eosio.wrap/CMakeLists.txt @@ -8,4 +8,4 @@ set_target_properties(eosio.wrap PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) +target_compile_options( eosio.wrap PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) From 0a2a9b65e6b5d0e213579f48e839daecc62e6373 Mon Sep 17 00:00:00 2001 From: johndebord Date: Tue, 7 May 2019 11:28:10 -0400 Subject: [PATCH 0806/1048] Code review changes --- contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp | 2 +- contracts/eosio.system/include/eosio.system/native.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index f188f843..4f320495 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -11,7 +11,7 @@ #include #include -// This header is needed until `capi_checksum256` is added to `eosio.cdt` +// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` #include namespace eosio { diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index bba20663..1643658e 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -13,7 +13,7 @@ #include #include -// This header is needed until `capi_checksum256` is added to `eosio.cdt` +// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` #include namespace eosio { From acf88584bf2c0ae455f78988846e8ce4fcbc45d5 Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Fri, 10 May 2019 06:32:31 -0300 Subject: [PATCH 0807/1048] Add configurable inflation to eosio.system contract --- .../include/eosio.system/eosio.system.hpp | 55 ++++++++++++++ contracts/eosio.system/src/eosio.system.cpp | 29 +++++++- contracts/eosio.system/src/producer_pay.cpp | 9 +-- tests/eosio.system_tester.hpp | 8 +++ tests/eosio.system_tests.cpp | 71 +++++++++++++++++++ 5 files changed, 165 insertions(+), 7 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 20f67723..48470468 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -181,6 +181,18 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) }; + /** + * Defines new global state parameters to store inflation rate and distribution + */ + struct [[eosio::table("global4"), eosio::contract("eosio.system")]] eosio_global_state4 { + eosio_global_state4() { } + double continuous_rate; + int64_t inflation_pay_factor; + int64_t votepay_factor; + + EOSLIB_SERIALIZE( eosio_global_state4, (continuous_rate)(inflation_pay_factor)(votepay_factor) ) + }; + /** * Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 */ @@ -295,6 +307,10 @@ namespace eosiosystem { * Global state singleton added in version 1.3 */ typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; + /** + * Global state singleton added in version 1.6.x + */ + typedef eosio::singleton< "global4"_n, eosio_global_state4 > global_state4_singleton; // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation static constexpr uint32_t seconds_per_day = 24 * 3600; @@ -475,9 +491,11 @@ namespace eosiosystem { global_state_singleton _global; global_state2_singleton _global2; global_state3_singleton _global3; + global_state4_singleton _global4; eosio_global_state _gstate; eosio_global_state2 _gstate2; eosio_global_state3 _gstate3; + eosio_global_state4 _gstate4; rammarket _rammarket; rex_pool_table _rexpool; rex_fund_table _rexfunds; @@ -1170,6 +1188,42 @@ namespace eosiosystem { [[eosio::action]] void bidrefund( const name& bidder, const name& newname ); + /** + * Set inflation action. + * + * @details Change the annual inflation rate of the core token supply and specify how + * the new issued tokens will be distributed based on the following structure. + * + * +----+ +----------------+ + * +rate| +--------->|per vote reward | + * +--+-+ | +----------------+ + * | +-----+------+ + * | +----->| bp rewards | + * v | +-----+------+ + * +-+--+---+-+ | +----------------+ + * |new tokens| +--------->|per block reward| + * +----+-----+ +----------------+ + * | +------------+ + * +----->| savings | + * +------------+ + * + * @param continuous_rate - Annual inflation rate of the core token supply. + * (eg. For 5% Annual inflation => continuous_rate=0.04879 ~= ln(1+0.05) + * For 1% Annual inflation => continuous_rate=0.00995 ~= ln(1+0.01) + * + * @param inflation_pay_factor - Percentage of the inflation used to reward block producers. + * The remaining inflation will be sent to the `eosio.saving` account. + * (eg. For 20% => inflation_pay_factor=5 + * For 100% => inflation_pay_factor=1). + * + * @param votepay_factor - Percentage of the block producer rewards to be distributed proportional to votes received. + * The remaining rewards will be distributed proportional to blocks produced. + * (eg. For 25% => votepay_factor=4 + * For 50% => votepay_factor=2). + */ + [[eosio::action]] + void setinflation( double continuous_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); + using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; using setacctnet_action = eosio::action_wrapper<"setacctnet"_n, &system_contract::setacctnet>; @@ -1240,6 +1294,7 @@ namespace eosiosystem { //defined in eosio.system.cpp static eosio_global_state get_default_parameters(); + static eosio_global_state4 get_default_inflation_parameters(); symbol core_symbol()const; void update_ram_supply(); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 6b756e0b..dd08af58 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -23,6 +23,7 @@ namespace eosiosystem { _global(_self, _self.value), _global2(_self, _self.value), _global3(_self, _self.value), + _global4(_self, _self.value), _rammarket(_self, _self.value), _rexpool(_self, _self.value), _rexfunds(_self, _self.value), @@ -33,6 +34,7 @@ namespace eosiosystem { _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; + _gstate4 = _global4.exists() ? _global4.get() : get_default_inflation_parameters(); } eosio_global_state system_contract::get_default_parameters() { @@ -41,6 +43,18 @@ namespace eosiosystem { return dp; } + eosio_global_state4 system_contract::get_default_inflation_parameters() { + const double default_continuous_rate = 0.04879; // 5% annual rate + const int64_t default_inflation_pay_factor = 5; // 20% of the inflation + const int64_t default_votepay_factor = 4; // 25% of the producer pay + + eosio_global_state4 gs4; + gs4.continuous_rate = default_continuous_rate; + gs4.inflation_pay_factor = default_inflation_pay_factor; + gs4.votepay_factor = default_votepay_factor; + return gs4; + } + symbol system_contract::core_symbol()const { const static auto sym = get_core_symbol( _rammarket ); return sym; @@ -50,6 +64,7 @@ namespace eosiosystem { _global.set( _gstate, _self ); _global2.set( _gstate2, _self ); _global3.set( _gstate3, _self ); + _global4.set( _gstate4, _self ); } void system_contract::setram( uint64_t max_ram_size ) { @@ -352,6 +367,18 @@ namespace eosiosystem { refunds_table.erase( it ); } + void system_contract::setinflation( double continuous_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { + require_auth(_self); + check(continuous_rate >= 0, "continuous_rate can't be negative"); + check(inflation_pay_factor > 0, "inflation_pay_factor must be positive"); + check(votepay_factor > 0, "votepay_factor must be positive"); + + _gstate4.continuous_rate = continuous_rate; + _gstate4.inflation_pay_factor = inflation_pay_factor; + _gstate4.votepay_factor = votepay_factor; + _global4.set( _gstate4, _self ); + } + /** * Called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. @@ -447,7 +474,7 @@ EOSIO_DISPATCH( eosiosystem::system_contract, (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) // eosio.system.cpp (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu)(activate) - (rmvproducer)(updtrevision)(bidname)(bidrefund) + (rmvproducer)(updtrevision)(bidname)(bidrefund)(setinflation) // rex.cpp (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) (defcpuloan)(defnetloan)(updaterex)(consolidate)(mvtosavings)(mvfrsavings)(setrex)(rexexec)(closerex) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index b5aba893..6199d2d3 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -9,9 +9,6 @@ namespace eosiosystem { const int64_t min_pervote_daily_pay = 100'0000; const int64_t min_activated_stake = 150'000'000'0000; - const double continuous_rate = 0.04879; // 5% annual rate - const int64_t inflation_pay_factor = 5; // 20% of the inflation - const int64_t votepay_factor = 4; // 25% of the producer pay const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year const uint32_t seconds_per_year = 52*7*24*3600; const uint32_t blocks_per_day = 2 * 24 * 3600; @@ -95,11 +92,11 @@ namespace eosiosystem { const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { - auto new_tokens = static_cast( (continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); + auto new_tokens = static_cast( (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); - auto to_producers = new_tokens / inflation_pay_factor; + auto to_producers = new_tokens / _gstate4.inflation_pay_factor; auto to_savings = new_tokens - to_producers; - auto to_per_block_pay = to_producers / votepay_factor; + auto to_per_block_pay = to_producers / _gstate4.votepay_factor; auto to_per_vote_pay = to_producers - to_per_block_pay; { token::issue_action issue_act{ token_account, { {_self, active_permission} } }; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 68baec76..c4f39d8e 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -962,6 +962,14 @@ class eosio_system_tester : public TESTER { } } + action_result setinflation( double continuous_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { + return push_action( N(eosio), N(setinflation), mvo() + ("continuous_rate", continuous_rate) + ("inflation_pay_factor", inflation_pay_factor) + ("votepay_factor", votepay_factor) + ); + } + abi_serializer abi_ser; abi_serializer token_abi_ser; }; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index cd6bc62c..a4809b77 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1378,6 +1378,77 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t } } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { + + { + const asset large_asset = core_sym::from_string("80.0000"); + create_account_with_resources( N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(defproducerb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(defproducerc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + + create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); + + BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); + BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducerb))); + BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducerc))); + + produce_block(fc::hours(24)); + + transfer( config::system_account_name, "producvotera", core_sym::from_string("400000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); + BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera),N(defproducerb),N(defproducerc) })); + + auto run_for_1year = [this](double inflation, int64_t inflation_pay_factor, int64_t votepay_factor) { + + double continuous_rate = std::log(double(1)+inflation); + + BOOST_REQUIRE_EQUAL(success(), setinflation( + continuous_rate, + inflation_pay_factor, + votepay_factor + )); + + produce_block(fc::hours(24)); + const asset initial_supply = get_token_supply(); + const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); + for (uint32_t i = 0; i < 7 * 52; ++i) { + produce_block(fc::seconds(8 * 3600)); + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerc), N(claimrewards), mvo()("owner", "defproducerc"))); + produce_block(fc::seconds(8 * 3600)); + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); + produce_block(fc::seconds(8 * 3600)); + BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + } + const asset final_supply = get_token_supply(); + const int64_t final_savings = get_balance(N(eosio.saving)).get_amount(); + + double computed_new_tokens = double(final_supply.get_amount() - initial_supply.get_amount()); + double theoretical_new_tokens = double(initial_supply.get_amount())*inflation; + double diff_new_tokens = std::abs(theoretical_new_tokens-computed_new_tokens); + + //Error should be less than 0.3% + BOOST_REQUIRE( diff_new_tokens/theoretical_new_tokens < double(0.003) ); + + double savings_inflation = inflation*double(inflation_pay_factor-1)/double(inflation_pay_factor); + + double computed_savings_tokens = double(final_savings-initial_savings); + double theoretical_savings_tokens = double(initial_supply.get_amount())*savings_inflation; + + double diff_savings_tokens = std::abs(theoretical_savings_tokens-computed_savings_tokens); + + //Error should be less than 0.3% + BOOST_REQUIRE( diff_savings_tokens/theoretical_savings_tokens < double(0.003) ); + }; + + //1% inflation for 1 year => 50% saving / 50% bp reward + run_for_1year(double(1)/double(100), 2, 5); + + //3% inflation for 1 year => 66.6% savings / 33.33 bp reward + run_for_1year(double(3)/double(100), 3, 5); + } + +} FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { From 103da297ccdd97742f0c23fe31efc05cc80a5318 Mon Sep 17 00:00:00 2001 From: Matias Romeo Date: Tue, 21 May 2019 05:22:20 -0300 Subject: [PATCH 0808/1048] * Use annual inflation rate as input in setinflation action * Add test for zero inflation rate --- .../include/eosio.system/eosio.system.hpp | 8 ++--- contracts/eosio.system/src/eosio.system.cpp | 21 +++++++----- contracts/eosio.system/src/producer_pay.cpp | 27 ++++++++++----- tests/eosio.system_tester.hpp | 4 +-- tests/eosio.system_tests.cpp | 34 +++++++++++++------ 5 files changed, 60 insertions(+), 34 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 48470468..30583c75 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1207,9 +1207,9 @@ namespace eosiosystem { * +----->| savings | * +------------+ * - * @param continuous_rate - Annual inflation rate of the core token supply. - * (eg. For 5% Annual inflation => continuous_rate=0.04879 ~= ln(1+0.05) - * For 1% Annual inflation => continuous_rate=0.00995 ~= ln(1+0.01) + * @param annual_rate - Annual inflation rate of the core token supply. + * (eg. For 5% Annual inflation => annual_rate=500 + * For 1.5% Annual inflation => annual_rate=150 * * @param inflation_pay_factor - Percentage of the inflation used to reward block producers. * The remaining inflation will be sent to the `eosio.saving` account. @@ -1222,7 +1222,7 @@ namespace eosiosystem { * For 50% => votepay_factor=2). */ [[eosio::action]] - void setinflation( double continuous_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); + void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index dd08af58..e6d43d28 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -15,6 +15,15 @@ namespace eosiosystem { + const int64_t inflation_precision = 100; // 2 decimals + const int64_t default_annual_rate = 500; // 5% annual rate + const int64_t default_inflation_pay_factor = 5; // 20% of the inflation + const int64_t default_votepay_factor = 4; // 25% of the producer pay + + double get_continuous_rate(int64_t annual_rate) { + return std::log(double(1)+double(annual_rate)/double(100*inflation_precision)); + } + system_contract::system_contract( name s, name code, datastream ds ) :native(s,code,ds), _voters(_self, _self.value), @@ -44,12 +53,8 @@ namespace eosiosystem { } eosio_global_state4 system_contract::get_default_inflation_parameters() { - const double default_continuous_rate = 0.04879; // 5% annual rate - const int64_t default_inflation_pay_factor = 5; // 20% of the inflation - const int64_t default_votepay_factor = 4; // 25% of the producer pay - eosio_global_state4 gs4; - gs4.continuous_rate = default_continuous_rate; + gs4.continuous_rate = get_continuous_rate(default_annual_rate); gs4.inflation_pay_factor = default_inflation_pay_factor; gs4.votepay_factor = default_votepay_factor; return gs4; @@ -367,13 +372,13 @@ namespace eosiosystem { refunds_table.erase( it ); } - void system_contract::setinflation( double continuous_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { + void system_contract::setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { require_auth(_self); - check(continuous_rate >= 0, "continuous_rate can't be negative"); + check(annual_rate >= 0, "annual_rate can't be negative"); check(inflation_pay_factor > 0, "inflation_pay_factor must be positive"); check(votepay_factor > 0, "votepay_factor must be positive"); - _gstate4.continuous_rate = continuous_rate; + _gstate4.continuous_rate = get_continuous_rate(annual_rate); _gstate4.inflation_pay_factor = inflation_pay_factor; _gstate4.votepay_factor = votepay_factor; _global4.set( _gstate4, _self ); diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 6199d2d3..0b34b3ac 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -98,15 +98,24 @@ namespace eosiosystem { auto to_savings = new_tokens - to_producers; auto to_per_block_pay = to_producers / _gstate4.votepay_factor; auto to_per_vote_pay = to_producers - to_per_block_pay; - { - token::issue_action issue_act{ token_account, { {_self, active_permission} } }; - issue_act.send( _self, asset(new_tokens, core_symbol()), "issue tokens for producer pay and savings" ); - } - { - token::transfer_action transfer_act{ token_account, { {_self, active_permission} } }; - transfer_act.send( _self, saving_account, asset(to_savings, core_symbol()), "unallocated inflation" ); - transfer_act.send( _self, bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" ); - transfer_act.send( _self, vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" ); + + if( new_tokens > 0 ) { + { + token::issue_action issue_act{ token_account, { {_self, active_permission} } }; + issue_act.send( _self, asset(new_tokens, core_symbol()), "issue tokens for producer pay and savings" ); + } + { + token::transfer_action transfer_act{ token_account, { {_self, active_permission} } }; + if( to_savings > 0 ) { + transfer_act.send( _self, saving_account, asset(to_savings, core_symbol()), "unallocated inflation" ); + } + if( to_per_block_pay > 0 ) { + transfer_act.send( _self, bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" ); + } + if( to_per_vote_pay > 0 ) { + transfer_act.send( _self, vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" ); + } + } } _gstate.pervote_bucket += to_per_vote_pay; diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index c4f39d8e..fbb408c1 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -962,9 +962,9 @@ class eosio_system_tester : public TESTER { } } - action_result setinflation( double continuous_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { + action_result setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { return push_action( N(eosio), N(setinflation), mvo() - ("continuous_rate", continuous_rate) + ("annual_rate", annual_rate) ("inflation_pay_factor", inflation_pay_factor) ("votepay_factor", votepay_factor) ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index a4809b77..b122df81 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1399,12 +1399,12 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera),N(defproducerb),N(defproducerc) })); - auto run_for_1year = [this](double inflation, int64_t inflation_pay_factor, int64_t votepay_factor) { + auto run_for_1year = [this](int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor) { - double continuous_rate = std::log(double(1)+inflation); + double inflation = double(annual_rate)/double(10000); BOOST_REQUIRE_EQUAL(success(), setinflation( - continuous_rate, + annual_rate, inflation_pay_factor, votepay_factor )); @@ -1427,25 +1427,37 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { double theoretical_new_tokens = double(initial_supply.get_amount())*inflation; double diff_new_tokens = std::abs(theoretical_new_tokens-computed_new_tokens); - //Error should be less than 0.3% - BOOST_REQUIRE( diff_new_tokens/theoretical_new_tokens < double(0.003) ); + if( annual_rate > 0 ) { + //Error should be less than 0.3% + BOOST_REQUIRE( diff_new_tokens/theoretical_new_tokens < double(0.003) ); + } else { + BOOST_REQUIRE_EQUAL( computed_new_tokens, 0 ); + BOOST_REQUIRE_EQUAL( theoretical_new_tokens, 0 ); + } double savings_inflation = inflation*double(inflation_pay_factor-1)/double(inflation_pay_factor); double computed_savings_tokens = double(final_savings-initial_savings); double theoretical_savings_tokens = double(initial_supply.get_amount())*savings_inflation; - double diff_savings_tokens = std::abs(theoretical_savings_tokens-computed_savings_tokens); - - //Error should be less than 0.3% - BOOST_REQUIRE( diff_savings_tokens/theoretical_savings_tokens < double(0.003) ); + + if( annual_rate > 0 ) { + //Error should be less than 0.3% + BOOST_REQUIRE( diff_savings_tokens/theoretical_savings_tokens < double(0.003) ); + } else { + BOOST_REQUIRE_EQUAL( computed_savings_tokens, 0 ); + BOOST_REQUIRE_EQUAL( theoretical_savings_tokens, 0 ); + } }; //1% inflation for 1 year => 50% saving / 50% bp reward - run_for_1year(double(1)/double(100), 2, 5); + run_for_1year(100, 2, 5); //3% inflation for 1 year => 66.6% savings / 33.33 bp reward - run_for_1year(double(3)/double(100), 3, 5); + run_for_1year(300, 3, 5); + + //0% inflation for 1 year + run_for_1year(0, 3, 5); } } FC_LOG_AND_RETHROW() From 3bbf43912252362762d206c314525a9dbfd90251 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 11 Jun 2019 10:54:31 -0400 Subject: [PATCH 0809/1048] RAM testing --- tests/eosio.system_tests.cpp | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b122df81..3f362dbc 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -17,10 +17,17 @@ struct _abi_hash { }; FC_REFLECT( _abi_hash, (owner)(hash) ); +struct connector { + asset balance; + double weight = .5; +}; +FC_REFLECT( connector, (balance)(weight) ); + using namespace eosio_system; BOOST_AUTO_TEST_SUITE(eosio_system_tests) + BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); @@ -117,7 +124,34 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("99396507.4158"), get_balance( "alice1111111" ) ); + BOOST_REQUIRE_EQUAL( false, get_row_by_account( config::system_account_name, config::system_account_name, + N(rammarket), symbol{SY(4,RAMCORE)}.value() ).empty() ); + + auto get_ram_market = [this]() -> fc::variant { + vector data = get_row_by_account( config::system_account_name, config::system_account_name, + N(rammarket), symbol{SY(4,RAMCORE)}.value() ); + BOOST_REQUIRE( !data.empty() ); + return abi_ser.binary_to_variant("exchange_state", data, abi_serializer_max_time); + }; + + transfer( "eosio", "alice1111111", core_sym::from_string("10000000.0000"), "eosio" ); + uint64_t bytes0 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); + + auto market = get_ram_market(); + const asset r0 = market["base"].as().balance; + const asset e0 = market["quote"].as().balance; + BOOST_REQUIRE_EQUAL( asset::from_string("0 RAM").get_symbol(), r0.get_symbol() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000").get_symbol(), e0.get_symbol() ); + + const asset payment = core_sym::from_string("10000000.0000"); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", payment ) ); + uint64_t bytes1 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); + + const int64_t fee = (payment.get_amount() + 199) / 200; + const double net_payment = payment.get_amount() - fee; + const int64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + double(e0.get_amount()) ); + + BOOST_REQUIRE_EQUAL( expected_delta, bytes1 - bytes0 ); } FC_LOG_AND_RETHROW() From 791ce6a397b97cd613fe58f08c160353f74646a0 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 11 Jun 2019 15:12:17 -0400 Subject: [PATCH 0810/1048] Fix producer pay unit tests --- contracts/eosio.system/src/eosio.system.cpp | 2 +- tests/eosio.system_tests.cpp | 20 +++++++++++--------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index e6d43d28..3cf24408 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -21,7 +21,7 @@ namespace eosiosystem { const int64_t default_votepay_factor = 4; // 25% of the producer pay double get_continuous_rate(int64_t annual_rate) { - return std::log(double(1)+double(annual_rate)/double(100*inflation_precision)); + return std::log1p(double(annual_rate)/double(100*inflation_precision)); } system_contract::system_contract( name s, name code, datastream ds ) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 3f362dbc..f5875389 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -149,7 +149,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { const int64_t fee = (payment.get_amount() + 199) / 200; const double net_payment = payment.get_amount() - fee; - const int64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + double(e0.get_amount()) ); + const int64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + e0.get_amount() ); BOOST_REQUIRE_EQUAL( expected_delta, bytes1 - bytes0 ); @@ -1222,7 +1222,9 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - const double continuous_rate = 4.879 / 100.; + auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; + + const double continuous_rate = std::log1p(double(0.05)); const double usecs_per_year = 52 * 7 * 24 * 3600 * 1000000ll; const double secs_per_year = 52 * 7 * 24 * 3600; @@ -1291,10 +1293,10 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * continuous_rate ) / secs_per_year ), supply.get_amount() - initial_supply.get_amount()); - BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (4. * continuous_rate/ 5.) / secs_per_year ) ), - savings - initial_savings); - BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ), - balance.get_amount() - initial_balance.get_amount()); + BOOST_REQUIRE(within_one(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (4. * continuous_rate/ 5.) / secs_per_year ) ), + savings - initial_savings)); + BOOST_REQUIRE(within_one(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ), + balance.get_amount() - initial_balance.get_amount())); int64_t from_perblock_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ; int64_t from_pervote_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.75 * continuous_rate/ 5.) / secs_per_year ) ; @@ -1502,7 +1504,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const int64_t secs_per_year = 52 * 7 * 24 * 3600; const double usecs_per_year = secs_per_year * 1000000; - const double cont_rate = 4.879/100.; + const double cont_rate = std::log1p(double(0.05)); const asset net = core_sym::from_string("80.0000"); const asset cpu = core_sym::from_string("80.0000"); @@ -1642,8 +1644,8 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth) - int64_t(expected_supply_growth)/5, savings - initial_savings ); - const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ); - const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ); + const int64_t expected_perblock_bucket = initial_supply.get_amount() * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year; + const int64_t expected_pervote_bucket = initial_supply.get_amount() * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year; const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; const int64_t from_pervote_bucket = int64_t( vote_shares[prod_index] * expected_pervote_bucket); From 6515ca613df599bf5f9986c4892bb222356de41f Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 11 Jun 2019 17:24:14 -0400 Subject: [PATCH 0811/1048] More accurate input to buyram in buyrambytes --- .../include/eosio.system/exchange_state.hpp | 3 ++ .../eosio.system/src/delegate_bandwidth.cpp | 10 ++-- contracts/eosio.system/src/exchange_state.cpp | 15 ++++++ tests/eosio.system_tests.cpp | 49 +++++++++++++------ 4 files changed, 57 insertions(+), 20 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 4c62e108..d673fa06 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -54,6 +54,9 @@ namespace eosiosystem { static int64_t get_bancor_output( int64_t inp_reserve, int64_t out_reserve, int64_t inp ); + static int64_t get_bancor_input( int64_t inp_reserve, + int64_t out_reserve, + int64_t out ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) }; diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index d5826b27..679fe86f 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -87,12 +87,12 @@ namespace eosiosystem { * This action will buy an exact amount of ram and bill the payer the current market price. */ void system_contract::buyrambytes( const name& payer, const name& receiver, uint32_t bytes ) { - auto itr = _rammarket.find(ramcore_symbol.raw()); - auto tmp = *itr; - auto eosout = tmp.direct_convert( asset(bytes, ram_symbol), core_symbol() ); - - buyram( payer, receiver, eosout ); + const int64_t ram_reserve = itr->base.balance.amount; + const int64_t eos_reserve = itr->quote.balance.amount; + const int64_t cost = exchange_state::get_bancor_input( ram_reserve, eos_reserve, bytes ); + const int64_t cost_plus_fee = cost / double(0.995); + buyram( payer, receiver, asset{ cost_plus_fee, core_symbol() } ); } diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index 23adba46..eb2264cf 100644 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -91,4 +91,19 @@ namespace eosiosystem { return out; } + int64_t exchange_state::get_bancor_input( int64_t out_reserve, + int64_t inp_reserve, + int64_t out ) + { + const double ob = out_reserve; + const double ib = inp_reserve; + // const double ou = out; + + int64_t inp = (ib * out) / (ob - out); + + if ( inp < 0 ) inp = 0; + + return inp; + } + } /// namespace eosiosystem diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index f5875389..b96e479c 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -30,6 +30,8 @@ BOOST_AUTO_TEST_SUITE(eosio_system_tests) BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { + auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); @@ -134,24 +136,41 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { return abi_ser.binary_to_variant("exchange_state", data, abi_serializer_max_time); }; - transfer( "eosio", "alice1111111", core_sym::from_string("10000000.0000"), "eosio" ); - uint64_t bytes0 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); + { + transfer( config::system_account_name, "alice1111111", core_sym::from_string("10000000.0000"), config::system_account_name ); + uint64_t bytes0 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); + + auto market = get_ram_market(); + const asset r0 = market["base"].as().balance; + const asset e0 = market["quote"].as().balance; + BOOST_REQUIRE_EQUAL( asset::from_string("0 RAM").get_symbol(), r0.get_symbol() ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000").get_symbol(), e0.get_symbol() ); - auto market = get_ram_market(); - const asset r0 = market["base"].as().balance; - const asset e0 = market["quote"].as().balance; - BOOST_REQUIRE_EQUAL( asset::from_string("0 RAM").get_symbol(), r0.get_symbol() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000").get_symbol(), e0.get_symbol() ); + const asset payment = core_sym::from_string("10000000.0000"); + BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", payment ) ); + uint64_t bytes1 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); - const asset payment = core_sym::from_string("10000000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", payment ) ); - uint64_t bytes1 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); + const int64_t fee = (payment.get_amount() + 199) / 200; + const double net_payment = payment.get_amount() - fee; + const int64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + e0.get_amount() ); - const int64_t fee = (payment.get_amount() + 199) / 200; - const double net_payment = payment.get_amount() - fee; - const int64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + e0.get_amount() ); + BOOST_REQUIRE_EQUAL( expected_delta, bytes1 - bytes0 ); + } - BOOST_REQUIRE_EQUAL( expected_delta, bytes1 - bytes0 ); + { + transfer( config::system_account_name, "bob111111111", core_sym::from_string("100000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("must reserve a positive amount"), + buyrambytes( "bob111111111", "bob111111111", 1 ) ); + + uint64_t bytes0 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); + BOOST_REQUIRE_EQUAL( success(), buyrambytes( "bob111111111", "bob111111111", 1024 ) ); + uint64_t bytes1 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); + BOOST_REQUIRE( within_one( 1024, bytes1 - bytes0 ) ); + + BOOST_REQUIRE_EQUAL( success(), buyrambytes( "bob111111111", "bob111111111", 1024 * 1024) ); + uint64_t bytes2 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); + BOOST_REQUIRE( within_one( 1024 * 1024, bytes2 - bytes1 ) ); + } } FC_LOG_AND_RETHROW() @@ -1648,7 +1667,7 @@ BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::uni const int64_t expected_pervote_bucket = initial_supply.get_amount() * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year; const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; - const int64_t from_pervote_bucket = int64_t( vote_shares[prod_index] * expected_pervote_bucket); + const int64_t from_pervote_bucket = vote_shares[prod_index] * expected_pervote_bucket; BOOST_REQUIRE( 1 >= abs(int32_t(initial_tot_unpaid_blocks - tot_unpaid_blocks) - int32_t(initial_unpaid_blocks - unpaid_blocks)) ); From d18afe0d389ab1232ac3b873e4ba7c4be7e6ce4a Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Jun 2019 10:51:35 -0400 Subject: [PATCH 0812/1048] Small changes --- contracts/eosio.system/src/exchange_state.cpp | 1 - tests/eosio.system_tests.cpp | 9 +-------- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index eb2264cf..cc6c054d 100644 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -97,7 +97,6 @@ namespace eosiosystem { { const double ob = out_reserve; const double ib = inp_reserve; - // const double ou = out; int64_t inp = (ib * out) / (ob - out); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b96e479c..80cd7383 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -27,11 +27,10 @@ using namespace eosio_system; BOOST_AUTO_TEST_SUITE(eosio_system_tests) +bool within_one(int64_t a, int64_t b) { return std::abs(a - b) <= 1; } BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { - auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); @@ -1241,8 +1240,6 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; - const double continuous_rate = std::log1p(double(0.05)); const double usecs_per_year = 52 * 7 * 24 * 3600 * 1000000ll; const double secs_per_year = 52 * 7 * 24 * 3600; @@ -1519,8 +1516,6 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; - const int64_t secs_per_year = 52 * 7 * 24 * 3600; const double usecs_per_year = secs_per_year * 1000000; const double cont_rate = std::log1p(double(0.05)); @@ -3927,8 +3922,6 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { - auto within_one = [](int64_t a, int64_t b) -> bool { return std::abs( a - b ) <= 1; }; - const asset init_balance = core_sym::from_string("3000000.0000"); const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; From a081f3698ed2045cefe7e6330b95e7e987729c50 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 12 Jun 2019 11:57:05 -0400 Subject: [PATCH 0813/1048] Fix pipeline config --- pipeline.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 28912b07..01efc1db 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,7 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "release/1.8.x", - "eosio.cdt": "release/1.6.x" + "eosio.cdt": "release_1.6.x_fixes" } } } \ No newline at end of file From 5f27c2e112679a6d37189ac9054ae9ff86834228 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 17 Jun 2019 14:10:28 -0400 Subject: [PATCH 0814/1048] Fix wrong assertion in create_core_token (adapted from @elmato's commit d8b9e9666b33a6ca3e2dce3baec21afc410de3c6) --- tests/eosio.system_tester.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index fbb408c1..8bec8562 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -52,7 +52,7 @@ class eosio_system_tester : public TESTER { } void create_core_token( symbol core_symbol = symbol{CORE_SYM} ) { - FC_ASSERT( core_symbol.precision() != 4, "create_core_token assumes precision of core token is 4" ); + FC_ASSERT( core_symbol.decimals() == 4, "create_core_token assumes core token has 4 digits of precision" ); create_currency( N(eosio.token), config::system_account_name, asset(100000000000000, core_symbol) ); issue( asset(10000000000000, core_symbol) ); BOOST_REQUIRE_EQUAL( asset(10000000000000, core_symbol), get_balance( "eosio", core_symbol ) ); From f8dbc78ddea2c9937a40716e679320c1f7fe254d Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 17 Jun 2019 14:47:23 -0400 Subject: [PATCH 0815/1048] cleanup extraneous and inconsistent license references --- .../include/eosio.bios/eosio.bios.hpp | 4 - contracts/eosio.bios/src/eosio.bios.cpp | 4 - .../include/eosio.msig/eosio.msig.hpp | 74 +++++++++---------- contracts/eosio.msig/src/eosio.msig.cpp | 8 +- .../include/eosio.system/eosio.system.hpp | 8 +- .../include/eosio.system/exchange_state.hpp | 10 +-- .../include/eosio.system/native.hpp | 74 +++++++++---------- .../include/eosio.system/rex.results.hpp | 4 - .../eosio.system/src/delegate_bandwidth.cpp | 12 +-- contracts/eosio.system/src/eosio.system.cpp | 4 - contracts/eosio.system/src/exchange_state.cpp | 6 +- contracts/eosio.system/src/producer_pay.cpp | 4 - contracts/eosio.system/src/rex.cpp | 16 ++-- contracts/eosio.system/src/voting.cpp | 6 +- .../include/eosio.token/eosio.token.hpp | 60 +++++++-------- contracts/eosio.token/src/eosio.token.cpp | 4 - .../include/eosio.wrap/eosio.wrap.hpp | 20 ++--- contracts/eosio.wrap/src/eosio.wrap.cpp | 4 - tests/eosio.system_tester.hpp | 4 - 19 files changed, 125 insertions(+), 201 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 4f320495..fa46a103 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eosio.cdt/LICENSE.txt - */ - #pragma once #include diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index cc35446a..fc8d2ff8 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eosio.cdt/LICENSE.txt - */ - #include EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi)(activate)(reqactivated) ) diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index 132b8c0c..cd923734 100644 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eosio.cdt/LICENSE.txt - */ - #pragma once #include @@ -22,18 +18,18 @@ namespace eosio { /** * Create proposal - * + * * @details Creates a proposal containing one transaction. * Allows an account `proposer` to make a proposal `proposal_name` which has `requested` - * permission levels expected to approve the proposal, and if approved by all expected + * permission levels expected to approve the proposal, and if approved by all expected * permission levels then `trx` transaction can we executed by this proposal. - * The `proposer` account is authorized and the `trx` transaction is verified if it was - * authorized by the provided keys and permissions, and if the proposal name doesn’t - * already exist; if all validations pass the `proposal_name` and `trx` trasanction are - * saved in the proposals table and the `requested` permission levels to the + * The `proposer` account is authorized and the `trx` transaction is verified if it was + * authorized by the provided keys and permissions, and if the proposal name doesn’t + * already exist; if all validations pass the `proposal_name` and `trx` trasanction are + * saved in the proposals table and the `requested` permission levels to the * approvals table (for the `proposer` context). * Storage changes are billed to `proposer`. - * + * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be unique for proposer) * @param requested - Permission levels expected to approve the proposal @@ -44,15 +40,15 @@ namespace eosio { ignore> requested, ignore trx); /** * Approve proposal - * + * * @details Approves an existing proposal * Allows an account, the owner of `level` permission, to approve a proposal `proposal_name` - * proposed by `proposer`. If the proposal's requested approval list contains the `level` - * permission then the `level` permission is moved from internal `requested_approvals` list to - * internal `provided_approvals` list of the proposal, thus persisting the approval for + * proposed by `proposer`. If the proposal's requested approval list contains the `level` + * permission then the `level` permission is moved from internal `requested_approvals` list to + * internal `provided_approvals` list of the proposal, thus persisting the approval for * the `proposal_name` proposal. * Storage changes are billed to `proposer`. - * + * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be unique for proposer) * @param level - Permission level approving the transaction @@ -63,12 +59,12 @@ namespace eosio { const eosio::binary_extension& proposal_hash ); /** * Revoke proposal - * + * * @details Revokes an existing proposal - * This action is the reverse of the `approve` action: if all validations pass - * the `level` permission is erased from internal `provided_approvals` and added to the internal + * This action is the reverse of the `approve` action: if all validations pass + * the `level` permission is erased from internal `provided_approvals` and added to the internal * `requested_approvals` list, and thus un-approve or revoke the proposal. - * + * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be an existing proposal) * @param level - Permission level revoking approval for proposal @@ -77,34 +73,34 @@ namespace eosio { void unapprove( name proposer, name proposal_name, permission_level level ); /** * Cancel proposal - * + * * @details Cancels an existing proposal - * + * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be an existing proposal) * @param canceler - The account cancelling the proposal (only the proposer can cancel an unexpired transaction, and the canceler has to be different than the proposer) - * - * Allows the `canceler` account to cancel the `proposal_name` proposal, created by a `proposer`, - * only after time has expired on the proposed transaction. It removes corresponding entries from + * + * Allows the `canceler` account to cancel the `proposal_name` proposal, created by a `proposer`, + * only after time has expired on the proposed transaction. It removes corresponding entries from * internal proptable and from approval (or old approvals) tables as well. */ [[eosio::action]] void cancel( name proposer, name proposal_name, name canceler ); /** * Execute proposal - * + * * @details Allows an `executer` account to execute a proposal. - * - * Preconditions: - * - `executer` has authorization, - * - `proposal_name` is found in the proposals table, - * - all requested approvals are received, - * - proposed transaction is not expired, - * - and approval accounts are not found in invalidations table. - * + * + * Preconditions: + * - `executer` has authorization, + * - `proposal_name` is found in the proposals table, + * - all requested approvals are received, + * - proposed transaction is not expired, + * - and approval accounts are not found in invalidations table. + * * If all preconditions are met the transaction is executed as a deferred transaction, * and the proposal is erased from the proposals table. - * + * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be an existing proposal) * @param executer - The account executing the transaction @@ -113,10 +109,10 @@ namespace eosio { void exec( name proposer, name proposal_name, name executer ); /** * Invalidate proposal - * - * @details Allows an `account` to invalidate itself, that is, its name is added to + * + * @details Allows an `account` to invalidate itself, that is, its name is added to * the invalidations table and this table will be cross referenced when exec is performed. - * + * * @param account - The account invalidating the transaction */ [[eosio::action]] @@ -128,7 +124,7 @@ namespace eosio { using cancel_action = eosio::action_wrapper<"cancel"_n, &multisig::cancel>; using exec_action = eosio::action_wrapper<"exec"_n, &multisig::exec>; using invalidate_action = eosio::action_wrapper<"invalidate"_n, &multisig::invalidate>; - + private: struct [[eosio::table]] proposal { name proposal_name; diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 32b68287..f7fbe824 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eosio.cdt/LICENSE.txt - */ - #include #include #include @@ -37,7 +33,7 @@ void multisig::propose( ignore proposer, auto res = check_transaction_authorization( trx_pos, size, (const char*)0, 0, packed_requested.data(), packed_requested.size()); - + check( res > 0, "transaction authorization failed" ); std::vector pkd_trans; @@ -179,7 +175,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { auto res = check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), (const char*)0, 0, packed_provided_approvals.data(), packed_provided_approvals.size()); - + check( res > 0, "transaction authorization failed" ); send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer, diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 30583c75..0daa9ab6 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #pragma once #include @@ -1191,9 +1187,9 @@ namespace eosiosystem { /** * Set inflation action. * - * @details Change the annual inflation rate of the core token supply and specify how + * @details Change the annual inflation rate of the core token supply and specify how * the new issued tokens will be distributed based on the following structure. - * + * * +----+ +----------------+ * +rate| +--------->|per vote reward | * +--+-+ | +----------------+ diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 4c62e108..83e80915 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -1,13 +1,9 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #pragma once #include namespace eosiosystem { - + using eosio::asset; using eosio::symbol; @@ -18,8 +14,8 @@ namespace eosiosystem { /** * Uses Bancor math to create a 50/50 relay between two asset types. - * - * @details The state of the bancor exchange is entirely contained within this struct. + * + * @details The state of the bancor exchange is entirely contained within this struct. * There are no external side effects associated with using this API. */ struct [[eosio::table, eosio::contract("eosio.system")]] exchange_state { diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 1643658e..11738312 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #pragma once #include @@ -45,7 +41,7 @@ namespace eosio { } namespace eosiosystem { - + using eosio::checksum256; using eosio::ignore; using eosio::name; @@ -57,9 +53,9 @@ namespace eosiosystem { * @{ */ /** - * A weighted permission. - * - * @details Defines a weighted permission, that is a permission which has a weight associated. + * A weighted permission. + * + * @details Defines a weighted permission, that is a permission which has a weight associated. * A permission is defined by an account name plus a permission name. */ struct permission_level_weight { @@ -72,7 +68,7 @@ namespace eosiosystem { /** * Weighted key. - * + * * @details A weighted key is defined by a public key and an associated weight. */ struct key_weight { @@ -85,7 +81,7 @@ namespace eosiosystem { /** * Wait weight. - * + * * @details A wait weight is defined by a number of seconds to wait for and a weight. */ struct wait_weight { @@ -98,7 +94,7 @@ namespace eosiosystem { /** * Blockchain authority. - * + * * @details An authority is defined by: * - a vector of key_weights (a key_weight is a public key plus a wieght), * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) @@ -117,7 +113,7 @@ namespace eosiosystem { /** * Blockchain block header. - * + * * @details A block header is defined by: * - a timestamp, * - the producer that created it, @@ -145,7 +141,7 @@ namespace eosiosystem { /** * abi_hash - * + * * @details abi_hash is the structure underlying the abihash table and consists of: * - `owner`: the account owner of the contract's abi * - `hash`: is the sha256 hash of the abi/binary @@ -161,7 +157,7 @@ namespace eosiosystem { // Method parameters commented out to prevent generation of code that parses input data. /** * The EOSIO core native contract that governs authorization and contracts' abi. - * + * * @details */ class [[eosio::contract("eosio.system")]] native : public eosio::contract { @@ -171,15 +167,15 @@ namespace eosiosystem { /** * @{ - * These actions map one-on-one with the ones defined in + * These actions map one-on-one with the ones defined in * [Native Action Handlers](@ref native_action_handlers) section. * They are present here so they can show up in the abi file and thus user can send them - * to this contract, but they have no specific implementation at this contract level, + * to this contract, but they have no specific implementation at this contract level, * they will execute the implementation at the core level and nothing else. */ /** - * New account action - * + * New account action + * * @details Called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. * @@ -199,9 +195,9 @@ namespace eosiosystem { /** * Update authorization action. - * + * * @details Updates pemission for an account - * + * * @param account - the account for which the permission is updated * @param pemission - the permission name which is updated * @param parem - the parent of the permission which is updated @@ -215,9 +211,9 @@ namespace eosiosystem { /** * Delete authorization action. - * + * * @details Deletes the authorization for an account's permision. - * + * * @param account - the account for which the permission authorization is deleted, * @param permission - the permission name been deleted. */ @@ -227,16 +223,16 @@ namespace eosiosystem { /** * Link authorization action. - * - * @details Assigns a specific action from a contract to a permission you have created. Five system + * + * @details Assigns a specific action from a contract to a permission you have created. Five system * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. - * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the - * action needed to be authorized (and the contract belonging to), and looks up which permission - * is needed to pass authorization validation. If a link is set, that permission is used for authoraization + * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the + * action needed to be authorized (and the contract belonging to), and looks up which permission + * is needed to pass authorization validation. If a link is set, that permission is used for authoraization * validation otherwise then active is the default, with the exception of `eosio.any`. * `eosio.any` is an implicit permission which exists on every account; you can link actions to `eosio.any` - * and that will make it so linked actions are accessible to any permissions defined for the account. - * + * and that will make it so linked actions are accessible to any permissions defined for the account. + * * @param account - the permission's owner to be linked and the payer of the RAM needed to store this link, * @param code - the owner of the action to be linked, * @param type - the action to be linked, @@ -250,9 +246,9 @@ namespace eosiosystem { /** * Unlink authorization action. - * + * * @details It's doing the reverse of linkauth action, by unlinking the given action. - * + * * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, * @param code - the owner of the action to be unlinked, * @param type - the action to be unlinked. @@ -264,9 +260,9 @@ namespace eosiosystem { /** * Cancel delay action. - * + * * @details Cancels a deferred transaction. - * + * * @param canceling_auth - the permission that authorizes this action, * @param trx_id - the deferred transaction id to be cancelled. */ @@ -275,9 +271,9 @@ namespace eosiosystem { /** * On error action. - * + * * @details Called every time an error occurs while a transaction was processed. - * + * * @param sender_id - the id of the sender, * @param sent_trx - the transaction that failed. */ @@ -286,9 +282,9 @@ namespace eosiosystem { /** * Set abi action. - * + * * @details Sets the contract abi for an account. - * + * * @param account - the account for which to set the contract abi. * @param abi - the abi content to be set, in the form of a blob binary. */ @@ -297,9 +293,9 @@ namespace eosiosystem { /** * Set code action. - * + * * @details Sets the contract code for an account. - * + * * @param account - the account for which to set the contract code. * @param vmtype - reserved, set it to zero. * @param vmversion - reserved, set it to zero. diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index 9d5fb6ba..b5a1949c 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #pragma once #include diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index d5826b27..e6fb7af3 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #include #include #include @@ -16,13 +12,13 @@ #include namespace eosiosystem { - + using eosio::asset; using eosio::const_mem_fun; using eosio::indexed_by; using eosio::permission_level; using eosio::time_point_sec; - + using std::map; using std::pair; @@ -135,7 +131,7 @@ namespace eosiosystem { const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); _rammarket.modify( market, same_payer, [&]( auto& es ) { - bytes_out = es.direct_convert( quant_after_fee, ram_symbol ).amount; + bytes_out = es.direct_convert( quant_after_fee, ram_symbol ).amount; }); check( bytes_out > 0, "must reserve a positive amount" ); @@ -208,7 +204,7 @@ namespace eosiosystem { get_resource_limits( res_itr->owner, ram_bytes, net, cpu ); set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); } - + { token::transfer_action transfer_act{ token_account, { {ram_account, active_permission}, {account, active_permission} } }; transfer_act.send( ram_account, account, asset(tokens_out), "sell ram" ); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index e6d43d28..15c6853b 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #include #include diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index 23adba46..1785a166 100644 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #include namespace eosiosystem { @@ -28,7 +24,7 @@ namespace eosiosystem { const double Fi = double(1) / reserve.weight; double dR = R0 * ( std::pow(1. + dS / S0, Fi) - 1. ); // dR < 0 since dS < 0 - if ( dR > 0 ) dR = 0; // rounding errors + if ( dR > 0 ) dR = 0; // rounding errors reserve.balance.amount -= int64_t(-dR); supply -= tokens; return asset( int64_t(-dR), reserve.balance.symbol ); diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 0b34b3ac..1c45e828 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #include #include diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 2a0a7b64..8e737532 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #include #include @@ -48,7 +44,7 @@ namespace eosiosystem { const asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); runrex(2); update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); - // dummy action added so that amount of REX tokens purchased shows up in action trace + // dummy action added so that amount of REX tokens purchased shows up in action trace rex_results::buyresult_action buyrex_act( rex_account, std::vector{ } ); buyrex_act.send( rex_received ); } @@ -525,11 +521,11 @@ namespace eosiosystem { pool->total_unlent.amount, itr->payment.amount ); /// conditions for loan renewal - bool renew_loan = itr->payment <= itr->balance /// loan has sufficient balance - && itr->payment.amount < rented_tokens /// loan has favorable return + bool renew_loan = itr->payment <= itr->balance /// loan has sufficient balance + && itr->payment.amount < rented_tokens /// loan has favorable return && rex_loans_available(); /// no pending sell orders if ( renew_loan ) { - /// update rex_pool in order to account for renewed loan + /// update rex_pool in order to account for renewed loan add_loan_to_rex_pool( itr->payment, rented_tokens, false ); /// update renewed loan fields delta_stake = update_renewed_loan( idx, itr, rented_tokens ); @@ -1010,7 +1006,7 @@ namespace eosiosystem { * @brief Reads amount of REX in savings bucket and removes the bucket from maturities * * Reads and (temporarily) removes REX savings bucket from REX maturities in order to - * allow uniform processing of remaining buckets as savings is a special case. This + * allow uniform processing of remaining buckets as savings is a special case. This * function is used in conjunction with put_rex_savings. * * @param bitr - iterator pointing to rex_balance object @@ -1064,7 +1060,7 @@ namespace eosiosystem { current_vote_stake.amount = ( uint128_t(bitr->rex_balance.amount) * _rexpool.begin()->total_lendable.amount ) / _rexpool.begin()->total_rex.amount; _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount = current_vote_stake.amount; + rb.vote_stake.amount = current_vote_stake.amount; }); delta_stake = current_vote_stake.amount - init_vote_stake.amount; } diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index ed08ddd2..cc540297 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #include #include #include @@ -18,7 +14,7 @@ #include namespace eosiosystem { - + using eosio::const_mem_fun; using eosio::indexed_by; using eosio::singleton; diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index 6ffb3f61..bb08ca40 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #pragma once #include @@ -20,10 +16,10 @@ namespace eosio { /** * @defgroup eosiotoken eosio.token * @ingroup eosiocontracts - * + * * eosio.token contract - * - * @details eosio.token contract defines the structures and actions that allow users to create, issue, and manage + * + * @details eosio.token contract defines the structures and actions that allow users to create, issue, and manage * tokens on eosio based blockchains. * @{ */ @@ -33,16 +29,16 @@ namespace eosio { /** * Create action. - * + * * @details Allows `issuer` account to create a token in supply of `maximum_supply`. * @param issuer - the account that creates the token, * @param maximum_supply - the maximum supply set for the token created. - * + * * @pre Token symbol has to be valid, * @pre Token symbol must not be already created, * @pre maximum_supply has to be smaller than the maximum supply allowed by the system: 1^62 - 1. - * @pre Maximum supply must be positive; - * + * @pre Maximum supply must be positive; + * * If validation is successful a new entry in statstable for token symbol scope gets created. */ [[eosio::action]] @@ -50,9 +46,9 @@ namespace eosio { const asset& maximum_supply); /** * Issue action. - * + * * @details This action issues to `to` account a `quantity` of tokens. - * + * * @param to - the account to issue tokens to, it must be the same as the issuer, * @param quntity - the amount of tokens to be issued, * @memo - the memo string that accompanies the token issue transaction. @@ -62,10 +58,10 @@ namespace eosio { /** * Retire action. - * - * @details The opposite for create action, if all validations succeed, + * + * @details The opposite for create action, if all validations succeed, * it debits the statstable.supply amount. - * + * * @param quantity - the quantity of tokens to retire, * @param memo - the memo string to accompany the transaction. */ @@ -74,10 +70,10 @@ namespace eosio { /** * Transfer action. - * + * * @details Allows `from` account to transfer to `to` account the `quantity` tokens. * One account is debited and the other is credited with quantity tokens. - * + * * @param from - the account to transfer from, * @param to - the account to be transferred to, * @param quantity - the quantity of tokens to be transferred, @@ -90,15 +86,15 @@ namespace eosio { const string& memo ); /** * Open action. - * - * @details Allows `ram_payer` to create an account `owner` with zero balance for + * + * @details Allows `ram_payer` to create an account `owner` with zero balance for * token `symbol` at the expense of `ram_payer`. - * + * * @param owner - the account to be created, * @param symbol - the token to be payed with by `ram_payer`, * @param ram_payer - the account that supports the cost of this action. - * - * More information can be read [here](https://github.com/EOSIO/eosio.contracts/issues/62) + * + * More information can be read [here](https://github.com/EOSIO/eosio.contracts/issues/62) * and [here](https://github.com/EOSIO/eosio.contracts/issues/61). */ [[eosio::action]] @@ -106,13 +102,13 @@ namespace eosio { /** * Close action. - * - * @details This action is the opposite for open, it closes the account `owner` + * + * @details This action is the opposite for open, it closes the account `owner` * for token `symbol`. - * + * * @param owner - the owner account to execute the close action for, * @param symbol - the symbol of the token to execute the close action for. - * + * * @pre The pair of owner plus symbol has to exist otherwise no action is executed, * @pre If the pair of owner plus symbol exists, the balance has to be zero. */ @@ -121,9 +117,9 @@ namespace eosio { /** * Get supply method. - * - * @details Gets the supply for token `sym_code`, created by `token_contract_account` account. - * + * + * @details Gets the supply for token `sym_code`, created by `token_contract_account` account. + * * @param token_contract_account - the account to get the supply for, * @param sym_code - the symbol to get the supply for. */ @@ -136,10 +132,10 @@ namespace eosio { /** * Get balance method. - * + * * @details Get the balance for a token `sym_code` created by `token_contract_account` account, * for account `owner`. - * + * * @param token_contract_account - the token creator account, * @param owner - the account for which the token balance is returned, * @param sym_code - the token for which the balance is returned. diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index 74d68aa0..9d246d4b 100644 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eos/LICENSE.txt - */ - #include namespace eosio { diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp index d66ef909..6833c94a 100644 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eosio.cdt/LICENSE.txt - */ - #pragma once #include @@ -14,10 +10,10 @@ namespace eosio { * @ingroup eosiocontracts * eosio.wrap contract simplifies Block Producer superuser actions by making them more readable and easier to audit. - * @details It does not grant block producers any additional powers that do not already exist within the - * system. Currently, 15/21 block producers can already change an account's keys or modify an - * account's contract at the request of ECAF or an account's owner. However, the current method - * is opaque and leaves undesirable side effects on specific system accounts. + * @details It does not grant block producers any additional powers that do not already exist within the + * system. Currently, 15/21 block producers can already change an account's keys or modify an + * account's contract at the request of ECAF or an account's owner. However, the current method + * is opaque and leaves undesirable side effects on specific system accounts. * eosio.wrap allows for a cleaner method of implementing these important governance actions. * @{ */ @@ -27,14 +23,14 @@ namespace eosio { /** * Execute action. - * + * * @details Execute a transaction while bypassing regular authorization checks. - * + * * @param executer - account executing the transaction, * @param trx - the transaction to be executed. - * + * * @pre Requires authorization of eosio.wrap which needs to be a privileged account. - * + * * @post Deferred transaction RAM usage is billed to 'executer' */ [[eosio::action]] diff --git a/contracts/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp index 9f10cd52..debbce11 100644 --- a/contracts/eosio.wrap/src/eosio.wrap.cpp +++ b/contracts/eosio.wrap/src/eosio.wrap.cpp @@ -1,7 +1,3 @@ -/** - * @copyright defined in eosio.cdt/LICENSE.txt - */ - #include namespace eosio { diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 8bec8562..179d4b0f 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -1,7 +1,3 @@ -/** - * @file - * @copyright defined in eos/LICENSE.txt - */ #pragma once #include From 5ec9782586ac2923a94b1f6fb19637032a9cfa7b Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 19 Jun 2019 13:38:28 -0400 Subject: [PATCH 0816/1048] Incorporated build script changes from master onto develop. --- build.sh | 56 ++++++++++++++++++- scripts/.environment | 13 +++++ scripts/helper.sh | 127 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 2 deletions(-) create mode 100755 scripts/.environment create mode 100755 scripts/helper.sh diff --git a/build.sh b/build.sh index 001f3c64..bfac5078 100755 --- a/build.sh +++ b/build.sh @@ -1,5 +1,57 @@ -#! /bin/bash -set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) +#!/usr/bin/env bash +set -eo pipefail + +function usage() { + printf "Usage: $0 OPTION... + -e DIR Directory where EOSIO is installed. (Default: $HOME/eosio/X.Y) + -c DIR Directory where EOSIO.CDT is installed. (Default: /usr/local/eosio.cdt) + -y Noninteractive mode (Uses defaults for each prompt.) + -h Print this help menu. + \\n" "$0" 1>&2 + exit 1 +} + +if [ $# -ne 0 ]; then + while getopts "e:c:yh" opt; do + case "${opt}" in + e ) + EOSIO_DIR_PROMPT=$OPTARG + ;; + c ) + CDT_DIR_PROMPT=$OPTARG + ;; + y ) + NONINTERACTIVE=true + PROCEED=true + ;; + h ) + usage + ;; + ? ) + echo "Invalid Option!" 1>&2 + usage + ;; + : ) + echo "Invalid Option: -${OPTARG} requires an argument." 1>&2 + usage + ;; + * ) + usage + ;; + esac + done +fi + +# Source helper functions and variables. +. ./scripts/helper.sh +. ./scripts/.environment +# Prompt user for location of eosio. +eosio-directory-prompt +# Prompt user for location of eosio.cdt. +cdt-directory-prompt +# Ensure eosio version is appropriate. +eosio-version-check + printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' NC='\033[0m' diff --git a/scripts/.environment b/scripts/.environment new file mode 100755 index 00000000..c41d3455 --- /dev/null +++ b/scripts/.environment @@ -0,0 +1,13 @@ +export SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +export REPO_ROOT="${SCRIPT_DIR}/.." +export BUILD_DIR="${REPO_ROOT}/build" +export TEST_DIR="${REPO_ROOT}/tests" + +export EOSIO_MIN_VERSION_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_MIN" | tail -1 | sed 's/.*EOSIO_VERSION_MIN //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1,1 -d '.') +export EOSIO_MIN_VERSION_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_MIN" | tail -1 | sed 's/.*EOSIO_VERSION_MIN //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f2,2 -d '.') +export EOSIO_SOFT_MAX_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1,1 -d '.') +export EOSIO_SOFT_MAX_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f2,2 -d '.') +export EOSIO_MAX_VERSION=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_HARD_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_HARD_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1) +export EOSIO_MAX_VERSION="${EOSIO_MAX_VERSION:-$(echo $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR | awk '{print int($1+1)}' | sed 's/$/.0/')}" +export EOSIO_MAX_VERSION_MAJOR=$(echo $EOSIO_MAX_VERSION | cut -f1,1 -d '.') +export EOSIO_MAX_VERSION_MINOR=$(echo $EOSIO_MAX_VERSION | cut -f2,2 -d '.') \ No newline at end of file diff --git a/scripts/helper.sh b/scripts/helper.sh new file mode 100755 index 00000000..373d4e5e --- /dev/null +++ b/scripts/helper.sh @@ -0,0 +1,127 @@ +function default-eosio-directories() { + # Handles choosing which EOSIO directory to select when the default location is used. + ALL_EOSIO_SUBDIRS=($(echo $(ls ${HOME}/eosio))) + PROMPT_EOSIO_DIRS=() + for ITEM in "${ALL_EOSIO_SUBDIRS[@]}"; do + if [[ "$ITEM" > "$EOSIO_MIN_VERSION_MAJOR.$EOSIO_MIN_VERSION_MINOR" && "$ITEM" < "$EOSIO_MAX_VERSION_MAJOR.$EOSIO_MAX_VERSION_MINOR" ]]; then + PROMPT_EOSIO_DIRS+=($ITEM) + fi + done + CONTINUE=true + if [[ $NONINTERACTIVE != true ]]; then + while $CONTINUE -eq true; do + echo "We detected the following items in the default EOSIO path:" + printf '%s\n' "${PROMPT_EOSIO_DIRS[@]}" + printf "Enter the EOSIO version number/directory to use:" && read -p " " EOSIO_VERSION + for ITEM in "${PROMPT_EOSIO_DIRS[@]}"; do + if [[ "$ITEM" = "$EOSIO_VERSION" ]]; then + CONTINUE=false + fi + done + done + else + REGEX='^[0-9]+([.][0-9]+)?$' + for ITEM in "${PROMPT_EOSIO_DIRS[@]}"; do + if [[ "$ITEM" =~ $REGEX ]]; then + EOSIO_VERSION=$ITEM + fi + done + fi +} + + +function eosio-directory-prompt() { + # Handles prompts and default behavior for choosing EOSIO directory. + if [[ -z $EOSIO_DIR_PROMPT ]]; then + echo 'No EOSIO location was specified.' + while true; do + if [[ $NONINTERACTIVE != true ]]; then + printf "Is EOSIO installed in the default location: $HOME/eosio/X.Y (y/n)" && read -p " " PROCEED + fi + echo "" + case $PROCEED in + "" ) + echo "Is EOSIO installed in the default location?";; + 0 | true | [Yy]* ) + default-eosio-directories; + break;; + 1 | false | [Nn]* ) + printf "Enter the installation location of EOSIO:" && read -p " " EOSIO_DIR_PROMPT; + break;; + * ) + echo "Please type 'y' for yes or 'n' for no.";; + esac + done + fi + export EOSIO_INSTALL_DIR="${EOSIO_DIR_PROMPT:-${HOME}/eosio/${EOSIO_VERSION}}" +} + + +function cdt-directory-prompt() { + # Handles prompts and default behavior for choosing EOSIO.CDT directory. + if [[ -z $CDT_DIR_PROMPT ]]; then + echo 'No EOSIO.CDT location was specified.' + while true; do + if [[ $NONINTERACTIVE != true ]]; then + printf "Is EOSIO.CDT installed in the default location? /usr/local/eosio.cdt (y/n)" && read -p " " PROCEED + fi + echo "" + case $PROCEED in + "" ) + echo "Is EOSIO.CDT installed in the default location?";; + 0 | true | [Yy]* ) + break;; + 1 | false | [Nn]* ) + printf "Enter the installation location of EOSIO.CDT:" && read -p " " CDT_DIR_PROMPT; + break;; + * ) + echo "Please type 'y' for yes or 'n' for no.";; + esac + done + fi + export CDT_INSTALL_DIR="${CDT_DIR_PROMPT:-/usr/local/eosio.cdt}" +} + + +function eosio-version-check() { + INSTALLED_VERSION_MAJOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f1,1 -d '.' | sed 's/v//g' ) + INSTALLED_VERSION_MINOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f2,2 -d '.' | sed 's/v//g' ) + + if [[ -z $INSTALLED_VERSION_MAJOR || -z $INSTALLED_VERSION_MINOR ]]; then + echo "Could not determine EOSIO version. Exiting..." + exit 1; + fi + + # Installed major between min and max majors. + if [[ $INSTALLED_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR && $INSTALLED_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then + VALID_VERSION=true + # Installed major same as minimum major. + elif [[ $INSTALLED_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR && $INSTALLED_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then + if [[ $INSTALLED_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR ]]; then + VALID_VERSION=true + fi + # Installed major same as maximum major. + elif [[ $INSTALLED_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR && $INSTALLED_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR ]]; then + if [[ $INSTALLED_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then + VALID_VERSION=true + fi + # Installed major same as both. + else + if [[ $INSTALLED_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR && $INSTALLED_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then + VALID_VERSION=true + fi + fi + + if $VALID_VERSION; then + if [[ $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR || $INSTALLED_VERSION_MAJOR -gt $EOSIO_SOFT_MAX_MAJOR ]]; then + echo "Detected EOSIO version is greater than recommand soft max of $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." + fi + echo "Using EOSIO installation at: $EOSIO_INSTALL_DIR" + echo "Using EOSIO.CDT installation at: $CDT_INSTALL_DIR" + else + echo "Supported versions are: $EOSIO_MIN_VERSION_MAJOR.$EOSIO_MIN_VERSION_MINOR - $EOSIO_MAX_VERSION_MAJOR.$EOSIO_MAX_VERSION_MINOR" + echo "Invalid EOSIO installation. Exiting..." + exit 1; + fi + export CMAKE_PREFIX_PATH="${EOSIO_INSTALL_DIR}:${CDT_INSTALL_DIR}" +} \ No newline at end of file From 9570dfe5f85ba22fbbc8c1f882aa91d248398d41 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 19 Jun 2019 17:20:43 -0400 Subject: [PATCH 0817/1048] Setting CMAKE_FRAMEWORK_PATH to values of user selected or default directories. --- scripts/.environment | 12 ++++++------ scripts/helper.sh | 44 +++++++++++++++++++++++++++----------------- 2 files changed, 33 insertions(+), 23 deletions(-) diff --git a/scripts/.environment b/scripts/.environment index c41d3455..21fec0e4 100755 --- a/scripts/.environment +++ b/scripts/.environment @@ -3,11 +3,11 @@ export REPO_ROOT="${SCRIPT_DIR}/.." export BUILD_DIR="${REPO_ROOT}/build" export TEST_DIR="${REPO_ROOT}/tests" -export EOSIO_MIN_VERSION_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_MIN" | tail -1 | sed 's/.*EOSIO_VERSION_MIN //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1,1 -d '.') -export EOSIO_MIN_VERSION_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_MIN" | tail -1 | sed 's/.*EOSIO_VERSION_MIN //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f2,2 -d '.') -export EOSIO_SOFT_MAX_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1,1 -d '.') -export EOSIO_SOFT_MAX_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f2,2 -d '.') +export EOSIO_MIN_VERSION_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_MIN" | tail -1 | sed 's/.*EOSIO_VERSION_MIN //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1 -d '.') +export EOSIO_MIN_VERSION_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_MIN" | tail -1 | sed 's/.*EOSIO_VERSION_MIN //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f2 -d '.') +export EOSIO_SOFT_MAX_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1 -d '.') +export EOSIO_SOFT_MAX_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f2 -d '.') export EOSIO_MAX_VERSION=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_HARD_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_HARD_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1) export EOSIO_MAX_VERSION="${EOSIO_MAX_VERSION:-$(echo $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR | awk '{print int($1+1)}' | sed 's/$/.0/')}" -export EOSIO_MAX_VERSION_MAJOR=$(echo $EOSIO_MAX_VERSION | cut -f1,1 -d '.') -export EOSIO_MAX_VERSION_MINOR=$(echo $EOSIO_MAX_VERSION | cut -f2,2 -d '.') \ No newline at end of file +export EOSIO_MAX_VERSION_MAJOR=$(echo $EOSIO_MAX_VERSION | cut -f1 -d '.') +export EOSIO_MAX_VERSION_MINOR=$(echo $EOSIO_MAX_VERSION | cut -f2 -d '.') \ No newline at end of file diff --git a/scripts/helper.sh b/scripts/helper.sh index 373d4e5e..233c933a 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -1,27 +1,36 @@ +# Handles choosing which EOSIO directory to select when the default location is used. function default-eosio-directories() { - # Handles choosing which EOSIO directory to select when the default location is used. - ALL_EOSIO_SUBDIRS=($(echo $(ls ${HOME}/eosio))) - PROMPT_EOSIO_DIRS=() + REGEX='^[0-9]+([.][0-9]+)?$' + ALL_EOSIO_SUBDIRS=($(ls ${HOME}/eosio)) + CONTINUE=true + for ITEM in "${ALL_EOSIO_SUBDIRS[@]}"; do - if [[ "$ITEM" > "$EOSIO_MIN_VERSION_MAJOR.$EOSIO_MIN_VERSION_MINOR" && "$ITEM" < "$EOSIO_MAX_VERSION_MAJOR.$EOSIO_MAX_VERSION_MINOR" ]]; then - PROMPT_EOSIO_DIRS+=($ITEM) + if [[ "$ITEM" =~ $REGEX ]]; then + DEFAULT_EOSIO_SUBDIRS+=($ITEM) + # DEFAULT_EOSIO_MAJOR+=($(echo $ITEM | cut -f1 -d '.')) + # DEFAULT_EOSIO_MINOR+=($(echo $ITEM | cut -f1 -d '.')) fi done - CONTINUE=true + + # for ITEM in "${DEFAULT_EOSIO_SUBDIRS[@]}"; do + # if [[ $ITEM > "$EOSIO_MIN_VERSION_MAJOR.$EOSIO_MIN_VERSION_MINOR" && $ITEM < "$EOSIO_MAX_VERSION_MAJOR.$EOSIO_MAX_VERSION_MINOR" ]]; then + # PROMPT_EOSIO_DIRS+=($ITEM) + # fi + # done + if [[ $NONINTERACTIVE != true ]]; then while $CONTINUE -eq true; do - echo "We detected the following items in the default EOSIO path:" - printf '%s\n' "${PROMPT_EOSIO_DIRS[@]}" + echo "The following installations are compatible in the default EOSIO path:" + printf '%s\n' "${DEFAULT_EOSIO_SUBDIRS[@]}" printf "Enter the EOSIO version number/directory to use:" && read -p " " EOSIO_VERSION - for ITEM in "${PROMPT_EOSIO_DIRS[@]}"; do + for ITEM in "${DEFAULT_EOSIO_SUBDIRS[@]}"; do if [[ "$ITEM" = "$EOSIO_VERSION" ]]; then CONTINUE=false fi done done else - REGEX='^[0-9]+([.][0-9]+)?$' - for ITEM in "${PROMPT_EOSIO_DIRS[@]}"; do + for ITEM in "${DEFAULT_EOSIO_SUBDIRS[@]}"; do if [[ "$ITEM" =~ $REGEX ]]; then EOSIO_VERSION=$ITEM fi @@ -30,13 +39,13 @@ function default-eosio-directories() { } +# Handles prompts and default behavior for choosing EOSIO directory. function eosio-directory-prompt() { - # Handles prompts and default behavior for choosing EOSIO directory. if [[ -z $EOSIO_DIR_PROMPT ]]; then echo 'No EOSIO location was specified.' while true; do if [[ $NONINTERACTIVE != true ]]; then - printf "Is EOSIO installed in the default location: $HOME/eosio/X.Y (y/n)" && read -p " " PROCEED + printf "Is EOSIO installed in a default location: ''$HOME/eosio/X.Y (y/n)" && read -p " " PROCEED fi echo "" case $PROCEED in @@ -57,8 +66,8 @@ function eosio-directory-prompt() { } +# Handles prompts and default behavior for choosing EOSIO.CDT directory. function cdt-directory-prompt() { - # Handles prompts and default behavior for choosing EOSIO.CDT directory. if [[ -z $CDT_DIR_PROMPT ]]; then echo 'No EOSIO.CDT location was specified.' while true; do @@ -83,9 +92,10 @@ function cdt-directory-prompt() { } +# Ensures EOSIO is installed and compatible via version listed in tests/CMakeLists.txt. function eosio-version-check() { - INSTALLED_VERSION_MAJOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f1,1 -d '.' | sed 's/v//g' ) - INSTALLED_VERSION_MINOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f2,2 -d '.' | sed 's/v//g' ) + INSTALLED_VERSION_MAJOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f1 -d '.' | sed 's/v//g' ) + INSTALLED_VERSION_MINOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f2 -d '.' | sed 's/v//g' ) if [[ -z $INSTALLED_VERSION_MAJOR || -z $INSTALLED_VERSION_MINOR ]]; then echo "Could not determine EOSIO version. Exiting..." @@ -123,5 +133,5 @@ function eosio-version-check() { echo "Invalid EOSIO installation. Exiting..." exit 1; fi - export CMAKE_PREFIX_PATH="${EOSIO_INSTALL_DIR}:${CDT_INSTALL_DIR}" + export CMAKE_FRAMEWORK_PATH="${EOSIO_INSTALL_DIR}:${CDT_INSTALL_DIR}:${CMAKE_PREFIX_PATH}" } \ No newline at end of file From 53f744239e8da4d3a15386ac43f5ededcd1bd006 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 19 Jun 2019 18:00:07 -0400 Subject: [PATCH 0818/1048] workaround check_transaction_authorization bug in eosio.cdt 1.6.1 for now --- contracts/eosio.msig/src/eosio.msig.cpp | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 32b68287..827fce24 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -34,10 +34,13 @@ void multisig::propose( ignore proposer, check( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); auto packed_requested = pack(_requested); - auto res = check_transaction_authorization( trx_pos, size, - (const char*)0, 0, - packed_requested.data(), packed_requested.size()); - + // TODO: Remove internal_use_do_not_use namespace after minimum eosio.cdt dependency becomes 1.7.x + auto res = internal_use_do_not_use::check_transaction_authorization( + trx_pos, size, + (const char*)0, 0, + packed_requested.data(), packed_requested.size() + ); + check( res > 0, "transaction authorization failed" ); std::vector pkd_trans; @@ -176,10 +179,13 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { old_apptable.erase(apps); } auto packed_provided_approvals = pack(approvals); - auto res = check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), - (const char*)0, 0, - packed_provided_approvals.data(), packed_provided_approvals.size()); - + // TODO: Remove internal_use_do_not_use namespace after minimum eosio.cdt dependency becomes 1.7.x + auto res = internal_use_do_not_use::check_transaction_authorization( + prop.packed_transaction.data(), prop.packed_transaction.size(), + (const char*)0, 0, + packed_provided_approvals.data(), packed_provided_approvals.size() + ); + check( res > 0, "transaction authorization failed" ); send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer, From 8b223377fe6c2c729912c1b220423a5863c4a262 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 09:43:24 -0400 Subject: [PATCH 0819/1048] Added version checking when suggesting default paths to user. --- build.sh | 5 +++- scripts/helper.sh | 76 +++++++++++++++++++++++++---------------------- 2 files changed, 44 insertions(+), 37 deletions(-) diff --git a/build.sh b/build.sh index bfac5078..da689d2b 100755 --- a/build.sh +++ b/build.sh @@ -43,12 +43,15 @@ if [ $# -ne 0 ]; then fi # Source helper functions and variables. -. ./scripts/helper.sh . ./scripts/.environment +. ./scripts/helper.sh + # Prompt user for location of eosio. eosio-directory-prompt + # Prompt user for location of eosio.cdt. cdt-directory-prompt + # Ensure eosio version is appropriate. eosio-version-check diff --git a/scripts/helper.sh b/scripts/helper.sh index 233c933a..07c84417 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -1,3 +1,31 @@ +# Ensures passed in version values are supported. +function version-check() { + CHECK_VERSION_MAJOR=$1 + CHECK_VERSION_MINOR=$2 + VALID_VERSION=1 + + if [[ $CHECK_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR && $CHECK_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then + VALID_VERSION=0 + # Installed major same as minimum major. + elif [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR && $CHECK_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then + if [[ $CHECK_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR ]]; then + VALID_VERSION=0 + fi + # Installed major same as maximum major. + elif [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR && $CHECK_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR ]]; then + if [[ $CHECK_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then + VALID_VERSION=0 + fi + # Installed major same as both. + else + if [[ $CHECK_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR && $CHECK_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then + VALID_VERSION=0 + fi + fi + exit $VALID_VERSION +} + + # Handles choosing which EOSIO directory to select when the default location is used. function default-eosio-directories() { REGEX='^[0-9]+([.][0-9]+)?$' @@ -6,31 +34,27 @@ function default-eosio-directories() { for ITEM in "${ALL_EOSIO_SUBDIRS[@]}"; do if [[ "$ITEM" =~ $REGEX ]]; then - DEFAULT_EOSIO_SUBDIRS+=($ITEM) - # DEFAULT_EOSIO_MAJOR+=($(echo $ITEM | cut -f1 -d '.')) - # DEFAULT_EOSIO_MINOR+=($(echo $ITEM | cut -f1 -d '.')) + DIR_MAJOR=$(echo $ITEM | cut -f1 -d '.') + DIR_MINOR=$(echo $ITEM | cut -f2 -d '.') + if $(version-check $DIR_MAJOR $DIR_MINOR); then + PROMPT_EOSIO_DIRS+=($ITEM) + fi fi done - # for ITEM in "${DEFAULT_EOSIO_SUBDIRS[@]}"; do - # if [[ $ITEM > "$EOSIO_MIN_VERSION_MAJOR.$EOSIO_MIN_VERSION_MINOR" && $ITEM < "$EOSIO_MAX_VERSION_MAJOR.$EOSIO_MAX_VERSION_MINOR" ]]; then - # PROMPT_EOSIO_DIRS+=($ITEM) - # fi - # done - if [[ $NONINTERACTIVE != true ]]; then while $CONTINUE -eq true; do echo "The following installations are compatible in the default EOSIO path:" - printf '%s\n' "${DEFAULT_EOSIO_SUBDIRS[@]}" + printf '%s\n' "${PROMPT_EOSIO_DIRS[@]}" printf "Enter the EOSIO version number/directory to use:" && read -p " " EOSIO_VERSION - for ITEM in "${DEFAULT_EOSIO_SUBDIRS[@]}"; do + for ITEM in "${PROMPT_EOSIO_DIRS[@]}"; do if [[ "$ITEM" = "$EOSIO_VERSION" ]]; then CONTINUE=false fi done done else - for ITEM in "${DEFAULT_EOSIO_SUBDIRS[@]}"; do + for ITEM in "${ALL_EOSIO_SUBDIRS[@]}"; do if [[ "$ITEM" =~ $REGEX ]]; then EOSIO_VERSION=$ITEM fi @@ -39,13 +63,13 @@ function default-eosio-directories() { } -# Handles prompts and default behavior for choosing EOSIO directory. +# Prompts or sets default behavior for choosing EOSIO directory. function eosio-directory-prompt() { if [[ -z $EOSIO_DIR_PROMPT ]]; then echo 'No EOSIO location was specified.' while true; do if [[ $NONINTERACTIVE != true ]]; then - printf "Is EOSIO installed in a default location: ''$HOME/eosio/X.Y (y/n)" && read -p " " PROCEED + printf "Is EOSIO installed in a default location: $HOME/eosio/X.Y (y/n)" && read -p " " PROCEED fi echo "" case $PROCEED in @@ -66,7 +90,7 @@ function eosio-directory-prompt() { } -# Handles prompts and default behavior for choosing EOSIO.CDT directory. +# Prompts or default behavior for choosing EOSIO.CDT directory. function cdt-directory-prompt() { if [[ -z $CDT_DIR_PROMPT ]]; then echo 'No EOSIO.CDT location was specified.' @@ -102,27 +126,7 @@ function eosio-version-check() { exit 1; fi - # Installed major between min and max majors. - if [[ $INSTALLED_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR && $INSTALLED_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then - VALID_VERSION=true - # Installed major same as minimum major. - elif [[ $INSTALLED_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR && $INSTALLED_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then - if [[ $INSTALLED_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR ]]; then - VALID_VERSION=true - fi - # Installed major same as maximum major. - elif [[ $INSTALLED_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR && $INSTALLED_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR ]]; then - if [[ $INSTALLED_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then - VALID_VERSION=true - fi - # Installed major same as both. - else - if [[ $INSTALLED_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR && $INSTALLED_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then - VALID_VERSION=true - fi - fi - - if $VALID_VERSION; then + if $(version-check $INSTALLED_VERSION_MAJOR $INSTALLED_VERSION_MINOR); then if [[ $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR || $INSTALLED_VERSION_MAJOR -gt $EOSIO_SOFT_MAX_MAJOR ]]; then echo "Detected EOSIO version is greater than recommand soft max of $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." fi From 17836c030b8f8af761dcdc8793778831b2066289 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 09:50:53 -0400 Subject: [PATCH 0820/1048] Updated docker build behavior to support new build flags. --- docker/buildContracts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/buildContracts.sh b/docker/buildContracts.sh index 56f4e0de..7bbd9991 100755 --- a/docker/buildContracts.sh +++ b/docker/buildContracts.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) cd /eosio.contracts -./build.sh +./build.sh -c /usr/opt/eosio.cdt -e /opt/eosio cd build tar -pczf /artifacts/contracts.tar.gz * From 1b5908988fa671ffc4d1fadd5b0e4dc7f05df005 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 10:24:32 -0400 Subject: [PATCH 0821/1048] Improved soft max logic. General cleanup. --- scripts/.environment | 3 +-- scripts/helper.sh | 9 +++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/.environment b/scripts/.environment index 21fec0e4..5f5b7731 100755 --- a/scripts/.environment +++ b/scripts/.environment @@ -1,6 +1,5 @@ export SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" export REPO_ROOT="${SCRIPT_DIR}/.." -export BUILD_DIR="${REPO_ROOT}/build" export TEST_DIR="${REPO_ROOT}/tests" export EOSIO_MIN_VERSION_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_MIN" | tail -1 | sed 's/.*EOSIO_VERSION_MIN //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1 -d '.') @@ -8,6 +7,6 @@ export EOSIO_MIN_VERSION_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:bla export EOSIO_SOFT_MAX_MAJOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f1 -d '.') export EOSIO_SOFT_MAX_MINOR=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_SOFT_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_SOFT_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1 | cut -f2 -d '.') export EOSIO_MAX_VERSION=$(cat $TEST_DIR/CMakeLists.txt | grep -E "^[[:blank:]]*set[[:blank:]]*\([[:blank:]]*EOSIO_VERSION_HARD_MAX" | tail -1 | sed 's/.*EOSIO_VERSION_HARD_MAX //g' | sed 's/ //g' | sed 's/"//g' | cut -d\) -f1) -export EOSIO_MAX_VERSION="${EOSIO_MAX_VERSION:-$(echo $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR | awk '{print int($1+1)}' | sed 's/$/.0/')}" +export EOSIO_MAX_VERSION="${EOSIO_MAX_VERSION:-$(echo $EOSIO_SOFT_MAX_MAJOR.999)}" export EOSIO_MAX_VERSION_MAJOR=$(echo $EOSIO_MAX_VERSION | cut -f1 -d '.') export EOSIO_MAX_VERSION_MINOR=$(echo $EOSIO_MAX_VERSION | cut -f2 -d '.') \ No newline at end of file diff --git a/scripts/helper.sh b/scripts/helper.sh index 07c84417..546f1528 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -4,19 +4,20 @@ function version-check() { CHECK_VERSION_MINOR=$2 VALID_VERSION=1 + # Installed major between min and max major. if [[ $CHECK_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR && $CHECK_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then VALID_VERSION=0 - # Installed major same as minimum major. + # Installed major same as minimum major. Check if minor is greater. elif [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR && $CHECK_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then if [[ $CHECK_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR ]]; then VALID_VERSION=0 fi - # Installed major same as maximum major. + # Installed major same as maximum major. Check if minor is less. elif [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR && $CHECK_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR ]]; then if [[ $CHECK_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then VALID_VERSION=0 fi - # Installed major same as both. + # Installed major same as both. Ensure minor is between both. else if [[ $CHECK_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR && $CHECK_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then VALID_VERSION=0 @@ -128,7 +129,7 @@ function eosio-version-check() { if $(version-check $INSTALLED_VERSION_MAJOR $INSTALLED_VERSION_MINOR); then if [[ $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR || $INSTALLED_VERSION_MAJOR -gt $EOSIO_SOFT_MAX_MAJOR ]]; then - echo "Detected EOSIO version is greater than recommand soft max of $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." + echo "Detected EOSIO version is greater than recommended soft max: $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." fi echo "Using EOSIO installation at: $EOSIO_INSTALL_DIR" echo "Using EOSIO.CDT installation at: $CDT_INSTALL_DIR" From 58dc77ca4712a48ee7fc35628ca84860ca1b35ec Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 20 Jun 2019 10:33:27 -0400 Subject: [PATCH 0822/1048] Revert pipeline config change --- pipeline.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 01efc1db..0a80edda 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,7 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "release/1.8.x", - "eosio.cdt": "release_1.6.x_fixes" + "eosio.cdt": "release_1.6.x" } } } \ No newline at end of file From 8955e4be785b237a99219f288fdee3ad9f8deb6e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 20 Jun 2019 10:44:22 -0400 Subject: [PATCH 0823/1048] Small change in function argument names --- .../eosio.system/include/eosio.system/exchange_state.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index d673fa06..9350af12 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -54,8 +54,8 @@ namespace eosiosystem { static int64_t get_bancor_output( int64_t inp_reserve, int64_t out_reserve, int64_t inp ); - static int64_t get_bancor_input( int64_t inp_reserve, - int64_t out_reserve, + static int64_t get_bancor_input( int64_t out_reserve, + int64_t inp_reserve, int64_t out ); EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) From 602624591c94e867d8e56144c1b4d6965129f74f Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 20 Jun 2019 11:15:28 -0400 Subject: [PATCH 0824/1048] fix eosio.cdt dependency in pipeline.jsonc --- pipeline.jsonc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 0a80edda..ddf8f23b 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,7 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "release/1.8.x", - "eosio.cdt": "release_1.6.x" + "eosio.cdt": "release/1.6.x" } } -} \ No newline at end of file +} From 46674ceaff41c08d7baae97e7ea58b324ca6d929 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 13:43:41 -0400 Subject: [PATCH 0825/1048] Added -y flag to ensure non-interactive mode. --- docker/buildContracts.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docker/buildContracts.sh b/docker/buildContracts.sh index 7bbd9991..52e768a3 100755 --- a/docker/buildContracts.sh +++ b/docker/buildContracts.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) cd /eosio.contracts -./build.sh -c /usr/opt/eosio.cdt -e /opt/eosio +./build.sh -c /usr/opt/eosio.cdt -e /opt/eosio -y cd build tar -pczf /artifacts/contracts.tar.gz * From b19f8ff733b6cc76e0162a3dd73ff3f5d7f20d91 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 13:44:17 -0400 Subject: [PATCH 0826/1048] Correct lexographic ordering with default selection. Improved prompts to user when selecting defaults. --- scripts/helper.sh | 51 +++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 28 deletions(-) diff --git a/scripts/helper.sh b/scripts/helper.sh index 546f1528..d7f33448 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -30,9 +30,7 @@ function version-check() { # Handles choosing which EOSIO directory to select when the default location is used. function default-eosio-directories() { REGEX='^[0-9]+([.][0-9]+)?$' - ALL_EOSIO_SUBDIRS=($(ls ${HOME}/eosio)) - CONTINUE=true - + ALL_EOSIO_SUBDIRS=($(ls ${HOME}/eosio | sort -V)) for ITEM in "${ALL_EOSIO_SUBDIRS[@]}"; do if [[ "$ITEM" =~ $REGEX ]]; then DIR_MAJOR=$(echo $ITEM | cut -f1 -d '.') @@ -42,45 +40,40 @@ function default-eosio-directories() { fi fi done - - if [[ $NONINTERACTIVE != true ]]; then - while $CONTINUE -eq true; do - echo "The following installations are compatible in the default EOSIO path:" - printf '%s\n' "${PROMPT_EOSIO_DIRS[@]}" - printf "Enter the EOSIO version number/directory to use:" && read -p " " EOSIO_VERSION - for ITEM in "${PROMPT_EOSIO_DIRS[@]}"; do - if [[ "$ITEM" = "$EOSIO_VERSION" ]]; then - CONTINUE=false - fi - done - done - else - for ITEM in "${ALL_EOSIO_SUBDIRS[@]}"; do - if [[ "$ITEM" =~ $REGEX ]]; then - EOSIO_VERSION=$ITEM - fi - done - fi + for ITEM in "${PROMPT_EOSIO_DIRS[@]}"; do + if [[ "$ITEM" =~ $REGEX ]]; then + EOSIO_VERSION=$ITEM + fi + done } # Prompts or sets default behavior for choosing EOSIO directory. function eosio-directory-prompt() { if [[ -z $EOSIO_DIR_PROMPT ]]; then + default-eosio-directories; echo 'No EOSIO location was specified.' while true; do if [[ $NONINTERACTIVE != true ]]; then - printf "Is EOSIO installed in a default location: $HOME/eosio/X.Y (y/n)" && read -p " " PROCEED + if [[ -z $EOSIO_VERSION ]]; then + echo "No default EOSIO installations detected..." + PROCEED=n + else + printf "Is EOSIO installed in the default location: $HOME/eosio/$EOSIO_VERSION (y/n)" && read -p " " PROCEED + fi fi echo "" case $PROCEED in "" ) echo "Is EOSIO installed in the default location?";; 0 | true | [Yy]* ) - default-eosio-directories; break;; 1 | false | [Nn]* ) - printf "Enter the installation location of EOSIO:" && read -p " " EOSIO_DIR_PROMPT; + if [[ $PROMPT_EOSIO_DIRS ]]; then + echo "Found these compatible EOSIO versions in the default location." + printf "$HOME/eosio/%s\n" "${PROMPT_EOSIO_DIRS[@]}" + fi + printf "Enter the installation location of EOSIO:" && read -e -p " " EOSIO_DIR_PROMPT; break;; * ) echo "Please type 'y' for yes or 'n' for no.";; @@ -106,7 +99,7 @@ function cdt-directory-prompt() { 0 | true | [Yy]* ) break;; 1 | false | [Nn]* ) - printf "Enter the installation location of EOSIO.CDT:" && read -p " " CDT_DIR_PROMPT; + printf "Enter the installation location of EOSIO.CDT:" && read -e -p " " CDT_DIR_PROMPT; break;; * ) echo "Please type 'y' for yes or 'n' for no.";; @@ -118,9 +111,11 @@ function cdt-directory-prompt() { # Ensures EOSIO is installed and compatible via version listed in tests/CMakeLists.txt. +# TODO: Rename this function, too similar to version-check. function eosio-version-check() { - INSTALLED_VERSION_MAJOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f1 -d '.' | sed 's/v//g' ) - INSTALLED_VERSION_MINOR=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version) | cut -f2 -d '.' | sed 's/v//g' ) + INSTALLED_VERSION=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version)) + INSTALLED_VERSION_MAJOR=$(echo $INSTALLED_VERSION | cut -f1 -d '.' | sed 's/v//g') + INSTALLED_VERSION_MINOR=$(echo $INSTALLED_VERSION | cut -f2 -d '.' | sed 's/v//g') if [[ -z $INSTALLED_VERSION_MAJOR || -z $INSTALLED_VERSION_MINOR ]]; then echo "Could not determine EOSIO version. Exiting..." From d7d078af52547a0e64cfc6e5adafb56677b4fb6a Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 14:01:25 -0400 Subject: [PATCH 0827/1048] Comment and function cleanup. --- build.sh | 2 +- scripts/helper.sh | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/build.sh b/build.sh index da689d2b..53745154 100755 --- a/build.sh +++ b/build.sh @@ -53,7 +53,7 @@ eosio-directory-prompt cdt-directory-prompt # Ensure eosio version is appropriate. -eosio-version-check +nodeos-version-check printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' diff --git a/scripts/helper.sh b/scripts/helper.sh index d7f33448..69835b54 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -1,5 +1,5 @@ # Ensures passed in version values are supported. -function version-check() { +function check-version-numbers() { CHECK_VERSION_MAJOR=$1 CHECK_VERSION_MINOR=$2 VALID_VERSION=1 @@ -35,7 +35,7 @@ function default-eosio-directories() { if [[ "$ITEM" =~ $REGEX ]]; then DIR_MAJOR=$(echo $ITEM | cut -f1 -d '.') DIR_MINOR=$(echo $ITEM | cut -f2 -d '.') - if $(version-check $DIR_MAJOR $DIR_MINOR); then + if $(check-version-numbers $DIR_MAJOR $DIR_MINOR); then PROMPT_EOSIO_DIRS+=($ITEM) fi fi @@ -111,8 +111,7 @@ function cdt-directory-prompt() { # Ensures EOSIO is installed and compatible via version listed in tests/CMakeLists.txt. -# TODO: Rename this function, too similar to version-check. -function eosio-version-check() { +function nodeos-version-check() { INSTALLED_VERSION=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version)) INSTALLED_VERSION_MAJOR=$(echo $INSTALLED_VERSION | cut -f1 -d '.' | sed 's/v//g') INSTALLED_VERSION_MINOR=$(echo $INSTALLED_VERSION | cut -f2 -d '.' | sed 's/v//g') @@ -122,7 +121,7 @@ function eosio-version-check() { exit 1; fi - if $(version-check $INSTALLED_VERSION_MAJOR $INSTALLED_VERSION_MINOR); then + if $(check-version-numbers $INSTALLED_VERSION_MAJOR $INSTALLED_VERSION_MINOR); then if [[ $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR || $INSTALLED_VERSION_MAJOR -gt $EOSIO_SOFT_MAX_MAJOR ]]; then echo "Detected EOSIO version is greater than recommended soft max: $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." fi From b09e7b5ac7d39644b255be9128a543156be81aea Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 15:14:00 -0400 Subject: [PATCH 0828/1048] Version logic now searches for instances where version is wrong instead of searching for correct versions. --- scripts/helper.sh | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/scripts/helper.sh b/scripts/helper.sh index 69835b54..7e37b49a 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -2,28 +2,24 @@ function check-version-numbers() { CHECK_VERSION_MAJOR=$1 CHECK_VERSION_MINOR=$2 - VALID_VERSION=1 - - # Installed major between min and max major. - if [[ $CHECK_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR && $CHECK_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then - VALID_VERSION=0 - # Installed major same as minimum major. Check if minor is greater. - elif [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR && $CHECK_VERSION_MAJOR -lt $EOSIO_MAX_VERSION_MAJOR ]]; then - if [[ $CHECK_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR ]]; then - VALID_VERSION=0 - fi - # Installed major same as maximum major. Check if minor is less. - elif [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR && $CHECK_VERSION_MAJOR -gt $EOSIO_MIN_VERSION_MAJOR ]]; then - if [[ $CHECK_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then - VALID_VERSION=0 + + if [[ $CHECK_VERSION_MAJOR -lt $EOSIO_MIN_VERSION_MAJOR ]]; then + exit 1 + fi + if [[ $CHECK_VERSION_MAJOR -gt $EOSIO_MAX_VERSION_MAJOR ]]; then + exit 1 + fi + if [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR ]]; then + if [[ $CHECK_VERSION_MINOR -lt $EOSIO_MIN_VERSION_MINOR ]]; then + exit 1 fi - # Installed major same as both. Ensure minor is between both. - else - if [[ $CHECK_VERSION_MINOR -ge $EOSIO_MIN_VERSION_MINOR && $CHECK_VERSION_MINOR -le $EOSIO_MAX_VERSION_MINOR ]]; then - VALID_VERSION=0 + fi + if [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR ]]; then + if [[ $CHECK_VERSION_MINOR -gt $EOSIO_MAX_VERSION_MINOR ]]; then + exit 1 fi fi - exit $VALID_VERSION + exit 0 } @@ -122,6 +118,7 @@ function nodeos-version-check() { fi if $(check-version-numbers $INSTALLED_VERSION_MAJOR $INSTALLED_VERSION_MINOR); then + # TODO: Fix if [[ $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR || $INSTALLED_VERSION_MAJOR -gt $EOSIO_SOFT_MAX_MAJOR ]]; then echo "Detected EOSIO version is greater than recommended soft max: $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." fi From d88b2f1e94259d1727fac5b99181bdda94f5ce18 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 20 Jun 2019 15:20:23 -0400 Subject: [PATCH 0829/1048] Corrected soft max version check logic. --- scripts/helper.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/scripts/helper.sh b/scripts/helper.sh index 7e37b49a..1ced68ed 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -2,7 +2,7 @@ function check-version-numbers() { CHECK_VERSION_MAJOR=$1 CHECK_VERSION_MINOR=$2 - + if [[ $CHECK_VERSION_MAJOR -lt $EOSIO_MIN_VERSION_MAJOR ]]; then exit 1 fi @@ -118,8 +118,10 @@ function nodeos-version-check() { fi if $(check-version-numbers $INSTALLED_VERSION_MAJOR $INSTALLED_VERSION_MINOR); then - # TODO: Fix - if [[ $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR || $INSTALLED_VERSION_MAJOR -gt $EOSIO_SOFT_MAX_MAJOR ]]; then + if [[ $INSTALLED_VERSION_MAJOR -gt $EOSIO_SOFT_MAX_MAJOR ]]; then + echo "Detected EOSIO version is greater than recommended soft max: $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." + fi + if [[ $INSTALLED_VERSION_MAJOR -eq $EOSIO_SOFT_MAX_MAJOR && $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR ]]; then echo "Detected EOSIO version is greater than recommended soft max: $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." fi echo "Using EOSIO installation at: $EOSIO_INSTALL_DIR" From f99fb470093a4adc659b2e5bfb1cfb2993b19872 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 7 Jun 2019 18:33:06 -0400 Subject: [PATCH 0830/1048] add Ricardian contracts --- README.md | 2 + contracts/CMakeLists.txt | 11 + contracts/eosio.bios/CMakeLists.txt | 4 +- .../include/eosio.bios/eosio.bios.hpp | 17 - .../ricardian/eosio.bios.contracts.md | 169 ----- .../ricardian/eosio.bios.contracts.md.in | 183 +++++ contracts/eosio.bios/src/eosio.bios.cpp | 2 +- contracts/eosio.msig/CMakeLists.txt | 4 +- .../ricardian/eosio.msig.contracts.md | 59 -- .../ricardian/eosio.msig.contracts.md.in | 73 ++ contracts/eosio.system/CMakeLists.txt | 4 +- .../ricardian/eosio.system.clauses.md | 63 ++ .../ricardian/eosio.system.contracts.md | 569 --------------- .../ricardian/eosio.system.contracts.md.in | 664 ++++++++++++++++++ contracts/eosio.token/CMakeLists.txt | 4 +- .../ricardian/eosio.token.contracts.md | 59 -- .../ricardian/eosio.token.contracts.md.in | 95 +++ contracts/eosio.wrap/CMakeLists.txt | 4 +- .../ricardian/eosio.wrap.contracts.md | 9 - .../ricardian/eosio.wrap.contracts.md.in | 13 + contracts/icons/account.png | Bin 0 -> 3795 bytes contracts/icons/account.svg | 1 + contracts/icons/admin.png | Bin 0 -> 2937 bytes contracts/icons/admin.svg | 1 + contracts/icons/multisig.png | Bin 0 -> 1411 bytes contracts/icons/multisig.svg | 1 + contracts/icons/resource.png | Bin 0 -> 1913 bytes contracts/icons/resource.svg | 1 + contracts/icons/rex.png | Bin 0 -> 2770 bytes contracts/icons/rex.svg | 1 + contracts/icons/token.png | Bin 0 -> 4268 bytes contracts/icons/token.svg | 1 + contracts/icons/transfer.png | Bin 0 -> 3856 bytes contracts/icons/transfer.svg | 1 + contracts/icons/voting.png | Bin 0 -> 3238 bytes contracts/icons/voting.svg | 1 + 36 files changed, 1128 insertions(+), 888 deletions(-) delete mode 100644 contracts/eosio.bios/ricardian/eosio.bios.contracts.md create mode 100644 contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in delete mode 100644 contracts/eosio.msig/ricardian/eosio.msig.contracts.md create mode 100644 contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in create mode 100644 contracts/eosio.system/ricardian/eosio.system.clauses.md delete mode 100644 contracts/eosio.system/ricardian/eosio.system.contracts.md create mode 100644 contracts/eosio.system/ricardian/eosio.system.contracts.md.in delete mode 100644 contracts/eosio.token/ricardian/eosio.token.contracts.md create mode 100644 contracts/eosio.token/ricardian/eosio.token.contracts.md.in delete mode 100644 contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md create mode 100644 contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in create mode 100644 contracts/icons/account.png create mode 100644 contracts/icons/account.svg create mode 100644 contracts/icons/admin.png create mode 100644 contracts/icons/admin.svg create mode 100644 contracts/icons/multisig.png create mode 100644 contracts/icons/multisig.svg create mode 100644 contracts/icons/resource.png create mode 100644 contracts/icons/resource.svg create mode 100644 contracts/icons/rex.png create mode 100644 contracts/icons/rex.svg create mode 100644 contracts/icons/token.png create mode 100644 contracts/icons/token.svg create mode 100644 contracts/icons/transfer.png create mode 100644 contracts/icons/transfer.svg create mode 100644 contracts/icons/voting.png create mode 100644 contracts/icons/voting.svg diff --git a/README.md b/README.md index dd735544..bb6ecb1b 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,8 @@ After build: [MIT](./LICENSE) +The included icons are provided under the same terms as the software and accompanying documentation, the MIT License. We welcome contributions from the artistically-inclined members of the community, and if you do send us alternative icons, then you are providing them under those same terms. + ## Important See LICENSE for copyright and license terms. Block.one makes its contribution on a voluntary basis as a member of the EOSIO community and is not responsible for ensuring the overall performance of the software or any related applications. We make no representation, warranty, guarantee or undertaking in respect of the software or any related documentation, whether expressed or implied, including but not limited to the warranties or merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or documentation or the use or other dealings in the software or documentation. Any test results or performance figures are indicative and will not reflect performance under all conditions. Any reference to any third party or third-party product, service or other resource is not an endorsement or recommendation by Block.one. We are not responsible, and disclaim any and all responsibility and liability, for your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so the information here may be out of date or inaccurate. diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt index fb59ebf6..69d438e1 100644 --- a/contracts/CMakeLists.txt +++ b/contracts/CMakeLists.txt @@ -5,6 +5,17 @@ project(contracts) set(EOSIO_WASM_OLD_BEHAVIOR "Off") find_package(eosio.cdt) +set(ICON_BASE_URL "http://127.0.0.1/ricardian_assets/eosio.contracts/icons") + +set(ACCOUNT_ICON_URI "account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f") +set(ADMIN_ICON_URI "admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e") +set(MULTISIG_ICON_URI "multisig.png#4fb41d3cf02d0dd2d35a29308e93c2d826ec770d6bb520db668f530764be7153") +set(RESOURCE_ICON_URI "resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19") +set(REX_ICON_URI "rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8") +set(TOKEN_ICON_URI "token.png#207ff68b0406eaa56618b08bda81d6a0954543f36adc328ab3065f31a5c5d654") +set(TRANSFER_ICON_URI "transfer.png#5dfad0df72772ee1ccc155e670c1d124f5c5122f1d5027565df38b418042d1dd") +set(VOTING_ICON_URI "voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84") + add_subdirectory(eosio.bios) add_subdirectory(eosio.msig) add_subdirectory(eosio.system) diff --git a/contracts/eosio.bios/CMakeLists.txt b/contracts/eosio.bios/CMakeLists.txt index 51e5de8e..3709f70c 100644 --- a/contracts/eosio.bios/CMakeLists.txt +++ b/contracts/eosio.bios/CMakeLists.txt @@ -8,4 +8,6 @@ set_target_properties(eosio.bios PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.bios.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.bios.contracts.md @ONLY ) + +target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index fa46a103..a08c9d1c 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -322,22 +322,6 @@ namespace eosio { set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); } - /** - * Set global resource limits. - * - * @details Not implemented yet. - * Set global resource limits - * - * @param ram - ram limit - * @param net - net limit - * @param cpu - cpu limit - */ - [[eosio::action]] - void setglimits( uint64_t ram, uint64_t net, uint64_t cpu ) { - (void)ram; (void)net; (void)cpu; - require_auth( _self ); - } - /** * Set a new list of active producers, that is, a new producers' schedule. * @@ -458,7 +442,6 @@ namespace eosio { using setcode_action = action_wrapper<"setcode"_n, &bios::setcode>; using setpriv_action = action_wrapper<"setpriv"_n, &bios::setpriv>; using setalimits_action = action_wrapper<"setalimits"_n, &bios::setalimits>; - using setglimits_action = action_wrapper<"setglimits"_n, &bios::setglimits>; using setprods_action = action_wrapper<"setprods"_n, &bios::setprods>; using setparams_action = action_wrapper<"setparams"_n, &bios::setparams>; using reqauth_action = action_wrapper<"reqauth"_n, &bios::reqauth>; diff --git a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md deleted file mode 100644 index 6b069ac1..00000000 --- a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md +++ /dev/null @@ -1,169 +0,0 @@ -

activate

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

canceldelay

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

deleteauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

linkauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

newaccount

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

onerror

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

reqactivated

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

reqauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setabi

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setalimits

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setcode

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setglimits

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setparams

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setpriv

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setprods

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

unlinkauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

updateauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY diff --git a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in new file mode 100644 index 00000000..1acb02b6 --- /dev/null +++ b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in @@ -0,0 +1,183 @@ +

activate

+ +--- +spec_version: "0.2.0" +title: Activate Protocol Feature +summary: 'Activate protocol feature {{nowrap feature_digest}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} activates the protocol feature with a digest of {{feature_digest}}. + +

canceldelay

+ +--- +spec_version: "0.2.0" +title: Cancel Delayed Transaction +summary: '{{nowrap canceling_auth.actor}} cancels a delayed transaction' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{canceling_auth.actor}} cancels the delayed transaction with id {{trx_id}}. + +

deleteauth

+ +--- +spec_version: "0.2.0" +title: Delete Account Permission +summary: 'Delete the {{nowrap permission}} permission of {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Delete the {{permission}} permission of {{account}}. + +

linkauth

+ +--- +spec_version: "0.2.0" +title: Link Action to Permission +summary: '{{nowrap account}} sets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract to {{nowrap requirement}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{account}} sets the minimum required permission for the {{#if type}}{{type}} action of the{{/if}} {{code}} contract to {{requirement}}. + +{{#if type}}{{else}}Any links explicitly associated to specific actions of {{code}} will take precedence.{{/if}} + +

newaccount

+ +--- +spec_version: "0.2.0" +title: Create New Account +summary: '{{nowrap creator}} creates a new account with the name {{nowrap name}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{creator}} creates a new account with the name {{name}} and the following permissions: + +owner permission with authority: +{{to_json owner}} + +active permission with authority: +{{to_json active}} + +

reqactivated

+ +--- +spec_version: "0.2.0" +title: Assert Protocol Feature Activation +summary: 'Assert that protocol feature {{nowrap feature_digest}} has been activated' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +Assert that the protocol feature with a digest of {{feature_digest}} has been activated. + +

reqauth

+ +--- +spec_version: "0.2.0" +title: Assert Authorization +summary: 'Assert that authorization by {{nowrap from}} is provided' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Assert that authorization by {{from}} is provided. + +

setabi

+ +--- +spec_version: "0.2.0" +title: Deploy Contract ABI +summary: 'Deploy contract ABI on account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Deploy the ABI file associated with the contract on account {{account}}. + +

setalimits

+ +--- +spec_version: "0.2.0" +title: Adjust Resource Limits of Account +summary: 'Adjust resource limits of account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} updates {{account}}’s resource limits to have a RAM quota of {{ram_bytes}} bytes, a NET bandwidth quota of {{net_weight}} and a CPU bandwidth quota of {{cpu_weight}}. + +

setcode

+ +--- +spec_version: "0.2.0" +title: Deploy Contract Code +summary: 'Deploy contract code on account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Deploy compiled contract code to the account {{account}}. + +

setparams

+ +--- +spec_version: "0.2.0" +title: Set System Parameters +summary: 'Set system parameters' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} sets system parameters to: +{{to_json params}} + +

setpriv

+ +--- +spec_version: "0.2.0" +title: Make an Account Privileged or Unprivileged +summary: '{{#if is_priv}}Make {{nowrap account}} privileged{{else}}Remove privileged status of {{nowrap account}}{{/if}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{#if is_priv}} +{{$action.account}} makes {{account}} privileged. +{{else}} +{{$action.account}} removes privileged status of {{account}}. +{{/if}} + +

setprods

+ +--- +spec_version: "0.2.0" +title: Set Block Producers +summary: 'Set block producer schedule' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} proposes a block producer schedule of: +{{#each schedule}} + 1. {{this.producer_name}} with a block signing key of {{this.block_signing_key}} +{{/each}} + +

unlinkauth

+ +--- +spec_version: "0.2.0" +title: Unlink Action from Permission +summary: '{{nowrap account}} unsets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{account}} removes the association between the {{#if type}}{{type}} action of the{{/if}} {{code}} contract and its minimum required permission. + +{{#if type}}{{else}}This will not remove any links explicitly associated to specific actions of {{code}}.{{/if}} + +

updateauth

+ +--- +spec_version: "0.2.0" +title: Modify Account Permission +summary: 'Add or update the {{nowrap permission}} permission of {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Modify, and create if necessary, the {{permission}} permission of {{account}} to have a parent permission of {{parent}} and the following authority: +{{to_json auth}} diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index fc8d2ff8..9a080e5e 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,3 @@ #include -EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setglimits)(setprods)(setparams)(reqauth)(setabi)(activate)(reqactivated) ) +EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setprods)(setparams)(reqauth)(setabi)(activate)(reqactivated) ) diff --git a/contracts/eosio.msig/CMakeLists.txt b/contracts/eosio.msig/CMakeLists.txt index 2b85470c..0947ea9d 100644 --- a/contracts/eosio.msig/CMakeLists.txt +++ b/contracts/eosio.msig/CMakeLists.txt @@ -8,4 +8,6 @@ set_target_properties(eosio.msig PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -target_compile_options( eosio.msig PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.msig.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.msig.contracts.md @ONLY ) + +target_compile_options( eosio.msig PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.msig/ricardian/eosio.msig.contracts.md b/contracts/eosio.msig/ricardian/eosio.msig.contracts.md deleted file mode 100644 index 6e1f55f1..00000000 --- a/contracts/eosio.msig/ricardian/eosio.msig.contracts.md +++ /dev/null @@ -1,59 +0,0 @@ -

approve

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

cancel

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

exec

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

invalidate

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

propose

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

unapprove

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY diff --git a/contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in b/contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in new file mode 100644 index 00000000..b9f3f35f --- /dev/null +++ b/contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in @@ -0,0 +1,73 @@ +

approve

+ +--- +spec_version: "0.2.0" +title: Approve Proposed Transaction +summary: '{{nowrap level.actor}} approves the {{nowrap proposal_name}} proposal' +icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ +--- + +{{level.actor}} approves the {{proposal_name}} proposal proposed by {{proposer}} with the {{level.permission}} permission of {{level.actor}}. + +

cancel

+ +--- +spec_version: "0.2.0" +title: Cancel Proposed Transaction +summary: '{{nowrap canceler}} cancels the {{nowrap proposal_name}} proposal' +icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ +--- + +{{canceler}} cancels the {{proposal_name}} proposal submitted by {{proposer}}. + +

exec

+ +--- +spec_version: "0.2.0" +title: Execute Proposed Transaction +summary: '{{nowrap executer}} executes the {{nowrap proposal_name}} proposal' +icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ +--- + +{{executer}} executes the {{proposal_name}} proposal submitted by {{proposer}} if the minimum required approvals for the proposal have been secured. + +

invalidate

+ +--- +spec_version: "0.2.0" +title: Invalidate All Approvals +summary: '{{nowrap account}} invalidates approvals on outstanding proposals' +icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ +--- + +{{account}} invalidates all approvals on proposals which have not yet executed. + +

propose

+ +--- +spec_version: "0.2.0" +title: Propose Transaction +summary: '{{nowrap proposer}} creates the {{nowrap proposal_name}}' +icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ +--- + +{{proposer}} creates the {{proposal_name}} proposal for the following transaction: +{{to_json trx}} + +The proposal requests approvals from the following accounts at the specified permission levels: +{{#each requested}} + + {{this.permission}} permission of {{this.actor}} +{{/each}} + +If the proposed transaction is not executed prior to {{trx.expiration}}, the proposal will automatically expire. + +

unapprove

+ +--- +spec_version: "0.2.0" +title: Unapprove Proposed Transaction +summary: '{{nowrap level.actor}} revokes the approval previously provided to {{nowrap proposal_name}} proposal' +icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ +--- + +{{level.actor}} revokes the approval previously provided at their {{level.permission}} permission level from the {{proposal_name}} proposal proposed by {{proposer}}. diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index 01683ede..e99eb37b 100644 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -19,4 +19,6 @@ set_target_properties(rex.results PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.rex") -target_compile_options( eosio.system PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.system.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.system.contracts.md @ONLY ) + +target_compile_options( eosio.system PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.system/ricardian/eosio.system.clauses.md b/contracts/eosio.system/ricardian/eosio.system.clauses.md new file mode 100644 index 00000000..19be74f8 --- /dev/null +++ b/contracts/eosio.system/ricardian/eosio.system.clauses.md @@ -0,0 +1,63 @@ +

UserAgreement

+ +User agreement for the chain can go here. + +

BlockProducerAgreement

+ +I, {{producer}}, hereby nominate myself for consideration as an elected block producer. + +If {{producer}} is selected to produce blocks by the system contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. + +If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. + +I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. + +{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: + +* proposing an objectively valid block at the time appointed by the block scheduling algorithm; +* pre-confirming a block produced by another producer in the schedule when I find said block objectively valid; +* and, confirming a block for which {{producer}} has received pre-confirmation messages from more than two-thirds of the active block producers. + +I hereby accept liability for any and all provable damages that result from my: + +* signing two different block proposals with the same timestamp with {{producer_key}}; +* signing two different block proposals with the same block number with {{producer_key}}; +* signing any block proposal which builds off of an objectively invalid block; +* signing a pre-confirmation for an objectively invalid block; +* or, signing a confirmation for a block for which I do not possess pre-confirmation messages from more than two-thirds of the active block producers. + +I hereby agree that double-signing for a timestamp or block number in concert with two or more other block producers shall automatically be deemed malicious and cause {{producer}} to be subject to: + +* a fine equal to the past year of compensation received, +* immediate disqualification from being a producer, +* and/or other damages. + +An exception may be made if {{producer}} can demonstrate that the double-signing occurred due to a bug in the reference software; the burden of proof is on {{producer}}. + +I hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. + +I hereby acknowledge that more than two-thirds of the active block producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among block producers. + +If {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least one validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among block producers, said method and reports to be made public. + +The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. + +I agree to process transactions on a FIFO (first in, first out) best-effort basis and to honestly bill transactions for measured execution time. + +I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: the order in which transactions are included, or the hash of the block that is produced. + +I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my business entity who own more than 10% and all direct shareholders. + +I, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain. + +I, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract. + +I, {{producer}}, agree to set the location value of {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer. + +I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among block producers. + +I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior block producer. + +I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either NET or CPU bandwidth metrics. + +I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by more than two-thirds of active block producers, as shown in the system parameters. diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md b/contracts/eosio.system/ricardian/eosio.system.contracts.md deleted file mode 100644 index 405b7fc6..00000000 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md +++ /dev/null @@ -1,569 +0,0 @@ -

bidname

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

bidrefund

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

buyram

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

buyrambytes

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

buyresult

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

buyrex

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

canceldelay

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

claimrewards

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

closerex

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

cnclrexorder

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

consolidate

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

defcpuloan

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

defnetloan

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

delegatebw

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

deleteauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

deposit

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

fundcpuloan

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

fundnetloan

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

init

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

linkauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

newaccount

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

mvfrsavings

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

mvtosavings

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

onblock

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

onerror

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

orderresult

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

refund

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

regproducer

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

regproxy

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

rentcpu

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

rentnet

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

rentresult

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

rexexec

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

rmvproducer

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

sellram

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

sellresult

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

sellrex

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setabi

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setacctcpu

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setacctnet

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setacctram

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setalimits

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setcode

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setparams

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setpriv

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setram

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setramrate

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

setrex

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

undelegatebw

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

unlinkauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

unregprod

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

unstaketorex

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

updateauth

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

updaterex

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

updtrevision

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

voteproducer

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

withdraw

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in new file mode 100644 index 00000000..2269428e --- /dev/null +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -0,0 +1,664 @@ +

activate

+ +--- +spec_version: "0.2.0" +title: Activate Protocol Feature +summary: 'Activate protocol feature {{nowrap feature_digest}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} activates the protocol feature with a digest of {{feature_digest}}. + +

bidname

+ +--- +spec_version: "0.2.0" +title: Bid On a Premium Account Name +summary: '{{nowrap bidder}} bids on the premium account name {{nowrap newname}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{bidder}} bids {{bid}} on an auction to own the premium account name {{newname}}. + +{{bidder}} transfers {{bid}} to the system to cover the cost of the bid, which will be returned to {{bidder}} only if {{bidder}} is later outbid in the auction for {{newname}} by another account. + +If the auction for {{newname}} closes with {{bidder}} remaining as the highest bidder, {{bidder}} will be authorized to create the account with name {{newname}}. + +## Bid refund behavior + +If {{bidder}}’s bid on {{newname}} is later outbid by another account, {{bidder}} will be able to claim back the transferred amount of {{bid}}. The system will attempt to automatically do this on behalf of {{bidder}}, but the automatic refund may occasionally fail which will then require {{bidder}} to manually claim the refund with the bidrefund action. + +## Auction close criteria + +The system should automatically close the auction for {{newname}} if it satisfies the condition that over a period of two minutes the following two properties continuously hold: + +- no one has bid on {{newname}} within the last 24 hours; +- and, the value of the latest bid on {{newname}} is greater than the value of the bids on each of the other open auctions. + +Be aware that the condition to close the auction described above are sufficient but not necessary. The auction for {{newname}} cannot close unless both of the properties are simultaneously satisfied, but it may be closed without requiring the properties to hold for a period of 2 minutes. + +

bidrefund

+ +--- +spec_version: "0.2.0" +title: Claim Refund on Name Bid +summary: 'Claim refund on {{nowrap newname}} bid' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{bidder}} claims refund on {{newname}} bid after being outbid by someone else. + +

buyram

+ +--- +spec_version: "0.2.0" +title: Buy RAM +summary: '{{nowrap payer}} buys RAM on behalf of {{nowrap receiver}} by paying {{nowrap quant}}' +icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ +--- + +{{payer}} buys RAM on behalf of {{receiver}} by paying {{quant}}. This transaction will incur a 0.5% fee out of {{quant}} and the amount of RAM delivered will depend on market rates. + +

buyrambytes

+ +--- +spec_version: "0.2.0" +title: Buy RAM +summary: '{{nowrap payer}} buys {{nowrap bytes}} bytes of RAM on behalf of {{nowrap receiver}}' +icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ +--- + +{{payer}} buys approximately {{bytes}} bytes of RAM on behalf of {{receiver}} by paying market rates for RAM. This transaction will incur a 0.5% fee and the cost will depend on market rates. + +

buyrex

+ +--- +spec_version: "0.2.0" +title: Buy REX Tokens +summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and his vote stake increases by {{nowrap amount}}' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{amount}} is taken out of {{from}}’s REX fund and used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{from}} must have voted for a proxy or at least 21 block producers. {{amount}} is added to {{from}}’s vote stake. + +A sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately. + +

canceldelay

+ +--- +spec_version: "0.2.0" +title: Cancel Delayed Transaction +summary: '{{nowrap canceling_auth.actor}} cancels a delayed transaction' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{canceling_auth.actor}} cancels the delayed transaction with id {{trx_id}}. + +

claimrewards

+ +--- +spec_version: "0.2.0" +title: Claim Block Producer Rewards +summary: '{{nowrap owner}} claims block and vote rewards' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{owner}} claims block and vote rewards from the system. + +

closerex

+ +--- +spec_version: "0.2.0" +title: Cleanup Unused REX Data +summary: 'Delete REX related DB entries and free associated RAM' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +Delete REX related DB entries and free associated RAM for {{owner}}. + +To fully delete all REX related DB entries, {{owner}} must ensure that their REX balance and REX fund amounts are both zero and they have no outstanding loans. + +

cnclrexorder

+ +--- +spec_version: "0.2.0" +title: Cancel Scheduled REX Sell Order +summary: '{{nowrap owner}} cancels a scheduled sell order if not yet filled' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{owner}} cancels their open sell order. + +

consolidate

+ +--- +spec_version: "0.2.0" +title: Consolidate REX Maturity Buckets Into One +summary: 'Consolidate REX maturity buckets into one' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +Consolidate REX maturity buckets into one bucket that {{owner}} will not be able to sell until 4 to 5 days later. + +

defcpuloan

+ +--- +spec_version: "0.2.0" +title: Withdraw from the Fund of a Specific CPU Loan +summary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of CPU loan number {{nowrap loan_num}} back to REX fund' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from}} transfers {{amount}} from the fund of CPU loan number {{loan_num}} back to REX fund. + +

defnetloan

+ +--- +spec_version: "0.2.0" +title: Withdraw from the Fund of a Specific NET Loan +summary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of NET loan number {{nowrap loan_num}} back to REX fund' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from}} transfers {{amount}} from the fund of NET loan number {{loan_num}} back to REX fund. + +

delegatebw

+ +--- +spec_version: "0.2.0" +title: Stake Tokens for NET and/or CPU +summary: 'Stake tokens for NET and/or CPU and optionally transfer ownership' +icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ +--- + +{{#if transfer}} {{from}} stakes on behalf of {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth. + +Staked tokens will also be transferred to {{receiver}}. The sum of these two quantities will be deducted from {{from}}’s liquid balance and add to the vote weight of {{receiver}}. +{{else}} +{{from}} stakes to self and delegates to {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth. + +The sum of these two quantities add to the vote weight of {{from}}. +{{/if}} + +

deleteauth

+ +--- +spec_version: "0.2.0" +title: Delete Account Permission +summary: 'Delete the {{nowrap permission}} permission of {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Delete the {{permission}} permission of {{account}}. + +

deposit

+ +--- +spec_version: "0.2.0" +title: Deposit Into REX Fund +summary: 'Add to {{nowrap owner}}’s REX fund by transferring {{nowrap amount}} from {{nowrap owner}}’s liquid balance' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +Transfer {{amount}} from {{owner}}’s liquid balance to {{owner}}’s REX fund. All proceeds and expenses related to REX are added to or taken out of this fund. + +

fundcpuloan

+ +--- +spec_version: "0.2.0" +title: Deposit into the Fund of a Specific CPU Loan +summary: '{{nowrap from}} funds a CPU loan' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from}} transfers {{payment}} from REX fund to the fund of CPU loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time. + +

fundnetloan

+ +--- +spec_version: "0.2.0" +title: Deposit into the Fund of a Specific NET Loan +summary: '{{nowrap from}} funds a NET loan' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from}} transfers {{payment}} from REX fund to the fund of NET loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time. + +

init

+ +--- +spec_version: "0.2.0" +title: Initialize System Contract +summary: 'Initialize system contract' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +Initialize system contract. The core token symbol will be set to {{core}}. + +

linkauth

+ +--- +spec_version: "0.2.0" +title: Link Action to Permission +summary: '{{nowrap account}} sets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract to {{nowrap requirement}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{account}} sets the minimum required permission for the {{#if type}}{{type}} action of the{{/if}} {{code}} contract to {{requirement}}. + +{{#if type}}{{else}}Any links explicitly associated to specific actions of {{code}} will take precedence.{{/if}} + +

newaccount

+ +--- +spec_version: "0.2.0" +title: Create New Account +summary: '{{nowrap creator}} creates a new account with the name {{nowrap name}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{creator}} creates a new account with the name {{name}} and the following permissions: + +owner permission with authority: +{{to_json owner}} + +active permission with authority: +{{to_json active}} + +

mvfrsavings

+ +--- +spec_version: "0.2.0" +title: Unlock REX Tokens +summary: '{{nowrap owner}} unlocks REX Tokens' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{owner}} unlocks {{rex}} by moving it out of the REX savings bucket. The unlocked REX tokens cannot be sold until 4 to 5 days later. + +

mvtosavings

+ +--- +spec_version: "0.2.0" +title: Lock REX Tokens +summary: '{{nowrap owner}} locks REX Tokens' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{owner}} locks {{rex}} by moving it into the REX savings bucket. The locked REX tokens cannot be sold directly and will have to be unlocked explicitly before selling. + +

refund

+ +--- +spec_version: "0.2.0" +title: Claim Unstaked Tokens +summary: 'Return previously unstaked tokens to {{nowrap owner}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Return previously unstaked tokens to {{owner}} after the unstaking period has elapsed. + +

regproducer

+ +--- +spec_version: "0.2.0" +title: Register as a Block Producer Candidate +summary: 'Register {{nowrap producer}} account as a block producer candidate' +icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ +--- + +Register {{producer}} account as a block producer candidate. + +{{$clauses.BlockProducerAgreement}} + +

regproxy

+ +--- +spec_version: "0.2.0" +title: Register/unregister as a Proxy +summary: 'Register/unregister {{nowrap proxy}} as a proxy account' +icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ +--- + +{{#if isproxy}} +{{proxy}} registers as a proxy that can vote on behalf of accounts that appoint it as their proxy. +{{else}} +{{proxy}} unregisters as a proxy that can vote on behalf of accounts that appoint it as their proxy. +{{/if}} + +

rentcpu

+ +--- +spec_version: "0.2.0" +title: Rent CPU Bandwidth for 30 Days +summary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent CPU bandwidth for {{nowrap receiver}}' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from}} pays {{loan_payment}} to rent CPU bandwidth on behalf of {{receiver}} for a period of 30 days. + +{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s CPU resources. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan. + +At expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s CPU bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s CPU bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund. + +

rentnet

+ +--- +spec_version: "0.2.0" +title: Rent NET Bandwidth for 30 Days +summary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent NET bandwidth for {{nowrap receiver}}' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from}} pays {{loan_payment}} to rent NET bandwidth on behalf of {{receiver}} for a period of 30 days. + +{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s NET resources for 30 days. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan. + +At expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s NET bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s NET bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund. + +

rexexec

+ +--- +spec_version: "0.2.0" +title: Perform REX Maintenance +summary: 'Process sell orders and expired loans' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +Performs REX maintenance by processing a maximum of {{max}} REX sell orders and expired loans. Any account can execute this action. + +

rmvproducer

+ +--- +spec_version: "0.2.0" +title: Forcibly Unregister a Block Producer Candidate +summary: '{{nowrap producer}} is unregistered as a block producer candidate' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} unregisters {{producer}} as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered. + +

sellram

+ +--- +spec_version: "0.2.0" +title: Sell RAM From Account +summary: 'Sell unused RAM from {{nowrap account}}' +icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ +--- + +Sell {{bytes}} bytes of unused RAM from account {{account}} at market price. This transaction will incur a 0.5% fee on the proceeds which depend on market rates. + +

sellrex

+ +--- +spec_version: "0.2.0" +title: Sell REX Tokens in Exchange for EOS +summary: '{{nowrap from}} sells {{nowrap rex}} tokens' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from}} initiates a sell order to sell {{rex}} tokens at the market exchange rate during the time at which the order is ultimately executed. If {{from}} already has an open sell order in the sell queue, {{rex}} will be added to the amount of the sell order without change the position of the sell order within the queue. Once the sell order is executed, proceeds are added to {{from}}’s REX fund, the value of sold REX tokens is deducted from {{from}}’s vote stake, and votes are updated accordingly. + +Depending on the market conditions, it may not be possible to fill the entire sell order immediately. In such a case, the sell order is added to the back of a sell queue. A sell order at the front of the sell queue will automatically be executed when the market conditions allow for the entire order to be filled. Regardless of the market conditions, the system is designed to execute this sell order within 30 days. {{from}} can cancel the order at any time before it is filled using the cnclrexorder action. + +

setabi

+ +--- +spec_version: "0.2.0" +title: Deploy Contract ABI +summary: 'Deploy contract ABI on account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Deploy the ABI file associated with the contract on account {{account}}. + +

setacctcpu

+ +--- +spec_version: "0.2.0" +title: Explicitly Manage the CPU Quota of Account +summary: 'Explicitly manage the CPU bandwidth quota of account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{#if_has_value cpu_weight}} +Explicitly manage the CPU bandwidth quota of account {{account}} by pinning it to a weight of {{cpu_weight}}. + +{{account}} can stake and unstake, however, it will not change their CPU bandwidth quota as long as it remains pinned. +{{else}} +Unpin the CPU bandwidth quota of account {{account}}. The CPU bandwidth quota of {{account}} will be driven by the current tokens staked for CPU bandwidth by {{account}}. +{{/if_has_value}} + +

setacctnet

+ +--- +spec_version: "0.2.0" +title: Explicitly Manage the NET Quota of Account +summary: 'Explicitly manage the NET bandwidth quota of account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{#if_has_value net_weight}} +Explicitly manage the network bandwidth quota of account {{account}} by pinning it to a weight of {{net_weight}}. + +{{account}} can stake and unstake, however, it will not change their NET bandwidth quota as long as it remains pinned. +{{else}} +Unpin the NET bandwidth quota of account {{account}}. The NET bandwidth quota of {{account}} will be driven by the current tokens staked for NET bandwidth by {{account}}. +{{/if_has_value}} + +

setacctram

+ +--- +spec_version: "0.2.0" +title: Explicitly Manage the RAM Quota of Account +summary: 'Explicitly manage the RAM quota of account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{#if_has_value ram_bytes}} +Explicitly manage the RAM quota of account {{account}} by pinning it to {{ram_bytes}} bytes. + +{{account}} can buy and sell RAM, however, it will not change their RAM quota as long as it remains pinned. +{{else}} +Unpin the RAM quota of account {{account}}. The RAM quota of {{account}} will be driven by the current RAM holdings of {{account}}. +{{/if_has_value}} + +

setalimits

+ +--- +spec_version: "0.2.0" +title: Adjust Resource Limits of Account +summary: 'Adjust resource limits of account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} updates {{account}}’s resource limits to have a RAM quota of {{ram_bytes}} bytes, a NET bandwidth quota of {{net_weight}} and a CPU bandwidth quota of {{cpu_weight}}. + +

setcode

+ +--- +spec_version: "0.2.0" +title: Deploy Contract Code +summary: 'Deploy contract code on account {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Deploy compiled contract code to the account {{account}}. + +

setparams

+ +--- +spec_version: "0.2.0" +title: Set System Parameters +summary: 'Set System Parameters' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} sets system parameters to: +{{to_json params}} + +

setpriv

+ +--- +spec_version: "0.2.0" +title: Make an Account Privileged or Unprivileged +summary: '{{#if is_priv}}Make {{nowrap account}} privileged{{else}}Remove privileged status of {{nowrap account}}{{/if}}' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{#if is_priv}} +{{$action.account}} makes {{account}} privileged. +{{else}} +{{$action.account}} removes privileged status of {{account}}. +{{/if}} + +

setram

+ +--- +spec_version: "0.2.0" +title: Configure the Available RAM +summary: 'Configure the available RAM' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} configures the available RAM to {{max_ram_size}} bytes. + +

setramrate

+ +--- +spec_version: "0.2.0" +title: Set the Rate of Increase of RAM +summary: 'Set the rate of increase of RAM per block' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} sets the rate of increase of RAM to {{bytes_per_block}} bytes/block. + +

setrex

+ +--- +spec_version: "0.2.0" +title: Adjust REX Pool Virtual Balance +summary: 'Adjust REX Pool Virtual Balance' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} adjusts REX loan rate by setting REX pool virtual balance to {{balance}}. No token transfer or issue is executed in this action. + +

undelegatebw

+ +--- +spec_version: "0.2.0" +title: Unstake Tokens for NET and/or CPU +summary: 'Unstake tokens for NET and/or CPU from {{nowrap receiver}}' +icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ +--- + +{{from}} unstakes from {{receiver}} {{unstake_net_quantity}} for NET bandwidth and {{unstake_cpu_quantity}} for CPU bandwidth. + +The sum of these two quantities will be removed from the vote weight of {{receiver}} and will be made available to {{from}} after an uninterrupted 3 day period without further unstaking by {{from}}. After the uninterrupted 3 day period passes, the system will attempt to automatically return the funds to {{from}}’s regular token balance. However, this automatic refund may occasionally fail which will then require {{from}} to manually claim the funds with the refund action. + +

unlinkauth

+ +--- +spec_version: "0.2.0" +title: Unlink Action from Permission +summary: '{{nowrap account}} unsets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +{{account}} removes the association between the {{#if type}}{{type}} action of the{{/if}} {{code}} contract and its minimum required permission. + +{{#if type}}{{else}}This will not remove any links explicitly associated to specific actions of {{code}}.{{/if}} + +

unregprod

+ +--- +spec_version: "0.2.0" +title: Unregister as a Block Producer Candidate +summary: '{{nowrap producer}} unregisters as a block producer candidate' +icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ +--- + +{{producer}} unregisters as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered. + +

unstaketorex

+ +--- +spec_version: "0.2.0" +title: Buy REX Tokens Using Staked Tokens +summary: '{{nowrap owner}} buys REX tokens in exchange for tokens currently staked to NET and/or CPU' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +{{from_net}} and {{from_cpu}} are withdrawn from {{receiver}}’s NET and CPU bandwidths respectively. These funds are used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{owner}} must have voted for a proxy or at least 21 block producers. + +A sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately. + +

updateauth

+ +--- +spec_version: "0.2.0" +title: Modify Account Permission +summary: 'Add or update the {{nowrap permission}} permission of {{nowrap account}}' +icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ +--- + +Modify, and create if necessary, the {{permission}} permission of {{account}} to have a parent permission of {{parent}} and the following authority: +{{to_json auth}} + +

updaterex

+ +--- +spec_version: "0.2.0" +title: Update REX Owner Vote Weight +summary: 'Update vote weight to current value of held REX tokens' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +Update vote weight of {{owner}} account to current value of held REX tokens. + +

updtrevision

+ +--- +spec_version: "0.2.0" +title: Update System Contract Revision Number +summary: 'Update system contract revision number' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} advances the system contract revision number to {{revision}}. + +

voteproducer

+ +--- +spec_version: "0.2.0" +title: Vote for Block Producers +summary: '{{nowrap voter}} votes for {{#if proxy}}the proxy {{nowrap proxy}}{{else}}up to 30 block producer candidates{{/if}}' +icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ +--- + +{{#if proxy}} +{{voter}} votes for the proxy {{proxy}}. +At the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the producers voted by {{proxy}}. +{{else}} +{{voter}} votes for the following block producer candidates: + +{{#each producers}} + + {{this}} +{{/each}} + +At the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the above producers. +{{/if}} + +

withdraw

+ +--- +spec_version: "0.2.0" +title: Withdraw from REX Fund +summary: 'Withdraw {{nowrap amount}} from {{nowrap owner}}’s REX fund by transferring to {{owner}}’s liquid balance' +icon: @ICON_BASE_URL@/@REX_ICON_URI@ +--- + +Withdraws {{amount}} from {{owner}}’s REX fund and transfer them to {{owner}}’s liquid balance. diff --git a/contracts/eosio.token/CMakeLists.txt b/contracts/eosio.token/CMakeLists.txt index 04efcfd7..cf53f62c 100644 --- a/contracts/eosio.token/CMakeLists.txt +++ b/contracts/eosio.token/CMakeLists.txt @@ -8,4 +8,6 @@ set_target_properties(eosio.token PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -target_compile_options( eosio.token PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.token.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.token.contracts.md @ONLY ) + +target_compile_options( eosio.token PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.token/ricardian/eosio.token.contracts.md b/contracts/eosio.token/ricardian/eosio.token.contracts.md deleted file mode 100644 index 8245071a..00000000 --- a/contracts/eosio.token/ricardian/eosio.token.contracts.md +++ /dev/null @@ -1,59 +0,0 @@ -

close

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

create

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

issue

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

open

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

retire

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY - -

transfer

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY diff --git a/contracts/eosio.token/ricardian/eosio.token.contracts.md.in b/contracts/eosio.token/ricardian/eosio.token.contracts.md.in new file mode 100644 index 00000000..f050eec7 --- /dev/null +++ b/contracts/eosio.token/ricardian/eosio.token.contracts.md.in @@ -0,0 +1,95 @@ +

close

+ +--- +spec_version: "0.2.0" +title: Close Token Balance +summary: 'Close {{nowrap owner}}’s zero quantity balance' +icon: @ICON_BASE_URL@/@TOKEN_ICON_URI@ +--- + +{{owner}} agrees to close their zero quantity balance for the {{symbol_to_symbol_code symbol}} token. + +RAM will be refunded to the RAM payer of the {{symbol_to_symbol_code symbol}} token balance for {{owner}}. + +

create

+ +--- +spec_version: "0.2.0" +title: Create New Token +summary: 'Create a new token' +icon: @ICON_BASE_URL@/@TOKEN_ICON_URI@ +--- + +{{$action.account}} agrees to create a new token with symbol {{asset_to_symbol_code maximum_supply}} to be managed by {{issuer}}. + +This action will not result any any tokens being issued into circulation. + +{{issuer}} will be allowed to issue tokens into circulation, up to a maximum supply of {{maximum_supply}}. + +RAM will deducted from {{$action.account}}’s resources to create the necessary records. + +

issue

+ +--- +spec_version: "0.2.0" +title: Issue Tokens into Circulation +summary: 'Issue {{nowrap quantity}} into circulation and transfer into {{nowrap to}}’s account' +icon: @ICON_BASE_URL@/@TOKEN_ICON_URI@ +--- + +The token manager agrees to issue {{quantity}} into circulation, and transfer it into {{to}}’s account. + +{{#if memo}}There is a memo attached to the transfer stating: +{{memo}} +{{/if}} + +If {{to}} does not have a balance for {{asset_to_symbol_code quantity}}, or the token manager does not have a balance for {{asset_to_symbol_code quantity}}, the token manager will be designated as the RAM payer of the {{asset_to_symbol_code quantity}} token balance for {{to}}. As a result, RAM will be deducted from the token manager’s resources to create the necessary records. + +This action does not allow the total quantity to exceed the max allowed supply of the token. + +

open

+ +--- +spec_version: "0.2.0" +title: Open Token Balance +summary: 'Open a zero quantity balance for {{nowrap owner}}' +icon: @ICON_BASE_URL@/@TOKEN_ICON_URI@ +--- + +{{ram_payer}} agrees to establish a zero quantity balance for {{owner}} for the {{symbol_to_symbol_code symbol}} token. + +If {{owner}} does not have a balance for {{symbol_to_symbol_code symbol}}, {{ram_payer}} will be designated as the RAM payer of the {{symbol_to_symbol_code symbol}} token balance for {{owner}}. As a result, RAM will be deducted from {{ram_payer}}’s resources to create the necessary records. + +

retire

+ +--- +spec_version: "0.2.0" +title: Remove Tokens from Circulation +summary: 'Remove {{nowrap quantity}} from circulation' +icon: @ICON_BASE_URL@/@TOKEN_ICON_URI@ +--- + +The token manager agrees to remove {{quantity}} from circulation, taken from their own account. + +{{#if memo}} There is a memo attached to the action stating: +{{memo}} +{{/if}} + +

transfer

+ +--- +spec_version: "0.2.0" +title: Transfer Tokens +summary: 'Send {{nowrap quantity}} from {{nowrap from}} to {{nowrap to}}' +icon: @ICON_BASE_URL@/@TRANSFER_ICON_URI@ +--- + +{{from}} agrees to send {{quantity}} to {{to}}. + +{{#if memo}}There is a memo attached to the transfer stating: +{{memo}} +{{/if}} + +If {{from}} is not already the RAM payer of their {{asset_to_symbol_code quantity}} token balance, {{from}} will be designated as such. As a result, RAM will be deducted from {{from}}’s resources to refund the original RAM payer. + +If {{to}} does not have a balance for {{asset_to_symbol_code quantity}}, {{from}} will be designated as the RAM payer of the {{asset_to_symbol_code quantity}} token balance for {{to}}. As a result, RAM will be deducted from {{from}}’s resources to create the necessary records. diff --git a/contracts/eosio.wrap/CMakeLists.txt b/contracts/eosio.wrap/CMakeLists.txt index d19206f0..27d42919 100644 --- a/contracts/eosio.wrap/CMakeLists.txt +++ b/contracts/eosio.wrap/CMakeLists.txt @@ -8,4 +8,6 @@ set_target_properties(eosio.wrap PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") -target_compile_options( eosio.wrap PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian ) +configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.wrap.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.wrap.contracts.md @ONLY ) + +target_compile_options( eosio.wrap PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md b/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md deleted file mode 100644 index 65a62155..00000000 --- a/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md +++ /dev/null @@ -1,9 +0,0 @@ -

exec

- ---- -title: TITLE -summary: SUMMARY -icon: ICON ---- - -BODY \ No newline at end of file diff --git a/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in b/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in new file mode 100644 index 00000000..8077a347 --- /dev/null +++ b/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in @@ -0,0 +1,13 @@ +

exec

+ +--- +spec_version: "0.2.0" +title: Privileged Execute +summary: '{{nowrap executer}} executes a transaction while bypassing authority checks' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{executer}} executes the following transaction while bypassing authority checks: +{{to_json trx}} + +{{$action.account}} must also authorize this action. diff --git a/contracts/icons/account.png b/contracts/icons/account.png new file mode 100644 index 0000000000000000000000000000000000000000..7686587824ac663ffb79f3ee30d06821a26e6c26 GIT binary patch literal 3795 zcmV;^4lMDBP)FWRNVR=Q&5~o{vsUi=0WccP1Vhp^+L0T^e&dJn!l764_-HuYO5T=qXAcLELol_v$~S}Q8pmFg=} zws|p=(DG>jWQadlt#Wp-$_blc5U@+c7i(!~KQ8ld2?PiLMt&lErRA0vJYAS zSVZjD(&q@j#MEGxcK{&Q*omd%&06G~)u05`04RDYyz^C_)B>vnwE)n&-}b-5i$O5C zD*e`8ivX~_!qOsh2-*ha0LXzlnCzDiDh3m#KLAd2 zh(~cz_}m)+L%_c5Hw`Kj;j$|L8XJbS2Zx~&3}Z(C?1Pp+sszII0zh(%=fRH9CkxdF zfYAJlZGXTRLw8_$01(PQxcwPpZa{$5<80;rlo8rOg9adU|J(kc5gtwq7Jxv0q4r0O z&>I*e0Kxu$%=S+h0)qn}lwa=88>R{YRwKXNA31_cDgy%GL*yqcm4g6apKSiq2xLUX ztXO`tKX~}NRmf%l%qPhoB5-Q1&j3)LC4Y#(+6KTVK1}`)0o?+C|FI8{KeU8P0|2(0 z{~H%=`R`1afpd*a4)+j9yMiPDTOaw|M&wte6bA zC4c1-0LTd*|I2MU&jm%CvrM+_N&s*?V2bv;|JciJk4H9}J9(B1qPt3b5Cq2y+@Tx* zF9K+GfTk>qxcR=#+rYXQ01kBkV{zq7^Mixu3S1!oTc!qeS$@o$gUJ$sTrMsle=5(Psyk>x;AqU}OaKnE zn6UDnWfKt)Xxt_kvj8~Wf+?u|&qya(Ca5pqCw7nkV1Sw7wJN1I$Uzq^R>++!CrbxV zqQwK~+W6jo?Vez>7%~8uP}=9}A5>i7)o%W&$eaRTV3$Bs!%p_CM@uZaByBoNPFuk? zKxsaKhd|R-#F6-_EsI5@^UA&V(oivl>50vwN~ zO>4p!Zb9kRDg`YL6=qnfEl)KD+)>M*A{YTGI9sB zS*`)KW`RDnxl~d@M(u#cX=4+s6l_DylpkQp|JrPA07ccf&yj1)sE})U$dUyL)#y_u zLPkbJK?0|*YBGd7F<4S?W}VL#GdW@3>=3*k~T zS}|ajWM#2IQH?Su-q*GbJaEx7`b`*q|cxs>}<7G3BAKXXX)Jy6p$*%rgx0j@C0+ zW`}@O)%t-tg9n?w?`qLp)uDFV`y%Ube)WREhHnlGKeg$&-x)mG4o+9~$=(`Yyna}l z;Wq#p8oP(?yHteX5WS9U|oh0 z@Z=x%J^(BM08oM+Fl& zUI>6sXq3^0gW#Is`{x2cvGH3~BtD+N^-=&R1lSPa%ObnA;t6c81%O20MIhmA1-V#~ zLZSnK@5KN_5P0ovt2gyE7Oi=VVyp*&@znrCTaxAQNp+ac^#DZLGG&ZD1ise;P|2h; z_2F+%M}qU-XH;y1Ufny0v%t_V=%`kLsT+O2y6Qe4_~8OVxt^V?ZUZ160-<}d_or`! z#NKtNHADHgzRe5t@t&#It#I_HzYS?h)$Xl3^flMwNem)eVVbXKTSdGJba)v$jg7YX z5dQL2FBi4#AYO*l^#J^_3BSg*4NHi(LDfAJe9|CZhpz|)A2X=@0DOkXg9n)*g3b|o z@*s1B?6rRI)D%1E^@Ge4T)JOEJkkmLpD8;295+Dc3h(U4xB)s_99%E(DK_w} zUSR$)RxnaAVt$MjjMNN4tHwSh4t%c~gVqf`dBo}lp_QYbVge48qub9g0`b~m_cJ1a zc=b4vKj6V5&L40v0?W4rAi*H9^?sBNw&UwIaC`L_(XW5H#PX&%M1U+ZC#R7wsX2Ks zK5(m-u0W(%WT3TvG1(W*&tHiLySWQ?fX^cYWRjwVH+Cv`9Ol~f-2ow!lsSfLoC+2oM*u5X&J>!tra6_`O%Cwzi9M#;a!a0VEY#?0o7 zQ4+@~`rFYrFMeKnZOu7=T(K%Fy7qqxO0y34*A4VphEfM2JASKGmJo5AbDqa1E=2)q0;odvpyga~Ek6UQ-E z1_oK|@_@4cWOvy?XC;HUZB6KqFwH(N+F#%ZQ;jFw1Sqgg1f4NvNQK|&lU1l2k3`sf(RLpI0tfAGQurGCXpP~9r zQ%camOZ#a~(LvQ*s{rXvQ?NGM{-NjFhAyrxE$=&A)Op%8`R5uXm^D z&E>bsA0nX6{z}A{v#i}Soc+GIKDp4J!I<_@F?Y_g>}OzQ%I*o^yGRgiwA~?r#IPCWZ5UlzgZQ>mgx6Z8;|r{mi!Q%6&yP(wKZ<8uW;0E z^lWtUh{lTT>~j72FaJc&i+vO;y6-jq1`zjGS6Kf*=533UWEWO;@-)XM^g9h8y+}g( zi*|BFbyg;*{0q+~834)*tOF~WA}iZt-s8_RN-K0KDMPjbuqP6}o>F5OPo_A()@OS? z0*|S)c2W7yZ8R&jGA$`2mv4d$AC*%p9YNqprA2gVT8@v(Di$XZcvN+rs+B(vfRH5n zaRsKl_VGNEE+BjYeprpQt4$urSfMXIP8+A*~7C&v0_^diWQlJmC&qfG>o@hWLN zOa8dUYI57UaWpb$s_2`;=%DKXLb>Kv1gF%c~X5zp2MTTpq+@2MAE8^J7(bjk3v2fV4#I%(nhlf zT@Y%csl=rjdP*-W`Z1;hm%6jP)L<|jI*@ibwwM(!J&IH95&+WCdyVvSuXo6f?F6I& z?S*0M_zK&(pMukkl!B8reP5m~Xegm_xMb-YWnA002ov JPDHLkV1nnf{$~IH literal 0 HcmV?d00001 diff --git a/contracts/icons/account.svg b/contracts/icons/account.svg new file mode 100644 index 00000000..511f0649 --- /dev/null +++ b/contracts/icons/account.svg @@ -0,0 +1 @@ +Account \ No newline at end of file diff --git a/contracts/icons/admin.png b/contracts/icons/admin.png new file mode 100644 index 0000000000000000000000000000000000000000..ae95364725ed2e9f6143044631d2ff136201fa2b GIT binary patch literal 2937 zcmY+Gc{J308^*uCnK5JROC%nd5XrvR5MwL*I+mnJ#=d5db$-^eMT#t0k|j&gVoe!K zLfMxmyLe>DPNFQY=bZPv=e+kn*XKItzW=+83-VPX|f)cuCe+pQxp!VnOzV z^K(i~bZ>5LZ9CihkB?2o-%ac78LF#pT$o?7v2gp?+(`+JfBZ1-MQPR1(UBlEr|$Ti zm27Hgc5MG|z}XiW_5jc|>S(GF?~E>IUyFQlo&l~axp!ypsBwoJU{r%d%^5y<@c6@9 zvn@4sZFStIyUd&54tUFDD$};`%j(qF-0npX%GSz*FtUU#^!?^1UyFi561RcPsCXVz$sE`I$V0q}Q*Zm~d zs?`J3ZdPpYt>xgjN5VtE{eyY@Vu1f-G(iP^Iv9|o!A!yNP>HK$ytb~55Ipkxd)+yM z*we5F@IBa_kP${G!B5NgyW^}MAngk00%)BFLEGjg-=|><>}!zTtygkya*!-3_|d{m z+OJAkG?o*dPTf}^?MrFVQ{Td8jlAk3Ttt|uHh`3^(84024OPbdAc}RR0g*RA_pT)Q z&DmrI>Q_Yd%#_wO4^#(8tDlT>ont9RB+J|2DwGP=p>)@GWu+!|I1W(J0Q6hw@gOGk zrSFXg@&Os{z$|jMvsV+N{Q*5VT5v;g6gmaJiVlnW?V82_oBKr^-mlVfIL8P)W{SGR zr5@U_Q-7=&mqxSV>V)!&vVJdlK11a3ki3e}nQ16k9$(VM7=h3M!)Uz$3;7r<@ZhW{ z^>RxA>lV^ug@+VP8DYmVI(T>r;|mRnujefBWIdWn?Q-Sf3Im(a`f+BI!D+z9FfCBi zloSwk+H!Z6S%Z)AmnR3y11lu|C3Smlb}-@0lg?dmonUMOG96YDJ|o*r zZ~ZA2zG92q86pGUpz(9by^M0;T6okewV_dr@#FS|-{v8&4W8mAW$LP8(aO;&C7`XS z@HK)Dv}l@JA#Rn$n~^%_K2y#d-VSVG;5^ctSRN%l6_t(ddK<_~GoO0uhrs92rk_lY zi_YK3%Ho-P@&zj=mYSK9pjdaoWx`8r=jrg!2&*LcvAIob0mSYG2ZXWw%N`@edKKGe z;mzb?G#!Vvb7gQ4AbJbQZPuYu0Q8n?0yMo|$}mtGTbrEhjMecAoOT`rwN`E`zA zZP95wkSRJ@Xz{&?Vt zRa)jscvsOAG~k4$OUqdn_Lv(HJMu_;Hm*o{82BRXeY@aTkJ z@qb;=d!}_cI{StMoEt&ld43&{>2Aa`O5) zI9wzCwWaHuRO7@gH&xFj&Stxj!9L%?P;VcH`5w9#!M2M@oL={JtJPQevi(mmCn*Gx z&2_rC#?BRv<*HT@F=-ph@BaKZCCo5}ik$vmX#TYaF<%nI9~mTuMqesg!&DCp2(VU} z*z<+mP_#IJ+C%dT+G#QCDG3un2;(ieM4 zAPQ`70!@z%4TvD5{Wpe%2;PR&HM8sSs-1146O$=noGwKrc3G)RC~IUIrR zz5`K`4cH`k$a!sP-fWBQBn_p*f*B6@y;qR5(_)s^Kt$p$4K(f~PnJPCcor0Vrp!Zj zYWB-OH~@$Qve;Ii$8sD0v2_D>tRY4l28`*6{tCAOLGsTv(GL^O-kts7qCmFbPk!0{ zj$T3_o{-=3m)kG4njzOWX@$snF#fD3KRDjY6-L01kWzl{dpVy&8A%UQxb^~%7Viq# z{L^|_Cu$!Vhp;4!|HX^@w&{h5gT!`^v1vZ>)ZP7F^85n8jvwva(>z47DQIA{t$O_k z0*x_g!7)r!u)ITvr1GmS?>a63TIvV-B<--Iu^J&BQMO9RE@f(VcdcWkro9Sk6>MBv zC{B6Df&}HQO6T|9V{*@!W7^HBiO*7|g0~HZq1!$P&)OsUI@_Ye=RLCW0ug$S29d$>J(>W9R zW%xNk%ZV+2NXnXk?3cPP1Q(j=3H-}s0yp>`XC(9po%cE2l%3lDkw$qxaUow0r-NbO zk*Zm73H^??pd%=m--v|lM2v&4cQQXuiSYiR{M{1N$1^W0Vb^C&?#x+dHm##v8fk!a zc(aRkUiY^@&yA>NgjpKEZbcU~V_e*lJ0+ZlT}ehooi~ZA<2N1{Gf&?DlYUT$cvDk= zLxs=R!zyW%On7!bq1^DU`SbQI+oE`Y*G@7-mVO#Pf3$D}Q1_MB_Z-ZxTC`5w+w1dr zQsTzZqHe>O9)!3c`_;Ufb7mFFmi?BWuE(;i*BYxMer3(1{VeS@z1CMJXm!KmYEj|C zQ5WVxAdYK90;i%JwZ_adm11mp}EP7n0kVd7>fM7ENVa`?T6_VTQFJBT`ub{FaE zq~#?r+tpd+-e$jwCnPIH%xaZ8Mm|G{-I-w7lAO{`hkVd`?!L5XfZG!7cJX#J|C*)dP?Fc0jd zxFzQwW4-60eSHCnYnO)#toYY0xy9PC=Yy@H{hjQkD!{Ja0M{h z=GXSVAGW!>FC7BhQZbKO-=u5PIf9pH!bOUm#=Z}>+1@4nxV?bKVdUoDY^X(G5314H zwsQ;xCv7Fvl9_O5I~VHrp1ojKYy=rd!++DL+7@&=Nu52NkGunMT{QGh-NHc8WsF|(J!vw*0AF}7kIC_DT|8(xa0K0Q)T}Khr=xSUz~e%S z{Inn?;QRS979f75mWPYDJ|BQJ^gZni*_;k|U*9r?1W7U^ONk~%s5h_c2%jD{N1sna zm59hGM&cDWW^VwZ#e3yxHg`qjboniA%OkrQit( zu8o1cT0Z!(QzBbM|BuFaIOlS-)2LIF{!D`jer56JyG)b%*Bi?6J0r8R(7rGggme6i V=0Y3_AOE>PN6S$2rMg|je*nyqJZk^| literal 0 HcmV?d00001 diff --git a/contracts/icons/admin.svg b/contracts/icons/admin.svg new file mode 100644 index 00000000..fbc05717 --- /dev/null +++ b/contracts/icons/admin.svg @@ -0,0 +1 @@ +Admin \ No newline at end of file diff --git a/contracts/icons/multisig.png b/contracts/icons/multisig.png new file mode 100644 index 0000000000000000000000000000000000000000..00fa7564c88ea2785f53d641f150b32ec68a7b47 GIT binary patch literal 1411 zcmZ`%doqG{65Om;k{$VjOf%}jL|q`{EKZ_{CyDS4zk z(jazeJThn}$`&WHgx7r|KPRBU)0;w2-ok=^j-Q{e~v!@bbksTMV)7UQT}8uv~^<) zI$fbW_lQS}W+oVL*;zwR1mJXycr06F{D&lRfmxK^r3bp`3GuFvkN6LW)?nAOQ93fq z{NKv|vE^}24I13&Wh`o#ToS$=*UB6&S+wz!O>_dYbMCipI)V7ntxsjw*ty)zAVSf@ z&_Dim2n9$=tBf-Io~;tQ+n($H@(}~A^u%D4Pc8_u^V;B0OaS5lReOLObZmOx;;G}#;8*|+;c2be4I3`gN zhA*dU-77eHcf@h4FR%G z^aZ0lMorCFr^CEtC{Ygw9Xv9H7uht5$`Kn7A&0(ix?>tq_wz@c;Czv+$H0B<@fC5_ z9^O&Zp-ZogJ!__ydf~*kd1zwdI~!h10hy_Vp5G`5#au9wFm3rbh33#LfS1xF(Rp3d zJI;SCx#J!;ZMoY>*CG>nzF~t|Qfl^Un0IA!!>OAI5=x`k}(g&Oz9Nt*cBh=0VG`vkBgj_>ji16&N=NetoxA@plV?sUDV0z&_Nds zzHBn;p*55~yBEcF0$Ep$~xv06jiA|H79p$LBE)8|Qx+v=u(O)N^t zRtH#rkk{syuG>An9-Go<{SB_$5xc_H^jz1y*RJg1-A7NY4@lW*x7xn&+;8m~?QvN>T-E3}C(Y{}`$>K-Ikm~!K&AM#mwr|S`X<*0X7g}z{(qH(X( z31&CWc{@Zxd}+R_Q0^=S3M|f29sr(*nyMR5^)AyiJZyIQWmk5p1~sg^zjorepylGp zgj$P1Xqrvaelf)=g)FDMUFW5j)@VI^UT~$UKB*WO%k%fCyfRP-|G?X8V*)#&nfEj6 YBtQ`z6CivXCH{CNh3rMDa-pC88^Gy0WB>pF literal 0 HcmV?d00001 diff --git a/contracts/icons/multisig.svg b/contracts/icons/multisig.svg new file mode 100644 index 00000000..d9167fb2 --- /dev/null +++ b/contracts/icons/multisig.svg @@ -0,0 +1 @@ +Multi Sig \ No newline at end of file diff --git a/contracts/icons/resource.png b/contracts/icons/resource.png new file mode 100644 index 0000000000000000000000000000000000000000..8e1bd127de7b7adb74c5d5765db70a036fd0aa8f GIT binary patch literal 1913 zcmZ`)X;72r7Jk3v3rUbAhzdcFutg}ftU*A)ghh$S9s{zJkjPRZ5D~&=hYv_)5n2{6 z?uyE-vKAEx2$cwEr6L6t1QZDr1=%H(2(sKvXYSnktNTnXHn@iK#cQN17U1Bia1wiuy-wzn?2E zO-ntqxw)ymt=dhtt`hI#;VVnOFkn!9fenCME8UsKNE(_M9=v~(qySh)w|l>qrVZJg zWJY=qo{cPeD#^dHs%8Ln%;nhGqDbIxAel~zjS$&rI~(y%4F0VbW!k&0TgYU^kI^7QI zo*6`4>LJIf#+h74bp(8*sJsY1!NVw#taO-eetMQ@tT+L-otSu);kn-hVIP10>p&D- z3f(ul5tG}Q_^k1w;Sgj_HPvB`hA@^T9_6g|-^@hd`i`iKiI3SI`ntBxSRW99d3O=q zP5Y*IHc25^-aZHs&RbzU_E+!a%=;B!6cz$hjRN~GWCf%jDS&qU;SLoZ8BL{^S$aMJ zvG_a2q=_yQ)9i6ctQ@I7HuI;9O=%r|ui>TGwPKO6hz4YLz4g#>Mbg>nB%;Krc;k zR%ztmV@_fbb&zA*#|GXLy9WX(st#$xl9iKl-;X;oRU=Wg!l=im;~e%!TV7u)2*HSA zQSEcc+%3+V}|AVxANkq;~ra21-~uijQef``8a|4 z&-&>(->x)nJ4`Nvz8<3-<7@ax=_uSgo-XnV9yzzx$BAQd2|&#x=RFpP%){dFU4g z11agtk9rcj@~uLuaHTHZXKVOT%3c;JGhib60d6~$g|)86Bbc56s5^jyR-C4nn8R{BxO?@e^c|@teZ#tpFnYf3RS&Rs##B z%BcGvOhC!--W#CfiktR-Pu<@K&lU2b6nVw2ED@3mPG;xqYtw{874!0{fhjgw&M^!U zj%EKc(i?r){I2GM-J;jr%Y{%&>tmvt=)AdZyc2S#U6Ez`1{~7EinU@8T0d-9ZGU%D zSUt-X8aJs$H=l|QrIbPobD(7Q7nS=&`YmVoJcrNkYaiBSJ4N+EnJG78OmCF zZzz@pBbvzmLMdv80n$wSGfzd7Z0|j}&X8gk__t4`IjLr_pJ*%1xf7|&sZRZ1eAKgfsSDGj%m`;!J#Cf65piZ5<5Rj8_2@Y8)GI^_-~#s_AB12g`?0(nO|i|= z6Ud<^(@2>m-riQ(?mte8aom~M;W`cD5rF##;vmb`SZ9cY|AMnmyAqUY7IRlA zQBl*e^=#?A5N5W3!wvOd3raS|O&oszyqWP%t4 lQzThj4saQu7QLp*0xy<3x9!Ue2$20bKzH$Qu5n~#{0CM4EzSS{ literal 0 HcmV?d00001 diff --git a/contracts/icons/resource.svg b/contracts/icons/resource.svg new file mode 100644 index 00000000..4a475592 --- /dev/null +++ b/contracts/icons/resource.svg @@ -0,0 +1 @@ +Resource \ No newline at end of file diff --git a/contracts/icons/rex.png b/contracts/icons/rex.png new file mode 100644 index 0000000000000000000000000000000000000000..b43ee27fcf6180649c35b0739a74e37bc34d08ea GIT binary patch literal 2770 zcmY*bX*|>m7e4=)F=lKr_9X^c5*pdU7$aMjkmMapLP;fYBfI=YtgOC*`shx_F{&xhwczu!5}^YNUEuFiJC0&)TXAZ)+i+6@5NY7rn{ zwmIs4FD$=YE#O`*&*On;0F1VU3a0Dw-F=0SD53$%h6o-`sH_D_A8ch#^tdT zKEty!sZf3nV(yfa!Zl!?dcIxo9`HcP)R{&)1Oy3fc6fSMIq&(1B_Vl z9vCd8kKoYcgTC3-#_8;0wER>bww2lBt6Kk@pln`Lf;ip7hNvjC92ss&3D|ulEl(Ze z=g~-GEf8mo?R=us&+#H~=#UTi(}%w8D!4AJ ziwjEP(Pl5qv6_d10a(|$$}Ibz0V&?0Dbv;zpRDelVo>O7@S%%vtzdIHP>oE$Ugqb} z8r-$X4)G7v>8pF1?9eNBhmS5U8bD5?C_m@>#u;ek_7@^WcAp6kN%nwnkUx+;Duhd<#r}b%ahfm5zo7o0+b>f#0>Z5LazX`u=S0hD7o&S7-kO=pZADN zUe)>}CQ8f}=U+c&Q7QdNh0ZT^oxl*EqE7473X)gnQbjR&Bet^$rR300Jpv^|@x2*n zwmnh642bL3(vnO;o4^fnAId2vK_bqlCZkh&lV5Qjj>w7Y zwb;BOWr`#g?HeI3-T{_*Ouag2@2+#o0_sJ!5l|TTeyDJYoKZ(KyQNR#06U&!3)-{v zK6SwCO!5F%&Awg%RJKFT2n!vnMp!?1>ZcE}`XE_( zbnX@&&a?)fxrB~mDF%;hjD%M{xizi7a8n}-aTV*O!zj^IGQ!O;MFjws@uJX4X zr5Q`<_vTjLz@g^1Hx~~LaGht@s#2Sw^FWOdhW@R*z50d#YIu)Vpw%3CIgIPE2WGC% z1|ClT7ApTK4=)l$Q*0CP{u{LhR&te-6qK3V%Zu`|Leg2~nHq}sYNWaSRwa)S#^xidGr9HoJ_54o9nUqrYWAF>1iALlq5QiS(w=tDnx!q^*+Sh%T0Rl{>> zo?H(+DC9T(lL4R3riAZWPWU}2G_AT+^n6;b%3tHL{@$KYad?!7yV}>gf;3%y5~zcO znGdyGJWD{!2}4HS)mVt;gciPq3Ug*=+6xb{$Z4o@0R=r`)>Oct-VU7K!;Ve6?zjU@ zp^e#WfVFFn=8=!XvBuOs@XMPf3?2_|kha-{jKnI=B;u~<%UyU~Sl4``;5KB`dZ~}j zZ(Myiq_O)(ATF935kjJ={-feT?acRJBoVmk?Vp|1^kN&cJMS}Mo6OXayUZn$N{qeE zgqx1YE!?IN5wG=h?eP7C9}utJsNG9w{YNm|1B*&C5ehLkj<%+h?a#)dKUdr<`hSW4 zXXZ3SJ25}w5`@N!xSFqS%6={}aAz;8lnZfQ??4GOt+0g+ws>RdNuXsd?3$M-Yb+eg z^lGaL7BV2tYx?VH$9}`fD#YvMnLvhpbi%MIMe5YvGO0i3~7QGl!x1&d z8+sbY5?ZX-znKhYICdHvIDStr^4L;%p7E3lp6pQb%r3ZSV%f1XZACv2G(HMntU|!djWZ zrYBR>M%8>ac(6jLGT8;o5Zt908(ZW2eqnY4P3{%8-ItYX!4JI6v>;_4YU0+N!3E5& zj8AqEIo=A*&5GuUXJN?v{OG%|UmGSELUt-)vP*)VW6-=eu@xeVlskURE0uSaj+R{Oz;6Ynl5@#v(UT4GXnYzEt1K?OwB*S$u)gE=y-K3yRe#M-CMh;r7~5cvHbo`3{)`ugOT+V%Sm3yzJ<+A zmDyfca^F%h{_4s#{DoK7JC{c(7Tu;U7ymFXGPoSixjN%y^vl7jP~@vOWUi28qT-lg zQR7XnC2W2?Urk>q5d#bLw{OWUc9~@~ zzjHsH->t&J$xE_wm=WEmtXgGo#`!$MarDBCn%1TZVB>tP&P$bE2{dNTWPtDv2Y-bN zr9d4cO}J|XH#qEh#>ctc%u8|1^nCKvFwo_86)?8B z4a|{_|3|m0HK-CN`(2PaLz>`H{I?CMg&@)I)!Lp0+M0hMP4w$8=Qw7D_P$^E!x3O= z|N8Ge;=0JTrCR^cj)_k^I2XRUJ*&wJd>x t8r&`rkbbJN6JuapUk~*lca%q@K$2uhugGzw16vOy*xNW;v-kNi{|A}y)Mfwx literal 0 HcmV?d00001 diff --git a/contracts/icons/rex.svg b/contracts/icons/rex.svg new file mode 100644 index 00000000..99f77f37 --- /dev/null +++ b/contracts/icons/rex.svg @@ -0,0 +1 @@ +Rex \ No newline at end of file diff --git a/contracts/icons/token.png b/contracts/icons/token.png new file mode 100644 index 0000000000000000000000000000000000000000..445188a0247749231e2de8832ac651a32a9a6c88 GIT binary patch literal 4268 zcmb7oX*d*q*!6GBV5~9rC5FZpAzLIGvX2n5?~MFO_MMESgo^A-*_EBL??Yr~vhPG? zY>|B{Pw&U~+w;d%Q$s}`0LVWI0dVL)a49n}{0D5_ zswUnBZjRo5ww_p^)Pk%mSUq)ER0-;Ya5|Kv8jnUlGu z0AG2!9ROGMG*y%g{b#oJR=e%NkTJxv78Y111BeGA&ekumw{`I;dYHHjAx{s}-7Ln}3Bt(KS|&0lveF zRY=-S#sxQ>@39v|_5x+)exu`$3b2wo|H?{Df`7&`{Ffsl%%noASW*f8dQGLKsRC>55%1;(oNnx6AZb)7ashKrZ>mKXbS@7YLxj;) z4m^-yu$ z$WxjJKWoZp=__S<$ubYEKqVKDo@R03=APv>X_bPsYu z1-|I3qiaU2J?$>7nSY?R*O748{Adi$>1oZH_Hr4o$?Q#vdmMts&hT-NM$e<)UT5T4 z!4M|qzD)|5fTF1{x`YEQ5{asZ><{Q63kBpVs!ig&E(@|b&}ng(4tl55%h z8q9G8lOZ^`zbKfCKP@H2{5MOFBzN#w;N9J0@%qa>b3K709Q5%s*Cg`--@%K0rZ!EQ z#>_3Q7PLaDd?+S)w+ETiv6c|WfP{Fi?GWE{S8E}Dv`W6fxsl={Mv9XG(Q0wH8QUU3 zDPlV-177o#mB%cE@E1KWe3MhJ?Lq}MnmoVRqaeP`6EL#`NIc?2zU$!WPVGB_Ht!uY z=QZ=MvcMPTt2-|^rHkb)RVwC~iMa=9xQ$0*u8s{3nGtEpY@t$M5enRa zGXKm}vumTg_F{KKOW0(7oDXoan(rd;^`n|(NOeYXDfo(3CQgu*sgxpbk1-q2UCMJU zh~`khBP|FY?wg3%PUhlornh47b6^PZ|)E{8;|a zwdbos!H1(!? zE8va20=uy4d$2{UV6TCpi$AArCG43BoZ6&fz;vLX`wjP*j3Dwd@i0e)g1}(3!_H_6 zT%9MQZ-Y6Vz(!H`S{CU!U~`7TKOC9X;?%l%<{y2fj2^UMU>XU%#p11F?6a+1oHGB3FsIu%-@fM|sDW!?HIeU*CpDLQWRP9~wk#KNEcI%; zT-*{6Q2DmnTJ}h0Lx~0|U~bHZH((4+20Dn3ya^K9x94%~lN40Z)TG{i;mV6OJ_l=P zp=XW4lvi!~p2|b3e7kK`*9RTCeJ1sfeuZ2k-{|NQR1J(c>KTa~{J7pED%WSd3zQo=?8?17P8E`>wN5slV41hFp-g z1O^oji=35)bKm5P@u>JDwIkY`_PA-u$&Bv0Y~EBcfm1`!V;mhA*U7;~i%-HlNms!% z7a0CL%qgRR#JIgC@Hu|yqyMZ@KJ(fV_=OPWh78zv72P{>m z&$Px6BGhqYc&o#?$ix5*q3fG@$&-|Ng1Gvrp3^S1w=#3whz)g|%EUCIBT%CQK=2hhsU z->NImcwCtmeqZf9Iqpl3RhPMw!GZeqOg`(xJY`}paIfMH`mdq+OO4_Ul>d+}Tu$G_ zN8la{ZBn5^quyOrSQ}%4TOZkopE-N=Y`#9mRU7_632a$RXJX7J^v%qbU)&x^f#9qe z$|jGt6xy#EAQI(3#;2;62<)u{XbrMbn z+Ziqbe?Q>{mrLEvm2_P`nG#*x70!tx6LXanLEB8%*SEQTzg^8G4PJiPIP>*2WtXb~ zhUz}5EqM3hSFknd3En%sX#E#mo&-|Gqs}FwONSDqhF<2IWIjC6=^08DbL?`tjf+QUHF!065gcuHW{b3SQPg z?R=f$nMXH&yxHR@qtz+mPbk+jr&!~;@#nFnz7t6V8Y!bS%t>0ZE^UzfYdV3fd44_9 zUAZ9-m9izsw2q^>cEI19TgNNhY%yBzhl*r&{es$OWOFcVp5eQ&kKJVbpdz!q~l2G*7Lj& z{MS2TrWD^|)N~R>V|s7WeTRBIt8(Iodk^040$u9zMI@6iy`n|lG=2H-o+A&VSjA{$ z;)PI#k_~g}@p5R|qeUP*2=C(LP`{Puxea))^EpY# z0Z4^veeYKJ^U>qFQ;gg7?91cAa|6X4atxe>0R4oHZh2c~th#~yb2IfZM>NTgydmH& zh2=R@1={x=YI6G@VnIWielppQSWu)^z;r)Ln^{olMB@-uxc(4~Bb2XXP?7u`FK7TjS-H9S3yT zn=^m)Mfup~hr>5vYELxJk_6KX*I%djn~I(x{eso9bL}UU=D+5jmq|HQ8J95fWnO=H zEom5&OFUnhVjFwJeB161Um#~!<($i&nUg*fpOFy5uGZF`sbi;c3Q-qd{`$A)otWf2 z4PhpF34?(;gkt(gcv6_@fYnuDaV<;02LA*{sPy9QpSWk!IY&XsFtcq@` z`53dhM^XdV9~ApcY|@u(wO6FAqVGt2;!WIbDq3I@986_!2ZEICkH7uT#ydewJvN{wdyWOC3iM>?NTUhH=0JP7lQ6dG1htW^pk@ux>JOsKRj zMoGs$%<;YdvtFN`(Xq-AS<%gxt9OFQO9(C&@<|5qID;fW;i>gI*(_``Hq8g3T{8t zdngpTX5G8-P11=C9$!dXuoyj8&ZoUHZetsQF6T&%6l4#`fzD4*XKY4GTj z<}wt`2)ni2Gpv?u(ANl+z5Fg)Z>FGLleyS+!noQe#_}cVV%(_G^#_&eL|}@IEcYfy zV|y{q_7C?H`grRPq#J<>y6(iNd$7wC3~DVg=D#;QHoxM=B}rp(rcZWV_}{uYzyGOw z5^5%(y3sf-%vMSdeeu@kDuc|WwkiUVu`DmtPpv1xZTa0aEA%~clqPe>tu7W;CCAh1 zGcn_MvVD;YJba|mPO@^o<|Q=t3X#CBGguW;IOw=J;$v3O>8W!8ZM&iVydip_Z-Xh$ z`(%I_$FG})en|w9&yj384DOsgfgsUI|(o41$+C#M5S=lkf@M$U1mYh3e zL?LBYQJL1UR`Pd3KRd4t>z?M*s;k}AD|ap=in>Qh(T)3(0do#; zFLAxK-t9Tu5R*M9k_k(7RVRt4?m)WQOS_o~y;ZA33kS}c z?xcR`DdmD`F93=WE9Q4PUKaIGLzXc)+LiDAAm-!4;z)7?u|1h>chzWuIDs{5ODAoL zJ2mIN9%vJMu*Amv-qp{(N1hYsM)#yD5_|I94Z19BEPEicMdPx57;M0>A_LlN)5<5; zzltv>glZD)+iEX8CBfax!2fk1Ke=mp2^R-6A$&71GmZIw)d0{`)lsQXwh8|qT!6zT literal 0 HcmV?d00001 diff --git a/contracts/icons/token.svg b/contracts/icons/token.svg new file mode 100644 index 00000000..67ff415b --- /dev/null +++ b/contracts/icons/token.svg @@ -0,0 +1 @@ +Token_1 \ No newline at end of file diff --git a/contracts/icons/transfer.png b/contracts/icons/transfer.png new file mode 100644 index 0000000000000000000000000000000000000000..d9c021957516ff0e1873a54feb4f40f547c62bed GIT binary patch literal 3856 zcmY+HX*ksX_r~8d24fgI*%=}VjgTSB*ou5j#{+}iwD z_yhE<1I)Z#0`A%SIRkAcZwF^FLr;5GXH#c;r(oY+XZ7QdBEiU9UtiNQzzfRHE#2JQ zGP!I&I56zy5O~wleR1Je{Nv}1_3tLer_$5%LPO#!O6$5h`i_o{g!x!RkJmW@OpVQs z?f)wvS@FUF09H#wJ#F)#@4s`F?-!nCfwcAX^;?h1G;-?4S(76ndo@Lo(3Kj;ZRIJZ zyu^6BU!mZLZg1TE%a2j#3S}zURW9eUZaaH{unTGaG-pU=y8`79Pl1T5`=EU8DkETg@!bX*PBj zp;KuUhF*T8dJZS)u9YvXDOJ7KWmmteL2(hoZO#KPltObZ_VEwN(>fR0i4$i5 z1~e?e@31vp0S&q{D$msJ77-D`3qkX(!6l)38mMln{VRtb0yr2DtgQM4-rj{lJwmSyMa- zQrkSdb{x?~!+4?BR%d~ja#RF6P%KFYK0=l1;-;>XM@zt*oe0)^+qOFaCwx2@tjoE| zp@<5eO#QB~{$8{`EaTSOXJL<287W10eHe>trhqzpo&}=9CJ~o8p)*xPZZ5vhfDc4* zBCs`uTe4wwB2a`;sSx;>Hnj0^6HPjeg{F)xSSVGG&>bLuFp5*5YXJPkFw+iYa+JbS zvUsHHVSA0S+`!7NPtJI1L;%<)kd9vHalqLvFojkgA-Lvy376O+qfxlE*6|1kHu_)omEJZAWM&IOGE%U&E;p$&gn5>frJBa z0_8rz_TG0GZZbiM2BiaZ8P&a`uU_+$9{?_kT~#zuyIAuTn#6QC)Weu3GpEW-*-CO( zqL!za1dFzcz5zWPK}$a=neoczBk%)VUZ^1JYKMX^-)Ec%l(-|Z0QwtwOs-s!Bntsj zqSs?-=XFtA-M0z%l^>uVw$S)q?br-ng3Cnczu&GG9`NJ_G^f_!9y-HNx; z+b6NF(@o81m9D_CbYqVGa%j?fi5vQRPu7zWd1Iz&CPc+~s^8-XYp;XPdx{wBOfiT|xjSD1+G<^&Aek1b>Y zq>;6R<1=S^EZR%eOjU-oPP{h?v7kCB=}wn8K09?209|HAy@tT}MKvKMWLCQ}J$BuQ zIL4C>Sa^lX^{6;yY=k3<=taCQT~$9l)o5bmAtp@7dxKiC&8B^d^yiD|=~XF7_ErF2 z@pL8JTDjV6q_;Axc%4cyPo5#@*1TuEdAojnbvC@ie8 z66O>;uG5!(YJ5QdhnzmTQlj=va!L;-g_lO^Xvt5Cix3o+=01uaicn6nh3I~2xHOU% zm3i*<&8&k$>%?8)5`5R6%B;s_K;<47DO4+RbS*ZG_nce))XEx(ff7@-UjA#%=AfXp_kR!Xp5`T4 zS*H-RZz=w<1I;aUhHqLq_Q<^9b$9`>=lRXjZI-=U$dr|K=~J~qte5rL0(=VmCHZ@6 zwZN<=4Z+wXB7ZPGd!x90gZcqgYON6IL95JDA!oSXwo*P4=0qi?Fkx&f+ZKh2%+$1`{K*14x(~7?3w^# z^~R+?t$&cM5IBT70KkObQMPv}HGfP#hrOPWsM|cu6Xh>;J|ita`kM%a_d!PkkJ>tV z@dU*Lhw)$&%dY?8Jm>imarM^!S=wRRSSy*F)|v2CN?mnA2#<>&PPe%C_0F664kmkl zu>1C_yS*))L9DC&8LALoo@dJ$EjgUDoLglmpR93ignQep(|zW)yjV8cMI|=F**$jP zIqSlIFj51}sI0kViJm13pL-knOb-I%Q zPvzs2Qg`3&It%ME!qL>rsJ>Hw;Hf#7Lh(udXx0X?`AyF|GX&QXE+JhiIhVoF#-*W_ z<3))^7Q0TXcJB)L{dJPRCF4%dckioek%W8JewxJ2ru)IdKE5M#fqXf%6Kb=k^jIcQ zpMK%rG~B!W1rsTyhj5LQU1|1LBNwlK{!T&ZDC&fpIS8*b`l-=|23RU8)Na3`$tX0c zYKyTP@P~=IX-Cw1Q@eCALB<3x)7n!aK@xX~j1P0tjgixaCe=36v3*lg=Zfs6r?xuY zo353UskM7XrN8mPH5`wkui`L~#a&$^%;kmSlQF9e#4nR#ne5{K(RY^9@W#3(YGenC zB>ezu)C~pkIu~iK22M3>zIVfAsYq%jhGgM*ezUxRRW_(Ct)4e>V(VY20_kqVjSsh` z)ySN8-`Qd@og-+5!{);s%@Z|wYFJaXThv=lac*QkrJ$|*64?364H>Mmvy6!muu~53 zj=J~aW!*F8gZI{XysrQKv)Zm={Ad_$%7kgV{~)zNtDscQpFiyEmK>CS!5|CN_MNRB6}Z3A_7x0MH%uom{Tqo z(kGIQ8ArNd)NAhergZB5kJ;#MnDxMAX>!)hwZ9fFJHD%S=~Zqq#ID5DDBJe)qho%; zwFQN$ubsvvV2J$=+d+?DDb$47)8;bSU-T(aq4&jGUcF*==4~$44yc;Zm!Va@nRpn* zbS6Sir;HS*74*VQN9SXE{)gfj)!RXK_Vb^Io)#>T*O4uIVZ4Sc=dfP~BDa^VHBnC8p0|^$qkX$mLyhQ~L&C*#8~1Y7(lYc#h&N6R@&xnLjeh`K+-EgO&+A#;RVkRT^wKqnJdx#C6ZBIpsL zUYqdM0ij{g;QEAY{K7sHt`}FQ(PQT7%JR80uKhwZAQboeeCBt^g8#MPHKH@{*amwG zEWXB>oLG9=Y&YWz)42sW?WIzes(U#CwsSGB>|0mg0D|B*!Z%af_y#c@K>9W(@n(W6 zJ^Oq&&YN6ogUtq z5j{4|&X1B#y#<{35dtR%+mJpa?4&_x?@QX3`q%<$>o4p)(obK+A%!Vakd^Y=Xc zzu;5MASUrw$AuhjXi@6W&5y|=B^@3k%eTJXV-jzp97wNY1sC%J=0dsynYdxBxCfFV zQ_oxgQ&LAYOG2q>A&Orwt`{EuMS+{WJ`cSn`btlTvBP5~wPxPcY`Uaiey6)K680$j zVa&_L{MAIIZw( z%j=m)D1;uAZzZS(=CHe^3C6)`8shg>)G=83Ypl?IEHz@6DeTcBKalAw_W;O*Eht2} zS`v9>TMd|4zPTEQS=jbHoXU@hfcwc;p%Y{Ih?sApkNX1M6+918T%D^yYNwAuXF>+Fh^f5z#0 zDib!xH|D{bWR+HL>PmUAD+orY+#USkF~tj*+taaol{Gsy2pz-8{)3+n0tQzRwD%I_ zU1fSx%#=$$IJRTH*^H}vcOJS?`THy@tq67a9ca!`5{~CJj9IH^(KNx1pxfZ3RD0l~ zhI5d&4f#juV`jQNdi#Y{&$(?$Sc~iVz0A>2I19k%P&|ue*Uuc|Cot4E)~nPZhW`(; C9O3i; literal 0 HcmV?d00001 diff --git a/contracts/icons/transfer.svg b/contracts/icons/transfer.svg new file mode 100644 index 00000000..06da6325 --- /dev/null +++ b/contracts/icons/transfer.svg @@ -0,0 +1 @@ +Transfer_1 \ No newline at end of file diff --git a/contracts/icons/voting.png b/contracts/icons/voting.png new file mode 100644 index 0000000000000000000000000000000000000000..0356bddaf2b0f61f82f8dbd7cfad977e0757b187 GIT binary patch literal 3238 zcmY*cc|4T+7yiEQyk?9gV~J#&uBEhCZuV_PSteN~+)!e;L|UXo$jsY@QYgaB9!6ZE zm0PZP(}KvZBBF$`@6l*xe(s;Y^Uryn=bZETJm;_TIoIgU_L5?o#Q*@3`)D?<06^;y z0;0I}biCZteLX3L+j@q(g&qx$^g9y>tOG**1IhbN`UM5L2Kog=g*63QtT*kZJG$H2 zS{+@-&Ti}U{{m=M{N)dT_|!fdYxnbgQ#q5-{o5qsUXFD+)(HO|U^f{(vnCUX zuOj%5U3L%8suarZF`CikvMOs2;NZ&)q0l7O5A3_dY!*z=q$Pg!_gVh!28gwE$ zKO>PSeILT+ABu=!S4Ay03}wdTBR+9xse7zG%s#kWENX#Z&a-K}JxI&$3CV@dt&Hsl zeXpRUUa>@21e&VUsi@8qZ@9wF_oGS-o`Rr2P%ZdZt0eq^t8W8Q^u@H9%p}j>fxp-i)VcFv57T>AAuwv zhjkOT!HM6xqFl`9apEKrqIW86IsKx09;%G)I~1!3`va@*JqlaMA`E=0a@H}=G~y;( zeuiA-LD+8cXU2g_7mWLfbMle@hd(k<1npQ`zIwRNkSGeOB85V~oa1pQKo9@=sOBuF zm)#WFah?)_Gda~EnCZWa+~+Mq{qh(iCng1Wv8>RiH<-%MbHNGlOt(mFFIqrR!bTu& zs@HhfdidS@uNB+rE*-I)hrTCqb(+Fo;_H~vi# zNB{-38bauqxBWc9{dIP@p1}O_J-cps+>3wVzZ%up^y7m(siFQAbIjPZc{1-tKGO)b z)ETxP-&rBlEX$K*B+0|A4nbc0$K^~NbiekLdL1pun$HAJM#jhB^KX=UkBskRv*ud{ zm#$u^$P;HIropl5mg3{Sdxw{;*07wc;n^CHRiumaFHdeVoN* zPITi;uLR!$n0t$>=r=%$yawl%8F8=*V)Jh^mAEezZI&K`PpU6W)e9+~(49{un;<=F zE4nSKMi?D2V+!cnj(ddy>0k7JoHpT65&H1Pl8k=EukF@d%rF-?^OcnzJ$tM3HI`G* zi)Sdo$-K#lW(FAM+iFa$qg}Ajs(~1O?Q>dhGcldvvw;cC|$ceMeu$NmJD#Z@rRT$sFK`qEw;^$>IWsAdr|K4O2kz}lfah^&J)T)|4Gg?x)<8={tvlJEFh_N1(jkD3 z>=(32!nZHf8vje~)f_u0|uy6Py)^g!i|5zj&EE7p8dAIsZD;W2o0!^iCF{ey`U$#4Iq zU4AMf6DWtO^k%;ZnA|#GzB`5iG9SKgI>Ki5bv18O{W&R$!+v}kJ@HOmPxiJ?>(wVk zn}F_xvu1TCc8|nVbsT4sprm!Q6by5_02cQ36rlt35Sv!1-X#w)1s zVeZ1k*s4`&fYH-%O!+_{|Kz~t><2$v6Ju_5%;Tf|3k!vV9G~<+-W{o(>e}zpbL~Y< z|I(2pyHIw&_cR=xzp~S9Gu2(#&G)_p@D)+sf?JO@(A8O15>F!!Ts=i2YtSH?h42vg z{T1cXRvMsHuq=Th5opUN;AnjmTd?N<3Sx1bz~R} z3wt2ZBAiif1`6o&$yR9ghIZ~Z7YKX9(gbtn)WSpx1QdnWai46QpsLk1D?LFrtK7HfDpcm0_c^~P+*CHe*~qHXn@#>==rUneUifib8N<*odOeJ$A5uBqd;pxF;sPTsK9OV++jI>Osr7RCn?qh*q(g8<WduSs%km^pMATc38N)wR`d0$@L=r`)*MSFzbz0`19v3``tNR<2Aj_DP%2Bp8 zjG;qU@I4*iwdmY(d~)k=eX+ry{_;cuV8DvJf~4W^M13(3T=&fe0n&{fZMip-2qZOk zd-H`&8Yv}%`X%@8K^pj;1A~U6vW*{RJU0=L~FO5=TEVVGwsJ3X(VUpfmcInBgbsrGW{`zwK{rTiTCEyx*GXF!j5(46) zp16iI1B{yI>KLj7zD;*MsdhFd0LL`b`1_v`l1g!B*yya$f5KmjTqT6$nARJr5iCt5 zn~ic(?>T{L8`H5rkP6sD^IeoI_p``c&bG0-%lUqQQ+?~v;GPZx)c1qln(Ssm3X89f Z0VhTSOesfxtUm={pRKdagFTE({{svY!SDb8 literal 0 HcmV?d00001 diff --git a/contracts/icons/voting.svg b/contracts/icons/voting.svg new file mode 100644 index 00000000..fac87089 --- /dev/null +++ b/contracts/icons/voting.svg @@ -0,0 +1 @@ +Voting_1 \ No newline at end of file From 76c0542bd49771c5f2427abbbbb3d26cbd329228 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 20 Jun 2019 18:06:44 -0400 Subject: [PATCH 0831/1048] update README links --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index bb6ecb1b..c610475d 100644 --- a/README.md +++ b/README.md @@ -6,16 +6,16 @@ The design of the EOSIO blockchain calls for a number of smart contracts that ar This repository contains examples of these privileged contracts that are useful when deploying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: - * [eosio.bios](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.bios) - * [eosio.system](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.system) - * [eosio.msig](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.msig) - * [eosio.wrap](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.wrap) + * [eosio.bios](./contracts/eosio.bios) + * [eosio.system](./contracts/eosio.system) + * [eosio.msig](./contracts/eosio.msig) + * [eosio.wrap](./contracts/eosio.wrap) The following unprivileged contract(s) are also part of the system. - * [eosio.token](https://github.com/EOSIO/eosio.contracts/tree/master/contracts/eosio.token) + * [eosio.token](./contracts/eosio.token) Dependencies: -* [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.0-rc1) +* [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.0-rc2) * [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.1) To build the contracts and the unit tests: From a5503824a4834e52650f320752fc6002a953f96e Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 20 Jun 2019 19:58:35 -0400 Subject: [PATCH 0832/1048] remove unnecessary EOSIO_DISPATCH macros; add action wrappers for activate and reqactivated actions --- .../include/eosio.bios/eosio.bios.hpp | 76 ++++++------------- contracts/eosio.bios/src/eosio.bios.cpp | 52 ++++++++++++- contracts/eosio.msig/src/eosio.msig.cpp | 2 - .../include/eosio.system/eosio.system.hpp | 16 +--- contracts/eosio.system/src/eosio.system.cpp | 18 ----- contracts/eosio.token/src/eosio.token.cpp | 2 - contracts/eosio.wrap/src/eosio.wrap.cpp | 2 - 7 files changed, 75 insertions(+), 93 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index a08c9d1c..1f6ed0e8 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -293,6 +293,19 @@ namespace eosio { /** @}*/ + /** + * Set abi for contract. + * + * @details Set the abi for contract identified by `account` name. Creates an entry in the abi_hash_table + * index, with `account` name as key, if it is not already present and sets its value with the abi hash. + * Otherwise it is updating the current abi hash value for the existing `account` key. + * + * @param account - the name of the account to set the abi for + * @param abi - the abi hash represented as a vector of characters + */ + [[eosio::action]] + void setabi( name account, const std::vector& abi ); + /** * Set privilege status for an account. * @@ -301,10 +314,7 @@ namespace eosio { * @param is_priv - 0 for false, > 0 for true. */ [[eosio::action]] - void setpriv( name account, uint8_t is_priv ) { - require_auth( _self ); - set_privileged( account, is_priv ); - } + void setpriv( name account, uint8_t is_priv ); /** * Set the resource limits of an account @@ -317,10 +327,7 @@ namespace eosio { * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts) */ [[eosio::action]] - void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { - require_auth( _self ); - set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); - } + void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); /** * Set a new list of active producers, that is, a new producers' schedule. @@ -333,10 +340,7 @@ namespace eosio { * @param schedule - New list of active producers to set */ [[eosio::action]] - void setprods( std::vector schedule ) { - require_auth( _self ); - set_proposed_producers( schedule ); - } + void setprods( std::vector schedule ); /** * Set the blockchain parameters @@ -346,10 +350,7 @@ namespace eosio { * @param params - New blockchain parameters to set */ [[eosio::action]] - void setparams( const eosio::blockchain_parameters& params ) { - require_auth( _self ); - set_blockchain_parameters( params ); - } + void setparams( const eosio::blockchain_parameters& params ); /** * Check if an account has authorization to access current action. @@ -360,9 +361,7 @@ namespace eosio { * @param from - the account name to authorize */ [[eosio::action]] - void reqauth( name from ) { - require_auth( from ); - } + void reqauth( name from ); /** * Activates a protocol feature. @@ -372,10 +371,7 @@ namespace eosio { * @param feature_digest - hash of the protocol feature to activate. */ [[eosio::action]] - void activate( const eosio::checksum256& feature_digest ) { - require_auth( get_self() ); - preactivate_feature( feature_digest ); - } + void activate( const eosio::checksum256& feature_digest ); /** * Asserts that a protocol feature has been activated. @@ -385,35 +381,7 @@ namespace eosio { * @param feature_digest - hash of the protocol feature to check for activation. */ [[eosio::action]] - void reqactivated( const eosio::checksum256& feature_digest ) { - check( is_feature_activated( feature_digest ), "protocol feature is not activated" ); - } - - /** - * Set abi for contract. - * - * @details Set the abi for contract identified by `account` name. Creates an entry in the abi_hash_table - * index, with `account` name as key, if it is not already present and sets its value with the abi hash. - * Otherwise it is updating the current abi hash value for the existing `account` key. - * - * @param account - the name of the account to set the abi for - * @param abi - the abi hash represented as a vector of characters - */ - [[eosio::action]] - void setabi( name account, const std::vector& abi ) { - abi_hash_table table(_self, _self.value); - auto itr = table.find( account.value ); - if( itr == table.end() ) { - table.emplace( account, [&]( auto& row ) { - row.owner = account; - row.hash = sha256(const_cast(abi.data()), abi.size()); - }); - } else { - table.modify( itr, same_payer, [&]( auto& row ) { - row.hash = sha256(const_cast(abi.data()), abi.size()); - }); - } - } + void reqactivated( const eosio::checksum256& feature_digest ); /** * Abi hash structure @@ -440,12 +408,14 @@ namespace eosio { using unlinkauth_action = action_wrapper<"unlinkauth"_n, &bios::unlinkauth>; using canceldelay_action = action_wrapper<"canceldelay"_n, &bios::canceldelay>; using setcode_action = action_wrapper<"setcode"_n, &bios::setcode>; + using setabi_action = action_wrapper<"setabi"_n, &bios::setabi>; using setpriv_action = action_wrapper<"setpriv"_n, &bios::setpriv>; using setalimits_action = action_wrapper<"setalimits"_n, &bios::setalimits>; using setprods_action = action_wrapper<"setprods"_n, &bios::setprods>; using setparams_action = action_wrapper<"setparams"_n, &bios::setparams>; using reqauth_action = action_wrapper<"reqauth"_n, &bios::reqauth>; - using setabi_action = action_wrapper<"setabi"_n, &bios::setabi>; + using activate_action = action_wrapper<"activate"_n, &bios::activate>; + using reqactivated_action = action_wrapper<"reqactivated"_n, &bios::reqactivated>; }; /** @}*/ // end of @defgroup eosiobios eosio.bios } /// namespace eosio diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index 9a080e5e..f5926221 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,3 +1,53 @@ #include -EOSIO_DISPATCH( eosio::bios, (setpriv)(setalimits)(setprods)(setparams)(reqauth)(setabi)(activate)(reqactivated) ) +namespace eosio { + +void bios::setabi( name account, const std::vector& abi ) { + abi_hash_table table(_self, _self.value); + auto itr = table.find( account.value ); + if( itr == table.end() ) { + table.emplace( account, [&]( auto& row ) { + row.owner = account; + row.hash = sha256(const_cast(abi.data()), abi.size()); + }); + } else { + table.modify( itr, same_payer, [&]( auto& row ) { + row.hash = sha256(const_cast(abi.data()), abi.size()); + }); + } +} + +void bios::setpriv( name account, uint8_t is_priv ) { + require_auth( _self ); + set_privileged( account, is_priv ); +} + +void bios::setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { + require_auth( _self ); + set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); +} + +void bios::setprods( std::vector schedule ) { + require_auth( _self ); + set_proposed_producers( schedule ); +} + +void bios::setparams( const eosio::blockchain_parameters& params ) { + require_auth( _self ); + set_blockchain_parameters( params ); +} + +void bios::reqauth( name from ) { + require_auth( from ); +} + +void bios::activate( const eosio::checksum256& feature_digest ) { + require_auth( get_self() ); + preactivate_feature( feature_digest ); +} + +void bios::reqactivated( const eosio::checksum256& feature_digest ) { + check( is_feature_activated( feature_digest ), "protocol feature is not activated" ); +} + +} diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 4d32ffb1..afb59b00 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -207,5 +207,3 @@ void multisig::invalidate( name account ) { } } /// namespace eosio - -EOSIO_DISPATCH( eosio::multisig, (propose)(approve)(unapprove)(cancel)(exec)(invalidate) ) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 0daa9ab6..58aa3131 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1224,6 +1224,7 @@ namespace eosiosystem { using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; using setacctnet_action = eosio::action_wrapper<"setacctnet"_n, &system_contract::setacctnet>; using setacctcpu_action = eosio::action_wrapper<"setacctcpu"_n, &system_contract::setacctcpu>; + using activate_action = eosio::action_wrapper<"activate"_n, &system_contract::activate>; using delegatebw_action = eosio::action_wrapper<"delegatebw"_n, &system_contract::delegatebw>; using deposit_action = eosio::action_wrapper<"deposit"_n, &system_contract::deposit>; using withdraw_action = eosio::action_wrapper<"withdraw"_n, &system_contract::withdraw>; @@ -1240,21 +1241,7 @@ namespace eosiosystem { using updaterex_action = eosio::action_wrapper<"updaterex"_n, &system_contract::updaterex>; using rexexec_action = eosio::action_wrapper<"rexexec"_n, &system_contract::rexexec>; using setrex_action = eosio::action_wrapper<"setrex"_n, &system_contract::setrex>; - /** - * Move to savings action. - * - * @details Moves a specified amount of REX to savings bucket. - * @param owner - account name of REX owner - * @param rex - amount of REX to be moved - */ using mvtosavings_action = eosio::action_wrapper<"mvtosavings"_n, &system_contract::mvtosavings>; - /** - * Move from savings action. - * - * @details Moves a specified amount of REX from savings bucket - * @param owner - account name of REX owner - * @param rex - amount of REX to be moved - */ using mvfrsavings_action = eosio::action_wrapper<"mvfrsavings"_n, &system_contract::mvfrsavings>; using consolidate_action = eosio::action_wrapper<"consolidate"_n, &system_contract::consolidate>; using closerex_action = eosio::action_wrapper<"closerex"_n, &system_contract::closerex>; @@ -1270,7 +1257,6 @@ namespace eosiosystem { using voteproducer_action = eosio::action_wrapper<"voteproducer"_n, &system_contract::voteproducer>; using regproxy_action = eosio::action_wrapper<"regproxy"_n, &system_contract::regproxy>; using claimrewards_action = eosio::action_wrapper<"claimrewards"_n, &system_contract::claimrewards>; - using rmvproducer_action = eosio::action_wrapper<"rmvproducer"_n, &system_contract::rmvproducer>; using updtrevision_action = eosio::action_wrapper<"updtrevision"_n, &system_contract::updtrevision>; using bidname_action = eosio::action_wrapper<"bidname"_n, &system_contract::bidname>; diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 881f66ee..371c62ca 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -468,21 +468,3 @@ namespace eosiosystem { } } /// eosio.system - - -EOSIO_DISPATCH( eosiosystem::system_contract, - // native.hpp (newaccount definition is actually in eosio.system.cpp) - (newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi) - // eosio.system.cpp - (init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu)(activate) - (rmvproducer)(updtrevision)(bidname)(bidrefund)(setinflation) - // rex.cpp - (deposit)(withdraw)(buyrex)(unstaketorex)(sellrex)(cnclrexorder)(rentcpu)(rentnet)(fundcpuloan)(fundnetloan) - (defcpuloan)(defnetloan)(updaterex)(consolidate)(mvtosavings)(mvfrsavings)(setrex)(rexexec)(closerex) - // delegate_bandwidth.cpp - (buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund) - // voting.cpp - (regproducer)(unregprod)(voteproducer)(regproxy) - // producer_pay.cpp - (onblock)(claimrewards) -) diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index 9d246d4b..a0b5ad63 100644 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -156,5 +156,3 @@ void token::close( const name& owner, const symbol& symbol ) } } /// namespace eosio - -EOSIO_DISPATCH( eosio::token, (create)(issue)(transfer)(open)(close)(retire) ) diff --git a/contracts/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp index debbce11..98b32d28 100644 --- a/contracts/eosio.wrap/src/eosio.wrap.cpp +++ b/contracts/eosio.wrap/src/eosio.wrap.cpp @@ -14,5 +14,3 @@ void wrap::exec( ignore, ignore ) { } } /// namespace eosio - -EOSIO_DISPATCH( eosio::wrap, (exec) ) From f5b6e4d51eeb713fe424cec2f2c1f174abfa75c4 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 20 Jun 2019 20:38:10 -0400 Subject: [PATCH 0833/1048] disallow directly calling onerror action --- .../include/eosio.bios/eosio.bios.hpp | 24 ++++++++++--------- contracts/eosio.bios/src/eosio.bios.cpp | 4 ++++ .../include/eosio.system/native.hpp | 12 ++++++---- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 1f6ed0e8..3fa4a4cd 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -267,17 +267,6 @@ namespace eosio { [[eosio::action]] void canceldelay( ignore canceling_auth, ignore trx_id ) {} - /** - * On error action. - * - * @details Called every time an error occurs while a transaction was processed. - * - * @param sender_id - the id of the sender, - * @param sent_trx - the transaction that failed. - */ - [[eosio::action]] - void onerror( ignore sender_id, ignore> sent_trx ) {} - /** * Set code action. * @@ -306,6 +295,19 @@ namespace eosio { [[eosio::action]] void setabi( name account, const std::vector& abi ); + /** + * On error action. + * + * @details Notification of this action is delivered to the sender of a deferred transaction + * when an objective error occurs while executing the deferred transaction. + * This action is not meant to be called directly. + * + * @param sender_id - the id for the deferred transaction chosen by the sender, + * @param sent_trx - the deferred transaction that failed. + */ + [[eosio::action]] + void onerror( ignore sender_id, ignore> sent_trx ); + /** * Set privilege status for an account. * diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index f5926221..d652ed11 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -17,6 +17,10 @@ void bios::setabi( name account, const std::vector& abi ) { } } +void bios::onerror( ignore, ignore> ) { + check( false, "the onerror action cannot be called directly" ); +} + void bios::setpriv( name account, uint8_t is_priv ) { require_auth( _self ); set_privileged( account, is_priv ); diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 11738312..6ae7a6c7 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -272,13 +272,17 @@ namespace eosiosystem { /** * On error action. * - * @details Called every time an error occurs while a transaction was processed. + * @details Notification of this action is delivered to the sender of a deferred transaction + * when an objective error occurs while executing the deferred transaction. + * This action is not meant to be called directly. * - * @param sender_id - the id of the sender, - * @param sent_trx - the transaction that failed. + * @param sender_id - the id for the deferred transaction chosen by the sender, + * @param sent_trx - the deferred transaction that failed. */ [[eosio::action]] - void onerror( ignore sender_id, ignore> sent_trx ) {} + void onerror( ignore sender_id, ignore> sent_trx ) { + eosio::check( false, "the onerror action cannot be called directly" ); + } /** * Set abi action. From 8391bd43a622a506c97f7292ff958ace732f9e91 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 25 Jun 2019 14:57:26 -0400 Subject: [PATCH 0834/1048] use get_self() rather than accessing _self directly --- contracts/eosio.bios/src/eosio.bios.cpp | 10 +-- contracts/eosio.msig/src/eosio.msig.cpp | 30 +++---- .../eosio.system/src/delegate_bandwidth.cpp | 14 +-- contracts/eosio.system/src/eosio.system.cpp | 90 +++++++++---------- contracts/eosio.system/src/producer_pay.cpp | 16 ++-- contracts/eosio.system/src/rex.cpp | 26 +++--- contracts/eosio.token/src/eosio.token.cpp | 22 ++--- contracts/eosio.wrap/src/eosio.wrap.cpp | 2 +- 8 files changed, 105 insertions(+), 105 deletions(-) diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index d652ed11..8b9165cc 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -3,7 +3,7 @@ namespace eosio { void bios::setabi( name account, const std::vector& abi ) { - abi_hash_table table(_self, _self.value); + abi_hash_table table(get_self(), get_self().value); auto itr = table.find( account.value ); if( itr == table.end() ) { table.emplace( account, [&]( auto& row ) { @@ -22,22 +22,22 @@ void bios::onerror( ignore, ignore> ) { } void bios::setpriv( name account, uint8_t is_priv ) { - require_auth( _self ); + require_auth( get_self() ); set_privileged( account, is_priv ); } void bios::setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { - require_auth( _self ); + require_auth( get_self() ); set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); } void bios::setprods( std::vector schedule ) { - require_auth( _self ); + require_auth( get_self() ); set_proposed_producers( schedule ); } void bios::setparams( const eosio::blockchain_parameters& params ) { - require_auth( _self ); + require_auth( get_self() ); set_blockchain_parameters( params ); } diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index afb59b00..8fd75213 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -26,7 +26,7 @@ void multisig::propose( ignore proposer, check( _trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); //check( trx_header.actions.size() > 0, "transaction must have at least one action" ); - proposals proptable( _self, _proposer.value ); + proposals proptable( get_self(), _proposer.value ); check( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); auto packed_requested = pack(_requested); @@ -47,7 +47,7 @@ void multisig::propose( ignore proposer, prop.packed_transaction = pkd_trans; }); - approvals apptable( _self, _proposer.value ); + approvals apptable( get_self(), _proposer.value ); apptable.emplace( _proposer, [&]( auto& a ) { a.proposal_name = _proposal_name; a.requested_approvals.reserve( _requested.size() ); @@ -63,12 +63,12 @@ void multisig::approve( name proposer, name proposal_name, permission_level leve require_auth( level ); if( proposal_hash ) { - proposals proptable( _self, proposer.value ); + proposals proptable( get_self(), proposer.value ); auto& prop = proptable.get( proposal_name.value, "proposal not found" ); assert_sha256( prop.packed_transaction.data(), prop.packed_transaction.size(), *proposal_hash ); } - approvals apptable( _self, proposer.value ); + approvals apptable( get_self(), proposer.value ); auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { auto itr = std::find_if( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), [&](const approval& a) { return a.level == level; } ); @@ -79,7 +79,7 @@ void multisig::approve( name proposer, name proposal_name, permission_level leve a.requested_approvals.erase( itr ); }); } else { - old_approvals old_apptable( _self, proposer.value ); + old_approvals old_apptable( get_self(), proposer.value ); auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level ); @@ -95,7 +95,7 @@ void multisig::approve( name proposer, name proposal_name, permission_level leve void multisig::unapprove( name proposer, name proposal_name, permission_level level ) { require_auth( level ); - approvals apptable( _self, proposer.value ); + approvals apptable( get_self(), proposer.value ); auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { auto itr = std::find_if( apps_it->provided_approvals.begin(), apps_it->provided_approvals.end(), [&](const approval& a) { return a.level == level; } ); @@ -105,7 +105,7 @@ void multisig::unapprove( name proposer, name proposal_name, permission_level le a.provided_approvals.erase( itr ); }); } else { - old_approvals old_apptable( _self, proposer.value ); + old_approvals old_apptable( get_self(), proposer.value ); auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); check( itr != apps.provided_approvals.end(), "no approval previously granted" ); @@ -119,7 +119,7 @@ void multisig::unapprove( name proposer, name proposal_name, permission_level le void multisig::cancel( name proposer, name proposal_name, name canceler ) { require_auth( canceler ); - proposals proptable( _self, proposer.value ); + proposals proptable( get_self(), proposer.value ); auto& prop = proptable.get( proposal_name.value, "proposal not found" ); if( canceler != proposer ) { @@ -128,12 +128,12 @@ void multisig::cancel( name proposer, name proposal_name, name canceler ) { proptable.erase(prop); //remove from new table - approvals apptable( _self, proposer.value ); + approvals apptable( get_self(), proposer.value ); auto apps_it = apptable.find( proposal_name.value ); if ( apps_it != apptable.end() ) { apptable.erase(apps_it); } else { - old_approvals old_apptable( _self, proposer.value ); + old_approvals old_apptable( get_self(), proposer.value ); auto apps_it = old_apptable.find( proposal_name.value ); check( apps_it != old_apptable.end(), "proposal not found" ); old_apptable.erase(apps_it); @@ -143,17 +143,17 @@ void multisig::cancel( name proposer, name proposal_name, name canceler ) { void multisig::exec( name proposer, name proposal_name, name executer ) { require_auth( executer ); - proposals proptable( _self, proposer.value ); + proposals proptable( get_self(), proposer.value ); auto& prop = proptable.get( proposal_name.value, "proposal not found" ); transaction_header trx_header; datastream ds( prop.packed_transaction.data(), prop.packed_transaction.size() ); ds >> trx_header; check( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); - approvals apptable( _self, proposer.value ); + approvals apptable( get_self(), proposer.value ); auto apps_it = apptable.find( proposal_name.value ); std::vector approvals; - invalidations inv_table( _self, _self.value ); + invalidations inv_table( get_self(), get_self().value ); if ( apps_it != apptable.end() ) { approvals.reserve( apps_it->provided_approvals.size() ); for ( auto& p : apps_it->provided_approvals ) { @@ -164,7 +164,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { } apptable.erase(apps_it); } else { - old_approvals old_apptable( _self, proposer.value ); + old_approvals old_apptable( get_self(), proposer.value ); auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); for ( auto& level : apps.provided_approvals ) { auto it = inv_table.find( level.actor.value ); @@ -192,7 +192,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { void multisig::invalidate( name account ) { require_auth( account ); - invalidations inv_table( _self, _self.value ); + invalidations inv_table( get_self(), get_self().value ); auto it = inv_table.find( account.value ); if ( it == inv_table.end() ) { inv_table.emplace( account, [&](auto& i) { diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 71fb2169..8449addb 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -139,7 +139,7 @@ namespace eosiosystem { _gstate.total_ram_bytes_reserved += uint64_t(bytes_out); _gstate.total_ram_stake += quant_after_fee.amount; - user_resources_table userres( _self, receiver.value ); + user_resources_table userres( get_self(), receiver.value ); auto res_itr = userres.find( receiver.value ); if( res_itr == userres.end() ) { res_itr = userres.emplace( receiver, [&]( auto& res ) { @@ -174,7 +174,7 @@ namespace eosiosystem { check( bytes > 0, "cannot sell negative byte" ); - user_resources_table userres( _self, account.value ); + user_resources_table userres( get_self(), account.value ); auto res_itr = userres.find( account.value ); check( res_itr != userres.end(), "no resource row" ); check( res_itr->ram_bytes >= bytes, "insufficient quota" ); @@ -242,7 +242,7 @@ namespace eosiosystem { // update stake delegated from "from" to "receiver" { - del_bandwidth_table del_tbl( _self, from.value ); + del_bandwidth_table del_tbl( get_self(), from.value ); auto itr = del_tbl.find( receiver.value ); if( itr == del_tbl.end() ) { itr = del_tbl.emplace( from, [&]( auto& dbo ){ @@ -267,7 +267,7 @@ namespace eosiosystem { // update totals of "receiver" { - user_resources_table totals_tbl( _self, receiver.value ); + user_resources_table totals_tbl( get_self(), receiver.value ); auto tot_itr = totals_tbl.find( receiver.value ); if( tot_itr == totals_tbl.end() ) { tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { @@ -314,7 +314,7 @@ namespace eosiosystem { // create refund or update from existing refund if ( stake_account != source_stake_from ) { //for eosio both transfer and refund make no sense - refunds_table refunds_tbl( _self, from.value ); + refunds_table refunds_tbl( get_self(), from.value ); auto req = refunds_tbl.find( from.value ); //create/update/delete refund @@ -383,7 +383,7 @@ namespace eosiosystem { if ( need_deferred_trx ) { eosio::transaction out; out.actions.emplace_back( permission_level{from, active_permission}, - _self, "refund"_n, + get_self(), "refund"_n, from ); out.delay_sec = refund_delay_sec; @@ -459,7 +459,7 @@ namespace eosiosystem { void system_contract::refund( const name& owner ) { require_auth( owner ); - refunds_table refunds_tbl( _self, owner.value ); + refunds_table refunds_tbl( get_self(), owner.value ); auto req = refunds_tbl.find( owner.value ); check( req != refunds_tbl.end(), "refund request not found" ); check( req->request_time + seconds(refund_delay_sec) <= current_time_point(), diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index 371c62ca..afcd0358 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -22,18 +22,18 @@ namespace eosiosystem { system_contract::system_contract( name s, name code, datastream ds ) :native(s,code,ds), - _voters(_self, _self.value), - _producers(_self, _self.value), - _producers2(_self, _self.value), - _global(_self, _self.value), - _global2(_self, _self.value), - _global3(_self, _self.value), - _global4(_self, _self.value), - _rammarket(_self, _self.value), - _rexpool(_self, _self.value), - _rexfunds(_self, _self.value), - _rexbalance(_self, _self.value), - _rexorders(_self, _self.value) + _voters(get_self(), get_self().value), + _producers(get_self(), get_self().value), + _producers2(get_self(), get_self().value), + _global(get_self(), get_self().value), + _global2(get_self(), get_self().value), + _global3(get_self(), get_self().value), + _global4(get_self(), get_self().value), + _rammarket(get_self(), get_self().value), + _rexpool(get_self(), get_self().value), + _rexfunds(get_self(), get_self().value), + _rexbalance(get_self(), get_self().value), + _rexorders(get_self(), get_self().value) { //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); @@ -62,14 +62,14 @@ namespace eosiosystem { } system_contract::~system_contract() { - _global.set( _gstate, _self ); - _global2.set( _gstate2, _self ); - _global3.set( _gstate3, _self ); - _global4.set( _gstate4, _self ); + _global.set( _gstate, get_self() ); + _global2.set( _gstate2, get_self() ); + _global3.set( _gstate3, get_self() ); + _global4.set( _gstate4, get_self() ); } void system_contract::setram( uint64_t max_ram_size ) { - require_auth( _self ); + require_auth( get_self() ); check( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues check( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" ); @@ -107,28 +107,28 @@ namespace eosiosystem { } void system_contract::setramrate( uint16_t bytes_per_block ) { - require_auth( _self ); + require_auth( get_self() ); update_ram_supply(); _gstate2.new_ram_per_block = bytes_per_block; } void system_contract::setparams( const eosio::blockchain_parameters& params ) { - require_auth( _self ); + require_auth( get_self() ); (eosio::blockchain_parameters&)(_gstate) = params; check( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); set_blockchain_parameters( params ); } void system_contract::setpriv( const name& account, uint8_t ispriv ) { - require_auth( _self ); + require_auth( get_self() ); set_privileged( account, ispriv ); } void system_contract::setalimits( const name& account, int64_t ram, int64_t net, int64_t cpu ) { - require_auth( _self ); + require_auth( get_self() ); - user_resources_table userres( _self, account.value ); + user_resources_table userres( get_self(), account.value ); auto ritr = userres.find( account.value ); check( ritr == userres.end(), "only supports unlimited accounts" ); @@ -144,7 +144,7 @@ namespace eosiosystem { } void system_contract::setacctram( const name& account, const std::optional& ram_bytes ) { - require_auth( _self ); + require_auth( get_self() ); int64_t current_ram, current_net, current_cpu; get_resource_limits( account, current_ram, current_net, current_cpu ); @@ -156,7 +156,7 @@ namespace eosiosystem { check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::ram_managed ), "RAM of account is already unmanaged" ); - user_resources_table userres( _self, account.value ); + user_resources_table userres( get_self(), account.value ); auto ritr = userres.find( account.value ); ram = ram_gift_bytes; @@ -189,7 +189,7 @@ namespace eosiosystem { } void system_contract::setacctnet( const name& account, const std::optional& net_weight ) { - require_auth( _self ); + require_auth( get_self() ); int64_t current_ram, current_net, current_cpu; get_resource_limits( account, current_ram, current_net, current_cpu ); @@ -201,7 +201,7 @@ namespace eosiosystem { check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::net_managed ), "Network bandwidth of account is already unmanaged" ); - user_resources_table userres( _self, account.value ); + user_resources_table userres( get_self(), account.value ); auto ritr = userres.find( account.value ); if( ritr != userres.end() ) { @@ -233,7 +233,7 @@ namespace eosiosystem { } void system_contract::setacctcpu( const name& account, const std::optional& cpu_weight ) { - require_auth( _self ); + require_auth( get_self() ); int64_t current_ram, current_net, current_cpu; get_resource_limits( account, current_ram, current_net, current_cpu ); @@ -245,7 +245,7 @@ namespace eosiosystem { check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed ), "CPU bandwidth of account is already unmanaged" ); - user_resources_table userres( _self, account.value ); + user_resources_table userres( get_self(), account.value ); auto ritr = userres.find( account.value ); if( ritr != userres.end() ) { @@ -282,7 +282,7 @@ namespace eosiosystem { } void system_contract::rmvproducer( const name& producer ) { - require_auth( _self ); + require_auth( get_self() ); auto prod = _producers.find( producer.value ); check( prod != _producers.end(), "producer not found" ); _producers.modify( prod, same_payer, [&](auto& p) { @@ -291,7 +291,7 @@ namespace eosiosystem { } void system_contract::updtrevision( uint8_t revision ) { - require_auth( _self ); + require_auth( get_self() ); check( _gstate2.revision < 255, "can not increment revision" ); // prevent wrap around check( revision == _gstate2.revision + 1, "can only increment revision by one" ); check( revision <= 1, // set upper bound to greatest revision supported in the code @@ -311,7 +311,7 @@ namespace eosiosystem { check( bid.amount > 0, "insufficient bid" ); token::transfer_action transfer_act{ token_account, { {bidder, active_permission} } }; transfer_act.send( bidder, names_account, bid, std::string("bid name ")+ newname.to_string() ); - name_bid_table bids(_self, _self.value); + name_bid_table bids(get_self(), get_self().value); print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); auto current = bids.find( newname.value ); if( current == bids.end() ) { @@ -326,7 +326,7 @@ namespace eosiosystem { check( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); check( current->high_bidder != bidder, "account is already highest bidder" ); - bid_refund_table refunds_table(_self, newname.value); + bid_refund_table refunds_table(get_self(), newname.value); auto it = refunds_table.find( current->high_bidder.value ); if ( it != refunds_table.end() ) { @@ -341,8 +341,8 @@ namespace eosiosystem { } transaction t; - t.actions.emplace_back( permission_level{_self, active_permission}, - _self, "bidrefund"_n, + t.actions.emplace_back( permission_level{get_self(), active_permission}, + get_self(), "bidrefund"_n, std::make_tuple( current->high_bidder, newname ) ); t.delay_sec = 0; @@ -359,7 +359,7 @@ namespace eosiosystem { } void system_contract::bidrefund( const name& bidder, const name& newname ) { - bid_refund_table refunds_table(_self, newname.value); + bid_refund_table refunds_table(get_self(), newname.value); auto it = refunds_table.find( bidder.value ); check( it != refunds_table.end(), "refund not found" ); @@ -369,7 +369,7 @@ namespace eosiosystem { } void system_contract::setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { - require_auth(_self); + require_auth(get_self()); check(annual_rate >= 0, "annual_rate can't be negative"); check(inflation_pay_factor > 0, "inflation_pay_factor must be positive"); check(votepay_factor > 0, "votepay_factor must be positive"); @@ -377,7 +377,7 @@ namespace eosiosystem { _gstate4.continuous_rate = get_continuous_rate(annual_rate); _gstate4.inflation_pay_factor = inflation_pay_factor; _gstate4.votepay_factor = votepay_factor; - _global4.set( _gstate4, _self ); + _global4.set( _gstate4, get_self() ); } /** @@ -394,7 +394,7 @@ namespace eosiosystem { ignore owner, ignore active ) { - if( creator != _self ) { + if( creator != get_self() ) { uint64_t tmp = newact.value >> 4; bool has_dot = false; @@ -405,7 +405,7 @@ namespace eosiosystem { if( has_dot ) { // or is less than 12 characters auto suffix = newact.suffix(); if( suffix == newact ) { - name_bid_table bids(_self, _self.value); + name_bid_table bids(get_self(), get_self().value); auto current = bids.find( newact.value ); check( current != bids.end(), "no active bid for name" ); check( current->high_bidder == creator, "only highest bidder can claim" ); @@ -417,7 +417,7 @@ namespace eosiosystem { } } - user_resources_table userres( _self, newact.value); + user_resources_table userres( get_self(), newact.value); userres.emplace( newact, [&]( auto& res ) { res.owner = newact; @@ -429,7 +429,7 @@ namespace eosiosystem { } void native::setabi( const name& acnt, const std::vector& abi ) { - eosio::multi_index< "abihash"_n, abi_hash > table(_self, _self.value); + eosio::multi_index< "abihash"_n, abi_hash > table(get_self(), get_self().value); auto itr = table.find( acnt.value ); if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { @@ -444,7 +444,7 @@ namespace eosiosystem { } void system_contract::init( unsigned_int version, const symbol& core ) { - require_auth( _self ); + require_auth( get_self() ); check( version.value == 0, "unsupported version for init action" ); auto itr = _rammarket.find(ramcore_symbol.raw()); @@ -454,7 +454,7 @@ namespace eosiosystem { check( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); check( system_token_supply.amount > 0, "system token supply must be greater than 0" ); - _rammarket.emplace( _self, [&]( auto& m ) { + _rammarket.emplace( get_self(), [&]( auto& m ) { m.supply.amount = 100000000000000ll; m.supply.symbol = ramcore_symbol; m.base.balance.amount = int64_t(_gstate.free_ram()); @@ -463,8 +463,8 @@ namespace eosiosystem { m.quote.balance.symbol = core; }); - token::open_action open_act{ token_account, { {_self, active_permission} } }; - open_act.send( rex_account, core, _self ); + token::open_action open_act{ token_account, { {get_self(), active_permission} } }; + open_act.send( rex_account, core, get_self() ); } } /// eosio.system diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 1c45e828..12bfbaf0 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -15,7 +15,7 @@ namespace eosiosystem { void system_contract::onblock( ignore ) { using namespace eosio; - require_auth(_self); + require_auth(get_self()); block_timestamp timestamp; name producer; @@ -51,7 +51,7 @@ namespace eosiosystem { update_elected_producers( timestamp ); if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { - name_bid_table bids(_self, _self.value); + name_bid_table bids(get_self(), get_self().value); auto idx = bids.get_index<"highbid"_n>(); auto highest = idx.lower_bound( std::numeric_limits::max()/2 ); if( highest != idx.end() && @@ -97,19 +97,19 @@ namespace eosiosystem { if( new_tokens > 0 ) { { - token::issue_action issue_act{ token_account, { {_self, active_permission} } }; - issue_act.send( _self, asset(new_tokens, core_symbol()), "issue tokens for producer pay and savings" ); + token::issue_action issue_act{ token_account, { {get_self(), active_permission} } }; + issue_act.send( get_self(), asset(new_tokens, core_symbol()), "issue tokens for producer pay and savings" ); } { - token::transfer_action transfer_act{ token_account, { {_self, active_permission} } }; + token::transfer_action transfer_act{ token_account, { {get_self(), active_permission} } }; if( to_savings > 0 ) { - transfer_act.send( _self, saving_account, asset(to_savings, core_symbol()), "unallocated inflation" ); + transfer_act.send( get_self(), saving_account, asset(to_savings, core_symbol()), "unallocated inflation" ); } if( to_per_block_pay > 0 ) { - transfer_act.send( _self, bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" ); + transfer_act.send( get_self(), bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" ); } if( to_per_vote_pay > 0 ) { - transfer_act.send( _self, vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" ); + transfer_act.send( get_self(), vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" ); } } } diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 8e737532..34b45218 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -59,7 +59,7 @@ namespace eosiosystem { check_voting_requirement( owner ); { - del_bandwidth_table dbw_table( _self, owner.value ); + del_bandwidth_table dbw_table( get_self(), owner.value ); auto del_itr = dbw_table.require_find( receiver.value, "delegated bandwidth record does not exist" ); check( from_net.amount <= del_itr->net_weight.amount, "amount exceeds tokens staked for net"); check( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); @@ -152,7 +152,7 @@ namespace eosiosystem { { require_auth( from ); - rex_cpu_loan_table cpu_loans( _self, _self.value ); + rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); int64_t rented_tokens = rent_rex( cpu_loans, from, receiver, loan_payment, loan_fund ); update_resource_limits( from, receiver, 0, rented_tokens ); } @@ -161,7 +161,7 @@ namespace eosiosystem { { require_auth( from ); - rex_net_loan_table net_loans( _self, _self.value ); + rex_net_loan_table net_loans( get_self(), get_self().value ); int64_t rented_tokens = rent_rex( net_loans, from, receiver, loan_payment, loan_fund ); update_resource_limits( from, receiver, rented_tokens, 0 ); } @@ -170,7 +170,7 @@ namespace eosiosystem { { require_auth( from ); - rex_cpu_loan_table cpu_loans( _self, _self.value ); + rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); fund_rex_loan( cpu_loans, from, loan_num, payment ); } @@ -178,7 +178,7 @@ namespace eosiosystem { { require_auth( from ); - rex_net_loan_table net_loans( _self, _self.value ); + rex_net_loan_table net_loans( get_self(), get_self().value ); fund_rex_loan( net_loans, from, loan_num, payment ); } @@ -186,7 +186,7 @@ namespace eosiosystem { { require_auth( from ); - rex_cpu_loan_table cpu_loans( _self, _self.value ); + rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); defund_rex_loan( cpu_loans, from, loan_num, amount ); } @@ -194,7 +194,7 @@ namespace eosiosystem { { require_auth( from ); - rex_net_loan_table net_loans( _self, _self.value ); + rex_net_loan_table net_loans( get_self(), get_self().value ); defund_rex_loan( net_loans, from, loan_num, amount ); } @@ -322,11 +322,11 @@ namespace eosiosystem { /// check for any outstanding loans or rex fund { - rex_cpu_loan_table cpu_loans( _self, _self.value ); + rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); auto cpu_idx = cpu_loans.get_index<"byowner"_n>(); bool no_outstanding_cpu_loans = ( cpu_idx.find( owner.value ) == cpu_idx.end() ); - rex_net_loan_table net_loans( _self, _self.value ); + rex_net_loan_table net_loans( get_self(), get_self().value ); auto net_idx = net_loans.get_index<"byowner"_n>(); bool no_outstanding_net_loans = ( net_idx.find( owner.value ) == net_idx.end() ); @@ -362,7 +362,7 @@ namespace eosiosystem { return; } - user_resources_table totals_tbl( _self, receiver.value ); + user_resources_table totals_tbl( get_self(), receiver.value ); auto tot_itr = totals_tbl.find( receiver.value ); if ( tot_itr == totals_tbl.end() ) { check( 0 <= delta_net && 0 <= delta_cpu, "logic error, should not occur"); @@ -551,7 +551,7 @@ namespace eosiosystem { /// process cpu loans { - rex_cpu_loan_table cpu_loans( _self, _self.value ); + rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); auto cpu_idx = cpu_loans.get_index<"byexpr"_n>(); for ( uint16_t i = 0; i < max; ++i ) { auto itr = cpu_idx.begin(); @@ -568,7 +568,7 @@ namespace eosiosystem { /// process net loans { - rex_net_loan_table net_loans( _self, _self.value ); + rex_net_loan_table net_loans( get_self(), get_self().value ); auto net_idx = net_loans.get_index<"byexpr"_n>(); for ( uint16_t i = 0; i < max; ++i ) { auto itr = net_idx.begin(); @@ -920,7 +920,7 @@ namespace eosiosystem { auto itr = _rexpool.begin(); if ( !rex_system_initialized() ) { /// initialize REX pool - _rexpool.emplace( _self, [&]( auto& rp ) { + _rexpool.emplace( get_self(), [&]( auto& rp ) { rex_received.amount = payment.amount * rex_ratio; rp.total_lendable = payment; rp.total_lent = asset( 0, core_symbol() ); diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index a0b5ad63..1e7d97b0 100644 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -5,18 +5,18 @@ namespace eosio { void token::create( const name& issuer, const asset& maximum_supply ) { - require_auth( _self ); + require_auth( get_self() ); auto sym = maximum_supply.symbol; check( sym.is_valid(), "invalid symbol name" ); check( maximum_supply.is_valid(), "invalid supply"); check( maximum_supply.amount > 0, "max-supply must be positive"); - stats statstable( _self, sym.code().raw() ); + stats statstable( get_self(), sym.code().raw() ); auto existing = statstable.find( sym.code().raw() ); check( existing == statstable.end(), "token with symbol already exists" ); - statstable.emplace( _self, [&]( auto& s ) { + statstable.emplace( get_self(), [&]( auto& s ) { s.supply.symbol = maximum_supply.symbol; s.max_supply = maximum_supply; s.issuer = issuer; @@ -30,7 +30,7 @@ void token::issue( const name& to, const asset& quantity, const string& memo ) check( sym.is_valid(), "invalid symbol name" ); check( memo.size() <= 256, "memo has more than 256 bytes" ); - stats statstable( _self, sym.code().raw() ); + stats statstable( get_self(), sym.code().raw() ); auto existing = statstable.find( sym.code().raw() ); check( existing != statstable.end(), "token with symbol does not exist, create token before issue" ); const auto& st = *existing; @@ -56,7 +56,7 @@ void token::retire( const asset& quantity, const string& memo ) check( sym.is_valid(), "invalid symbol name" ); check( memo.size() <= 256, "memo has more than 256 bytes" ); - stats statstable( _self, sym.code().raw() ); + stats statstable( get_self(), sym.code().raw() ); auto existing = statstable.find( sym.code().raw() ); check( existing != statstable.end(), "token with symbol does not exist" ); const auto& st = *existing; @@ -83,7 +83,7 @@ void token::transfer( const name& from, require_auth( from ); check( is_account( to ), "to account does not exist"); auto sym = quantity.symbol.code(); - stats statstable( _self, sym.raw() ); + stats statstable( get_self(), sym.raw() ); const auto& st = statstable.get( sym.raw() ); require_recipient( from ); @@ -101,7 +101,7 @@ void token::transfer( const name& from, } void token::sub_balance( const name& owner, const asset& value ) { - accounts from_acnts( _self, owner.value ); + accounts from_acnts( get_self(), owner.value ); const auto& from = from_acnts.get( value.symbol.code().raw(), "no balance object found" ); check( from.balance.amount >= value.amount, "overdrawn balance" ); @@ -113,7 +113,7 @@ void token::sub_balance( const name& owner, const asset& value ) { void token::add_balance( const name& owner, const asset& value, const name& ram_payer ) { - accounts to_acnts( _self, owner.value ); + accounts to_acnts( get_self(), owner.value ); auto to = to_acnts.find( value.symbol.code().raw() ); if( to == to_acnts.end() ) { to_acnts.emplace( ram_payer, [&]( auto& a ){ @@ -132,11 +132,11 @@ void token::open( const name& owner, const symbol& symbol, const name& ram_payer auto sym_code_raw = symbol.code().raw(); - stats statstable( _self, sym_code_raw ); + stats statstable( get_self(), sym_code_raw ); const auto& st = statstable.get( sym_code_raw, "symbol does not exist" ); check( st.supply.symbol == symbol, "symbol precision mismatch" ); - accounts acnts( _self, owner.value ); + accounts acnts( get_self(), owner.value ); auto it = acnts.find( sym_code_raw ); if( it == acnts.end() ) { acnts.emplace( ram_payer, [&]( auto& a ){ @@ -148,7 +148,7 @@ void token::open( const name& owner, const symbol& symbol, const name& ram_payer void token::close( const name& owner, const symbol& symbol ) { require_auth( owner ); - accounts acnts( _self, owner.value ); + accounts acnts( get_self(), owner.value ); auto it = acnts.find( symbol.code().raw() ); check( it != acnts.end(), "Balance row already deleted or never existed. Action won't have any effect." ); check( it->balance.amount == 0, "Cannot close because the balance is not zero." ); diff --git a/contracts/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp index 98b32d28..12056bf1 100644 --- a/contracts/eosio.wrap/src/eosio.wrap.cpp +++ b/contracts/eosio.wrap/src/eosio.wrap.cpp @@ -3,7 +3,7 @@ namespace eosio { void wrap::exec( ignore, ignore ) { - require_auth( _self ); + require_auth( get_self() ); name executer; _ds >> executer; From bbe07640164448c0dee12a0b2cfd2924645383d0 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 25 Jun 2019 16:54:50 -0400 Subject: [PATCH 0835/1048] compile eosio.system contract with multiple cpp files --- contracts/eosio.system/CMakeLists.txt | 10 +- .../include/eosio.system/eosio.system.hpp | 84 +++++++++++++++-- .../include/eosio.system/exchange_state.hpp | 1 + .../include/eosio.system/native.hpp | 21 +---- .../eosio.system/src/delegate_bandwidth.cpp | 71 ++------------ contracts/eosio.system/src/eosio.system.cpp | 92 ++----------------- contracts/eosio.system/src/exchange_state.cpp | 6 ++ contracts/eosio.system/src/name_bidding.cpp | 80 ++++++++++++++++ contracts/eosio.system/src/native.cpp | 27 ++++++ contracts/eosio.system/src/producer_pay.cpp | 14 +-- contracts/eosio.system/src/rex.cpp | 4 + contracts/eosio.system/src/voting.cpp | 6 +- 12 files changed, 228 insertions(+), 188 deletions(-) create mode 100644 contracts/eosio.system/src/name_bidding.cpp create mode 100644 contracts/eosio.system/src/native.cpp diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index e99eb37b..3f909084 100644 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -1,4 +1,12 @@ -add_contract(eosio.system eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp) +add_contract(eosio.system eosio.system + ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/delegate_bandwidth.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/exchange_state.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/voting.cpp +) target_include_directories(eosio.system PUBLIC diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 58aa3131..1b252d29 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -30,8 +30,8 @@ namespace eosiosystem { using eosio::const_mem_fun; using eosio::datastream; using eosio::indexed_by; - using eosio::microseconds; using eosio::name; + using eosio::same_payer; using eosio::symbol; using eosio::symbol_code; using eosio::time_point; @@ -57,6 +57,22 @@ namespace eosiosystem { return ( flags & ~static_cast(field) ); } + static constexpr uint32_t seconds_per_year = 52 * 7 * 24 * 3600; + static constexpr uint32_t seconds_per_day = 24 * 3600; + static constexpr int64_t useconds_per_year = int64_t(seconds_per_year) * 1000'000ll; + static constexpr int64_t useconds_per_day = int64_t(seconds_per_day) * 1000'000ll; + static constexpr uint32_t blocks_per_day = 2 * seconds_per_day; // half seconds per day + + static constexpr int64_t min_activated_stake = 150'000'000'0000; + static constexpr int64_t ram_gift_bytes = 1400; + static constexpr int64_t min_pervote_daily_pay = 100'0000; + static constexpr uint32_t refund_delay_sec = 3 * seconds_per_day; + + static constexpr int64_t inflation_precision = 100; // 2 decimals + static constexpr int64_t default_annual_rate = 500; // 5% annual rate + static constexpr int64_t default_inflation_pay_factor = 5; // 20% of the inflation + static constexpr int64_t default_votepay_factor = 4; // 25% of the producer pay + /** * * @defgroup eosiosystem eosio.system @@ -308,8 +324,56 @@ namespace eosiosystem { */ typedef eosio::singleton< "global4"_n, eosio_global_state4 > global_state4_singleton; - // static constexpr uint32_t max_inflation_rate = 5; // 5% annual inflation - static constexpr uint32_t seconds_per_day = 24 * 3600; + struct [[eosio::table, eosio::contract("eosio.system")]] user_resources { + name owner; + asset net_weight; + asset cpu_weight; + int64_t ram_bytes = 0; + + bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0 && ram_bytes == 0; } + uint64_t primary_key()const { return owner.value; } + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(ram_bytes) ) + }; + + /** + * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. + */ + struct [[eosio::table, eosio::contract("eosio.system")]] delegated_bandwidth { + name from; + name to; + asset net_weight; + asset cpu_weight; + + bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0; } + uint64_t primary_key()const { return to.value; } + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) ) + + }; + + struct [[eosio::table, eosio::contract("eosio.system")]] refund_request { + name owner; + time_point_sec request_time; + eosio::asset net_amount; + eosio::asset cpu_amount; + + bool is_empty()const { return net_amount.amount == 0 && cpu_amount.amount == 0; } + uint64_t primary_key()const { return owner.value; } + + // explicit serialization macro is not necessary, used here only to improve compilation time + EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(net_amount)(cpu_amount) ) + }; + + /** + * These tables are designed to be constructed in the scope of the relevant user, this + * facilitates simpler API for per-user queries + */ + typedef eosio::multi_index< "userres"_n, user_resources > user_resources_table; + typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; + typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; /** * `rex_pool` structure underlying the rex pool table. @@ -1207,15 +1271,15 @@ namespace eosiosystem { * (eg. For 5% Annual inflation => annual_rate=500 * For 1.5% Annual inflation => annual_rate=150 * - * @param inflation_pay_factor - Percentage of the inflation used to reward block producers. + * @param inflation_pay_factor - Inverse of the fraction of the inflation used to reward block producers. * The remaining inflation will be sent to the `eosio.saving` account. - * (eg. For 20% => inflation_pay_factor=5 - * For 100% => inflation_pay_factor=1). + * (eg. For 20% of inflation going to block producer rewards => inflation_pay_factor=5 + * For 100% of inflation going to block producer rewards => inflation_pay_factor=1). * - * @param votepay_factor - Percentage of the block producer rewards to be distributed proportional to votes received. - * The remaining rewards will be distributed proportional to blocks produced. - * (eg. For 25% => votepay_factor=4 - * For 50% => votepay_factor=2). + * @param votepay_factor - Inverse of the fraction of the block producer rewards to be distributed proportional to blocks produced. + * The remaining rewards will be distributed proportional to votes received. + * (eg. For 25% of block producer rewards going towards block pay => votepay_factor=4 + * For 50% of block producer rewards going towards block pay => votepay_factor=2). */ [[eosio::action]] void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 2fccffc0..999ea7d7 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace eosiosystem { diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 6ae7a6c7..40a42850 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -22,22 +22,9 @@ namespace eosio { void preactivate_feature( const ::capi_checksum256* feature_digest ); } } -} -namespace eosio { - bool is_feature_activated( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); - } - - void preactivate_feature( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); - } + bool is_feature_activated( const eosio::checksum256& feature_digest ); + void preactivate_feature( const eosio::checksum256& feature_digest ); } namespace eosiosystem { @@ -280,9 +267,7 @@ namespace eosiosystem { * @param sent_trx - the deferred transaction that failed. */ [[eosio::action]] - void onerror( ignore sender_id, ignore> sent_trx ) { - eosio::check( false, "the onerror action cannot be called directly" ); - } + void onerror( ignore sender_id, ignore> sent_trx ); /** * Set abi action. diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index 8449addb..e1ecbd1f 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -8,76 +8,19 @@ #include #include -#include -#include +#include "name_bidding.cpp" +// Unfortunately, this is needed until CDT fixes the duplicate symbol error with eosio::send_deferred namespace eosiosystem { using eosio::asset; using eosio::const_mem_fun; + using eosio::current_time_point; using eosio::indexed_by; using eosio::permission_level; + using eosio::seconds; using eosio::time_point_sec; - - using std::map; - using std::pair; - - static constexpr uint32_t refund_delay_sec = 3*24*3600; - static constexpr int64_t ram_gift_bytes = 1400; - - struct [[eosio::table, eosio::contract("eosio.system")]] user_resources { - name owner; - asset net_weight; - asset cpu_weight; - int64_t ram_bytes = 0; - - bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0 && ram_bytes == 0; } - uint64_t primary_key()const { return owner.value; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(ram_bytes) ) - }; - - - /** - * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. - */ - struct [[eosio::table, eosio::contract("eosio.system")]] delegated_bandwidth { - name from; - name to; - asset net_weight; - asset cpu_weight; - - bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0; } - uint64_t primary_key()const { return to.value; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) ) - - }; - - struct [[eosio::table, eosio::contract("eosio.system")]] refund_request { - name owner; - time_point_sec request_time; - eosio::asset net_amount; - eosio::asset cpu_amount; - - bool is_empty()const { return net_amount.amount == 0 && cpu_amount.amount == 0; } - uint64_t primary_key()const { return owner.value; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(net_amount)(cpu_amount) ) - }; - - /** - * These tables are designed to be constructed in the scope of the relevant user, this - * facilitates simpler API for per-user queries - */ - typedef eosio::multi_index< "userres"_n, user_resources > user_resources_table; - typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; - typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; - - + using eosio::token; /** * This action will buy an exact amount of ram and bill the payer the current market price. @@ -387,10 +330,10 @@ namespace eosiosystem { from ); out.delay_sec = refund_delay_sec; - cancel_deferred( from.value ); // TODO: Remove this line when replacing deferred trxs is fixed + eosio::cancel_deferred( from.value ); // TODO: Remove this line when replacing deferred trxs is fixed out.send( from.value, from, true ); } else { - cancel_deferred( from.value ); + eosio::cancel_deferred( from.value ); } auto transfer_amount = net_balance + cpu_balance; diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index afcd0358..a6071c4a 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -1,20 +1,15 @@ +#include +#include + #include #include -#include - -#include "producer_pay.cpp" -#include "delegate_bandwidth.cpp" -#include "voting.cpp" -#include "exchange_state.cpp" -#include "rex.cpp" +#include namespace eosiosystem { - const int64_t inflation_precision = 100; // 2 decimals - const int64_t default_annual_rate = 500; // 5% annual rate - const int64_t default_inflation_pay_factor = 5; // 20% of the inflation - const int64_t default_votepay_factor = 4; // 25% of the producer pay + using eosio::current_time_point; + using eosio::token; double get_continuous_rate(int64_t annual_rate) { return std::log1p(double(annual_rate)/double(100*inflation_precision)); @@ -89,7 +84,7 @@ namespace eosiosystem { } void system_contract::update_ram_supply() { - auto cbt = current_block_time(); + auto cbt = eosio::current_block_time(); if( cbt <= _gstate2.last_ram_increase ) return; @@ -299,74 +294,7 @@ namespace eosiosystem { _gstate2.revision = revision; } - void system_contract::bidname( const name& bidder, const name& newname, const asset& bid ) { - require_auth( bidder ); - check( newname.suffix() == newname, "you can only bid on top-level suffix" ); - - check( (bool)newname, "the empty name is not a valid account name to bid on" ); - check( (newname.value & 0xFull) == 0, "13 character names are not valid account names to bid on" ); - check( (newname.value & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); - check( !is_account( newname ), "account already exists" ); - check( bid.symbol == core_symbol(), "asset must be system token" ); - check( bid.amount > 0, "insufficient bid" ); - token::transfer_action transfer_act{ token_account, { {bidder, active_permission} } }; - transfer_act.send( bidder, names_account, bid, std::string("bid name ")+ newname.to_string() ); - name_bid_table bids(get_self(), get_self().value); - print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); - auto current = bids.find( newname.value ); - if( current == bids.end() ) { - bids.emplace( bidder, [&]( auto& b ) { - b.newname = newname; - b.high_bidder = bidder; - b.high_bid = bid.amount; - b.last_bid_time = current_time_point(); - }); - } else { - check( current->high_bid > 0, "this auction has already closed" ); - check( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); - check( current->high_bidder != bidder, "account is already highest bidder" ); - - bid_refund_table refunds_table(get_self(), newname.value); - - auto it = refunds_table.find( current->high_bidder.value ); - if ( it != refunds_table.end() ) { - refunds_table.modify( it, same_payer, [&](auto& r) { - r.amount += asset( current->high_bid, core_symbol() ); - }); - } else { - refunds_table.emplace( bidder, [&](auto& r) { - r.bidder = current->high_bidder; - r.amount = asset( current->high_bid, core_symbol() ); - }); - } - - transaction t; - t.actions.emplace_back( permission_level{get_self(), active_permission}, - get_self(), "bidrefund"_n, - std::make_tuple( current->high_bidder, newname ) - ); - t.delay_sec = 0; - uint128_t deferred_id = (uint128_t(newname.value) << 64) | current->high_bidder.value; - cancel_deferred( deferred_id ); - t.send( deferred_id, bidder ); - - bids.modify( current, bidder, [&]( auto& b ) { - b.high_bidder = bidder; - b.high_bid = bid.amount; - b.last_bid_time = current_time_point(); - }); - } - } - - void system_contract::bidrefund( const name& bidder, const name& newname ) { - bid_refund_table refunds_table(get_self(), newname.value); - auto it = refunds_table.find( bidder.value ); - check( it != refunds_table.end(), "refund not found" ); - token::transfer_action transfer_act{ token_account, { {names_account, active_permission}, {bidder, active_permission} } }; - transfer_act.send( names_account, bidder, asset(it->amount), std::string("refund bid on name ")+(name{newname}).to_string() ); - refunds_table.erase( it ); - } void system_contract::setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { require_auth(get_self()); @@ -417,7 +345,7 @@ namespace eosiosystem { } } - user_resources_table userres( get_self(), newact.value); + user_resources_table userres( get_self(), newact.value ); userres.emplace( newact, [&]( auto& res ) { res.owner = newact; @@ -434,11 +362,11 @@ namespace eosiosystem { if( itr == table.end() ) { table.emplace( acnt, [&]( auto& row ) { row.owner = acnt; - row.hash = sha256(const_cast(abi.data()), abi.size()); + row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); }); } else { table.modify( itr, same_payer, [&]( auto& row ) { - row.hash = sha256(const_cast(abi.data()), abi.size()); + row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); }); } } diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp index 1089ffd0..8f9734bc 100644 --- a/contracts/eosio.system/src/exchange_state.cpp +++ b/contracts/eosio.system/src/exchange_state.cpp @@ -1,7 +1,13 @@ #include +#include + +#include + namespace eosiosystem { + using eosio::check; + asset exchange_state::convert_to_exchange( connector& reserve, const asset& payment ) { const double S0 = supply.amount; diff --git a/contracts/eosio.system/src/name_bidding.cpp b/contracts/eosio.system/src/name_bidding.cpp new file mode 100644 index 00000000..d08aed65 --- /dev/null +++ b/contracts/eosio.system/src/name_bidding.cpp @@ -0,0 +1,80 @@ +#include +#include + +#include + +namespace eosiosystem { + + using eosio::current_time_point; + using eosio::token; + + void system_contract::bidname( const name& bidder, const name& newname, const asset& bid ) { + require_auth( bidder ); + check( newname.suffix() == newname, "you can only bid on top-level suffix" ); + + check( (bool)newname, "the empty name is not a valid account name to bid on" ); + check( (newname.value & 0xFull) == 0, "13 character names are not valid account names to bid on" ); + check( (newname.value & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); + check( !is_account( newname ), "account already exists" ); + check( bid.symbol == core_symbol(), "asset must be system token" ); + check( bid.amount > 0, "insufficient bid" ); + token::transfer_action transfer_act{ token_account, { {bidder, active_permission} } }; + transfer_act.send( bidder, names_account, bid, std::string("bid name ")+ newname.to_string() ); + name_bid_table bids(get_self(), get_self().value); + print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); + auto current = bids.find( newname.value ); + if( current == bids.end() ) { + bids.emplace( bidder, [&]( auto& b ) { + b.newname = newname; + b.high_bidder = bidder; + b.high_bid = bid.amount; + b.last_bid_time = current_time_point(); + }); + } else { + check( current->high_bid > 0, "this auction has already closed" ); + check( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); + check( current->high_bidder != bidder, "account is already highest bidder" ); + + bid_refund_table refunds_table(get_self(), newname.value); + + auto it = refunds_table.find( current->high_bidder.value ); + if ( it != refunds_table.end() ) { + refunds_table.modify( it, same_payer, [&](auto& r) { + r.amount += asset( current->high_bid, core_symbol() ); + }); + } else { + refunds_table.emplace( bidder, [&](auto& r) { + r.bidder = current->high_bidder; + r.amount = asset( current->high_bid, core_symbol() ); + }); + } + + eosio::transaction t; + t.actions.emplace_back( permission_level{get_self(), active_permission}, + get_self(), "bidrefund"_n, + std::make_tuple( current->high_bidder, newname ) + ); + t.delay_sec = 0; + uint128_t deferred_id = (uint128_t(newname.value) << 64) | current->high_bidder.value; + eosio::cancel_deferred( deferred_id ); + t.send( deferred_id, bidder ); + + bids.modify( current, bidder, [&]( auto& b ) { + b.high_bidder = bidder; + b.high_bid = bid.amount; + b.last_bid_time = current_time_point(); + }); + } + } + + void system_contract::bidrefund( const name& bidder, const name& newname ) { + bid_refund_table refunds_table(get_self(), newname.value); + auto it = refunds_table.find( bidder.value ); + check( it != refunds_table.end(), "refund not found" ); + + token::transfer_action transfer_act{ token_account, { {names_account, active_permission}, {bidder, active_permission} } }; + transfer_act.send( names_account, bidder, asset(it->amount), std::string("refund bid on name ")+(name{newname}).to_string() ); + refunds_table.erase( it ); + } + +} diff --git a/contracts/eosio.system/src/native.cpp b/contracts/eosio.system/src/native.cpp new file mode 100644 index 00000000..a8f76304 --- /dev/null +++ b/contracts/eosio.system/src/native.cpp @@ -0,0 +1,27 @@ +#include + +#include + +namespace eosio { + bool is_feature_activated( const eosio::checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + return internal_use_do_not_use::is_feature_activated( + reinterpret_cast( feature_digest_data.data() ) + ); + } + + void preactivate_feature( const eosio::checksum256& feature_digest ) { + auto feature_digest_data = feature_digest.extract_as_byte_array(); + internal_use_do_not_use::preactivate_feature( + reinterpret_cast( feature_digest_data.data() ) + ); + } +} + +namespace eosiosystem { + + void native::onerror( ignore, ignore> ) { + eosio::check( false, "the onerror action cannot be called directly" ); + } + +} diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 12bfbaf0..91a54eee 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -3,14 +3,9 @@ namespace eosiosystem { - const int64_t min_pervote_daily_pay = 100'0000; - const int64_t min_activated_stake = 150'000'000'0000; - const uint32_t blocks_per_year = 52*7*24*2*3600; // half seconds per year - const uint32_t seconds_per_year = 52*7*24*3600; - const uint32_t blocks_per_day = 2 * 24 * 3600; - const uint32_t blocks_per_hour = 2 * 3600; - const int64_t useconds_per_day = 24 * 3600 * int64_t(1000000); - const int64_t useconds_per_year = seconds_per_year*1000000ll; + using eosio::current_time_point; + using eosio::microseconds; + using eosio::token; void system_contract::onblock( ignore ) { using namespace eosio; @@ -70,7 +65,6 @@ namespace eosiosystem { } } - using namespace eosio; void system_contract::claimrewards( const name& owner ) { require_auth( owner ); @@ -84,7 +78,7 @@ namespace eosiosystem { check( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - const asset token_supply = eosio::token::get_supply(token_account, core_symbol().code() ); + const asset token_supply = token::get_supply(token_account, core_symbol().code() ); const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 34b45218..4a4596e2 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -1,8 +1,12 @@ #include +#include #include namespace eosiosystem { + using eosio::current_time_point; + using eosio::token; + void system_contract::deposit( const name& owner, const asset& amount ) { require_auth( owner ); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index cc540297..95f1dd36 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include @@ -16,9 +15,10 @@ namespace eosiosystem { using eosio::const_mem_fun; + using eosio::current_time_point; using eosio::indexed_by; + using eosio::microseconds; using eosio::singleton; - using eosio::transaction; void system_contract::regproducer( const name& producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { check( url.size() < 512, "url too long" ); @@ -204,7 +204,7 @@ namespace eosiosystem { new_vote_weight += voter->proxied_vote_weight; } - std::map > producer_deltas; + std::map > producer_deltas; if ( voter->last_vote_weight > 0 ) { if( voter->proxy ) { auto old_proxy = _voters.find( voter->proxy.value ); From 28aeda476fe66fadf41801a19fc3b7865c95d3fd Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 25 Jun 2019 17:45:58 -0400 Subject: [PATCH 0836/1048] add Ricardian contract for eosio::setinflation action --- .../ricardian/eosio.system.contracts.md.in | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 2269428e..13016351 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -546,6 +546,21 @@ icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ {{$action.account}} adjusts REX loan rate by setting REX pool virtual balance to {{balance}}. No token transfer or issue is executed in this action. +

setinflation

+ +--- +spec_version: "0.2.0" +title: Set Inflation Parameters +summary: 'Set inflation parameters' +icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ +--- + +{{$action.account}} sets the inflation parameters as follows: + +* Annual inflation rate (in units of a hundredth of a percent): {{annual_rate}} +* Fraction of inflation used to reward block producers: 1/{{inflation_pay_factor}} +* Fraction of block producer rewards to be distributed proportional to blocks produced: 1/{{votepay_factor}} +

undelegatebw

--- From d08eb8b6d634cd85131a35d825277e3401483a5a Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 26 Jun 2019 18:26:44 -0400 Subject: [PATCH 0837/1048] Add is_account check to token::open --- contracts/eosio.token/src/eosio.token.cpp | 3 ++- tests/eosio.token_tests.cpp | 5 ++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.token/src/eosio.token.cpp b/contracts/eosio.token/src/eosio.token.cpp index a0b5ad63..b1bbd4d4 100644 --- a/contracts/eosio.token/src/eosio.token.cpp +++ b/contracts/eosio.token/src/eosio.token.cpp @@ -130,8 +130,9 @@ void token::open( const name& owner, const symbol& symbol, const name& ram_payer { require_auth( ram_payer ); - auto sym_code_raw = symbol.code().raw(); + check( is_account( owner ), "owner account does not exist" ); + auto sym_code_raw = symbol.code().raw(); stats statstable( _self, sym_code_raw ); const auto& st = statstable.get( sym_code_raw, "symbol does not exist" ); check( st.supply.symbol == symbol, "symbol precision mismatch" ); diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 654b1703..acca038a 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -367,7 +367,10 @@ BOOST_FIXTURE_TEST_CASE( open_tests, eosio_token_tester ) try { auto bob_balance = get_account(N(bob), "0,CERO"); BOOST_REQUIRE_EQUAL(true, bob_balance.is_null() ); - BOOST_REQUIRE_EQUAL( success(), open( N(bob), "0,CERO", N(alice) ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("owner account does not exist"), + open( N(nonexistent), "0,CERO", N(alice) ) ); + BOOST_REQUIRE_EQUAL( success(), + open( N(bob), "0,CERO", N(alice) ) ); bob_balance = get_account(N(bob), "0,CERO"); REQUIRE_MATCHING_OBJECT( bob_balance, mvo() From 950e1e46dc5dd8bb23289c196e83e98a7ed8b388 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 26 Jun 2019 19:46:12 -0400 Subject: [PATCH 0838/1048] create eosio.rex account before eosio::init action (fixes test failures) --- tests/eosio.msig_tests.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index 570fbd1a..e28e229c 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -414,7 +414,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) set_producers( {N(alice),N(bob),N(carol)} ); produce_blocks(50); - create_accounts( { N(eosio.token) } ); + create_accounts( { N(eosio.token), N(eosio.rex) } ); set_code( N(eosio.token), contracts::token_wasm() ); set_abi( N(eosio.token), contracts::token_abi().data() ); @@ -533,7 +533,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester set_producers( {N(alice),N(bob),N(carol), N(apple)} ); produce_blocks(50); - create_accounts( { N(eosio.token) } ); + create_accounts( { N(eosio.token), N(eosio.rex) } ); set_code( N(eosio.token), contracts::token_wasm() ); set_abi( N(eosio.token), contracts::token_abi().data() ); From 8df327471ae154698c9e4bc1809330df1c7d5b1d Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 27 Jun 2019 16:46:12 -0400 Subject: [PATCH 0839/1048] fix double-move bug in system_contract::registration --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 58aa3131..bc6f037e 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1338,7 +1338,7 @@ namespace eosiosystem { template static constexpr void call( system_contract* this_contract, Args&&... args ) { - std::invoke( P, this_contract, std::forward(args)... ); + std::invoke( P, this_contract, args... ); for_each::call( this_contract, std::forward(args)... ); } }; From c8c84b40aaef84885efea15a48139e972f3cb30e Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Jul 2019 18:06:45 -0400 Subject: [PATCH 0840/1048] pass through Boost variables to unit tests external project --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1e20245c..e56ee860 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,13 +71,14 @@ elseif (UNIX) endif() set(SECP256K1_ROOT "/usr/local") +string(REPLACE ";" "|" TEST_PREFIX_PATH "${CMAKE_PREFIX_PATH}") string(REPLACE ";" "|" TEST_FRAMEWORK_PATH "${CMAKE_FRAMEWORK_PATH}") string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") ExternalProject_Add( contracts_unit_tests LIST_SEPARATOR | # Use the alternate list separator - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_PREFIX_PATH=${TEST_PREFIX_PATH} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} -DBOOST_ROOT=${BOOST_ROOT} -DBoost_NO_BOOST_CMAKE=${Boost_NO_BOOST_CMAKE} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 From 9329233ff4a9d7453a35e5463c99d9c8e458f67d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 10 Jul 2019 18:32:55 -0400 Subject: [PATCH 0841/1048] remove Boost_NO_BOOST_CMAKE --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e56ee860..d9190e60 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,7 @@ string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") ExternalProject_Add( contracts_unit_tests LIST_SEPARATOR | # Use the alternate list separator - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_PREFIX_PATH=${TEST_PREFIX_PATH} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} -DBOOST_ROOT=${BOOST_ROOT} -DBoost_NO_BOOST_CMAKE=${Boost_NO_BOOST_CMAKE} + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_PREFIX_PATH=${TEST_PREFIX_PATH} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} -DBOOST_ROOT=${BOOST_ROOT} SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests BINARY_DIR ${CMAKE_BINARY_DIR}/tests BUILD_ALWAYS 1 From 59e0ff9ef65389fe085f7845b22a0778b7c79c11 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Fri, 2 Aug 2019 15:58:23 -0400 Subject: [PATCH 0842/1048] Default list of eosio subdirs as empty. Check the default directory only if it exists. --- scripts/helper.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/helper.sh b/scripts/helper.sh index 1ced68ed..d08be5fe 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -26,7 +26,10 @@ function check-version-numbers() { # Handles choosing which EOSIO directory to select when the default location is used. function default-eosio-directories() { REGEX='^[0-9]+([.][0-9]+)?$' - ALL_EOSIO_SUBDIRS=($(ls ${HOME}/eosio | sort -V)) + ALL_EOSIO_SUBDIRS=() + if [[ -d ${HOME}/eosio ]]; then + ALL_EOSIO_SUBDIRS=($(ls ${HOME}/eosio | sort -V)) + fi for ITEM in "${ALL_EOSIO_SUBDIRS[@]}"; do if [[ "$ITEM" =~ $REGEX ]]; then DIR_MAJOR=$(echo $ITEM | cut -f1 -d '.') From 041318f9362e506792b8dfe8c58e8be2e584638a Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 5 Aug 2019 17:57:19 -0400 Subject: [PATCH 0843/1048] Change setinflation parameters --- .../include/eosio.system/eosio.system.hpp | 14 +++++++----- contracts/eosio.system/src/producer_pay.cpp | 10 ++++----- tests/eosio.system_tests.cpp | 22 +++++++++---------- 3 files changed, 24 insertions(+), 22 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index f2ebe9a3..e42f72c8 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -70,8 +70,9 @@ namespace eosiosystem { static constexpr int64_t inflation_precision = 100; // 2 decimals static constexpr int64_t default_annual_rate = 500; // 5% annual rate - static constexpr int64_t default_inflation_pay_factor = 5; // 20% of the inflation - static constexpr int64_t default_votepay_factor = 4; // 25% of the producer pay + static constexpr int64_t pay_factor_precision = 10000; + static constexpr int64_t default_inflation_pay_factor = 50000; // producers pay share = 10000 / 50000 = 20% of the inflation + static constexpr int64_t default_votepay_factor = 40000; // per-block pay share = 10000 / 40000 = 25% of the producer pay /** * @@ -1273,13 +1274,13 @@ namespace eosiosystem { * * @param inflation_pay_factor - Inverse of the fraction of the inflation used to reward block producers. * The remaining inflation will be sent to the `eosio.saving` account. - * (eg. For 20% of inflation going to block producer rewards => inflation_pay_factor=5 - * For 100% of inflation going to block producer rewards => inflation_pay_factor=1). + * (eg. For 20% of inflation going to block producer rewards => inflation_pay_factor = 50000 + * For 100% of inflation going to block producer rewards => inflation_pay_factor = 10000). * * @param votepay_factor - Inverse of the fraction of the block producer rewards to be distributed proportional to blocks produced. * The remaining rewards will be distributed proportional to votes received. - * (eg. For 25% of block producer rewards going towards block pay => votepay_factor=4 - * For 50% of block producer rewards going towards block pay => votepay_factor=2). + * (eg. For 25% of block producer rewards going towards block pay => votepay_factor = 40000 + * For 75% of block producer rewards going towards block pay => votepay_factor = 13333). */ [[eosio::action]] void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); @@ -1328,6 +1329,7 @@ namespace eosiosystem { using setpriv_action = eosio::action_wrapper<"setpriv"_n, &system_contract::setpriv>; using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; + using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; private: // Implementation details: diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 91a54eee..28ec8f51 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -82,12 +82,12 @@ namespace eosiosystem { const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { - auto new_tokens = static_cast( (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year) ); + int64_t new_tokens = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); - auto to_producers = new_tokens / _gstate4.inflation_pay_factor; - auto to_savings = new_tokens - to_producers; - auto to_per_block_pay = to_producers / _gstate4.votepay_factor; - auto to_per_vote_pay = to_producers - to_per_block_pay; + int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; + int64_t to_savings = new_tokens - to_producers; + int64_t to_per_block_pay = (to_producers * uint128_t(pay_factor_precision)) / _gstate4.votepay_factor; + int64_t to_per_vote_pay = to_producers - to_per_block_pay; if( new_tokens > 0 ) { { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 80cd7383..9fd1b3da 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1382,12 +1382,12 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t BOOST_REQUIRE_EQUAL(claim_time, microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); auto usecs_between_fills = claim_time - initial_claim_time; - BOOST_REQUIRE_EQUAL(int64_t( ( double(initial_supply.get_amount()) * double(usecs_between_fills) * continuous_rate / usecs_per_year ) ), - supply.get_amount() - initial_supply.get_amount()); + BOOST_REQUIRE_EQUAL( int64_t( initial_supply.get_amount() * double(usecs_between_fills) * continuous_rate / usecs_per_year ), + supply.get_amount() - initial_supply.get_amount() ); BOOST_REQUIRE_EQUAL( (supply.get_amount() - initial_supply.get_amount()) - (supply.get_amount() - initial_supply.get_amount()) / 5, - savings - initial_savings); + savings - initial_savings ); - int64_t to_producer = int64_t( (double(initial_supply.get_amount()) * double(usecs_between_fills) * continuous_rate) / usecs_per_year ) / 5; + int64_t to_producer = int64_t( initial_supply.get_amount() * double(usecs_between_fills) * continuous_rate / usecs_per_year ) / 5; int64_t to_perblock_bucket = to_producer / 4; int64_t to_pervote_bucket = to_producer - to_perblock_bucket; @@ -1487,7 +1487,7 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { BOOST_REQUIRE_EQUAL( theoretical_new_tokens, 0 ); } - double savings_inflation = inflation*double(inflation_pay_factor-1)/double(inflation_pay_factor); + double savings_inflation = inflation - inflation * 10000 / inflation_pay_factor; double computed_savings_tokens = double(final_savings-initial_savings); double theoretical_savings_tokens = double(initial_supply.get_amount())*savings_inflation; @@ -1502,14 +1502,14 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { } }; - //1% inflation for 1 year => 50% saving / 50% bp reward - run_for_1year(100, 2, 5); + // 1% inflation for 1 year. 50% savings / 50% bp reward. 10000 / 50000 = 0.2 => 20% blockpay, 80% votepay + run_for_1year(100, 20000, 50000); - //3% inflation for 1 year => 66.6% savings / 33.33 bp reward - run_for_1year(300, 3, 5); + // 3% inflation for 1 year. 66.6% savings / 33.33% bp reward. 10000/13333 = 0.75 => 75% blockpay, 25% votepay + run_for_1year(300, 30000, 13333); - //0% inflation for 1 year - run_for_1year(0, 3, 5); + // 0% inflation for 1 year + run_for_1year(0, 30000, 50000); } } FC_LOG_AND_RETHROW() From d3f14a5f83537aae0cd152abbd2d79fe34d6c38c Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 6 Aug 2019 11:23:20 -0400 Subject: [PATCH 0844/1048] Added additional checks to setinflation --- contracts/eosio.system/src/eosio.system.cpp | 13 +++++++------ tests/eosio.system_tests.cpp | 12 ++++++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index a6071c4a..b05c5f01 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -290,18 +290,19 @@ namespace eosiosystem { check( _gstate2.revision < 255, "can not increment revision" ); // prevent wrap around check( revision == _gstate2.revision + 1, "can only increment revision by one" ); check( revision <= 1, // set upper bound to greatest revision supported in the code - "specified revision is not yet supported by the code" ); + "specified revision is not yet supported by the code" ); _gstate2.revision = revision; } - - void system_contract::setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { require_auth(get_self()); check(annual_rate >= 0, "annual_rate can't be negative"); - check(inflation_pay_factor > 0, "inflation_pay_factor must be positive"); - check(votepay_factor > 0, "votepay_factor must be positive"); - + if ( inflation_pay_factor < pay_factor_precision ) { + check( false, "inflation_pay_factor must not be less than " + std::to_string(pay_factor_precision) ); + } + if ( votepay_factor < pay_factor_precision ) { + check( false, "votepay_factor must not be less than " + std::to_string(pay_factor_precision) ); + } _gstate4.continuous_rate = get_continuous_rate(annual_rate); _gstate4.inflation_pay_factor = inflation_pay_factor; _gstate4.votepay_factor = votepay_factor; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 9fd1b3da..e4bca563 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1432,6 +1432,17 @@ BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::t BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { + { + BOOST_REQUIRE_EQUAL( success(), + setinflation(0, 10000, 10000) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("annual_rate can't be negative"), + setinflation(-1, 10000, 10000) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("inflation_pay_factor must not be less than 10000"), + setinflation(1, 9999, 10000) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("votepay_factor must not be less than 10000"), + setinflation(1, 10000, 9999) ); + } + { const asset large_asset = core_sym::from_string("80.0000"); create_account_with_resources( N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); @@ -1514,6 +1525,7 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { } FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { const int64_t secs_per_year = 52 * 7 * 24 * 3600; From 7666714e8205a2f37b6f32cda4584068cceb94c6 Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 24 Jul 2019 14:49:46 +0300 Subject: [PATCH 0845/1048] introduce the file structure, layout and part of the content sanitized all content existing at this point order the sub-items clean up the index.md files, we will introduce them if needed where needed later. Clean up the *action-reference.md files, they will be generated later and add more layout content, and content. add more content and clean up compile and deploy can't be put together for each individual contract cause right now to compile you have to compile them all but to deploy you can deploy each one individually. clean up not suitable phrase. --- docs.json | 22 ++ docs/eosio.bios/deploy.md | 12 + docs/eosio.bios/introduction.md | 30 +++ docs/eosio.msig/deploy.md | 12 + ...a-multisig-transaction-with-eosio.msig.md} | 41 ++-- docs/eosio.msig/introduction.md | 19 ++ docs/eosio.system/deploy.md | 12 + docs/eosio.system/guides/how-to-buy-ram.md | 20 ++ docs/eosio.system/guides/how-to-stake.md | 47 ++++ docs/eosio.system/guides/how-to-vote.md | 12 + .../upgrading-the-eosio.system-contract.md | 209 ++++++++++++++++++ docs/eosio.system/introduction.md | 65 ++++++ docs/eosio.token/deploy.md | 12 + ...w-to-create,-issue-and-transfer-a-token.md | 152 +++++++++++++ docs/eosio.token/introduction.md | 21 ++ docs/eosio.wrap/deploy.md | 12 + .../guides/how-to-use-eosio.wrap.md} | 0 docs/eosio.wrap/introduction.md | 12 + docs/introduction.md | 52 +++++ docs2.json | 21 ++ 20 files changed, 757 insertions(+), 26 deletions(-) create mode 100644 docs.json create mode 100644 docs/eosio.bios/deploy.md create mode 100644 docs/eosio.bios/introduction.md create mode 100644 docs/eosio.msig/deploy.md rename docs/{eosio.msig.md => eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md} (89%) create mode 100644 docs/eosio.msig/introduction.md create mode 100644 docs/eosio.system/deploy.md create mode 100644 docs/eosio.system/guides/how-to-buy-ram.md create mode 100644 docs/eosio.system/guides/how-to-stake.md create mode 100644 docs/eosio.system/guides/how-to-vote.md create mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md create mode 100644 docs/eosio.system/introduction.md create mode 100644 docs/eosio.token/deploy.md create mode 100644 docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md create mode 100644 docs/eosio.token/introduction.md create mode 100644 docs/eosio.wrap/deploy.md rename docs/{eosio.wrap.md => eosio.wrap/guides/how-to-use-eosio.wrap.md} (100%) create mode 100644 docs/eosio.wrap/introduction.md create mode 100644 docs/introduction.md create mode 100644 docs2.json diff --git a/docs.json b/docs.json new file mode 100644 index 00000000..f6a7a50c --- /dev/null +++ b/docs.json @@ -0,0 +1,22 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "output": "00_eosio.token", + "INPUT": "eosio.token" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md new file mode 100644 index 00000000..57a5923b --- /dev/null +++ b/docs/eosio.bios/deploy.md @@ -0,0 +1,12 @@ +## Steps deploy eosio.bios contract + +In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerbios` + +``` +cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios +``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md new file mode 100644 index 00000000..fc31c0c7 --- /dev/null +++ b/docs/eosio.bios/introduction.md @@ -0,0 +1,30 @@ +## Introducing eosio.bios contract + +The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. + +The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. + +|Action name|Action description| +|---|---| +|setpriv|Set privilege status for an account.| +|setalimits|Set the resource limits of an account| +|setglimits|Not implemented yet.| +|setprods|Set a new list of active producers, that is, a new producers' schedule.| +|setparams|Set the blockchain parameters.| +|reqauth|Check if an account has authorization to access the current action.| +|setabi|Set the abi for a contract identified by an account name.| + +The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. + +Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: + +|Action name|Description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md new file mode 100644 index 00000000..d5f027d8 --- /dev/null +++ b/docs/eosio.msig/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.msig contract + +In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testermsig` + +``` +cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig +``` \ No newline at end of file diff --git a/docs/eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 89% rename from docs/eosio.msig.md rename to docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md index 2006a468..f68dff87 100644 --- a/docs/eosio.msig.md +++ b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -1,16 +1,14 @@ -eosio.msig examples -------------------- +## eosio.msig examples -Cleos usage example for issuing tokens. ---------------------------------------- +### Cleos usage example for issuing tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' is the issuer of SYS token. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester @@ -18,8 +16,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -60,8 +57,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -69,8 +65,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user initiates execution: +#### First user initiates execution: ```` $ cleos multisig exec tester test -p tester @@ -79,16 +74,15 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e ```` -Cleos usage example for transferring tokens. -------------------------------------------- +### Cleos usage example for transferring tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' has at least 1.1000 SYS token balance. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester @@ -96,8 +90,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -139,8 +132,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -148,8 +140,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user check account balance before executing the proposed transaction +#### First user check account balance before executing the proposed transaction ```` $ cleos get account tester ... @@ -160,8 +151,7 @@ SYS balances: total: 4.0487 SYS ```` - -First user initiates execution of proposed transaction: +#### First user initiates execution of proposed transaction: ```` $ cleos multisig exec tester test -p tester @@ -169,8 +159,7 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e # eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} ```` - -First user can check account balance, it should be increased by 1.0000 SYS +#### First user can check account balance, it should be increased by 1.0000 SYS ```` $ cleos get account tester ... diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md new file mode 100644 index 00000000..8fea8056 --- /dev/null +++ b/docs/eosio.msig/introduction.md @@ -0,0 +1,19 @@ +## Introducing eosio.msig contract + +The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. + +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +- first you create a transaction json file, +- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, +- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, +- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. + +These are the actions implemented and publicly exposed by the `eosio.msig` contract: +|Action name|Action description| +|---|---| +|propose|Creates a proposal containing one transaction.| +|approve|Approves an existing proposal.| +|unapprove|Revokes an existing proposal.| +|cancel|Cancels an existing proposal.| +|exec|Allows an account to execute a proposal.| +|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md new file mode 100644 index 00000000..13703abd --- /dev/null +++ b/docs/eosio.system/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.system contract + +In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testersystem` + +``` +cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md new file mode 100644 index 00000000..19c83a37 --- /dev/null +++ b/docs/eosio.system/guides/how-to-buy-ram.md @@ -0,0 +1,20 @@ +## How buy RAM + +### What RAM is + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### How to buy RAM + +To check the amount of RAM for an account eostutorial1: +``` +cleos get account eostutorial1 +``` + +Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: +``` +cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md new file mode 100644 index 00000000..fb0a5e31 --- /dev/null +++ b/docs/eosio.system/guides/how-to-stake.md @@ -0,0 +1,47 @@ +## How to stake + +### What staking is + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. + +### Staking tokens for CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active +``` + +### Staking tokens for Bandwidth + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active +``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md new file mode 100644 index 00000000..7ebb62f7 --- /dev/null +++ b/docs/eosio.system/guides/how-to-vote.md @@ -0,0 +1,12 @@ +## How to vote + +### What voting is + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +### How to vote + +To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. +``` +cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md new file mode 100644 index 00000000..2bd712fb --- /dev/null +++ b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md @@ -0,0 +1,209 @@ +## Upgrading the system contract + +### Indirect method using eosio.msig contract + +Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. + +So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). + +The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. + +The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. + +For now, it is recommended to use the direct method to upgrade the system contract. + +### Direct method (avoids using eosio.msig contract) + +Each of the top 21 block producers should do the following: + +1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): + +``` +$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio +code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 +saving wast to original_system_contract.wast +saving abi to original_system_contract.abi +``` + +2. Generate the unsigned transaction which upgrades the system contract: + +``` +$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json +``` + +The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): + +``` +{ + "expiration": "2018-06-15T22:17:10", + "ref_block_num": 4552, + "ref_block_prefix": 511016679, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], +``` + +and the last few lines should be: + +``` + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: + +3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. + +4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. + +Then each of the top 21 block producers should do the following: + +5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: + +``` +$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json +2,4c2,4 +< "expiration": "2018-06-15T22:17:10", +< "ref_block_num": 4552, +< "ref_block_prefix": 511016679, +--- +> "expiration": "2018-06-15T21:20:39", +> "ref_block_num": 4972, +> "ref_block_prefix": 195390844, +``` + +6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. + +First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. + +Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): + +``` +$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 +private key: "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" + ], + "context_free_data": [] +} +``` + +Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. + +The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. + +When the lead producer collects 15 producer signatures, the lead producer should do the following: + +7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: + +``` +$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 + "transaction_extensions": [], + "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", + "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", + "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", + "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", + "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", + "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", + "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", + "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", + "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", + "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", + "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", + "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", + "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", + "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", + "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" + ], + "context_free_data": [] +} +``` + +8. Push the signed transaction to the blockchain: + +``` +$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json +{ + "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "processed": { + "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "receipt": { + "status": "executed", + "cpu_usage_us": 4909, + "net_usage_words": 15124 + }, + "elapsed": 4909, + "net_usage": 120992, + "scheduled": false, + "action_traces": [{ +... +``` + +If you get an error message like the following: + +``` +Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations +Ensure that you have the related private keys inside your wallet and your wallet is unlocked. +``` + +That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. + +If you get an error message like the following: + +``` +Error 3090002: irrelevant signature included +Please remove the unnecessary signature from your transaction! +``` + +That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. + +If you get an error message like the following: + +``` +Error 3040006: Transaction Expiration Too Far +Please decrease the expiration time of your transaction! +``` + +That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. + +If you get an error message like the following: + +``` +Error 3040005: Expired Transaction +Please increase the expiration time of your transaction! +``` + +That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. + +9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: + +``` +$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio +code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 +saving wast to new_system_contract.wast +saving abi to new_system_contract.abi +$ diff original_system_contract.abi new_system_contract.abi +584,592d583 +< },{ +< "name": "deferred_trx_id", +< "type": "uint32" +< },{ +< "name": "last_unstake_time", +< "type": "time_point_sec" +< },{ +< "name": "unstaking", +< "type": "asset" +``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md new file mode 100644 index 00000000..1ca3ca04 --- /dev/null +++ b/docs/eosio.system/introduction.md @@ -0,0 +1,65 @@ +## Introducing eosio.system contract + +The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: +- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. +- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. +- Users can buy and sell RAM at a market-determined price. +- Users can bid on premium names. +- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. + +The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + +|Action name|Action description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setabi|Allows for updates of the contract ABI of an account.| +|setcode|Allows for updates of the contract code of an account.| +|init|Initializes the system contract for a version and a symbol.| +|setram|Set the ram supply.| +|setramrate|Set the ram increase rate.| +|setparams|Set the blockchain parameters.| +|setpriv|Set privilege status for an account (turn it on/off).| +|setalimits|Set the resource limits of an account.| +|setacctram|Set the RAM limits of an account.| +|setacctnet|Set the NET limits of an account.| +|setacctcpu|Set the CPU limits of an account.| +|rmvproducer|Deactivates a producer by name, if not found asserts.| +|updtrevision|Updates the current revision.| +|bidname|Allows an account to place a bid for a name.| +|bidrefund|Allows an account to get back the amount it bid so far on a name.| +|deposit|Deposits core tokens to user REX fund.| +|withdraw|Withdraws core tokens from user REX fund.| +|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| +|unstaketorex|Use staked core tokens to buy REX.| +|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| +|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| +|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| +|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| +|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| +|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| +|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| +|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| +|updaterex|Updates REX owner vote weight to current value of held REX tokens.| +|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| +|mvtosavings|Moves a specified amount of REX to savings bucket.| +|mvfrsavings|Moves a specified amount of REX from savings bucket.| +|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| +|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| +|buyrambytes|Increases receiver's ram in quantity of bytes provided.| +|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| +|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| +|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| +|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| +|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| +|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| +|unregprod|Deactivate the block producer with specified account.| +|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| +|regproxy|Set specified account as proxy.| +|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| +|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md new file mode 100644 index 00000000..5f341b63 --- /dev/null +++ b/docs/eosio.token/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.token contract + +In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testertoken` + +``` +cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken +``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md new file mode 100644 index 00000000..59dc0451 --- /dev/null +++ b/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md @@ -0,0 +1,152 @@ +TO DO: use this: +https://dash.readme.io/project/eosio-home/v2.3.8/docs/token-contract +(don't use below link cause it is deprecated) +https://dash.readme.io/project/eosio-cpp/v1.6/docs/quick-start-token + +## How to create, issue and transfer a token + + +## Step 1: Obtain Contract Source + +Navigate to your contracts directory. + +```text +cd CONTRACTS_DIR +``` +Pull the source + +```text +git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +``` +This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. + + +```text +cd eosio.contracts/eosio.token +``` + +## Step 2: Create Account for Contract +Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. +[[info]] +| +You may have to unlock your wallet first! + + +```shell +cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +``` + +## Step 3: Compile the Contract + + +```shell +eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen +``` + +## Step 4: Deploy the Token Contract + + +```shell +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +``` + +Result +```shell +Reading WASM from ... +Publishing contract... +executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us +# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... +# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... +warning: transaction executed locally, but may not be confirmed by the network yet ] +``` + +## Step 5: Create the Token +To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. + +Below is the concise way to call this method, using positional arguments: + +```shell +cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +An alternate approach uses named arguments: + +```shell +cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. + +## Step 6: Issue Tokens +The issuer can issue new tokens to the "alice" account created earlier. + +```text +cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +``` + +Result +```shell +executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles +# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> issue +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> transfer +# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +``` +This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. + +Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. + +To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. + +```shell +cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j +``` + +## Step 7: Transfer Tokens +Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. + +```shell +cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +``` + +Result +```text +executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles +# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +>> transfer +# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +``` +Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) + +```shell +cleos get currency balance eosio.token bob SYS +``` + + +```text +25.00 SYS +``` +Check "alice's" balance, notice that tokens were deducted from the account + +```shell +cleos get currency balance eosio.token alice SYS +``` + + +```text +75.00 SYS +``` +Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md new file mode 100644 index 00000000..dcde42fd --- /dev/null +++ b/docs/eosio.token/introduction.md @@ -0,0 +1,21 @@ +## Introducing eosio.token contract + +The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. + +These are the public actions the `eosio.token` contract is implementing: +|Action name|Action description| +|---|---| +|create|Allows an account to create a token in a given supply amount.| +|issue|This action issues to an account a specific quantity of tokens.| +|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| +|close|This action is the opposite for `open` action, it closes the specified account for specified token.| +|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| +|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| + +The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. + +The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). + +The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. + +Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md new file mode 100644 index 00000000..bad4e3bb --- /dev/null +++ b/docs/eosio.wrap/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.wrap contract + +In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerwrap` + +``` +cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap +``` \ No newline at end of file diff --git a/docs/eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md similarity index 100% rename from docs/eosio.wrap.md rename to docs/eosio.wrap/guides/how-to-use-eosio.wrap.md diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md new file mode 100644 index 00000000..db4adc63 --- /dev/null +++ b/docs/eosio.wrap/introduction.md @@ -0,0 +1,12 @@ +## Introducing eosio.wrap contract + +The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. + +It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. + +However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. + +The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. + +Why is it easier for governance actions to be executed via this contract? +The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 00000000..226ce05e --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,52 @@ +## About System Contracts + +The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. + +Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. + +## System contracts, system accounts, priviledged accounts + +At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. + +As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: +|Account|Priviledged|Has contract|Description| +|---|---|---|---| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| +|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.names|No|No|The account which is holding funds from namespace auctions.| +|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| +|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| +|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| +|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| +|eosio.saving|No|No|The account which holds the 4% of network inflation.| +|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| +|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| + +## How to compile the eosio.contracts + +To compile the eosio.contracts execute the following commands. + +On all platforms except macOS: +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$( nproc ) +cd .. +``` + +For macOS +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$(sysctl -n hw.ncpu) +cd .. +``` \ No newline at end of file diff --git a/docs2.json b/docs2.json new file mode 100644 index 00000000..c009574b --- /dev/null +++ b/docs2.json @@ -0,0 +1,21 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "INPUT": "eosio.bios eosio.system eosio.msig eosio.token eosio.wrap" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file From cb63f5667955de310a2df32769f2bfd6b11f24c4 Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 24 Jul 2019 14:49:46 +0300 Subject: [PATCH 0846/1048] introduce the file structure, layout and part of the content sanitized all content existing at this point order the sub-items clean up the index.md files, we will introduce them if needed where needed later. Clean up the *action-reference.md files, they will be generated later and add more layout content, and content. add more content and clean up compile and deploy can't be put together for each individual contract cause right now to compile you have to compile them all but to deploy you can deploy each one individually. clean up not suitable phrase. clean up a leftover TO DO. punctuation marks are not allowed in file names by gatsby introduce a second version for content layout, this one is more compact, better structured in relation with "Reference" section which can be only one at the root, we can not have a "Reference" section for each eosio.contract separately Restructure a little bit the introduction. --- docs.json | 22 + docs/eosio.bios/deploy.md | 12 + docs/eosio.bios/introduction.md | 30 + docs/eosio.msig/deploy.md | 12 + ...a-multisig-transaction-with-eosio.msig.md} | 41 +- docs/eosio.msig/introduction.md | 19 + docs/eosio.system/deploy.md | 12 + docs/eosio.system/guides/how-to-buy-ram.md | 20 + docs/eosio.system/guides/how-to-stake.md | 47 + docs/eosio.system/guides/how-to-vote.md | 12 + .../upgrading-the-eosio.system-contract.md | 209 +++++ docs/eosio.system/introduction.md | 65 ++ docs/eosio.token/deploy.md | 12 + ...ow-to-create-issue-and-transfer-a-token.md | 146 +++ docs/eosio.token/introduction.md | 21 + docs/eosio.wrap/deploy.md | 12 + .../guides/how-to-use-eosio.wrap.md} | 0 docs/eosio.wrap/introduction.md | 12 + docs/introduction.md | 52 ++ docs2.json | 21 + docs_v2/01_introduction.md | 186 ++++ docs_v2/02_compile-and-deploy.md | 55 ++ .../01_upgrading-the-eosio.system-contract.md | 209 +++++ docs_v2/03_guides/02_how-to-buy-ram.md | 20 + docs_v2/03_guides/03_how-to-stake.md | 47 + docs_v2/03_guides/04_how-to-vote.md | 12 + ...ow-to-create-issue-and-transfer-a-token.md | 146 +++ ...-a-multisig-transaction-with-eosio.msig.md | 171 ++++ docs_v2/03_guides/07_how-to-use-eosio.wrap.md | 874 ++++++++++++++++++ 29 files changed, 2471 insertions(+), 26 deletions(-) create mode 100644 docs.json create mode 100644 docs/eosio.bios/deploy.md create mode 100644 docs/eosio.bios/introduction.md create mode 100644 docs/eosio.msig/deploy.md rename docs/{eosio.msig.md => eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md} (89%) create mode 100644 docs/eosio.msig/introduction.md create mode 100644 docs/eosio.system/deploy.md create mode 100644 docs/eosio.system/guides/how-to-buy-ram.md create mode 100644 docs/eosio.system/guides/how-to-stake.md create mode 100644 docs/eosio.system/guides/how-to-vote.md create mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md create mode 100644 docs/eosio.system/introduction.md create mode 100644 docs/eosio.token/deploy.md create mode 100644 docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md create mode 100644 docs/eosio.token/introduction.md create mode 100644 docs/eosio.wrap/deploy.md rename docs/{eosio.wrap.md => eosio.wrap/guides/how-to-use-eosio.wrap.md} (100%) create mode 100644 docs/eosio.wrap/introduction.md create mode 100644 docs/introduction.md create mode 100644 docs2.json create mode 100644 docs_v2/01_introduction.md create mode 100644 docs_v2/02_compile-and-deploy.md create mode 100644 docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md create mode 100644 docs_v2/03_guides/02_how-to-buy-ram.md create mode 100644 docs_v2/03_guides/03_how-to-stake.md create mode 100644 docs_v2/03_guides/04_how-to-vote.md create mode 100644 docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md create mode 100644 docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md create mode 100644 docs_v2/03_guides/07_how-to-use-eosio.wrap.md diff --git a/docs.json b/docs.json new file mode 100644 index 00000000..f6a7a50c --- /dev/null +++ b/docs.json @@ -0,0 +1,22 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "output": "00_eosio.token", + "INPUT": "eosio.token" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md new file mode 100644 index 00000000..57a5923b --- /dev/null +++ b/docs/eosio.bios/deploy.md @@ -0,0 +1,12 @@ +## Steps deploy eosio.bios contract + +In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerbios` + +``` +cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios +``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md new file mode 100644 index 00000000..fc31c0c7 --- /dev/null +++ b/docs/eosio.bios/introduction.md @@ -0,0 +1,30 @@ +## Introducing eosio.bios contract + +The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. + +The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. + +|Action name|Action description| +|---|---| +|setpriv|Set privilege status for an account.| +|setalimits|Set the resource limits of an account| +|setglimits|Not implemented yet.| +|setprods|Set a new list of active producers, that is, a new producers' schedule.| +|setparams|Set the blockchain parameters.| +|reqauth|Check if an account has authorization to access the current action.| +|setabi|Set the abi for a contract identified by an account name.| + +The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. + +Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: + +|Action name|Description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md new file mode 100644 index 00000000..d5f027d8 --- /dev/null +++ b/docs/eosio.msig/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.msig contract + +In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testermsig` + +``` +cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig +``` \ No newline at end of file diff --git a/docs/eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 89% rename from docs/eosio.msig.md rename to docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md index 2006a468..f68dff87 100644 --- a/docs/eosio.msig.md +++ b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -1,16 +1,14 @@ -eosio.msig examples -------------------- +## eosio.msig examples -Cleos usage example for issuing tokens. ---------------------------------------- +### Cleos usage example for issuing tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' is the issuer of SYS token. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester @@ -18,8 +16,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -60,8 +57,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -69,8 +65,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user initiates execution: +#### First user initiates execution: ```` $ cleos multisig exec tester test -p tester @@ -79,16 +74,15 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e ```` -Cleos usage example for transferring tokens. -------------------------------------------- +### Cleos usage example for transferring tokens. -Prerequisites: +#### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' has at least 1.1000 SYS token balance. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -One user creates a proposal: +#### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester @@ -96,8 +90,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` - -Another user reviews the transaction: +#### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -139,8 +132,7 @@ $ cleos multisig review tester test } ```` - -And then approves it: +#### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -148,8 +140,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` - -First user check account balance before executing the proposed transaction +#### First user check account balance before executing the proposed transaction ```` $ cleos get account tester ... @@ -160,8 +151,7 @@ SYS balances: total: 4.0487 SYS ```` - -First user initiates execution of proposed transaction: +#### First user initiates execution of proposed transaction: ```` $ cleos multisig exec tester test -p tester @@ -169,8 +159,7 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e # eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} ```` - -First user can check account balance, it should be increased by 1.0000 SYS +#### First user can check account balance, it should be increased by 1.0000 SYS ```` $ cleos get account tester ... diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md new file mode 100644 index 00000000..8fea8056 --- /dev/null +++ b/docs/eosio.msig/introduction.md @@ -0,0 +1,19 @@ +## Introducing eosio.msig contract + +The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. + +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +- first you create a transaction json file, +- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, +- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, +- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. + +These are the actions implemented and publicly exposed by the `eosio.msig` contract: +|Action name|Action description| +|---|---| +|propose|Creates a proposal containing one transaction.| +|approve|Approves an existing proposal.| +|unapprove|Revokes an existing proposal.| +|cancel|Cancels an existing proposal.| +|exec|Allows an account to execute a proposal.| +|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md new file mode 100644 index 00000000..13703abd --- /dev/null +++ b/docs/eosio.system/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.system contract + +In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testersystem` + +``` +cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md new file mode 100644 index 00000000..19c83a37 --- /dev/null +++ b/docs/eosio.system/guides/how-to-buy-ram.md @@ -0,0 +1,20 @@ +## How buy RAM + +### What RAM is + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### How to buy RAM + +To check the amount of RAM for an account eostutorial1: +``` +cleos get account eostutorial1 +``` + +Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: +``` +cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md new file mode 100644 index 00000000..fb0a5e31 --- /dev/null +++ b/docs/eosio.system/guides/how-to-stake.md @@ -0,0 +1,47 @@ +## How to stake + +### What staking is + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. + +### Staking tokens for CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active +``` + +### Staking tokens for Bandwidth + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active +``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md new file mode 100644 index 00000000..7ebb62f7 --- /dev/null +++ b/docs/eosio.system/guides/how-to-vote.md @@ -0,0 +1,12 @@ +## How to vote + +### What voting is + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +### How to vote + +To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. +``` +cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 +``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md new file mode 100644 index 00000000..2bd712fb --- /dev/null +++ b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md @@ -0,0 +1,209 @@ +## Upgrading the system contract + +### Indirect method using eosio.msig contract + +Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. + +So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). + +The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. + +The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. + +For now, it is recommended to use the direct method to upgrade the system contract. + +### Direct method (avoids using eosio.msig contract) + +Each of the top 21 block producers should do the following: + +1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): + +``` +$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio +code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 +saving wast to original_system_contract.wast +saving abi to original_system_contract.abi +``` + +2. Generate the unsigned transaction which upgrades the system contract: + +``` +$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json +``` + +The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): + +``` +{ + "expiration": "2018-06-15T22:17:10", + "ref_block_num": 4552, + "ref_block_prefix": 511016679, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], +``` + +and the last few lines should be: + +``` + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: + +3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. + +4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. + +Then each of the top 21 block producers should do the following: + +5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: + +``` +$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json +2,4c2,4 +< "expiration": "2018-06-15T22:17:10", +< "ref_block_num": 4552, +< "ref_block_prefix": 511016679, +--- +> "expiration": "2018-06-15T21:20:39", +> "ref_block_num": 4972, +> "ref_block_prefix": 195390844, +``` + +6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. + +First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. + +Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): + +``` +$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 +private key: "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" + ], + "context_free_data": [] +} +``` + +Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. + +The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. + +When the lead producer collects 15 producer signatures, the lead producer should do the following: + +7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: + +``` +$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 + "transaction_extensions": [], + "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", + "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", + "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", + "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", + "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", + "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", + "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", + "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", + "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", + "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", + "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", + "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", + "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", + "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", + "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" + ], + "context_free_data": [] +} +``` + +8. Push the signed transaction to the blockchain: + +``` +$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json +{ + "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "processed": { + "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "receipt": { + "status": "executed", + "cpu_usage_us": 4909, + "net_usage_words": 15124 + }, + "elapsed": 4909, + "net_usage": 120992, + "scheduled": false, + "action_traces": [{ +... +``` + +If you get an error message like the following: + +``` +Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations +Ensure that you have the related private keys inside your wallet and your wallet is unlocked. +``` + +That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. + +If you get an error message like the following: + +``` +Error 3090002: irrelevant signature included +Please remove the unnecessary signature from your transaction! +``` + +That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. + +If you get an error message like the following: + +``` +Error 3040006: Transaction Expiration Too Far +Please decrease the expiration time of your transaction! +``` + +That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. + +If you get an error message like the following: + +``` +Error 3040005: Expired Transaction +Please increase the expiration time of your transaction! +``` + +That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. + +9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: + +``` +$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio +code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 +saving wast to new_system_contract.wast +saving abi to new_system_contract.abi +$ diff original_system_contract.abi new_system_contract.abi +584,592d583 +< },{ +< "name": "deferred_trx_id", +< "type": "uint32" +< },{ +< "name": "last_unstake_time", +< "type": "time_point_sec" +< },{ +< "name": "unstaking", +< "type": "asset" +``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md new file mode 100644 index 00000000..1ca3ca04 --- /dev/null +++ b/docs/eosio.system/introduction.md @@ -0,0 +1,65 @@ +## Introducing eosio.system contract + +The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: +- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. +- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. +- Users can buy and sell RAM at a market-determined price. +- Users can bid on premium names. +- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. + +The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + +|Action name|Action description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setabi|Allows for updates of the contract ABI of an account.| +|setcode|Allows for updates of the contract code of an account.| +|init|Initializes the system contract for a version and a symbol.| +|setram|Set the ram supply.| +|setramrate|Set the ram increase rate.| +|setparams|Set the blockchain parameters.| +|setpriv|Set privilege status for an account (turn it on/off).| +|setalimits|Set the resource limits of an account.| +|setacctram|Set the RAM limits of an account.| +|setacctnet|Set the NET limits of an account.| +|setacctcpu|Set the CPU limits of an account.| +|rmvproducer|Deactivates a producer by name, if not found asserts.| +|updtrevision|Updates the current revision.| +|bidname|Allows an account to place a bid for a name.| +|bidrefund|Allows an account to get back the amount it bid so far on a name.| +|deposit|Deposits core tokens to user REX fund.| +|withdraw|Withdraws core tokens from user REX fund.| +|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| +|unstaketorex|Use staked core tokens to buy REX.| +|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| +|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| +|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| +|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| +|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| +|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| +|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| +|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| +|updaterex|Updates REX owner vote weight to current value of held REX tokens.| +|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| +|mvtosavings|Moves a specified amount of REX to savings bucket.| +|mvfrsavings|Moves a specified amount of REX from savings bucket.| +|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| +|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| +|buyrambytes|Increases receiver's ram in quantity of bytes provided.| +|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| +|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| +|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| +|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| +|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| +|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| +|unregprod|Deactivate the block producer with specified account.| +|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| +|regproxy|Set specified account as proxy.| +|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| +|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md new file mode 100644 index 00000000..5f341b63 --- /dev/null +++ b/docs/eosio.token/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.token contract + +In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testertoken` + +``` +cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken +``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md new file mode 100644 index 00000000..3592f059 --- /dev/null +++ b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md @@ -0,0 +1,146 @@ +## How to create, issue and transfer a token + +## Step 1: Obtain Contract Source + +Navigate to your contracts directory. + +```text +cd CONTRACTS_DIR +``` +Pull the source + +```text +git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +``` +This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. + + +```text +cd eosio.contracts/eosio.token +``` + +## Step 2: Create Account for Contract +Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. +[[info]] +| +You may have to unlock your wallet first! + + +```shell +cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +``` + +## Step 3: Compile the Contract + + +```shell +eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen +``` + +## Step 4: Deploy the Token Contract + + +```shell +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +``` + +Result +```shell +Reading WASM from ... +Publishing contract... +executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us +# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... +# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... +warning: transaction executed locally, but may not be confirmed by the network yet ] +``` + +## Step 5: Create the Token +To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. + +Below is the concise way to call this method, using positional arguments: + +```shell +cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +An alternate approach uses named arguments: + +```shell +cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. + +## Step 6: Issue Tokens +The issuer can issue new tokens to the "alice" account created earlier. + +```text +cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +``` + +Result +```shell +executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles +# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> issue +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> transfer +# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +``` +This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. + +Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. + +To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. + +```shell +cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j +``` + +## Step 7: Transfer Tokens +Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. + +```shell +cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +``` + +Result +```text +executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles +# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +>> transfer +# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +``` +Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) + +```shell +cleos get currency balance eosio.token bob SYS +``` + + +```text +25.00 SYS +``` +Check "alice's" balance, notice that tokens were deducted from the account + +```shell +cleos get currency balance eosio.token alice SYS +``` + + +```text +75.00 SYS +``` +Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md new file mode 100644 index 00000000..dcde42fd --- /dev/null +++ b/docs/eosio.token/introduction.md @@ -0,0 +1,21 @@ +## Introducing eosio.token contract + +The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. + +These are the public actions the `eosio.token` contract is implementing: +|Action name|Action description| +|---|---| +|create|Allows an account to create a token in a given supply amount.| +|issue|This action issues to an account a specific quantity of tokens.| +|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| +|close|This action is the opposite for `open` action, it closes the specified account for specified token.| +|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| +|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| + +The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. + +The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). + +The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. + +Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md new file mode 100644 index 00000000..bad4e3bb --- /dev/null +++ b/docs/eosio.wrap/deploy.md @@ -0,0 +1,12 @@ +## Steps to compile and deploy eosio.wrap contract + +In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. + +### To deploy execute the following commands: + +To deploy a contract you will need first an account to which to deploy it to. +Let's assume your account name is `testerwrap` + +``` +cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap +``` \ No newline at end of file diff --git a/docs/eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md similarity index 100% rename from docs/eosio.wrap.md rename to docs/eosio.wrap/guides/how-to-use-eosio.wrap.md diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md new file mode 100644 index 00000000..db4adc63 --- /dev/null +++ b/docs/eosio.wrap/introduction.md @@ -0,0 +1,12 @@ +## Introducing eosio.wrap contract + +The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. + +It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. + +However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. + +The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. + +Why is it easier for governance actions to be executed via this contract? +The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md new file mode 100644 index 00000000..226ce05e --- /dev/null +++ b/docs/introduction.md @@ -0,0 +1,52 @@ +## About System Contracts + +The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. + +Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. + +## System contracts, system accounts, priviledged accounts + +At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. + +As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: +|Account|Priviledged|Has contract|Description| +|---|---|---|---| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| +|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.names|No|No|The account which is holding funds from namespace auctions.| +|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| +|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| +|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| +|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| +|eosio.saving|No|No|The account which holds the 4% of network inflation.| +|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| +|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| + +## How to compile the eosio.contracts + +To compile the eosio.contracts execute the following commands. + +On all platforms except macOS: +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$( nproc ) +cd .. +``` + +For macOS +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$(sysctl -n hw.ncpu) +cd .. +``` \ No newline at end of file diff --git a/docs2.json b/docs2.json new file mode 100644 index 00000000..c009574b --- /dev/null +++ b/docs2.json @@ -0,0 +1,21 @@ +{ + "name": "eosio.contracts", + "generators": [ + { + "name": "collate_markdown", + "options": { + "docs_dir": "docs" + } + }, + { + "name": "doxygen_to_xml", + "options": { + "INPUT": "eosio.bios eosio.system eosio.msig eosio.token eosio.wrap" + } + }, + { + "name": "doxybook", + "options": {} + } + ] +} \ No newline at end of file diff --git a/docs_v2/01_introduction.md b/docs_v2/01_introduction.md new file mode 100644 index 00000000..b2900892 --- /dev/null +++ b/docs_v2/01_introduction.md @@ -0,0 +1,186 @@ +# About System Contracts + +The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. + +Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. + +## System contracts, system accounts, priviledged accounts + +At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. + +As you just learned the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: + +|Account|Priviledged|Has contract|Description| +|---|---|---|---| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| +|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.names|No|No|The account which is holding funds from namespace auctions.| +|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| +|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| +|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| +|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| +|eosio.saving|No|No|The account which holds the 4% of network inflation.| +|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| +|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| + +# System contracts defined in eosio.contracts + +1. [eosio.bios](#eosio.bios-system-contract) +2. [eosio.system](#eosio.system-system-contract) +3. [eosio.msig](#eosio.msig-system-contract) +4. [eosio.token](#eosio.token-system-contract) +5. [eosio.wrap](#eosio.wrap-system-contract) + +## eosio.bios system contract + +The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. + +The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. + +|Action name|Action description| +|---|---| +|setpriv|Set privilege status for an account.| +|setalimits|Set the resource limits of an account| +|setglimits|Not implemented yet.| +|setprods|Set a new list of active producers, that is, a new producers' schedule.| +|setparams|Set the blockchain parameters.| +|reqauth|Check if an account has authorization to access the current action.| +|setabi|Set the abi for a contract identified by an account name.| + +The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. + +Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: + +|Action name|Description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setcode|Allows for update of the contract code of an account.| + +## eosio.system system contract + +The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: +- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. +- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. +- Users can buy and sell RAM at a market-determined price. +- Users can bid on premium names. +- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. + +The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + +|Action name|Action description| +|---|---| +|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| +|updateauth|Updates the permission for an account.| +|deleteauth|Delete permission for an account.| +|linkauth|Assigns a specific action from a contract to a permission you have created.| +|unlinkauth|Assigns a specific action from a contract to a permission you have created.| +|canceldelay|Allows for cancellation of a deferred transaction.| +|onerror|Called every time an error occurs while a transaction was processed.| +|setabi|Allows for updates of the contract ABI of an account.| +|setcode|Allows for updates of the contract code of an account.| +|init|Initializes the system contract for a version and a symbol.| +|setram|Set the ram supply.| +|setramrate|Set the ram increase rate.| +|setparams|Set the blockchain parameters.| +|setpriv|Set privilege status for an account (turn it on/off).| +|setalimits|Set the resource limits of an account.| +|setacctram|Set the RAM limits of an account.| +|setacctnet|Set the NET limits of an account.| +|setacctcpu|Set the CPU limits of an account.| +|rmvproducer|Deactivates a producer by name, if not found asserts.| +|updtrevision|Updates the current revision.| +|bidname|Allows an account to place a bid for a name.| +|bidrefund|Allows an account to get back the amount it bid so far on a name.| +|deposit|Deposits core tokens to user REX fund.| +|withdraw|Withdraws core tokens from user REX fund.| +|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| +|unstaketorex|Use staked core tokens to buy REX.| +|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| +|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| +|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| +|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| +|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| +|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| +|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| +|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| +|updaterex|Updates REX owner vote weight to current value of held REX tokens.| +|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| +|mvtosavings|Moves a specified amount of REX to savings bucket.| +|mvfrsavings|Moves a specified amount of REX from savings bucket.| +|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| +|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| +|buyrambytes|Increases receiver's ram in quantity of bytes provided.| +|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| +|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| +|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| +|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| +|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| +|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| +|unregprod|Deactivate the block producer with specified account.| +|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| +|regproxy|Set specified account as proxy.| +|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| +|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| + +## eosio.msig system contract + +The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. + +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +- first you create a transaction json file, +- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, +- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, +- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. + +These are the actions implemented and publicly exposed by the `eosio.msig` contract: +|Action name|Action description| +|---|---| +|propose|Creates a proposal containing one transaction.| +|approve|Approves an existing proposal.| +|unapprove|Revokes an existing proposal.| +|cancel|Cancels an existing proposal.| +|exec|Allows an account to execute a proposal.| +|invalidate|Invalidate proposal.| + +## eosio.token system contract + +The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. + +These are the public actions the `eosio.token` contract is implementing: +|Action name|Action description| +|---|---| +|create|Allows an account to create a token in a given supply amount.| +|issue|This action issues to an account a specific quantity of tokens.| +|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| +|close|This action is the opposite for `open` action, it closes the specified account for specified token.| +|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| +|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| + +The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. + +The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). + +The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. + +Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. + +## eosio.wrap system contract +The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. + +It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. + +However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. + +The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. + +Why is it easier for governance actions to be executed via this contract? +The answer to this question is explained in detailed [here](./guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs_v2/02_compile-and-deploy.md b/docs_v2/02_compile-and-deploy.md new file mode 100644 index 00000000..0d082a8e --- /dev/null +++ b/docs_v2/02_compile-and-deploy.md @@ -0,0 +1,55 @@ +## How to compile the eosio.contracts + +To compile the eosio.contracts execute the following commands. + +On all platforms except macOS: +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$( nproc ) +cd .. +``` + +For macOS +``` +cd you_local_path_to/eosio.contracts/ +rm -fr build +mkdir build +cd build +cmake .. +make -j$(sysctl -n hw.ncpu) +cd .. +``` + +## To deploy eosio.bios contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testerbios` +``` +cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios +``` + +## To deploy eosio.msig contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testermsig` +``` +cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig +``` + +## To deploy eosio.system contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testersystem` +``` +cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem +``` + +## To deploy eosio.token contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testertoken` +``` +cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken +``` + +## To deploy eosio.wrap contract execute the following command: +Let's assume your account name to which you want to deploy the contract is `testerwrap` +``` +cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap +``` \ No newline at end of file diff --git a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md b/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md new file mode 100644 index 00000000..2bd712fb --- /dev/null +++ b/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md @@ -0,0 +1,209 @@ +## Upgrading the system contract + +### Indirect method using eosio.msig contract + +Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. + +So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). + +The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. + +The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. + +For now, it is recommended to use the direct method to upgrade the system contract. + +### Direct method (avoids using eosio.msig contract) + +Each of the top 21 block producers should do the following: + +1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): + +``` +$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio +code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 +saving wast to original_system_contract.wast +saving abi to original_system_contract.abi +``` + +2. Generate the unsigned transaction which upgrades the system contract: + +``` +$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json +``` + +The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): + +``` +{ + "expiration": "2018-06-15T22:17:10", + "ref_block_num": 4552, + "ref_block_prefix": 511016679, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], +``` + +and the last few lines should be: + +``` + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: + +3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. + +4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. + +Then each of the top 21 block producers should do the following: + +5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: + +``` +$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json +2,4c2,4 +< "expiration": "2018-06-15T22:17:10", +< "ref_block_num": 4552, +< "ref_block_prefix": 511016679, +--- +> "expiration": "2018-06-15T21:20:39", +> "ref_block_num": 4972, +> "ref_block_prefix": 195390844, +``` + +6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. + +First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. + +Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): + +``` +$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 +private key: "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" + ], + "context_free_data": [] +} +``` + +Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. + +The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. + +When the lead producer collects 15 producer signatures, the lead producer should do the following: + +7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: + +``` +$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 + "transaction_extensions": [], + "signatures": [ + "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", + "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", + "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", + "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", + "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", + "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", + "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", + "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", + "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", + "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", + "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", + "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", + "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", + "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", + "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" + ], + "context_free_data": [] +} +``` + +8. Push the signed transaction to the blockchain: + +``` +$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json +{ + "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "processed": { + "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", + "receipt": { + "status": "executed", + "cpu_usage_us": 4909, + "net_usage_words": 15124 + }, + "elapsed": 4909, + "net_usage": 120992, + "scheduled": false, + "action_traces": [{ +... +``` + +If you get an error message like the following: + +``` +Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations +Ensure that you have the related private keys inside your wallet and your wallet is unlocked. +``` + +That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. + +If you get an error message like the following: + +``` +Error 3090002: irrelevant signature included +Please remove the unnecessary signature from your transaction! +``` + +That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. + +If you get an error message like the following: + +``` +Error 3040006: Transaction Expiration Too Far +Please decrease the expiration time of your transaction! +``` + +That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. + +If you get an error message like the following: + +``` +Error 3040005: Expired Transaction +Please increase the expiration time of your transaction! +``` + +That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. + +9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: + +``` +$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio +code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 +saving wast to new_system_contract.wast +saving abi to new_system_contract.abi +$ diff original_system_contract.abi new_system_contract.abi +584,592d583 +< },{ +< "name": "deferred_trx_id", +< "type": "uint32" +< },{ +< "name": "last_unstake_time", +< "type": "time_point_sec" +< },{ +< "name": "unstaking", +< "type": "asset" +``` diff --git a/docs_v2/03_guides/02_how-to-buy-ram.md b/docs_v2/03_guides/02_how-to-buy-ram.md new file mode 100644 index 00000000..19c83a37 --- /dev/null +++ b/docs_v2/03_guides/02_how-to-buy-ram.md @@ -0,0 +1,20 @@ +## How buy RAM + +### What RAM is + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### How to buy RAM + +To check the amount of RAM for an account eostutorial1: +``` +cleos get account eostutorial1 +``` + +Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: +``` +cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active +``` \ No newline at end of file diff --git a/docs_v2/03_guides/03_how-to-stake.md b/docs_v2/03_guides/03_how-to-stake.md new file mode 100644 index 00000000..fb0a5e31 --- /dev/null +++ b/docs_v2/03_guides/03_how-to-stake.md @@ -0,0 +1,47 @@ +## How to stake + +### What staking is + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. + +### Staking tokens for CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active +``` + +### Staking tokens for Bandwidth + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +To check the amount of CPU staked for an account currently: +``` +cleos get account eostutorial1 +``` + +The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. + +To stake to itself: +``` +cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active +``` + +To stake for another account, below eostutorial2 stakes for eostutorial1 account: +``` +cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active +``` diff --git a/docs_v2/03_guides/04_how-to-vote.md b/docs_v2/03_guides/04_how-to-vote.md new file mode 100644 index 00000000..7ebb62f7 --- /dev/null +++ b/docs_v2/03_guides/04_how-to-vote.md @@ -0,0 +1,12 @@ +## How to vote + +### What voting is + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +### How to vote + +To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. +``` +cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 +``` \ No newline at end of file diff --git a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md new file mode 100644 index 00000000..3592f059 --- /dev/null +++ b/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -0,0 +1,146 @@ +## How to create, issue and transfer a token + +## Step 1: Obtain Contract Source + +Navigate to your contracts directory. + +```text +cd CONTRACTS_DIR +``` +Pull the source + +```text +git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +``` +This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. + + +```text +cd eosio.contracts/eosio.token +``` + +## Step 2: Create Account for Contract +Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. +[[info]] +| +You may have to unlock your wallet first! + + +```shell +cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +``` + +## Step 3: Compile the Contract + + +```shell +eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen +``` + +## Step 4: Deploy the Token Contract + + +```shell +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +``` + +Result +```shell +Reading WASM from ... +Publishing contract... +executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us +# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... +# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... +warning: transaction executed locally, but may not be confirmed by the network yet ] +``` + +## Step 5: Create the Token +To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. + +Below is the concise way to call this method, using positional arguments: + +```shell +cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +An alternate approach uses named arguments: + +```shell +cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active +``` + +Result +```shell +executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles +# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} +``` +This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. + +## Step 6: Issue Tokens +The issuer can issue new tokens to the "alice" account created earlier. + +```text +cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +``` + +Result +```shell +executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles +# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> issue +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +>> transfer +# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +``` +This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. + +Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. + +To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. + +```shell +cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j +``` + +## Step 7: Transfer Tokens +Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. + +```shell +cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +``` + +Result +```text +executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles +# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +>> transfer +# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +``` +Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) + +```shell +cleos get currency balance eosio.token bob SYS +``` + + +```text +25.00 SYS +``` +Check "alice's" balance, notice that tokens were deducted from the account + +```shell +cleos get currency balance eosio.token alice SYS +``` + + +```text +75.00 SYS +``` +Excellent! Everything adds up. diff --git a/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md new file mode 100644 index 00000000..f68dff87 --- /dev/null +++ b/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -0,0 +1,171 @@ +## eosio.msig examples + +### Cleos usage example for issuing tokens. + +#### Prerequisites: + - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. + - account 'treasury' is the issuer of SYS token. + - account 'tester' exists. + - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. + +#### One user creates a proposal: +```` +$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester + +executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles +# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... +```` + +#### Another user reviews the transaction: +```` +$ cleos multisig review tester test +{ + "proposal_name": "test", + "requested_approvals": [{ + "actor": "treasury", + "permission": "active" + } + ], + "provided_approvals": [], + "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", + "transaction": { + "expiration": "2018-05-01T00:00:00", + "region": 0, + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_kcpu_usage": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "issue", + "authorization": [{ + "actor": "treasury", + "permission": "active" + } + ], + "data": { + "to": "tester", + "quantity": "1000.0000 SYS", + "memo": "" + }, + "hex_data": "000000005c95b1ca809698000000000004454f530000000000" + } + ] + } +} +```` + +#### And then approves it: +```` +$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury + +executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles +# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} +```` + +#### First user initiates execution: +```` +$ cleos multisig exec tester test -p tester + +executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles +# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} +```` + + +### Cleos usage example for transferring tokens. + +#### Prerequisites: + - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. + - account 'treasury' has at least 1.1000 SYS token balance. + - account 'tester' exists. + - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. + +#### One user creates a proposal: +```` +$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester + +executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles +# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... +```` + +#### Another user reviews the transaction: +```` +$ cleos multisig review tester test +{ + "proposal_name": "test", + "requested_approvals": [{ + "actor": "treasury", + "permission": "active" + } + ], + "provided_approvals": [], + "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", + "transaction": { + "expiration": "2018-05-01T00:00:00", + "region": 0, + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_kcpu_usage": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.token", + "name": "transfer", + "authorization": [{ + "actor": "treasury", + "permission": "active" + } + ], + "data": { + "from": "treasury", + "to": "tester", + "quantity": "1.0000 SYS", + "memo": "" + }, + "hex_data": "000000005c95b1ca809698000000000004454f530000000000" + } + ] + } +} +```` + +#### And then approves it: +```` +$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury + +executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles +# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} +```` + +#### First user check account balance before executing the proposed transaction +```` +$ cleos get account tester +... +SYS balances: + liquid: 1.0487 SYS + staked: 2.0000 SYS + unstaking: 0.0000 SYS + total: 4.0487 SYS +```` + +#### First user initiates execution of proposed transaction: +```` +$ cleos multisig exec tester test -p tester + +executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles +# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} +```` + +#### First user can check account balance, it should be increased by 1.0000 SYS +```` +$ cleos get account tester +... +SYS balances: + liquid: 2.0487 SYS + staked: 2.0000 SYS + unstaking: 0.0000 SYS + total: 4.0487 SYS +```` diff --git a/docs_v2/03_guides/07_how-to-use-eosio.wrap.md b/docs_v2/03_guides/07_how-to-use-eosio.wrap.md new file mode 100644 index 00000000..0f3395fc --- /dev/null +++ b/docs_v2/03_guides/07_how-to-use-eosio.wrap.md @@ -0,0 +1,874 @@ +# eosio.wrap + +## 1. Installing the eosio.wrap contract + +The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. + +First, the account `eosio.wrap` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.wrap` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.wrap` account. + +The `eosio.wrap` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. + +This guide will be using cleos to carry out the process. + +### 1.1 Create the eosio.wrap account + +#### 1.1.1 Generate the transaction to create the eosio.wrap account + +The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. + +A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. + +Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. + +First, generate a transaction to capture the necessary actions involved in creating a new account: +``` +$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json +726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} +726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} +$ cat generated_account_creation_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305501000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c660100000001000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c6601000000" + },{ + "account": "eosio", + "name": "buyrambytes", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305500c80000" + },{ + "account": "eosio", + "name": "delegatebw", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` +Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. +The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. + +Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: +``` +$ cat newaccount_payload.json +{ + "creator": "eosio", + "name": "eosio.wrap", + "owner": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": {"actor": "eosio", "permission": "active"}, + "weight": 1 + }], + "waits": [] + }, + "active": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": {"actor": "eosio", "permission": "active"}, + "weight": 1 + }], + "waits": [] + } +} +``` + +Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: +``` +$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json +$ cat generated_newaccount_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: +``` +$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json +$ cat generated_setpriv_trx.json +{ + "expiration": "2018-06-29T17:11:36", + "ref_block_num": 16349, + "ref_block_prefix": 3248946195, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setpriv", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "00004d1a03ea305501" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: +``` +$ cat create_wrap_account_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. + +Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: +``` +$ cat create_wrap_account_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" + },{ + "account": "eosio", + "name": "buyrambytes", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea305500c80000" + },{ + "account": "eosio", + "name": "delegatebw", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" + },{ + "account": "eosio", + "name": "setpriv", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": "00004d1a03ea305501" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The transaction in create_wrap_account_trx.json is now ready to be proposed. + +It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. + +This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. + +In that case, create a file producer_permissions.json with the content shown in the command below: +``` +$ cat producer_permissions.json +[ + {"actor": "blkproducera", "permission": "active"}, + {"actor": "blkproducerb", "permission": "active"}, + {"actor": "blkproducerc", "permission": "active"}, + {"actor": "blkproducerd", "permission": "active"}, + {"actor": "blkproducere", "permission": "active"}, + {"actor": "blkproducerf", "permission": "active"}, + {"actor": "blkproducerg", "permission": "active"}, + {"actor": "blkproducerh", "permission": "active"}, + {"actor": "blkproduceri", "permission": "active"}, + {"actor": "blkproducerj", "permission": "active"}, + {"actor": "blkproducerk", "permission": "active"}, + {"actor": "blkproducerl", "permission": "active"}, + {"actor": "blkproducerm", "permission": "active"}, + {"actor": "blkproducern", "permission": "active"}, + {"actor": "blkproducero", "permission": "active"}, + {"actor": "blkproducerp", "permission": "active"}, + {"actor": "blkproducerq", "permission": "active"}, + {"actor": "blkproducerr", "permission": "active"}, + {"actor": "blkproducers", "permission": "active"}, + {"actor": "blkproducert", "permission": "active"}, + {"actor": "blkproduceru", "permission": "active"} +] +``` + +#### 1.1.2 Propose the transaction to create the eosio.wrap account + +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. + +The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). + +The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. + +The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: +``` +$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera +executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.1.3 Review and approve the transaction to create the eosio.wrap account + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. + +The proposed transaction can be reviewed using the `cleos multisig review` command: +``` +$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json +$ head -n 30 create_wrap_account_trx_to_review.json +{ + "proposal_name": "createwrap", + "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "newaccount", + "authorization": [{ + "actor": "eosio", + "permission": "active" + } + ], + "data": { + "creator": "eosio", + "name": "eosio.wrap", + "owner": { + "threshold": 1, + "keys": [], + "accounts": [{ + "permission": { + "actor": "eosio", + "permission": "active" + }, +``` + +The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: +``` +$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex +$ cat expected_create_wrap_trx_serialized.hex +c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 +$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex +$ cat proposed_create_wrap_trx_serialized.hex +c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 +$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.1.4 Execute the transaction to create the eosio.wrap account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera createwrap blkproducera +executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +Anyone can now verify that the `eosio.wrap` was created: +``` +$ cleos get account eosio.wrap +privileged: true +permissions: + owner 1: 1 eosio@active, + active 1: 1 eosio@active, +memory: + quota: 49.74 KiB used: 3.33 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 us + available: 460.8 ms + limit: 460.8 ms + +producers: + +``` + +### 1.2 Deploy the eosio.wrap contract + +#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract + +The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. + +The easy way to generate this transaction is using cleos: +``` +$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json +Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... +Using already assembled WASM... +Publishing contract... +$ cat deploy_wrap_contract_trx.json +{ + "expiration": "2018-06-29T19:55:26", + "ref_block_num": 18544, + "ref_block_prefix": 562790588, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + },{ + "account": "eosio", + "name": "setabi", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: +``` +$ head -n 9 deploy_wrap_contract_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ +``` + +This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. + +#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract + +Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. + +The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). + +This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. + +The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: +``` +$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera +executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. + +The proposed transaction can be reviewed using the `cleos multisig review` command: +``` +$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json +$ cat deploy_wrap_contract_trx_to_review.json +{ + "proposal_name": "deploywrap", + "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "setcode", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": { + "account": "eosio.wrap", + "vmtype": 0, + "vmversion": 0, + "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + }, + "hex_data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" + },{ + "account": "eosio", + "name": "setabi", + "authorization": [{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": { + "account": "eosio.wrap", + "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + }, + "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" + } + ], + "transaction_extensions": [] + } +} +``` + +Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. + +This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: +``` +$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex +$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 +c0593f5b00000000000000000000020000000000ea30550000 +$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex +$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 +c0593f5b00000000000000000000020000000000ea30550000 +$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 1.2.4 Execute the transaction to create the eosio.wrap account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera deploywrap blkproducera +executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} +``` + +Anyone can now verify that the `eosio.wrap` contract was deployed correctly. + +``` +$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap +code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c +saving abi to retrieved-eosio.wrap.abi +$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm +1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm +``` + +If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. + +## 2. Using the eosio.wrap contract + +### 2.1 Example: Updating owner authority of an arbitrary account + +This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. + +This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. + +The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: +``` +$ cat producer_permissions.json +[ + {"actor": "blkproducera", "permission": "active"}, + {"actor": "blkproducerb", "permission": "active"}, + {"actor": "blkproducerc", "permission": "active"}, + {"actor": "blkproducerd", "permission": "active"}, + {"actor": "blkproducere", "permission": "active"}, + {"actor": "blkproducerf", "permission": "active"}, + {"actor": "blkproducerg", "permission": "active"}, + {"actor": "blkproducerh", "permission": "active"}, + {"actor": "blkproduceri", "permission": "active"}, + {"actor": "blkproducerj", "permission": "active"}, + {"actor": "blkproducerk", "permission": "active"}, + {"actor": "blkproducerl", "permission": "active"}, + {"actor": "blkproducerm", "permission": "active"}, + {"actor": "blkproducern", "permission": "active"}, + {"actor": "blkproducero", "permission": "active"}, + {"actor": "blkproducerp", "permission": "active"}, + {"actor": "blkproducerq", "permission": "active"}, + {"actor": "blkproducerr", "permission": "active"}, + {"actor": "blkproducers", "permission": "active"}, + {"actor": "blkproducert", "permission": "active"}, + {"actor": "blkproduceru", "permission": "active"} +] +``` + +#### 2.1.1 Generate the transaction to change the owner permission of an account + +The goal of this example is for the block producers to change the owner permission of the account `alice`. + +The initial status of the `alice` account might be: +``` +permissions: + owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV + active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +memory: + quota: 49.74 KiB used: 3.365 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 us + available: 460.8 ms + limit: 460.8 ms + +producers: +``` + +Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. + +The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: +``` +$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json +``` + +Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: +``` +$ cat update_alice_owner_trx.json +{ + "expiration": "1970-01-01T00:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "updateauth", + "authorization": [{ + "actor": "alice", + "permission": "active" + } + ], + "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. + +``` +$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json +``` + +Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. +``` +$ cat wrap_update_alice_owner_trx.json +{ + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.wrap", + "name": "exec", + "authorization": [{ + "actor": "blkproducera", + "permission": "active" + },{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. + +First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: +``` +$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex +$ cat update_alice_owner_trx_serialized.hex +0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 +``` + +Then generate the template for the transaction containing the `eosio.wrap::exec` action: +``` +$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json +$ cat wrap_update_alice_owner_trx.json +{ + "expiration": "2018-06-29T23:34:01", + "ref_block_num": 23708, + "ref_block_prefix": 3605208482, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.wrap", + "name": "exec", + "authorization": [], + "data": "60ae423ad15b613c" + } + ], + "transaction_extensions": [], + "signatures": [], + "context_free_data": [] +} +``` + +Then modify the transaction in wrap_update_alice_owner_trx.json as follows: + * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; + * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); + * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. + + +#### 2.1.2 Propose the transaction to change the owner permission of an account + +The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: +``` +$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera +executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us +# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.1.3 Review and approve the transaction to change the owner permission of an account + +Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. +``` +$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json +$ cat wrap_update_alice_owner_trx_to_review.json +{ + "proposal_name": "updatealice", + "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", + "transaction": { + "expiration": "2018-07-06T12:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio.wrap", + "name": "exec", + "authorization": [{ + "actor": "blkproducera", + "permission": "active" + },{ + "actor": "eosio.wrap", + "permission": "active" + } + ], + "data": { + "executer": "blkproducera", + "trx": { + "expiration": "1970-01-01T00:00:00", + "ref_block_num": 0, + "ref_block_prefix": 0, + "max_net_usage_words": 0, + "max_cpu_usage_ms": 0, + "delay_sec": 0, + "context_free_actions": [], + "actions": [{ + "account": "eosio", + "name": "updateauth", + "authorization": [{ + "actor": "alice", + "permission": "active" + } + ], + "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" + } + ], + "transaction_extensions": [] + } + }, + "hex_data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" + } + ], + "transaction_extensions": [] + } +} +``` + +The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.wrap::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. + +Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. + +Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: +``` +$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex +$ cat expected_wrap_update_alice_owner_trx_serialized.hex +c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 +$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex +$ cat proposed_wrap_update_alice_owner_trx_serialized.hex +c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 +$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex +``` + +When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +``` +$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us +# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +#### 2.1.4 Execute the transaction to change the owner permission of an account + +When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). + +``` +$ cleos multisig exec blkproducera updatealice blkproducera +executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us +# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} +warning: transaction executed locally, but may not be confirmed by the network yet +``` + +Anyone can now verify that the owner authority of `alice` was successfully changed: +``` +$ cleos get account alice +permissions: + owner 1: 1 eosio@active, + active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV +memory: + quota: 49.74 KiB used: 3.348 KiB + +net bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 0 bytes + available: 2.304 MiB + limit: 2.304 MiB + +cpu bandwidth: + staked: 1.0000 SYS (total stake delegated from account to self) + delegated: 0.0000 SYS (total staked delegated to account from others) + used: 413 us + available: 460.4 ms + limit: 460.8 ms + +producers: + +``` From 3fe59fb664c8c8fd567d61099386213cf965e3e2 Mon Sep 17 00:00:00 2001 From: ovi Date: Mon, 12 Aug 2019 13:40:34 +0300 Subject: [PATCH 0847/1048] refactoring after feedback from Sean/Han and incorporating corrections made by Zorba80 we decided to go with the docs_v2 content layout, so renaming docs_v2 to docs. correct the internal links to anchors --- {docs_v2 => docs}/01_introduction.md | 55 +- {docs_v2 => docs}/02_compile-and-deploy.md | 0 .../01_upgrading-the-eosio.system-contract.md | 2 + docs/03_guides/02_how-to-buy-ram.md | 8 + docs/03_guides/03_how-to-stake.md | 8 + docs/03_guides/04_how-to-vote.md | 8 + ...ow-to-create-issue-and-transfer-a-token.md | 44 +- ...-a-multisig-transaction-with-eosio.msig.md | 0 .../03_guides/07_how-to-use-eosio.wrap.md | 0 docs/eosio.bios/deploy.md | 12 - docs/eosio.bios/introduction.md | 30 - docs/eosio.msig/deploy.md | 12 - ...-a-multisig-transaction-with-eosio.msig.md | 171 ---- docs/eosio.msig/introduction.md | 19 - docs/eosio.system/deploy.md | 12 - docs/eosio.system/guides/how-to-buy-ram.md | 20 - docs/eosio.system/guides/how-to-stake.md | 47 - docs/eosio.system/guides/how-to-vote.md | 12 - .../upgrading-the-eosio.system-contract.md | 209 ----- docs/eosio.system/introduction.md | 65 -- docs/eosio.token/deploy.md | 12 - ...ow-to-create-issue-and-transfer-a-token.md | 146 --- docs/eosio.token/introduction.md | 21 - docs/eosio.wrap/deploy.md | 12 - .../guides/how-to-use-eosio.wrap.md | 874 ------------------ docs/eosio.wrap/introduction.md | 12 - docs/introduction.md | 52 -- docs_v2/03_guides/02_how-to-buy-ram.md | 20 - docs_v2/03_guides/03_how-to-stake.md | 47 - docs_v2/03_guides/04_how-to-vote.md | 12 - 30 files changed, 80 insertions(+), 1862 deletions(-) rename {docs_v2 => docs}/01_introduction.md (76%) rename {docs_v2 => docs}/02_compile-and-deploy.md (100%) rename {docs_v2 => docs}/03_guides/01_upgrading-the-eosio.system-contract.md (99%) create mode 100644 docs/03_guides/02_how-to-buy-ram.md create mode 100644 docs/03_guides/03_how-to-stake.md create mode 100644 docs/03_guides/04_how-to-vote.md rename {docs_v2 => docs}/03_guides/05_how-to-create-issue-and-transfer-a-token.md (67%) rename {docs_v2 => docs}/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md (100%) rename {docs_v2 => docs}/03_guides/07_how-to-use-eosio.wrap.md (100%) delete mode 100644 docs/eosio.bios/deploy.md delete mode 100644 docs/eosio.bios/introduction.md delete mode 100644 docs/eosio.msig/deploy.md delete mode 100644 docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md delete mode 100644 docs/eosio.msig/introduction.md delete mode 100644 docs/eosio.system/deploy.md delete mode 100644 docs/eosio.system/guides/how-to-buy-ram.md delete mode 100644 docs/eosio.system/guides/how-to-stake.md delete mode 100644 docs/eosio.system/guides/how-to-vote.md delete mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md delete mode 100644 docs/eosio.system/introduction.md delete mode 100644 docs/eosio.token/deploy.md delete mode 100644 docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md delete mode 100644 docs/eosio.token/introduction.md delete mode 100644 docs/eosio.wrap/deploy.md delete mode 100644 docs/eosio.wrap/guides/how-to-use-eosio.wrap.md delete mode 100644 docs/eosio.wrap/introduction.md delete mode 100644 docs/introduction.md delete mode 100644 docs_v2/03_guides/02_how-to-buy-ram.md delete mode 100644 docs_v2/03_guides/03_how-to-stake.md delete mode 100644 docs_v2/03_guides/04_how-to-vote.md diff --git a/docs_v2/01_introduction.md b/docs/01_introduction.md similarity index 76% rename from docs_v2/01_introduction.md rename to docs/01_introduction.md index b2900892..d1e29f40 100644 --- a/docs_v2/01_introduction.md +++ b/docs/01_introduction.md @@ -1,10 +1,12 @@ -# About System Contracts +## About System Contracts The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. -Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. +Block.one implements and maintains EOSIO open source platform which contains, as an example, the system contracts encapsulating the base functionality for an EOSIO based blockchain. This document will detail each one of them, [eosio.bios](#eosiobios-system-contract), [eosio.system](#eosiosystem-system-contract), [eosio.msig](#eosiomsig-system-contract), [eosio.token](#eosiotoken-system-contract), [eosio.wrap](#eosiowrap-system-contract) along with a few other main concepts. -## System contracts, system accounts, priviledged accounts +## Concepts + +### System contracts, system accounts, priviledged accounts At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. @@ -26,15 +28,38 @@ As you just learned the relation between an account and a contract, we are addin |eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| |eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| -# System contracts defined in eosio.contracts +### RAM + +RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM as the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +### CPU + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time an account has at its disposal when pushing actions to a contract. + +### NET + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. + +### Stake + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, in spite of inflation caused by minting new tokens in order to reward BPs for their services every 24 hours. + +### Vote + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these nodes are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. + +## System contracts defined in eosio.contracts -1. [eosio.bios](#eosio.bios-system-contract) -2. [eosio.system](#eosio.system-system-contract) -3. [eosio.msig](#eosio.msig-system-contract) -4. [eosio.token](#eosio.token-system-contract) -5. [eosio.wrap](#eosio.wrap-system-contract) +1. [eosio.bios](#eosiobios-system-contract) +2. [eosio.system](#eosiosystem-system-contract) +3. [eosio.msig](#eosiomsig-system-contract) +4. [eosio.token](#eosiotoken-system-contract) +5. [eosio.wrap](#eosiowrap-system-contract) -## eosio.bios system contract +### eosio.bios system contract The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. @@ -65,7 +90,7 @@ Below are listed the actions which are declared in the `eosio.bios` contract, ma |onerror|Called every time an error occurs while a transaction was processed.| |setcode|Allows for update of the contract code of an account.| -## eosio.system system contract +### eosio.system system contract The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. @@ -131,7 +156,7 @@ The actions implemented and publicly exposed by the `eosio.system` system contra |onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| |claimrewards|Claim block producing and vote rewards for block producer identified by an account.| -## eosio.msig system contract +### eosio.msig system contract The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. @@ -146,12 +171,12 @@ These are the actions implemented and publicly exposed by the `eosio.msig` contr |---|---| |propose|Creates a proposal containing one transaction.| |approve|Approves an existing proposal.| -|unapprove|Revokes an existing proposal.| +|unapprove|Revokes approval of an existing proposal.| |cancel|Cancels an existing proposal.| |exec|Allows an account to execute a proposal.| |invalidate|Invalidate proposal.| -## eosio.token system contract +### eosio.token system contract The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. @@ -173,7 +198,7 @@ The `eosio.token` contract manages the set of tokens, accounts and their corresp Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. -## eosio.wrap system contract +### eosio.wrap system contract The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. diff --git a/docs_v2/02_compile-and-deploy.md b/docs/02_compile-and-deploy.md similarity index 100% rename from docs_v2/02_compile-and-deploy.md rename to docs/02_compile-and-deploy.md diff --git a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md b/docs/03_guides/01_upgrading-the-eosio.system-contract.md similarity index 99% rename from docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md rename to docs/03_guides/01_upgrading-the-eosio.system-contract.md index 2bd712fb..953ce073 100644 --- a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md +++ b/docs/03_guides/01_upgrading-the-eosio.system-contract.md @@ -73,6 +73,8 @@ Then each of the top 21 block producers should do the following: 5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: +TO DO: Shouldn't one of the files be upgrade_system_contract_trx.json? + ``` $ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json 2,4c2,4 diff --git a/docs/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md new file mode 100644 index 00000000..5c4f49d3 --- /dev/null +++ b/docs/03_guides/02_how-to-buy-ram.md @@ -0,0 +1,8 @@ +## How buy RAM + +You can buy RAM using `cleos` command line tool or using a wallet that implements the buy RAM functionality. + +TO DO: add link below +To buy ram using `cleos` check [how to buy ram](how-to-buy-ram). + +To buy ram using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md new file mode 100644 index 00000000..0389415d --- /dev/null +++ b/docs/03_guides/03_how-to-stake.md @@ -0,0 +1,8 @@ +## How to stake tokens for CPU and/or NET bandwidth + +You can stake tokens for CPU and/or NET bandwidth using `cleos` command line tool or using a wallet that implements this functionality. + +TO DO: add link below +To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](how-to-stake-resource). + +To stake tokens for CPU and/or NET bandwidth using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md new file mode 100644 index 00000000..babb2195 --- /dev/null +++ b/docs/03_guides/04_how-to-vote.md @@ -0,0 +1,8 @@ +## How to vote + +You can vote using `cleos` command line tool or using a wallet that implements the vote functionality. + +TO DO: add link below +To vote using `cleos` check [how to vote](how-to-vote). + +To vote using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md similarity index 67% rename from docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md rename to docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md index 3592f059..584e4a64 100644 --- a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -7,24 +7,19 @@ Navigate to your contracts directory. ```text cd CONTRACTS_DIR ``` -Pull the source +Pull the source ```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch +git clone https://github.com/EOSIO/eosio.contracts --branch master --single-branch ``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - ```text cd eosio.contracts/eosio.token ``` ## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. [[info]] -| -You may have to unlock your wallet first! - +| You may have to unlock your wallet first! ```shell cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV @@ -32,19 +27,17 @@ cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHu ## Step 3: Compile the Contract - ```shell eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen ``` ## Step 4: Deploy the Token Contract - ```shell cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active ``` -Result +Result should look similar to the one below: ```shell Reading WASM from ... Publishing contract... @@ -55,26 +48,24 @@ warning: transaction executed locally, but may not be confirmed by the network y ``` ## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: ```shell cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active ``` -Result +Result should look similar to the one below: ```shell executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} ``` + An alternate approach uses named arguments: ```shell cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active ``` -Result +Result should look similar to the one below: ```shell executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} @@ -82,13 +73,14 @@ executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. ## Step 6: Issue Tokens + The issuer can issue new tokens to the "alice" account created earlier. ```text cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active ``` -Result +Result should look similar to the one below: ```shell executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles # eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} @@ -98,24 +90,16 @@ executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd411 # eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} # user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` ## Step 7: Transfer Tokens + Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. ```shell cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active ``` -Result +Result should look similar to the one below: ```text executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles # eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} @@ -129,18 +113,18 @@ Now check if "bob" got the tokens using [cleos get currency balance](https://dev cleos get currency balance eosio.token bob SYS ``` - +Result: ```text 25.00 SYS ``` + Check "alice's" balance, notice that tokens were deducted from the account ```shell cleos get currency balance eosio.token alice SYS ``` - +Result: ```text 75.00 SYS ``` -Excellent! Everything adds up. diff --git a/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 100% rename from docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md rename to docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md diff --git a/docs_v2/03_guides/07_how-to-use-eosio.wrap.md b/docs/03_guides/07_how-to-use-eosio.wrap.md similarity index 100% rename from docs_v2/03_guides/07_how-to-use-eosio.wrap.md rename to docs/03_guides/07_how-to-use-eosio.wrap.md diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md deleted file mode 100644 index 57a5923b..00000000 --- a/docs/eosio.bios/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps deploy eosio.bios contract - -In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerbios` - -``` -cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios -``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md deleted file mode 100644 index fc31c0c7..00000000 --- a/docs/eosio.bios/introduction.md +++ /dev/null @@ -1,30 +0,0 @@ -## Introducing eosio.bios contract - -The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. - -The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. - -|Action name|Action description| -|---|---| -|setpriv|Set privilege status for an account.| -|setalimits|Set the resource limits of an account| -|setglimits|Not implemented yet.| -|setprods|Set a new list of active producers, that is, a new producers' schedule.| -|setparams|Set the blockchain parameters.| -|reqauth|Check if an account has authorization to access the current action.| -|setabi|Set the abi for a contract identified by an account name.| - -The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. - -Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: - -|Action name|Description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md deleted file mode 100644 index d5f027d8..00000000 --- a/docs/eosio.msig/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.msig contract - -In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testermsig` - -``` -cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig -``` \ No newline at end of file diff --git a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md deleted file mode 100644 index f68dff87..00000000 --- a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ /dev/null @@ -1,171 +0,0 @@ -## eosio.msig examples - -### Cleos usage example for issuing tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' is the issuer of SYS token. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "issue", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "to": "tester", - "quantity": "1000.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user initiates execution: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - - -### Cleos usage example for transferring tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' has at least 1.1000 SYS token balance. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "transfer", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "from": "treasury", - "to": "tester", - "quantity": "1.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user check account balance before executing the proposed transaction -```` -$ cleos get account tester -... -SYS balances: - liquid: 1.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` - -#### First user initiates execution of proposed transaction: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - -#### First user can check account balance, it should be increased by 1.0000 SYS -```` -$ cleos get account tester -... -SYS balances: - liquid: 2.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md deleted file mode 100644 index 8fea8056..00000000 --- a/docs/eosio.msig/introduction.md +++ /dev/null @@ -1,19 +0,0 @@ -## Introducing eosio.msig contract - -The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. - -The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: -- first you create a transaction json file, -- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, -- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, -- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. - -These are the actions implemented and publicly exposed by the `eosio.msig` contract: -|Action name|Action description| -|---|---| -|propose|Creates a proposal containing one transaction.| -|approve|Approves an existing proposal.| -|unapprove|Revokes an existing proposal.| -|cancel|Cancels an existing proposal.| -|exec|Allows an account to execute a proposal.| -|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md deleted file mode 100644 index 13703abd..00000000 --- a/docs/eosio.system/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.system contract - -In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testersystem` - -``` -cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md deleted file mode 100644 index 19c83a37..00000000 --- a/docs/eosio.system/guides/how-to-buy-ram.md +++ /dev/null @@ -1,20 +0,0 @@ -## How buy RAM - -### What RAM is - -RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). -The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). - -### How to buy RAM - -To check the amount of RAM for an account eostutorial1: -``` -cleos get account eostutorial1 -``` - -Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: -``` -cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md deleted file mode 100644 index fb0a5e31..00000000 --- a/docs/eosio.system/guides/how-to-stake.md +++ /dev/null @@ -1,47 +0,0 @@ -## How to stake - -### What staking is - -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. - -### Staking tokens for CPU - -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active -``` - -### Staking tokens for Bandwidth - -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active -``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md deleted file mode 100644 index 7ebb62f7..00000000 --- a/docs/eosio.system/guides/how-to-vote.md +++ /dev/null @@ -1,12 +0,0 @@ -## How to vote - -### What voting is - -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. - -### How to vote - -To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. -``` -cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md deleted file mode 100644 index 2bd712fb..00000000 --- a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md +++ /dev/null @@ -1,209 +0,0 @@ -## Upgrading the system contract - -### Indirect method using eosio.msig contract - -Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. - -So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). - -The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. - -The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. - -For now, it is recommended to use the direct method to upgrade the system contract. - -### Direct method (avoids using eosio.msig contract) - -Each of the top 21 block producers should do the following: - -1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): - -``` -$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio -code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 -saving wast to original_system_contract.wast -saving abi to original_system_contract.abi -``` - -2. Generate the unsigned transaction which upgrades the system contract: - -``` -$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json -``` - -The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): - -``` -{ - "expiration": "2018-06-15T22:17:10", - "ref_block_num": 4552, - "ref_block_prefix": 511016679, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], -``` - -and the last few lines should be: - -``` - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: - -3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. - -4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. - -Then each of the top 21 block producers should do the following: - -5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: - -``` -$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json -2,4c2,4 -< "expiration": "2018-06-15T22:17:10", -< "ref_block_num": 4552, -< "ref_block_prefix": 511016679, ---- -> "expiration": "2018-06-15T21:20:39", -> "ref_block_num": 4972, -> "ref_block_prefix": 195390844, -``` - -6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. - -First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. - -Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): - -``` -$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 -private key: "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" - ], - "context_free_data": [] -} -``` - -Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. - -The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. - -When the lead producer collects 15 producer signatures, the lead producer should do the following: - -7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: - -``` -$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 - "transaction_extensions": [], - "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", - "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", - "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", - "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", - "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", - "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", - "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", - "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", - "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", - "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", - "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", - "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", - "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", - "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", - "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" - ], - "context_free_data": [] -} -``` - -8. Push the signed transaction to the blockchain: - -``` -$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json -{ - "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "processed": { - "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "receipt": { - "status": "executed", - "cpu_usage_us": 4909, - "net_usage_words": 15124 - }, - "elapsed": 4909, - "net_usage": 120992, - "scheduled": false, - "action_traces": [{ -... -``` - -If you get an error message like the following: - -``` -Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations -Ensure that you have the related private keys inside your wallet and your wallet is unlocked. -``` - -That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. - -If you get an error message like the following: - -``` -Error 3090002: irrelevant signature included -Please remove the unnecessary signature from your transaction! -``` - -That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. - -If you get an error message like the following: - -``` -Error 3040006: Transaction Expiration Too Far -Please decrease the expiration time of your transaction! -``` - -That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. - -If you get an error message like the following: - -``` -Error 3040005: Expired Transaction -Please increase the expiration time of your transaction! -``` - -That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. - -9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: - -``` -$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio -code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 -saving wast to new_system_contract.wast -saving abi to new_system_contract.abi -$ diff original_system_contract.abi new_system_contract.abi -584,592d583 -< },{ -< "name": "deferred_trx_id", -< "type": "uint32" -< },{ -< "name": "last_unstake_time", -< "type": "time_point_sec" -< },{ -< "name": "unstaking", -< "type": "asset" -``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md deleted file mode 100644 index 1ca3ca04..00000000 --- a/docs/eosio.system/introduction.md +++ /dev/null @@ -1,65 +0,0 @@ -## Introducing eosio.system contract - -The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: -- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. -- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. -- Users can buy and sell RAM at a market-determined price. -- Users can bid on premium names. -- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. - -The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - -|Action name|Action description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setabi|Allows for updates of the contract ABI of an account.| -|setcode|Allows for updates of the contract code of an account.| -|init|Initializes the system contract for a version and a symbol.| -|setram|Set the ram supply.| -|setramrate|Set the ram increase rate.| -|setparams|Set the blockchain parameters.| -|setpriv|Set privilege status for an account (turn it on/off).| -|setalimits|Set the resource limits of an account.| -|setacctram|Set the RAM limits of an account.| -|setacctnet|Set the NET limits of an account.| -|setacctcpu|Set the CPU limits of an account.| -|rmvproducer|Deactivates a producer by name, if not found asserts.| -|updtrevision|Updates the current revision.| -|bidname|Allows an account to place a bid for a name.| -|bidrefund|Allows an account to get back the amount it bid so far on a name.| -|deposit|Deposits core tokens to user REX fund.| -|withdraw|Withdraws core tokens from user REX fund.| -|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| -|unstaketorex|Use staked core tokens to buy REX.| -|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| -|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| -|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| -|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| -|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| -|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| -|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| -|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| -|updaterex|Updates REX owner vote weight to current value of held REX tokens.| -|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| -|mvtosavings|Moves a specified amount of REX to savings bucket.| -|mvfrsavings|Moves a specified amount of REX from savings bucket.| -|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| -|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| -|buyrambytes|Increases receiver's ram in quantity of bytes provided.| -|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| -|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| -|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| -|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| -|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| -|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| -|unregprod|Deactivate the block producer with specified account.| -|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| -|regproxy|Set specified account as proxy.| -|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| -|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md deleted file mode 100644 index 5f341b63..00000000 --- a/docs/eosio.token/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.token contract - -In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testertoken` - -``` -cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken -``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md deleted file mode 100644 index 3592f059..00000000 --- a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md +++ /dev/null @@ -1,146 +0,0 @@ -## How to create, issue and transfer a token - -## Step 1: Obtain Contract Source - -Navigate to your contracts directory. - -```text -cd CONTRACTS_DIR -``` -Pull the source - -```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch -``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - - -```text -cd eosio.contracts/eosio.token -``` - -## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. -[[info]] -| -You may have to unlock your wallet first! - - -```shell -cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -``` - -## Step 3: Compile the Contract - - -```shell -eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen -``` - -## Step 4: Deploy the Token Contract - - -```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active -``` - -Result -```shell -Reading WASM from ... -Publishing contract... -executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us -# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... -# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... -warning: transaction executed locally, but may not be confirmed by the network yet ] -``` - -## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: - -```shell -cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -An alternate approach uses named arguments: - -```shell -cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. - -## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. - -```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active -``` - -Result -```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` - -## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. - -```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active -``` - -Result -```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -``` -Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) - -```shell -cleos get currency balance eosio.token bob SYS -``` - - -```text -25.00 SYS -``` -Check "alice's" balance, notice that tokens were deducted from the account - -```shell -cleos get currency balance eosio.token alice SYS -``` - - -```text -75.00 SYS -``` -Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md deleted file mode 100644 index dcde42fd..00000000 --- a/docs/eosio.token/introduction.md +++ /dev/null @@ -1,21 +0,0 @@ -## Introducing eosio.token contract - -The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. - -These are the public actions the `eosio.token` contract is implementing: -|Action name|Action description| -|---|---| -|create|Allows an account to create a token in a given supply amount.| -|issue|This action issues to an account a specific quantity of tokens.| -|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| -|close|This action is the opposite for `open` action, it closes the specified account for specified token.| -|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| -|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| - -The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. - -The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). - -The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. - -Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md deleted file mode 100644 index bad4e3bb..00000000 --- a/docs/eosio.wrap/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.wrap contract - -In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerwrap` - -``` -cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap -``` \ No newline at end of file diff --git a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md deleted file mode 100644 index 0f3395fc..00000000 --- a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md +++ /dev/null @@ -1,874 +0,0 @@ -# eosio.wrap - -## 1. Installing the eosio.wrap contract - -The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. - -First, the account `eosio.wrap` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.wrap` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.wrap` account. - -The `eosio.wrap` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. - -This guide will be using cleos to carry out the process. - -### 1.1 Create the eosio.wrap account - -#### 1.1.1 Generate the transaction to create the eosio.wrap account - -The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. - -Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. - -First, generate a transaction to capture the necessary actions involved in creating a new account: -``` -$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json -726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} -726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} -$ cat generated_account_creation_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305501000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c660100000001000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c6601000000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` -Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. -The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. - -Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: -``` -$ cat newaccount_payload.json -{ - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - }, - "active": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - } -} -``` - -Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: -``` -$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json -$ cat generated_newaccount_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: -``` -$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json -$ cat generated_setpriv_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. - -Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - },{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The transaction in create_wrap_account_trx.json is now ready to be proposed. - -It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. - -In that case, create a file producer_permissions.json with the content shown in the command below: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 1.1.2 Propose the transaction to create the eosio.wrap account - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: -``` -$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera -executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.3 Review and approve the transaction to create the eosio.wrap account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json -$ head -n 30 create_wrap_account_trx_to_review.json -{ - "proposal_name": "createwrap", - "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": { - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": { - "actor": "eosio", - "permission": "active" - }, -``` - -The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: -``` -$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex -$ cat expected_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex -$ cat proposed_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera createwrap blkproducera -executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the `eosio.wrap` was created: -``` -$ cleos get account eosio.wrap -privileged: true -permissions: - owner 1: 1 eosio@active, - active 1: 1 eosio@active, -memory: - quota: 49.74 KiB used: 3.33 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: - -``` - -### 1.2 Deploy the eosio.wrap contract - -#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract - -The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -The easy way to generate this transaction is using cleos: -``` -$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json -Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... -Using already assembled WASM... -Publishing contract... -$ cat deploy_wrap_contract_trx.json -{ - "expiration": "2018-06-29T19:55:26", - "ref_block_num": 18544, - "ref_block_prefix": 562790588, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: -``` -$ head -n 9 deploy_wrap_contract_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ -``` - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. - -#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: -``` -$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera -executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json -$ cat deploy_wrap_contract_trx_to_review.json -{ - "proposal_name": "deploywrap", - "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "vmtype": 0, - "vmversion": 0, - "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - }, - "hex_data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - }, - "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [] - } -} -``` - -Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. - -This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: -``` -$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex -$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex -$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera deploywrap blkproducera -executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} -``` - -Anyone can now verify that the `eosio.wrap` contract was deployed correctly. - -``` -$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap -code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c -saving abi to retrieved-eosio.wrap.abi -$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm -1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm -``` - -If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. - -## 2. Using the eosio.wrap contract - -### 2.1 Example: Updating owner authority of an arbitrary account - -This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. - -This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. - -The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 2.1.1 Generate the transaction to change the owner permission of an account - -The goal of this example is for the block producers to change the owner permission of the account `alice`. - -The initial status of the `alice` account might be: -``` -permissions: - owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.365 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: -``` - -Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. - -The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: -``` -$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json -``` - -Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: -``` -$ cat update_alice_owner_trx.json -{ - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. - -``` -$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json -``` - -Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. -``` -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. - -First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: -``` -$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex -$ cat update_alice_owner_trx_serialized.hex -0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 -``` - -Then generate the template for the transaction containing the `eosio.wrap::exec` action: -``` -$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-06-29T23:34:01", - "ref_block_num": 23708, - "ref_block_prefix": 3605208482, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [], - "data": "60ae423ad15b613c" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Then modify the transaction in wrap_update_alice_owner_trx.json as follows: - * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; - * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); - * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. - - -#### 2.1.2 Propose the transaction to change the owner permission of an account - -The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: -``` -$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera -executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.3 Review and approve the transaction to change the owner permission of an account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. -``` -$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json -$ cat wrap_update_alice_owner_trx_to_review.json -{ - "proposal_name": "updatealice", - "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "executer": "blkproducera", - "trx": { - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [] - } - }, - "hex_data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [] - } -} -``` - -The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.wrap::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. - -Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. - -Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: -``` -$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex -$ cat expected_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex -$ cat proposed_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.4 Execute the transaction to change the owner permission of an account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera updatealice blkproducera -executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the owner authority of `alice` was successfully changed: -``` -$ cleos get account alice -permissions: - owner 1: 1 eosio@active, - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.348 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 413 us - available: 460.4 ms - limit: 460.8 ms - -producers: - -``` diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md deleted file mode 100644 index db4adc63..00000000 --- a/docs/eosio.wrap/introduction.md +++ /dev/null @@ -1,12 +0,0 @@ -## Introducing eosio.wrap contract - -The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. - -It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. - -However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. - -The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. - -Why is it easier for governance actions to be executed via this contract? -The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md deleted file mode 100644 index 226ce05e..00000000 --- a/docs/introduction.md +++ /dev/null @@ -1,52 +0,0 @@ -## About System Contracts - -The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. - -Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. - -## System contracts, system accounts, priviledged accounts - -At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. - -As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: -|Account|Priviledged|Has contract|Description| -|---|---|---|---| -|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| -|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| -|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| -|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| -|eosio.names|No|No|The account which is holding funds from namespace auctions.| -|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| -|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| -|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| -|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| -|eosio.saving|No|No|The account which holds the 4% of network inflation.| -|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| -|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| -|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| - -## How to compile the eosio.contracts - -To compile the eosio.contracts execute the following commands. - -On all platforms except macOS: -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$( nproc ) -cd .. -``` - -For macOS -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$(sysctl -n hw.ncpu) -cd .. -``` \ No newline at end of file diff --git a/docs_v2/03_guides/02_how-to-buy-ram.md b/docs_v2/03_guides/02_how-to-buy-ram.md deleted file mode 100644 index 19c83a37..00000000 --- a/docs_v2/03_guides/02_how-to-buy-ram.md +++ /dev/null @@ -1,20 +0,0 @@ -## How buy RAM - -### What RAM is - -RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). -The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). - -### How to buy RAM - -To check the amount of RAM for an account eostutorial1: -``` -cleos get account eostutorial1 -``` - -Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: -``` -cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active -``` \ No newline at end of file diff --git a/docs_v2/03_guides/03_how-to-stake.md b/docs_v2/03_guides/03_how-to-stake.md deleted file mode 100644 index fb0a5e31..00000000 --- a/docs_v2/03_guides/03_how-to-stake.md +++ /dev/null @@ -1,47 +0,0 @@ -## How to stake - -### What staking is - -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. - -### Staking tokens for CPU - -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active -``` - -### Staking tokens for Bandwidth - -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active -``` diff --git a/docs_v2/03_guides/04_how-to-vote.md b/docs_v2/03_guides/04_how-to-vote.md deleted file mode 100644 index 7ebb62f7..00000000 --- a/docs_v2/03_guides/04_how-to-vote.md +++ /dev/null @@ -1,12 +0,0 @@ -## How to vote - -### What voting is - -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. - -### How to vote - -To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. -``` -cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 -``` \ No newline at end of file From ff925d9de3a0d9a7af53f027f5f284a11aedd652 Mon Sep 17 00:00:00 2001 From: Sandwich Date: Mon, 12 Aug 2019 13:51:18 +0200 Subject: [PATCH 0848/1048] Adjust annotations, remove typedef docs and adjust files --- .../include/eosio.bios/eosio.bios.hpp | 19 - .../include/eosio.msig/eosio.msig.hpp | 7 +- .../include/eosio.system/eosio.system.hpp | 311 ++----- .../include/eosio.system/exchange_state.hpp | 3 +- .../include/eosio.token/eosio.token.hpp | 45 +- docs.json | 30 +- {docs_v2 => docs}/01_introduction.md | 0 {docs_v2 => docs}/02_compile-and-deploy.md | 0 .../01_upgrading-the-eosio.system-contract.md | 0 .../03_guides/02_how-to-buy-ram.md | 0 .../03_guides/03_how-to-stake.md | 0 {docs_v2 => docs}/03_guides/04_how-to-vote.md | 0 ...ow-to-create-issue-and-transfer-a-token.md | 0 ...-a-multisig-transaction-with-eosio.msig.md | 0 .../03_guides/07_how-to-use-eosio.wrap.md | 0 docs/eosio.bios/deploy.md | 12 - docs/eosio.bios/introduction.md | 30 - docs/eosio.msig/deploy.md | 12 - ...-a-multisig-transaction-with-eosio.msig.md | 171 ---- docs/eosio.msig/introduction.md | 19 - docs/eosio.system/deploy.md | 12 - docs/eosio.system/guides/how-to-buy-ram.md | 20 - docs/eosio.system/guides/how-to-stake.md | 47 - docs/eosio.system/guides/how-to-vote.md | 12 - .../upgrading-the-eosio.system-contract.md | 209 ----- docs/eosio.system/introduction.md | 65 -- docs/eosio.token/deploy.md | 12 - ...w-to-create,-issue-and-transfer-a-token.md | 152 --- ...ow-to-create-issue-and-transfer-a-token.md | 146 --- docs/eosio.token/introduction.md | 21 - docs/eosio.wrap/deploy.md | 12 - .../guides/how-to-use-eosio.wrap.md | 874 ------------------ docs/eosio.wrap/introduction.md | 12 - docs/introduction.md | 52 -- 34 files changed, 100 insertions(+), 2205 deletions(-) rename {docs_v2 => docs}/01_introduction.md (100%) rename {docs_v2 => docs}/02_compile-and-deploy.md (100%) rename {docs_v2 => docs}/03_guides/01_upgrading-the-eosio.system-contract.md (100%) rename {docs_v2 => docs}/03_guides/02_how-to-buy-ram.md (100%) rename {docs_v2 => docs}/03_guides/03_how-to-stake.md (100%) rename {docs_v2 => docs}/03_guides/04_how-to-vote.md (100%) rename {docs_v2 => docs}/03_guides/05_how-to-create-issue-and-transfer-a-token.md (100%) rename {docs_v2 => docs}/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md (100%) rename {docs_v2 => docs}/03_guides/07_how-to-use-eosio.wrap.md (100%) delete mode 100644 docs/eosio.bios/deploy.md delete mode 100644 docs/eosio.bios/introduction.md delete mode 100644 docs/eosio.msig/deploy.md delete mode 100644 docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md delete mode 100644 docs/eosio.msig/introduction.md delete mode 100644 docs/eosio.system/deploy.md delete mode 100644 docs/eosio.system/guides/how-to-buy-ram.md delete mode 100644 docs/eosio.system/guides/how-to-stake.md delete mode 100644 docs/eosio.system/guides/how-to-vote.md delete mode 100644 docs/eosio.system/guides/upgrading-the-eosio.system-contract.md delete mode 100644 docs/eosio.system/introduction.md delete mode 100644 docs/eosio.token/deploy.md delete mode 100644 docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md delete mode 100644 docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md delete mode 100644 docs/eosio.token/introduction.md delete mode 100644 docs/eosio.wrap/deploy.md delete mode 100644 docs/eosio.wrap/guides/how-to-use-eosio.wrap.md delete mode 100644 docs/eosio.wrap/introduction.md delete mode 100644 docs/introduction.md diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 3fa4a4cd..4807abc0 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -38,25 +38,6 @@ namespace eosio { } } -/** - * EOSIO Contracts - * - * @details The design of the EOSIO blockchain calls for a number of smart contracts that are run at a - * privileged permission level in order to support functions such as block producer registration and - * voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart - * contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. - * - * This repository contains examples of these privileged contracts that are useful when deploying, - * managing, and/or using an EOSIO blockchain. They are provided for reference purposes: - * - eosio.bios - * - eosio.system - * - eosio.msig - * - eosio.wrap - * - * The following unprivileged contract(s) are also part of the system. - * - eosio.token - */ - namespace eosio { using eosio::ignore; diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index cd923734..465433ec 100644 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -6,6 +6,7 @@ #include namespace eosio { + /** * @defgroup eosiomsig eosio.msig * @ingroup eosiocontracts @@ -27,8 +28,7 @@ namespace eosio { * authorized by the provided keys and permissions, and if the proposal name doesn’t * already exist; if all validations pass the `proposal_name` and `trx` trasanction are * saved in the proposals table and the `requested` permission levels to the - * approvals table (for the `proposer` context). - * Storage changes are billed to `proposer`. + * approvals table (for the `proposer` context). Storage changes are billed to `proposer`. * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be unique for proposer) @@ -46,8 +46,7 @@ namespace eosio { * proposed by `proposer`. If the proposal's requested approval list contains the `level` * permission then the `level` permission is moved from internal `requested_approvals` list to * internal `provided_approvals` list of the proposal, thus persisting the approval for - * the `proposal_name` proposal. - * Storage changes are billed to `proposer`. + * the `proposal_name` proposal. Storage changes are billed to `proposer`. * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be unique for proposer) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index f2ebe9a3..b98db352 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -89,9 +89,7 @@ namespace eosiosystem { */ /** - * A name bid. - * - * @details A name bid consists of: + * A name bid, which consists of: * - a `newname` name that the bid is for * - a `high_bidder` account name that is the one with the highest bid so far * - the `high_bid` which is amount of highest bid @@ -108,9 +106,7 @@ namespace eosiosystem { }; /** - * A bid refund. - * - * @details A bid refund is defined by: + * A bid refund, which is defined by: * - the `bidder` account name owning the refund * - the `amount` to be refunded */ @@ -120,21 +116,10 @@ namespace eosiosystem { uint64_t primary_key()const { return bidder.value; } }; - - /** - * Name bid table - * - * @details The name bid table is storing all the `name_bid`s instances. - */ typedef eosio::multi_index< "namebids"_n, name_bid, indexed_by<"highbid"_n, const_mem_fun > > name_bid_table; - /** - * Bid refund table. - * - * @details The bid refund table is storing all the `bid_refund`s instances. - */ typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; /** @@ -243,9 +228,7 @@ namespace eosiosystem { }; /** - * Voter info. - * - * @details Voter info stores information about the voter: + * Voter info. Voter info stores information about the voter: * - `owner` the voter * - `proxy` the proxy set by the voter, if any * - `producers` the producers approved by this voter if no proxy set @@ -288,40 +271,23 @@ namespace eosiosystem { EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(flags1)(reserved2)(reserved3) ) }; - /** - * Voters table - * - * @details The voters table stores all the `voter_info`s instances, all voters information. - */ + typedef eosio::multi_index< "voters"_n, voter_info > voters_table; - /** - * Defines producer info table added in version 1.0 - */ typedef eosio::multi_index< "producers"_n, producer_info, indexed_by<"prototalvote"_n, const_mem_fun > > producers_table; - /** - * Defines new producer info table added in version 1.3.0 - */ + typedef eosio::multi_index< "producers2"_n, producer_info2 > producers_table2; - /** - * Global state singleton added in version 1.0 - */ + typedef eosio::singleton< "global"_n, eosio_global_state > global_state_singleton; - /** - * Global state singleton added in version 1.1.0 - */ + typedef eosio::singleton< "global2"_n, eosio_global_state2 > global_state2_singleton; - /** - * Global state singleton added in version 1.3 - */ + typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; - /** - * Global state singleton added in version 1.6.x - */ + typedef eosio::singleton< "global4"_n, eosio_global_state4 > global_state4_singleton; struct [[eosio::table, eosio::contract("eosio.system")]] user_resources { @@ -367,18 +333,13 @@ namespace eosiosystem { EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(net_amount)(cpu_amount) ) }; - /** - * These tables are designed to be constructed in the scope of the relevant user, this - * facilitates simpler API for per-user queries - */ + typedef eosio::multi_index< "userres"_n, user_resources > user_resources_table; typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; /** - * `rex_pool` structure underlying the rex pool table. - * - * @details A rex pool table entry is defined by: + * `rex_pool` structure underlying the rex pool table. A rex pool table entry is defined by: * - `version` defaulted to zero, * - `total_lent` total amount of CORE_SYMBOL in open rex_loans * - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), @@ -401,18 +362,10 @@ namespace eosiosystem { uint64_t primary_key()const { return 0; } }; - /** - * Rex pool table - * - * @details The rex pool table is storing the only one instance of rex_pool which it stores - * the global state of the REX system. - */ typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; /** - * `rex_fund` structure underlying the rex fund table. - * - * @details A rex fund table entry is defined by: + * `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: * - `version` defaulted to zero, * - `owner` the owner of the rex fund, * - `balance` the balance of the fund. @@ -425,17 +378,10 @@ namespace eosiosystem { uint64_t primary_key()const { return owner.value; } }; - /** - * Rex fund table - * - * @details The rex fund table is storing all the `rex_fund`s instances. - */ typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; /** - * `rex_balance` structure underlying the rex balance table. - * - * @details A rex balance table entry is defined by: + * `rex_balance` structure underlying the rex balance table. A rex balance table entry is defined by: * - `version` defaulted to zero, * - `owner` the owner of the rex fund, * - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, @@ -453,17 +399,10 @@ namespace eosiosystem { uint64_t primary_key()const { return owner.value; } }; - /** - * Rex balance table - * - * @details The rex balance table is storing all the `rex_balance`s instances. - */ typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; /** - * `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. - * - * @details A rex net/cpu loan table entry is defined by: + * `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. A rex net/cpu loan table entry is defined by: * - `version` defaulted to zero, * - `from` account creating and paying for loan, * - `receiver` account receiving rented resources, @@ -489,21 +428,11 @@ namespace eosiosystem { uint64_t by_owner()const { return from.value; } }; - /** - * Rex cpu loan table - * - * @details The rex cpu loan table is storing all the `rex_loan`s instances for cpu, indexed by loan number, expiration and owner. - */ typedef eosio::multi_index< "cpuloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, indexed_by<"byowner"_n, const_mem_fun> > rex_cpu_loan_table; - /** - * Rex net loan table - * - * @details The rex net loan table is storing all the `rex_loan`s instances for net, indexed by loan number, expiration and owner. - */ typedef eosio::multi_index< "netloan"_n, rex_loan, indexed_by<"byexpr"_n, const_mem_fun>, indexed_by<"byowner"_n, const_mem_fun> @@ -523,11 +452,6 @@ namespace eosiosystem { uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } }; - /** - * Rex order table - * - * @details The rex order table is storing all the `rex_order`s instances, indexed by owner and time and owner. - */ typedef eosio::multi_index< "rexqueue"_n, rex_order, indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; @@ -538,9 +462,7 @@ namespace eosiosystem { }; /** - * The EOSIO system contract. - * - * @details The EOSIO system contract governs ram market, voters, producers, global state. + * The EOSIO system contract. The EOSIO system contract governs ram market, voters, producers, global state. */ class [[eosio::contract("eosio.system")]] system_contract : public native { @@ -578,15 +500,6 @@ namespace eosiosystem { static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); - /** - * System contract constructor. - * - * @details Constructs a system contract based on self account, code account and data. - * - * @param s - The current code account that is executing the action, - * @param code - The original code account that executed the action, - * @param ds - The contract data represented as an `eosio::datastream`. - */ system_contract( name s, name code, datastream ds ); ~system_contract(); @@ -603,9 +516,7 @@ namespace eosiosystem { // Actions: /** - * Init action. - * - * @details Init action initializes the system contract for a version and a symbol. + * The Init action initializes the system contract for a version and a symbol. * Only succeeds when: * - version is 0 and * - symbol is found and @@ -619,9 +530,7 @@ namespace eosiosystem { void init( unsigned_int version, const symbol& core ); /** - * On block action. - * - * @details This special action is triggered when a block is applied by the given producer + * On block action. This special action is triggered when a block is applied by the given producer * and cannot be generated from any other source. It is used to pay producers and calculate * missed blocks of other producers. Producer pay is deposited into the producer's stake * balance and can be withdrawn over time. If blocknum is the start of a new round this may @@ -633,9 +542,7 @@ namespace eosiosystem { void onblock( ignore header ); /** - * Set account limits action. - * - * @details Set the resource limits of an account + * Set account limits action sets the resource limits of an account * * @param account - name of the account whose resource limit to be set, * @param ram_bytes - ram limit in absolute bytes, @@ -646,9 +553,7 @@ namespace eosiosystem { void setalimits( const name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); /** - * Set account RAM limits action. - * - * @details Set the RAM limits of an account + * Set account RAM limits action, which sets the RAM limits of an account * * @param account - name of the account whose resource limit to be set, * @param ram_bytes - ram limit in absolute bytes. @@ -657,9 +562,7 @@ namespace eosiosystem { void setacctram( const name& account, const std::optional& ram_bytes ); /** - * Set account NET limits action. - * - * @details Set the NET limits of an account + * Set account NET limits action, which sets the NET limits of an account * * @param account - name of the account whose resource limit to be set, * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts). @@ -668,9 +571,7 @@ namespace eosiosystem { void setacctnet( const name& account, const std::optional& net_weight ); /** - * Set account CPU limits action. - * - * @details Set the CPU limits of an account + * Set account CPU limits action, which sets the CPU limits of an account * * @param account - name of the account whose resource limit to be set, * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). @@ -680,9 +581,7 @@ namespace eosiosystem { /** - * Activates a protocol feature. - * - * @details Activates a protocol feature + * Activates a protocol feature * * @param feature_digest - hash of the protocol feature to activate. */ @@ -692,9 +591,7 @@ namespace eosiosystem { // functions defined in delegate_bandwidth.cpp /** - * Delegate bandwidth and/or cpu action. - * - * @details Stakes SYS from the balance of `from` for the benefit of `receiver`. + * Delegate bandwidth and/or cpu action. Stakes SYS from the balance of `from` for the benefit of `receiver`. * * @param from - the account to delegate bandwidth from, that is, the account holding * tokens to be staked, @@ -720,9 +617,7 @@ namespace eosiosystem { void setrex( const asset& balance ); /** - * Deposit to REX fund action. - * - * @details Deposits core tokens to user REX fund. + * Deposit to REX fund action. Deposits core tokens to user REX fund. * All proceeds and expenses related to REX are added to or taken out of this fund. * An inline transfer from 'owner' liquid balance is executed. * All REX-related costs and proceeds are deducted from and added to 'owner' REX fund, @@ -748,9 +643,7 @@ namespace eosiosystem { void withdraw( const name& owner, const asset& amount ); /** - * Buyrex action. - * - * @details Buys REX in exchange for tokens taken out of user's REX fund by transfering + * Buyrex action. Buys REX in exchange for tokens taken out of user's REX fund by transfering * core tokens from user REX fund and converts them to REX stake. By buying REX, user is * lending tokens in order to be rented as CPU or NET resourses. * Storage change is billed to 'from' account. @@ -769,9 +662,7 @@ namespace eosiosystem { void buyrex( const name& from, const asset& amount ); /** - * Unstaketorex action. - * - * @details Use staked core tokens to buy REX. + * Unstaketorex action. Use staked core tokens to buy REX. * Storage change is billed to 'owner' account. * * @param owner - owner of staked tokens, @@ -790,9 +681,7 @@ namespace eosiosystem { void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); /** - * Sellrex action. - * - * @details Sells REX in exchange for core tokens by converting REX stake back into core tokens + * Sellrex action. Sells REX in exchange for core tokens by converting REX stake back into core tokens * at current exchange rate. If order cannot be processed, it gets queued until there is enough * in REX pool to fill order, and will be processed within 30 days at most. If successful, user * votes are updated, that is, proceeds are deducted from user's voting power. In case sell order @@ -805,9 +694,7 @@ namespace eosiosystem { void sellrex( const name& from, const asset& rex ); /** - * Cnclrexorder action. - * - * @details Cancels unfilled REX sell order by owner if one exists. + * Cnclrexorder action. Cancels unfilled REX sell order by owner if one exists. * * @param owner - owner account name. * @@ -817,9 +704,7 @@ namespace eosiosystem { void cnclrexorder( const name& owner ); /** - * Rentcpu action. - * - * @details Use payment to rent as many SYS tokens as possible as determined by market price and + * Rentcpu action. Use payment to rent as many SYS tokens as possible as determined by market price and * stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user @@ -839,9 +724,7 @@ namespace eosiosystem { void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Rentnet action. - * - * @details Use payment to rent as many SYS tokens as possible as determined by market price and + * Rentnet action. Use payment to rent as many SYS tokens as possible as determined by market price and * stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user @@ -861,9 +744,7 @@ namespace eosiosystem { void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Fundcpuloan action. - * - * @details Transfers tokens from REX fund to the fund of a specific CPU loan in order to + * Fundcpuloan action. Transfers tokens from REX fund to the fund of a specific CPU loan in order to * be used for loan renewal at expiry. * * @param from - loan creator account, @@ -874,9 +755,7 @@ namespace eosiosystem { void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); /** - * Fundnetloan action. - * - * @details Transfers tokens from REX fund to the fund of a specific NET loan in order to + * Fundnetloan action. Transfers tokens from REX fund to the fund of a specific NET loan in order to * be used for loan renewal at expiry. * * @param from - loan creator account, @@ -887,9 +766,7 @@ namespace eosiosystem { void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); /** - * Defcpuloan action. - * - * @details Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. + * Defcpuloan action. Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. * * @param from - loan creator account, * @param loan_num - loan id, @@ -899,9 +776,7 @@ namespace eosiosystem { void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); /** - * Defnetloan action. - * - * @details Withdraws tokens from the fund of a specific NET loan and adds them to REX fund. + * Defnetloan action. Withdraws tokens from the fund of a specific NET loan and adds them to REX fund. * * @param from - loan creator account, * @param loan_num - loan id, @@ -911,9 +786,7 @@ namespace eosiosystem { void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); /** - * Updaterex action. - * - * @details Updates REX owner vote weight to current value of held REX tokens. + * Updaterex action. Updates REX owner vote weight to current value of held REX tokens. * * @param owner - REX owner account. */ @@ -921,9 +794,7 @@ namespace eosiosystem { void updaterex( const name& owner ); /** - * Rexexec action. - * - * @details Processes max CPU loans, max NET loans, and max queued sellrex orders. + * Rexexec action. Processes max CPU loans, max NET loans, and max queued sellrex orders. * Action does not execute anything related to a specific user. * * @param user - any account can execute this action, @@ -933,9 +804,7 @@ namespace eosiosystem { void rexexec( const name& user, uint16_t max ); /** - * Consolidate action. - * - * @details Consolidates REX maturity buckets into one bucket that can be sold after 4 days + * Consolidate action. Consolidates REX maturity buckets into one bucket that can be sold after 4 days * starting from the end of the day. * * @param owner - REX owner account name. @@ -944,9 +813,7 @@ namespace eosiosystem { void consolidate( const name& owner ); /** - * Mvtosavings action. - * - * @details Moves a specified amount of REX into savings bucket. REX savings bucket + * Mvtosavings action. Moves a specified amount of REX into savings bucket. REX savings bucket * never matures. In order for it to be sold, it has to be moved explicitly * out of that bucket. Then the moved amount will have the regular maturity * period of 4 days starting from the end of the day. @@ -958,9 +825,7 @@ namespace eosiosystem { void mvtosavings( const name& owner, const asset& rex ); /** - * Mvfrsavings action. - * - * @details Moves a specified amount of REX out of savings bucket. The moved amount + * Mvfrsavings action. Moves a specified amount of REX out of savings bucket. The moved amount * will have the regular REX maturity period of 4 days. * * @param owner - REX owner account name. @@ -970,9 +835,7 @@ namespace eosiosystem { void mvfrsavings( const name& owner, const asset& rex ); /** - * Closerex action. - * - * @details Deletes owner records from REX tables and frees used RAM. Owner must not have + * Closerex action. Deletes owner records from REX tables and frees used RAM. Owner must not have * an outstanding REX balance. * * @param owner - user account name. @@ -986,9 +849,7 @@ namespace eosiosystem { void closerex( const name& owner ); /** - * Undelegate bandwitdh action. - * - * @details Decreases the total tokens delegated by `from` to `receiver` and/or + * Undelegate bandwitdh action. Decreases the total tokens delegated by `from` to `receiver` and/or * frees the memory associated with the delegation if there is nothing * left to delegate. * This will cause an immediate reduction in net/cpu bandwidth of the @@ -1019,9 +880,7 @@ namespace eosiosystem { const asset& unstake_net_quantity, const asset& unstake_cpu_quantity ); /** - * Buy ram action. - * - * @details Increases receiver's ram quota based upon current price and quantity of + * Buy ram action. Increases receiver's ram quota based upon current price and quantity of * tokens provided. An inline transfer from receiver to system contract of * tokens will be executed. * @@ -1033,9 +892,7 @@ namespace eosiosystem { void buyram( const name& payer, const name& receiver, const asset& quant ); /** - * Buy a specific amount of ram bytes action. - * - * @details Increases receiver's ram in quantity of bytes provided. + * Buy a specific amount of ram bytes action. Increases receiver's ram in quantity of bytes provided. * An inline transfer from receiver to system contract of tokens will be executed. * * @param payer - the ram buyer, @@ -1046,9 +903,7 @@ namespace eosiosystem { void buyrambytes( const name& payer, const name& receiver, uint32_t bytes ); /** - * Sell ram action. - * - * @details Reduces quota by bytes and then performs an inline transfer of tokens + * Sell ram action. Reduces quota by bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. * * @param account - the ram seller account, @@ -1058,9 +913,7 @@ namespace eosiosystem { void sellram( const name& account, int64_t bytes ); /** - * Refund action. - * - * @details This action is called after the delegation-period to claim all pending + * Refund action. This action is called after the delegation-period to claim all pending * unstaked tokens belonging to owner. * * @param owner - the owner of the tokens claimed. @@ -1071,9 +924,7 @@ namespace eosiosystem { // functions defined in voting.cpp /** - * Register producer action. - * - * @details Register producer action, indicates that a particular account wishes to become a producer, + * Register producer action. Register producer action, indicates that a particular account wishes to become a producer, * this action will create a `producer_config` and a `producer_info` object for `producer` scope * in producers tables. * @@ -1090,27 +941,21 @@ namespace eosiosystem { void regproducer( const name& producer, const public_key& producer_key, const std::string& url, uint16_t location ); /** - * Unregister producer action. - * - * @details Deactivate the block producer with account name `producer`. + * Unregister producer action. Deactivate the block producer with account name `producer`. * @param producer - the block producer account to unregister. */ [[eosio::action]] void unregprod( const name& producer ); /** - * Set ram action. - * - * @details Set the ram supply. + * Set ram action sets the ram supply * @param max_ram_size - the amount of ram supply to set. */ [[eosio::action]] void setram( uint64_t max_ram_size ); /** - * Set ram rate action. - - * @details Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to + * Set ram rate action. Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to * a maximum rate of 3 TB per year. If update_ram_supply hasn't been called for the most recent block, * then new ram will be allocated at the old rate up to the present block before switching the rate. * @@ -1120,9 +965,7 @@ namespace eosiosystem { void setramrate( uint16_t bytes_per_block ); /** - * Vote producer action. - * - * @details Votes for a set of producers. This action updates the list of `producers` voted for, + * Vote producer action. Votes for a set of producers. This action updates the list of `producers` voted for, * for `voter` account. If voting for a `proxy`, the producer votes will not change until the * proxy updates their own vote. Voter can vote for a proxy __or__ a list of at most 30 producers. * Storage change is billed to `voter`. @@ -1148,9 +991,7 @@ namespace eosiosystem { void voteproducer( const name& voter, const name& proxy, const std::vector& producers ); /** - * Register proxy action. - * - * @details Set `proxy` account as proxy. + * Register proxy action. Set `proxy` account as proxy. * An account marked as a proxy can vote with the weight of other accounts which * have selected it as a proxy. Other accounts must refresh their voteproducer to * update the proxy's weight. @@ -1166,29 +1007,22 @@ namespace eosiosystem { void regproxy( const name& proxy, bool isproxy ); /** - * Set the blockchain parameters - * - * @details Set the blockchain parameters. By tunning these parameters a degree of + * Set the blockchain parameters Set the blockchain parameters. By tunning these parameters a degree of * customization can be achieved. * @param params - New blockchain parameters to set. */ [[eosio::action]] void setparams( const eosio::blockchain_parameters& params ); - // functions defined in producer_pay.cpp /** - * Claim rewards action. - * - * @details Claim block producing and vote rewards. + * Claim rewards action. Claim block producing and vote rewards. * @param owner - producer account claiming per-block and per-vote rewards. */ [[eosio::action]] void claimrewards( const name& owner ); /** - * Set privilege status for an account. - * - * @details Allows to set privilege status for an account (turn it on/off). + * Set privilege status for an account. Allows to set privilege status for an account (turn it on/off). * @param account - the account to set the privileged status for. * @param is_priv - 0 for false, > 0 for true. */ @@ -1196,18 +1030,14 @@ namespace eosiosystem { void setpriv( const name& account, uint8_t is_priv ); /** - * Remove producer action. - * - * @details Deactivates a producer by name, if not found asserts. + * Remove producer action. Deactivates a producer by name, if not found asserts. * @param producer - the producer account to deactivate. */ [[eosio::action]] void rmvproducer( const name& producer ); /** - * Update revision action. - * - * @details Updates the current revision. + * Update revision action. Updates the current revision. * @param revision - it has to be incremented by 1 compared with current revision. * * @pre Current revision can not be higher than 254, and has to be smaller @@ -1217,9 +1047,7 @@ namespace eosiosystem { void updtrevision( uint8_t revision ); /** - * Bid name action. - * - * @details Allows an account `bidder` to place a bid for a name `newname`. + * Bid name action. Allows an account `bidder` to place a bid for a name `newname`. * @param bidder - the account placing the bid, * @param newname - the name the bid is placed for, * @param bid - the amount of system tokens payed for the bid. @@ -1238,9 +1066,7 @@ namespace eosiosystem { void bidname( const name& bidder, const name& newname, const asset& bid ); /** - * Bid refund action. - * - * @details Allows the account `bidder` to get back the amount it bid so far on a `newname` name. + * Bid refund action. Allows the account `bidder` to get back the amount it bid so far on a `newname` name. * * @param bidder - the account that gets refunded, * @param newname - the name for which the bid was placed and now it gets refunded for. @@ -1249,23 +1075,9 @@ namespace eosiosystem { void bidrefund( const name& bidder, const name& newname ); /** - * Set inflation action. - * - * @details Change the annual inflation rate of the core token supply and specify how + * Change the annual inflation rate of the core token supply and specify how * the new issued tokens will be distributed based on the following structure. - * - * +----+ +----------------+ - * +rate| +--------->|per vote reward | - * +--+-+ | +----------------+ - * | +-----+------+ - * | +----->| bp rewards | - * v | +-----+------+ - * +-+--+---+-+ | +----------------+ - * |new tokens| +--------->|per block reward| - * +----+-----+ +----------------+ - * | +------------+ - * +----->| savings | - * +------------+ + * * @param annual_rate - Annual inflation rate of the core token supply. * (eg. For 5% Annual inflation => annual_rate=500 @@ -1427,5 +1239,4 @@ namespace eosiosystem { registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; }; - /** @}*/ // end of @defgroup eosiosystem eosio.system -} /// eosiosystem +} diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 999ea7d7..64a23822 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -59,5 +59,4 @@ namespace eosiosystem { }; typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; - /** @}*/ // enf of @addtogroup eosiosystem -} /// namespace eosiosystem +} diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index bb08ca40..08d14609 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -14,23 +14,16 @@ namespace eosio { using std::string; /** - * @defgroup eosiotoken eosio.token - * @ingroup eosiocontracts - * - * eosio.token contract - * - * @details eosio.token contract defines the structures and actions that allow users to create, issue, and manage + * eosio.token contract defines the structures and actions that allow users to create, issue, and manage * tokens on eosio based blockchains. - * @{ */ class [[eosio::contract("eosio.token")]] token : public contract { public: using contract::contract; /** - * Create action. + * Allows `issuer` account to create a token in supply of `maximum_supply`. If validation is successful a new entry in statstable for token symbol scope gets created. * - * @details Allows `issuer` account to create a token in supply of `maximum_supply`. * @param issuer - the account that creates the token, * @param maximum_supply - the maximum supply set for the token created. * @@ -38,16 +31,12 @@ namespace eosio { * @pre Token symbol must not be already created, * @pre maximum_supply has to be smaller than the maximum supply allowed by the system: 1^62 - 1. * @pre Maximum supply must be positive; - * - * If validation is successful a new entry in statstable for token symbol scope gets created. */ [[eosio::action]] void create( const name& issuer, const asset& maximum_supply); /** - * Issue action. - * - * @details This action issues to `to` account a `quantity` of tokens. + * This action issues to `to` account a `quantity` of tokens. * * @param to - the account to issue tokens to, it must be the same as the issuer, * @param quntity - the amount of tokens to be issued, @@ -57,9 +46,7 @@ namespace eosio { void issue( const name& to, const asset& quantity, const string& memo ); /** - * Retire action. - * - * @details The opposite for create action, if all validations succeed, + * The opposite for create action, if all validations succeed, * it debits the statstable.supply amount. * * @param quantity - the quantity of tokens to retire, @@ -69,9 +56,7 @@ namespace eosio { void retire( const asset& quantity, const string& memo ); /** - * Transfer action. - * - * @details Allows `from` account to transfer to `to` account the `quantity` tokens. + * Allows `from` account to transfer to `to` account the `quantity` tokens. * One account is debited and the other is credited with quantity tokens. * * @param from - the account to transfer from, @@ -85,9 +70,7 @@ namespace eosio { const asset& quantity, const string& memo ); /** - * Open action. - * - * @details Allows `ram_payer` to create an account `owner` with zero balance for + * Allows `ram_payer` to create an account `owner` with zero balance for * token `symbol` at the expense of `ram_payer`. * * @param owner - the account to be created, @@ -101,9 +84,7 @@ namespace eosio { void open( const name& owner, const symbol& symbol, const name& ram_payer ); /** - * Close action. - * - * @details This action is the opposite for open, it closes the account `owner` + * This action is the opposite for open, it closes the account `owner` * for token `symbol`. * * @param owner - the owner account to execute the close action for, @@ -116,9 +97,7 @@ namespace eosio { void close( const name& owner, const symbol& symbol ); /** - * Get supply method. - * - * @details Gets the supply for token `sym_code`, created by `token_contract_account` account. + * Gets the supply for token `sym_code`, created by `token_contract_account` account. * * @param token_contract_account - the account to get the supply for, * @param sym_code - the symbol to get the supply for. @@ -131,9 +110,7 @@ namespace eosio { } /** - * Get balance method. - * - * @details Get the balance for a token `sym_code` created by `token_contract_account` account, + * Get the balance for a token `sym_code` created by `token_contract_account` account, * for account `owner`. * * @param token_contract_account - the token creator account, @@ -174,5 +151,5 @@ namespace eosio { void sub_balance( const name& owner, const asset& value ); void add_balance( const name& owner, const asset& value, const name& ram_payer ); }; - /** @}*/ // end of @defgroup eosiotoken eosio.token -} /// namespace eosio + +} diff --git a/docs.json b/docs.json index f6a7a50c..2d4e43af 100644 --- a/docs.json +++ b/docs.json @@ -8,15 +8,33 @@ } }, { - "name": "doxygen_to_xml", + "name": "mdjavadoc", "options": { - "output": "00_eosio.token", - "INPUT": "eosio.token" + "source_dirs": [ + "contracts/eosio.token/include/eosio.token/", + "contracts/eosio.wrap/include/eosio.wrap/", + "contracts/eosio.bios/include/eosio.bios/", + "contracts/eosio.system/include/eosio.system/", + "contracts/eosio.msig/include/eosio.msig/" + ], + "output_dir": "action-reference" + } + } + ], + "skip_default_filters": true, + "filters": [ + { + "name": "sanitize", + "options": { + "exclude": ["action-reference"] } }, { - "name": "doxybook", - "options": {} + "name": "capitalize", + "options": { + "mode": "all", + "exclude": ["action-reference"] + } } ] -} \ No newline at end of file +} diff --git a/docs_v2/01_introduction.md b/docs/01_introduction.md similarity index 100% rename from docs_v2/01_introduction.md rename to docs/01_introduction.md diff --git a/docs_v2/02_compile-and-deploy.md b/docs/02_compile-and-deploy.md similarity index 100% rename from docs_v2/02_compile-and-deploy.md rename to docs/02_compile-and-deploy.md diff --git a/docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md b/docs/03_guides/01_upgrading-the-eosio.system-contract.md similarity index 100% rename from docs_v2/03_guides/01_upgrading-the-eosio.system-contract.md rename to docs/03_guides/01_upgrading-the-eosio.system-contract.md diff --git a/docs_v2/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md similarity index 100% rename from docs_v2/03_guides/02_how-to-buy-ram.md rename to docs/03_guides/02_how-to-buy-ram.md diff --git a/docs_v2/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md similarity index 100% rename from docs_v2/03_guides/03_how-to-stake.md rename to docs/03_guides/03_how-to-stake.md diff --git a/docs_v2/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md similarity index 100% rename from docs_v2/03_guides/04_how-to-vote.md rename to docs/03_guides/04_how-to-vote.md diff --git a/docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md similarity index 100% rename from docs_v2/03_guides/05_how-to-create-issue-and-transfer-a-token.md rename to docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md diff --git a/docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 100% rename from docs_v2/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md rename to docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md diff --git a/docs_v2/03_guides/07_how-to-use-eosio.wrap.md b/docs/03_guides/07_how-to-use-eosio.wrap.md similarity index 100% rename from docs_v2/03_guides/07_how-to-use-eosio.wrap.md rename to docs/03_guides/07_how-to-use-eosio.wrap.md diff --git a/docs/eosio.bios/deploy.md b/docs/eosio.bios/deploy.md deleted file mode 100644 index 57a5923b..00000000 --- a/docs/eosio.bios/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps deploy eosio.bios contract - -In order to deploy the eosio.bios contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerbios` - -``` -cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios -``` \ No newline at end of file diff --git a/docs/eosio.bios/introduction.md b/docs/eosio.bios/introduction.md deleted file mode 100644 index fc31c0c7..00000000 --- a/docs/eosio.bios/introduction.md +++ /dev/null @@ -1,30 +0,0 @@ -## Introducing eosio.bios contract - -The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. - -The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. - -|Action name|Action description| -|---|---| -|setpriv|Set privilege status for an account.| -|setalimits|Set the resource limits of an account| -|setglimits|Not implemented yet.| -|setprods|Set a new list of active producers, that is, a new producers' schedule.| -|setparams|Set the blockchain parameters.| -|reqauth|Check if an account has authorization to access the current action.| -|setabi|Set the abi for a contract identified by an account name.| - -The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. - -Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: - -|Action name|Description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setcode|Allows for update of the contract code of an account.| diff --git a/docs/eosio.msig/deploy.md b/docs/eosio.msig/deploy.md deleted file mode 100644 index d5f027d8..00000000 --- a/docs/eosio.msig/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.msig contract - -In order to deploy the eosio.msig contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testermsig` - -``` -cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig -``` \ No newline at end of file diff --git a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md deleted file mode 100644 index f68dff87..00000000 --- a/docs/eosio.msig/guides/how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ /dev/null @@ -1,171 +0,0 @@ -## eosio.msig examples - -### Cleos usage example for issuing tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' is the issuer of SYS token. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "issue", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "to": "tester", - "quantity": "1000.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user initiates execution: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - - -### Cleos usage example for transferring tokens. - -#### Prerequisites: - - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - - account 'treasury' has at least 1.1000 SYS token balance. - - account 'tester' exists. - - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. - -#### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester - -executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles -# eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` - -#### Another user reviews the transaction: -```` -$ cleos multisig review tester test -{ - "proposal_name": "test", - "requested_approvals": [{ - "actor": "treasury", - "permission": "active" - } - ], - "provided_approvals": [], - "packed_transaction": "00aee75a0000000000000000000000000100a6823403ea30550000000000a5317601000000fe6a6cd4cd00000000a8ed323219000000005c95b1ca809698000000000004454f530000000000", - "transaction": { - "expiration": "2018-05-01T00:00:00", - "region": 0, - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_kcpu_usage": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.token", - "name": "transfer", - "authorization": [{ - "actor": "treasury", - "permission": "active" - } - ], - "data": { - "from": "treasury", - "to": "tester", - "quantity": "1.0000 SYS", - "memo": "" - }, - "hex_data": "000000005c95b1ca809698000000000004454f530000000000" - } - ] - } -} -```` - -#### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - -executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles -# eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` - -#### First user check account balance before executing the proposed transaction -```` -$ cleos get account tester -... -SYS balances: - liquid: 1.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` - -#### First user initiates execution of proposed transaction: -```` -$ cleos multisig exec tester test -p tester - -executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles -# eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` - -#### First user can check account balance, it should be increased by 1.0000 SYS -```` -$ cleos get account tester -... -SYS balances: - liquid: 2.0487 SYS - staked: 2.0000 SYS - unstaking: 0.0000 SYS - total: 4.0487 SYS -```` diff --git a/docs/eosio.msig/introduction.md b/docs/eosio.msig/introduction.md deleted file mode 100644 index 8fea8056..00000000 --- a/docs/eosio.msig/introduction.md +++ /dev/null @@ -1,19 +0,0 @@ -## Introducing eosio.msig contract - -The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. - -The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: -- first you create a transaction json file, -- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, -- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, -- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. - -These are the actions implemented and publicly exposed by the `eosio.msig` contract: -|Action name|Action description| -|---|---| -|propose|Creates a proposal containing one transaction.| -|approve|Approves an existing proposal.| -|unapprove|Revokes an existing proposal.| -|cancel|Cancels an existing proposal.| -|exec|Allows an account to execute a proposal.| -|invalidate|Invalidate proposal.| diff --git a/docs/eosio.system/deploy.md b/docs/eosio.system/deploy.md deleted file mode 100644 index 13703abd..00000000 --- a/docs/eosio.system/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.system contract - -In order to deploy the eosio.system contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testersystem` - -``` -cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-buy-ram.md b/docs/eosio.system/guides/how-to-buy-ram.md deleted file mode 100644 index 19c83a37..00000000 --- a/docs/eosio.system/guides/how-to-buy-ram.md +++ /dev/null @@ -1,20 +0,0 @@ -## How buy RAM - -### What RAM is - -RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). -The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM for the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). - -### How to buy RAM - -To check the amount of RAM for an account eostutorial1: -``` -cleos get account eostutorial1 -``` - -Below command buys RAM in value of 0.1 SYS tokens for account eostutorial1: -``` -cleos --url=https://jungle2.cryptolions.io:443 system buyram eostutorial1 eostutorial1 "0.1 SYS" -p eostutorial1@active -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/how-to-stake.md b/docs/eosio.system/guides/how-to-stake.md deleted file mode 100644 index fb0a5e31..00000000 --- a/docs/eosio.system/guides/how-to-stake.md +++ /dev/null @@ -1,47 +0,0 @@ -## How to stake - -### What staking is - -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, inspite the process of inflation because BPs are rewarded new minted coins for their services every 24 hours. - -### Staking tokens for CPU - -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time a contract has at its disposal when executing its actions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for CPU bandwidth in addition to what the account has already, and adds zero tokens to NET bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "0.0000 SYS" "1.0000 SYS" -p eostutorial2@active -``` - -### Staking tokens for Bandwidth - -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. - -To check the amount of CPU staked for an account currently: -``` -cleos get account eostutorial1 -``` - -The commands below stake 1.0000 system tokens, in this case SYS, for NET bandwidth in addition to what the account has already, and adds zero tokens to CPU bandwidth. - -To stake to itself: -``` -cleos system delegatebw eostutorial1 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial1@active -``` - -To stake for another account, below eostutorial2 stakes for eostutorial1 account: -``` -cleos system delegatebw eostutorial2 eostutorial1 "1.0000 SYS" "0.0000 SYS" -p eostutorial2@active -``` diff --git a/docs/eosio.system/guides/how-to-vote.md b/docs/eosio.system/guides/how-to-vote.md deleted file mode 100644 index 7ebb62f7..00000000 --- a/docs/eosio.system/guides/how-to-vote.md +++ /dev/null @@ -1,12 +0,0 @@ -## How to vote - -### What voting is - -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these blocks are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. - -### How to vote - -To __vote__ block producers execute below command, which allows one account to vote for as up to 30 block producer identified by their account name; in this particular example account eostutorial1 votes for 3 producers accounts: accountprod1, accountprod2 and accountprod3. -``` -cleos system voteproducer prods eostutorial1 accountprod1 accountprod2 accountprod3 -``` \ No newline at end of file diff --git a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md b/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md deleted file mode 100644 index 2bd712fb..00000000 --- a/docs/eosio.system/guides/upgrading-the-eosio.system-contract.md +++ /dev/null @@ -1,209 +0,0 @@ -## Upgrading the system contract - -### Indirect method using eosio.msig contract - -Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. - -So, at the moment it is difficult to propose an atomic transaction with multiple actions (for example `eosio::setcode` followed by `eosio::setabi`). - -The advantage of the eosio.msig method is that it makes coordination much easier and does not place strict time limits (less than 9 hours) on signature collection. - -The disadvantage of the eosio.msig method is that it requires the proposer to have sufficient RAM to propose the transaction and currently cleos does not provide convenient tools to use it with custom transactions like the one that would be necessary to atomically upgrade the system contract. - -For now, it is recommended to use the direct method to upgrade the system contract. - -### Direct method (avoids using eosio.msig contract) - -Each of the top 21 block producers should do the following: - -1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): - -``` -$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio -code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 -saving wast to original_system_contract.wast -saving abi to original_system_contract.abi -``` - -2. Generate the unsigned transaction which upgrades the system contract: - -``` -$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json -``` - -The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): - -``` -{ - "expiration": "2018-06-15T22:17:10", - "ref_block_num": 4552, - "ref_block_prefix": 511016679, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], -``` - -and the last few lines should be: - -``` - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -One of the top block producers should be chosen to lead the upgrade process. This lead producer should take their generated `upgrade_system_contract_trx.json`, rename it to `upgrade_system_contract_official_trx.json`, and do the following: - -3. Modify the `expiration` timestamp in `upgrade_system_contract_official_trx.json` to a time that is sufficiently far in the future to give enough time to collect all the necessary signatures, but not more than 9 hours from the time the transaction was generated. Also, keep in mind that the transaction will not be accepted into the blockchain if the expiration is more than 1 hour from the present time. - -4. Pass the `upgrade_system_contract_official_trx.json` file to all the other top 21 block producers. - -Then each of the top 21 block producers should do the following: - -5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: - -``` -$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json -2,4c2,4 -< "expiration": "2018-06-15T22:17:10", -< "ref_block_num": 4552, -< "ref_block_prefix": 511016679, ---- -> "expiration": "2018-06-15T21:20:39", -> "ref_block_num": 4972, -> "ref_block_prefix": 195390844, -``` - -6. If the comparison is good, each block producer should proceed with signing the official upgrade transaction with the keys necessary to satisfy their active permission. If the block producer only has a single key (i.e the "active key") in the active permission of their block producing account, then they only need to generate one signature using that active key. This signing process can be done offline for extra security. - -First, the block producer should collect all the necessary information. Let us assume that the block producers active key pair is `(EOS5kBmh5kfo6c6pwB8j77vrznoAaygzoYvBsgLyMMmQ9B6j83i9c, 5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3)`. The block producer needs their active private key (`5JjpkhxAmEfynDgSn7gmEKEVcBqJTtu6HiQFf4AVgGv5A89LfG3` in this example), the `upgrade_system_contract_official_trx.json`, and the `chain_id` (`d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e` in this example) which can be retrieved through `cleos get info`. - -Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): - -``` -$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 -private key: "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" - ], - "context_free_data": [] -} -``` - -Make sure to use the `chain_id` of the actual main-net blockchain that the transaction will be submitted to and not the example `chain_id` provided above. - -The output should include the signature (in this case `"SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5"`) which the producer should then send to the lead producer. - -When the lead producer collects 15 producer signatures, the lead producer should do the following: - -7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: - -``` -$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 - "transaction_extensions": [], - "signatures": [ - "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", - "SIG_K1_Kj7XJxnPQSxEXZhMA8uK3Q1zAxp7AExzsRd7Xaa7ywcE4iUrhbVA3B6GWre5Ctgikb4q4CeU6Bvv5qmh9uJjqKEbbjd3sX", - "SIG_K1_KbE7qyz3A9LoQPYWzo4e6kg5ZVojQVAkDKuufUN2EwVUqtFhtjmGoC6QPQqLi8J7ftiysBp52wJBPjtNQUfZiGpGMsnZ1f", - "SIG_K1_KdQsE7ahHA9swE9SDGg4oF6XahpgHmZfEgQAy9KPBLd9HuwrF6c8m6jz43zizK2oo32Ejg1DYuMfoEvJgVfXo81jsqTHvA", - "SIG_K1_K6228Hi2z1WabgVdf5bk2UdKyyDSVFwkMaagTn9oLVDV8rCX7aQcjY94c39ah2CkLTsTEqzTPAYknJ8m2m9B7npPkHaFzc", - "SIG_K1_Jzdx75hBCA2WSaXgrupmrNbcQocUCsP8r1BKkPXMreiAKPZDwX9J3G8fS1HhyqWjc7FbukwZf8sVRdS3wKbJVpytqXe7Nn", - "SIG_K1_KW7Qu2SdPD3zuQKh2ziFLzn9QbKqeMpeiemULky5Bbg1Mst6ijbCX3k2AVFGNFLkNLA36PM1WAT5oipzu1B1K7ymRxTx1Z", - "SIG_K1_KXJf1KZNpz73YFKKE7u6jFgsQ8XcX3yA7rDX6ZmG1Qfnc9FLLmT1WViv4bwcPbxaEYfR6SNWfk5cCR9eao2si1soqkXq92", - "SIG_K1_JynjkHFT5UFGDpEcqdriXTzCGCwS36Xztq4UAWQHLQgRUZT2YFoLhUcc87kvUteqCUGVxsmSbfgWv1KLy24voKN4Qs5zTe", - "SIG_K1_JxhfCaGBhuNShpDHn7j1CryG3iSebvfi7FUnJsfkXNTiwLyq2NDBkeakwjCMWFbzr6qqWuMDLjfXbzdtU17f1wCXMjKSgk", - "SIG_K1_KcMSz89QG1ZRFNrXc69R63d5KXbJA8CBjNPYv1VEA3TRfjqVYuhyaHpGXQN4RSKDq4ygr3UTRYBQQVutkJnR6zZ4Ssgd7R", - "SIG_K1_JuxT6bhUAbDs6Q2ppuKyKauduvbaJLxvh4gBH4e4A9yRhvUBT7w3DcvMyhdaor27Kbu29jnqhTbvXcb57QqKWQDpboLv7e", - "SIG_K1_K8BuFYpCiC5FhpVK8ZAzc3VUg7vz6WwLoWBrGN6nnuqUjngGqvHp3UxDVzcwhqccHdv8kdPXvF6G1NszwF1dd3wjCrHBYw", - "SIG_K1_KfH5ZirPwDk1RQKvJv2AGPfsJyPXvXLegZ7LvcPmRtjtMiErs1STXLNT8kiBfhZr4xkWRA5NR1kMF3d49DFMJiB2iWMXJc", - "SIG_K1_KjJB8jtcqpVe3r5jouFiAa9wJeYqoLMh5xrUV6kBF6UWfbYjimMWBJWz2ZPomGDsk7JtdUESVrYj1AhYbdp3X48KLm5Cev" - ], - "context_free_data": [] -} -``` - -8. Push the signed transaction to the blockchain: - -``` -$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json -{ - "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "processed": { - "id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", - "receipt": { - "status": "executed", - "cpu_usage_us": 4909, - "net_usage_words": 15124 - }, - "elapsed": 4909, - "net_usage": 120992, - "scheduled": false, - "action_traces": [{ -... -``` - -If you get an error message like the following: - -``` -Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations -Ensure that you have the related private keys inside your wallet and your wallet is unlocked. -``` - -That means that at least one of the signatures provided were bad. This may be because a producer signed the wrong transaction, used the wrong private key, or used the wrong chain ID. - -If you get an error message like the following: - -``` -Error 3090002: irrelevant signature included -Please remove the unnecessary signature from your transaction! -``` - -That means unnecessary signatures were included. If there are 21 active producers, only signatures from exactly 15 of those 21 active producers are needed. - -If you get an error message like the following: - -``` -Error 3040006: Transaction Expiration Too Far -Please decrease the expiration time of your transaction! -``` - -That means that the expiration time is more than 1 hour in the future and you need to wait some time before being allowed to push the transaction. - -If you get an error message like the following: - -``` -Error 3040005: Expired Transaction -Please increase the expiration time of your transaction! -``` - -That means the expiration time of the signed transaction has passed and this entire process has to restart from step 1. - -9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: - -``` -$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio -code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 -saving wast to new_system_contract.wast -saving abi to new_system_contract.abi -$ diff original_system_contract.abi new_system_contract.abi -584,592d583 -< },{ -< "name": "deferred_trx_id", -< "type": "uint32" -< },{ -< "name": "last_unstake_time", -< "type": "time_point_sec" -< },{ -< "name": "unstaking", -< "type": "asset" -``` diff --git a/docs/eosio.system/introduction.md b/docs/eosio.system/introduction.md deleted file mode 100644 index 1ca3ca04..00000000 --- a/docs/eosio.system/introduction.md +++ /dev/null @@ -1,65 +0,0 @@ -## Introducing eosio.system contract - -The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: -- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. -- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. -- Users can buy and sell RAM at a market-determined price. -- Users can bid on premium names. -- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. - -The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - -|Action name|Action description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setabi|Allows for updates of the contract ABI of an account.| -|setcode|Allows for updates of the contract code of an account.| -|init|Initializes the system contract for a version and a symbol.| -|setram|Set the ram supply.| -|setramrate|Set the ram increase rate.| -|setparams|Set the blockchain parameters.| -|setpriv|Set privilege status for an account (turn it on/off).| -|setalimits|Set the resource limits of an account.| -|setacctram|Set the RAM limits of an account.| -|setacctnet|Set the NET limits of an account.| -|setacctcpu|Set the CPU limits of an account.| -|rmvproducer|Deactivates a producer by name, if not found asserts.| -|updtrevision|Updates the current revision.| -|bidname|Allows an account to place a bid for a name.| -|bidrefund|Allows an account to get back the amount it bid so far on a name.| -|deposit|Deposits core tokens to user REX fund.| -|withdraw|Withdraws core tokens from user REX fund.| -|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| -|unstaketorex|Use staked core tokens to buy REX.| -|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| -|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| -|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| -|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| -|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| -|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| -|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| -|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| -|updaterex|Updates REX owner vote weight to current value of held REX tokens.| -|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| -|mvtosavings|Moves a specified amount of REX to savings bucket.| -|mvfrsavings|Moves a specified amount of REX from savings bucket.| -|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| -|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| -|buyrambytes|Increases receiver's ram in quantity of bytes provided.| -|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| -|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| -|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| -|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| -|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| -|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| -|unregprod|Deactivate the block producer with specified account.| -|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| -|regproxy|Set specified account as proxy.| -|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| -|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| diff --git a/docs/eosio.token/deploy.md b/docs/eosio.token/deploy.md deleted file mode 100644 index 5f341b63..00000000 --- a/docs/eosio.token/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.token contract - -In order to deploy the eosio.token contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testertoken` - -``` -cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken -``` \ No newline at end of file diff --git a/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md deleted file mode 100644 index 59dc0451..00000000 --- a/docs/eosio.token/guides/how-to-create,-issue-and-transfer-a-token.md +++ /dev/null @@ -1,152 +0,0 @@ -TO DO: use this: -https://dash.readme.io/project/eosio-home/v2.3.8/docs/token-contract -(don't use below link cause it is deprecated) -https://dash.readme.io/project/eosio-cpp/v1.6/docs/quick-start-token - -## How to create, issue and transfer a token - - -## Step 1: Obtain Contract Source - -Navigate to your contracts directory. - -```text -cd CONTRACTS_DIR -``` -Pull the source - -```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch -``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - - -```text -cd eosio.contracts/eosio.token -``` - -## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. -[[info]] -| -You may have to unlock your wallet first! - - -```shell -cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -``` - -## Step 3: Compile the Contract - - -```shell -eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen -``` - -## Step 4: Deploy the Token Contract - - -```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active -``` - -Result -```shell -Reading WASM from ... -Publishing contract... -executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us -# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... -# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... -warning: transaction executed locally, but may not be confirmed by the network yet ] -``` - -## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: - -```shell -cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -An alternate approach uses named arguments: - -```shell -cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. - -## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. - -```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active -``` - -Result -```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` - -## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. - -```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active -``` - -Result -```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -``` -Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) - -```shell -cleos get currency balance eosio.token bob SYS -``` - - -```text -25.00 SYS -``` -Check "alice's" balance, notice that tokens were deducted from the account - -```shell -cleos get currency balance eosio.token alice SYS -``` - - -```text -75.00 SYS -``` -Excellent! Everything adds up. diff --git a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md b/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md deleted file mode 100644 index 3592f059..00000000 --- a/docs/eosio.token/guides/how-to-create-issue-and-transfer-a-token.md +++ /dev/null @@ -1,146 +0,0 @@ -## How to create, issue and transfer a token - -## Step 1: Obtain Contract Source - -Navigate to your contracts directory. - -```text -cd CONTRACTS_DIR -``` -Pull the source - -```text -git clone https://github.com/EOSIO/eosio.contracts --branch v1.5.2 --single-branch -``` -This repository contains several contracts, but it's the `eosio.token` contract that is important now. Navigate to the directory now. - - -```text -cd eosio.contracts/eosio.token -``` - -## Step 2: Create Account for Contract -Before we can deploy the token contract we must create an account to deploy it to, we'll use the **eosio development key** for this account. -[[info]] -| -You may have to unlock your wallet first! - - -```shell -cleos create account eosio eosio.token EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -``` - -## Step 3: Compile the Contract - - -```shell -eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen -``` - -## Step 4: Deploy the Token Contract - - -```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active -``` - -Result -```shell -Reading WASM from ... -Publishing contract... -executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us -# eosio <= eosio::setcode {"account":"eosio.token","vmtype":0,"vmversion":0,"code":"0061736d0100000001aa011c60037f7e7f0060047f... -# eosio <= eosio::setabi {"account":"eosio.token","abi":"0e656f73696f3a3a6162692f312e30000605636c6f73650002056f776e6572046e61... -warning: transaction executed locally, but may not be confirmed by the network yet ] -``` - -## Step 5: Create the Token -To create a new token call the `create(...)` action with the proper arguments. This action accepts 1 argument, it's a `symbol_name` type composed of two pieces of data, a maximum supply float and a `symbol_name` in capitalized alpha characters only, for example "1.0000 SYS". The issuer will be the one with authority to call issue and or perform other actions such as freezing, recalling, and whitelisting of owners. - -Below is the concise way to call this method, using positional arguments: - -```shell -cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -An alternate approach uses named arguments: - -```shell -cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"1000000000.0000 SYS"}' -p eosio.token@active -``` - -Result -```shell -executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles -# eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} -``` -This command created a new token `SYS` with a precision of 4 decimals and a maximum supply of 1000000000.0000 SYS. To create this token requires the permission of the `eosio.token` contract. For this reason, `-p eosio.token@active` was passed to authorize the request. - -## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. - -```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active -``` - -Result -```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -``` -This time the output contains several different actions: one issue and three transfers. While the only action signed was `issue`, the `issue` action performed an "inline transfer" and the "inline transfer" notified the sender and receiver accounts. The output indicates all of the action handlers that were called, the order they were called in, and whether or not any output was generated by the action. - -Technically, the `eosio.token` contract could have skipped the `inline transfer` and opted to just modify the balances directly. However, in this case the `eosio.token` contract is following our token convention that requires that all account balances be derivable by the sum of the transfer actions that reference them. It also requires that the sender and receiver of funds be notified so they can automate handling deposits and withdrawals. - -To inspect the transaction, try using the `-d -j` options, they indicate "don't broadcast" and "return transaction as json," which you may find useful during development. - -```shell -cleos push action eosio.token issue '["alice", "100.0000 SYS", "memo"]' -p eosio@active -d -j -``` - -## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. - -```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active -``` - -Result -```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -``` -Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) - -```shell -cleos get currency balance eosio.token bob SYS -``` - - -```text -25.00 SYS -``` -Check "alice's" balance, notice that tokens were deducted from the account - -```shell -cleos get currency balance eosio.token alice SYS -``` - - -```text -75.00 SYS -``` -Excellent! Everything adds up. diff --git a/docs/eosio.token/introduction.md b/docs/eosio.token/introduction.md deleted file mode 100644 index dcde42fd..00000000 --- a/docs/eosio.token/introduction.md +++ /dev/null @@ -1,21 +0,0 @@ -## Introducing eosio.token contract - -The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. - -These are the public actions the `eosio.token` contract is implementing: -|Action name|Action description| -|---|---| -|create|Allows an account to create a token in a given supply amount.| -|issue|This action issues to an account a specific quantity of tokens.| -|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| -|close|This action is the opposite for `open` action, it closes the specified account for specified token.| -|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| -|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| - -The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. - -The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). - -The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. - -Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. \ No newline at end of file diff --git a/docs/eosio.wrap/deploy.md b/docs/eosio.wrap/deploy.md deleted file mode 100644 index bad4e3bb..00000000 --- a/docs/eosio.wrap/deploy.md +++ /dev/null @@ -1,12 +0,0 @@ -## Steps to compile and deploy eosio.wrap contract - -In order to deploy the eosio.wrap contract you need to build it first; instructions on how to build all system eosio.contracts can be found in the introduction section [here](../introduction.md), please go through those steps first before following below instructions. - -### To deploy execute the following commands: - -To deploy a contract you will need first an account to which to deploy it to. -Let's assume your account name is `testerwrap` - -``` -cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap -``` \ No newline at end of file diff --git a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md b/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md deleted file mode 100644 index 0f3395fc..00000000 --- a/docs/eosio.wrap/guides/how-to-use-eosio.wrap.md +++ /dev/null @@ -1,874 +0,0 @@ -# eosio.wrap - -## 1. Installing the eosio.wrap contract - -The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. - -First, the account `eosio.wrap` needs to be created. Since it has the restricted `eosio.` prefix, only a privileged account can create this account. So this guide will use the `eosio` account to create the `eosio.wrap` account. On typical live blockchain configurations, the `eosio` account can only be controlled by a supermajority of the current active block producers. So, this guide will use the `eosio.msig` contract to help coordinate the approvals of the proposed transaction that creates the `eosio.wrap` account. - -The `eosio.wrap` account also needs to have sufficient RAM to host the contract and sufficient CPU and network bandwidth to deploy the contract. This means that the creator of the account (`eosio`) needs to gift sufficient RAM to the new account and delegate (preferably with transfer) sufficient bandwidth to the new account. To pull this off the `eosio` account needs to have enough of the core system token (the `SYS` token will be used within this guide) in its liquid balance. So prior to continuing with the next steps of this guide, the active block producers of the chain who are coordinating this process need to ensure that a sufficient amount of core system tokens that they are authorized to spend is placed in the liquid balance of the `eosio` account. - -This guide will be using cleos to carry out the process. - -### 1.1 Create the eosio.wrap account - -#### 1.1.1 Generate the transaction to create the eosio.wrap account - -The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -A simple way to generate a transaction to create a new account is to use the `cleos system newaccount`. However, that sub-command currently only accepts a single public key as the owner and active authority of the new account. However, the owner and active authorities of the new account should only be satisfied by the `active` permission of `eosio`. One option is to create the new account with the some newly generated key, and then later update the authorities of the new account using `cleos set account permission`. This guide will take an alternative approach which atomically creates the new account in its proper configuration. - -Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. - -First, generate a transaction to capture the necessary actions involved in creating a new account: -``` -$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json -726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} -726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} -$ cat generated_account_creation_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305501000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c660100000001000000010003c8162ea04fed738bfd5470527fd1ae7454c2e9ad1acbadec9f9e35bab2f33c6601000000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` -Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. -The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. - -Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: -``` -$ cat newaccount_payload.json -{ - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - }, - "active": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": {"actor": "eosio", "permission": "active"}, - "weight": 1 - }], - "waits": [] - } -} -``` - -Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: -``` -$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json -$ cat generated_newaccount_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: -``` -$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json -$ cat generated_setpriv_trx.json -{ - "expiration": "2018-06-29T17:11:36", - "ref_block_num": 16349, - "ref_block_prefix": 3248946195, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. - -Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: -``` -$ cat create_wrap_account_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed3232010000" - },{ - "account": "eosio", - "name": "buyrambytes", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea305500c80000" - },{ - "account": "eosio", - "name": "delegatebw", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001" - },{ - "account": "eosio", - "name": "setpriv", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": "00004d1a03ea305501" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The transaction in create_wrap_account_trx.json is now ready to be proposed. - -It will be useful to have a JSON of the active permissions of each of the active block producers for later when proposing transactions using the eosio.msig contract. - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. - -In that case, create a file producer_permissions.json with the content shown in the command below: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 1.1.2 Propose the transaction to create the eosio.wrap account - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: -``` -$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera -executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.3 Review and approve the transaction to create the eosio.wrap account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json -$ head -n 30 create_wrap_account_trx_to_review.json -{ - "proposal_name": "createwrap", - "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "newaccount", - "authorization": [{ - "actor": "eosio", - "permission": "active" - } - ], - "data": { - "creator": "eosio", - "name": "eosio.wrap", - "owner": { - "threshold": 1, - "keys": [], - "accounts": [{ - "permission": { - "actor": "eosio", - "permission": "active" - }, -``` - -The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: -``` -$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex -$ cat expected_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex -$ cat proposed_create_wrap_trx_serialized.hex -c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.1.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera createwrap blkproducera -executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the `eosio.wrap` was created: -``` -$ cleos get account eosio.wrap -privileged: true -permissions: - owner 1: 1 eosio@active, - active 1: 1 eosio@active, -memory: - quota: 49.74 KiB used: 3.33 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: - -``` - -### 1.2 Deploy the eosio.wrap contract - -#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract - -The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. - -The easy way to generate this transaction is using cleos: -``` -$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json -Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... -Using already assembled WASM... -Publishing contract... -$ cat deploy_wrap_contract_trx.json -{ - "expiration": "2018-06-29T19:55:26", - "ref_block_num": 18544, - "ref_block_prefix": 562790588, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: -``` -$ head -n 9 deploy_wrap_contract_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ -``` - -This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. - -#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract - -Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. - -The approvers are typically going to be the active block producers of the chain, so it makes sense that one of the block producers is elected as the leader to propose the actual transaction. Note that this lead block producer will need to incur the temporary RAM cost of proposing the transaction, but they will get the RAM back when the proposal has executed or has been canceled (which only the proposer can do prior to expiration). - -This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. - -The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: -``` -$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera -executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. - -The proposed transaction can be reviewed using the `cleos multisig review` command: -``` -$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json -$ cat deploy_wrap_contract_trx_to_review.json -{ - "proposal_name": "deploywrap", - "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "setcode", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "vmtype": 0, - "vmversion": 0, - "code": "0061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - }, - "hex_data": "00004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f636174656400" - },{ - "account": "eosio", - "name": "setabi", - "authorization": [{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "account": "eosio.wrap", - "abi": "0e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - }, - "hex_data": "00004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e01000000000080545704657865630000000000" - } - ], - "transaction_extensions": [] - } -} -``` - -Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. - -This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: -``` -$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex -$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex -$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 -c0593f5b00000000000000000000020000000000ea30550000 -$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 1.2.4 Execute the transaction to create the eosio.wrap account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera deploywrap blkproducera -executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} -``` - -Anyone can now verify that the `eosio.wrap` contract was deployed correctly. - -``` -$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap -code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c -saving abi to retrieved-eosio.wrap.abi -$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm -1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm -``` - -If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. - -## 2. Using the eosio.wrap contract - -### 2.1 Example: Updating owner authority of an arbitrary account - -This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. - -This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. - -The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: -``` -$ cat producer_permissions.json -[ - {"actor": "blkproducera", "permission": "active"}, - {"actor": "blkproducerb", "permission": "active"}, - {"actor": "blkproducerc", "permission": "active"}, - {"actor": "blkproducerd", "permission": "active"}, - {"actor": "blkproducere", "permission": "active"}, - {"actor": "blkproducerf", "permission": "active"}, - {"actor": "blkproducerg", "permission": "active"}, - {"actor": "blkproducerh", "permission": "active"}, - {"actor": "blkproduceri", "permission": "active"}, - {"actor": "blkproducerj", "permission": "active"}, - {"actor": "blkproducerk", "permission": "active"}, - {"actor": "blkproducerl", "permission": "active"}, - {"actor": "blkproducerm", "permission": "active"}, - {"actor": "blkproducern", "permission": "active"}, - {"actor": "blkproducero", "permission": "active"}, - {"actor": "blkproducerp", "permission": "active"}, - {"actor": "blkproducerq", "permission": "active"}, - {"actor": "blkproducerr", "permission": "active"}, - {"actor": "blkproducers", "permission": "active"}, - {"actor": "blkproducert", "permission": "active"}, - {"actor": "blkproduceru", "permission": "active"} -] -``` - -#### 2.1.1 Generate the transaction to change the owner permission of an account - -The goal of this example is for the block producers to change the owner permission of the account `alice`. - -The initial status of the `alice` account might be: -``` -permissions: - owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.365 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 us - available: 460.8 ms - limit: 460.8 ms - -producers: -``` - -Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. - -The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: -``` -$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json -``` - -Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: -``` -$ cat update_alice_owner_trx.json -{ - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. - -``` -$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json -``` - -Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. -``` -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. - -First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: -``` -$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex -$ cat update_alice_owner_trx_serialized.hex -0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 -``` - -Then generate the template for the transaction containing the `eosio.wrap::exec` action: -``` -$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json -$ cat wrap_update_alice_owner_trx.json -{ - "expiration": "2018-06-29T23:34:01", - "ref_block_num": 23708, - "ref_block_prefix": 3605208482, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [], - "data": "60ae423ad15b613c" - } - ], - "transaction_extensions": [], - "signatures": [], - "context_free_data": [] -} -``` - -Then modify the transaction in wrap_update_alice_owner_trx.json as follows: - * replace the values of the `ref_block_num` and `ref_block_prefix` fields to 0; - * replace the time of the `expiration` field to the desired expiration time as described above (e.g. `"2018-07-06T12:00:00"`); - * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. - - -#### 2.1.2 Propose the transaction to change the owner permission of an account - -The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: -``` -$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera -executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us -# eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.3 Review and approve the transaction to change the owner permission of an account - -Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. -``` -$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json -$ cat wrap_update_alice_owner_trx_to_review.json -{ - "proposal_name": "updatealice", - "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", - "transaction": { - "expiration": "2018-07-06T12:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio.wrap", - "name": "exec", - "authorization": [{ - "actor": "blkproducera", - "permission": "active" - },{ - "actor": "eosio.wrap", - "permission": "active" - } - ], - "data": { - "executer": "blkproducera", - "trx": { - "expiration": "1970-01-01T00:00:00", - "ref_block_num": 0, - "ref_block_prefix": 0, - "max_net_usage_words": 0, - "max_cpu_usage_ms": 0, - "delay_sec": 0, - "context_free_actions": [], - "actions": [{ - "account": "eosio", - "name": "updateauth", - "authorization": [{ - "actor": "alice", - "permission": "active" - } - ], - "data": "0000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed3232010000" - } - ], - "transaction_extensions": [] - } - }, - "hex_data": "60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000" - } - ], - "transaction_extensions": [] - } -} -``` - -The approvers should go through the human-readable transaction output and make sure everything looks fine. However, due to a current limitation of nodeos/cleos, the JSONification of action payload data does not occur recursively. So while both the `hex_data` and the human-readable JSON `data` of the payload of the `eosio.wrap::exec` action is available in the output of the `cleos multisig review` command, only the hex data is available of the payload of the inner `eosio::updateauth` action. So it is not clear what the `updateauth` will actually do. - -Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. - -Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: -``` -$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex -$ cat expected_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex -$ cat proposed_wrap_update_alice_owner_trx_serialized.hex -c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex -``` - -When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: -``` -$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb -executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us -# eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -#### 2.1.4 Execute the transaction to change the owner permission of an account - -When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). - -``` -$ cleos multisig exec blkproducera updatealice blkproducera -executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us -# eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} -warning: transaction executed locally, but may not be confirmed by the network yet -``` - -Anyone can now verify that the owner authority of `alice` was successfully changed: -``` -$ cleos get account alice -permissions: - owner 1: 1 eosio@active, - active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV -memory: - quota: 49.74 KiB used: 3.348 KiB - -net bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 0 bytes - available: 2.304 MiB - limit: 2.304 MiB - -cpu bandwidth: - staked: 1.0000 SYS (total stake delegated from account to self) - delegated: 0.0000 SYS (total staked delegated to account from others) - used: 413 us - available: 460.4 ms - limit: 460.8 ms - -producers: - -``` diff --git a/docs/eosio.wrap/introduction.md b/docs/eosio.wrap/introduction.md deleted file mode 100644 index db4adc63..00000000 --- a/docs/eosio.wrap/introduction.md +++ /dev/null @@ -1,12 +0,0 @@ -## Introducing eosio.wrap contract - -The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. - -It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. - -However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. - -The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. - -Why is it easier for governance actions to be executed via this contract? -The answer to this question is explained in detailed [here](./03_guides/how-to-use-eosio.wrap.md) \ No newline at end of file diff --git a/docs/introduction.md b/docs/introduction.md deleted file mode 100644 index 226ce05e..00000000 --- a/docs/introduction.md +++ /dev/null @@ -1,52 +0,0 @@ -## About System Contracts - -The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. - -Block.one implements and maintains EOSIO open source platform which contains as an example, the system contracts which encapsulates the base functionality for an EOSIO based blockchain and this tutorial will explain each of them: eosio.bios, eosio.system, eosio.msig, eosio.wrap (formerly known as sudo) and eosio.token. - -## System contracts, system accounts, priviledged accounts - -At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. - -As you learned earlier the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: -|Account|Priviledged|Has contract|Description| -|---|---|---|---| -|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| -|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| -|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| -|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| -|eosio.names|No|No|The account which is holding funds from namespace auctions.| -|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| -|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| -|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| -|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| -|eosio.saving|No|No|The account which holds the 4% of network inflation.| -|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| -|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| -|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| - -## How to compile the eosio.contracts - -To compile the eosio.contracts execute the following commands. - -On all platforms except macOS: -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$( nproc ) -cd .. -``` - -For macOS -``` -cd you_local_path_to/eosio.contracts/ -rm -fr build -mkdir build -cd build -cmake .. -make -j$(sysctl -n hw.ncpu) -cd .. -``` \ No newline at end of file From ff91a49924e8a459a19cec3d398734a71c9748f1 Mon Sep 17 00:00:00 2001 From: Sandwich Date: Mon, 12 Aug 2019 14:57:54 +0200 Subject: [PATCH 0849/1048] remove second docs.json --- docs2.json | 21 --------------------- 1 file changed, 21 deletions(-) delete mode 100644 docs2.json diff --git a/docs2.json b/docs2.json deleted file mode 100644 index c009574b..00000000 --- a/docs2.json +++ /dev/null @@ -1,21 +0,0 @@ -{ - "name": "eosio.contracts", - "generators": [ - { - "name": "collate_markdown", - "options": { - "docs_dir": "docs" - } - }, - { - "name": "doxygen_to_xml", - "options": { - "INPUT": "eosio.bios eosio.system eosio.msig eosio.token eosio.wrap" - } - }, - { - "name": "doxybook", - "options": {} - } - ] -} \ No newline at end of file From f15511e5b8792c57fd055dce95a1163175da928e Mon Sep 17 00:00:00 2001 From: ovi Date: Mon, 12 Aug 2019 16:26:24 +0300 Subject: [PATCH 0850/1048] annotating rex.results.cpp as well rewording the NET explanation to be more concise --- .../include/eosio.system/rex.results.hpp | 31 +++++++++++++++++++ docs/01_introduction.md | 2 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index b5a1949c..791bed52 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -13,17 +13,48 @@ class [[eosio::contract("rex.results")]] rex_results : eosio::contract { using eosio::contract::contract; + /** + * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. + * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. + * An inline convenience action does not have any effect, however, + * its data includes the result of the parent action and appears in its trace. + * @{ + */ + + /** + * Buyresult action. + * + * @param rex_received - amount of tokens used in buy order + */ [[eosio::action]] void buyresult( const asset& rex_received ); + /** + * Sellresult action. + * + * @param proceeds - amount of tokens used in sell order + */ [[eosio::action]] void sellresult( const asset& proceeds ); + /** + * Orderresult action. + * + * @param owner - the owner of the order + * @param proceeds - amount of tokens used in order + */ [[eosio::action]] void orderresult( const name& owner, const asset& proceeds ); + /** + * Rentresult action. + * + * @param rented_tokens - amount of rented tokens + */ [[eosio::action]] void rentresult( const asset& rented_tokens ); + + /** @}*/ using buyresult_action = action_wrapper<"buyresult"_n, &rex_results::buyresult>; using sellresult_action = action_wrapper<"sellresult"_n, &rex_results::sellresult>; diff --git a/docs/01_introduction.md b/docs/01_introduction.md index d1e29f40..fc52b2f2 100644 --- a/docs/01_introduction.md +++ b/docs/01_introduction.md @@ -41,7 +41,7 @@ CPU is processing power, the amount of CPU an account has is measured in microse ### NET -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is data storage measured in bytes and you need to allocate NET according to how much is needed for your transactions to be stored in the blockchain, or more if you wish so, but not less if you want your contract's actions to function. Be careful to not confuse NET with RAM, RAM stores any random data that the contract wants to store in the blockchain, whereas NET although it is also storage space, it measures the size of the transactions. +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is reffered to as "net bandwidth" on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. ### Stake From 5662155aaa15b8911e7d8c854371485a8334f3ca Mon Sep 17 00:00:00 2001 From: ovi Date: Tue, 13 Aug 2019 11:14:25 +0300 Subject: [PATCH 0851/1048] fix a typo and position correctly annotation for rex.results class --- .../include/eosio.system/rex.results.hpp | 16 ++++++---------- docs/01_introduction.md | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index 791bed52..29af8533 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -8,19 +8,17 @@ using eosio::action_wrapper; using eosio::asset; using eosio::name; +/** + * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. + * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. + * An inline convenience action does not have any effect, however, + * its data includes the result of the parent action and appears in its trace. + */ class [[eosio::contract("rex.results")]] rex_results : eosio::contract { public: using eosio::contract::contract; - /** - * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. - * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. - * An inline convenience action does not have any effect, however, - * its data includes the result of the parent action and appears in its trace. - * @{ - */ - /** * Buyresult action. * @@ -53,8 +51,6 @@ class [[eosio::contract("rex.results")]] rex_results : eosio::contract { */ [[eosio::action]] void rentresult( const asset& rented_tokens ); - - /** @}*/ using buyresult_action = action_wrapper<"buyresult"_n, &rex_results::buyresult>; using sellresult_action = action_wrapper<"sellresult"_n, &rex_results::sellresult>; diff --git a/docs/01_introduction.md b/docs/01_introduction.md index fc52b2f2..50b0052e 100644 --- a/docs/01_introduction.md +++ b/docs/01_introduction.md @@ -41,7 +41,7 @@ CPU is processing power, the amount of CPU an account has is measured in microse ### NET -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is reffered to as "net bandwidth" on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is referred to as "net bandwidth" on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. ### Stake From 9c7383807705764112abb28c00c177ec0b8ec5eb Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 14 Aug 2019 11:19:36 +0300 Subject: [PATCH 0852/1048] correct relative links to md files --- docs/01_introduction.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/01_introduction.md b/docs/01_introduction.md index 50b0052e..9ef07998 100644 --- a/docs/01_introduction.md +++ b/docs/01_introduction.md @@ -160,7 +160,7 @@ The actions implemented and publicly exposed by the `eosio.system` system contra The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. -The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/#how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: +The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: - first you create a transaction json file, - then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, - the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, @@ -208,4 +208,4 @@ However, the current method is opaque and leaves undesirable side effects on spe The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. Why is it easier for governance actions to be executed via this contract? -The answer to this question is explained in detailed [here](./guides/how-to-use-eosio.wrap.md) \ No newline at end of file +The answer to this question is explained in detailed [here](./03_guides/07_how-to-use-eosio.wrap.md) \ No newline at end of file From e151db6372b2f1b8b691f9ad61ee6a14ebe4caee Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 14 Aug 2019 11:24:10 +0300 Subject: [PATCH 0853/1048] correct links to eos how-to's --- docs/03_guides/02_how-to-buy-ram.md | 4 ++-- docs/03_guides/03_how-to-stake.md | 4 ++-- docs/03_guides/04_how-to-vote.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md index 5c4f49d3..878757e3 100644 --- a/docs/03_guides/02_how-to-buy-ram.md +++ b/docs/03_guides/02_how-to-buy-ram.md @@ -2,7 +2,7 @@ You can buy RAM using `cleos` command line tool or using a wallet that implements the buy RAM functionality. -TO DO: add link below -To buy ram using `cleos` check [how to buy ram](how-to-buy-ram). +TO DO: verify and correct the next url +To buy ram using `cleos` check [how to buy ram](https://eosio.github.io/eos/cleos/how-to-buy-ram) To buy ram using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md index 0389415d..bf2a1f38 100644 --- a/docs/03_guides/03_how-to-stake.md +++ b/docs/03_guides/03_how-to-stake.md @@ -2,7 +2,7 @@ You can stake tokens for CPU and/or NET bandwidth using `cleos` command line tool or using a wallet that implements this functionality. -TO DO: add link below -To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](how-to-stake-resource). +TO DO: verify and correct the next url +To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](https://eosio.github.io/eos/cleos/how-to-stake-resource) To stake tokens for CPU and/or NET bandwidth using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file diff --git a/docs/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md index babb2195..d27cccac 100644 --- a/docs/03_guides/04_how-to-vote.md +++ b/docs/03_guides/04_how-to-vote.md @@ -2,7 +2,7 @@ You can vote using `cleos` command line tool or using a wallet that implements the vote functionality. -TO DO: add link below -To vote using `cleos` check [how to vote](how-to-vote). +TO DO: verify and correct the next url +To vote using `cleos` check [how to vote](https://eosio.github.io/eos/cleos/how-to-vote) To vote using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file From 22e0d74584bab62a05fbca55af130273e7124a39 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 22 Aug 2019 10:00:01 -0400 Subject: [PATCH 0854/1048] Implemented TravisCI for community PRs. --- .cicd/build.sh | 26 ++++++++++++++++++++++++++ .cicd/helpers/dependency-info.sh | 26 ++++++++++++++++++++++++++ .cicd/helpers/general.sh | 6 ++++++ .cicd/pipeline.yml | 23 +++++++++++++++++++++++ .cicd/tests.sh | 26 ++++++++++++++++++++++++++ .travis.yml | 16 ++++++++++++++++ pipeline.jsonc | 5 +++-- 7 files changed, 126 insertions(+), 2 deletions(-) create mode 100755 .cicd/build.sh create mode 100755 .cicd/helpers/dependency-info.sh create mode 100644 .cicd/helpers/general.sh create mode 100644 .cicd/pipeline.yml create mode 100755 .cicd/tests.sh create mode 100644 .travis.yml diff --git a/.cicd/build.sh b/.cicd/build.sh new file mode 100755 index 00000000..a80c1d9c --- /dev/null +++ b/.cicd/build.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -eo pipefail + +. ./.cicd/helpers/general.sh +. ./.cicd/helpers/dependency-info.sh + +mkdir -p $BUILD_DIR + +FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} +ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:$PATH" + +PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" +BUILD_COMMANDS="cmake .. && make -j $JOBS" + +COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" + +# Load BUILDKITE Environment Variables for use in docker run +if [[ -f $BUILDKITE_ENV_FILE ]]; then + evars="" + while read -r var; do + evars="$evars --env ${var%%=*}" + done < "$BUILDKITE_ENV_FILE" +fi + +eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh new file mode 100755 index 00000000..533bf1d5 --- /dev/null +++ b/.cicd/helpers/dependency-info.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -eo pipefail +[[ "$RAW_PIPELINE_CONFIG" == '' ]] && export RAW_PIPELINE_CONFIG="$1" +[[ "$RAW_PIPELINE_CONFIG" == '' ]] && export RAW_PIPELINE_CONFIG='pipeline.jsonc' +[[ "$PIPELINE_CONFIG" == '' ]] && export PIPELINE_CONFIG='pipeline.json' +# read dependency file +if [[ -f "$RAW_PIPELINE_CONFIG" ]]; then + echo 'Reading pipeline configuration file...' + cat "$RAW_PIPELINE_CONFIG" | grep -Po '^[^"/]*("((?<=\\).|[^"])*"[^"/]*)*' | jq -c .\"eosio-dot-contracts\" > "$PIPELINE_CONFIG" + EOSIO_BRANCH=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies.eosio') + CDT_BRANCH=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies."eosio.cdt"') + CDT_VERSION=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies."cdt-version"') +else + echo 'ERROR: No pipeline configuration file or dependencies file found!' + exit 1 +fi +if [[ $TRAVIS ]]; then + CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_BRANCH && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_BRANCH) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match +else + CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_BRANCH && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_BRANCH) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match +fi +test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_BRANCH | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already +echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_BRANCH\"..." + +export BRANCH=$(echo $EOSIO_BRANCH | sed 's/\//\_/') +export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt_${CDT_VERSION}-ubuntu-18.04_amd64.deb" \ No newline at end of file diff --git a/.cicd/helpers/general.sh b/.cicd/helpers/general.sh new file mode 100644 index 00000000..42b04117 --- /dev/null +++ b/.cicd/helpers/general.sh @@ -0,0 +1,6 @@ +export ROOT_DIR=$( dirname "${BASH_SOURCE[0]}" )/../.. +export BUILD_DIR=$ROOT_DIR/build +export CICD_DIR=$ROOT_DIR/.cicd +export HELPERS_DIR=$CICD_DIR/helpers +export JOBS=${JOBS:-"$(getconf _NPROCESSORS_ONLN)"} +export MOUNTED_DIR='/workdir' diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml new file mode 100644 index 00000000..1d4c3c5e --- /dev/null +++ b/.cicd/pipeline.yml @@ -0,0 +1,23 @@ +steps: + + - wait + + - label: ":ubuntu: Ubuntu 18.04 - Build" + command: + - ./.cicd/build.sh + - "tar -pczf build.tar.gz build && buildkite-agent artifact upload build.tar.gz" + agents: + queue: "automation-eos-builder-fleet" + timeout: ${TIMEOUT:-10} + skip: $SKIP_UBUNTU_18 + + - wait + + - label: ":ubuntu: Ubuntu 18.04 - Test" + command: + - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' && tar -xzf build.tar.gz" + - ./.cicd/tests.sh + agents: + queue: "automation-eos-builder-fleet" + timeout: ${TIMEOUT:-10} + skip: $SKIP_UBUNTU_18 \ No newline at end of file diff --git a/.cicd/tests.sh b/.cicd/tests.sh new file mode 100755 index 00000000..29db7c36 --- /dev/null +++ b/.cicd/tests.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -eo pipefail + +. ./.cicd/helpers/general.sh +. ./.cicd/helpers/dependency-info.sh + +mkdir -p $BUILD_DIR + +FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} +ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:$PATH" + +PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" +TEST_COMMANDS="ctest -j $JOBS" + +COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" + +# Load BUILDKITE Environment Variables for use in docker run +if [[ -f $BUILDKITE_ENV_FILE ]]; then + evars="" + while read -r var; do + evars="$evars --env ${var%%=*}" + done < "$BUILDKITE_ENV_FILE" +fi + +eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..fd9aeb34 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,16 @@ +language: cpp +git: + depth: false +if: fork = true OR type = api OR type = cron +matrix: + include: + - os: linux + dist: xenial + services: docker +script: "./.cicd/build.sh && ./.cicd/tests.sh" +notifications: + webhooks: + secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= +env: + global: + secure: jE/hVrQwgGs4KDdBqtiaGb9QE7xg8tn9NK2xMyedsi1CzqSZwl1iLjoefD4nH2wYRCGWfTBFES7QtJbj7SZK0+eobwQMO+jyXSOBd8D8HqcT37UMOPYW72YY2UuZpSCinuLHkZxZnb5dGfMqXDIZ3Y3GIgxOAd2+a0Y6xLt0dfZvh4OH8KVc/wWtuAjh0kMYEoQV9gEyok7xnXNjSLbAbkVslQBKHv451oi8saIGQbFC3b1KSGlE9LBv0QAR9MLXlkYMF3tAfegTGzx/NUIwdOOJ6XoPWoUGWV/u/nWexjHwsb1MwqQHN+LWHRM39ehL46na4m32S/ro3wHmBXnxlF3ys8QH0PEpfJL+r8aKGOv3pmWE//x+Ias6K6RWzTMLRFqlDPGTAGgMRGFiyGhT1aRHXD+mC2RppXptBST9brhE7+lyVqzKYFFHi0SHxfRsSQLgGhIJTMBr2Jj5ORlT86BWdxj3P8VOitKif/RP1zuJBKr78EyLGDPvsJhmot/gPg3VAo2R+cyFqVBWig2PC2ylneSS2DptMV6qLlujA+Fr38diYacsMqhej3ukqVZGaOecSIJXweJQ+7Y9SvGQDeAH8gEzgLLlkNrwpaFtLpxUqHrGWKJHUS8oKtleTznoK1Ck9Es2JTG2Tr4gVHk0OCIfc3hZRQl5Kj7AVi20Tec= \ No newline at end of file diff --git a/pipeline.jsonc b/pipeline.jsonc index ddf8f23b..cc6acfcd 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,8 +4,9 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "release/1.8.x", - "eosio.cdt": "release/1.6.x" + "eosio": "trav-poc", + "eosio.cdt": "release/1.6.x", + "cdt-version": "1.6.2-1" } } } From 28c8f1ac3db28ef4f487fcd0fc848379e5324885 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 22 Aug 2019 10:14:15 -0400 Subject: [PATCH 0855/1048] adjust setinflation Ricardian contract to reflect pay factor precision changes --- contracts/eosio.system/ricardian/eosio.system.contracts.md.in | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 13016351..70e1b7cd 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -558,8 +558,8 @@ icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ {{$action.account}} sets the inflation parameters as follows: * Annual inflation rate (in units of a hundredth of a percent): {{annual_rate}} -* Fraction of inflation used to reward block producers: 1/{{inflation_pay_factor}} -* Fraction of block producer rewards to be distributed proportional to blocks produced: 1/{{votepay_factor}} +* Fraction of inflation used to reward block producers: 10000/{{inflation_pay_factor}} +* Fraction of block producer rewards to be distributed proportional to blocks produced: 10000/{{votepay_factor}}

undelegatebw

From 751e315aff067a486d31a87795facc4f588a0793 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 22 Aug 2019 10:29:38 -0400 Subject: [PATCH 0856/1048] Set pipeline.jsonc to correct values. --- pipeline.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index cc6acfcd..a339ac5b 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,7 +4,7 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "trav-poc", + "eosio": "release/1.8.x", "eosio.cdt": "release/1.6.x", "cdt-version": "1.6.2-1" } From 836ed1da8c65ea8c93a5b2cc2cb53f4043efdf1a Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 22 Aug 2019 13:36:39 -0400 Subject: [PATCH 0857/1048] Escape PATH. --- .cicd/build.sh | 2 +- .cicd/tests.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index a80c1d9c..0571e22f 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -8,7 +8,7 @@ mkdir -p $BUILD_DIR FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:$PATH" +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake .. && make -j $JOBS" diff --git a/.cicd/tests.sh b/.cicd/tests.sh index 29db7c36..2223c594 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -8,7 +8,7 @@ mkdir -p $BUILD_DIR FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:$PATH" +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" TEST_COMMANDS="ctest -j $JOBS" From 3d0629f6d76e55560cfee63eada3c1eb539b7bbf Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 22 Aug 2019 13:42:18 -0400 Subject: [PATCH 0858/1048] Escape PATH. --- .cicd/build.sh | 2 +- .cicd/tests.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 0571e22f..0d9573ae 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -8,7 +8,7 @@ mkdir -p $BUILD_DIR FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\$PATH" +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake .. && make -j $JOBS" diff --git a/.cicd/tests.sh b/.cicd/tests.sh index 2223c594..abf0cd0d 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -8,7 +8,7 @@ mkdir -p $BUILD_DIR FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\$PATH" +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" TEST_COMMANDS="ctest -j $JOBS" From 47d2f62cb9b11b8c5ce63fd90fa8caf38d943954 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 22 Aug 2019 13:57:06 -0400 Subject: [PATCH 0859/1048] Added test metrics. --- .cicd/metrics/test-metrics.js | 431 ++++++++++++++++++++++++++++++ .cicd/metrics/test-metrics.tar.gz | Bin 0 -> 96551 bytes .cicd/pipeline.yml | 16 +- 3 files changed, 446 insertions(+), 1 deletion(-) create mode 100644 .cicd/metrics/test-metrics.js create mode 100644 .cicd/metrics/test-metrics.tar.gz diff --git a/.cicd/metrics/test-metrics.js b/.cicd/metrics/test-metrics.js new file mode 100644 index 00000000..b995134d --- /dev/null +++ b/.cicd/metrics/test-metrics.js @@ -0,0 +1,431 @@ +#!/usr/bin/env node +/* includes */ +const execSync = require('child_process').execSync; // run shell commands +const fetch = require('node-fetch'); // downloading +const fs = require('fs'); // file stream +const XML = require('xml2js'); // parse xml + +/* globals */ +const buildkiteAccessToken = `?access_token=${process.env.BUILDKITE_API_KEY}`; // import buildkite access token from environment +const debug = (process.env.DEBUG === 'true') ? true : false; +let errorCount = 0; // count number of jobs which caused an error +const EXIT_SUCCESS = 0; +const inBuildkite = (process.env.BUILDKITE === 'true') ? true : false; +const outputFile = 'test-metrics.json'; +const pipelineWhitelist = // the pipelines for which we run diagnostics +[ + 'eosio', + 'eosio-base-images', + 'eosio-beta', + 'eosio-build-unpinned', + 'eosio-debug', + 'eosio-lrt', + 'eosio-security' +]; + +/* functions */ +// given a url string, download a text document +async function download(url) +{ + if (debug) console.log(`download(${url.replace(buildkiteAccessToken, '')})`); // DEBUG + const httpResponse = await fetch(url); + const body = await httpResponse.text(); + if (isNullOrEmpty(body)) + { + console.log(`ERROR: URL returned nothing! URL: ${url.replace(buildkiteAccessToken, '')}`); + const error = + { + http: { body, response: httpResponse, url}, + message: 'http body is null or empty', + origin: 'download()', + } + throw error; + } + if (debug) console.log('Download complete.'); // DEBUG + return body; +} + +// given a pipeline and a build number, get a build object +async function getBuild(pipeline, buildNumber) +{ + if (debug) console.log(`getBuild(${pipeline}, ${buildNumber})`); // DEBUG + const httpResponse = await fetch(`https://api.buildkite.com/v2/organizations/EOSIO/pipelines/${pipeline}/builds/${buildNumber}${buildkiteAccessToken}`); + return httpResponse.json(); +} + +// given a buildkite job, return the environmental variables +async function getEnvironment(job) +{ + if (debug) console.log('getEnvironment()'); // DEBUG + const httpResponse = await fetch(`${job.build_url}/jobs/${job.id}/env${buildkiteAccessToken}`); + const environment = await httpResponse.json(); + return environment.env; +} + +// given a string to search, a key as regex or a string, and optionally a start index, return the lowest line number containing the key +function getLineNumber(text, key, startIndex) +{ + if (debug) console.log('getLineNumber()'); // DEBUG + const begin = (isNullOrEmpty(startIndex) || !Number.isInteger(startIndex) || startIndex < 1) ? 0 : startIndex; + let found = false; + let lineNumber = 0; + const regex = (key instanceof RegExp); + text.split('\n').some((line) => + { + if (lineNumber >= begin && ((regex && key.test(line)) || (!regex && line.includes(key)))) + { + found = true; + return true; // c-style break + } + lineNumber += 1; + return false; // for the linter, plz delete when linter is fixed + }); + return (found) ? lineNumber : -1; +} + +// given a buildkite job, return a sanitized log file +async function getLog(job) +{ + if (debug) console.log(`getLog(${job.raw_log_url})`); // DEBUG + const logText = await download(job.raw_log_url + buildkiteAccessToken); + // returns log lowercase, with single spaces and '\n' only, and only ascii-printable characters + return sanitize(logText); // made this a separate function for unit testing purposes +} + +// given a Buildkite environment, return the operating system used +function getOS(environment) +{ + if (debug) console.log(`getOS(${environment.BUILDKITE_LABEL})`); // DEBUG + if (isNullOrEmpty(environment) || isNullOrEmpty(environment.BUILDKITE_LABEL)) + { + console.log('ERROR: getOS() called with empty environment.BUILDKITE_LABEL!'); + console.log(JSON.stringify(environment)); + return null; + } + const label = environment.BUILDKITE_LABEL.toLowerCase(); + if ((/aws(?!.*[23])/.test(label) || /amazon(?!.*[23])/.test(label))) + return 'Amazon Linux 1'; + if (/aws.*2/.test(label) || /amazon.*2/.test(label)) + return 'Amazon Linux 2'; + if (/centos(?!.*[89])/.test(label)) + return 'CentOS 7'; + if (/fedora(?!.*2[89])/.test(label) && /fedora(?!.*3\d)/.test(label)) + return 'Fedora 27'; + if (/high.*sierra/.test(label)) + return 'High Sierra'; + if (/mojave/.test(label)) + return 'Mojave'; + if (/ubuntu.*16.*04/.test(label) || /ubuntu.*16(?!.*10)/.test(label)) + return 'Ubuntu 16.04'; + if (/ubuntu.*18.*04/.test(label) || /ubuntu.*18(?!.*10)/.test(label)) + return 'Ubuntu 18.04'; + if (/docker/.test(label)) + return 'Docker'; + return 'Unknown'; +} + +// given a Buildkite job, return the test-results.xml file as JSON +async function getXML(job) +{ + if (debug) console.log('getXML()'); // DEBUG + const xmlFilename = 'test-results.xml'; + const artifacts = await download(job.artifacts_url + buildkiteAccessToken); + const testResultsArtifact = JSON.parse(artifacts).filter(artifact => artifact.filename === xmlFilename); + if (isNullOrEmpty(testResultsArtifact)) + { + console.log(`WARNING: No ${xmlFilename} found for "${job.name}"! Link: ${job.web_url}`); + return null; + } + const urlBuildkite = testResultsArtifact[0].download_url; + const rawXML = await download(urlBuildkite + buildkiteAccessToken); + const xmlOptions = + { + attrNameProcessors: [function lower(name) { return name.toLowerCase(); }], + explicitArray: false, // do not put single strings in single-element arrays + mergeAttrs: true, // make attributes children of their node + normalizeTags: true, // convert all tag names to lowercase + }; + let xmlError, xmlTestResults; + await XML.parseString(rawXML, xmlOptions, (err, result) => {xmlTestResults = result; xmlError = err;}); + if (isNullOrEmpty(xmlError)) + return xmlTestResults; + console.log(`WARNING: Failed to parse xml for "${job.name}" job! Link: ${job.web_url}`); + console.log(JSON.stringify(xmlError)); + return null; +} + +// test if variable is empty +function isNullOrEmpty(str) +{ + return (str === null || str === undefined || str.length === 0 || /^\s*$/.test(str)); +} + +// return array of test results from a buildkite job log +function parseLog(logText) +{ + if (debug) console.log('parseLog()'); // DEBUG + const lines = logText.split('\n'); + const resultLines = lines.filter(line => /test\s+#\d+/.test(line)); // 'grep' for the test result lines + // parse the strings and make test records + return resultLines.map((line) => + { + const y = line.trim().split(/test\s+#\d+/).pop(); // remove everything before the test declaration + const parts = y.split(/\s+/).slice(1, -1); // split the line and remove the test number and time unit + const testName = parts[0]; + const testTime = parts[(parts.length - 1)]; + const rawResult = parts.slice(1, -1).join(); + let testResult; + if (rawResult.includes('failed')) + testResult = 'Failed'; + else if (rawResult.includes('passed')) + testResult = 'Passed'; + else + testResult = 'Exception'; + return { testName, testResult, testTime }; // create a test record + }); +} + +// return array of test results from an xUnit-formatted JSON object +function parseXunit(xUnit) +{ + if (debug) console.log('parseXunit()'); // DEBUG + if (isNullOrEmpty(xUnit)) + { + console.log('WARNING: xUnit is empty!'); + return null; + } + return xUnit.site.testing.test.map((test) => + { + const testName = test.name; + const testTime = test.results.namedmeasurement.filter(x => /execution\s+time/.test(x.name.toLowerCase()))[0].value; + let testResult; + if (test.status.includes('failed')) + testResult = 'Failed'; + else if (test.status.includes('passed')) + testResult = 'Passed'; + else + testResult = 'Exception'; + return { testName, testResult, testTime }; + }); +} + +// returns text lowercase, with single spaces and '\n' only, and only ascii-printable characters +function sanitize(text) +{ + if (debug) console.log(`sanitize(text) where text.length = ${text.length} bytes`); // DEBUG + const chunkSize = 131072; // process text in 128 kB chunks + if (text.length > chunkSize) + return sanitize(text.slice(0, chunkSize)).concat(sanitize(text.slice(chunkSize))); + return text + .replace(/(?!\n)\r(?!\n)/g, '\n').replace(/\r/g, '') // convert all line endings to '\n' + .replace(/[^\S\n]+/g, ' ') // convert all whitespace to ' ' + .replace(/[^ -~\n]+/g, '') // remove non-printable characters + .toLowerCase(); +} + +// input is array of whole lines containing "test #" and ("failed" or "exception") +function testDiagnostics(test, logText) +{ + if (debug) + { + console.log(`testDiagnostics(test, logText) where logText.length = ${logText.length} bytes and test is`); // DEBUG + console.log(JSON.stringify(test)); + } + // get basic information + const testResultLine = new RegExp(`test\\s+#\\d+.*${test.testName}`, 'g'); // regex defining "test #" line + const startIndex = getLineNumber(logText, testResultLine); + const output = { errorMsg: null, lineNumber: startIndex + 1, stackTrace: null }; // default output + // filter tests + if (test.testResult.toLowerCase() === 'passed') + return output; + output.errorMsg = 'test diangostics are not enabled for this pipeline'; + if (!pipelineWhitelist.includes(test.pipeline)) + return output; + // diagnostics + if (debug) console.log('Running diagnostics...'); // DEBUG + output.errorMsg = 'uncategorized'; + const testLog = logText.split(testResultLine)[1].split(/test\s*#/)[0].split('\n'); // get log output from this test only, as array of lines + let errorLine = testLog[0]; // first line, from "test ## name" to '\n' exclusive + if (/\.+ *\** *not run\s+0+\.0+ sec$/.test(errorLine)) // not run + output.errorMsg = 'test not run'; + else if (/\.+ *\** *time *out\s+\d+\.\d+ sec$/.test(errorLine)) // timeout + output.errorMsg = 'test timeout'; + else if (/exception/.test(errorLine)) // test exception + output.errorMsg = errorLine.split('exception')[1].replace(/[: \d.]/g, '').replace(/sec$/, ''); // isolate the error message after exception + else if (/fc::.*exception/.test(testLog.filter(line => !isNullOrEmpty(line))[1])) // fc exception + { + [, errorLine] = testLog.filter(line => !isNullOrEmpty(line)); // get first line + output.errorMsg = `fc::${errorLine.split('::')[1].replace(/['",]/g, '').split(' ')[0]}`; // isolate fx exception body + } + else if (testLog.join('\n').includes('ctest:')) // ctest exception + { + [errorLine] = testLog.filter(line => line.includes('ctest:')); + output.errorMsg = `ctest:${errorLine.split('ctest:')[1]}`; + } + else if (!isNullOrEmpty(testLog.filter(line => /boost.+exception/.test(line)))) // boost exception + { + [errorLine] = testLog.filter(line => /boost.+exception/.test(line)); + output.errorMsg = `boost: ${errorLine.replace(/[()]/g, '').split(/: (.+)/)[1]}`; // capturing parenthesis, split only at first ' :' + output.stackTrace = testLog.filter(line => /thread-\d+/.test(line))[0].split('thread-')[1].replace(/^\d+/, '').trim().replace(/[[]\d+m$/, ''); // get the bottom of the stack trace + } + else if (/unit[-_. ]+test/.test(test.testName) || /plugin[-_. ]+test/.test(test.testName)) // unit test, application exception + { + if (!isNullOrEmpty(testLog.filter(line => line.includes('exception: ')))) + { + [errorLine] = testLog.filter(line => line.includes('exception: ')); + [, output.errorMsg] = errorLine.replace(/[()]/g, '').split(/: (.+)/); // capturing parenthesis, split only at first ' :' + output.stackTrace = testLog.filter(line => /thread-\d+/.test(line))[0].split('thread-')[1].replace(/^\d+/, '').trim().replace(/[[]\d+m$/, ''); // get the bottom of the stack trace + } + // else uncategorized unit test + } + // else integration test, add cross-referencing code here (or uncategorized) + if (errorLine !== testLog[0]) // get real line number from log file + output.lineNumber = getLineNumber(logText, errorLine, startIndex) + 1; + return output; +} + +// return test metrics given a buildkite job or build +async function testMetrics(buildkiteObject) +{ + if (!isNullOrEmpty(buildkiteObject.type)) // input is a Buildkite job object + { + const job = buildkiteObject; + console.log(`Processing test metrics for "${job.name}"${(inBuildkite) ? '' : ` at ${job.web_url}`}...`); + if (isNullOrEmpty(job.exit_status)) + { + console.log(`${(inBuildkite) ? '+++ :warning: ' : ''}WARNING: "${job.name}" was skipped!`); + return null; + } + // get test results + const logText = await getLog(job); + let testResults; + let xUnit; + try + { + xUnit = await getXML(job); + testResults = parseXunit(xUnit); + } + catch (error) + { + console.log(`XML processing failed for "${job.name}"! Link: ${job.web_url}`); + console.log(JSON.stringify(error)); + testResults = null; + } + finally + { + if (isNullOrEmpty(testResults)) + testResults = parseLog(logText); + } + // get test metrics + const env = await getEnvironment(job); + env.BUILDKITE_REPO = env.BUILDKITE_REPO.replace(new RegExp('^git@github.com:(EOSIO/)?'), '').replace(new RegExp('.git$'), ''); + const metrics = []; + const os = getOS(env); + testResults.forEach((result) => + { + // add test properties + const test = + { + ...result, // add testName, testResult, testTime + agentName: env.BUILDKITE_AGENT_NAME, + agentRole: env.BUILDKITE_AGENT_META_DATA_QUEUE || env.BUILDKITE_AGENT_META_DATA_ROLE, + branch: env.BUILDKITE_BRANCH, + buildNumber: env.BUILDKITE_BUILD_NUMBER, + commit: env.BUILDKITE_COMMIT, + job: env.BUILDKITE_LABEL, + os, + pipeline: env.BUILDKITE_PIPELINE_SLUG, + repo: env.BUILDKITE_REPO, + testTime: parseFloat(result.testTime), + url: job.web_url, + }; + metrics.push({ ...test, ...testDiagnostics(test, logText) }); + }); + return metrics; + } + else if (!isNullOrEmpty(buildkiteObject.number)) // input is a Buildkite build object + { + const build = buildkiteObject; + console.log(`Processing test metrics for ${build.pipeline.slug} build ${build.number}${(inBuildkite) ? '' : ` at ${build.web_url}`}...`); + let metrics = [], promises = []; + // process test metrics + build.jobs.filter(job => job.type === 'script' && /test/.test(job.name.toLowerCase()) && ! /test metrics/.test(job.name.toLowerCase())).forEach((job) => + { + promises.push( + testMetrics(job) + .then((moreMetrics) => { + if (!isNullOrEmpty(moreMetrics)) + metrics = metrics.concat(moreMetrics); + else + console.log(`${(inBuildkite) ? '+++ :warning: ' : ''}WARNING: "${job.name}" metrics are empty!\nmetrics = ${JSON.stringify(moreMetrics)}`); + }).catch((error) => { + console.log(`${(inBuildkite) ? '+++ :no_entry: ' : ''}ERROR: Failed to process test metrics for "${job.name}"! Link: ${job.web_url}`); + console.log(JSON.stringify(error)); + errorCount++; + }) + ); + }); + await Promise.all(promises); + return metrics; + } + else // something else + { + console.log(`${(inBuildkite) ? '+++ :no_entry: ' : ''}ERROR: Buildkite object not recognized or not a test step!`); + console.log(JSON.stringify({buildkiteObject})); + return null; + } +} + +/* main */ +async function main() +{ + if (debug) console.log(`$ ${process.argv.join(' ')}`); + let build, metrics = null; + console.log(`${(inBuildkite) ? '+++ :evergreen_tree: ' : ''}Getting information from enviroment...`); + const buildNumber = process.env.BUILDKITE_BUILD_NUMBER || process.argv[2]; + const pipeline = process.env.BUILDKITE_PIPELINE_SLUG || process.argv[3]; + if (debug) + { + console.log(`BUILDKITE=${process.env.BUILDKITE}`); + console.log(`BUILDKITE_BUILD_NUMBER=${process.env.BUILDKITE_BUILD_NUMBER}`); + console.log(`BUILDKITE_PIPELINE_SLUG=${process.env.BUILDKITE_PIPELINE_SLUG}`); + console.log(' State:') + console.log(`inBuildkite = "${inBuildkite}"`); + console.log(`buildNumber = "${buildNumber}"`); + console.log(`pipeline = "${pipeline}"`); + } + if (isNullOrEmpty(buildNumber) || isNullOrEmpty(pipeline) || isNullOrEmpty(process.env.BUILDKITE_API_KEY)) + { + console.log(`${(inBuildkite) ? '+++ :no_entry: ' : ''}ERROR: Missing required inputs!`); + if (isNullOrEmpty(process.env.BUILDKITE_API_KEY)) console.log('- Buildkite API key, as BUILDKITE_API_KEY environment variable'); + if (isNullOrEmpty(buildNumber)) console.log('- Build Number, as BUILDKITE_BUILD_NUMBER or argument 1'); + if (isNullOrEmpty(pipeline)) console.log('- Pipeline Slug, as BUILDKITE_PIPELINE_SLUG or argument 2'); + errorCount = -1; + } + else + { + console.log(`${(inBuildkite) ? '+++ :bar_chart: ' : ''}Processing test metrics...`); + build = await getBuild(pipeline, buildNumber); + metrics = await testMetrics(build); + console.log('Done processing test metrics.'); + } + console.log(`${(inBuildkite) ? '+++ :pencil: ' : ''}Writing to file...`); + fs.writeFileSync(outputFile, JSON.stringify({ metrics })); + console.log(`Saved metrics to "${outputFile}" in "${process.cwd()}".`); + if (inBuildkite) + { + console.log('+++ :arrow_up: Uploading artifact...'); + execSync(`buildkite-agent artifact upload ${outputFile}`); + } + if (errorCount === 0) + console.log(`${(inBuildkite) ? '+++ :white_check_mark: ' : ''}Done!`); + else + { + console.log(`${(inBuildkite) ? '+++ :warning: ' : ''}Finished with errors.`); + console.log(`Please send automation a link to this job${(isNullOrEmpty(build)) ? '.' : `: ${build.web_url}`}`); + console.log('@kj4ezj or @zreyn on Telegram'); + } + return (inBuildkite) ? process.exit(EXIT_SUCCESS) : process.exit(errorCount); +}; + +main(); \ No newline at end of file diff --git a/.cicd/metrics/test-metrics.tar.gz b/.cicd/metrics/test-metrics.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..2381787ca06196f1b95c636435a77b58ba1cc0aa GIT binary patch literal 96551 zcmV)oK%BoHiwFP~s5xB#1MGcyUmHi#@bmAZPcg>(M3OBDNeGY&;N|W$PS<@zuCPDJGg0_j-!DSB+E^D z&&MJE{fm4W^Pb;#J`Mf;c;JK&Lkz{{zq8b7E-oxAwPF5WEp-;3=KnE1jrqt4qx#T^ z0=E}7K8Fv`M*jSFIXxn6HD?mMCNV!qV#y)d$zFHUd&#_L%tR^a?Pb_1tU?p?Tp{-;sk_na^+R~w?t zYioYq3dWulUO0n+)$@l#+v|rM(wP(WE_5*1Xq}#xt5mh`UwZ@J?z`T(s1xcH&O%=B z%pEvZ7zK_!o+7p!;cccjMEK-4C}X)Ra3M`GE$~VlXU% zVVwp3(1Pl2;Cn;Ii+Bh6&gu9ZTCC_TtaslYes8U;tXSnJ7(3;v^__)ZtYzyAy6?O$ z4IG%AAn=1Vf9yq2ze!!_(Jya2Jaq!gKeImjr=fLy;R5b^_BeFHaAkb&{X(P$jK!x_V(CfD)3vM4ulN6x_YoS!eC!GRm% zh+sI;g(F{u)|nshv0OVuX?@o|_xvydaHXS?1)s9xhpu0)X+P?xcIedIp?&Uzu@_Ec z$DZJr>tk=^dY;oa-_b;wj|M?xJ_w!OIB=tza_RUr(c9VB>qRaM5h)G^bnadODcIIH z7$6A)t=A;s!{f;L0uO(-`>Yl@nR^ zZ@)w7M&OJFcF(D#QG3lQm#eqc6SiE4@(47Wn2RVH?K$BHe&7_^*S5l}EHc;=sec6tetg%ZR@DgsW872hTZ zlZaT>2KLMA-_~HNH4wAV?FqgMm*?m0k=u}@(g6I-U$y7`;N14y-)vg7^WB~Ojh%VP zg66fJ%u`i-r1yvaiV>frJC15&bs!_e)nQ^@NfF@THBk{6q9#M^fpujEu6+t>dPAOu%9Al*y?5+wag0L+U4774s;7=GjxXe~aqI1Pt+2srr%5QUua8q-u3g zPQ?+**ewWSD|GCjcTt09m(Go4hXCN*`GV`xmP{Gx-5(($?ZM!NUf2PO#lG{!n2mvd z4N}dbMZ)DS3?Z^zk6MEg&`3$2l}#whsHK98v4#a|4E_d!FEC9Sh^$#Ub%2|o=r)lt#7RsiuoqUc=eRc0BR#=pnCM7K`#Hrigrk8QRmvYdP&Y$==u|2QwQ8-riAfDanbzQ& z6^@3lzOpJ6)*gI?_8O>)Feo(4$}{;EA2x(4jD4$CxpYd32Qg+;eO?=H1cl%WQq1aM zbOTz@DX6WNDO_Fa^~)8jrGRlj46CI60-X}!xiDkEg-3(mK#4@o4$2WwI(v@N=FI)# z^qGh-S4xHYjgzT0yKL24#h4H*24Inq`x}U1ph!~4Q@GD25bI>FbHYn99ue5rpWrF+ zjx5#=?+;K<5`00*%NPLbWvX`1QGvz^4JV{A;4%(+HcInrH@dJwSiNXwj6k0Vi5npK zS-v;8;mpB9wh;DQw>|=v5g`w@&|0*6fc{WNx4>3~_nZxDX!jkMNSG(Urvqk+4QQ75 z!&x3fH46z9Imu`ojQkMTyg5TkOV`++!Jzz+1E3K^coRm>&_Xl7U`RXr6|HiC`GN|6 z`(0}gK41i{Hnr}q@CX(SAkfE+FSLW^Ou=3rr#*3r& z!f|z;GcN>4n47nU_HQ5#(@SW~i+8ZRO64t(BI7SstE^hWh8i#0SuMn0O@Q3iA@^Xw zJ|D%`-^BZv0JH|hclNDUI*2o;?*}%4XeVJH@79YfeC$tZx;JmDj0I*$`0WL+{c9wqA}4q_>$`G5Hq2KpPLDu<>O$ zU~VE%?r`m|FlCLMrE(Q-9 z+hc95^11+-SQR?sZB+wVWG?rm>uf4^*P z`(VClP26$~3Z>l~(*Wr4+%se$muT1Hvuo#+G=h_&%oYmk?yHmzA2p8~0{sZvP)zM> z=248zk^!~A1i?UeM$G%O5<`z2MZq?VbeH+n{2*MmjwE@KGE$*Auzr^#g`Y7AVci}p z4}tRqwB()}tpYc?;cmDZbF8AX1Qdu!YBeOuLQuN-lRD^+WNX=2Ig~JmPH^t5LSLbK zsLIxu;&SQG0Nm3tVAdjsZ~)5_baz;ZZonMM0*2=YLwf+~&w+ieg8>{}Ibc$OfVLw0 zoW_T~Ql*NqX;r2K;IoTvj~aeEP;<&ku*rgnW7NM-W2~^btZ8#mvns%_$(aL{(TK2q zH{p>l8Na=jO`_lqg4eg1YeE!EGPtz9rmv27wu`z7pg=mUlPd!mU;gUIQCw6n4R*^G z5#zMDR&ad6uYiUGDNagdj9Zk_kt56tctp&E++Acuvfr@Ooii7`ckE#UxWG9mX85j2 zqUT>9!xw+!0s{d{w}>!3kUojf9I_zUe35HCX04!BuewYKMKeRF;1k%sET6^rnMZm> z7$drgYTCHi!%a~b{}sHLJO)5~v={d=eEIxi|K+@Hmr}ds^S~LErO~Gin?Vz{45Jt< zA{I9qDYR61ot_``4YNe+TVrUCGL33Bk{jOt27n({s(ipk=c|p8KdP{P2hPyH0;2?$ z_zgK~!4ii-IBFDqr#C>O2c{?16pV!y;f-hn8UWxSus5gDs)3!#+Mu_>7G^F=-mGkd zdt~rc11!!$$l5#k0bHbV4hbJqd=%T_pk%Ut2wLZBKb zZ*o=wl@YowmhBH6I~)h3NC+nPg*Y5;5swkWu#j;XayIv+k<@9bRn*L`?1Ao3%Uc}O zjWDvKad>abBOT_SZ-JyPgplnb-n&Cft`h0aiY5!v6SFXSC{YHW#1yh0v>5I8t#x_> zBg}C9^)ANVk1i2lil=ty_5hbmt_e*l?jG1A zP1Ew6YreO_hW3&4Hc;FeFK`J0%M%Re_5^16yeu?1+!!In-Ix!YDXlqeqi7|z%f<0g zi*?CRlv$t%RQ;W8ZEuC=%Ov7z+8%|z@dO5Vi+0U=mj^&{4lB*I2I#Gg9F{>97-KSt zdZBX#K5(uO8Pv)mTm<8fGYSTsje>n|h`tMF5QeCD=Zt=U)E%fV`C1@UZYdE!#az_{>Tyt5b@f2ku$#^Ng7x-9bHtnxh%mt5nPD7+;EcOlv84U#rkRXo@55ckQGhFm$pVWBH zddtg=7x7VX>WG`_&rE%uEkEcj8~a%=)`}7RFzV?}+1;7h_+G@66g6CBXreovrx zc{z^P@?1?~l@|i-02YLZX5<(>`=W+LF+!RcGBjo!5Sg`1fl-Qc58p!jO!Y`15e-pA z&}8n=EAX%L@WM)^U`A92?7+y=2KOxK{!Z!D{HYIIv+*)cOKcX|;Hk*n2A|(dE()k7 zdJPp06ggC?F>07!wknO6)p?E>nmc<05{7o8L6&*2)R9|W0}t>tpOFG^VF z3@^F>i@#rwJHs?-z)QsF`CnLr^`CpF)Yy)W;pI?g7r35~Rh;@!1l*o^u9-GrMcBhM zI+#aG|ET_{VI9B3u4&9ds!nVNZ8R94yWXUtL=tk7A0*cZJ@}-@WztA-dW@|S32+%! zd3Hq0EDO*CZN|X>=ZjI|vBCX|5a69?@2^aMiU#om)rb@gbxYBYX&o@4#h5PUVihFT z?_0gV55s!koPqh`^$?>yzwcON%~UAtM1x;7E~@0Yb6K zFyg{8>;>7R5gvz{zhPMmh1YNgl9=JK=IQZFXhYJ2`0g-P-C{LWDDe*Y3UvcAwhUt> z8_~^(FL7n-n)}zn|7fm4ra9y56)OfaJvilrZz58>p+4%w-qGKFuV``o82?p2!ONE~t>tSwK;vT>*DiGGR{BBBy{~If z?!!xWG;;dSPGX!U;TBD-o^$R-6wcuo%HwfmS_oT~D>5`+kndGJih`RAoG|aM){uxs zFo&cy#C8!(?{wNQVd?fR_+l+IBe>H&QUt{OE3<6K$05gKru2Qs^Z{l~-I+^4xEZ6# zjZcU6IE#;cvV^+?y{L#fo*5*uU~a#+O-epjK7GUjxXbYxgcN zwpMJWXUr0y5M>Xc5Xf!h1d;263F6^MUNK($o|r>mP62m^Yk;$T~=Rdw!5G9HxIv0Rs(YO<5h5RBuk2UUS{k0-N3gaPLmDsu9~a{ENt1*_?cPa*5p;< z+}dayUQ~WZ5@aeB|B~YIctS;30i<=kA(BA# zjk$lrUf_U-d&3wOCkAL^|`F>718aC znUp7$U%t#jmGL-(V=@J6mo0<_D1{ZVD2lUH3>@;|B?To(63f^EoOT)%=Vd&XIq;pH zf9{dB?g#XQhqHu{GkO+3lA3|z-(wv5cEZVnTRML{v|SI69>*+Pd|a8db^kX@9ecNf z^DFM$wX|cj$cm|7HEpe{UKBzlhKQX9j^llb;IBmJ_fABIR9J7b*hO z7-c3@qf{o?GCtUk?8sTx_EU|9&CCP9w6q7ebD8}$=YGySm785n&M|zbnmpet>!|b9 zDasf>$(%gEB==`iUghPI$d9C-mLF}oOk3l*G5SnP44>t@b|!StoYA_*^q>ek&1#2M zqM~uASA-Xrb33A=IK5eGn;%9uS~M0pp6dd7K6?C!>T5YT~lMU$2 zwe{wVbRG3pTrkZt?WcC|2}5ooIqw-7dQ62DTEBEywtkAee=(rvzl`e22ezqH3&Dvnk!p1ecbnw6lCaI~Ygd{a9E@9>Pq--@hvu|I) z0up7QE#MXk9H@{WYUdPt>|OUO)!RAQ6{0q6Fgf$h25AGmTz?vmmaW4PPmH4u?KBz& zY4IF9oDCxUI(aK(1#3(&EThXw4yV&72IXh)=uBN3gH?bco!;fAp&eYx8A1Y(OlMYV zk8ASpT+a>Be*27k;qSi%&W&e5s|U^icV>nr?ThmhvC&I*{KbtbdcvM6bjEn8 zrVj({UYANt(R&@s|J0Zt*}Y33kov&yT~aQEd(Sb|Y&MrVoy`1i?dIa5ng6Zb>@=62 z@_#+X2iM&kR|ekKc_Avqui{mBVJjH_I>TJ*f{0LSek)1~rk-Oi~LUh)|{y^?k3 z+Kt6Vb53~GphZ{}z(ets$iWgg=Pt0|n}#mSDd{Bbb8`1$)EuGe~pUrK*5%=;_u+igAN~6C z_Ws_*&xv8ORB9O`Z9+d=-%LGJ1`|fhzSJ3*$s=~ce|kUs^M@VxhrMsEfBtdnW_-2Z zZQU%b|GK!jHvYl(e!ch-4&Jv%y;o=bL}Ph_wO8C80zUpX%7WGTe|5Z~}b&4bbMRIsW!Gjzm>34Uw$w z40z;V87}#cIzh`vXRF@5c{SYKfA#LC!Iz)T-1X+QyRaDiXn!C6qbW$B#M}sfG_!j8 z-1{e%|CKMu`)y$Gx{P z{rYcqI?bo~e~eF({|iOp{@R#+{@cyg6aRmdPxkzydg-2fe&F1-jS2RDv)NgI`EM`0 zYA!7-zC!-rX||eA_Wxsi8c|?hxnbjGI4FfduSDU)BPTd3^?Wc(>~rTy>;F&wWUv3t zjkWIfe)k^QnCSm|)r_tG1$g+h{vYFWaN$^68wb{=+jB69Zv}o-OQkh`bQ8Ge7m-!z zRV@(53)aqW=i>nW_T0$6ER}YhV2C@4lmv)Q44mFr=Yj1-P9G0WIu0IXK%AXpB&KiK z-i-x}C4>t8sW{SYTRmv0M28*#Oz59Q*BEv~Ii|zV@3}Un=n#3(`QE<^q-s_0n8e&Z zuQ6ApM*5CDD7h>RoOnfh0{)m{y>Y_^Vbu5y2iOPkdf*OS-U3#q;fEyvI>yWi*w2~; z>%=|7e;pduXnZ><73(O2~>WC{LaNoFO)2$9{H~}_~8G9qw9$0wo0i`*M z4YL95zwcW6JMRvDUft_j8~fJo-p)@O>)my0Zgn4i&(*A-HxAzK93EIuVsCZ(;DfdE z&RX66VEwqUy27tm4;s)aJhQq#!4GTy{p#i>HdR_Zgx>FA|E#s0-4A;k-@iYw z-tTO#cj4jNF7#~m?PixX1%q1KT;15JS?jA?tKWC2)($|~D`7F#JL~87U3`S?t-^n6 z2OB%vIE=NO?Snn|S%XpT9muLbZ|rw#*6QBIJ|g7Z-p*F7gy@7CI|KykZFdbYe zC;9&93)K6Hj)YS2c;^N^RTU&(UycC%Rp`SJX@b%Yxlonxzx zD#@#Q^XqzRsZ_U4C}$1JDi;py@Z!XxP>+D;?Wfy!Mp0;;;P&PThU{G9#YA|7jI!O} z)K)^hkp-iX#UhRLY!sT;C@blD9STLjGgW6`Mj^IB4SqWTf3=Uo6=mkcmQb7O<0Txb z_mpWzB-ZNnZ|rQ@lk#<5gyeFNiohpFbZK3&-Z7nG12i()~TV&eyw3_Zwv8lOX}(`b?sg4?>H zdrPfZy0_HQyVq3RTZI3hdwZ0t2s(%nAT0S2sXGj{Fh#0JI3Ce0PG^3Q-q9^kVu$0Q z3aJyo@O~Gdge52>F+zACyvXb`q*@Y*v>GkC_rS6HIAJXf4V{^0se`j5h>DMm4a7MI z9rwzi`zwS-jU&R*20SPWzC z=t@hYuz}x)4minCqjVvQKLOFvA5r$29r_&ZB$74&!<3hdtjlnY|87LM>tduVOIKhm_ zw32z$d&Bw}@5fMV+Ac`|qD+kd;Nle04vI2U=-lz}A_XS>SZX<%9>>PZ)$n&o6lDpc zM0aqF4O~1_D?75mZnR9LR1N$0r0n8eJpI
vu^w`0UC1|pW0Ld`rur-{x}@mWX{z!@(Xz41lSps&e;ukN)|3fSNTM` zq3A{yL}ET85`&Uk#*pl8Ltc_jcDR;-tKc)X z?y&=u)e1Agx)`@h$4j01)vMCC-;Lbw-h7Ki=HK9Re1^Z?@Hb>{zhV3V>0l{A2Ti$@ zdSIOTLt@&@0HAqxWKKhVkC`Sk6+KIe@dpFoIFufy&xePZ9#~TRp9$;(p(-$+0uX^G8g%TTXb>qC`MXU6Weu}%^e`!RNqis% z$S`I1y#ieRO&CYK-(rbCFHoinDRmNR?N`{3nl;5R-ul3*2~Q5g?uBDtxj<`dmfYW{ zb3!_Ew#ewZuMssePA=gX26R%TkzkH$HRbH2Ti6RIn+JkNNe?tnH++c^o{-o%vAFMA z#~$Z5i<+@UbVkbd7OA0}Yhh-ch}npY9iloMx0CoVB7cO-lDXnZF89ZvY7Fe(ZUnec zYuTXirY37-6I^e@cEt@8>>3CX2tvxUXASEoW=z>)E>0-NG4g(3)$B_TN)GVLrE_YZ zatRQ6_N8+|!b*Z9&5bw7tphsw8}@8u{;&@GpwG{g;LwlOY|r;xKs`6znqY@JJ@+s>+9>r^#b`d4)*5T&1Q4{=k+>>=6bKy@zAZ&Y_?k8G%ljy;5izG)FiZ2ZE!ii zIE#Y6*r{4fMgMwfhU#B0RZU@jV&irKoqssd)N4+1T$Lss&tKw3j)OUy47Y>Kc^W!{ zvpTvcoW5#E7qLg6>fi!g!_*jR1di9h#RGHV+Jsd6HBW_}Z?pX7RmLA-X2Fg=IX-@K zf*Lv%5fWIO_vq1Oj)Bn6m?CxzpEut=JE9s#Z%#M`cT9V-#T+(=qdqa3R3i=reN(G0 z7QkY?)n-mB4Z)tj?vH^5bUje>VHgIQ89&3t4ZkoOa^Pd8W(R7bPVTZh;gE(%$;VtO zjD8UqqL}xgrS}1b(2Dt-_`P#oWCso+xbDIsXFFM_!g?q z(-!~$UqIsWcX?3gjvNUFK&WcsA%Ig4rTp$_+>H=x82E(R=a{qi1aG~|g81P4rGu@97Eknh`IhPe1uY&Cft~Wc|qOP?Y zON~XnYfT*8VdzLB%nfM*PIQ+Wx51#~hUOT97kL_M=*Uf1uAFjiR}Qt#bW~>+>+M&Q zSjPe#Zc)`264l?1ha=6~c3r6*3qIx=kqyD%J%i)9_$HzH9Qw$Jr9r!%eFGvtn0!fi&lcD=^r7p=c zPTerB1Y*eJ)*6|x`#_UDzPUd1K_;UO$8;fffrjY&qK-Mv(I*VOtqpzA#2lm0{OT>{ zOy1{$(x$DNzJoX0HXC1SkTs+>VOA$YZfYItG?rBLR=o}5`rm!z^O)r%nSnvAX<}da zocZ-J0Xtjf(CPnWa>n%mndoTsxI+V9?SnQz8y1ez6tpWk={g0~IkB!gB*GRY!2s!V zBDYwM9@0t2binf3_4@vGsMseFmrF|aK0os70_iYvgU+eDsb~bWjF_wN0xuH8TvSZ3 zL0Q*hetpS)sY)YHwVpRO%wW*6p(fTi15H*L?Tiixij&^ zI9+Mw46n&5QUt95YZ<`Wsl0{J7~2Wa1t*wubTtrZGO^7NshfW@i*EjnJ||7Ri_MNg z8n$$>K=%kFn%2*E*+dnyF-a&);p zaL#RzQzsw>BzvOb$|4b-TIre<-3GP3+33{Z&m#U=YM`J*JCNKurpK0a0|M+3#^eB$ zro4cr+d@-UD#k2Jx5EgBZ*VikLg^`*%y@-A+uq zPQ-LqqX-ZgoW$^@-u~#^P{j>0o;l}Dka>cU%K?NEOHF+iTg>#6js<|r?zLvVb7aJT z3YSb*9K9B<%k5KrU9`;Q#euJ}{RWu_N8e63JEOT|J1jKYM9G+LUxV39z|18SZMCJe ziTj}ZS~Z#|aa9>hZz`>eB+tA6Wr()Hbw9XP^a{)YwFU)Bx9m%YMX?=HM~RylMnxzz zExnrBF0E+W2o0TP>1}9`B5hBQ$;9_3Xv@h{F)U3@sU~b{I=fQS`78so3IhKe8N|qT zgHUMd=%}NeQ!XWDQCZvHRFwc@)XW$U*O$Q@LRCt5OkAljvw$2$0c;XSei+5Esx5X* zK*O5D5Gfq%m~8gQr!1^0Uo=}lY|GG$HV~s-m}QTAL2i*ZHG`y09xh!1?R8hzx4MmC zpKBxPwA_hSzoqJbU0={0gNkC%5ls_zW?!LGKElxJ;)zb{ zCw##eYPH^}1=XiljH7N~6b_HRJ#mMqq^OB8QPegn>;5&Vy7r~}6({BtAfpPeNm$+O zEJ~2Eq{8r|?}ugOBp$)I16E!Wdz45G+9suBg@QojrKO1-__|4Z9$F5d%i#V8%mU0a zzJABu5(bTM1hhyVDGqu*wvjw2fF<4yVMQ_jd(ZaJz&X|89qdR|8aP+ZKx?p>(I8uW zC(O~qZY4=Ufdr%iBNZTw%fPY}3I>#NLy?&tZg~Raa)|a1#QeyCa%?iJZOXS`Beu--FnW>sJAV8cbb$~1R5qS`Jj0lg)M4}BC@z|$Qk8Nt^Qwzh| z$%l@uD0?H6+=4l%>w1e=jJyay(t(T9D7R^~m`JeOL~tnXUZB)8!yL5ksCC<1WSezr z-3IoxxCGN5iS;Mcj3J7oSOmTXSFP)2htUJ!Nm@p|z8%?OIGha3jV?2kA{jm*8*6Gy z7aIed{_mO(=oe8Sye=yJTy)5qYUScK(L$<;&eYwZ)btO8bYk5RTcP&3jiiaEUV?QP zoYsn1%uVw1v<&_bS8OPmwsNr&85%4^gWJ*J>LMXcXH+LoSaF;aLyO{J4BC34#+80l zx44f)s#(U%)F4fe7>)>&@Dijgh-vK6E(izA4Q9Q-$*ELA)T$=NN%-QCR7NLeMQU4N zsihXEU<1yVk&S8r4_g%UrSG&87{0M#z>(?K(X zY6?)T5X^@ml&wU*-3O!^lFij=;G|X>Ik}8WWDOlPFEd4 zR~<%Io!RNCBj~Eb=&Cb2U3CPmI*hJ5v*T((^@?z{Fng~SM6VWDuNG$S6-68|P}D0H zfiyFy4uT>WB_2OCGpGdts#D^zL^FeG3s4Is9yv5KsFncLF7YU$nL#xLs8)$b6wL@~ zQ4Nr0aB=nlE{XvzvH>p6KEOpWz(qE|#n}hgfst`gG(e2>nHkg~0|hWjJT7NuP#pnk zvBU#aW(Kt&Ky^wyC}n0)Z2@Yb#6weN2GtUv+9e*CGBc>A0M#n-0FoI&Ehtb#3=6Y^ zYKs9bFi_hvkR}b5EE@CyxOyiiMG%g+DuHeXV)3pLgKWU&d{D+;?Nea z00q5bTfQ@cq5%?&65sHh8B|k%YL)m#?~I_hVbWq~Z_RF)w8RXym|@bIeFj@%23u?f zTeHt#Q}C-6o5AMn{HiJVRg>|n=Is2cDfm^B@vG+S{HiJVRg>|n=Is26?e+**ge= zJi0WTr!2S7-1hF4$Vivh?UTKwOqwD^)hqv%)NKI+CKfJ$&v1N*& zp-WfCVb*wALhuZRHVNOXa=qsgy3=704%VG3Yh9f~%kNSjfcEG6&ebfvLd+0=dVe^n zS8Etrv&IvjXU+`Ej6N95gd~I~0U$KCGBSHrdj9;mwSmzTg8@Z(EVDdE;YA6zN?rCw zTgBpN@^kAjgi$OTX_3UTUJ>UW%q&K)sSrGY0)pyzOo&QOzw(~Q&~ zz1Z<4*TbA>7{8!qFg7K4e;5K5H;Jhx)!ky)A^i%o^56A|so@pqT1*Pc!iYup{asag zj)4HYO5r&~$TC9EybF!pCMITXgC!>N97mz7T@bAl)?D}(h7db;*95UAr2EeeJIq_8kPsEhJ z0N&i#vm1P7y`bl}Y+w{0H7#B8aS#nXtJf_x1gl=Br`RLw3)GmiZt(BC@w81(JF%w= z^z@t9(+-2M6nnf#kK2oLlsrLph{hz+e;r}&jcLNGv3yle7{*eR@SJktw4mm@ydr~1 zhm%p)9ynh_p1SZUNp*oww*Ie2-rTK?3Htv+yWNT1|I=A$E+Hef<+k?FF$;({Jjii7 zvjBkJA2~gIX~GQcD~G?qgPr^--Mkm8P~x|TvQc7k!ME7|BUXdo*odW$MX7tdGIZ_} zOkFr8;s6ufah4YPZKt=mxU>j=UODaNS*O=-_s_nud-l@TOQ)@7UsUA7$f7Aaflm{C z7=jd>Hy7Ca&wg+@kI9)n%)4E{)qv%(vnx zKQ3c{&{8d6PgCrBZr;!F;#cdbS3L7zesL`nyVUuGKplI_T4Gn^YOlDpgU{tt7vsZE z#{=UbrCec8B!+nIQ}eEAEc0fi14@%DcL7@ChZS1A@V;_@FUAa8KtkQvVBkk-n(?Y|eW)RpEs<%Q3UnL5@cKD8X zFJ8>QXs|jT=d7>3vcw$o zlqt*}7yvz}E+(!%e!6D(Q9s%GACmF?v@yf|kBdv~r~4ltV&D7h#9ph>YBye$RKoPCB^)I{ z8Ebfcrbge`xf}Yvez3k8MVr9-#m_D~mmz;*lFA$LYujgM*Vu2BR)hWadj}v9>AMa^ zWy#)9$pq-lo_$@jVpK~H@Hh~CVb9*$A=m!d2~umt(z3$C0;utGPM94YbtLi}fug{Y zScy08nNU<2Iphm<}3e|>wta^n3 zz|wU5TOETJ(A1;XtgKN6kLxk$;_atTlqK)er&I|1fR|{L;fD_oD*S%ifFC>8-Y!p} z_qqfn%xTjd%Z+*S9lFtY1vanA!tA*!NFs~8K%~)#H#mXiUf=icqTm;G` zq%T#r_;CR%2(LK+TGl*M`3g^2{+c_&OKC0071@x-!!_;%&s67-DRFk?)~wGpYv6eF zr&R-#pV1%sivH(N^avgTL;%zf8TQ2+;&kXAZxR%mxU&X)JC82NV~$Um%Us)2U}?pu z?2&u?+I-${!%aJk_Iy9W44ya?G)+aRTmG-!nYvt^x|m4YGsUzBLLnW z9UEi)EXUen18B+7erBU>!MDuewvIk);|*C}vkDDRuVJwi=g*jEk!Pd*vl#cRE^Ad} zuN$LrctOO~(DF_(Sk>xlqY54Pe_gO)#%(7z%F5lnLC%mTHrQk3?%rT3cb(Y$D6Lk( z&hS*tlbR4mRTDsOW6OezWMcu}zMjN4)H!mEalpf>wk^nWP)Od?pz8)IWvgtx#4W)F zoy>h{l~?A(6PES|9?g}jMY}>L$n|b`bk7l`%_z_v_5^RatMDq&yiCxJ9V6!zITql} z@$nmc#&GQQ(N{=cqCi>#h%eDIDs27x-xebSl!-Z%FdfxATi;nb_^{hm znr_S*oEbm2rR291j&*z|QTf1<(vgml$&wP3-CA5+B2o;an#NE>g0f4RSFD8G%odxh z3M!6L${3TPv3C`{XBf7my}M{Roay`+<4{r($>pSK4v4e9*iAgCQ8H1f*3@Uev!H$dJCBrju zH`h}@n`HOsB~!z@TgM`{Irk^*nKEbZjl7<%9vp0L>>nrs;XHVoFCz6qYHK;KXhR@D zp`2m-gcu-q(=*h+p09V`tsZV3lnc{t98R{%sF$1sel8V$hC^ohg>q*Xt@I?^-=udp zyIb9DZPLBOl$w0vj~TYuT)wYSZy#(Nd`R&zk0#Q{{}nM!%T~IzH65p(E5|uTip$Y7 zSBiK(@7woT!25Xz|EDhWWdk0m#}gaaraZK2DyY`PEwaZYZ7meyo``#U=V0|sW{B@2J4?;ZQ~d8^d}fXR zwZULM_i7fuN*lkBs};Yz7I(wU%XY z8S;6Bh6)>WgY{f<&l=Ag_GmP?snB6S)vS;`Cg)H3JbAY#x;J24yQ24HhSz>rPVH1eDa26U=0wngpF-Kra^^=k=aF zgJ-Bz@hQ=q3H-V&HX5o)n-53)wm|{^xU9Fz@0v|-ld>3y;EQ+%DiyZ3gN?I0s(6C} zQW-Z+s0==3y>IxyMJ1nj{)_vr z?xF%t(EpYen+q}hZ?V-}deZ+M<8z1eU-H_g#QCgk@`R)-f*5Z=4D9LP)!hzWF+D*$ zSi_CAak#X8pxkheCFIgi;)sAkUP;m- z1E)%H@E8y*%V5ozJ4^cA#H?xI`V^*}Vhn15T<~X`Xn_j%_niTc;S$ZL=SpqjdBwQk zRTxoa`OuA%LF#2<>^Ko|6l>)(CX~m%#O7SQCH}~V$Ai6E6QjLa5+nH$U#%lvOh3_; z)?rx=)vzdHb5cprlU7$m@fhc^7#9{nPcXDDNZg7k9Q47FR!lG{AyB-NYdpM%M=F?o zG72^LjfN{)7ZZAYO7Gcu9u1Hha(v${4p{RgCuutM^bX@@u?;9r;@g7L(Z*+jRi$tN z&Ti|i@{ZD^J- z!>l;~9&5<{<^Gw>9j<58DSr5~5nj5ZZ9w{}TGkjGnjNT@;Oi{lk}DIsWaWZMCx}9u zV+ANLpnCvrK#{*3SF`9ZgYZ~{?42Z}dGTpdM&{BhwrF}P(uvh@m=UPSL4tz7IWd}H zg8Z7|_{1eCHj@Z5AQ-W>vrVP2qxCsVoNdh)~89sNgQk<@6y{= zOF2o^`3>EBGiuL_x2A2E(N^7m*hbkz`+u7y2fIrf`S$-p>s6-}-~Z`6?f*Q^=l=7* z6wKkmd<2D(xv<KnU*WOs=9=cPW^a_c&#-ox1yC{)n;6gJ(PRConOwzqBhP;7 zPg(8~{RvN2qCd(?P9n>s+3nmh5T^#y3dcef>8H_Ed#PocR-iim5UXSva!D9L++^fW zV+NYQbj8=L=78||ftfD%H1(3jy`$HD?kz||DadQ6;z{4gej+^x#Kc&hLla^QtT$%VYDU!?ezpJEm9&x z$7HdXxgYb&q$tK2*1sTAiZZu3!TM51N zUhK>w`n$^264&293;q3bTz}{J+(~)=Y$)&gWEp2yuuA@EEzN99^fVJJb(q_bX;E+! zEN$)qFK%ULZ@A-5Ge=2$lRaq^$Ba}_8@E*x2C;4uGguX4dy?%Ba{0)fq(j#iPa0U$ z)^^W5KX8EI`M~e|AjDQ;j#PfR0$8>`I&{Jg2Hv0?tw4}@W!XMuGv3X_EGyFjA&28r zfR_uH({7a*h>1f*6EUBHGeVB;&>GnQDy5Mo_vquDW%Og|iH@{gaqCj%Il7Fm9>OG&R&R#x1rEH-%Uv946(%>?lB2af94hOF8m1kwyMpMDMbf40#%x5ntD{qwwvR*I z%c>KOFetR*%JMyZ+IeYR6U-q1CeXFxspIg1>so1TOVlOyoQhB0>KV(i`CmPE#_8$5 z%KWjq*&E=lxzjzv)bJMY(kGe{j)l8U3I=@>;&V}R73hLP2 zeNyF2b>H#rcw-}enxzy!HlDKAuE9wR_kemyV>LHri*_<~V=vanL^jPSJ4t%;!}l_o zLvz}G3dQ$vdYV*Tvih4U?;c%~5O#rynEMhuQy?y(IQ-#wn<&Nqc-+MjXH2;?_Rzq3 z;AP<&&Ux8WcDg1t3JGc)@VD@lf^g`Y+Ryu(h!Wu^u+oAQ#n~+OCEs;y#?%-AVtV+_ z6z*r9s3qS4&AV2>1uak`E5$s~2~$+onB<1$;ytUss%2Lkjhf^;j?^R`2&id3WHHHV zOtMD7u_;1%^k^+}%abju)IBG@&`i2lAXAo{20QOS`V64z0z{ljd zT5l3E>raEviL&d@h0~1O<2)aDO=j}0X=%1i^!EK;4KG6mNTPjsBnB-)sMRWFMb)C! zHn}SVE5B`B_!#$1G>>!cWYEL)VwF~6olnO1=@(gyz3{?4iz=*67JI-dEJHS0g79nN zH2A$JmI9m-ZotsZoEjQI6S8@)ww9M-|WVogw zano++cugzu<;%|rv(ZY)>_`FpDOvc$O&EqeF(%tRW?iN8I$9w$Y37?`9PU|r(qPRk zI;@ehN5_VHnK9gU`fyX+Ju%u8EU1P(;G?O|GEf65iNrXxG)URhJszbyx2ExA9SGkQ zd3!+LfiL3hiFF7I7Wx99UGpM()SJ-jB`@J&rV!1Ed5XH)KBdEejZ~>+Li~{E>$3r}uN<#`caHUr6%3B=-j@`dOe?BgyGdBp? zDlD>yH112cKTR5^7jxj<<2Z3MvED*~%)Y1AR~J=HgA?3mn+YW^3!uauV*KWMp=-qG zh!U=Nse#HTTypV?J7Q<4R52Cesjouqy*w;vWJyT#T*x}JD5lO}DxbcN=0bZsx!Vb| zwmf-nILCFJ>$%ojAzymN@rpS6wTl8}@fF3O_WWT{s40%RTm!FwO{c@3WK87>rgT1& z&a4aAQ8U<2Mq8R4RKx_z=}Tk~aJnH88zxq)q^S5g3-pg#o`1;Ve1N6-5DW7`mSx`N zfDRSIh6*n9M_cCO$%}kEn!LQ342I`#*}co!2nenS}m^5RR z)N87hN5on&($xvsCXtls!HAC#mo0m?V|J48lEjC^gApox%~Kb1Ea;n{8exmZlkj#V zs!T}v?a?WC13;FI&dW=sU-Kbonn4Qo?)990Uh_&}5WV;hKiU5DDe{@D|H&&lXVw5G z=zpDN>s4I;>ntoh>3@&$xr_cMDMM+1Pa54lXmkZsvsAT7&PQ>@Nt?n6s*@}!Cq%nw zNOOzCezM#T@r!@VC#D*v_{}WI`Sjb5rpZ8r7o+Cq=`&7o&jf!`mLt-L%&VBD2aR-> z0XlL0()7?di1Y^H@a2w5`FXiYcSacpvJ$sS;hj==1xNfvp}{nUcGSD5%>S$Me6RbD z!;QV}`oEuVZ0&At;FotBzu-Uo#;WSy=Bv4b-|(*Nf!h~7;jv|GNyC~0RnzG&Te6{= zC0c@S)RYChMzl5=S$MK7Z$MM_e%+>X8=8DRIz=0*o`f zukf>@Vqyl&tx?GqX3@~uIlC!T=QX+y5UXVw}Wbtn-DkNSk+?B(p+m z-n}@~dlmM4G%T%BM))aXNOGQ%6UD_lRY5JZM0xcp zN2iJHBo|X{%yply;TSutX*Ec=AlZq&Pg*VxZ^nzkMi z%d_+&I@*b>WusDdD5QD*d2$o{6i_aBeynLq(3}LHpT97Ynjl5;+Ca{! z05Uf5gM><-v365$=zxa_wVvH5kC&oQ7MPb-d1X#K(Qbz?+HNBKN9vX1#>Ll(d&ZB* zoH~+MXp`{-Z;p@E_1DI|(*?Sf%=a-v$Le(}(J8B5pSf2V$5T^#Mpts`Tr<%}^%9s{ z`P=WnP!gw2SJZvv{E0rR+Ib@pk)4*TfWehP+Zs$+%K&;C2d;v=bHJ-YS_4|m)F!B| zLP+e=^zYu3UndI2E-s&Tef6b&IC-&Gso#Pq_{3f7n0hZcTs{?|b|d(;IWI zj)OibzcwGG&9=}q47lp$Y|2Kqx-miFn4ogxYXnlqP6*VPTA;RKI6X3Y(+~6)Yft2x zpV(g46udLHM{0h7=BV6VTN75ofMYj71Q+!YkPUU z$WZ-K+_Z<@rRQIJ6evI^Vv&Wj{G!b1pxaAE#!>b$@;RreiFy&nhmNO|Q4b)Z(ry{Z z5>a#up^{UdjYJFVR1p(fdfElBUU4MM^)4;EYp`XVsEBw=sTMa6rQU6nHGT35Q-&=m z?(|>^dkk*ksB{dB{*%*L7F_LDtfZKE!cx8{H;iB;09FUJPAMaGfv$U+C zWO?GgMK;CxcP*MXe(7Xt+;W#{Ii-qk%6^QLVZH^#1UE`jnuZfw0X$O{yYySFvub>t ztapQfe@*H9V<+fonZEgU-oP(gimB>+D%nh0*7JG5l1fv|#LUE7i>@g!ULQ4&8`*dF z@zKV0qjU(dLgi_2l$sWc`z5@H4Gq^aLJMOv!m_Po=wumMS*w6rmXmHp^pJ^x%sg%E zlVn6MU&e(}I!`lio@JlYz_BlL07`U+JOllBg1q#~4Om7LnWKJaQ`%MxQ8{0&p%B;w--6dn0D$|GML*LwB>g z)!o)+&`ZpZL32}#s@N#R{`>t9Bn)Na;6rlfVU#wn|Cc^{Wh>Pvp2+6r5*SPRu1(9O zh|~P;Zu0_;^Qm0taY@TCMH*}x$Zd*VR48RZdT~&Xzkak}j{Bj#?VW?wgN>c-3FPz0 znP6-g8wbw12?@7F2@Tu z*$Q5vJXdmVG9S6?!`O{q#xy6v_X@ zb39wxGYiw7WN+;b1pfr~3W`MyI*c>mL~ zSc`i6$Vd_hf1w^|2hPP|+r)|UaqLjE97ty2wYRh9yN=-|t%`h^D(kt;Y51c_5VLCq zwQK!itXy8W7|1(*vc+ve*wV#4Qp!3`KeTK^+A`UuQc|8@|`|`uenDqbX+dvrI_&);^ZW_W2V_coc`fP&jfN{uyR5)TBYAdi-es_wDYF z0lin_nj-9T&1!6Y7K3`S|5qtavx?X;{Bcc#zvx)f{tT-?k9MTHOos(V8J^sxoz`Wi5{IB%_4yWzQi?|<~dIC zJjlL@WG>99kmxdho;CvhNqdtXJI;9qD?mza;3g$rI=b%LmYvkf zy-L{hliazoHno3$A*uW4`4r6mPIrbrjQ!t&ADwvqcc}3s{~zOX2l=mG>`d$P)HOx@ z83>J`Q~g~mTm?ow@)~$G)lG#ijSJ3cX9t!ltofoMGCOy)xVAW%vLu-X+PoB3+Xuz7 zUttKXZ93=nU=3&hAmT_XY42*5k>Y`?H9WbOasGeey}>L<$Y1xzrvs;}Y%{@1{aviY2k)I#=TSoDgStevY&+L)r=TEG6|pJVQ2PF-C?pes!3f zK7gV-2k?+pnFn3r@bpyIO7z5Lh=3#nUS<~#VrdKRr3*a$OE>Jdw}zR2;fqWR{H9#JXDp_q2QJ)eu11Nw@apvmSKqB^Cj_jX?RkDg zG;0H$_i4G*FQ88z%j2R3k;pl6*Fne9Z5RU<$)Qt5JP|IxH*XT`Y@8NpLEM&iN2-q^ zjlv7IE*0tr!JbgE?}HXUe)p!}Es{#XH4F~oi4zGCUKJdi^8d{|yl2|@S|1xn&H6XT zFAI)R_$9sZ@YD(JcU+qIyZgZYb+lUlr(OT;xbodH{|e)5e5xN;UlhFtC?6UX)WpTaPiGO znb!lpLQyCo*!0oI=Ew27ckjCN_ucWok3Npqziu|`@XuTLUHR@AK3QW=utfFW$kG30 z7W?H2i)c;!7JkNr9r>L#4+#9~ zg72@(RrzZE+xc^RJcx{^Z`jjw^XbQcJ%0XW{dKvhRwz};zZ??g*wbIfehdwfK*KlY zb5A^9EsVB!ZVkeo@Pfy2Iu6YA$>~|sxylBt z2+J&IBW?T7{%>c2ADR2`RK*L z0Nt>3+z4esgTh|KfGhxzW(-0~4s#B!qk&7!bZ)@z=&;l8B9Mqn+-Q(<*?}Bkv5q(6 zl0QA`8yn%G?y`*)i4AWN@n24mND}Z0OO2k4z)5zYtf;~~qiQ4sw#+oaDT^akkUi8K z(@WYg*;Zh#TY71tUwWyKV|r;;&$K4|lrj>U&Z!B^XgWrNgPdb%n?ocdfamj~_#_fI z#cpyz8XPOhs?tCg;!Shxo8C4MvdO6?ai%%`H3Nt!n9rEz*tZNAyjW4TG?(%?19BRG zzZQp@i$BX4X`PHB%cP*K2tD;?%6&1y1*Dal;Oi>K=qYJbDO47;ss2iz ziT2-~eSOyi029yuCG!7t+E3>{9_Mo(@t;5pSdu;2F`C27LE*O*8eM_vRZw0$q}j+4*-$us*80IzH=_g1h+Y@G zFOiET7Re|Nv>VB3mY+!C$*H8(#JU9 z7|ZFS-WfT7_>O)e0T4dd3QF=$mX)uJ;_||mL}~WMESxcM>XlJkyV4_3Uc6HkB)Pt#dDyIC+fytR=3?r9`+#ObOD(BoYQ)=s~Ow3=fGBKBo zW|p$EsoL7D#M;ptGJ2nIRJ@+9Lk6&PUCWQRWcX7g^z?3+3R=7qX4th+hfUuas57T_ z?-Jp&1Vy;rqLIRFtP;$%Q3q2Pc&&b?T02h%BOS9}hS**}(+v&(2WmbmLShwRy+ z)H8UB1g~13veu2djU|nK^_f<8`WnmUC{gfO*mhbo341c@jCmBx{8G$in!1?M?s=cE zo+Q2ND2|c+cJ|FHNf#yK6*8ESpO|5Dq@9_W;OOKbFnuR$0O@|vEX3HF`Vd1+?A#;2 zVrpBo`jhUA@@mn`DcvBn{=RTos#z6&-EJhRVGTtNw#S}Hpj zpd+d$gvKzHkw~VPLUXySL&P)W
c90&1F2)lQL#F^L)l$EFD9v4yL-5Yv-(u%&6P0R<~- zk*23{D70*6mZ^Qiv!~cp@$_O-tk@K*K35mjGe=de;W&&?AB`>?>&y+pEQ{5gp!Hbx zsY$8RCUH`|PY=UUc^YheI?z6^S(I2CI&0nrnvZkl`j}?dP`Cn$_#*OWFY1d~0}<<3 zEDVXJZ<4vy@LIWH5p|KTS1^kk8KV|$jpIEz-HT~U**$Y(AL zb$!XhtP5N26UfnX-@>+Oj>mqoEiWFfMj|8mZ7|c6j%jMz7 zj#}WDqt!P(@i7n&gMm@^aZ!N5oPRD1cxkuY-!lrt7TavxN7jBA1dK=N;VyA!C2Q+j zGd?pR91lPW3RQ?90u*WZ!Xtlj(|P&KVL86YaBb7Ean-_716 zN)O+T^)E-rCQ#LPa4Tq{aL$zP_4*w+Wj~!tu3;veG(vf^5~ma>F&-riO(XCLH|0c; zNqy4RUNH)elUAOlgp5kfxfz@_iAIXK$psvP@fbZMJCrVN2b*?eQoC}6=I@;~@m0<( z^2s$IHWf8immvBSMkUdb!KJFz1Uj{$#V}qBgK{YqL*W`0?PXYb%mw_`TZ@t^DW*V`i3ysj}!w5sf)pqWE_8rWd<7KP1S(9=M7DV}7K z!&PrZcci8HrV99qX7CXiTd-6Ju$C+99<7?OS`0Vy{A|LV~faVZ*1 zjQbf9=J`Y~%Cs$wy0bRr`O~%JN#{XkQ`$upvc>^!0lOJ63@eOgBp=Dv|LQ#KxaNe(Dxic zseNJt7?KM_7I^l6qf#L;9v?b;zxLxjfmIgk2inxw_nCT=5{o6~o@dcb&I;w%)uBvi z$-Ia>*;2?;>Ly#FWVaWp+!#nVD>fa<%GEGFuW0LzpJ9E5uW0Q66>EBY<4o zf{HB4S%g8~9!@2^96A{Bojr+(TjeAtdZ;_)oEccV<_~+Lg|H@~bGmaMX6W#@NUO}%DG+rL$ zC-vP_XFfl0Su;*uYOHoz{nyy6lk?6B>3XA78<~y~J7I`bSa*e@f(Zrm5%5R!Jxycg zh0>DHv-68Ouww%#JG`hhoOW&z+sIV13aMD8a+U0R=B2e06e?4dO6U`OUJINmOo>Kf z3!gurAG3r!il7HTQFy_aY0+S!Sl=Hnka5DuA0=S%{_r+M7~-TUpC;V!{su5j6yY=@ zm=G;^e*>5*2yns(iU#}LU+?eN0@0$;Q}-m23~Rbg7GtM4d+Q^~TOOFNq-89r zz(Z_T#nB-MS1rjlGDBqgY0ZW3*NUeovi~o1-G{mVyV>q6CiefAp7K9G&gX9a zU&E(Me%vST?H`v1+H{K+-pp5%IB`2)TD`eaI>t2~WjkNm_SqZyMK`mvwzBVG8@qt` z&D`~$u*p307IQ*9$=+U`d2=~shgFit!|kyeKAOB;R#EW3&UBI$tne+OfC3sBb^@Fff+I4~fyorojq$EaJad;v9)ilZf;so zYj1V?V57TV`g!Bvy|vf225A+*p0P*|py7?3Grx zKUn*_-L;L?%^Gxfue)|ogZkndlwaF{RsWAefCXi&_0_G_@39Me7FOjyOFzF~J=ouY z7WZIO`-htc*!y>TJ6qP~&OUb7I^6F<1FHwCSQYRFo!zflKfmun*Y>c-tJ|g3wS$eF zZ7dCq9_+1R54OACZ*F|w-CpZr#T_bru(JmR4*{!Gp=Pb_ZR}%QBzqLwG-Aa+;~!w?Pct&M{cUqe9eA&@jiA%)9K+NebpgZS-56pg~=`S~Gx zeoBuUr_THvR#RJBDJ$SCaL5ILtmzz&u===;kjz7<;Gage>p@Qml1+;eOPh-i7YAs3 ze$OQvK)6krHg)ELRKO4|hhWU@^ICINYOL?rlspsHo_Hl!ZQ$T?7s=|q-eBApeGx?l z?$G5eQDPlLQJBF*h7JvpV)McarbsJ}g32puX?y~B)S)BSG#j_-WsNZfpTH1Xh&bA) z{p$;VXpRa{b_N;)G>r@ghVBCjsa4u<=a4A76HPr52S@B(?$ zDVqX@NFLs%4KKj1;5nYig*id1fShEpVK;a`Ca|{}EhJoIoEd$<)q{NCM_?HY_uXH1 zfddeO;GCD5B3(_DPjLjCVm`^o?RD4*vR zOu6+Lw76CLRu7|_frA!#2&x|HWnc>tZ+d^QwF%r~-3i@u57-asXh%pq#}yP}Aj9y- zXRykG^Z6>Wr=jbCi~@uK2lK}RsN)BhAW}R$a#%vPbPAR>HU#bX@H?QcI*hk| z2_v`bFuF^Jnuqlaay4ZXRt1#UQ~PvqQ?QK~<$|3ZTFn8|T1BO(R z7H;U3Bg>5%mbHPUJ_9{74-)JAI%sBZnMW5ueelPW9D9seG*M_-G0YIhe5={~KZ}w{ zxFDt&7Aqkp*JC)`U;QOE?^S@d1(?NG(2*EXknaWP><9bGrm5)TOb&b;1*Ph8a6455ZFU$Q99d^ql1FeHO< z75hx=qtR!S%(f|`_`#@eh#Sn?4L5?+H=lrrk$RA`)qw@?cl?1_ar3jzys9n4?dj0 z;z3P>ukvdb)CeT<0ZVUqYKLx*5Jm1Q)GkoP!}Qhc=2+4g#hyor{5|2ab@G)x9KE)_ z8bt8t9RJv0%)vjuj{WHMNrTZRJPO@YTCEs5ffQ}`nUZ7=N_vCX0nl|v<0v9!`vM(r zOiu(HG}sE_L(oVQ^xp^(RU-02LWP#ktQ(;GYot187xc%-AzKxJoq&?YGAf){&J}qz znJ(tgB=s(cQ}H4pdkMUPN+=8wPWpY;O@MsDIS64K)SZ(WK`fm*)({kUz*qzmcIaJt z{0pq^n&+?*iHBer;DQk@ z4xAds@rgs>8v`DuF^cSS1EfkR1W+0(2=o}2(b)_k0oNun5ky0r zKoAlFRP?e0k7M}2fPOuIuA>@P=nc@wL<9q~Dq>3iC=;$b1MThkJkX*+AFtLbpY!7r zB=$z=Au&%g^L1oGWE_KL5MkmmskGU2jH)8q5{SSciAIb8i6m+v9^fApZHt0SWf%_^ zcNQt2Spqu{MS*7JJd@=)f(B%Xme7FE1ngMCnP_6SRWk~kWUA7mRBqh{D$3kI4e3~g z=-Rf%il|iH0sYIV-6oQRl6VzoWtw2eZNq9Kdu7xK2S6@6j7}Y3wl6`Fj6x{);W8r0 zBuR1{KQ)70_WT3RM`W>sZ9se2fH>iIL!v)GJduUr%qnvh;slg*7*eLd zq|cHg2QjT4Ykjj?TPP@YppD@j;9?PG-MGB^asjb%lr%ac1Yi*V8hPyizhuf!Opp#r z(5!TQ35&yTh{q$AngOff{L2^PL6^v-NEj^%}Nv1CLOl zc9rEYkT*IkfYDzdkJ0Y|{U&KpbA$V+yY4^>&E#nDYDh z#sYIOdTV4D(j!00%cd}OgGxM678ux|^eox}Lfv{YcDzn5`C-EGV>0!_hLJwL!e}d7%H+QmFQHsK{Wr3>a126UO?hXhtR8#UFMf zJjmIm%d^2G9#UW}+n_KJ(G;$t9KjuO13;BJxF-jeiBwCZ-C;U82`}CiI}@41^kdtU#)t?}1DV0YzO!!u zGKLyPdYz-N4rEZ!!Nf_@tiX0BhT6eRFA4ylJD?{@(1af(oe9E`-I+FBcoD{#n8wj|HT&OdU1zFJ4^~-=7Fdu~Sxhd*K*ee=9Sa*k_+eoxwSB+pd!FsY9 z&*CMS2oRIiz#&E;BA*GV&WL+^SIowd`Oz$7Bv-L+|L2Bz+bt1ItNxJk)J zfk@h8-<+sl>5xhKxC15drIkwM10urIP$d=Hq384*Xp9*SlbJMg%F=x8vE&JB3y5w; zEZs6o2d0%>5=*KG5%RVlFAwTXq%4D^(zmJ?4U>rz?f5S0KBEg%s>$XvGTJS-%nU^z zxZwE3eSI)NNEH(_AxF*N?);}A99E*z^m%wd9 zU&l~$WTj&{loJLITRf(1G>AW8!`}nP2da@gUjlhNy;usqM|?KzRt$lLUDH8y?=X|^ zCP-d{K0^ijfEr>ek_}o(6#uh|!z>+GGN$;x?G45UvyE<0Al(k}(21;@o$O*baE6ZK zI08VDVQ~Dzo7e8F05skR#Wod;Uvw(hWGx0z$+ktys|#;9sVZmJQJm7r86%SHN>JiZ zt*s2{hz&H95bd{u^1usXY=rEMY(E{LKO7(I>6?MZl8lhoEAnjMV8Aq$R4-y0I7Z%( z{yT$)&8v({@Lq-S0ClQ*1+A*GM^Ly9{iVUMqEjRYxE~z^au+(R$Wouj5gBpGkQ)uh zliQ$U+v}hL0*&BiQCA6`Jv`QRl|;&=~;F-k(vMRrTufi*R(DreOlY>hV-(?2U5!MY3*5Z*}oNkKfnQJH(1##+gU8aj6* z;F_sB@D(3KHfAu>Nzz~u1wHlvk~pof10_qy8P)aX@H!d{8aRNcKf) zV2mOQaeBd+%<7dD2UTc^S>=`$cJyy=v^jeviDXn%Hy8zuRX*eFF)SV;^*r4{mz&d0 z&;`^ZxzDR2GEHgO;F#=Pg^Y~2Fi1+3U#2LP4#daAuxir2&SRM6;dC&G=?o542Z^F2 zvKzHkM`Q(h3{~Y+Y&vH7(^O^6vs&w9&6zWk5-+LXNo?3dl*2Kao#c(!L1fU0&(2lFLVg?zO_eOecQ39M?s$#8D zD4L;(7qb3K>PdM$rvm7xk(`^vnKe0EeW-%^5U{I+&mg$T;tuXS64bO;$SJ?5UzW9HX!mZ3x(94K7@ zNhPa1+x~Xak3e8B;^ItxR~pEl5^FQsRIf8)>GZu-Ekn7sfy*<}eQ=;GD-7 zQ#3kEQPmD73=2ZHj0TnnC#9=rX;>(vUIEw-YRi!!WlRsr#)1hbZQ<c}vCb zP^JNp1uZI5063)x>ePq*eUs5w z>EkZ{@0HE9U}bH6bG^N>wzjz%v{zRjt*!j-|MTzo!K0$3kLdZjv=!hX+aF&%Z#Ora z?WH>9#C=U)X|6WcHFflIilzz3W8=7_PNItxFT7xt%Wz|5wej|szwBN;IT>%iegE_R zu>JP&^v%W(H?P+=-(UPWe$omjf4zQq^XRAj(SJSeeY)QN;m_${{pQE@+Yi88Zr9%b zX}B?ZxAN(Icl6W6>ty`PhquQ^mmjX5KNmny&PJ|;J<|C#Cyy^dB~6Aq5_|)4|M8h~ zgqB7)EWT2*gbF#<2jSu(T4LwMr8K%g-%=b3nd~Jsye^xjKn`v>OOt?nhU2LJwwMFW z90Oaz)Lb(e&^XD$!$3(TH-vl*ysBcygx8N=BDAMm1y5vGf6lPfnU>0u!4(aBNxhDB zl+Dq2D4ttL0UG#kgBH9wx%gEk6;?Ex5}K?&UfEn-TaQ-P9zE{%`@QvOV{K#oJnU}t z!tn8vjsE$gm3F)TL@Ns9MeHJ5EUn%949I`W-(;;1N&2Zp8V|WCeFA3M!1F>hG6St5 zmYubR5sDC5;UX&zpSpn-E|b(QxUN<4a)VjAAuw4i68|y&HERwHT1?Y{&L2!4h>sUd zF3_^;(Vbpowlk*&&iDoJuW1*bYiPyTJ&{~sW-a1)ncE6(uw5~;^x`Pr@89&zq!#KYxGhBJCs`Q{qayxzSv) zLm=mIi<07E(v)R^6uD`npT_ajV(n!zjK;u>7Ma3tQSOwbS`t@qTIS;&PJ>0IS;+xX z*t@X#>9ioB?VqC((0dLUAY~3zO{`$1L~zzN3mr|wrCr(zFj7#EfaD9S(`bNn^fV|Y zqj;=vU>hig(HLZvg2q0HX07jFm;sLXJ7?mthP+^dm0_+l7+wK1*9B8=5nJ+dSh5 zX#SQw*A)=MIyj#d_J5;e*6WCEJZM#Tv;E`8m+$xY_l`ck-h2DQ$t&X(P#2ROS&qar zOT0yb1ejPl#XAUIt5g)~!Ef9M*>iO3Q<2bTPTiYUFf_PIlsW zNdEq0(+krZ3cWMb{*c<83HngiMweQq;z;-Bi*w}C`305 zJWR*edm}vj0~ANY5Xeqwrx~FT08^W&3k@2?5|B(~F7~G>9{J;8Yh8e2D;zmEO-Rwg zQ#ZUF5ui&D-fj!T&`W1@xHfD^LcMhAlpz~ zLi-okHag;IEzrMK7wWl4=F4)}uv`z8@c?%>>J9L3JT#z?BlvfC zfr>2tDQDQrEDJ8h>jf5DL4%tp<=mG5q(R z{|x@|IhWP6zNyd4lc82wI%1347Mb9b7G6sNnFw-i+HyGubW_M&1bOg)|8z6;(1fyO;d8U2MQVPdA>EBQ zZob_6;oxntKlPpUXU@-aYv~;uXWV`}-{-=~A&&g`=JiLdScAzgmN2<)UrYof0QTt_ zBR5cL$FUgCfBDvcM2!N$ktsTrj3;u&!)_>9pvQ35)vm5(*-w>P%J`y2Cef0}OTcVc zXPW5n&~8#)E1XP!h!`&Q?XkB>p+~;QNY@BSgkj7`^`OhcAasIucAf)-akhN$+(kVH zRIhRY+;O2*H2FEWPTr;P-4^iiUvx~6=7EJIBc_`;KpGwqHg5{FTQAWQY7+~YN!+J< zHySl*--`~GNGei0po`}cFl@hCE6~hy19<_uPtk3bgAJ2rL57`$mOKPDwpxrr2$aOe zlU$&&Y7C@2f1br4Hx zUd7&I8V=05Is<{EdVo19@UZOs6tbQL1Nimup+6&o$YRf_R632%&ZMH0#F@d8FC4Jl zh*z*9&=;^pj9RWgidO_)z2sA972Bg*JT~RNK*Dw#L4850k^3ug^o zai32@GxSd<#~bwnHP0AtPQ$oHDO^s!^~GUMx_wwvrao&bfZ+6nR> zULsCq1;H&RD`3X~oF0#L>rWT9)2B+IEf#tFhHzxqzPo!>7StV&pMD2!juj5>=w9Tf zyZcu`%dixOk>wyTZ164+A~y{as%bZQ5NtO9lho*MM-h7&qhqwk|U$k|RfY%u}M@ zN;--J!>((QAf69^e9nNNe0Ml3kP#O-4GqcP2QxNN@8oe+JH*xiPAM z#~3B-hLdlic(pz)YlbZh0TLt0Lxto#=*N67hwnd=^V={AL1~a%AYmqVQTk0= z554LyF%SY>Eu|aIRGe&UBJg*dyDY_aBRKQz zNF(%Ov|1o>$Vj8Bx+CggtZ2}8o^91S!V9f%QATTQ856FzT62ga6B?0MY*Wf|nO@F9kY=6~ zQosRsy(j^>7X2ZTT<(1c29c{e!jK&`;W-g7WX6pZk9wDG`Ep`K#(2G~a`YG; zfl`#osZAP<2Vqa6lG*D4J&a`@>B$|1GNZ7Zbj^7fj_|5BUMqCONOymEVBS<>aoALhuPnu8|Bx7%;_j^AzXP=4_~KNM-LJbCiC<=N|{ z^4sIPs;{=&?G{=5T3V0IdMI+E%lnoOL_MIwTZPtjg6BsZcze>o)0<;F71@DF<~n>A z&%Yjsk=`(DfE;YmS(@Ajv8zKzns{TRqNkMEw0B8YY(REEM}9hflq-FZKS{$u16F$E zv;un93ZA$(_V(dN;;mSJb-W-EpT|86{Y3gW-9^RgtQ55%iY1@~3?Wb*h;?3W$-2h{ z(C@_*9ixNbz#lDMyTFTg$HZu~WD{Q9?PyS>wH;IG|H`u8z??9<0SeXQ>9!@p~fsMy-0UHW$)K34WI z2M}hbLBDqKUn;h`@)&b=+Vru%2On$g_6mILKEgWtPbg=9cLzUq_vvGQfA_3aalpmn zzW>h9Vy7=3VFzvQZIe1!+oulJ+s(iA8+Jr|Xla+=+yADc0*GCJ%_97Fg?I5)u-DqN z4>s-$#w7Rj&K^r)@V|flQ$PMT^1f2*VVHiRknLu8w&KSRuMSR_(G=UrRXExE@x&Iopr>gD zeBIyV^SRwmwirgdVM{#4mB4a`@AjbI?LTkZQqR~B@B=W!-MyXHPR4_mueXnW@UuVu z*Zaehz1>17yoDbubwd`sh2y)WB+1P#X-lPsCG;W>FTK*cC-aIf1*bu?+056tyAQ0m z1kh8>ox?X6H2EW}^AW~yck4CW5?+Rv1Iw_Ruh|H&r=U>I2h0?cawt!^`66N2_!PES zq0_TM-p5rZm$Tm;9qxQQczf)Q=KIUo&-?iDaQ7#_0J7#Z$`vaN8w)N`$)(_Xi+v~C zZXpm}5*di*ems7?ef+9WCTLNq?UR$EgO^Tj=p>Wq=H>;uuulHRh@KUk#`?oV1FKwIm|HuDwO5>oQ?DHiKYgN*P zRC-@hiRv&OA=J5*YlVJR>9n>&DDr|y$j;HhI~UXBPOI6qT)@Snd@-U`pVjrrbyYAV zc^PQl@>a0?2X*_onBeCN{T$HeGyTL7V#1Q~W*R3MBrGj2xn2DWyOD(Ly+M2dDJxGN zYf6Y=cqnO2lX`L5qm*?`xk$q+F0`sis98|TBTboLpkqqf(4^^bKna_Yumfsh%t=oq zY479}e6O|@pgjd>wY{QA0?=w(d*4%lKrYfG?hC{jNjR_#DLeRZTMEc6_Rdx1)PSG%xpzH zZdjLHNY$p9^0a?W&?<0)5a=tVC~zYpw=0hnw(OF|`$!=hhCS-^k;2iJ2~Z%$gK0J- zP#-B6*>t>u36D2y!YY+`Y!lWf!R#re;Exs5Vcbgz)W-_yI7~xIST#lZeFp!rnMkG0 zkJs%S3@JeYPIV3*E4=4v*jrhrq{nU&!Tk7%le9*qo|v_!tH6|`KvMh?B3EX@VtiwY zP*FQP6c)B-wr3J)igtJ03qh8{B!jS-P15oH#7n+rmg9Vs;F7N!HX~c(k)hwZ4Idc_ zvppDJ;>Cn(Ll;**L&kE9uRy_46XjFHe^_%eCsezE~SK_ z<_C!+=#>6B9FI9g0e&40yM0blh~G@Z4B{^EO3S({wfU_GOFJOmvwCn2F9{B2LC?k+8FXYFl%Fo=#VCAL*X6qrviIJ zQ?Oxnf?b;pg>+0s42ey7Z480UaBa>hY1K`l6vIe(xeR@s+8Hr4cFfCT2y9Qj71S{= zm!+?|T!uZ+lx4R_ah@1@h+SP$%40L2EBrQ;EE*9Pd2GeiXs9V0rs-HpS*h~Z>(S4g zvTjl&L8}eYAtxC6H;@DcZ`5a2{n!eELz|=^4l*X2kFD63+9X5zyCzA;I_PVX+2W~9 z(jL1uNqg*v=xWGmI=o#c&1{J2V8AH~*kv>r#5`3-w4+zCxSSEC#wk#1PSQ@_*`zfy z@=#$jdndJNX8R=QV$4YjF7S+u``onR8?m*=YX%eJVR%9H)(s+FM{$(W0M-p>##1X! z(P2)~u+J3@B87wKoYC*`hQX3Sn9`JO7|myDQgo21Nm)13uPF-ErAaXxM5}EYLOIx$ z6tmx_CPlF%H7SZDeUqZ?TxyD$x$`6qd8Hp2bRXmO8cNaLqMJCAB<+p@8gh~mb;Ir; zq$Gp$aTbp_MP~_LPm?5_rcun_hGL{ipHsBuY)Z5L$YAy`9!)b&GJ7ex4h2ZVe_$=+ z9wk|nO_MRFX!kMRSHkF_bFw+PcX_M+0$>iTI#{Ptccx?*sQ)O&~t_ zv?e~mu@$gIwa_SbR52ci>cC5n0huESh0G+JI)9y+CgeCf1N9Rh3+Th=v5bStddDUd zaN2mlN_aWfQ%Kw|D2IGEyaeMh^SRI}z2a_KMtA)aa&yYNA?c+U@w2bZa31zV$d)T_DVv0jqeo0-= zQD>%%gF|kv@Ep`fI@c9lE+xV~dQiB#Sd-AT`(Zq=0K6Z`ZAbKO!K-h}c9u=EbgdA* zr{rQ`&3fd`EaMza-ccM69&7IEdABy+kD{9~P*{ux@A&G@#*dk|TFtdi<6B%<3)6x1 zwI|0ZE#qB+tULGe7Fjzx{TA7W7#QFpDsh|?$7ymP=a9X0%>AHh0!+=lLQD?F4pJ^- z9D2QTZz1vK)5RoyWNgNwDAcBI?yx+%KEc?qMLd0wYu?_NMeiqj3sDkI^EZCas`gTw z+}3pKWT(#G>YLXHR?h6@SySD+rOO}xAa|Rs91u?Q;|!zSIafM0hCf}^iTizwczsSS zbNJ!`c_fiz*mFD|Ucz&H_7n3@?B?Gz#S5t;xwDIri$|HWXocIe#wSs(`juTo@h{vd$6P(K(XpqTl1h zugQ_Up`JEz+O}d5#s7BmR_s;bXE(tT&E3*-4J3!N{=&?$jbjZYlHef0it0FbcMJfM zBgxvextQZ_`hQ5RE%{yN;#*RyxJww8MRrN<3a<_JU=i4+&D=8ru7he0&gcpjnp3Y? z*g-xNh?I6?5r#)#wbcQ451&o6%!5@fvFPg6tS6WK1&qyNjPi`<4%f(Ej4^!0zdK^fJEh%QE?n=F z*6plx^H%cJK0CLf`Vn1kbzbw7XMX67F?r_9JlR1}dAbp>)(rl!tz`5dElD`CdHDV~ zzW60!i<-F902w|UVfrGcI=p5QZ5c^ktD)ff_ehaV{@QIbmd1xA^|*)7s)MhS-(6!xxd0v{>1E#PYv^!}3B z-{o9Mq)gpwxO_925oQ*ckD3QtTGi1Ecx1r z9+jiJMo{$m6U@byuHN{}$@=VYlv;j@@M;OanP})(k+j;f^sW~^DT$Xr=t_}!8FfT= zejH`T)(YlcUun=#Ti;4U>Q!1EDqxnrQXVuwZb4j?RXmN){8CIdMpvpXXvUS$4#-*Y za~vIoH|3}x9nMfme1t7mO}q`tMHt^*p%Klw%NV1os!Q+gS|5tgI1lm<6XB6ZcMavG zUv7F%KXGzgO~p+ojD&w2cJ7L{{6a<=Eob?6w)hdP5d~x62UyK+sJkujQ}AdJ;kTcL z7<0wOP;mro+`atQ17A>lkfU5*M!SmCi;C4;Q7CM>t5^_qW^v+?FyGLWyNla~cC&j8 z&(`&QZi)cJ*|Ft@9B#~h8^u||{OO}=ZX-6(nK7HW#Fu0qn_#W!GfWPS^;%1l%3H#- zSw53TW+=uC(i7v%8y8-=QN(d|XcJ1!>J-9>nof+kYK=Fe1n6+_$un4@xsrX1b!GAr zexW#8H_MliMG135KghwC4>@vQwfPQYDLc}bZ?sbmZbn|wQBB^*c!E@93;En}mG+}@o#ZId~MAz(+E$%PX-5BEy#NxzP z3>TxD`aDiEd`avRzQ&!J2MYZMyh2iCK?)%EfXu|wdltTU)_w7;)r0@=clbhH@}o7y z+oQL1f27V&)8a$PHd0YeT5|(~i40w8?k!+k-T-DR-en;EY&v7iPHY{@;a8ihlSae0 z8u9RaS#xscAQcs8jufG!^_{! zNc0hU5G%&lrLOTIU4BIjfz+40;JzaI_p_M1Q~$mJPG za(YfVA-H4TEleItx2U`RdcZydO9ef$Mk9C;Onek6IXLhbVluAg2U&veghF%nz72U> zm_P>>lt@j$L_auTQMC0NC+-N#<|303iJdiwhH@+;~niEOU zJ8>;)!2sMM~XxvPrIwW=1hW zRxP^0tm!Hoj3&}%Jy_ZFitxn3A2za#Em2@7<(;nF-D&&IPTOU>Bj2BKBKdp!VXJPG zV4Sl!dmFy3LYp-tKHN!8jz=oP4bA6R2P06B+;9@`s2;>FU6Tg}3^gU31L>zcCXy-5*|L*kR{}M`1+ZiR6po_h$6_iE z=T02N#AVF8dDxtCipRXBK;=BA4zqQacQ`_f1eiPLXg?_R2HP11eL=&H#DLaFLd}97 z35SzH^yLVU`L0KO&uPculkEOt>#O&RZA0>8+HJ6`oa7%Ho=1|sT~!tS(aL8Vr3PsQ z6*C?_%!dLclyhkKgI;Z>BwiGXX1J>rVsk&V7Ac1c{B5-Ci!!SF#G~lp!(w_ak~aZW zJdgAWJIxdh?lhjUyVYEH$Uq~$Ut7fva-r!R?=YvVJKE{~-u`}W#1y}75|5k%M*n0o zM^+uGS}AFx6m~bH##d{ZVsGRInzOIX@Y(Z+&ml^Ivd83A15&t`Er{KtFm7z{c(&|( z{Gl+Pci_FhFpddr7AEV@Y>f7sEXV9zD+LVC<(FW({*+*RY2}jUKUd~``(Gv6EEA_} z+GSgEm6xr~t2XOo-DCQM5+!I-R3IGO5tB)NKJOG8^2HVr9_CDOnLvSHTGNh<$G&Re zV0{rA%H#&}z@~7E$#jy%Fzpy{4jUzLWVtqH!JLUM+Z3hpgv7bC*29@R?&ow;9 z93BQMpd#fMM3JVlV$(135@3iknl2Gl(BF%KsscFuTJvX6v8#B?q_CgwWY7x{0ms0c zZ*(?!GjY&zd%2q5jL?0p={!v($B-0qD?fp=&Q$pYgYwriEaGE}_n`~(-vDv;M9GkN zmoyp+>_-k`R@yJW8aETJ1qj-r(=EZ=?u6D2Kj$v16qIN09EnC`oJFLWg7mq3FbcfjN+YIW_s87Na;07Hw!MawptMHo#CD?qFy-BCd<@| z`B*)ty%MbUmi`Nsl3WnZBI?YTpoOuxfSwDH<$J-7Awhow;LB%sqj3pjzlll}W0B69 zt9#R$k}#)Ve--b>^F^r9%rR&<)$(;(TnxFN{;LAYZ=vwHFt1+&@N%56Qq;VQ=u*lj zobK^~4CX<@pxYAr83G4nQy^WfC;->o-azA_g%0ue*B=Eua#+NZ^8k-Vv3G3 zGEoIRjUH0)V)?@FB!S;$PLK6`b$;0tkLR=tw2LkIZ7tn7nZI#1=Ltn$q*ZY!sk5&4lWTp?# z96fo)JD2xRIqq6icUA7ckpHrkw86W}7x6xpu9$!yobw4=i$G`9&th`w=k@+Ao`wx%6x?tAMzV;N1#&hm36lc}n2jE_By5 zZz$=)unGlntUie--S+pl!!Aq{7Fr5e^}F}=?47X4;+bgqxkYoW^a#!zBfas%UBLRm zfj>&$ES`%hf!^UPt-6S*f6kc#zXed%V!ny_UQqUDF?TZd!6j5)&Y!2}&z1|obA0`o zeC}S0FOMNCx^MlZ$X|w|_T{oj$!aZpQn8<;*J0XkP&jOQOdYz_O9|+Hbe_ml=iS@j z#a;I8!gMV(LGliSQ&c?N&}Sa~o5+XX-lZh3|J$f=M)x&1z+LN5GRgNl`QSlBAOzPi+Jn{^w zyl0fYCfB{w`d&O8nY%lScKLhwY~a&AkvqY2HrkBt^_8c)ci6oZz_N#`3KZ?ZoKt}N z`r4H~NVN#|mW+3<-fn^lrP!SGCRExoEQ%%x`^O$9L1iq8Ig|*98{41TcTy7x9cMaStw6PVcpw zXRCj|L2g}?f_)9cT)~i;&70GOCdGYOcrK$dua7QL>b*O$e0dYE79Qhr=5o5z^K&mk z=3STB?gE~FoDR#~)&l7n_lde5FXv0prNOeE@0gl$80IS_K1dG3{W7TD-wUczUFBYI z+3(Ml^1bnNhA?`{y__MnqZE#DP^zK}a+vGs^GRJf_Lb0euUU=G@V)!Y{FZ#&WrEe) z=wE2`@{TN|%@P&AIDzF?<4c9;FPp^5Tq+}B2VES@N56NJ?N6iR8bk4f6aQ%lrU4c0 zk!O@}T_Jb*uPo%i8G2IpB&*02sz!1o>JwrycXo`LJ+<7 zW0*XUM=T=z^PhIe5 z+uc0L%}x(uF%A!UM2KF#c{guT2(>xbVtGeG^s%XJ*rOOR(X{q7php%c1ev0Ha2XD+ zqRi_EPd|m!FeT~Ujxcry&>WbsC~N&3UWKeJH0YigZ2E6aiw*Q^oDRZh#)>wc(~`Oy z7k|9n3Ha;G(Tf)tQwHX?eY5*GSIynJey#t*LsTOw|8 zOjmvD!5vs>fhx0yI==eo5c}NmjhxANMci{6;QQzC#WW4O11N@032rV1E3r9t>@$NL zl`%hLKkm0L3{-0z#^-ZQW0XWU<0PGMko{#7>J|g~Qb3k0 zY+)FJkHe%t9RTgbkH&cf8bIsy!Oq^>N-wpUg*H{0t$dv$GfbK^gP_SYETT|ZO2&I_RY8lr}A3j*?F5T(U(cjfa~0`vQS z$j`}T6udb&30}uNV4@($!AGr9*-6H?{B{F|#8_>wYzDjG6$ljjX*dFv`yD>Vn`I~h z$60{)wL!GMfV@f6uLFIGD9i=U*ahC&=2tL)&Sv-$LU$6z5gV_4&r8pai*eR=~!wk)u@wx6b>pe#pn(+%lHKVLm~AN z+Ngt&(Hl(Z?F7vp#KTy6!0I&ktOAWrv#3sR*6}7oe2%{(8rFE)9mLsXJ?O`o9E8+C zcIggyF6%gs76vYj27?N;5ChyaRtp`Kp^#-bp%a-R3UPmZnGF4r#98GWSR-^9QJsDQ zQ${@^KciNTmP}VOY)o*JSJW zpRe>YoB!ih`C;$%;SXOd0nF$BtE-#q?L7Zqf3)&D|NnRVR6v^>T||TAqVimSDwWE& z!D{mcSmq!Kvj{%F4X#$38_jm5(g^lOm-wXTR?s<$vN2Hms1tDXLwpxQIYkz9(x@M& z6d}BWAvsCSYI+S2rd4Ylsu=cq5kC40tSId_#vzmrIxh!Fw-dy}@gTAyK$y{$3T*2T zgT-ti2S&vz=#0bOr|=?b43gfb=Fh-OJHbUXic(YY8db(Cj24*;<*llr+fZ}`|BWNi zlSaMUU^?!D2;$_U!}TyS=`u6x%@v%PeGIs4K?Y_Rq_C|h8WHZS;90QJt|JsMbzvVN zhJqP7a))Hh?u!oQH0)1#*he1Rd6_1YLEOPH;NxM$v9sxzdaO?A3=I2Q&VpYDaku78 zI)mPyF}1Kr^qNIehm%DUvS#CzOS)ejPAAC_3il`=KMt+){^<2_6sEn)cVQY1vyQ3U zc?H7+k%kvIjR;Bj*@a8W;aJ+H`~+k)I>O0lmT1maRv*G2!5{%NO%0O7V&IZyQo%$s zackuhw~aC5kK>C`IOyn%)%hWqqrL6jH+!%EATeR}c&12}~LF*4anYCu^OZE?%0T(@m3WG}iwN6NfJ?%E|)n^(KuG zbPZBmG`fn@WHhA5%C9M6QU{+WF$i@P#sk_D7qHH_R%UKiU2Ihp>ICP5@B&{ytpSXoRd2#Z zz!gUYM<;Z<55xWVG0NUhHA_cT+E?oi6X3$&1)EW77yQNzi_6OR%DaXXH0@U!c!S0@ z+>aSm*#;^)(K%dct{Md5d*B^B5`-~DpiK2yeSx{b_maFhZFGS=6YZhm40NVV34MSe zf))~qA&~FZOk`utANFuaL}(_xUsznV$a{nP{A4?0%o zRgz59Ic6snm~D3tYZF37NWD}_VU_?Hnyl{N z)=o6+RHz#;TcfxBkYtdz1Le1ywrq~#(ZcZdan=CoDniid@)DfG%G;43H9v}enZmjo zuwjw_6<(d3yfbsewG43=?vDo*>4?|@O(J%40kmpFB)v{}gyaSYST`QvNh=jg21r6P zd;v4fG_YGQNpXIlsR_OJ+4mR*X`$3=BLh`CCW<%=N5JR})PT(+tS@$ACEo5hatlLQ zg_X&Si6AVY{1l*P5Pym&;z6;pb|F#`E;H)Qguqr)4^6ieaGQeM*|=J|!fjmP6I9eG zZo)A9IZ0JUYX)?t8=NN76!^$R3eW`?)3_gwsf22f~qkpPTbalZ>( zqBRUNSi;u(cRw6$@9s5zcn=yni2pTOIt-`{OGIQ5a=v?mutdc;*4aE=}4N3`cKiMQ`*9Et?7ugX|Q*^88E$;ZSRqKiUUX_ z5|@WyeULzq{^g~8Ronv$Q z-lc7hHj>aNUKwW_S!oSsGzG!Gv%^ArgFQJqcr+$&^mgT`EhH8A0BkyB*`H#(@}gE% z52z^tvwSDCObe}&y>N=QM0pT_o(V@*h9s(o*XU{6dMxzAtL>8yKLnsPs02_CdP3!q z*Ixq*xV~siQ;^YR%848!Mqk z%K+hNNV+H*l_#XN2qvNJ7+oSeEr$UGLrT-GBxW)a6-(GMtn6xg9Y)tsJ&xK$ zW4}WB6p|3C%zz=3n(Vz-E6vU3YRy8XjNZs&hzEA|cmp}q+69@JThRGo?}WvTS0I;m z%sLScO4J4DorN*tt$5DNsO2H2tKm7b6%%ok^Eyi_VEt*x_E8 zn20z>o5R@}^3GL9#H8j$G}#^u0F8nH69SGSUDa9aB~jY5T^mm6 zJv;@ik=rrq=gj+5%O&LK(P(IvcirPFPedOg#bgEi62(}U^X+#Bc;1!e(J}-fGou(; z${2LUjcP|`yOo^T4izpj9#A5z25jd?P1dBl(QPv718X^sqTsZrra&Ya*ibhG050z% zKte6gaLke;kkBw5WTL7dHCglKfpMCoaAJM>kUh*T+D$^#ryOjD_V9(5JX`4?Cu?9p zqK<35gb@ql$h;yio(H5f)htx2{_4adgk6DQ$;0ZZ-X@i;kS#=caYH(ko2Vme0og5} z$qmnk1Y@_c?0lMEbWHdTSILpT5m6h6Di z6p2yUF%C_U)OX}@YScU&%?wS0D9NxMqlJjTBPAQ-m<(MX;UQtq%%6XzD|2f`Txz?c zfg6e*j$;uRfuD|IR6puC3|$D~6f`E455<X}HTq5>P-z{WQ4Ly|w6=hS#|1(8yrc z&(i}w#bYBLh`2xp)nxS@HC~;(dENT)&Fj+2bCC>LqY8V*QZ|b4NIY^(zjZZ;;{p)^ zngxW)f-J6uy)Y*-@f*A^U7Z;57qMgwemfd5uCdo6J)+_@ZAQ>s zGPv^WP}oxsqzD+Hvs1_#lcasC+_UHn_{WAA?ROxeE`jInbpjP-G2SUgD<|CF-Fv-v zvS;R*Sf$^hKVF=6G=_PDK@dSK<&wD9_^E_z-2nW~7^sS{3&qZbxPg?ln$@T(43sFT zU5&hzZ6vGKBS|~aHTo1q;|4G?I@=$O1pUTIBH)Ze3TA~C6SjDT)|iLgSo&h@7igRe zI>T@@B||wGh1sMRp*=_KZ>cC$p7{ds8FZ&l(a24;z4?2a=K|JSt$w7e!*4at3CXWc zE^lzie;h}jfUc*$xaBejTsq(wK3M_xpw?>JRII$hpAC6P)|T#X7saocVxJhd-ODu z>M~OA!-m*J-oUi+0{N;eE#Y)}<>+r=)`&CPiN9*4GA6DZnejWch1FVXhx92<0sR}F zp!8)tDjn3qeXyle_!Y}CY~Cc`%~@D^*Iqw#nZ*?^FOix?gudq?rT})L`EQZNRAyv2 zS>V8@UW=1~zDR&9>H2C8w|bv2f2H02KfWL6{z{*K+0E7bFX;3f)3e zehdnaU$lT}v7b#pMU#1GxaP19D|#1<5Q6aN>=jLXvMNi7eY`t7K54ys5C3hS?7Xt( z4xcsgO0(!gn@lXsB=cp{-X*d{Bd=Ik@~2m3_xLv19_YikLv(M0d{5duE3PB*dqTiS zs$*0|j3iPN9D}xFn6MhunI2dRql0veF?6ZM5$wl+b!;^=wst$;t0mTcJeyU61xS__ zN4TvjQ0k6Sfexu;0r`3nTdA`XSe&`I1x4a>pmyg`2y#{AtoKSu|3b7clT7s!L?5&_ z!D?4o#%k~*SokQEG)nSIJXuD;1iJ3VAnzI4h;Lznt_|yk^_>2FiiFe0#~4jB-6)%| zDMF2}T6;AIy?;(ULW|fS{uPBzzNn(IElRs0JJ*qBUg7GamJ3i0(KG#1l-WLt5Hf&D zB*yep?92{QG} z_OVhJ0!oyMp`wU)p;o|ZnkYWhlL5-e{-#-fX7J^CB(Nl+=FBVp`B*jPvm`|BOk_yP zHq=hr5_?MzRKS#_3p!YnO-_3h&lP}AwUAEpGxG{yySZuRmJIC|DG1%SMk*v@01{M0 zYkE>1l_pbpqvDYi(U0)z17HpJE$d`M2pTd|bk%T9VU?C!mSD;fuV7p5gjG131(Sd} z7OEK*%5{GYNL)yM&J=CR76_UKUdGO+S<*w6z*~TKbBqXt(#ANlB9ZNI%@H$YQSnrk zJ#TeJL^d9v<1jO%q9!<(mEknq3#}ViC3FeI%BpVGkBPzrcM!lV15YXy+ZO+Pu4rO_g~nITiOz$$z!~*KGek@tgQ^ z_y0Tm|JK)5R@d|Xe=BQ`e)s?Tcl_7|xBh?6E0xm+r+AcxC-ShV&hVoV4*{jm_;1ix z&#+K;8l&-K0(?9>I|VJ~D$Yzn`P8yzS7`AbpZl5e`mGg+Z-BmxRN_p(8u(?Zc!^Z6 zvJC{~;&Rfsj>yMd&i%-(pi6ezpab$9uV!Yo1`JiZVMVn<17QYq_wg6s0LJrUQReU+`$JEkPMu@Nha|XsfB0NZ-?ds zIos(z3rf(_w<0sqdBf?hIeKRw6h~5GMgtY>@q7czG@LRF7`1f36RG{j&L`!+PQt!w zT6)P%oZDoIq1J#4HK0(#Db#>M;`c;t?XbY~KEpMve#`PxV~U@A6AsF}BXNSBo`fYp z6B?8x8KZ%TjU;VcPKEP~$5}R$Fsr^c=3h0Qq)HkyoNh$(nQVE*~a_^B!?=82BGpfJ9w&R>?pX=FrgvP6^pS<=9E*>+Ak=pZOX~2nqmid zVsIX+X@!W1q%=^7&$nl7ccw`iEFm$|9==b71cv|Ox$9w&43OF{$bFeG%}Y@t+cH!Z zq%KQkE0qI#24lRSN!kAK&Ffb{(XAqBoeWSVnU2&sq+#^qQ`Y;($>0_ca!|?=_|Fy- zT|6zkB?aIjVd5>0y&bIC;e!=sP;@33^P$W4F#kyIJC?D4QZWSSaj3WH$yY1S4N87ArYGVV2mpOlOXRgTN(8uv9;Yvn7| zkc7XEl2MrUlirM<6b*v6` z<6Gk7yVeChp;T^*Z25Q+vUL!&d!)pCknYbdOlXq?`A=kk&w6n(&CquV07=fz^M<8U z@qZCb5HRTM)CKE|2|i~w;Z)e(U0r)9DsD%dYPhI4^H(ifZ^qPM@NT8 zjaS=mck#ZRIX0i92`GaRXvPVy03+v}A|GKb9_Rm=7TlJHj_7*iaq(Qf5geT3f(Do2 zc#KCobnO*=Ok-y8B6YGDokRZwJIK(o5e@k2FI2}cl@z=Lg!_H{IX zO-|N?~%YxuUsU-By-(w9+wVq5O5!Y-jvJGtK^85hqPUL6O9S>r z2B_0n;Y7S;bzjF5W3d3{YMoiW%zcGOF?y5ae5%V`q!AZ93X2Xv-v&ixMwWu5z2y=B zC9GK!A3U$3>&o*NfhAmSCK*N{7nd~|L`@hnrPXR?r2qufZz|GjzFUw#n@-p0K$;0G zv%p|->1L9XS`G}-p*%1gm8^UU@OL*J5mQ6q9OJLZ+1XaGj0Z!I!tW_9htF4*HF(M_ z2r*m`y7ci?tdM=_j3dTOm2aa)I`(3xA4bD(kDK`Um5jIAZ5H) z$@z|jM{#3qxBxIG}LFRW(VU`HxY@r*;(J^^^b_k4G2bm`OJy0mAjL#7O z7qxcYq8&04gMk13ie#7csJHl&VPWV+l7^zD`GS ze4{9uu*(hAH=INcSPQ-|0IPEu4e*G@_~v3BU4uYQ^=Df<0sO5=&C2JwyO}Gr*4u55!#l$& z*~sozT_&6-^F=hF06@)Va~XEH3WvVoQQ5z^-ywlrQj&ii-Y((ViqfH4BD=1E-j7C$ ztr@6?mpUd{qt_p~5)7RVWGy|^0(g_`;~3IfhrJ2Yrx!FqG)}A`c$R4`QaXgNy*oLl(hx2S$RY8B8M(6A<(Ze&=09FcReDU4@ z^u{QAI6vwF+YG8q2{nQJfj#>N@v7~22Q{CUpve^3n#(}QjEV=_%O#B9D^IiQ$?J)- z5?uL(fl!jXQgr%`i-q9;0qcVATDh5B$Ta<%L~tKLbTi17e>yXhx7(csoDE!7NUvk0 z;dQmPKsmgnvF!RREZ0gAajwlhFNN?%!0;8k4}3A?JaeQFv0yzf)Tu6$KT>mYGbzKi zdx#y<#lKdPoppZTPmS@ebf-gWJF`NvF-vAz1w}GU{+a?Ab@O%Rr2>rX@Te}>p*~)6 zg&Ojh3<0*uZevo!7ZYIPg=rsY&~F+)SCNwq)UGO?vcw~B#UfR#`UNUab2J`;28Kja?rXO470|T4Ju>kq z@Y+i}6!R?IC=~xs|~{4kEL*o%+N=vE?=Fgv*sv1GlR2V&V^luZ*< z%r$@*$tBhI={f3rC;WkNsR7A}2icaI)E(4h{Tc>Quh=~d3L0)!KK$Eqt8o(V)j5d9 zS%h)?61?R`AQsRzvL~sc;fwICeo+2R0Rjxze9hxp(ocANm zVh;q@c}y`Msxl*#OMZ7cTQY^jdkp6x)!xSY`3+GDurmDvljNxMf?}wxkQ|DX2e)47 z$toJlJ9N=_Th9y9NG^D&aTo6?W9!rayViB2fsT9rO8Mq|*4P8_W?}WXrV|RakNAqx zR`3iB1TVzI`iH^f>FMlK*gsrMo<3_)1q#1OWHcO^=Gj~e+k!@8HD0_W*#(M(uXGU( znsX4HaE*9`Gft#n98NBw;{hMt;P9)R7K#Kd@)K{RNiyk>(nMDyd&!_sx&?%%(T(VS z3;Sw7U))2D)n$n+E%(X&OCT_eXCU?VpD%fHy7b~%D||tVDYMRDE%ipEbFUM|e?1av z5&`{?6~}lLMvG-k1yqMNvdHm>r52FGYZy!M=@w?@v!EaLlml5C+~<19MpCIvoHR+} zL0|elqFN6K02vq{!`u<>-ZBD}T!F2k&4MiJHHZ6gDDINJNgL6-|6EG%`r%)!iO^rL zzbJIRy&|TO%2Xa?4TsOUVEjywfnh>-dLdBnztH_ny4qq-#x6Cygj|eaC*PkVrwnzW zgwh=obb)u7^0qXGb@I^@+ed(965(>fCD;Xb&SP^6?;Ii7qduz1RklEl_a<3G44EO) zt;uH4MqtW3e6gO;#I2y6UoZ?|V%?ZW!7!71ji`bJiM@~@J!t5=>fy1t(u(^uXoxZ? zF$V2G(+P&P>+9W9ejr@$5lXaj1w@_4-GkP`IV|9EIN$^?`4drs@u;b*> zD_^F0ym+EL(291Po0Ql={-O{y^0DgM*x}zE2m7j{EThIDtbdY*qYQ|cGgt(IZ#3Ca z+WWAvTz5vdF{u9@y?M47GCK%I^1$b7st*?tQfeK;zC4dBhkg03StJ?f#00ffvZuO@ z(E=0=$O3TLy0DyQL(& zTuFcQfCNSqaXRB~w3yLf^j1nr55B+`UW}!Cu^ko^EZAj4z90dl$rW(tK0_^++^IVa znaCe}MIQfV%of=;nI{;6%!Q_eC>)8)z=UKF%W(AQ*ttSnC8LQiy*|r^urpqKS4D@Q z1_CySL)cN@J!^4Jg=YmS&JuA$#wH5z#U?U)VXew%3rf)VYIdz$06z7{c{Wo3uI#8F zL-7k>fVM-vKhz`+?aDiNFRdUbNu>8vamKSML?5)p0j_0pnEVQ`hosm?qsIH=76#X7 zeTcd(Pz+kqul`0Q^#C|-Vxy3%-<`(DBN1AclBfv#6^kDRS-N;u3xg_91!jX~WI>Ln zeYzlSQD3mJ?~r@^tt*}@vP;S~vcf5cI<=0MsA7twn_Um`V2l<755c)k^%P-tFnn9})TA zh{@cs`2%tJWz-At$UsGT3?bpKGaY+jp#N(QWg1i|J}B+_iN!NC0&vik2%T$y3Ir+O z%;1(TIpdjyj*t;wCqZ|QQZs|Z$)|-DcE<+yu#rza>J^{M5g&6+7I66jCv+QpK*|-N z_(m7$5|U_aCH2nZ!#Et}1(~X4HzT3`WyXLl6B0bAArYwdPnXg2Egzh;Qe^>pnB zcPDyLP3ZdF9iukEyL^3xog2L2xAP=RB#k1)GUBpBn?w=^T`(S_(5B9J6zYjXCgOo> zNLnLsKsPXFGuR&3=wjkz%`}PjiLa0s+-K9srDQHERU_~zZR&e4P#_6nbby)DXX`jj zV}w@_1{_p17ZTMW5lSI)C7Rl}DCbekESN%d)k~tRqL_zfj0WFG9)@F+K`i{%#L}{S zhwUApHSLM{6-Xdi7|2Yjw1zE6dC%f+#XMwgZ%D8(wvOTj4l&CY{EpC7t#vaTka=YJ zCBBJ@H#S~|eawBfwp{tFMpo6Fo_mXgjmzcL4;@@1@bW$Qa2MAtRXZ zp@az?O(rlej2gudKsWK(krX((V?o66;}cGT+vvVB&bc|FQh|lED~_ROhzGFgSY9W> z9YwM3918NC;lQU(;Qtw737a(0!Vf$l9A^^UT1cN4IlBq%PQ)pjpW$49I+|c;Sk?_E zF7YhUW~?DP4YYi2+o|VfES|6)z4-8&`B{9QEyyUp!?7oLmA!+PJiGk29RXbnk(Z>% zvSb(~VmHw1elvI{ce(5I^c1IZVc5%vAYF=|+UMXn9;{wKNp}ns7}81L6B{RiU3M27 zWBJ*DG5qf^&`y{hx-r3F7>!pNBZOGllfe~xlqLs$U6k4wvBpe&9;%9cNWxN3gG-8_-WSlH5a~V?u zu9l+{&#me8 zmDO+QPc~yu8f%Z9wA+s!Jz1>>^C4_G)b<$neo#{t_A0bN-HfIYo0H!lwodc>nxFra z3dWnJq8$zh(hLq*Q9*ySaOl2Ufxgcc+)nv)yxA?A4)W~su6QD|3`d_x1wD1ISKfX9 zl3HgIpTyowC={&k{6JPn)Xh+ec0KE^R!ChmaRKPG?(~n0zjIK#_B6O!EvKd&0RFQ@q= z#$ijU&Th^J#jD(e4cW{tTYRAZ{rI`th$nh(-Jxn$ayGZS%73fHv2-OTXxhrT`ynis z@)Z&O`=eI+sNq3Rhy9T%yiQ9CTjNx*J2e+BomLiha50rDCG6riv{z`Pa+<%!_FJ0G zxAFVqkpF{zX2*YWAG`RnKJIw`d1Gy5Em&Dw-&}`3*EZTgdv$$fee?JDPydb|wA?Ly zM61QpRa{q39dad-dx@Gq~zPrVfoyslq;`tHVuEeI(R>h zetaDM^ypzP-MNnUUjONrM}HZ#llJQmKVCn7E`Vq}UF@+{7{eGu#7Q#Txr_&WkmZ)h zL5p%k(2a1A>G= z*zavdtKpLk*zN1#`s0oEidK}-6qb)3RiKr9PZyK@jo89B_*&>D(x6ympW;c>ztPA@Xs4hTu^EH0qd zI^EDt+Et}Bjxujo_5BP%VDorjKUbKCEj!}wfM{+!2XrVx-ez-kv$^JH zjtA3=c+|jntfTIf+gOL*Hgm89kLz`>Obw5LwmzGH8qTPIC2m=VTYiIaC>OAAf}^$OR_kRh6ZIS=N z$P_MFBS=}u{SI#^+JzAYU^^f#f$f=16TIAhx%c|x-rK)CXABGESEFZl9*3@+RnLUB zgq;yI8aObt)p4{5=bNm$w5fu|5l5AEZ!zHIVA=epa1i}T>qQB{+0)Q zX&-m!|0`?ljePv)%}49M>;M0bpCt*o5ceia?Aek==cPu#NpI~*3y*P zPKfb*Z@Gq!7?}SmxyC0e<Txt?KMg*6Rai}$Q;7@YtI6S4KYom|H-sw` zdV+jV*(^#oyKR6ZG6O?>y-){jI1~@QP}flk314&@U5OgzEenNNMkI z4|OBWBeHXqWj@-Y2q;(q8Qi?$m~RTdPY3hLQtUOS-R!Q0GgJIm*k$ud zWB#(n;CLCLYZ^WqSHhi#V`#7SbJjHSC_ZAHl9WKY!Fc-{`HJZ}!9R zyu0>jb@P1ne6`=*ppDM;1~ERzNY&{z1n3iA6h?lqq>g@_)0ZMr-#`8?o~&r0re zp^)aWy>c1JnNM^VsG+6j{4*g#2fYM)E7XQx|2 zoI{&(R#x>o(AShHBp25AJcX$lLp^W+PF+iSLgWHaKsH7*L)&YW5}cjke+Lgug0oF# zfE;!OI_85OV5z0od>fBHtI{5SHOWgRui}07iV)(t1FRLZ@f6bqG&QV&=H5)EJO9h4 zq8s9NJX@B5&=k4j5K@c)H1ThTa-)zpnMwHZ72rJ4=PjUdO^&gC-F)ti`ijcZvbz@q zZ@s$AB0O@#HJ=6T8Rg%Elgs8Xys7e*=P}fwxYN#@it(r_HL!k7HVtzC9Pb>6_h>$N z3VjL*8AX7(cph9RI}cd55`apjJwRpQ#^K0q+^ycoFHgHxVAeBt9HCGDr55t`-HcV| z`F%(*)oe@1)@AD;epXMKRGMK&7FKLxWv7oNa-n2+u#43*~W?Rk61w zh2X)?Fq-r?9D3s)F!^}2hWkpT^EzxU0%=Aj!BL)DA<@2EHORxj0-GU=vA)~hbhR&v9Cq|@yn5H`m#BE*-SKe(DEVV{@NVK|yunYf_-h$}WGk>4{0JsU+c z>t?svB;p9L0mjiYS8zCkM@Y2=pPc=uR31;9G3gSW@=lV)FdK`DSOT1Mfk9FIaz3#y1l&r!5%?eOTe^gtz z0aO|#xY=x3%BP5A0?Z}8pdoQ%#Dl-|Nfo~01@x*xHyoU48Dp#rAQHV#Cn;c^%#i?N z6cskvInkNT?g0R0lX1YzYAzpYmQ`~bhbC;18O1sJTd-_1QB6W_C-+UBRwn7Ks8{ro ziWAXNuY)Ytnx^z;iG5v-P$Ezj@8Ipp-qG9b*T;?;M{jNG1!N8tDmtb<6%vrUPq6e3 z)VvdZ#bSoWiMxbiXFpqMOP5Y1t9v?$mUIvx!}um1$?iUKt===-jp@=~kr<%ifv+MTj^GgiR$zhH~6+kk5X52P__yZ-7CG*n__=P;z$~$qE51!92YvdaZ^Fj7) zqptqP7sq^k!R?I12kGId%`l3#C>6yLLN@Fk*G`yNGvbiCsgks#EuSqH#^dD99!U=T z5}QEzWH|+~)SRhOD*=DFijXE)#m9k!JF-eV?@=>h0?x=@h~%r~oZL&Iv_}Un5=vx3 zkJQhZ3t3KmbA{9x6gdq6Jfj=(To-oLH~lz+ecp}wR?_)~IL?+JBx+Sgi?Nb8vr)4* z%CNp<)Y@|skJ6}{<+`K9VJLprP{pk8c`!3hC|WAg6t*5k@U_B2=YZq?=id>8HXT3{lAJ%+RA7Ed!PgzO z`VZFq5ug&?-)R&}U@P^Ct${a`=hrd|s#S^007aMg%gl^~{?-ZtE@lY7XziHTDl;TV zIk~z_!!*)ZjRVBml?9wNiW=(_U&Fq@v+NG?NEG?-+8Zbmv%(1d0rK5xf|10JiOOpl ztN@sn`&|~%9NqEI&ikd4BP0}rh4^Ar#S9<@?^1r>93vxO!P#3LCJzMJ(PI@&@N#rFF|FI^yF+Ne+u}Z`P?MG0mjD|=n^pfwg0=DR!qY?0~ zIWHOtf5YtBz3ETn!q_2pjw;1lN6$QYPIfNn-G!;jf^$_DLhlD`O*axf;eKBlAsyx)25&;V?YWR z11Yjze2m5QSv>c__^^m74cQV6SII5xHdiHe_E6Q=O4pqoN2fir#3hgX%wi1ai6nf1 zH~`0I8Q{4A1${x%Z)C}iNZ3R^E*8mAH7Ah;Q4#aZ4 zqpZ5xYI(nWjw7p#!PR=zwi&I{H11h$+E*x54?tr#wyXz1B`t`uGe`Hl3rwRQa?AN` z7z1)ji24zF@yWZh71@e2RGF_aJ7So@q>G4;zIgxiCR2_voQqMz%Nh21)1jXGn}nAb zvszAeD3QXAKWD8DS6pBvnbCpQ;V}YvU1FeHVHh$_tb&K|@|(=6|3T%9ql!D?kq|T9 zg{mqV2Br=AZ&~DAHsMEy!P|sow^BLH7_k(nxys%;3v5*i`)AUm>gQpG!E~017D<{B z+Jwd05k1udZM56clYaUVkXZH?RC(`w5aS!x19Bl4oi{Ob;W&sH+2q*9K6fIGR_i$p zKt~)GP9OZ!ry61qoKgwZ$hwb;Qu9{lH|XQ*iz(#3EbUG;ZyHAUcdW}Bx3bT-P! z5kB4A(!ACY(8w5qW=y;F9&$6*&gm4rH#Tc@d+NvP8G^QiwG>}}%jRHFnx0{JLxD0B zWs3uGp?>ax{nTXh2{}*M(~{YZMtyH`^Yc1$7QN?KEFs|LJq6FBqv9Asu+^P;pQGjF zH>3pgy9}=)Za~7>O_C%SB6{=NT5S9Oc70{NHgAb`m}Mjreg09-Z|O+J$8(e)zXYr4 zpU*}L+vUfpR86%Wo2&yneu3~m4R5b4N62#_ujfAh0qt{A+!RhT)8)AhjjgTw;f?44A+ff?3!M&kS*JTWaHuCACH^fgR%W*`Hmvy=(W) zav(Y9dEb*YYp{CXZ?&sxSN#f*NbYpum-*kuItbRFxkZ2y5TNE0gn{oG($EDPRC86u z^R8;cduHGnk)E3Wo|~K)YKialvL{75px~f51j`3f?gATF5Qsz)f<2)O;bo%G5?(53 zirrq$@EuSP1+45ydUIs%1K3+F(Y2aV~)z)TosBHix+eH5i!f zFHXAmoBVwaxZq}YGfPJm(Lm(_#{f>jI@j=^_3r2G!*AN_Nf@8UL&)VA69`4h4JA_> zVS@ySSsb4MB`WUhXhA6D{oY`cLT8|5Pu`HB*TEcZPp?3|hE2!(7WCH8Ra4&U{dWi~ zdi$XpMf2uiyJfz#f9lIvppY93)VjGst?z!y4sSoi;6MoG%602y_^D5s_?y@Iz;B(o z9*)DhR-FFO%{|1_nx!*VR9)JhpHIeD^!ulWCXZ=e_Tnn@agr{9Ku|v#elOkjvV9Ux zZ^mjz)`}2T0KJxH3EUvC;T=<;n1Q_i&S{o>OsDZQJV`8)Uw2}J@^zjx+Y308AC3nb z{XvtiXYc!&a6{@)d^qmk?``y&{zO_`uo%lGQxs2urkPs-Pm+}|e5Hz|A5ByO8M4f+ z`TMs(lnbwKg1)TD@2Wt9gKzKVfChW_?tFW{zqyg8wDv*w_!l(E;NPgtqRZlf>^aPN zJ)Wb^>k3+0d~P&#izC&O|W-#DC!hsU&@1++i=>E1K)4d zhI1On+{khn>D5kKNBij#ShlVX&nRZajB1Tl!|OkzmD_JHiS1i#pj=k6U6=b^(K7DP zBW8~wxC-6y9}++bH_|l(CaJVT`!P8;?2n6trff>)HqfXl>}U^`%&~FMdP{QS+5)dL z>l-d)uZ5c)&`npcevHLDbQ3~>{0MCtDs8Ge zRt0-^<`}#~;M`LLHi_cPHv@5Ai+C&e6a)5iQ<|gbMt*LT?Loa^q!U;VvU+aEHdRTUOTV%=&C&s_dEQm1s7oO2PIp2>Gm^|1iK09JJ4C z3t#RDG>yt zzy=8emGBWcpONVI8!gmtH_gI8U4@7d{DCkfwjj$jbmIUo+2wBVAw<|^dw9&eFDG#( zv0T(HS5eNwFFn8Nv~p*7J}6MS7>8A;TOThCvp8LhFFHniqOdRkRULd-LVV_ADlK++ zUEyR!Q&!J%)W{HI$?+0=gwaax1T8VaO44)#u#GEK+6C3ORgD&GuGCraNO7Se`tGWt zpa`>ZluWmU^(RJhyYaP*x}+%%P5_Ise%>{5eHV$way~{bJ04xpgS=wCpug9rgziJb z9uz05Mm=Am(665KKh}V(ve_@N8Czxlc(nFGIjv=09mDA&&BtJAL{{8IK>pFL*&`bT ze%)r;KIWz#-1?kvz16-v^1E4Qu2u40!RN7wPZs#J&iXS72ncGfs!8D*@ug66MeItO z2~9smEI4cUw(7xBB>bQdD>s1dV{|e&P#KK;rrBYJ<3^>$O*&@|9DM2m7@{%1>E<%) zz$J|uL<}ekCoh4JY#?|fta*pnXJdrjEfP zXU>O#`j0+AZfv0==BF?vz@iAKzfb7R5D%bRsCM<)Gj=|y=E=%#fkf!HBHgB)#`Otz z?<$g}2^bqNelg*~%A7}E?lct{EwWqNznBic((#wJ!uQmR*MKVtS0w6;%2VWZ!gQbq zRNS=M56^`gGlK8mr|G9Db=B75e{P9Af+;(|vfhk%BW+m^syb>=pf8-+ZX|pKQFo3y z=5LJ<2|;3A^_LmpWh!v z-CuXQ|N5!h>wbIVuebi=Z_RIRhrj*T;rg~;lp1|(ZYN!S@zXiD7N6gXe>%Spf1I2^ zNw;aRY_y2Mil{|0yqP!lkU6^b8UDhXo8;GAFG;wkVsKQf_Mq^np^R9#Qru7}h&AK* zgSih?_&coV$gWJGvluM8h2l@!I@eKu@y~pRb8|zzrsB2zq{`|#iaA_Qc}F}=I1uq! zd?5mui&MwijYtpHSuJ5u9_6ILw<9Xj3q(U+uW;gd-{FrEP3v!Oq)wk~oB(2x=^dME zspZFx<=xknSsIVdl%-jO88_ejB1BE3W=m#GKC3pDZ+6fq6;m5O?z~d&Q>H0I$iRao z$LzDS&Gb&5Gn&jRti`(837q`Jx3MG=iw2fOoDBq}FmiFZyHU?~H|o{78}-25NR7S0 z9{*D-7s zBpawWRKRG%jScK1A08CsL7hd-wy7cvO2rTPX3F$@+uL!wAailLM)FZBLBaTV6+|5> zP{;(L0d;Y<8@^$PYQ<(KGIVR@w5-XbVHPD2l1iSCIaFiQ&a7B4WWcPLE%lxK!%f)t z-%GBSs6U)>NI5N|oS0@7<~lu%peZ1KW5bMRf6%Rd-R+#ImxhtQ%-N*=Zr)~x-Cy)_J)^I3f%Yt${xkZO!9hIv=S`(orYu`}|Ph-f-5; zNN8|n?YK12;L~Dq@xJgnX+D=y2fvG@)AWj?+hhHSVH19h)l^Ltz@U5G^&NhU_;`%e zTr&fFyVE6{zkq7)>yqaQym`Pp!(E>xjM-X|g@dndsvpo5Z|@Xkm(4eJ1r~-Do@mEv z_b;dlmnHlqO{Ogfw`w0Hc%Gi)d5byDF%VRD&H57~SeHQn>bB!(coqb^=kaj4U{O7e zFxqB3A#Dei1Jj@^AVyBC$f0XH^ABymdXAgPp7AE#{B;C>9+APxIeAmtwuLfO@&hI} z9J7{`a6ExD@O8Y9eYOA}q?k;aeIcP~#Z6_+0cDvVWarod#4MsmjH^Yfi?-_c{T7tK zzXUW(IUPK(nSc~PA}Mp^Y}!b zc83fjBH`PnsCG0rIPptp?)9fmGE@8iS@SH!^F|5r%uz^W1zh$1-6T1SYm(plWb=Ty zDsFaZWnz3Ht6Gz*E*z$hJlm&H_Peeeu|z4GFn^YE`|SxC*|;0x`iHu5XlfUcEzci+ zo0e?|wj=WQMKx;y_G2QYUgZk7$F^QLMwIOeuG-LIZq9#*(Thr0Vt9D~PAn|e|D3aM z3&^keev>GgG69#|4F1wI*$aF@N!zsGSGP|2uF*agSfvN%(w!%|3;4vH&~vKRDpKr~Eq&e7w{J0@oZt>mTY zjVn%Fs;NMC=-pXff(f=N3%<)W-KnVxDQ;WoGQ~bfDKrHNs_Cs>1sOocgbt2Vz2{hx zlvfqz%D+-5T5D3s+AIk~3pZl^f@a`fgh1a4dW6a%uVh?ajjpOW*DrJA?AN`M7ATq> zfI#VcEnliP@b%monSSsqLXiRYYUPk?^Z@@5-6RWyR@7C-bV-C8>$2YBWy&}aXwDbJ~$m7fZ zq>^DmZ)pLFf@`C6D%2aaE_QzW`3PkY^zZGUuaO8?8pZ0VYws{0Nt@IH-Wm;R!BDzR z#Xczi`tGpg(rve^5gn^G(WmGn*RpmnJFaXOhr3$W2ByIUAS94w%7STdi3_wVuIe*c~Tp3HUT(M{)*vzUeK zV`|6(Mor0fXEr*0!UF+qsmv7PAKF{p8^@_{v z1wDaV^LhQ0l(7}BY_8mEV-5rZ84IY!y*<`FPrHYhMKWCqg7%uV!3#lAW&TA=b(F-V zi2sZgkkLG6QExL>JT-gDZQBJ=yyK?Qj0EcfN(9NZwX%$;G$_SkFXpz|hzgZC-nezc zDNIp$k8Cz4=jQmY65eS4R$sA4_I-9G$jtqNor5>~?;r0y+1nv@Lu7T`!FDu=wP6Vt zOK2GqLjGkq!9lO*7@KnXfh8O!QNtOp$=fO-@Qe8lXuX=+z`p5Y;0&FuIe_j}7@*r% zT$No;uC&D3Ouw;?Za{fr7x*c2LWEggTh7N@G&ANeWSD4%)Sm~4L!@R8KEMp>E&h&@ zi06{KgoeI^lgAbCFUyG$M4)N94js^R7kZ}(P-9n>pt=4Om0@g9;JLNS;aTF+5i_%d{>!^(@ zphar8^2dr@tkU3v-mP06P9mnHXZ$fe>ySVrtHR&iheiQB6Op-EG6D~Rx>8A1%#EYP zu~uoJc+?fiFocREJ(}9e4=RDkK$Ru4SCNh@cYRR&vYEI-c#2fz5!9IyVh}_i# zo7H)GfluA|55S;&I7^*LxO6AKjgbmt~lUoozm;Z4MMDg zBKSvz>#XWq)AMkZ-B-#!dea?X$h9gr);u4HW@kb0m}K3R*hs21$3?n@yTZKj_wsyX zz+le8=*{aF0`@?cGg#ZxPGg;4em^O!ADSZ51^gpCoyUS@i)ut87|%h_2TvY4I-(hA z(zN2VW!oSl15*CmXFCUPe`sdl?k0&+8QKA!z{@1UIN-eqSO(yDG|tk%>=HOehUG}+ z!I490IHHm?|5Diz^z_IvF46SjQ*=RqKXzKs8iUD4OAU}%!kpn1gLTt{5X=OrNsi+a zP@zVPMLd};80re^t!eG()@Q8g^2jluYkX=s)RFE$U6;*YPG1Vk?ioLZ{L8SRl->Pq z{;+$1h#Iy4{b4SSH->MvDu3Q4XgL;oOg&VZr$u(Ja89wUgcyv{5FA}-94gS?p6%{D zX}0TB$a0*}G|5!44n?F6cIHOYNNBz3&kJ_zk@#ff$MR5p+gf#4rj&TIV=j^8N`x-k zI`d_WFSkX_3aXu5CiS65+!==3!OY?>LpkMFuVGQV>SQ&nL6U4G>ci(tZS^cu_J_!E zw)#Itn4_=}bPp9*^r4+U%;AJ^=th&i;@wZSu&yFn0{CU;i4*lCm0p~6TYL9>hD@fk zWT*(4N9w?X{(V<2v<|G$O6S63$$1OOPqzc~m*zkZS1=Z%OC~$*6L{2*ynp zRmyTfvMDK5D|5)d^7ole+v3huW>tw>MtBsXEWq6XN!1$S+ux*aG-d$(yvGwc_UBkV$-<-oP=&tzvPz$nEXxNxFl) zq^l+Lt4c~fEu7QYxuT#P#cJ6akA0bFZ4>GwYa$vJpu8Zr5=(!j*m_aSx`L#JCH^>L zkCHB#=4t;_N~(2I_El1@BSY60gF(*5wXTzr9g;PnS6c?$kW+cI!+^}9wvrH{c_Bf{ z1v~WsHzFCJN4mr>O)WmxF+dAu8G#4tSGR)mHS~^K+M{Y(bMa(#@|I!*Ikn>OZr4Bg zlor-1T#(e!zdl>Uv!EYtFlL>1`R@$Dr(LdnNdiM%N$Ld6Z`QxjAUcntEE!VWT&3+Z z?ZaV;oTd5gH<#jD^abcs6aJ(43&+?glYrAI93pkq}7c0XT?p3 zEr#trFg~Pe3GVCFgHd;<@#0fDKkKIR?l2kxjFH_bSuhAUyMyo^16vYvMlR$3V0&R^ zwDiQVH?(D+)_-oj+S@<)?bVxu_O11V7D+M_ec}ZwZK2uY$gPDoJYO%i9kHkfWZR)o z5aa*~Tgb`{T>|8mDFQAi7qnuJSXy-@owtkTdsU&5GbNla<#N2QF17knnU(7I%TD#1 zES`6Ffb}Rn*(%wbZUt-D4|_rD_9_U7?dxnQ=;s}ODJ=t55J!mYba!p+z)I5O@|aP4 z_%)ez%=HL}!9J+TJlUXa=@2q%k)5;0|p#hPR~I9DVVuv zfdQ_PBY=G53(Z+IqA-gz0}rgitrM zYefhxE0&88>atX1mk6N>41cvqot@w&Lx^AFwLn!s)(<6dJK2|;>Q-+D{KfH@1V7{) z*vgg6AbbU|tC%%eUPIf=W((9%nXuatAY8?PxENz@yw(d zX4X*&X70pAG zbRaSkj=~%_X`P*$UBroW?lgKH`?WgfE80JuJ>(}j-NdD|bHffAga`Q%5}uq2Q{bh9 z@g!Nez#XpM%e-z6aJuoYkjKv*gpJnprwLix*yq3;Lw?-HI`6sv<}T zUni>k2*Y_u$1sGH;R*S7J`hcQ-7z#xeo%A(+`wsg^>Jt_IxAGq&{w~YhKeU+3O-X6 z{jemoMQ+o!w{`dC)&L>!Xtl^smFw%C7MxO})aVsp?mc@nVYW4seMhz=T_5m3z^Y0p zP9`0X4OO=WrDb&hqi%aOP6?+oAM@b_e{XVU%4^yvsfjc_u3q=bx~Tji>DO?6?2~t`IKu%uwm*ezoRO5`Uf^9bQ~CUSG81eKqk?7GFeXC zCY%G{2C!45*8@a*Dmfn|2gE-itBvh0D4u92$<$C%kT2V=ob`%OoUnDkrCc7*yhoYFz>i31@ICH={P$8p!4s;daosnaY$Bss_>;=_=@p%~Gu&q1}^07*x%Y z+9Y|J@HujuY@hpccet$9_A1Nut+y5R9ff3Oqqk9Du+8ssm1f!DDBrT6P9|WyF+~C7 zj-d`28##^%gn#Z^;)BX-IkhU~KX4y|983Yx z_5j#?&cLRSgK8}+7%DJnENT*RpARCUp)To^MgRmd=i3t_+ zoe{!x=a^Y}gm5bMRqNi|a(oZP9^)pYd@^Ms1LPzd#?xq?q#1A=%&`c)hAqQ%g^TvX zvP57&M@a@WX~Y=^VSqMcib*kFH$sSxmLHnp%1oY3%p+a5j8SXQqey}#%bn1s1I08v zFolM2nKw8yYbLJPYb1n*`nF|0^2c=l>@$PN@^e7I-FifzVgbM^P3Ni2)`j7G?sOf^>cWCsPrDi(J zUeCB9VpcO!f@I_5!zqBY=Xq9+l7Y{%3$PK5@Zra9g<}AzpG;C0GCky!o$;sW0^+|w z$Nu$x|DP`(zkmAT&HgjkP=M+l41vEKr7;zu1M}-RIo``rjg#>*JKe&hP*+4p*3i== zJAGP_$3M8B&W2|y**$JA(DPMpg9Od|>o1&Y8G?WR^@%qDi{U5Z;Hgx>JacCh2%2`$#H?$h{f*1gX!T z?_*4wof*DJ>dY4K_3EnyM;?9Rd#^TXE${7Ef_P@|d;^evCx#~CODfU^nCbP6dw2TZ z-XGj=SiXm<0*AuC1-qefhqV;E;91NxLDaqmv>Md+@QP#x( z9lxssrR}r&&PTmB_mt%l@l6Mx60Q3MbD$Vhasmp8lK8P4ry`(S5Xb{u{NP8m4@^!~ zr!8RmF=^?Q)}y^;HUFZcVt8QgXma=riZRRUd4@f<>Wlg!W#TK>Ya+ZEP= zoUIeweE&Yqe#BaCc7o3V8wZlno0)XZ7z%KfZNViuRO)A9pD9Tq)jtq1KquM#BY(O? zCm)(*_hY;9m&*S_Gyr)|6O!q8nC3LCBNRy(1Gs;66<7Y(>-Fw#ZU*r0y}Nh$-#hqk zuh$>+`kRBGw{hoguiw9W*KkR_!RF?@JAVm!U(n{t|1AwYpPR1y8bN5Ai|}~47{~Ks zzN^x4FulP3`~S#)j7E)5Zf~PG1nz6ygjYpc_22|hRDod!C*vW6?hb=DX8VPcUow0s zGS>>=TiD=|WN${sj0KX*qZiF~Lf2Im#E(xeTr@)_VpztUH zRuweEMT4isWcD$dum6&b!1~FMg!L%8f9H4*9iQ~>nT>gJa_{)$&ai)ScN9e@#~b$s zcTWZ-? z>F#Ugyh#y2FaQ8%IQZwQU6m}ctJ%j5Vv&@?B%rl66b6@sW>dXG!>C?Gb06w}P+AJF z>)OLjSHV$#1<0J-J@A3G=RgRg9nUi*g4usy-kbLSToPx7hrj5g^KaeV!6RHhu##!6NN;n_l zq;sxNf+5@A7mIlB zvtmSoDZZzQN#${vhLS`@Gun70yxtd`e+^9vac3vN6; zz;-d2gPhoo&h6EJb8jb8&%ce!2*>e|4XtU4^f;Il6Osf5Wphb}4_Z_b{@6#&M4~S? zEMqhx+lTTU`*U|XlC8`&mxAo8vH>HvD{@06zYBU5`G1TSr{N?zZ_$ybF?39JRZmU9 zWZL2qnX{eY8-T$yt9rbP^TBcLJPK(NiXEox`R*C$~ z^7Pt;%ewN!;r1Cx!0y01cNMEn^Lrcnq>S?5TIZvKG1A^0g3ttXW=rjMcnivZR2V-&$w>qXjJUEaSwK-CtM~?)h7xFmo>Ie& z%s1Xu@2=eSPC#p^+F04}yu`lTH%Vs*6SO%;bv)R1VVV)dj;P5aH0%md8v?Hzky#3F zV63tsGMevYAU5YCdmETSQv?lhc`+S2clqC90Pkk~S_bfC#c~GlS~XIdT@2t|B8W-s zI|V+B+YPn`;@@obo6PYQRo>u2o7))x0Y^{(=}}_bBeK9<0iQ=3-j_?9^~UxUruK5$ zu_Ke@JP|AU*DD0nJ*GIFennkvx}&<`yL$pV6MICVs?3GLI7MWnaqIJYK?uCO(!d*a81Hj)8mf+_b9ppUXbJjS{Yr3VZEy;GEza2V4s-~|Jw)rX@{^= zmA8P|vp(GWSJ5xfEbBq4ur_+2K+Fmw^alt+j)J$v$2AT0D8QVdXAUG*X`~ZI^qA)M z7f+7w$jUFCuh=$un9gAT!dG9+L%kcxRi?0~>q5nwU}CO`#J2@=+OY4+#n~*`GQVUL zt*&mbKpvh-%N-09dvNX9acWd&8qRh6=lnOxjU`gB%BLtFTAkAVp+^;U{E=7 z5-o&w49Hoe+DU|K=|U}H0D8IVoP!eZsyQzz3V+A!y0hs|1ts^f_{K zRR=Vn4;jpA(Rgmb_BCnjy4%-{twzeF~8+*-Nr46{n$ zOlZR)bX+0m-1;mlIizCbB*fS8rZ zLr_T#EbP?Co>z6#%7;{QG5XV1ke#N>@yJLK-~@JxP>YNWP$kNIjoD$v416N2xQNfs zaIwTIi?=miSa=q2IiullIgxjN`#~Uldh$_R-9f6`Zg_|Ry1!Qe2CzfD_MWzA3L^i3 z$vHX4DE5en8J)s{Cvvu;d$9~dkOnI~%d8ShI#ny|Z4$%Q!idrK8yCHtWNl#DkQU`U zlP~#--Spg$FL_$n2A39AH2W)xy!fV7CFp9{VL$M|C&ToxPrfW1`6i)Gj&$s`6KSQ| zJmxQ&Sn?n`LAC@aVlYJlw@tEcB-uw;sk+tq9rF0*Y67{>OY6z5H8zIXrYQkaM@T5R zgcZzA)pkZ@2&ggL(YsC6I6bGzdhOjTeiYb_lQVeR;;tPhlLVb6RXf&c5`HwDEpBcg zy4Mf9Zg1OUdLgGN+b)^i3Ku3jua&cyb8ydm2X`&td35aEQ*@Y-729UTwv(>!Y@O5lbocJjH+}J4ue*1xcZ@mL{LTN91TR`=htGb^{&)P1 zP=h2G37IjtOx-$!^#EI1-%}_)s0RAU*LTMnrG9b+xu>iKgji?6F^_LAfD+p;7xepu zypt!4_7RL68@Z*4%s8FJey$|X|H(Nc(8+KJj_~Ppq4Z_}f<+&)b_KHA*YEQ(@#@rw zrDq{T|Hu#boakrJ5r)7wI#}5&8Sn(4h8SL#X@N~cjqkdGqsts32l=%8^}2nGTX@rc znJ1Z#dL0-X5o(+YN|yEOwQ<<`60mw+T=K0pU#qkaUV z1BfnI61c@6`A7A{z(=4AJ_A7=!nlKcN$2?ndog@gfObz1d8bKjC8 zdOfNUKbCQqVOQ#TwjaW5ujX7Rvg-@Z=AS;iS$Ya~1o_!KWbYd=HPT}fouR=3-{x+- zPFqqh6YV`gBKowD$zrhoMG4BlWm3on7(vMHwWoZ@H~ul^i7wrfYG7FFKqXD8y)RnR z%TrmoH7FD$TA}=YPY=m(4%;7e`1Z8}bzofj7br*)s19c9LO5CNPdO%y)uRlUkENgq z0J2HYx_`C{pu*JK0W*+E+^Ga2S+Pu6f!x{tr2T@9@vOt<^!!&dsD#Tm_bFk6p^JfO zG83RDQg+`Fn1YduOP*4YzDhZ zj2(+yw0%6?Xkc;m^WCu>Lw@*nUT*9d^chR9xKb(6`#d5@FtE{tDA3-2#|7!mmzMXi z0aa;A)%8~HpXN=D@9-4$^fyzceD8KzHtgem~$|AyMNWS8jW0FK4l? z=R&=dImpp1Vnw{_Ok$!B@<@_!SN@I_d4R`cS$%TWN{~8lmY~);LE0`XkDTRJRFm|C zj=ao=3AF79d^{+l5#=PFg9aJSbK_U7K(@J!OHA6EWOfhhYo{cNe=Uki2o+)^Ic^Sb z#cP|51O7M=`8O#TJfw>ROaKrPnrik`dIqU&!G&=Q#Ss8$0fKVF77pTNi`i;u&@*2) z$5k<%5vvtz6jqCLBFuigCxmzb?)JmT=`?d0OK&0}qjdU+WhiEpE2BLwUYSF9+Zg(08Bo|#|%0S_5GxJ`;>rv+>mQz`n%L}KrZ82 zq+Hecd5mGw9%_rXZ{pmJ>kY-s(hRCLDP%fYP}4eL$ms|)QGsPmo2$=g>*f)xY=%C* zSRI=hs+q+wjEPSw08hG0q!NzzY=}MOkkJM}sHM%SvKT+pB()Dnp#al#?7}1VT+Jd* zQmIP-`<+Aw`~OP@tpZQ9u(WUzECq`57;d8~{+>XPA1ykfOq zxI2p@-bKC!e(B|+bRfceDP~pSJbFin^m@*J{{(FqH|y;)vrhgzm|JI&^lEDl*BF^S z{c%rCfs=slh8zc5|Le)30gn;IDFO4GW8sOJ^Kp0i*!#Tt=`en0ipQxs;Tc9C_HQ1y zuheBZSA4{tH6WwXO1VwKn|e_Pxzo;EWI+MByAP+Q+OrM~8ZsMRSn@j4FxtOP=ou56 zdRREo2W4|89IU9RP3m|OVoIj;X^ULU*mq%yoEWG80@(n6X73NVe-B8Y z$ZQ}T}_bzN+?H36 zR9sRD0`b|KbS0IF6Qr(=dDRa5snG(t?|qlD<(YPG1K10TyIItSh062i_T7V~%@}<* zASN|2RTpGh;Q~^0f%0GZ4>(8w?LKxb@c+m`@nXhvh1-bRS&h1$7$j9u+gzEh70!Co{Fk^n12m{^?g@DSSM7fB_i7{Ro6r2GWz zJ4_b5wPb2%jKQlWf%Q0kLhk+8a-8o;H!e=j#a}df8wwRwHHB$|kE#QzWD;h7cffQ# zNWj)8Q(_quml8#g=T#}Y&c7((d+?Rw^@wopJVQ`t-VywgEVTT*NL`MMG}5M9WUp6s zWatH5>8^WfCggaYKK*zRgXRHzc4;{%xsw^9Z8XWDfMDg~@ii(i_7 zBwOo#63{fDqcNo`p0@jMa8U8)`G4sKu@(HdXaq1H*~p-*JgWBpkGL@7|_USB4P&X}?WTblK-%qslz|3sif3oj+=-Q(k`52X;2LAmCF`&>!wfs(mqzL$ep?aE&>#s z(%trd_4xCuX*+JXr5 zoT(?HuBDkw_A6FwS}uxf)QS}ZJ#S}a`P|hACIP)#8Yf;k0sbQHkivkfZV}W-w*bMR<11f!$TCD9 zBJmpJvriZ0>?QkgYw3(_vQCXnxg#^e2y+v79)tT+m|<*c@MfI{mLqY3xuS3lns%C>g=j{iz(c+S<_oxEOtzisrE zJFJ3)a?k=GsVE?@HZ}WNwwJ))Kny=&3 z+firNK@?;D^hIPqI-(iZ;w-oL>6Ms_0p562sA~@HoY+{>`No7#RBZ?+BY6H;CGiL8 zTc`1j%QqZ*7)%^UpXDuVQr)}3)rBd@oz}+>tgdmgMUz{)0&*-9+qF5a!3wIa`=~vX zcxRODACdBgX4=31lNm$~CX$n!AkJ4`@$|Sj)P880VSTsh-e*a)=rqc5(vn#?2yskCBZ};o5t1r2}WKDQB6-?0HA4DQ=nWRH4ydOOu<|KymnXOar z?PqcsQ(is8nN4M1`RmR{BhfD;CURZhJ{QCd9ajdtI71nMr{GWnjQNlLsCW;aG4<4? zgyoSZr#X`jzArZD$S(kI$R<6G`F-HGe$U!gQS)C2d0yxcCr{`arm2av^z|GIc2$MA ziaD#`zT;U)hRf7K6fr6V#`AFHg47r#8T>CmtYxh)ywW5&G9!Q{V1{}S%&ohGYkC7a zVgyfkp1f0r2YK|ozmw%e+Z{bKM~uYTe`n8K@R=ckKFHn1)AR|N4kBW6OOua+$f*D?u1f;%@?APC8;eW)_bzBQyky|Yg0 z358ZR7@ELpRj<&1R~gT`jsKd4^^-WIDsfpHMxP~V)_yexFsNJJ2wyMLBT^!(%(H%_ z<+%LFi&xvbz7j12%83}&q5lhvgmue{XpV;G_J3A3De|2~nqY~DClJWl96}}wndFTp ztX2LPN$wP&@?DeFA?A~cXH3nwg9G##Qw>#Gfct{{JhX6VMBNmt8u?X+miFDP>Avug z`I=To0x(FdP%D4vf6BrNrDWE<3ME}lwciE~J!ackh@u$vZQoV4ZE20NZMaK={DPPs z$6nRUNu+tEV}YtgKs>=SCa+-spEyCR>UD_Pmj68^IN9`nt^_BDs~5PT-gd_Zh08Tr z=Zh=>mJ=<)5)efntuw9&+h4PjeOq!U#Vk#rd;zIa!47?1$aQdiw-#B&NZj}_@rK+9 z9`=6}abn8Irg~Lf!T9+df6K6Szo6+N?Z#$fGz}Zv%_)PDr7)Sh0}QsJkK6N2=puuZ67R74gzm5di zcC>jeIN1=;(L@4T|HB8y>`k}-SAihMCO-#lnX7C1ViZ2r^B+%<<>nmOZt35K8XoIIVj@Wvu^t=Pn`&DHf${UF+G{!7Q(E41|@YL zEgP&zMX_iXc|Iw8#6b+^Z-Y%|rD8fvvdjeKW|puITEE=WCi*KKQ}yIF(_l&FaTwjn zUllW73^r3G(q8Oq-GAs|A4jSaep})e=eou$L9Q&FfQru#kvt4y^yNx#7lBu!b3%s6 z?w>zE#4y{UM{S7P+UYCI2S21zpICOkm=ODwsYt1bI#&mD z2;QFj^Nkj;9A&hOPR34mJA&<%p@7kx9E>yt3$4tsS`OKUJO;!+Pws1Jb=w{Tti?0|#i!WYfu2>H@3uKl zptg_z^&q{i{F|s$9dG;cjWTzBKq~|`f#+?-Jjxy8VGw?}>Ym{{oA{+^qM1?3po~^3 zJMVSsjT1-gSSg8Iv?8;z$*07JOE$hyHFuAGW(_4}JIBj@OKe1wM~}e>i4p2b05xFy z2}oP#8~g9gQCny$<$755ugFC#zVp93!vM6hUvcKV&PEO1)FWnfkq{>26-#L7WfHOZ z4Yz5EHbPhw9)Iap7jEf))KGu0Yi?~uLSo=&qp%{j9qQf37TT|&k5 zY+iWn&9kA$=YSScj7NWKUNo3MJRw6^&Gvj5|4kP0KJddp^$TQ~%9^5k*E#Q68db-V z;QL~onCGQpb$yyfmBHa+-f*8yX( zX&=l!RDAYTO*H;bsSF(g)=0!&ipH3B0$}DqEY!6cD*x{hAhL*VO5_C!v1-6xEymw@J)0&_x4*hD%3wy{ z^2ux|-yK!9&My6Xxd;+>!?HlN+Y_*ZYk^$R8!0A!S!AwR2jI}CaHLAe2=mMbt_XM@ zaCSEB1@hdKWH?BXI0kDDHLEe9tH8<9gM;4tVRz($l;vs=aBW37b8{+>jU?S@55GWw z9nwEe2>ZITGkw2W5=`;sq_Yi9^3V`Z(R!;5!2;1}QXIr50%4WTg_f1hAo9J=$d$5& zBH4cTqhEA#G~~Tp)5r7B4Mur`>1G?qNBe<;(JZCxb*5CajGNO{AMF&l3);g-(O4dY z{uJsrW<#M|1|OHM6UFK-@CZ*p5R({CN;{yaZggsl;)|+u8G+;;o5nzj;LgVM=hzsLlFQ%hmQK4iOkZHO6bXqtDhtpo&!zPB+M8 zw|OkZWQ$qD^=L}bIVb_tPc>-3SkXa!{@HR~Qx$^2qD}2E^`7&Qu|U`EwcM4gha4_B zdwj{r()o7wO)mXZY13kZi*@=sg#*lTg97xhdi-5MkyB_>e11h&Wy^`mqrkp-Fmwp2 z&=XKr2K9-(!?(ghO_GCGZ{2IR5bHegU^`=B{bl_37ZFnz*CIWeCSsYtnp7t4vUA`q2wO~$9uvH6qb);kjVhOP)CYRgvk&hs!0O~gz zlIzJQ@H6$hmdI$aW{Q=Tx93&716DhiS9s}a2I&dc+or%gqpN%3T*pf&4q2Z=H`PP= z@4n&S7|_D2iWC}zQ8FF{iiwDgU?-qWAlHfqPk##q^5eok{x6g!&GlR0091JLbR21z zJJXHiMm^+6)E0!cq=|#{=TYZ1`G6(rB#Ru;YMDIZJviG#vqcJR(6tYeO@ucNm2_p1 zB_SK%!|avq$A7$H#0sm-ijXdrRv2WkXOdD#_Cg(pgGv2 z=t-21#N}+Jv&;A8^lC!fTMuT_1VEWH*sEv_b?5#PmQ-da4KoHX9FAyfp_)SF=;l90 z(}r|O=>sqv&<`(8P`C6Rwbb1m&@?R|7)h2}(s9hcI!SsqHBgYlDVOzduwJ0zemKp+ z+CDN1Bp%QecV1^ZEAS7RD@++7Uk{l9zP{!xP0%mq{m7=%8-Bu+SJSO7k0>SRbGxA< zpR%1nnGDXQ;v_ryAw3NWFy|Zfu!^Kz;jz-jBFO`KthO?>W3Ka8jW>gn6iQ@G{Ig63 z-EpQ8*+650xH0lq>P*vW?B{%cra-}+P>uOhL~|Vw!OfbnX5 zcodzdFk8WUqDjq~w4<&&=cR>0mdqkC+(Vd~MT=i?gF-9CujlFFg^nkXd+gHPNK>Vr zDv`@=ID^zIAX{RB+#!q;f(qP-@RP0iPKyVyIRX2h<)Og}Yzm;;p*maRU5TXSd7iGiN&apMbCaol-4DULY|S*KTCV|F#LhJ$uG&;_^JU0W%HTvQYRG ztSyrJ_lOhaW9!PG_Wk1DtGbRNbHKY>)z$`gWEyyxK2=Tw+^CpwlL@C%Y*MM%1Ml|g zZZNlVWcaZrgi_$h?VO^yM31lcKEI_JSqCwtve!U*^n99kM++6aua_jM54-VYkY?a= z?11L4hi1jRrNq~PSi5^1uI0Zs-h(5YU38<%Niq zPy|yBRKb#9K|K7U2tUf60>;YEnpp5t_?D-c2JvEReGwgdIURei4}EtygEkmMYo7Ic zr1Q>SnUxKynZ8@RKk1YmMgU?7E@xEObWG9ThkoDhgdh6h%kJf-lY-WiPkwio>2{$B<}|wqQ0TrkmZZ?_ku8WnS=PnobL1c=)Bj2lxdVj)rvpz zYKNOZY=pAg%ZxWWYm--?o%JGj6JLC8>~^@je=D(n%)t5Y2{}_TE+tYjQdHp<@`h#K zl$Q#DE%B^!1Um$dW1T}tv#ocW-(z!4dh9lzPsh8~Yof9u%5N!uY=o~@D-CiPE*sas zmqDlwN8v4m5JLK83f5E=4wx!5<~AkuiFVTlf_hy$7S!yCjQZ6n5z)NwFS&KVEJvJD zBK-T~l5C!JN#1U3)*``l)3(=uSO5XYkp9Ax?kd8L?=4JBs%o+jVzWNLL=@=IPo5iR z`eeDDS*7mGDY1XTuMvx+&8Dpis~whI>rtk|W-qg7lU^pDo&hA=yxe0z)-rxx`4pmV ze>;v93bc=g#nOg_YVs4j>wsbl=3;u*Fe^;yurMDBLAwa{@@(Z|KhZ-a`waugUD+>W99Y@9+gfYCJT6*xjqz; zb2=}6sA}V{_ExV^h>f4>qCgYz6s6Y8)t`Nkbwd%slI2F;O0H#jWW37??HJ%~P-f3V z5>reUKBVU`@F($N5Q^jrH z71n(QcafWlW7mOt;$MV?086fjX>I2}mT>rqx=Si5OzACcVn>r6FAxUaGZh5a``-3t z{IMb#!A4=!UOk-@cDm*+#0zSZmo7<|wit3QhaK*my?ouSdkr;w4sAXXD588f)4G6) zg^%rF0cu|1w&m9ogVh$dFnrQi;OsSJFDrYjI9JdHTAZr){21^*>t=pUG|vnc^v4_G z3b5!`YKz4*JG3VwkHFG*K5YYs@C|jhBkOuaQ*-%UgwTHpO+0dJIejUp^-^K7JsaKD9_?kHc;S;qU z=8`z%tE2A%D)V=VW>fFp@}S-Q%b&`exD?eedr;2hEdf?C5z&LOFz!@0exz=v`78QS_-4oO~hc{+h z3nC)it}KyD{FO;?MoRb;02bn~5D@QBo^_JRQ5GTSZk9dIFKZzgT$CajS^$@PR*jMu z$GEGHIF@@>ZKdppCWg^BQk%ci4;^O>{}Lks#L+W_OaXzJjU=O3D$kU5MJ%3(3kh2v zU&g$URE_nlLWBb!TY1r?IcJ9JpD=yG`jxp-Phkj4dvbV=aL4STA3717n*1Ms3@tEK zBRkyrMnlR*c&{zcnP{s9F~NV)P@!B*V2UKXV~JfNxmGwDFnKLY=6%z=foGWV|3J5t zL_`bMGz|U%5*}3w?|j)VoudS&WqY7Y8d8jL9)Pk~*!0?iu{D0DTBCxeWCwy z7UfaqM%q4(_T;Qv=8l>+%^v^KVjz$ERNl#zNv?gA`WxhA=@NZ(P{p!6D8LA@hM!kH z`mAcHJ?49J$4lx5S{AcgX|i^?li?*6mO7SFR52nPjih`*$ZQPoYpv>gwLQIVnYgtw zqeixqB8VRQvAFo&b(*dl$7h6&hg)6FLB+0mdtxh#nx;bykL*cdaeVIYE--W*|5323 z+Y4*Mt<6Ge2^5vqfp9B!ziw{#^=`kZIUz_al;H#`FBp!VX=;1&eC+*^bpCv^B*}!% zs2_bESF*D_SXnk^$y^paN6v(X%?%@+3vpF(?Vcfj7qT^HtFl+F*?$ccga7_M4Nl;`iKSLHJhWk$- z3<{)mZ`=!%vf#7ruUfx{il!2=yM&HXM~54=X;-oh)gum}ZMbIRWDw7xo@g>EB7_JG zlh{e)5{aVRlP44OL~}yi2!+P|tLG0%=axils|h=JMCtWuwp1w*^t~!p|270wb>R@w zj-l-Q$@u~$jomrhfXIR3d?#cGngPJw4N50?1s%z53>f0dHY4LQ4h!Q9_`DLbrlJ!< zL&vm+YBH6Fm-D;`wJcokh}!(TT59ZBnicDqRN@FoGMpYzH01#y**I(W6}DQhaaIfv zMe8sP3(njG*wi2&^YX}_@p~{8V*iK;R;2|ffazo2zG5?^xSQU#48y|CfH0V|;W1F& zUD*jjRVXS5L_YKXaM^%I91?ndrhx-}x?Mro!q^r5BUl$m>4y&>U}i2<`Dq_Bt^VMi zVhHtOSlpPYW+YW=71Awdw5o+QwC;OQkeXNpFN-^0kk$A=u3w*-WBx#{0GkQEFc4|x zCmxTv(^LVb8y$QxBJyIAMi2@e7eeYry*L&h)9p%9t(qA|EK#XIAVxWw;vbV0aIeQ> z9wd|C6P#S3oxMXGYga=N_ukc%bD{Nao@SGQQr8n49GI%rkD_j4t{Uo(vw+{dp&Gs5 zR8h6EJ+;3caLL6T)JlJ~?!Y278>`Z6{K>T^xsVQd3{l|q*?0cbB3FXxn9*>VuvUFj z(QvQD9mSpdKKb0f0+J&sxyA(czN~bwM|yaONXBbPWWlOl2PW$1FC!ZSZEd&8Y_Aq@ z^kfNUru!;(S`TI&$0Vxdq< z&4np3d1II>-~%IQLv-(Q{(HO$lW>tyP-vpBjJ8Y`h_rl&CI+LomJml3?y^ zjTY_@u@RE?N)q27cCp`pb8z$1e9J{Elh0I#z{SCY$p24!jsl)vu zuimkpb?rnFY(+?on?}o&2AaT8&ZFl|5$!T@K z-SO|izgY)p7d?&H`F*FtU^h0@cN1>Dpv3-qUf^a!D2+8d(-b8T_F#hUkeIDmWUa}L z4l;<%8Knaq0!R7U8PFAg8n)~3!5d$xl6o#NZPUJJPU5JkQn+EylnplG%%6-L|6T4o z%6NjE!g|gihF}ZvpBbAZ>}o=X6_`JDB(H%vG{y`KyQnkKJAl2A<;d~o;>Wzj>}Ksa z2_Pkj?g*hpTqf+_Lq~W#t=xSREvT;kwwDllzC+ojsz4ABPTCj}E?Aqe`TS^xaWVLG9 zrRPM#h^YSl?}Zgu!80$T*oLfzi!M#Mtg8p=ekAf?1&fCXT`=(#7Js95Y?tJo?Jgt=fBU^K?24qlx9+?9x5q6 zW7&x+t)F16ht<~v399MuKf^Mk++BVj#jxcLG!bh$U;=Z0b(qCcOx%(%Q+m|fvf2qOwwzMyK-G-_+}ZN&2-J)*x3 zv!lYOH*!=pM7XA2%_pu$2~-VU#xYvWmQ6%C31 zTNYNsXQ!IQoVMmn7{X7QKTGQ+Uvx9|BATYOTdNM^-ciT%g@WGyY~DqI>G^}1Q&$kt z6|2u8qHgvG>J$wMq!#AiuluW)e&+HiJNxA-ez*MNs?dMxz~GYB%QCeBV|@&$g|V## z`~vmUNEgCqpi>y_bQv^?S%HeHR+DcL1c7{;&!0E;zwiF-JI%KByuX(IpO^nkjTP&| zCg-YWZZNku$$F1Gr3U!Xg9?qBAwwkLO@{`OrGJ!AVT}+@`h=fM{T6}4j=2~|rp@aAxw?3l|UM=SzCK*w#Cn{89#c9%70 zqGw3Iyd=N-hp{J`JpN~7&d{x#_MFPbc6B4Y*l&jYq%qwixG23G zx3f4o?|@(LS2{~ z&?zmQLt$P#Fvv2Y0tZ;=!(4OR7ze6Jos5VPPq=SDCV=GV@yfFkr|I3!f?9^O*JN}? zjsoJ5Pvp1Y)aCPpK=u_!Q@{^h9TNj1MC{uP+&1V{2H4z8%#s z+64T#9J&V)rVPGkd40Jnt3CK+k4c-Qc+P@-atUcRai=q|q2X()@KY&pytQN*wlVc6 zr;e4+cHQcoGvElHnX&Uj*)++ZYN|@Ca7Lk*Ydd=eW047C<1@VKQBPb;Ww`u+mo`_( zXHebm{XIfE1!S-qn@M0H^|w?7^JurXsmB>I?Ji*G;OP0JfH01~z}5B|f_sa`n!pWC zo|FQQPq}ki(_}~bF7$O9zlQkGZOMRKHkk90ApSM~haU*l=aCuL0y+_3sfd9@N~!*5 zwmJJXtVN$+l&-uIkb{=O5+rhxy75lULq14SD|fR`89YM>*9D8`-r`A6C7Y0$gl4O8O=cN%<;;# zj^LZd+KhOloLP3My9zWwfUDE=mQvRJa$XE#0VD3|4U zsAq|u_Aq6^%NZA2-$)+oYH^V-ep{m>T+pJ+m_{MIxQ1<0X(n&2cHo9%E|u74Ai}mP zG$cIB&7xs~rJSo0=La3b3lFuN=Jw3;82M9`m)ynH?Eom3VMjkf=;ob}Vd_^m?RRT0 z;bm7N2H4Q*maIZjhm;5jvv)655`mti&GtJ~JmbkE+*J(dylTLR|B{2z%p?!6*pryl zpN0E~THV$bj#bqBll*(4a!!r?_{}sX>$Agc9z?tm6p6~G_E6>#q9=!!bOF&v zuNu!WnqZf(Ak!pZ*6Q6UIf5due;`pyZU$Rjn680y5;T?D`CcXvEmtB{xFkEl;jY{H zqd<`$UFFV{s#`_JZBm%?^`*q6Mx$so*tN$G$iw?JSCvKfgq}X{hT$LSKQDOEc8erk zUc!91z^`un2X+)-nZlp^E|>U6q?U^jOj><*Sf~`aAe3IvrT|m0xeP)&**I z!kvaa7?TGKd)?@-@a{elC#MAT*MHD)E|yoLTW?Ir*tv9Np=nPu*M-j&9}k>aqA&~! zm0Vkyg1LSQ9oLx%Kwj@006xF?f%($UCkr#DDMtVzoF>HCF^pvM$v-;-O1?C$atTHD z=b5VDgN3H*2v}UjAQgsLRmH3F|4wfcV2@xc=;ejbf1XivDg&Yh%EIUsg6>2-n%1Kr zss+Rb_gBh_$YIQoXzi;UrQk=iRz=S9_hK<1OHuAc7oDJ)wE(C>#%Bvwt=Tr|sk@DQ znY@fpgjE-voA6MqT&hz?^m@eY-uW7LmT4JSp$+Jc?q4lNc;d{inwcR31Ac?69&8hw z=ag=VPLiZEfD3y~t?!29m9cym6!S>$D-Zb%!;D(wG?uld)8=IGAGTZuQf)h^SV{!C z0Fwt6MVD)+;w0_YVLEBsh=q*f*==_0p_P<%NpfT+Iyrr4K-)F>Ro1SOz6*4sm>hle zPxohjKF2=iTwLvd>7*|SvAQtdM1heM^>T|?cMe`p_)(xxbbD-cXM2& zBdm}!_uUL<6j>g6-x(nwsXRw$DHN`v?$P%r`arov{P*Zzd<9YA)fnD!*p51Kfc~VL z(79=lAVD5s)w3tBbITD>hlZiQt-gbrD|h=m$}iT>VV(})!wB8o(n)A!vuq>ReJ*kX z%Bi@w!~v&@wID>MAkV1YLbCmK=Q4R*CsbN{U{1!@ZICAnk;aug(2OgQYgJ&Yiwc$` z+R|1JI(5~-RqUy0<0q!SMH<3#kPj6Jyf!cIz3s)o2kT}8AQfwlOrqOlvsZ@IzDp|5 zB%tQUx(LMp_$K@Z7*uCPA&ts2pg*brg+q{P#$OS2f`b>}CT%phYb|+8p4G~IJPEV-0 z3CQk9i^uREC`oN~SCvCy>2a2(}Y$xs%_I1J?#958f!kq7loW#z{9eYj>c2>@fNNaV6jrmx)ISuT24Ae z+HJIxxPFW?k`Qo5bicQ|e2EPZowy|AM0+q-Pg0f_4hkfLoSB z6=6axqTr5E5DLMe$GA0V`3tYAT1%S$UR9|tnIIkUuemKhRFv!hbootM zn(Kwfm0sJrK0@q-3@ zsu4SBsAkn4esR=Ztjb$oGgT(^9LhFq!=I%4Vo6f*eZ;{4RLZLl;*gE07YKOwEUM42 znEHj|nOA-r2Xn*V3O_44h!d{A4&uo}h1s&5(r$m6z@F0-ko)Vq=5Q$~D4zl}Tbtcx z%tuY6WkMt4Jc?rJ}LN)}q$oRT%w_EV4v093TjhHd2n@10HTnKYM6CeI12 zbc=+o(kvx5Nxtjc>V!HPg@|ZUs8O?s+CY9Z9*G!D>YI3YED^N}xLm_+YIL@k?cF~7 zQf_gn&dtHTYEpkkNjvfIYM><*{-oDFsAoj2wh_rTkrNvPNy7Z2Zgg6Urp*|ssS&qW zH$-TDp)^mvz;~G|E!8YP-XlHkVsi3k#5B6rw(O$ZAlg9jU^U^7>qrypip8(FsE#7S z#z^*~-Jq0USAq=m;YaFAaXH|a2g0JCj`T+8^Gw~oCv@9E#!FT17eh{!{67`nKNa6U z72iJ<-#-=KKNa6U72iJ<-#-=K|9y(@8{kL0KGs#rMYQ(zYQpzIuI+dGaeFoKxmCL; zQM=OF*^b@U`+T*1=y$!_d$W`0_N+I%bAouawSl*}(S`c}5#)P4tsl6pVb%N8TipJ1 zR6^S;fdqU)!l%bDeA|_FUEz!)WAOdy_osK{^uh=MuiEh7y&K`fkMP^i|J#lXJ={K$ zd)5J~EkSA3qAT!Zi|o@sS&=Um-tXOz0NcUD1S`hlH$ym+DIpLx2Y4=(KiW*6#Em;L zIi8e*#kw8Q34z7+LLz|DATI!srAm%RmZ{{83ZEgHd0fiK)oK=G`20v9wQVg_0;dq` zH!L+%5ZM}0*nJw=-^5PX0k|+BnMal^ifuod-A$a7!cM=h>yM#8KV!UQYY#pSJQv6! z0hQ)8oFiih!e}<=;z_RM1rO4w5u^wg2q<4TCaUg1zLP<4)Q(;10awB75>!93qY{2* zjcCgRI&aDHbQWtRIDhK#La1hrmtQSQ7JX5k&ekuyc(B#&$hdME<*;=?tgRJUN!fw1 zc*Eq!Kr&-Z$mM&J`5uaopv$g6&v0vG?}Kc-N4smbb-m9IyO-1FTYWbjwR+c|2d{}+ zl>JlLKKJitlur) z1$#Viy;r=wzWxqp;8e)z{UCNX8SmcYh0^2uzI_cSe=uP5hiI=j?tE8Vi|wo>6l4{2 zBjEr0o7m0G9$q+xWXzu~^{NfZ-d&nL4?2$B>00%`@AABVTiX7rvHXfCe>%KRRnX5= zclF!!@j%K@pK3LDCOnd?`?fv?z*6+g++*W$)Sdt!F^w7}-(b>rXnjzG>l>kTjw zTzB)i+xWUpQt1<}7TD!pU%LiougpBlY2Yg8U#FiL^2kN-R}Ce3waYa3sX}f?rqSKJ zPkq%?Gr2c(-VZD`?=Xe99NqY>1%20kX!w5jZf|+q9oTYV`y_LmU4KV=;dW1beD*rD ze)m3q=iU#^`?r9^dzw;~IadlC(G0&n zmwm@UkxW5ubP0kqHr(GUDyqKM4JTdiGOnvM^`Z(5R5)hmNygpqt=0$G*kJ3R!}k?N zmT%{?OeE&#ddrV3?IP4n6ZeS;^~PC0oahDD-sj|t$G{8HihI z_{Jw#us>WZ`Z&s3Fe)Z)4-JIHxg`gS7s7g;Ca`;*L!}Zr$DvzTe>&`zIj|1~cSp!z zw)sI+H8#SGU(hK|J1#+eZy?slMEXCC`5?mDaZmP||Bf#mlx8;&H_SJDHw)Fqk6qQqR8Z#uZ()TWzAZ?P zzl_);YkUZee?E3#EiA;!m29&vseCWB>^RAA5VF^IUK{FhlllI|_GQUKExD`=1Y|vV zqSzm7AUR11Z0Kzf6L0B(CMP)Lq!^viK&U*(ZDfu)E4j-BukY#X{1Bzd!qW=xZvfy} zt@sL<)U1?R*s%_y@xg^nLrc6pa&uy>y3WNm<2`KdxZUFM?Oand)uNy`uMUN&ICK~0 zcmfWzE;-<0Gw%gZZ=Bqk^K4k~Nd%##aWWrqM~`YWi6+d8iqr;&QM>zwQ%Rur7;Lc4 z!$R&!th&Pz5{lCGr$H+>^f_f?2MlEv5u5E>zEur7ol;Q8Nm=RGNrPme_)&E19G3I?xWa+rywAN|cA}-Z5^%F%cA@bnKy~pFXN1#WrN5HFjj&Y93vK>7T*bl{o z#Ea?IY3AN;+$f*`a0A1wdZvYy;g+WJMp*3!CJCLWS%xBBHEO|r&DC|RKg>-yiD5;d zLd_vxiC;P6^;1#g6SnFa4luipD4f@DRI12|SsGojs(k*M^TIox#IV789Tjan^z-) zRk*}xw^58ZBAj)a}DK&~aC6@0cwZ2;>w4)etcNlV!2**V|y zPAeNDh6Db0&cdWJNe^QhdxEy)>@fp)yolIhNw9Gci9pA+94&^y&nA0o@aZ;Qn;g>^ z`|K2JwV&$ApGCq6pX@*T>Dz|IqSboBW5;PD-Uzax22Sd4o(7t(0h$UW^%HTyK`9fo zDn*)J4nm$8Yyp!q3PB>u;EEpcVVPS~1bk(#lk=M zIU*Ta50ZR7i8wd6fZ{_}p}?|B&xno3(DlyyidPOSIx_&f99R@)zyQ+boAcoYp6S*E z;xbm0^S=xZFjm^_%cwSzl^IQ?60jUnf$(i!p+lHc=&fllSD5B<#wgbdo|5(hCYwQM5=%n~kC( z&h5n(x%vP8_y0N2_5({B^vx{mT)2uas!1S@TY*Tb#8PH)Hf0M!t4GGz4Sfy)_0YWCxbk#Z{l-?FtEwD%Xp z8ruC}f03y-Poo+ACir)Qoog5BBRw!joVh12A$^t_ovIn~zp}SEHN2Ab?#lj~rceZ^ z8|GFtSp3syxWQ(#=spt;!kCtJnVY0G;wOsVA&84{Y7iAgMiL9{odIlt_>)(4APhVy zIMe*VoSoJClkl7aZ_QCvQtJz1A+NH8QSJVNyD#tZ=@pX?1C|T>V8~zu@ob=UC1wp! zXn-rv<=S1w*}{0Cis+cnCyTj4F5qZlNnS2hV%N4IG}1c~E`zD#merDLWU@~U2$I*I zkzRqKF9=Sv9NLxe=sbw!pt(BhV%6zdAYAXe(%7XSskYp!ZG!SRGXQ;QWhCT8FruO8 zBfxTdx|6gJIS4ij!l|6EVF33oySL}SUJkaAp%uuG9=#RE_M>CmSNGh2z8f4=AbgFj ziq6)m$UU#s+%GF@UZCnyosQ$Oxdk|J34u#J4c4teZFp)w)rV7VDv7Fu?Q5X7+mV4n zrJ8ZQpd8qZ`~)mlHkG8 zcALP~i|rP+x_1}E-HFPNn2Io?r`8w|caO4HqYQMUPwS${Mhbm(1&X5gprUbrjlg<6^A1NAwE3tu|-GLOfh43{aC zMA6Zd3$4vLsmgJjZLnry#9#AX2;R{ojfz?oew)i2w71%3>|6Xzd;3Os<7WAmf0lr# zI6VuJp}cXsf$XDds*bRLWviUcjk|jUL9Hy1yQx|#K)Gd{A9v@l({oI(eSxH6*0~Z( zl~LaqIZgHkRtf~ATk6oLx(U1FUtyr*x;dEK)FSb8Fp#icw*CAmjRHw_TXH9EZ$P@w zbETx3P9r87(3*`56Lb~iyTRbIL2ow@+!FYb+z5`AW6w|uzDqL*eo+F|7D)(t8eqj7 z>ODa+NP*SLk z6^X1ljE|F^EUP8c|M|t^8u6o5 zqc!$I|J-a7gDJ3F;rygVN1e$YcC7LNMNER8ijyeklWPhDy-Ks7 ztzWfa`|H3Ir}tbK+$~*SJK+t(Kj;I8h!e9~gIiTbr}n;QcB*n+0~~V|_^LmAhHD7C zbNf`z;N^;0u+2HsJi-G&p2`>;D#($oayf*Z&Md_w4>|mS6RgSh!I$$CLO>$&`b-VKXVW*9x-i5H z3F~IEl58$lQbcLm(HxyOpV*NjWp-5aT7|wu4sH#0iLWd{C%>C7-F6T3Fma|YW@jOP zRt9t!r&=Na=>D0adXYDsHDIiY)_nz$0FscOj(I>Tg$T~6F5cIYJ6X{uIw07A;Ci@y zOMwvO=d+Qw+kI(+#XMTfVKh3;86oh6ikeR=Ba$|lH+(KrOeJ)wHw4W)*l5Z-cjiSvXn^kpIn2ZMm& zfkOMEoCUk7W=lfT?dh^5GKnDzl!E~mbt1B2wxNFM@E~Ntk?}o{R`Qaxm9B=*PiTOX z^UrOcoj&@iTl)SbZFK%Zj}AkF$qpeyNP7rMATxE&oR977(U4P5&BPa18LB}Hk9Efq zakLz87lsd|d5k5Do&CRB3=t{RvMX{VoVK7)-)v#Ymz!9Od4*fEOe{>V9V-jV33Y>! zJWI_+^4P{B4qMQD@W1XJx?avy&93ymQ{`Ae|NqU^%9*;%JSk1CZbn>xlC;{T<(~g= zvr{ucu0J=9Y5qUn1l=^|9b^@1B@TY|MV zPAs&rxX%OWVpsl!s(6ezFV^9SJE=<2@2+jjIpSo_V{@Ra%i1^_f2GNu`c}cXtN&nu z&0k&g#c@2UOoNgzFwE_63j^2Lwejlbmyb5S#7i8Y8gp=LN8d0pkof?grDi9Q5nEj= zoas1JT@8Y}TCUOdM=^$yHUI-Cfl>KTLo^6XDiW(l^%;X&`LKj~5R`wL<9c>0YE)^a z46ED>Rm3TIpA|s+8G;8dAB4d}0$}iGhs03K+6ls0!*Mb0TnwZk1Q{ULhu>C`!nd!r z7k$6HLkX^F(F7!Ff01SBaa0qW?It53m=d>Q6#Bfh3;#SzVgDfn~qpe&T!-&6z3!H)k;@HIA&X63+r00@Az< z9U)FlNqIU*J*-nqQZHKemhT&^@0W|oj<0e>a3P7w*;l0Re*^-j5`LbKBYo=~NUK70 z=YWE9R-rT)?}Wk9kIO2` zi$xoeqyLY@q!_nIgq95w`T{eS1z@ZQ<5j;DtocEk0BgTC?$^?yYnjp+(X4?OpF0cp z2=*Cxn%!={9%xH2Yt!=yQCVdkRGz(D>~G-K@k}rwAqGvWC=+0kT;jk`#s^DCg3yZt z^ta>YgIAbIK6^5ilLXd8Rt_d0C!Y%ER%}+5m?QN#KO<7&tIPaI+l=0(@I-R>Q(x@V z@jKexMDoYUSgVC-`RwEz@u@sfXR*O9Zg_0zUvfL6rav6t#}?(qEWuny6ETa>zysC~ z_fs^d6G=I?f8JW`xM&fInK>Ej{Y{!?pfoTcAI5R=cN2>e&y+0{QD@2sPXuH{dUQ^! zc2|I-2~0Db>NTpi@?D+9TEsG90YvDkC!l2=u_~>y2y0<6%N0G;F5!J+4iz~5pq7|U zl>nk}OALQUi;1$|o^$4uvy+q!y*&4)v-C_B(Lf7|+DgP=t_^$2#-GgOsxoXxHb9XK zSP+W6Ni#hSa5f>qEKg#q;+xcS@Td%3H!rBnUZog z5guEY#mweY3E8T|U&>iOLe^>6dZmoD9F=Z6%S-PJyVK7#_skahSPf1Nat$JW9OgGU zZyDK(cn(M8V!JDxr!Vv14+vEpPRlD1C`hCyapNPC{Y{3zH(v z&gB{#L^dK1`6yP$WucHykQahjAYxrPlajC{GqDiFxMi`QmeKJXh^wVR`34s-9YrGv zMPxD!F_Po2-NYRF9%VT_&V!xDDHt&`8K%X^fc-9^`PLEi%n-+KaV^6qt=4xc=253x ztdWlAJSO+JRm7)UiN=*-Q9Kl`bviZPG4M}uk^o~CQ^p&evr@sF zL+%h;D*seWO2=uc5e?;pO3M<+cqwS5WgxLQgLtW7LI8Z`ULCEj?Dph{kXl2otfqg$ z(YT28iqI1d5ylfqC)3p2RWgbXdHnew=FtdZarlPF$%pr`JpaS?^_!gk>H5vum1^ZCUg?4IPtO-`_aAPb-+b`emx!j?dH1|M_<0%{`*e+WO7{W{C@5C^!iu- zdgqP;L?@9(kDCtgbE4fvI@R7%s_^H9l&CC%F-9j=dVXo95Lww!!uXYny|I$=^wvKkTukCDo6@PU-8Xj$pw}+#nZPI?Dov*e>x4zuD72VPws$n?m#CNUn^5LS# zeAC@#o3GOBbTe8M=?2?@PDzs4Ku%0pWAjb1l;oS!7=BRIB-K7ivvP6u@;oJJ>NNOa zF-%60StRgS6i!jN_bz#xkfJRL;4Ch5wM90uXRTJvtO%H6*>mMH%fPiJI~@Tbx5nHrBf@ZYm=l1^x{^Hbp0-Z6>*Wm&sS^EBd z?-9#>g|oAnw>_lfh-YV9fm>YO+LI^_emJ8IzXoh?qWBb5mp7P9gBL039mVo`|L1=c zgw(U(#Ufuc4dm?XEX<=xaYpl)jly`bVlek3B%BHEr$kBXD>LF!8p$NylfUt2rJWK17?I8uJV<8AAKtByAtPY&$0fG_f3u?Ngs2(`vftARt<~m9vj7AaCJ@s#nY8FkaEn>CaiWPhjrHe`Ml=QkN$=4ZDh7YEy{?exRiLxa{WO4_t z*lwtc#F1;D-BT#?`v|Lo#mk2RRADckrnozD6~?DoR)Cz70>JSGn;&b>HeHa7#{N5;26~f_C(qPwHG31xg z`6SJP??`k^8swB}wzT|MRbJk3Ivxl2vh!#yfu*3@*^p~5ZIz_QEDr9zB?;0e(oIkt zMqIoazqz(lUIRHEz}|K@DNbV_K^aqN7;)(uw2am$k^mvv&eQoCz3-D!7oP{uvMfFG z?XsN9NsU4I-W*Q(WE7vpnBH)4x(feTrS%D7DA<#K!fCv+r6+J&y^JSEX*Tw>carSA z;k!~AH>{Mdz^rNT{o?qL(&j@-ILz5Cwlv`j*Bz6B4lq5Rhy%9Md$lPJco7qKJJ)+0eCI0 z%-12s+qZ76z$Q`?qDk=ZWD;jS$#u@SwUG8QcrL92{IH?aa5(siGt zCo><(D3a+L6z!cyCuzEF$JC-UxEz(!<1x*_{gY^X>J>x_(mP=Er_PCEzYDXqbiS9_ z`98i{$+41g@G4Dxq?p~G;XFK};??VpfUbNJFNzc4Co2~Jr-T-hl=72j%hNv8F;tx}m9mZ{A09IwPGDtT$kB;Mp1zl=~l(|zW`m7G9R6`H{ zP}!Nf_JFzkRMt-MV$<|NSeT&CTFDb82FE?xvz9Ubqw9YIRMnUr8#| zM#4ckde}w^UXDcO1KCd_zHh7**uTwP`G!P% z-dPUVMK8n&-!6i;dRMpCt^YLBelbKZlnsO55&$DzcJ6`9qLE@C2 zq)a%Vzh6`PQpCS*2N&guQqIwe#y~AXzFZdv6jG2NZUD9MJ0#GH6bguGt$cM`>N<76 z=cILAdU%*4E9&8)w*`H5sOnVaM-2~&RWCyN@$78&T%`bE5^T{d#B~xPbP;aSw^_ONuHYchy#XVj0y8OeP zqI+gtbaGqu#;NsOFO5nFC%@|q*j$oQ&*#4;Q*5UH8om!_04w4@w}{wR>Hp2`n^*Mz zuXz56^j{(%`KW1MlaE~e!~s|Nb1jnRp=PBWQ4yh4WYMKW4m>t5A_|?ISLAkel{Xi$ zNZOVY)os{$UREXr^ko2aHn&n=$q!EuT_zy2beip1zy{n=xvj((zWJY zRfh`Ge*OBJwk5}xl~y$`kZQf9L+#+i`fGZ=F&%&7Q(#J3SH&QU3hU$u>Ac8G(yMqs z@aCv5xe{*MR9WW+0K(`3s%kMFb>LMOvP7Yz394w{I>SnoBU5mvN}xz*MKUXU*LhTc zWJe-em=YT@ErU3qUwD9V$L)g#HCBUzTJHysVr6O}O7X-_yKdtMj#bfHcd=CNx_+Q? zeq!ZjOb}50p&USz9|(!o5U9_PNX`N_RIha{)n>JpdaY|==DGrINUw7PXgJ|q{Je9w zd%S0zb~I32!QfAa@Tc?I6!z>zD!&MP9Ug31tDs&2W8|*`{k5rd5yYe$``h~#&Wv|`*_RF;>DgCw61M_;0>xe2F&(#c zse0(HBwrdy3*(Sw&h=mYI54MKv*@gAXr$D=?NqHztNVTNPTwZreAKEn0C@R;ZwbldlV8V{#GU$zW*G|`r&z$c!yz*DY=UI?n(mCebG)YgD!yY{a7#=>kp7mAuT z&Ba<9RtD`Kb$uxA23FtJ$J4Nl{cU1XOG}=HnkT{C-p#{sH~Eq^uA{D^rK>hO56ju9 z{w=RNsmZ1tkxgq<*Zyd&#niH+zZu`;Ya&ruS=Er2WH>8v>7JHSBh|ETe=O_n!$_dN z%O#k1DH^i|Y=V=1^4v6RFB}?=fEfRT&EJ44s*#4dU9xZ(g9e^Y&@~~h<`13DdTX~7 z{lv&ur0U|9X293yl-A!`0h3eqc!(UU~0@{Om48BnRs@z@of*OUmB>tXS8qgc7cVlbk%KrCPJRi;emrfnqAFkfTO`7>bTUe~Z+PIGdP>-k6c$^RzLP&;*>moXu^#h~xmZ2Hm}l8?E&KTb}mKaH`*JOPAi_Mbb47QlZ_*GRixTNrO>YM9u{GRsy1?P zx*NYOSklkh@|w0Q(d$pN1VXQD`;fF}o1?Z$tEsg^Y#8jllJM@alr+AOvL8%1C5==R zz9)JLwX?;gj+agKe>+HmuTe;UeDOsoEvbsmCkKhqKN5jYm32#yJOLUgteb_6b88KM z-gD(cUgE}6`3_w>DsL~>MFxt}t-cqr#|Rx<%(o9aAMhJrRe~ouo;}N+FY*)T3%kJg zp_;zCoFd+V%_^vTxWp#T+GbZSe?W?@*@$&QXTp0PV<3ozTTAA#YG1svxqoDvyVAKT za`?=Fs$SY`DTjk+mbX`S;@nDAn*yh5Evve#P%W=ZU>;bra^W9T?Xz$(%TJP{!lHU5 z$bPI;cZEA%`RB?TZaf*4?N;+f$>tiJEM})9yJVT!tJ!&Fj#Qshxldb@@~>;232JE{ zFgtU`uk{L=Ms8PU)s)nflK=v32#@4|13< zh9tRkxB5-vUOFg$WB!)<)!H)U^$y;DT5Q3gPKA4QG$s*^16y(DX_{@@i%f4|C*b$D zJ-e#}it4;P$uAEYy;0#|W^ZUydmmhaZ=omw6@Fux z?w6AiCrhe3Tr~!5tQSG{7uUJuLCgAQ2l_h?*{L-k@SCqKo+%)@FxtK7zrDn*0#!Jt zDeaosyS?6eXz`=G?qu>~k{8hO@~$g}*n5Wl7Rjix z6GhRpEkQ^?Y@N=M$B^k-3A3(U4?C;be3sxox7koHoyD~XvDNNRj?Hq``LNP1k{M59 z*PO?gQ?1yrmFq1o+sy{V!*WBn8OnBF2#NzpiFJ+E!1^???t6(za>wHzJFX8}Ic`*1 zd(5*jjrdS=cM>c`hx)+bYZ&U7^zd)be|&uZ@yo;e-`{=l!^6KZ$T!4O1!?Lg83PX*uYwtlzKBBeN=HRoL|wR>8GV!3$zV7gzQ@T+Zc|mvf4lSKr~1|*AfmD&X}Q5X z>$64HgDy=v>tvJtqJ6oM5TwOrDSdstu~rz|_3m z&|kgO?kv|6b|BNHwDXN%yEZd6cM7M_=DM5z_$~kZvrVDz+)ouuy|QZ7_4iG{dMkKo zN`2Eo#;#Me3Qu(gfiJ4A=Zh7+l(v;ib){p0H-F3j-05Fz9`}QG(C)1PLZwv~nzxtW zY;UVv&2G8eZXk2bON9xs?el3hSQMzB#WCUj7W1!)jovw2iYiS!0B|XHgg4Ys+O6zu zb=kT^UUq2m8p?MK8ZXrGCL^5Hv%HJL~}VO6SgrMy#ZL*rJ&J6bUdo>3v(pa+lNC@Q)JJ;OI?GV9W; zRoY%PftHO@Kd!B^0+J77%%XOA^@s}rx$^@J+-nI9t_wwt#xMQ&jbIg!8r0lXL8ZNJ zgC6L^+Zw}LCc2~0ieSF8B7*sS7^gwMx(-kWzN&WkarwaektW&x!upz6Ol!SQs;KXo zk;fv&PXGeSw>;k(?Fstscog zQ*>A@JglowGFI5)um?RIlI*CxM*McmFOdmSV}joEnNRJgO+6%zX)Ma^#RpXh=0ml9!VE7kBu2!MZfPn*FZ9HT|5T z!b&P#sr&9;;g(+xC9P2@VU#;(207}rwN7sg>_Z1L2DP9R1*%mNJqf zcdZC(M^ZFwGaumo{U{+F7(q3R<^6&)x{aP%@DZQOvuS-g+=L#Q39aj^8AXUXNU(1B5dS=!a>D4|l58U`X^8rPAr35i4EyT(c9R51fWk0@UzeUGohe9D@y~%pB-zS$MI;_5(YXdKR0yv?QqM~q>^|xO2;@tO+`Py ze6;bUU5JR&aRl>YN5-wi30+4W!L7h$4!Aln&{`J7dB>eVdXLlrvjY9o59>XNBDg^l z1;5QY)t<|fz7=FpA=$gZHh7$GyPCRCPSy8D7P?B*`tR>qlK+oX#gB0K_g_}Ze_PkC zRpq~(TQ{y<$$x*v^D)lbZKZo~!5Txq7aitLN&udaj Date: Thu, 22 Aug 2019 15:51:38 -0400 Subject: [PATCH 0860/1048] Fixed EOSIO version not able to use tags. Now reference builder by commit hash. --- .cicd/build.sh | 2 +- .cicd/helpers/dependency-info.sh | 16 +++++++++------- .cicd/tests.sh | 2 +- pipeline.jsonc | 3 +-- 4 files changed, 12 insertions(+), 11 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 0d9573ae..c099f344 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -6,7 +6,7 @@ set -eo pipefail mkdir -p $BUILD_DIR -FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} +FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 533bf1d5..38c9c4d3 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -7,20 +7,22 @@ set -eo pipefail if [[ -f "$RAW_PIPELINE_CONFIG" ]]; then echo 'Reading pipeline configuration file...' cat "$RAW_PIPELINE_CONFIG" | grep -Po '^[^"/]*("((?<=\\).|[^"])*"[^"/]*)*' | jq -c .\"eosio-dot-contracts\" > "$PIPELINE_CONFIG" - EOSIO_BRANCH=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies.eosio') - CDT_BRANCH=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies."eosio.cdt"') - CDT_VERSION=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies."cdt-version"') + CDT_VERSION=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies."eosio.cdt"') + EOSIO_VERSION=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies.eosio') else echo 'ERROR: No pipeline configuration file or dependencies file found!' exit 1 fi if [[ $TRAVIS ]]; then - CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_BRANCH && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_BRANCH) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match + CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match + EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match else - CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_BRANCH && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_BRANCH) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match + CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match + EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match fi test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_BRANCH | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_BRANCH\"..." +test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already +echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." -export BRANCH=$(echo $EOSIO_BRANCH | sed 's/\//\_/') -export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt_${CDT_VERSION}-ubuntu-18.04_amd64.deb" \ No newline at end of file +export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt_ubuntu-18.04_amd64.deb" \ No newline at end of file diff --git a/.cicd/tests.sh b/.cicd/tests.sh index abf0cd0d..d421f438 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -6,7 +6,7 @@ set -eo pipefail mkdir -p $BUILD_DIR -FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$BRANCH} +FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" diff --git a/pipeline.jsonc b/pipeline.jsonc index a339ac5b..ddf8f23b 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,8 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "release/1.8.x", - "eosio.cdt": "release/1.6.x", - "cdt-version": "1.6.2-1" + "eosio.cdt": "release/1.6.x" } } } From 65a561ccbd9bc993e3f4e58f9f75be84de9a0a7c Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 22 Aug 2019 23:17:43 +0300 Subject: [PATCH 0861/1048] add index.md from introduction.md --- docs/{01_introduction.md => index.md} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename docs/{01_introduction.md => index.md} (100%) diff --git a/docs/01_introduction.md b/docs/index.md similarity index 100% rename from docs/01_introduction.md rename to docs/index.md From b8894f48036acb5a7cb47dfe9a70465ad2d9eae1 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 22 Aug 2019 18:00:31 -0400 Subject: [PATCH 0862/1048] Fix CDT_URL. --- .cicd/helpers/dependency-info.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 38c9c4d3..ed8e09eb 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -25,4 +25,4 @@ echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_BRANCH\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." -export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt_ubuntu-18.04_amd64.deb" \ No newline at end of file +export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt-ubuntu-18.04_amd64.deb" \ No newline at end of file From b670a82b993cd7d4375f846427c7c2cfbf590ad9 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 26 Aug 2019 11:14:53 -0400 Subject: [PATCH 0863/1048] only build unit tests (and therefore depend on EOSIO) if -DBUILD_TESTS=true is provided to cmake; update build script to build unit tests only if -t flag is provided --- CMakeLists.txt | 29 ++++++++++++++++++----------- README.md | 24 ++++++++++++++---------- build.sh | 30 ++++++++++++++++++++++++------ docker/buildContracts.sh | 2 +- scripts/helper.sh | 12 ++++++------ 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d9190e60..99738d46 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts) set(VERSION_MAJOR 1) -set(VERSION_MINOR 7) +set(VERSION_MINOR 8) set(VERSION_PATCH 0) set(VERSION_SUFFIX rc1) @@ -75,13 +75,20 @@ string(REPLACE ";" "|" TEST_PREFIX_PATH "${CMAKE_PREFIX_PATH}") string(REPLACE ";" "|" TEST_FRAMEWORK_PATH "${CMAKE_FRAMEWORK_PATH}") string(REPLACE ";" "|" TEST_MODULE_PATH "${CMAKE_MODULE_PATH}") -ExternalProject_Add( - contracts_unit_tests - LIST_SEPARATOR | # Use the alternate list separator - CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_PREFIX_PATH=${TEST_PREFIX_PATH} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} -DBOOST_ROOT=${BOOST_ROOT} - SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests - BINARY_DIR ${CMAKE_BINARY_DIR}/tests - BUILD_ALWAYS 1 - TEST_COMMAND "" - INSTALL_COMMAND "" -) +set(BUILD_TESTS FALSE CACHE BOOL "Build unit tests") + +if(BUILD_TESTS) + message(STATUS "Building unit tests.") + ExternalProject_Add( + contracts_unit_tests + LIST_SEPARATOR | # Use the alternate list separator + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${TEST_BUILD_TYPE} -DCMAKE_PREFIX_PATH=${TEST_PREFIX_PATH} -DCMAKE_FRAMEWORK_PATH=${TEST_FRAMEWORK_PATH} -DCMAKE_MODULE_PATH=${TEST_MODULE_PATH} -DEOSIO_ROOT=${EOSIO_ROOT} -DLLVM_DIR=${LLVM_DIR} -DBOOST_ROOT=${BOOST_ROOT} + SOURCE_DIR ${CMAKE_SOURCE_DIR}/tests + BINARY_DIR ${CMAKE_BINARY_DIR}/tests + BUILD_ALWAYS 1 + TEST_COMMAND "" + INSTALL_COMMAND "" + ) +else() + message(STATUS "Unit tests will not be built. To build unit tests, set BUILD_TESTS to true.") +endif() diff --git a/README.md b/README.md index c610475d..464431e9 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.7.0-rc1 +## Version : 1.8.0-rc1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. @@ -15,18 +15,22 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](./contracts/eosio.token) Dependencies: -* [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.0-rc2) -* [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.1) +* [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.2) +* [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.1) (optional dependency only needed to build unit tests) -To build the contracts and the unit tests: -* First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. -* Second, make sure that you have ```sudo make install```ed __eosio__. -* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. +To build contracts alone: +1. Ensure an appropriate version of eosio.cdt is installed. Installing eosio.cdt from binaries is sufficient. +2. Run the `build.sh` script in the top directory to build all the contracts. + +To build the contracts and unit tests: +1. Ensure an appropriate version of eosio.cdt is installed. Installing eosio.cdt from binaries is sufficient. +2. Ensure an appropriate version of eosio has been built from source and installed. Installing eosio from binaries is not sufficient. +3. Run the `build.sh` script in the top directory with the `-t` flag to build all the contracts and the unit tests for these contracts. After build: -* The unit tests executable is placed in the _build/tests_ and is named __unit_test__. -* The contracts are built into a _bin/\_ folder in their respective directories. -* Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory. +* If the build was configured to also build unit tests, the unit tests executable is placed in the _build/tests_ folder and is named __unit_test__. +* The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. +* Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. ## Contributing diff --git a/build.sh b/build.sh index 53745154..558736cc 100755 --- a/build.sh +++ b/build.sh @@ -5,14 +5,17 @@ function usage() { printf "Usage: $0 OPTION... -e DIR Directory where EOSIO is installed. (Default: $HOME/eosio/X.Y) -c DIR Directory where EOSIO.CDT is installed. (Default: /usr/local/eosio.cdt) + -t Build unit tests. -y Noninteractive mode (Uses defaults for each prompt.) -h Print this help menu. \\n" "$0" 1>&2 exit 1 } +BUILD_TESTS=false + if [ $# -ne 0 ]; then - while getopts "e:c:yh" opt; do + while getopts "e:c:tyh" opt; do case "${opt}" in e ) EOSIO_DIR_PROMPT=$OPTARG @@ -20,6 +23,9 @@ if [ $# -ne 0 ]; then c ) CDT_DIR_PROMPT=$OPTARG ;; + t ) + BUILD_TESTS=true + ;; y ) NONINTERACTIVE=true PROCEED=true @@ -46,14 +52,26 @@ fi . ./scripts/.environment . ./scripts/helper.sh -# Prompt user for location of eosio. -eosio-directory-prompt +if [[ ${BUILD_TESTS} == true ]]; then + # Prompt user for location of eosio. + eosio-directory-prompt +fi # Prompt user for location of eosio.cdt. cdt-directory-prompt -# Ensure eosio version is appropriate. -nodeos-version-check +# Include CDT_INSTALL_DIR in CMAKE_FRAMEWORK_PATH +echo "Using EOSIO.CDT installation at: $CDT_INSTALL_DIR" +export CMAKE_FRAMEWORK_PATH="${CDT_INSTALL_DIR}:${CMAKE_FRAMEWORK_PATH}" + +if [[ ${BUILD_TESTS} == true ]]; then + # Ensure eosio version is appropriate. + nodeos-version-check + + # Include EOSIO_INSTALL_DIR in CMAKE_FRAMEWORK_PATH + echo "Using EOSIO installation at: $EOSIO_INSTALL_DIR" + export CMAKE_FRAMEWORK_PATH="${EOSIO_INSTALL_DIR}:${CMAKE_FRAMEWORK_PATH}" +fi printf "\t=========== Building eosio.contracts ===========\n\n" RED='\033[0;31m' @@ -61,6 +79,6 @@ NC='\033[0m' CPU_CORES=$(getconf _NPROCESSORS_ONLN) mkdir -p build pushd build &> /dev/null -cmake ../ +cmake -DBUILD_TESTS=${BUILD_TESTS} ../ make -j $CPU_CORES popd &> /dev/null diff --git a/docker/buildContracts.sh b/docker/buildContracts.sh index 52e768a3..d04dab96 100755 --- a/docker/buildContracts.sh +++ b/docker/buildContracts.sh @@ -1,6 +1,6 @@ #!/bin/bash set -e # exit on failure of any "simple" command (excludes &&, ||, or | chains) cd /eosio.contracts -./build.sh -c /usr/opt/eosio.cdt -e /opt/eosio -y +./build.sh -c /usr/opt/eosio.cdt -e /opt/eosio -t -y cd build tar -pczf /artifacts/contracts.tar.gz * diff --git a/scripts/helper.sh b/scripts/helper.sh index d08be5fe..bb3d478b 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -9,12 +9,12 @@ function check-version-numbers() { if [[ $CHECK_VERSION_MAJOR -gt $EOSIO_MAX_VERSION_MAJOR ]]; then exit 1 fi - if [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR ]]; then + if [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MIN_VERSION_MAJOR ]]; then if [[ $CHECK_VERSION_MINOR -lt $EOSIO_MIN_VERSION_MINOR ]]; then exit 1 fi fi - if [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR ]]; then + if [[ $CHECK_VERSION_MAJOR -eq $EOSIO_MAX_VERSION_MAJOR ]]; then if [[ $CHECK_VERSION_MINOR -gt $EOSIO_MAX_VERSION_MINOR ]]; then exit 1 fi @@ -73,6 +73,7 @@ function eosio-directory-prompt() { printf "$HOME/eosio/%s\n" "${PROMPT_EOSIO_DIRS[@]}" fi printf "Enter the installation location of EOSIO:" && read -e -p " " EOSIO_DIR_PROMPT; + EOSIO_DIR_PROMPT="${EOSIO_DIR_PROMPT/#\~/$HOME}" break;; * ) echo "Please type 'y' for yes or 'n' for no.";; @@ -99,6 +100,7 @@ function cdt-directory-prompt() { break;; 1 | false | [Nn]* ) printf "Enter the installation location of EOSIO.CDT:" && read -e -p " " CDT_DIR_PROMPT; + CDT_DIR_PROMPT="${CDT_DIR_PROMPT/#\~/$HOME}" break;; * ) echo "Please type 'y' for yes or 'n' for no.";; @@ -111,6 +113,7 @@ function cdt-directory-prompt() { # Ensures EOSIO is installed and compatible via version listed in tests/CMakeLists.txt. function nodeos-version-check() { + echo "EOSIO_INSTALL_DIR = ${EOSIO_INSTALL_DIR}" INSTALLED_VERSION=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version)) INSTALLED_VERSION_MAJOR=$(echo $INSTALLED_VERSION | cut -f1 -d '.' | sed 's/v//g') INSTALLED_VERSION_MINOR=$(echo $INSTALLED_VERSION | cut -f2 -d '.' | sed 's/v//g') @@ -127,12 +130,9 @@ function nodeos-version-check() { if [[ $INSTALLED_VERSION_MAJOR -eq $EOSIO_SOFT_MAX_MAJOR && $INSTALLED_VERSION_MINOR -gt $EOSIO_SOFT_MAX_MINOR ]]; then echo "Detected EOSIO version is greater than recommended soft max: $EOSIO_SOFT_MAX_MAJOR.$EOSIO_SOFT_MAX_MINOR. Proceed with caution." fi - echo "Using EOSIO installation at: $EOSIO_INSTALL_DIR" - echo "Using EOSIO.CDT installation at: $CDT_INSTALL_DIR" else echo "Supported versions are: $EOSIO_MIN_VERSION_MAJOR.$EOSIO_MIN_VERSION_MINOR - $EOSIO_MAX_VERSION_MAJOR.$EOSIO_MAX_VERSION_MINOR" echo "Invalid EOSIO installation. Exiting..." exit 1; fi - export CMAKE_FRAMEWORK_PATH="${EOSIO_INSTALL_DIR}:${CDT_INSTALL_DIR}:${CMAKE_PREFIX_PATH}" -} \ No newline at end of file +} From 0cd41d2b8e153a3316a54b0b1d80d1645046719b Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 26 Aug 2019 11:58:00 -0400 Subject: [PATCH 0864/1048] remove debugging echo --- scripts/helper.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/helper.sh b/scripts/helper.sh index bb3d478b..6ef760b3 100755 --- a/scripts/helper.sh +++ b/scripts/helper.sh @@ -113,7 +113,6 @@ function cdt-directory-prompt() { # Ensures EOSIO is installed and compatible via version listed in tests/CMakeLists.txt. function nodeos-version-check() { - echo "EOSIO_INSTALL_DIR = ${EOSIO_INSTALL_DIR}" INSTALLED_VERSION=$(echo $($EOSIO_INSTALL_DIR/bin/nodeos --version)) INSTALLED_VERSION_MAJOR=$(echo $INSTALLED_VERSION | cut -f1 -d '.' | sed 's/v//g') INSTALLED_VERSION_MINOR=$(echo $INSTALLED_VERSION | cut -f2 -d '.' | sed 's/v//g') From c85c191764685c8c3823639d0fdba7a408595ad3 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Mon, 26 Aug 2019 14:52:33 -0400 Subject: [PATCH 0865/1048] Add flag to build tests. --- .cicd/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index c099f344..98d27f1a 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -11,7 +11,7 @@ ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" -BUILD_COMMANDS="cmake .. && make -j $JOBS" +BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" From 89754b2d260a196d726809a8c500e5d6fece808a Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Mon, 26 Aug 2019 14:55:34 -0400 Subject: [PATCH 0866/1048] Add flag to build tests. --- .cicd/helpers/dependency-info.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index ed8e09eb..f29ac1cb 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -20,8 +20,8 @@ else CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match fi -test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_BRANCH | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already -echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_BRANCH\"..." +test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already +echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." From 3291ef29d17c3b3fc3b8fe967c42871e13a840e6 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 27 Aug 2019 11:50:01 -0400 Subject: [PATCH 0867/1048] add IMPORTANT file and update README --- IMPORTANT | 27 +++++++++++++++++++++++++++ README.md | 4 +++- 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 IMPORTANT diff --git a/IMPORTANT b/IMPORTANT new file mode 100644 index 00000000..ed433799 --- /dev/null +++ b/IMPORTANT @@ -0,0 +1,27 @@ +# Important Notice + +We (block.one and its affiliates) make available EOSIO and other software, updates, patches and documentation (collectively, Software) on a voluntary basis as a member of the EOSIO community. A condition of you accessing any Software, websites, articles, media, publications, documents or other material (collectively, Material) is your acceptance of the terms of this important notice. + +## Software +We are not responsible for ensuring the overall performance of Software or any related applications. Any test results or performance figures are indicative and will not reflect performance under all conditions. Software may contain components that are open sourced and subject to their own licenses; you are responsible for ensuring your compliance with those licenses. + +We make no representation, warranty, guarantee or undertaking in respect of Software, whether expressed or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the Software or the use or other dealings in the Software. + +Wallets and related components are complex software that require the highest levels of security. If incorrectly built or used, they may compromise users’ private keys and digital assets. Wallet applications and related components should undergo thorough security evaluations before being used. Only experienced developers should work with such Software. + +Material is not made available to any person or entity that is the subject of sanctions administered or enforced by any country or government or otherwise designated on any list of prohibited or restricted parties (including but not limited to the lists maintained by the United Nations Security Council, the U.S. Government, the European Union or its Member States, or other applicable government authority) or organized or resident in a country or territory that is the subject of country-wide or territory-wide sanctions. You represent and warrant that neither you nor any party having a direct or indirect beneficial interest in you or on whose behalf you are acting as agent or nominee is such a person or entity and you will comply with all applicable import, re-import, sanctions, anti-boycott, export, and re-export control laws and regulations. If this is not accurate or you do not agree, then you must immediately cease accessing our Material and delete all copies of Software. + +Any person using or offering Software in connection with providing software, goods or services to third parties shall advise such third parties of this important notice, including all limitations, restrictions and exclusions of liability. + +## Trademarks +Block.one, EOSIO, EOS, the heptahedron and associated logos and related marks are our trademarks. Other trademarks referenced in Material are the property of their respective owners. + +## Third parties +Any reference in Material to any third party or third-party product, resource or service is not an endorsement or recommendation by Block.one. We are not responsible for, and disclaim any and all responsibility and liability for, your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so information in Material may be out of date or inaccurate. + +## Forward-looking statements +Please note that in making statements expressing Block.one’s vision, we do not guarantee anything, and all aspects of our vision are subject to change at any time and in all respects at Block.one’s sole discretion, with or without notice. We call these “forward-looking statements”, which includes statements on our website and in other Material, other than statements of historical facts, such as statements regarding EOSIO’s development, expected performance, and future features, or our business strategy, plans, prospects, developments and objectives. These statements are only predictions and reflect Block.one’s current beliefs and expectations with respect to future events; they are based on assumptions and are subject to risk, uncertainties and change at any time. + +We operate in a rapidly changing environment and new risks emerge from time to time. Given these risks and uncertainties, you are cautioned not to rely on these forward-looking statements. Actual results, performance or events may differ materially from what is predicted in the forward-looking statements. Some of the factors that could cause actual results, performance or events to differ materially from the forward-looking statements include, without limitation: technical feasibility and barriers; market trends and volatility; continued availability of capital, financing and personnel; product acceptance; the commercial success of any new products or technologies; competition; government regulation and laws; and general economic, market or business conditions. + +All statements are valid only as of the date of first posting and Block.one is under no obligation to, and expressly disclaims any obligation to, update or alter any statements, whether as a result of new information, subsequent events or otherwise. Nothing in any Material constitutes technological, financial, investment, legal or other advice, either in general or with regard to any particular situation or implementation. Please consult with experts in appropriate areas before implementing or utilizing anything contained in Material. diff --git a/README.md b/README.md index 464431e9..95c2c1b9 100644 --- a/README.md +++ b/README.md @@ -46,4 +46,6 @@ The included icons are provided under the same terms as the software and accompa ## Important -See LICENSE for copyright and license terms. Block.one makes its contribution on a voluntary basis as a member of the EOSIO community and is not responsible for ensuring the overall performance of the software or any related applications. We make no representation, warranty, guarantee or undertaking in respect of the software or any related documentation, whether expressed or implied, including but not limited to the warranties or merchantability, fitness for a particular purpose and noninfringement. In no event shall we be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or documentation or the use or other dealings in the software or documentation. Any test results or performance figures are indicative and will not reflect performance under all conditions. Any reference to any third party or third-party product, service or other resource is not an endorsement or recommendation by Block.one. We are not responsible, and disclaim any and all responsibility and liability, for your use of or reliance on any of these resources. Third-party resources may be updated, changed or terminated at any time, so the information here may be out of date or inaccurate. +See [LICENSE](./LICENSE) for copyright and license terms. + +All repositories and other materials are provided subject to the terms of this [IMPORTANT](./IMPORTANT) notice and you must familiarize yourself with its terms. The notice contains important information, limitations and restrictions relating to our software, publications, trademarks, third-party resources, and forward-looking statements. By accessing any of our repositories and other materials, you accept and agree to the terms of the notice. From 4911a3630cab45b191bc2975205590ea6184691d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 28 Aug 2019 11:36:19 -0400 Subject: [PATCH 0868/1048] rename IMPORTANT to IMPORTANT.md; add link to LICENSE file in CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- IMPORTANT => IMPORTANT.md | 0 README.md | 2 +- 3 files changed, 2 insertions(+), 2 deletions(-) rename IMPORTANT => IMPORTANT.md (100%) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 76e61028..b3413262 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -100,7 +100,7 @@ Examples of unacceptable behavior include: ## Contributor License & Acknowledgments -Whenever you make a contribution to this project, you license your contribution under the same terms as set out in LICENSE, and you represent and warrant that you have the right to license your contribution under those terms. Whenever you make a contribution to this project, you also certify in the terms of the Developer’s Certificate of Origin set out below: +Whenever you make a contribution to this project, you license your contribution under the same terms as set out in [LICENSE](./LICENSE), and you represent and warrant that you have the right to license your contribution under those terms. Whenever you make a contribution to this project, you also certify in the terms of the Developer’s Certificate of Origin set out below: ``` Developer Certificate of Origin diff --git a/IMPORTANT b/IMPORTANT.md similarity index 100% rename from IMPORTANT rename to IMPORTANT.md diff --git a/README.md b/README.md index 95c2c1b9..2b759f46 100644 --- a/README.md +++ b/README.md @@ -48,4 +48,4 @@ The included icons are provided under the same terms as the software and accompa See [LICENSE](./LICENSE) for copyright and license terms. -All repositories and other materials are provided subject to the terms of this [IMPORTANT](./IMPORTANT) notice and you must familiarize yourself with its terms. The notice contains important information, limitations and restrictions relating to our software, publications, trademarks, third-party resources, and forward-looking statements. By accessing any of our repositories and other materials, you accept and agree to the terms of the notice. +All repositories and other materials are provided subject to the terms of this [IMPORTANT](./IMPORTANT.md) notice and you must familiarize yourself with its terms. The notice contains important information, limitations and restrictions relating to our software, publications, trademarks, third-party resources, and forward-looking statements. By accessing any of our repositories and other materials, you accept and agree to the terms of the notice. From cf7f3f9b5f3c7145d471dbb6ad61a1671621960e Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 1 Sep 2019 21:55:29 -0400 Subject: [PATCH 0869/1048] prevent overflow within claimrewards in cases of extreme inflation; added eosio_system_tests/extreme_inflation test --- contracts/eosio.system/src/producer_pay.cpp | 1 + tests/eosio.system_tests.cpp | 37 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index 28ec8f51..aca71172 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -83,6 +83,7 @@ namespace eosiosystem { if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { int64_t new_tokens = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); + check( new_tokens >= 0, "overflow in calculating new tokens to be issued; inflation rate is too high" ); int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; int64_t to_savings = new_tokens - to_producers; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index e4bca563..1eed42e4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -1525,6 +1525,43 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { } FC_LOG_AND_RETHROW() +BOOST_AUTO_TEST_CASE(extreme_inflation) try { + eosio_system_tester t(eosio_system_tester::setup_level::minimal); + symbol core_symbol{CORE_SYM}; + t.create_currency( N(eosio.token), config::system_account_name, asset((1ll << 62) - 1, core_symbol) ); + t.issue( asset(10000000000000, core_symbol) ); + t.deploy_contract(); + t.produce_block(); + t.create_account_with_resources(N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false); + BOOST_REQUIRE_EQUAL(t.success(), t.regproducer(N(defproducera))); + t.transfer( config::system_account_name, "defproducera", core_sym::from_string("200000000.0000"), config::system_account_name); + BOOST_REQUIRE_EQUAL(t.success(), t.stake("defproducera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); + BOOST_REQUIRE_EQUAL(t.success(), t.vote( N(defproducera), { N(defproducera) })); + t.produce_blocks(4); + t.produce_block(fc::hours(24)); + + BOOST_REQUIRE_EQUAL(t.success(), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + t.produce_block(); + asset current_supply; + { + vector data = t.get_row_by_account( N(eosio.token), core_symbol.to_symbol_code().value, N(stat), core_symbol.to_symbol_code().value ); + current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, eosio_system_tester::abi_serializer_max_time)["supply"].template as(); + } + t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply ); + BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(std::numeric_limits::max(), 50000, 40000)); + t.produce_block(); + + t.produce_block(fc::hours(10*24)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + + t.produce_block(fc::hours(11*24)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("magnitude of asset amount must be less than 2^62"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + + t.produce_block(fc::hours(24)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("overflow in calculating new tokens to be issued; inflation rate is too high"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); + BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(500, 50000, 40000)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); +} FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { From 642450faaff17791709a15426110e565439cd3c8 Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 1 Sep 2019 23:02:22 -0400 Subject: [PATCH 0870/1048] handle overflow check properly (avoid undefined behavior) --- contracts/eosio.system/src/producer_pay.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index aca71172..b8403714 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -82,8 +82,10 @@ namespace eosiosystem { const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { - int64_t new_tokens = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); - check( new_tokens >= 0, "overflow in calculating new tokens to be issued; inflation rate is too high" ); + double additional_inflation = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); + check( additional_inflation <= double(std::numeric_limits::max() - ((1ll << 10) - 1)), + "overflow in calculating new tokens to be issued; inflation rate is too high" ); + int64_t new_tokens = static_cast(additional_inflation); int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; int64_t to_savings = new_tokens - to_producers; From 6da7bece2cf0bc36867ef4abfcc244ea90e9651a Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 1 Sep 2019 23:19:22 -0400 Subject: [PATCH 0871/1048] ensure floating point math cannot possibly lead to a negative result --- contracts/eosio.system/src/producer_pay.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index b8403714..cf7e2dde 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -85,7 +85,7 @@ namespace eosiosystem { double additional_inflation = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); check( additional_inflation <= double(std::numeric_limits::max() - ((1ll << 10) - 1)), "overflow in calculating new tokens to be issued; inflation rate is too high" ); - int64_t new_tokens = static_cast(additional_inflation); + int64_t new_tokens = (additional_inflation < 0.0) ? 0 : static_cast(additional_inflation); int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; int64_t to_savings = new_tokens - to_producers; From 8f05770098794c040faf7b98cd966105b6c1ccf1 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Sep 2019 20:58:43 -0400 Subject: [PATCH 0872/1048] the minimum eosio.cdt dependency is now v1.7.x; this means that the is_feature_activated and preactivate_feature intrinsic definitions can be removed from the contracts --- CMakeLists.txt | 6 +-- README.md | 2 +- .../include/eosio.bios/eosio.bios.hpp | 41 ++++--------------- contracts/eosio.bios/src/eosio.bios.cpp | 8 ++-- contracts/eosio.msig/src/eosio.msig.cpp | 6 +-- .../include/eosio.system/native.hpp | 18 -------- contracts/eosio.system/src/native.cpp | 16 -------- pipeline.jsonc | 2 +- 8 files changed, 18 insertions(+), 81 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 99738d46..8ef311a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -3,7 +3,7 @@ cmake_minimum_required(VERSION 3.5) project(eosio_contracts) set(VERSION_MAJOR 1) -set(VERSION_MINOR 8) +set(VERSION_MINOR 9) set(VERSION_PATCH 0) set(VERSION_SUFFIX rc1) @@ -19,8 +19,8 @@ find_package(eosio.cdt) message(STATUS "Building eosio.contracts v${VERSION_FULL}") -set(EOSIO_CDT_VERSION_MIN "1.6") -set(EOSIO_CDT_VERSION_SOFT_MAX "1.6") +set(EOSIO_CDT_VERSION_MIN "1.7") +set(EOSIO_CDT_VERSION_SOFT_MAX "1.7") #set(EOSIO_CDT_VERSION_HARD_MAX "") ### Check the version of eosio.cdt diff --git a/README.md b/README.md index 2b759f46..70bcafbf 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](./contracts/eosio.token) Dependencies: -* [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.2) +* [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) * [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.1) (optional dependency only needed to build unit tests) To build contracts alone: diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 3fa4a4cd..cadc70e8 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -7,37 +7,6 @@ #include #include -// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` -#include - -namespace eosio { - namespace internal_use_do_not_use { - extern "C" { - __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); - - __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); - } - } -} - -namespace eosio { - bool is_feature_activated( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); - } - - void preactivate_feature( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); - } -} - /** * EOSIO Contracts * @@ -57,9 +26,13 @@ namespace eosio { * - eosio.token */ -namespace eosio { +namespace eosiobios { + using eosio::action_wrapper; + using eosio::check; + using eosio::checksum256; using eosio::ignore; + using eosio::name; using eosio::permission_level; using eosio::public_key; @@ -161,7 +134,7 @@ namespace eosio { * * @{ */ - class [[eosio::contract("eosio.bios")]] bios : public contract { + class [[eosio::contract("eosio.bios")]] bios : public eosio::contract { public: using contract::contract; /** @@ -420,4 +393,4 @@ namespace eosio { using reqactivated_action = action_wrapper<"reqactivated"_n, &bios::reqactivated>; }; /** @}*/ // end of @defgroup eosiobios eosio.bios -} /// namespace eosio +} /// namespace eosiobios diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index 8b9165cc..582f0334 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -1,6 +1,6 @@ #include -namespace eosio { +namespace eosiobios { void bios::setabi( name account, const std::vector& abi ) { abi_hash_table table(get_self(), get_self().value); @@ -8,11 +8,11 @@ void bios::setabi( name account, const std::vector& abi ) { if( itr == table.end() ) { table.emplace( account, [&]( auto& row ) { row.owner = account; - row.hash = sha256(const_cast(abi.data()), abi.size()); + row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); }); } else { - table.modify( itr, same_payer, [&]( auto& row ) { - row.hash = sha256(const_cast(abi.data()), abi.size()); + table.modify( itr, eosio::same_payer, [&]( auto& row ) { + row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); }); } } diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp index 8fd75213..17692192 100644 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ b/contracts/eosio.msig/src/eosio.msig.cpp @@ -30,8 +30,7 @@ void multisig::propose( ignore proposer, check( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); auto packed_requested = pack(_requested); - // TODO: Remove internal_use_do_not_use namespace after minimum eosio.cdt dependency becomes 1.7.x - auto res = internal_use_do_not_use::check_transaction_authorization( + auto res = check_transaction_authorization( trx_pos, size, (const char*)0, 0, packed_requested.data(), packed_requested.size() @@ -175,8 +174,7 @@ void multisig::exec( name proposer, name proposal_name, name executer ) { old_apptable.erase(apps); } auto packed_provided_approvals = pack(approvals); - // TODO: Remove internal_use_do_not_use namespace after minimum eosio.cdt dependency becomes 1.7.x - auto res = internal_use_do_not_use::check_transaction_authorization( + auto res = check_transaction_authorization( prop.packed_transaction.data(), prop.packed_transaction.size(), (const char*)0, 0, packed_provided_approvals.data(), packed_provided_approvals.size() diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 40a42850..854a0544 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -9,24 +9,6 @@ #include #include -// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` -#include - -namespace eosio { - namespace internal_use_do_not_use { - extern "C" { - __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); - - __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); - } - } - - bool is_feature_activated( const eosio::checksum256& feature_digest ); - void preactivate_feature( const eosio::checksum256& feature_digest ); -} - namespace eosiosystem { using eosio::checksum256; diff --git a/contracts/eosio.system/src/native.cpp b/contracts/eosio.system/src/native.cpp index a8f76304..df98daab 100644 --- a/contracts/eosio.system/src/native.cpp +++ b/contracts/eosio.system/src/native.cpp @@ -2,22 +2,6 @@ #include -namespace eosio { - bool is_feature_activated( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); - } - - void preactivate_feature( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); - } -} - namespace eosiosystem { void native::onerror( ignore, ignore> ) { diff --git a/pipeline.jsonc b/pipeline.jsonc index ddf8f23b..3b08495f 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,7 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "release/1.8.x", - "eosio.cdt": "release/1.6.x" + "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } } From 327eab305c0aefff8448ccf28092f5ee555f103e Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 13:32:44 -0400 Subject: [PATCH 0873/1048] Fix issue where specifying commit would break grep. --- .cicd/helpers/dependency-info.sh | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index f29ac1cb..fe7a1e39 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -14,12 +14,14 @@ else exit 1 fi if [[ $TRAVIS ]]; then - CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match - EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match -else - CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match - EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | grep -v 'null' | tr -d '"' | sed -n '1p') # search GitHub for commit hash by tag and branch, preferring tag if both match + AUTH="-H \"Authorization: token $key\"" fi + +# search GitHub for commit hash by tag and branch, preferring tag if both match +CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + +EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already From e69bcc591ce69ad1f9994a3176d384a88835f09e Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 13:45:23 -0400 Subject: [PATCH 0874/1048] Switch back to separate Travis command. --- .cicd/helpers/dependency-info.sh | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index fe7a1e39..75a52bac 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -13,15 +13,15 @@ else echo 'ERROR: No pipeline configuration file or dependencies file found!' exit 1 fi +# search GitHub for commit hash by tag and branch, preferring tag if both match if [[ $TRAVIS ]]; then - AUTH="-H \"Authorization: token $key\"" + CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') +else + CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') fi -# search GitHub for commit hash by tag and branch, preferring tag if both match -CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - -EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already From 1999854681d1f59973f7a346117287380664c23d Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 14:03:33 -0400 Subject: [PATCH 0875/1048] Cleanup of old auth variable. --- .cicd/helpers/dependency-info.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 75a52bac..12bd6e9a 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -15,11 +15,11 @@ else fi # search GitHub for commit hash by tag and branch, preferring tag if both match if [[ $TRAVIS ]]; then - CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') else - CDT_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - EOSIO_COMMIT=$((curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl $AUTH -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') fi test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already From da799f5293a67aa632a24ff06a521d55ed8c49f4 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Tue, 17 Sep 2019 14:06:41 -0400 Subject: [PATCH 0876/1048] Remove whitespace. --- .cicd/helpers/dependency-info.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 12bd6e9a..1ce31f3d 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -21,10 +21,8 @@ else CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') fi - test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." - export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt-ubuntu-18.04_amd64.deb" \ No newline at end of file From 03659bf07f54e757912d70f9c25c248da3e7459d Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:21:02 -0400 Subject: [PATCH 0877/1048] Remove empty lines --- .cicd/build.sh | 7 ------- .cicd/pipeline.yml | 1 - .cicd/tests.sh | 7 ------- 3 files changed, 15 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 98d27f1a..96f3eaa7 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -1,20 +1,14 @@ #!/usr/bin/env bash set -eo pipefail - . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh - mkdir -p $BUILD_DIR - FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" - PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" - COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" - # Load BUILDKITE Environment Variables for use in docker run if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="" @@ -22,5 +16,4 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi - eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 870ae96c..ab8bc6d9 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -1,5 +1,4 @@ steps: - - wait - label: ":ubuntu: Ubuntu 18.04 - Build" diff --git a/.cicd/tests.sh b/.cicd/tests.sh index d421f438..84115abb 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -1,20 +1,14 @@ #!/usr/bin/env bash set -eo pipefail - . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh - mkdir -p $BUILD_DIR - FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" - PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" TEST_COMMANDS="ctest -j $JOBS" - COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" - # Load BUILDKITE Environment Variables for use in docker run if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="" @@ -22,5 +16,4 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi - eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file From afcebdb21e170dae7d39f865eecfcc0e9034c7db Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:22:48 -0400 Subject: [PATCH 0878/1048] Switch shebang from "#!/usr/bin/env bash" to "#!/bin/bash" for security reasons --- .cicd/build.sh | 2 +- .cicd/helpers/dependency-info.sh | 2 +- .cicd/tests.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 96f3eaa7..39eff489 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/bash set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 1ce31f3d..d24f74b3 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/bash set -eo pipefail [[ "$RAW_PIPELINE_CONFIG" == '' ]] && export RAW_PIPELINE_CONFIG="$1" [[ "$RAW_PIPELINE_CONFIG" == '' ]] && export RAW_PIPELINE_CONFIG='pipeline.jsonc' diff --git a/.cicd/tests.sh b/.cicd/tests.sh index 84115abb..d366fdbd 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/bash set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh From 74021e80a29eda5cdc9d647d1bb12186268b9140 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:31:25 -0400 Subject: [PATCH 0879/1048] Consistent command-step formatting --- .cicd/pipeline.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index ab8bc6d9..ec851b43 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -2,9 +2,10 @@ steps: - wait - label: ":ubuntu: Ubuntu 18.04 - Build" - command: - - ./.cicd/build.sh - - "tar -pczf build.tar.gz build && buildkite-agent artifact upload build.tar.gz" + command: | + ./.cicd/build.sh + tar -pczf build.tar.gz build + buildkite-agent artifact upload build.tar.gz agents: queue: "automation-eos-builder-fleet" timeout: ${TIMEOUT:-10} @@ -13,9 +14,10 @@ steps: - wait - label: ":ubuntu: Ubuntu 18.04 - Test" - command: - - "buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' && tar -xzf build.tar.gz" - - ./.cicd/tests.sh + command: | + buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' + tar -xzf build.tar.gz + ./.cicd/tests.sh agents: queue: "automation-eos-builder-fleet" timeout: ${TIMEOUT:-10} From 49bd59909af71b4e92b3be20230ce73ebca08841 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:36:51 -0400 Subject: [PATCH 0880/1048] Add quotes to Buildkite variables --- .cicd/pipeline.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index ec851b43..c20d91d4 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -8,8 +8,8 @@ steps: buildkite-agent artifact upload build.tar.gz agents: queue: "automation-eos-builder-fleet" - timeout: ${TIMEOUT:-10} - skip: $SKIP_UBUNTU_18 + timeout: "${TIMEOUT:-10}" + skip: "$SKIP_UBUNTU_18" - wait @@ -20,8 +20,8 @@ steps: ./.cicd/tests.sh agents: queue: "automation-eos-builder-fleet" - timeout: ${TIMEOUT:-10} - skip: $SKIP_UBUNTU_18 + timeout: "${TIMEOUT:-10}" + skip: "$SKIP_UBUNTU_18" - wait: continue_on_failure: true From 027c8d8e69c212de54665f0c8767267b49ccb62b Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:41:13 -0400 Subject: [PATCH 0881/1048] Retry "docker pull" to protect against failures due to race conditions with eosio pipeline --- .cicd/build.sh | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.cicd/build.sh b/.cicd/build.sh index 39eff489..27a2b121 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -16,4 +16,16 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi +# retry docker pull to protect against failures due to race conditions with eosio pipeline +INDEX='1' +echo "$ docker pull $FULL_TAG" +while [[ "$(docker pull $FULL_TAG 2>&1 | grep -ice "manifest for $FULL_TAG not found")" != '0' ]]; do + echo "ERROR: Docker image \"$FULL_TAG\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' + printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://eos-coverage.s3-us-west-2.amazonaws.com/build-$BUILDKITE_BUILD_NUMBER/code-coverage-report/index.html;content=here\a for this container to exist.\n" + echo "Attempt $INDEX, retry in 60 seconds..." + echo '' + INDEX=$(( $INDEX + 1 )) + sleep 60 +done +# run eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file From b3db2046fcbeed14f105b9572504740927eeab2a Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Wed, 18 Sep 2019 16:58:42 -0400 Subject: [PATCH 0882/1048] Increase build step timeout from 10 to 40 minutes --- .cicd/pipeline.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index c20d91d4..4ea9722b 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -8,7 +8,7 @@ steps: buildkite-agent artifact upload build.tar.gz agents: queue: "automation-eos-builder-fleet" - timeout: "${TIMEOUT:-10}" + timeout: "${TIMEOUT:-40}" skip: "$SKIP_UBUNTU_18" - wait From ebccfee8b176b33be4e3717ce02685ea58b3166d Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:36:47 -0400 Subject: [PATCH 0883/1048] Always use the same container to build and test --- .cicd/build.sh | 1 + .cicd/tests.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 27a2b121..7c99994b 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -4,6 +4,7 @@ set -eo pipefail . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} +buildkite-agent meta-data set docker-image "$FULL_TAG" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" diff --git a/.cicd/tests.sh b/.cicd/tests.sh index d366fdbd..9f87e59c 100755 --- a/.cicd/tests.sh +++ b/.cicd/tests.sh @@ -3,7 +3,7 @@ set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR -FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} +FULL_TAG="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" From 8e2284d5c048e4c281c185657e89ecf1202b7e36 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:39:23 -0400 Subject: [PATCH 0884/1048] Rename tests.sh to test.sh for consistency --- .cicd/pipeline.yml | 2 +- .cicd/{tests.sh => test.sh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename .cicd/{tests.sh => test.sh} (100%) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 4ea9722b..009fe0ef 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -17,7 +17,7 @@ steps: command: | buildkite-agent artifact download build.tar.gz . --step ':ubuntu: Ubuntu 18.04 - Build' tar -xzf build.tar.gz - ./.cicd/tests.sh + ./.cicd/test.sh agents: queue: "automation-eos-builder-fleet" timeout: "${TIMEOUT:-10}" diff --git a/.cicd/tests.sh b/.cicd/test.sh similarity index 100% rename from .cicd/tests.sh rename to .cicd/test.sh From d8ed1ec6f23011997f6222d328aba4aed82537e9 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:42:04 -0400 Subject: [PATCH 0885/1048] Rename FULL_TAG to DOCKER_IMAGE for clarity --- .cicd/build.sh | 12 ++++++------ .cicd/test.sh | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 7c99994b..e2df3a87 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -3,8 +3,8 @@ set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR -FULL_TAG=${FULL_TAG:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} -buildkite-agent meta-data set docker-image "$FULL_TAG" +DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} +buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" @@ -19,9 +19,9 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then fi # retry docker pull to protect against failures due to race conditions with eosio pipeline INDEX='1' -echo "$ docker pull $FULL_TAG" -while [[ "$(docker pull $FULL_TAG 2>&1 | grep -ice "manifest for $FULL_TAG not found")" != '0' ]]; do - echo "ERROR: Docker image \"$FULL_TAG\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' +echo "$ docker pull $DOCKER_IMAGE" +while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMAGE not found")" != '0' ]]; do + echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://eos-coverage.s3-us-west-2.amazonaws.com/build-$BUILDKITE_BUILD_NUMBER/code-coverage-report/index.html;content=here\a for this container to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' @@ -29,4 +29,4 @@ while [[ "$(docker pull $FULL_TAG 2>&1 | grep -ice "manifest for $FULL_TAG not f sleep 60 done # run -eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/test.sh b/.cicd/test.sh index 9f87e59c..4bc91843 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -3,7 +3,7 @@ set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR -FULL_TAG="$(buildkite-agent meta-data get docker-image)" +DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" @@ -16,4 +16,4 @@ if [[ -f $BUILDKITE_ENV_FILE ]]; then evars="$evars --env ${var%%=*}" done < "$BUILDKITE_ENV_FILE" fi -eval docker run $ARGS $evars $FULL_TAG bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file From 7824efe7e441981c94216efc8eabd74d8da951bc Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 10:58:48 -0400 Subject: [PATCH 0886/1048] Move Buildkite environment loading into function --- .cicd/build.sh | 10 ++-------- .cicd/helpers/buildkite.sh | 11 +++++++++++ .cicd/test.sh | 10 ++-------- 3 files changed, 15 insertions(+), 16 deletions(-) create mode 100755 .cicd/helpers/buildkite.sh diff --git a/.cicd/build.sh b/.cicd/build.sh index e2df3a87..4a32d65c 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -1,5 +1,6 @@ #!/bin/bash set -eo pipefail +. ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR @@ -10,13 +11,6 @@ CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dp PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" -# Load BUILDKITE Environment Variables for use in docker run -if [[ -f $BUILDKITE_ENV_FILE ]]; then - evars="" - while read -r var; do - evars="$evars --env ${var%%=*}" - done < "$BUILDKITE_ENV_FILE" -fi # retry docker pull to protect against failures due to race conditions with eosio pipeline INDEX='1' echo "$ docker pull $DOCKER_IMAGE" @@ -29,4 +23,4 @@ while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMA sleep 60 done # run -eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/helpers/buildkite.sh b/.cicd/helpers/buildkite.sh new file mode 100755 index 00000000..1d2eee39 --- /dev/null +++ b/.cicd/helpers/buildkite.sh @@ -0,0 +1,11 @@ +# load buildkite intrinsic environment variables for use in docker run +function buildkite-intrinsics() +{ + BK_ENV='' + if [[ -f $BUILDKITE_ENV_FILE ]]; then + while read -r var; do + BK_ENV="$BK_ENV --env ${var%%=*}" + done < "$BUILDKITE_ENV_FILE" + fi + echo "$BK_ENV" +} \ No newline at end of file diff --git a/.cicd/test.sh b/.cicd/test.sh index 4bc91843..b54d1fac 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -1,5 +1,6 @@ #!/bin/bash set -eo pipefail +. ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR @@ -9,11 +10,4 @@ CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dp PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" TEST_COMMANDS="ctest -j $JOBS" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" -# Load BUILDKITE Environment Variables for use in docker run -if [[ -f $BUILDKITE_ENV_FILE ]]; then - evars="" - while read -r var; do - evars="$evars --env ${var%%=*}" - done < "$BUILDKITE_ENV_FILE" -fi -eval docker run $ARGS $evars $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file From a5474d70d270f078308b95aaf2957f255e7ed801 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 11:36:03 -0400 Subject: [PATCH 0887/1048] Remove dependency-info.sh from test.sh --- .cicd/test.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/.cicd/test.sh b/.cicd/test.sh index b54d1fac..836494de 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -2,7 +2,6 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh -. ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} From a14ed3b07dea7eafd68a6b96cebd413ae2c6c90d Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 11:43:27 -0400 Subject: [PATCH 0888/1048] Revert "Remove dependency-info.sh from test.sh" as it is needed for CDT installation This reverts commit a5474d70d270f078308b95aaf2957f255e7ed801. --- .cicd/test.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/.cicd/test.sh b/.cicd/test.sh index 836494de..b54d1fac 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -2,6 +2,7 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh +. ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} From fa8d8ea78d76410950efe65b5d4a9eb20a3a0fc4 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 11:56:50 -0400 Subject: [PATCH 0889/1048] Fix Buildkite URL in Docker pull retry message --- .cicd/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 4a32d65c..acc2c4a6 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -16,7 +16,7 @@ INDEX='1' echo "$ docker pull $DOCKER_IMAGE" while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMAGE not found")" != '0' ]]; do echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' - printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://eos-coverage.s3-us-west-2.amazonaws.com/build-$BUILDKITE_BUILD_NUMBER/code-coverage-report/index.html;content=here\a for this container to exist.\n" + printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio/builds?commit=$BUILDKITE_COMMIT;content=here\a for this container to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' INDEX=$(( $INDEX + 1 )) From 0c1e13ce7841e93317dfa4a1a448d48cc517c043 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 13:16:53 -0400 Subject: [PATCH 0890/1048] Use the EOSIO_COMMIT for the URL, not the BUILDKITE_COMMIT --- .cicd/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index acc2c4a6..721df2c5 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -16,7 +16,7 @@ INDEX='1' echo "$ docker pull $DOCKER_IMAGE" while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMAGE not found")" != '0' ]]; do echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' - printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio/builds?commit=$BUILDKITE_COMMIT;content=here\a for this container to exist.\n" + printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio/builds?commit=$EOSIO_COMMIT;content=here\a for this container to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' INDEX=$(( $INDEX + 1 )) From d8e19380bbaf545548211072b89b5ea4e14f1eb9 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 13:21:57 -0400 Subject: [PATCH 0891/1048] Use the same CDT binary for both the build and test step --- .cicd/build.sh | 2 ++ .cicd/test.sh | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 721df2c5..c8519bb6 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -6,6 +6,8 @@ set -eo pipefail mkdir -p $BUILD_DIR DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" +buildkite-agent meta-data set cdt-url "$CDT_URL" +buildkite-agent meta-data set cdt-version "$CDT_VERSION" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" diff --git a/.cicd/test.sh b/.cicd/test.sh index b54d1fac..4eaecffa 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -2,8 +2,9 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh -. ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR +CDT_URL="$(buildkite-agent meta-data get cdt-url)" +CDT_VERSION="$(buildkite-agent meta-data get cdt-version)" DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" From a75612498a8d76c85ea21827e52594d574eacbb3 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 15:29:23 -0400 Subject: [PATCH 0892/1048] Export dependency and Docker information as variables on Travis --- .cicd/build.sh | 12 +++++++++--- .cicd/test.sh | 8 +++++--- .travis.yml | 2 +- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index c8519bb6..bf97c186 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -5,9 +5,15 @@ set -eo pipefail . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} -buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" -buildkite-agent meta-data set cdt-url "$CDT_URL" -buildkite-agent meta-data set cdt-version "$CDT_VERSION" +if [[ "$BUILDKITE" == 'true' ]]; then + buildkite-agent meta-data set cdt-url "$CDT_URL" + buildkite-agent meta-data set cdt-version "$CDT_VERSION" + buildkite-agent meta-data set docker-image "$DOCKER_IMAGE" +else + export CDT_URL + export CDT_VERSION + export DOCKER_IMAGE +fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" diff --git a/.cicd/test.sh b/.cicd/test.sh index 4eaecffa..52153019 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -3,9 +3,11 @@ set -eo pipefail . ./.cicd/helpers/buildkite.sh . ./.cicd/helpers/general.sh mkdir -p $BUILD_DIR -CDT_URL="$(buildkite-agent meta-data get cdt-url)" -CDT_VERSION="$(buildkite-agent meta-data get cdt-version)" -DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" +if [[ "$BUILDKITE" == 'true' ]]; then + CDT_URL="$(buildkite-agent meta-data get cdt-url)" + CDT_VERSION="$(buildkite-agent meta-data get cdt-version)" + DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" +fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" diff --git a/.travis.yml b/.travis.yml index fd9aeb34..57b617af 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ matrix: - os: linux dist: xenial services: docker -script: "./.cicd/build.sh && ./.cicd/tests.sh" +script: ". ./.cicd/build.sh && ./.cicd/tests.sh" notifications: webhooks: secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= From cbc4f3a4b59145c99485e73645833308897cbdf1 Mon Sep 17 00:00:00 2001 From: Zach Butler Date: Thu, 19 Sep 2019 15:50:03 -0400 Subject: [PATCH 0893/1048] Fix travis.yml test invocation --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 57b617af..51635525 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ matrix: - os: linux dist: xenial services: docker -script: ". ./.cicd/build.sh && ./.cicd/tests.sh" +script: ". ./.cicd/build.sh && ./.cicd/test.sh" notifications: webhooks: secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= From 22dac816140da101ec11c98503564a268b4f0f48 Mon Sep 17 00:00:00 2001 From: Sandwich <“dskvr@users.noreply.github.com”> Date: Thu, 26 Sep 2019 14:59:25 +0200 Subject: [PATCH 0894/1048] Had to make some modifications to some of the inline comments so they would not be picked up by mdjavadoc, which we are temporarily using until we can get standardese to correctly parse the documentation on eosio.contracts --- .../include/eosio.system/eosio.system.hpp | 142 +++++++----------- 1 file changed, 53 insertions(+), 89 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index b98db352..d2903efd 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -74,9 +74,6 @@ namespace eosiosystem { static constexpr int64_t default_votepay_factor = 4; // 25% of the producer pay /** - * - * @defgroup eosiosystem eosio.system - * @ingroup eosiocontracts * eosio.system contract defines the structures and actions needed for blockchain's core functionality. * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or * delegate their vote to a proxy. @@ -88,13 +85,11 @@ namespace eosiosystem { * @{ */ - /** - * A name bid, which consists of: - * - a `newname` name that the bid is for - * - a `high_bidder` account name that is the one with the highest bid so far - * - the `high_bid` which is amount of highest bid - * - and `last_bid_time` which is the time of the highest bid - */ + // A name bid, which consists of: + // - a `newname` name that the bid is for + // - a `high_bidder` account name that is the one with the highest bid so far + // - the `high_bid` which is amount of highest bid + // - and `last_bid_time` which is the time of the highest bid struct [[eosio::table, eosio::contract("eosio.system")]] name_bid { name newname; name high_bidder; @@ -105,11 +100,9 @@ namespace eosiosystem { uint64_t by_high_bid()const { return static_cast(-high_bid); } }; - /** - * A bid refund, which is defined by: - * - the `bidder` account name owning the refund - * - the `amount` to be refunded - */ + // A bid refund, which is defined by: + // - the `bidder` account name owning the refund + // - the `amount` to be refunded struct [[eosio::table, eosio::contract("eosio.system")]] bid_refund { name bidder; asset amount; @@ -122,9 +115,7 @@ namespace eosiosystem { typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; - /** - * Defines new global state parameters. - */ + // Defines new global state parameters. struct [[eosio::table("global"), eosio::contract("eosio.system")]] eosio_global_state : eosio::blockchain_parameters { uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } @@ -151,9 +142,7 @@ namespace eosiosystem { (last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) }; - /** - * Defines new global state parameters added after version 1.0 - */ + // Defines new global state parameters added after version 1.0 struct [[eosio::table("global2"), eosio::contract("eosio.system")]] eosio_global_state2 { eosio_global_state2(){} @@ -167,9 +156,7 @@ namespace eosiosystem { (total_producer_votepay_share)(revision) ) }; - /** - * Defines new global state parameters added after version 1.3.0 - */ + // Defines new global state parameters added after version 1.3.0 struct [[eosio::table("global3"), eosio::contract("eosio.system")]] eosio_global_state3 { eosio_global_state3() { } time_point last_vpay_state_update; @@ -178,9 +165,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) }; - /** - * Defines new global state parameters to store inflation rate and distribution - */ + // Defines new global state parameters to store inflation rate and distribution struct [[eosio::table("global4"), eosio::contract("eosio.system")]] eosio_global_state4 { eosio_global_state4() { } double continuous_rate; @@ -190,9 +175,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state4, (continuous_rate)(inflation_pay_factor)(votepay_factor) ) }; - /** - * Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 - */ + // Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { name owner; double total_votes = 0; @@ -213,9 +196,7 @@ namespace eosiosystem { (unpaid_blocks)(last_claim_time)(location) ) }; - /** - * Defines new producer info structure to be stored in new producer info table, added after version 1.3.0 - */ + // Defines new producer info structure to be stored in new producer info table, added after version 1.3.0 struct [[eosio::table, eosio::contract("eosio.system")]] producer_info2 { name owner; double votepay_share = 0; @@ -227,30 +208,23 @@ namespace eosiosystem { EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) }; - /** - * Voter info. Voter info stores information about the voter: - * - `owner` the voter - * - `proxy` the proxy set by the voter, if any - * - `producers` the producers approved by this voter if no proxy set - * - `staked` the amount staked - */ + // Voter info. Voter info stores information about the voter: + // - `owner` the voter + // - `proxy` the proxy set by the voter, if any + // - `producers` the producers approved by this voter if no proxy set + // - `staked` the amount staked struct [[eosio::table, eosio::contract("eosio.system")]] voter_info { name owner; /// the voter name proxy; /// the proxy set by the voter, if any std::vector producers; /// the producers approved by this voter if no proxy set int64_t staked = 0; - /** - * Every time a vote is cast we must first "undo" the last vote weight, before casting the - * new vote weight. Vote weight is calculated as: - * - * stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) - */ + // Every time a vote is cast we must first "undo" the last vote weight, before casting the + // new vote weight. Vote weight is calculated as: + // stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) double last_vote_weight = 0; /// the vote weight cast the last time the vote was updated - /** - * Total vote weight delegated to this voter. - */ + // Total vote weight delegated to this voter. double proxied_vote_weight= 0; /// the total vote weight delegated to this voter as a proxy bool is_proxy = 0; /// whether the voter is a proxy for others @@ -303,9 +277,7 @@ namespace eosiosystem { EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(ram_bytes) ) }; - /** - * Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. - */ + // Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. struct [[eosio::table, eosio::contract("eosio.system")]] delegated_bandwidth { name from; name to; @@ -338,17 +310,15 @@ namespace eosiosystem { typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; - /** - * `rex_pool` structure underlying the rex pool table. A rex pool table entry is defined by: - * - `version` defaulted to zero, - * - `total_lent` total amount of CORE_SYMBOL in open rex_loans - * - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), - * - `total_rent` fees received in exchange for lent (connector), - * - `total_lendable` total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent), - * - `total_rex` total number of REX shares allocated to contributors to total_lendable, - * - `namebid_proceeds` the amount of CORE_SYMBOL to be transferred from namebids to REX pool, - * - `loan_num` increments with each new loan. - */ + // `rex_pool` structure underlying the rex pool table. A rex pool table entry is defined by: + // - `version` defaulted to zero, + // - `total_lent` total amount of CORE_SYMBOL in open rex_loans + // - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), + // - `total_rent` fees received in exchange for lent (connector), + // - `total_lendable` total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent), + // - `total_rex` total number of REX shares allocated to contributors to total_lendable, + // - `namebid_proceeds` the amount of CORE_SYMBOL to be transferred from namebids to REX pool, + // - `loan_num` increments with each new loan struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { uint8_t version = 0; asset total_lent; @@ -364,12 +334,10 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; - /** - * `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: - * - `version` defaulted to zero, - * - `owner` the owner of the rex fund, - * - `balance` the balance of the fund. - */ + // `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: + // - `version` defaulted to zero, + // - `owner` the owner of the rex fund, + // - `balance` the balance of the fund. struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { uint8_t version = 0; name owner; @@ -380,14 +348,12 @@ namespace eosiosystem { typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; - /** - * `rex_balance` structure underlying the rex balance table. A rex balance table entry is defined by: - * - `version` defaulted to zero, - * - `owner` the owner of the rex fund, - * - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, - * - `rex_balance` the amount of REX owned by owner, - * - `matured_rex` matured REX available for selling. - */ + // `rex_balance` structure underlying the rex balance table. A rex balance table entry is defined by: + // - `version` defaulted to zero, + // - `owner` the owner of the rex fund, + // - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, + // - `rex_balance` the amount of REX owned by owner, + // - `matured_rex` matured REX available for selling struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { uint8_t version = 0; name owner; @@ -401,18 +367,16 @@ namespace eosiosystem { typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; - /** - * `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. A rex net/cpu loan table entry is defined by: - * - `version` defaulted to zero, - * - `from` account creating and paying for loan, - * - `receiver` account receiving rented resources, - * - `payment` SYS tokens paid for the loan, - * - `balance` is the amount of SYS tokens available to be used for loan auto-renewal, - * - `total_staked` total amount staked, - * - `loan_num` loan number/id, - * - `expiration` the expiration time when loan will be either closed or renewed - * If payment <= balance, the loan is renewed, and closed otherwise. - */ + // `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. A rex net/cpu loan table entry is defined by: + // - `version` defaulted to zero, + // - `from` account creating and paying for loan, + // - `receiver` account receiving rented resources, + // - `payment` SYS tokens paid for the loan, + // - `balance` is the amount of SYS tokens available to be used for loan auto-renewal, + // - `total_staked` total amount staked, + // - `loan_num` loan number/id, + // - `expiration` the expiration time when loan will be either closed or renewed + // If payment <= balance, the loan is renewed, and closed otherwise. struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { uint8_t version = 0; name from; From f7eb4f77fefa9bb4ca111859cb5474fcbbe6da43 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 27 Sep 2019 20:47:46 -0400 Subject: [PATCH 0895/1048] the minimum eosio dependency is now v2.0.x; update tests to work with eosio v2.0.x --- README.md | 2 +- pipeline.jsonc | 2 +- tests/CMakeLists.txt | 4 +- tests/eosio.msig_tests.cpp | 62 +++++++++++------- tests/eosio.system_tester.hpp | 105 ++++++++++++++++++++++++++---- tests/eosio.system_tests.cpp | 119 +++++++++++++++++----------------- tests/eosio.token_tests.cpp | 6 +- tests/eosio.wrap_tests.cpp | 22 +++---- 8 files changed, 210 insertions(+), 112 deletions(-) diff --git a/README.md b/README.md index 70bcafbf..52663847 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ The following unprivileged contract(s) are also part of the system. Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) -* [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.1) (optional dependency only needed to build unit tests) +* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) (optional dependency only needed to build unit tests) To build contracts alone: 1. Ensure an appropriate version of eosio.cdt is installed. Installing eosio.cdt from binaries is sufficient. diff --git a/pipeline.jsonc b/pipeline.jsonc index 3b08495f..c06f57fc 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,7 +4,7 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "release/1.8.x", + "eosio": "26ed54d90f4e5436faac7fda0f6a0eabbbccc6e2", // eventually update to release/2.0.x "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index a1423648..2048afff 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required( VERSION 3.5 ) -set(EOSIO_VERSION_MIN "1.8") -set(EOSIO_VERSION_SOFT_MAX "1.8") +set(EOSIO_VERSION_MIN "2.0") +set(EOSIO_VERSION_SOFT_MAX "2.0") #set(EOSIO_VERSION_HARD_MAX "") find_package(eosio) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index e28e229c..cbc614b9 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -181,7 +181,7 @@ transaction eosio_msig_tester::reqauth( account_name from, const vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); + auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -313,7 +313,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { - auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); + auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); //try with not enough requested auth BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -406,10 +406,17 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) // / | \ <--- implicitly updated in onblock action // alice active bob active carol active - set_authority(N(eosio), "active", authority(1, - vector{{get_private_key("eosio", "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}}), "owner", - { { N(eosio), "active" } }, { get_private_key( N(eosio), "active" ) }); + set_authority( + config::system_account_name, + config::active_name, + authority( 1, + vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, + vector{{{N(eosio.prods), config::active_name}, 1}} + ), + config::owner_name, + {{config::system_account_name, config::active_name}}, + {get_private_key(config::system_account_name, "active")} + ); set_producers( {N(alice),N(bob),N(carol)} ); produce_blocks(50); @@ -421,7 +428,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); issue(config::system_account_name, core_sym::from_string("1000000000.0000")); BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); @@ -436,7 +443,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, {N(carol), config::active_name} }; @@ -524,10 +531,17 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ) try { // set up the link between (eosio active) and (eosio.prods active) - set_authority(N(eosio), "active", authority(1, - vector{{get_private_key("eosio", "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}}), "owner", - { { N(eosio), "active" } }, { get_private_key( N(eosio), "active" ) }); + set_authority( + config::system_account_name, + config::active_name, + authority( 1, + vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, + vector{{{N(eosio.prods), config::active_name}, 1}} + ), + config::owner_name, + {{config::system_account_name, config::active_name}}, + {get_private_key(config::system_account_name, "active")} + ); create_accounts( { N(apple) } ); set_producers( {N(alice),N(bob),N(carol), N(apple)} ); @@ -539,7 +553,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); issue(config::system_account_name, core_sym::from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( "eosio" ) ); + BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( config::system_account_name ) ); set_code( config::system_account_name, contracts::system_wasm() ); set_abi( config::system_account_name, contracts::system_abi().data() ); @@ -555,7 +569,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); + get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, {N(carol), config::active_name}, {N(apple), config::active_name}}; @@ -653,7 +667,7 @@ BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -696,7 +710,7 @@ BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( propose_invalidate_approve, eosio_msig_tester ) try { - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") @@ -752,7 +766,7 @@ BOOST_FIXTURE_TEST_CASE( approve_execute_old, eosio_msig_tester ) try { produce_blocks(); //propose with old version of eosio.msig - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -797,7 +811,7 @@ BOOST_FIXTURE_TEST_CASE( approve_unapprove_old, eosio_msig_tester ) try { produce_blocks(); //propose with old version of eosio.msig - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -839,7 +853,7 @@ BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); produce_blocks(); - auto trx = reqauth("alice", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); + auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); push_action( N(alice), N(propose), mvo() ("proposer", "alice") ("proposal_name", "first") @@ -895,7 +909,7 @@ BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { - auto trx = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); auto trx_hash = fc::sha256::hash( trx ); auto not_trx_hash = fc::sha256::hash( trx_hash ); @@ -944,7 +958,7 @@ BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( switch_proposal_and_fail_approve_with_hash, eosio_msig_tester ) try { - auto trx1 = reqauth("alice", {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); + auto trx1 = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); auto trx1_hash = fc::sha256::hash( trx1 ); push_action( N(alice), N(propose), mvo() @@ -954,7 +968,7 @@ BOOST_FIXTURE_TEST_CASE( switch_proposal_and_fail_approve_with_hash, eosio_msig_ ("requested", vector{{ N(alice), config::active_name }}) ); - auto trx2 = reqauth("alice", + auto trx2 = reqauth( N(alice), { permission_level{N(alice), config::active_name}, permission_level{N(alice), config::owner_name} }, abi_serializer_max_time ); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 179d4b0f..753df1a1 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -23,9 +23,9 @@ using mvo = fc::mutable_variant_object; #endif #endif - namespace eosio_system { + class eosio_system_tester : public TESTER { public: @@ -249,13 +249,23 @@ class eosio_system_tester : public TESTER { action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { return push_action( payer, N(buyram), mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); } + action_result buyram( std::string_view payer, std::string_view receiver, const asset& eosin ) { + return buyram( account_name(payer), account_name(receiver), eosin ); + } + action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { return push_action( payer, N(buyrambytes), mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); } + action_result buyrambytes( std::string_view payer, std::string_view receiver, uint32_t numbytes ) { + return buyrambytes( account_name(payer), account_name(receiver), numbytes ); + } action_result sellram( const account_name& account, uint64_t numbytes ) { return push_action( account, N(sellram), mvo()( "account", account)("bytes",numbytes) ); } + action_result sellram( std::string_view account, uint64_t numbytes ) { + return sellram( account_name(account), numbytes ); + } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { string action_type_name = abi_ser.get_action_type(name); @@ -265,7 +275,7 @@ class eosio_system_tester : public TESTER { act.name = name; act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); } action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { @@ -277,10 +287,16 @@ class eosio_system_tester : public TESTER { ("transfer", 0 ) ); } + action_result stake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { + return stake( account_name(from), account_name(to), net, cpu ); + } action_result stake( const account_name& acnt, const asset& net, const asset& cpu ) { return stake( acnt, acnt, net, cpu ); } + action_result stake( std::string_view acnt, const asset& net, const asset& cpu ) { + return stake( account_name(acnt), net, cpu ); + } action_result stake_with_transfer( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), N(delegatebw), mvo() @@ -291,10 +307,16 @@ class eosio_system_tester : public TESTER { ("transfer", true ) ); } + action_result stake_with_transfer( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { + return stake_with_transfer( account_name(from), account_name(to), net, cpu ); + } action_result stake_with_transfer( const account_name& acnt, const asset& net, const asset& cpu ) { return stake_with_transfer( acnt, acnt, net, cpu ); } + action_result stake_with_transfer( std::string_view acnt, const asset& net, const asset& cpu ) { + return stake_with_transfer( account_name(acnt), net, cpu ); + } action_result unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { return push_action( name(from), N(undelegatebw), mvo() @@ -304,10 +326,16 @@ class eosio_system_tester : public TESTER { ("unstake_cpu_quantity", cpu) ); } + action_result unstake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { + return unstake( account_name(from), account_name(to), net, cpu ); + } action_result unstake( const account_name& acnt, const asset& net, const asset& cpu ) { return unstake( acnt, acnt, net, cpu ); } + action_result unstake( std::string_view acnt, const asset& net, const asset& cpu ) { + return unstake( account_name(acnt), net, cpu ); + } int64_t bancor_convert( int64_t S, int64_t R, int64_t T ) { return double(R) * T / ( double(S) + T ); }; @@ -565,7 +593,7 @@ class eosio_system_tester : public TESTER { fc::variant get_loan_info( const uint64_t& loan_num, bool cpu ) const { name table_name = cpu ? N(cpuloan) : N(netloan); - vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, loan_num ); + vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, account_name(loan_num) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer_max_time ); } @@ -669,6 +697,9 @@ class eosio_system_tester : public TESTER { ("bid", bid) ); } + action_result bidname( std::string_view bidder, std::string_view newname, const asset& bid ) { + return bidname( account_name(bidder), account_name(newname), bid ); + } static fc::variant_object producer_parameters_example( int n ) { return mutable_variant_object() @@ -710,35 +741,54 @@ class eosio_system_tester : public TESTER { ("proxy", proxy) ("producers", producers)); } + action_result vote( const account_name& voter, const std::vector& producers, std::string_view proxy ) { + return vote( voter, producers, account_name(proxy) ); + } uint32_t last_block_time() const { return time_point_sec( control->head_block_time() ).sec_since_epoch(); } asset get_balance( const account_name& act, symbol balance_symbol = symbol{CORE_SYM} ) { - vector data = get_row_by_account( N(eosio.token), act, N(accounts), balance_symbol.to_symbol_code().value ); + vector data = get_row_by_account( N(eosio.token), act, N(accounts), account_name(balance_symbol.to_symbol_code().value) ); return data.empty() ? asset(0, balance_symbol) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); } + asset get_balance( std::string_view act, symbol balance_symbol = symbol{CORE_SYM} ) { + return get_balance( account_name(act), balance_symbol ); + } + fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); } + fc::variant get_total_stake( std::string_view act ) { + return get_total_stake( account_name(act) ); + } fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); } + fc::variant get_voter_info( std::string_view act ) { + return get_voter_info( account_name(act) ); + } fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); } + fc::variant get_producer_info( std::string_view act ) { + return get_producer_info( account_name(act) ); + } fc::variant get_producer_info2( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers2), act ); return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer_max_time ); } + fc::variant get_producer_info2( std::string_view act ) { + return get_producer_info2( account_name(act) ); + } void create_currency( name contract, name manager, asset maxsupply ) { auto act = mutable_variant_object() @@ -765,6 +815,18 @@ class eosio_system_tester : public TESTER { ); } + void transfer( const name& from, std::string_view to, const asset& amount, const name& manager = config::system_account_name ) { + transfer( from, name(to), amount, manager ); + } + + void transfer( std::string_view from, std::string_view to, const asset& amount, std::string_view manager ) { + transfer( name(from), name(to), amount, name(manager) ); + } + + void transfer( std::string_view from, std::string_view to, const asset& amount ) { + transfer( name(from), name(to), amount ); + } + void issue_and_transfer( const name& to, const asset& amount, const name& manager = config::system_account_name ) { signed_transaction trx; trx.actions.emplace_back( get_action( N(eosio.token), N(issue), @@ -791,6 +853,18 @@ class eosio_system_tester : public TESTER { push_transaction( trx ); } + void issue_and_transfer( std::string_view to, const asset& amount, std::string_view manager ) { + issue_and_transfer( name(to), amount, name(manager) ); + } + + void issue_and_transfer( std::string_view to, const asset& amount, const name& manager ) { + issue_and_transfer( name(to), amount, manager); + } + + void issue_and_transfer( std::string_view to, const asset& amount ) { + issue_and_transfer( name(to), amount ); + } + double stake2votes( asset stake ) { auto now = control->pending_block_time().time_since_epoch().count() / 1000000; return stake.get_amount() * pow(2, int64_t((now - (config::block_timestamp_epoch / 1000)) / (86400 * 7))/ double(52) ); // 52 week periods (i.e. ~years) @@ -803,7 +877,7 @@ class eosio_system_tester : public TESTER { fc::variant get_stats( const string& symbolname ) { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); + vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } @@ -840,7 +914,7 @@ class eosio_system_tester : public TESTER { abi_serializer msig_abi_ser; { create_account_with_resources( N(eosio.msig), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( "eosio", "eosio.msig", core_sym::from_string("5000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), buyram( N(eosio), N(eosio.msig), core_sym::from_string("5000.0000") ) ); produce_block(); auto trace = base_tester::push_action(config::system_account_name, N(setpriv), @@ -863,8 +937,8 @@ class eosio_system_tester : public TESTER { vector active_and_vote_producers() { //stake more than 15% of total EOS supply to activate chain - transfer( "eosio", "alice1111111", core_sym::from_string("650000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); + transfer( N(eosio), N(alice1111111), core_sym::from_string("650000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), N(alice1111111), core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers std::vector producer_names; @@ -896,9 +970,9 @@ class eosio_system_tester : public TESTER { //vote for producers { - transfer( config::system_account_name, "alice1111111", core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake( "alice1111111", core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("30000000.0000") ) ); + transfer( config::system_account_name, N(alice1111111), core_sym::from_string("100000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL(success(), stake( N(alice1111111), core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000") ) ); + BOOST_REQUIRE_EQUAL(success(), buyram( N(alice1111111), N(alice1111111), core_sym::from_string("30000000.0000") ) ); BOOST_REQUIRE_EQUAL(success(), push_action(N(alice1111111), N(voteproducer), mvo() ("voter", "alice1111111") ("proxy", name(0).to_string()) @@ -981,14 +1055,23 @@ inline fc::mutable_variant_object voter( account_name acct ) { ("is_proxy", 0) ; } +inline fc::mutable_variant_object voter( std::string_view acct ) { + return voter( account_name(acct) ); +} inline fc::mutable_variant_object voter( account_name acct, const asset& vote_stake ) { return voter( acct )( "staked", vote_stake.get_amount() ); } +inline fc::mutable_variant_object voter( std::string_view acct, const asset& vote_stake ) { + return voter( account_name(acct), vote_stake ); +} inline fc::mutable_variant_object voter( account_name acct, int64_t vote_stake ) { return voter( acct )( "staked", vote_stake ); } +inline fc::mutable_variant_object voter( std::string_view acct, int64_t vote_stake ) { + return voter( account_name(acct), vote_stake ); +} inline fc::mutable_variant_object proxy( account_name acct ) { return voter( acct )( "is_proxy", 1 ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 1eed42e4..ce51882f 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -126,17 +126,17 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); BOOST_REQUIRE_EQUAL( false, get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), symbol{SY(4,RAMCORE)}.value() ).empty() ); + N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ).empty() ); auto get_ram_market = [this]() -> fc::variant { vector data = get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), symbol{SY(4,RAMCORE)}.value() ); + N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ); BOOST_REQUIRE( !data.empty() ); return abi_ser.binary_to_variant("exchange_state", data, abi_serializer_max_time); }; { - transfer( config::system_account_name, "alice1111111", core_sym::from_string("10000000.0000"), config::system_account_name ); + transfer( config::system_account_name, N(alice1111111), core_sym::from_string("10000000.0000"), config::system_account_name ); uint64_t bytes0 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); auto market = get_ram_market(); @@ -157,7 +157,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { } { - transfer( config::system_account_name, "bob111111111", core_sym::from_string("100000.0000"), config::system_account_name ); + transfer( config::system_account_name, N(bob111111111), core_sym::from_string("100000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must reserve a positive amount"), buyrambytes( "bob111111111", "bob111111111", 1 ) ); @@ -246,7 +246,7 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try //eosio stakes for alice with transfer flag transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //check that alice has both bandwidth and voting power auto total = get_total_stake("alice1111111"); @@ -287,7 +287,7 @@ BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() @@ -298,7 +298,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot use transfer flag if delegating to self"), - stake_with_transfer( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) + stake_with_transfer( N(alice1111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() @@ -310,7 +310,7 @@ BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { //eosio stakes for alice with transfer flag transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "bob111111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); //check that alice has both bandwidth and voting power auto total = get_total_stake("alice1111111"); @@ -351,7 +351,7 @@ BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); } FC_LOG_AND_RETHROW() @@ -634,7 +634,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("250.0000") ), get_voter_info( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); - auto refund = get_refund_request( "alice1111111" ); + auto refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); //XXX auto request_time = refund["request_time"].as_int64(); @@ -646,7 +646,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("350.0000") ), get_voter_info( "alice1111111" ) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); @@ -655,7 +655,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { total = get_total_stake( "alice1111111" ); BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("50.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("25.0000"), refund["cpu_amount"].as() ); //request time should stay the same @@ -669,7 +669,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); //pending refund should be removed - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_TEST_REQUIRE( refund.is_null() ); //balance should stay the same BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); @@ -680,7 +680,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); @@ -690,7 +690,7 @@ BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("700.0000") ), get_voter_info( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_TEST_REQUIRE( refund.is_null() ); //200 core tokens should be taken from alice's account BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_balance( "alice1111111" ) ); @@ -713,7 +713,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tes //unstake BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - auto refund = get_refund_request( "alice1111111" ); + auto refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); //auto orig_request_time = refund["request_time"].as_int64(); @@ -725,7 +725,7 @@ BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tes BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); //stake should be taken from alices' balance, and refund request should stay the same BOOST_REQUIRE_EQUAL( core_sym::from_string("400.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( "alice1111111" ); + refund = get_refund_request( N(alice1111111) ); BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); //BOOST_REQUIRE_EQUAL( orig_request_time, refund["request_time"].as_int64() ); @@ -851,7 +851,7 @@ BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_t //bob111111111 increases his stake BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("33.0000"), core_sym::from_string("0.3333") ) ); //alice1111111 stake with transfer to bob111111111 - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( "alice1111111", "bob111111111", core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); + BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); //should increase alice1111111's total_votes prod = get_producer_info( "alice1111111" ); BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("88.8888")) == prod["total_votes"].as_double() ); @@ -1088,7 +1088,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", true ) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //unregister proxy BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() @@ -1106,7 +1106,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "bob111111111" )( "staked", 3000003 ), get_voter_info( "bob111111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(bob111111111) )( "staked", 3000003 ), get_voter_info( "bob111111111" ) ); //unrgister and check that stake is still in place BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() ("proxy", "bob111111111") @@ -1124,7 +1124,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tes issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("246.0002"), core_sym::from_string("531.0001") ) ); //check that both proxy flag and stake a correct - REQUIRE_MATCHING_OBJECT( proxy( "carol1111111" )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(carol1111111) )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); //unregister BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() @@ -1146,25 +1146,25 @@ BOOST_FIXTURE_TEST_CASE( proxy_stake_unstake_keeps_proxy_flag, eosio_system_test ) ); issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //stake BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); //stake more BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0000"), core_sym::from_string("20.0000") ) ); //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); //unstake more BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); //unstake the rest BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 0 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 0 ), get_voter_info( "alice1111111" ) ); } FC_LOG_AND_RETHROW() @@ -1173,9 +1173,9 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * cross_15_percent_threshold(); create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); //register as a proxy BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -1188,7 +1188,7 @@ BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), vector(), N(alice1111111) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); //vote for producers BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); @@ -1463,7 +1463,7 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera),N(defproducerb),N(defproducerc) })); auto run_for_1year = [this](int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor) { - + double inflation = double(annual_rate)/double(10000); BOOST_REQUIRE_EQUAL(success(), setinflation( @@ -1485,7 +1485,7 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { } const asset final_supply = get_token_supply(); const int64_t final_savings = get_balance(N(eosio.saving)).get_amount(); - + double computed_new_tokens = double(final_supply.get_amount() - initial_supply.get_amount()); double theoretical_new_tokens = double(initial_supply.get_amount())*inflation; double diff_new_tokens = std::abs(theoretical_new_tokens-computed_new_tokens); @@ -1516,8 +1516,8 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { // 1% inflation for 1 year. 50% savings / 50% bp reward. 10000 / 50000 = 0.2 => 20% blockpay, 80% votepay run_for_1year(100, 20000, 50000); - // 3% inflation for 1 year. 66.6% savings / 33.33% bp reward. 10000/13333 = 0.75 => 75% blockpay, 25% votepay - run_for_1year(300, 30000, 13333); + // 3% inflation for 1 year. 66.6% savings / 33.33% bp reward. 10000/13333 = 0.75 => 75% blockpay, 25% votepay + run_for_1year(300, 30000, 13333); // 0% inflation for 1 year run_for_1year(0, 30000, 50000); @@ -1544,7 +1544,7 @@ BOOST_AUTO_TEST_CASE(extreme_inflation) try { t.produce_block(); asset current_supply; { - vector data = t.get_row_by_account( N(eosio.token), core_symbol.to_symbol_code().value, N(stat), core_symbol.to_symbol_code().value ); + vector data = t.get_row_by_account( N(eosio.token), name(core_symbol.to_symbol_code().value), N(stat), account_name(core_symbol.to_symbol_code().value) ); current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, eosio_system_tester::abi_serializer_max_time)["supply"].template as(); } t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply ); @@ -2541,7 +2541,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) act.name = name; act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); }; // test begins vector prod_perms; @@ -2738,9 +2738,9 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system cross_15_percent_threshold(); create_accounts_with_resources( { N(donald111111), N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); //alice1111111 becomes a producer BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -2748,7 +2748,7 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //alice1111111 makes stake and votes issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); @@ -2763,7 +2763,7 @@ BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "donald111111" ), get_voter_info( "donald111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(donald111111) ), get_voter_info( "donald111111" ) ); //bob111111111 chooses alice1111111 as a proxy issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); @@ -2822,10 +2822,10 @@ BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) tr ("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); //carol1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), regproducer( "carol1111111", 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(carol1111111), 1) ); //bob111111111 chooses alice1111111 as a proxy @@ -2863,13 +2863,13 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("5.0000"), core_sym::from_string("5.0000") ) ); edump((get_voter_info("alice1111111"))); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //bob111111111 stakes and selects alice1111111 as a proxy issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //double regestering should fail without affecting total votes and stake BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), @@ -2878,7 +2878,7 @@ BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_sys ("isproxy", 1) ) ); - REQUIRE_MATCHING_OBJECT( proxy( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); + REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); //uregister BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() @@ -2960,9 +2960,9 @@ fc::mutable_variant_object config_to_variant( const eosio::chain::chain_config& BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_tester ) try { create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer1", 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer2", 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( "defproducer3", 3) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); + BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); //stake more than 15% of total EOS supply to activate chain transfer( "eosio", "alice1111111", core_sym::from_string("600000000.0000"), "eosio" ); @@ -3029,8 +3029,8 @@ BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { create_accounts_with_resources( { N(dan), N(sam) } ); transfer( config::system_account_name, "dan", core_sym::from_string( "10000.0000" ) ); transfer( config::system_account_name, "sam", core_sym::from_string( "10000.0000" ) ); - stake_with_transfer( config::system_account_name, "sam", core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); - stake_with_transfer( config::system_account_name, "dan", core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(sam), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(dan), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); regproducer( config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), vote( N(sam), { config::system_account_name } ) ); @@ -3094,8 +3094,8 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { produce_block(); // stake but but not enough to go live - stake_with_transfer( config::system_account_name, "bob", core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); - stake_with_transfer( config::system_account_name, "carl", core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(bob), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(carl), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(bob), { N(producer) } ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(carl), { N(producer) } ) ); @@ -3151,7 +3151,7 @@ BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { fc::exception, fc_assert_exception_message_is( not_closed_message ) ); // stake enough to go above the 15% threshold - stake_with_transfer( config::system_account_name, "alice", core_sym::from_string( "10000000.0000" ), core_sym::from_string( "10000000.0000" ) ); + stake_with_transfer( config::system_account_name, N(alice), core_sym::from_string( "10000000.0000" ), core_sym::from_string( "10000000.0000" ) ); BOOST_REQUIRE_EQUAL(0, get_producer_info("producer")["unpaid_blocks"].as()); BOOST_REQUIRE_EQUAL( success(), vote( N(alice), { N(producer) } ) ); @@ -3323,7 +3323,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { act.name = name; act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111) ); + return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); }; // test begins @@ -3487,7 +3487,7 @@ BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( cur_ram_size + 2 * rate, get_global_state()["max_ram_size"].as_uint64() ); BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( "alice1111111", N(setramrate), mvo()("bytes_per_block", rate) ) ); + push_action( N(alice1111111), N(setramrate), mvo()("bytes_per_block", rate) ) ); cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); produce_blocks(10); @@ -3510,14 +3510,14 @@ BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol{CORE_SYM}.to_symbol_code() ).empty() ); + BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); //remove row base_tester::push_action( N(eosio.token), N(close), N(alice1111111), mvo() ( "owner", "alice1111111" ) ( "symbol", symbol{CORE_SYM} ) ); - BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), symbol{CORE_SYM}.to_symbol_code() ).empty() ); + BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); auto rlm = control->get_resource_limits_manager(); auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); @@ -5106,7 +5106,8 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { BOOST_AUTO_TEST_CASE( setabi_bios ) try { - validating_tester t( validating_tester::default_config() ); + fc::temp_directory tempdir; + validating_tester t( tempdir, true ); t.execute_setup_policy( setup_policy::preactivate_feature_only ); abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); t.set_code( config::system_account_name, contracts::bios_wasm() ); diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index acca038a..9a1d8219 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -44,14 +44,14 @@ class eosio_token_tester : public tester { act.name = name; act.data = abi_ser.variant_to_binary( action_type_name, data,abi_serializer_max_time ); - return base_tester::push_action( std::move(act), uint64_t(signer)); + return base_tester::push_action( std::move(act), signer.to_uint64_t() ); } fc::variant get_stats( const string& symbolname ) { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), symbol_code, N(stat), symbol_code ); + vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); } @@ -59,7 +59,7 @@ class eosio_token_tester : public tester { { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), acc, N(accounts), symbol_code ); + vector data = get_row_by_account( N(eosio.token), acc, N(accounts), account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); } diff --git a/tests/eosio.wrap_tests.cpp b/tests/eosio.wrap_tests.cpp index 4e24a48f..e7b7cb03 100644 --- a/tests/eosio.wrap_tests.cpp +++ b/tests/eosio.wrap_tests.cpp @@ -184,7 +184,7 @@ BOOST_FIXTURE_TEST_CASE( wrap_exec_direct, eosio_wrap_tester ) try { ) ); */ wrap_trx.sign( get_private_key( N(alice), "active" ), control->get_chain_id() ); - for( const auto& actor : {"prod1", "prod2", "prod3", "prod4"} ) { + for( const auto& actor : {N(prod1), N(prod2), N(prod3), N(prod4)} ) { wrap_trx.sign( get_private_key( actor, "active" ), control->get_chain_id() ); } push_transaction( wrap_trx ); @@ -194,8 +194,8 @@ BOOST_FIXTURE_TEST_CASE( wrap_exec_direct, eosio_wrap_tester ) try { BOOST_REQUIRE( bool(trace) ); BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio", name{trace->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "reqauth", name{trace->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( config::system_account_name, name{trace->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(reqauth), name{trace->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); } FC_LOG_AND_RETHROW() @@ -238,13 +238,13 @@ BOOST_FIXTURE_TEST_CASE( wrap_with_msig, eosio_wrap_tester ) try { BOOST_REQUIRE_EQUAL( 2, traces.size() ); BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio.wrap", name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio", name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "reqauth", name{traces[1]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); } FC_LOG_AND_RETHROW() @@ -354,13 +354,13 @@ BOOST_FIXTURE_TEST_CASE( wrap_with_msig_producers_change, eosio_wrap_tester ) tr BOOST_REQUIRE_EQUAL( 2, traces.size() ); BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio.wrap", name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "exec", name{traces[0]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( "eosio", name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( "reqauth", name{traces[1]->action_traces[0].act.name} ); + BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); + BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); } FC_LOG_AND_RETHROW() From 3717e1d24ca17f99d2062f937bb05266eca3ba75 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 27 Sep 2019 22:27:16 -0400 Subject: [PATCH 0896/1048] adjust eosio dependency commit --- pipeline.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index c06f57fc..831e35bb 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,7 +4,7 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "26ed54d90f4e5436faac7fda0f6a0eabbbccc6e2", // eventually update to release/2.0.x + "eosio": "d5c7ee2e52e448abc0f0e854b31b177d427f6bce", // eventually update to release/2.0.x "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } From 298bcf8297769284d888f48ce27979ca76050e36 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 27 Sep 2019 22:31:06 -0400 Subject: [PATCH 0897/1048] Add support for proposing producer schedules with block signing authorities to eosio.bios and eosio.system contracts. The setprods action of eosio.bios contract has been modified to support block signing authorities in a way that is not backwards compatible. The regproducer action of eosio.system contract is backwards compatible for valid submitted producer keys. A new regproducer2 action has been added to eosio.system contract to support registering a block signing authority to a producer. Both the eosio.bios and eosio.system contract now depend on the set_proposed_producers_ex intrinsic and therefore can only be deployed on an EOSIO chain that has activated the WTMSIG_BLOCK_SIGNATURES protocol feature. --- .../include/eosio.bios/eosio.bios.hpp | 2 +- .../ricardian/eosio.bios.contracts.md.in | 8 +- contracts/eosio.bios/src/eosio.bios.cpp | 2 +- .../include/eosio.system/eosio.system.hpp | 44 +++++-- .../ricardian/eosio.system.clauses.md | 10 +- .../ricardian/eosio.system.contracts.md.in | 24 ++++ contracts/eosio.system/src/voting.cpp | 124 ++++++++++++++---- pipeline.jsonc | 2 +- 8 files changed, 172 insertions(+), 44 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index cadc70e8..37c387ab 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -315,7 +315,7 @@ namespace eosiobios { * @param schedule - New list of active producers to set */ [[eosio::action]] - void setprods( std::vector schedule ); + void setprods( const std::vector& schedule ); /** * Set the blockchain parameters diff --git a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in index 1acb02b6..a08b66e4 100644 --- a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in +++ b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in @@ -154,7 +154,13 @@ icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ {{$action.account}} proposes a block producer schedule of: {{#each schedule}} - 1. {{this.producer_name}} with a block signing key of {{this.block_signing_key}} + 1. {{this.producer_name}} +{{/each}} + +The block signing authorities of each of the producers in the above schedule are listed below: +{{#each schedule}} +### {{this.producer_name}} +{{to_json this.authority}} {{/each}}

unlinkauth

diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp index 582f0334..69d6758f 100644 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ b/contracts/eosio.bios/src/eosio.bios.cpp @@ -31,7 +31,7 @@ void bios::setalimits( name account, int64_t ram_bytes, int64_t net_weight, int6 set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); } -void bios::setprods( std::vector schedule ) { +void bios::setprods( const std::vector& schedule ) { require_auth( get_self() ); set_proposed_producers( schedule ); } diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index e42f72c8..01f23cce 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1,7 +1,9 @@ #pragma once #include +#include #include +#include #include #include #include @@ -210,19 +212,20 @@ namespace eosiosystem { * Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 */ struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { - name owner; - double total_votes = 0; - eosio::public_key producer_key; /// a packed public key object - bool is_active = true; - std::string url; - uint32_t unpaid_blocks = 0; - time_point last_claim_time; - uint16_t location = 0; + name owner; + double total_votes = 0; + eosio::public_key producer_key; /// a packed public key object + bool is_active = true; + std::string url; + uint32_t unpaid_blocks = 0; + time_point last_claim_time; + uint16_t location = 0; + eosio::binary_extension producer_authority; // added in version 1.9.0 uint64_t primary_key()const { return owner.value; } double by_votes()const { return is_active ? -total_votes : total_votes; } bool active()const { return is_active; } - void deactivate() { producer_key = public_key(); is_active = false; } + void deactivate() { producer_key = public_key(); producer_authority.reset(); is_active = false; } // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url) @@ -1083,13 +1086,30 @@ namespace eosiosystem { * @param url - the url of the block producer, normally the url of the block producer presentation website, * @param location - is the country code as defined in the ISO 3166, https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes * - * @pre Producer is not already registered * @pre Producer to register is an account * @pre Authority of producer to register */ [[eosio::action]] void regproducer( const name& producer, const public_key& producer_key, const std::string& url, uint16_t location ); + /** + * Register producer action. + * + * @details Register producer action, indicates that a particular account wishes to become a producer, + * this action will create a `producer_config` and a `producer_info` object for `producer` scope + * in producers tables. + * + * @param producer - account registering to be a producer candidate, + * @param producer_authority - the weighted threshold multisig block signing authority of the block producer used to sign blocks, + * @param url - the url of the block producer, normally the url of the block producer presentation website, + * @param location - is the country code as defined in the ISO 3166, https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes + * + * @pre Producer to register is an account + * @pre Authority of producer to register + */ + [[eosio::action]] + void regproducer2( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ); + /** * Unregister producer action. * @@ -1316,6 +1336,7 @@ namespace eosiosystem { using sellram_action = eosio::action_wrapper<"sellram"_n, &system_contract::sellram>; using refund_action = eosio::action_wrapper<"refund"_n, &system_contract::refund>; using regproducer_action = eosio::action_wrapper<"regproducer"_n, &system_contract::regproducer>; + using regproducer2_action = eosio::action_wrapper<"regproducer2"_n, &system_contract::regproducer2>; using unregprod_action = eosio::action_wrapper<"unregprod"_n, &system_contract::unregprod>; using setram_action = eosio::action_wrapper<"setram"_n, &system_contract::setram>; using setramrate_action = eosio::action_wrapper<"setramrate"_n, &system_contract::setramrate>; @@ -1386,7 +1407,8 @@ namespace eosiosystem { const asset& stake_net_quantity, const asset& stake_cpu_quantity, bool transfer ); void update_voting_power( const name& voter, const asset& total_update ); - // defined in voting.hpp + // defined in voting.cpp + void register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ); void update_elected_producers( const block_timestamp& timestamp ); void update_votes( const name& voter, const name& proxy, const std::vector& producers, bool voting ); void propagate_weight_change( const voter_info& voter ); diff --git a/contracts/eosio.system/ricardian/eosio.system.clauses.md b/contracts/eosio.system/ricardian/eosio.system.clauses.md index 19be74f8..ef5bfc98 100644 --- a/contracts/eosio.system/ricardian/eosio.system.clauses.md +++ b/contracts/eosio.system/ricardian/eosio.system.clauses.md @@ -6,13 +6,13 @@ User agreement for the chain can go here. I, {{producer}}, hereby nominate myself for consideration as an elected block producer. -If {{producer}} is selected to produce blocks by the system contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure. +If {{producer}} is selected to produce blocks by the system contract, I will sign blocks with my registered block signing keys and I hereby attest that I will keep these keys secret and secure. -If {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key. +If {{producer}} is unable to perform obligations under this contract I will resign my position using the unregprod action. I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. -{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios: +{{producer}} hereby agrees to only use my registered block signing keys to sign messages under the following scenarios: * proposing an objectively valid block at the time appointed by the block scheduling algorithm; * pre-confirming a block produced by another producer in the schedule when I find said block objectively valid; @@ -20,8 +20,8 @@ I acknowledge that a block is 'objectively valid' if it conforms to the determin I hereby accept liability for any and all provable damages that result from my: -* signing two different block proposals with the same timestamp with {{producer_key}}; -* signing two different block proposals with the same block number with {{producer_key}}; +* signing two different block proposals with the same timestamp; +* signing two different block proposals with the same block number; * signing any block proposal which builds off of an objectively invalid block; * signing a pre-confirmation for an objectively invalid block; * or, signing a confirmation for a block for which I do not possess pre-confirmation messages from more than two-thirds of the active block producers. diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 70e1b7cd..296094e4 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -309,6 +309,30 @@ icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ Register {{producer}} account as a block producer candidate. +URL: {{url}} +Location code: {{location}} +Block signing key: {{producer_key}} + +## Block Producer Agreement +{{$clauses.BlockProducerAgreement}} + +

regproducer2

+ +--- +spec_version: "0.2.0" +title: Register as a Block Producer Candidate +summary: 'Register {{nowrap producer}} account as a block producer candidate' +icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ +--- + +Register {{producer}} account as a block producer candidate. + +URL: {{url}} +Location code: {{location}} +Block signing authority: +{{to_json producer_authority}} + +## Block Producer Agreement {{$clauses.BlockProducerAgreement}}

regproxy

diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 95f1dd36..a7ac599f 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include @@ -9,6 +10,9 @@ #include #include +#include +#include +#include #include #include @@ -20,20 +24,40 @@ namespace eosiosystem { using eosio::microseconds; using eosio::singleton; - void system_contract::regproducer( const name& producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { - check( url.size() < 512, "url too long" ); - check( producer_key != eosio::public_key(), "public key should not be the default value" ); - require_auth( producer ); + eosio::block_signing_authority convert_to_block_signing_authority( const eosio::public_key& producer_key ) { + return eosio::block_signing_authority_v0{ .threshold = 1, .keys = {{producer_key, 1}} }; + } + template struct overloaded : Ts... { using Ts::operator()...; }; + template overloaded(Ts...) -> overloaded; + + bool is_null_key( const eosio::public_key& pub_key ) { + return std::visit( overloaded{ + []( const eosio::ecc_public_key& k ) { return (k == eosio::ecc_public_key{}); }, + []( const eosio::webauthn_public_key& k ) { return (k.key == eosio::ecc_public_key{}); } + }, pub_key ); + } + + void system_contract::register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { auto prod = _producers.find( producer.value ); const auto ct = current_time_point(); + eosio::public_key producer_key{}; + + std::visit( [&](auto&& auth ) { + if( auth.keys.size() == 1 ) { + // if the producer_authority consists of a single key, use that key in the legacy producer_key field + producer_key = auth.keys[0].key; + } + }, producer_authority ); + if ( prod != _producers.end() ) { _producers.modify( prod, producer, [&]( producer_info& info ){ - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; + info.producer_key = producer_key; + info.is_active = true; + info.url = url; + info.location = location; + info.producer_authority.emplace( producer_authority ); if ( info.last_claim_time == time_point() ) info.last_claim_time = ct; }); @@ -49,13 +73,14 @@ namespace eosiosystem { } } else { _producers.emplace( producer, [&]( producer_info& info ){ - info.owner = producer; - info.total_votes = 0; - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; - info.last_claim_time = ct; + info.owner = producer; + info.total_votes = 0; + info.producer_key = producer_key; + info.is_active = true; + info.url = url; + info.location = location; + info.last_claim_time = ct; + info.producer_authority.emplace( producer_authority ); }); _producers2.emplace( producer, [&]( producer_info2& info ){ info.owner = producer; @@ -65,6 +90,47 @@ namespace eosiosystem { } + void system_contract::regproducer( const name& producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { + require_auth( producer ); + check( url.size() < 512, "url too long" ); + + check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); + check( !is_null_key( producer_key ), "public key should not be the default value" ); + check_permission_authorization( null_account, active_permission, {} ); // aborts transaction if native side cannot unpack producer_key + + register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); + } + + void system_contract::regproducer2( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { + require_auth( producer ); + check( url.size() < 512, "url too long" ); + + std::visit( [&](auto&& auth ) { + uint32_t sum_weights = 0; + std::set unique_keys; + + for (const auto& kw: auth.keys ) { + check( kw.key.index() < 2, "currently only K1 and R1 producer keys are supported" ); + check( !is_null_key( kw.key ), "producer authority includes an invalid key" ); + + if( std::numeric_limits::max() - sum_weights <= kw.weight ) { + sum_weights = std::numeric_limits::max(); + } else { + sum_weights += kw.weight; + } + + unique_keys.insert(kw.key); + } + + check( auth.keys.size() == unique_keys.size(), "producer authority includes a duplicated key" ); + check( auth.threshold > 0, "producer authority has a threshold of 0" ); + check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); + }, producer_authority ); + + + register_producer( producer, producer_authority, url, location ); + } + void system_contract::unregprod( const name& producer ) { require_auth( producer ); @@ -79,25 +145,35 @@ namespace eosiosystem { auto idx = _producers.get_index<"prototalvote"_n>(); - std::vector< std::pair > top_producers; + using value_type = std::pair; + std::vector< value_type > top_producers; top_producers.reserve(21); - for ( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) { - top_producers.emplace_back( std::pair({{it->owner, it->producer_key}, it->location}) ); + for( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) { + top_producers.emplace_back( + eosio::producer_authority{ + .producer_name = it->owner, + .authority = it->producer_authority.has_value() ? *it->producer_authority + : convert_to_block_signing_authority( it->producer_key ) + }, + it->location + ); } - if ( top_producers.size() == 0 || top_producers.size() < _gstate.last_producer_schedule_size ) { + if( top_producers.size() == 0 || top_producers.size() < _gstate.last_producer_schedule_size ) { return; } - /// sort by producer name - std::sort( top_producers.begin(), top_producers.end() ); + std::sort( top_producers.begin(), top_producers.end(), []( const value_type& lhs, const value_type& rhs ) { + return lhs.first.producer_name < rhs.first.producer_name; // sort by producer name + // return lhs.second < rhs.second; // sort by location + } ); - std::vector producers; + std::vector producers; producers.reserve(top_producers.size()); - for( const auto& item : top_producers ) - producers.push_back(item.first); + for( auto& item : top_producers ) + producers.push_back( std::move(item.first) ); if( set_proposed_producers( producers ) >= 0 ) { _gstate.last_producer_schedule_size = static_cast( top_producers.size() ); diff --git a/pipeline.jsonc b/pipeline.jsonc index 831e35bb..7acda92e 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -5,7 +5,7 @@ "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { "eosio": "d5c7ee2e52e448abc0f0e854b31b177d427f6bce", // eventually update to release/2.0.x - "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x + "eosio.cdt": "72cbc2b6cb045d744d241d53a78467d5b65b9191" // eventually update to release/1.7.x } } } From cf9dafcb666b19c10210b2644170e30e4f8f7739 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 30 Sep 2019 19:08:25 -0400 Subject: [PATCH 0898/1048] verify keys provided when registering producers can be successfully unpacked --- contracts/eosio.system/src/voting.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index a7ac599f..6f418a88 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -96,7 +96,7 @@ namespace eosiosystem { check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); check( !is_null_key( producer_key ), "public key should not be the default value" ); - check_permission_authorization( null_account, active_permission, {} ); // aborts transaction if native side cannot unpack producer_key + check_permission_authorization( null_account, active_permission, {producer_key} ); // aborts transaction if native side cannot unpack producer_key register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); } @@ -105,9 +105,9 @@ namespace eosiosystem { require_auth( producer ); check( url.size() < 512, "url too long" ); + std::set unique_keys; std::visit( [&](auto&& auth ) { uint32_t sum_weights = 0; - std::set unique_keys; for (const auto& kw: auth.keys ) { check( kw.key.index() < 2, "currently only K1 and R1 producer keys are supported" ); @@ -127,6 +127,7 @@ namespace eosiosystem { check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); }, producer_authority ); + check_permission_authorization( null_account, active_permission, unique_keys ); // aborts transaction if native side cannot unpack all of the keys register_producer( producer, producer_authority, url, location ); } From fc31fe3b05b805fae3e539c3f3f04693d50046eb Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 30 Sep 2019 19:08:54 -0400 Subject: [PATCH 0899/1048] forgot to reflect producer_authority field --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 01f23cce..89d05a67 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -229,7 +229,7 @@ namespace eosiosystem { // explicit serialization macro is not necessary, used here only to improve compilation time EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url) - (unpaid_blocks)(last_claim_time)(location) ) + (unpaid_blocks)(last_claim_time)(location)(producer_authority) ) }; /** From 261fd02d47c7c00b408d506afad42593b343b4b9 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 30 Sep 2019 19:11:56 -0400 Subject: [PATCH 0900/1048] add eosio_system_tests/producer_wtmsig test --- tests/eosio.system_tests.cpp | 83 ++++++++++++++++++++++++++++++++++++ tests/main.cpp | 7 ++- 2 files changed, 89 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index ce51882f..b8cf7e1e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -803,6 +803,89 @@ BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { + cross_15_percent_threshold(); + + BOOST_REQUIRE_EQUAL( control->active_producers().version, 0u ); + + issue_and_transfer( N(alice1111111), core_sym::from_string("200000000.0000"), config::system_account_name ); + block_signing_authority_v0 alice_signing_authority; + alice_signing_authority.threshold = 1; + alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs1"), .weight = 1} ); + alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs2"), .weight = 1} ); + producer_authority alice_producer_authority = {.producer_name = N(alice1111111), .authority = alice_signing_authority}; + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); + + block_signing_private_keys.emplace(get_public_key(N(alice1111111), "bs1"), get_private_key(N(alice1111111), "bs1")); + + auto alice_prod_info = get_producer_info( N(alice1111111) ); + wdump((alice_prod_info)); + BOOST_REQUIRE_EQUAL( alice_prod_info["is_active"], true ); + + produce_block(); + produce_block( fc::minutes(2) ); + produce_blocks(2); + BOOST_REQUIRE_EQUAL( control->active_producers().version, 1u ); + produce_block(); + BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); + produce_block(); + + alice_signing_authority.threshold = 0; + alice_producer_authority.authority = alice_signing_authority; + + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority has a threshold of 0"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + + alice_signing_authority.threshold = 3; + alice_producer_authority.authority = alice_signing_authority; + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority is unsatisfiable"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + + alice_signing_authority.threshold = 1; + alice_signing_authority.keys[1] = alice_signing_authority.keys[0]; + alice_producer_authority.authority = alice_signing_authority; + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes a duplicated key"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + + alice_signing_authority.keys[1] = {}; + alice_producer_authority.authority = alice_signing_authority; + BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes an invalid key"), + push_action( N(alice1111111), N(regproducer2), mvo() + ("producer", "alice1111111") + ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) + ("url", "http://block.one") + ("location", 0 ) + ) + ); + +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { cross_15_percent_threshold(); diff --git a/tests/main.cpp b/tests/main.cpp index 2c658f31..e3d61750 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -31,7 +31,12 @@ boost::unit_test::test_suite* init_unit_test_suite(int argc, char* argv[]) { break; } } - if(!is_verbose) fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + + if(is_verbose) { + fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::debug); + } else { + fc::logger::get(DEFAULT_LOGGER).set_log_level(fc::log_level::off); + } // Register fc::exception translator boost::unit_test::unit_test_monitor.template register_exception_translator(&translate_fc_exception); From 5ac7138463ddffa2c250cfc5f73a62d5aa5a0055 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 1 Oct 2019 11:43:11 -0400 Subject: [PATCH 0901/1048] remove unnecessary checks --- contracts/eosio.system/src/voting.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 6f418a88..0b385372 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -96,7 +96,6 @@ namespace eosiosystem { check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); check( !is_null_key( producer_key ), "public key should not be the default value" ); - check_permission_authorization( null_account, active_permission, {producer_key} ); // aborts transaction if native side cannot unpack producer_key register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); } @@ -127,8 +126,6 @@ namespace eosiosystem { check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); }, producer_authority ); - check_permission_authorization( null_account, active_permission, unique_keys ); // aborts transaction if native side cannot unpack all of the keys - register_producer( producer, producer_authority, url, location ); } From 1f46094943bfbc58c7cba2d9b132fe0c03a2db80 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 1 Oct 2019 22:10:54 -0400 Subject: [PATCH 0902/1048] adjust eosio dependency commit again --- pipeline.jsonc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 831e35bb..f9bafb1e 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,7 +4,7 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "d5c7ee2e52e448abc0f0e854b31b177d427f6bce", // eventually update to release/2.0.x + "eosio": "89166b5a314fa2bcda664329efcc13f505bd8eac", // eventually update to release/2.0.x "eosio.cdt": "0e9b9b0ca5244d0caae4ea1c23ebcd3e7c7398fc" // eventually update to release/1.7.x } } From 4b608fe7c66c3460c0401561f8fe4432bc77a7ec Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 Oct 2019 09:36:23 -0400 Subject: [PATCH 0903/1048] output on unit test failure --- .cicd/test.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/test.sh b/.cicd/test.sh index 52153019..43083b6f 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -11,6 +11,6 @@ fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" -TEST_COMMANDS="ctest -j $JOBS" +TEST_COMMANDS="ctest -j $JOBS --output-on-failure" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" -eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file +eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" From 86f5bf54fa8b0c1bac56ad489a5accc9e9e7219e Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 Oct 2019 09:47:16 -0400 Subject: [PATCH 0904/1048] fix eosio_system_tests/setabi_bios test --- tests/eosio.system_tests.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index b8cf7e1e..d59dd4d4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5191,7 +5191,8 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { BOOST_AUTO_TEST_CASE( setabi_bios ) try { fc::temp_directory tempdir; validating_tester t( tempdir, true ); - t.execute_setup_policy( setup_policy::preactivate_feature_only ); + t.execute_setup_policy( setup_policy::full ); + abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); t.set_code( config::system_account_name, contracts::bios_wasm() ); t.set_abi( config::system_account_name, contracts::bios_abi().data() ); From 79b1e07c209e9023e9e635de16d184f86ed51c4d Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 2 Oct 2019 17:51:57 -0400 Subject: [PATCH 0905/1048] Update `regproducer` and `regproducer2` in eosio.system contract to relax validation rules on keys. Also use the new CDT `is_valid` member function of `block_signing_authority_v0` to validate the user-submitted block signing authorities (requires bumping dependency on CDT). Changes to tests to reflect the fact that `set_proposed_producers_ex` now accepts authorities even with invalid keys (requires bumping dependency on EOSIO). --- contracts/eosio.system/src/voting.cpp | 33 +-------------------------- pipeline.jsonc | 4 ++-- tests/eosio.system_tests.cpp | 20 ++++++++++++---- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index 0b385372..d26e187c 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -28,16 +28,6 @@ namespace eosiosystem { return eosio::block_signing_authority_v0{ .threshold = 1, .keys = {{producer_key, 1}} }; } - template struct overloaded : Ts... { using Ts::operator()...; }; - template overloaded(Ts...) -> overloaded; - - bool is_null_key( const eosio::public_key& pub_key ) { - return std::visit( overloaded{ - []( const eosio::ecc_public_key& k ) { return (k == eosio::ecc_public_key{}); }, - []( const eosio::webauthn_public_key& k ) { return (k.key == eosio::ecc_public_key{}); } - }, pub_key ); - } - void system_contract::register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { auto prod = _producers.find( producer.value ); const auto ct = current_time_point(); @@ -94,9 +84,6 @@ namespace eosiosystem { require_auth( producer ); check( url.size() < 512, "url too long" ); - check( producer_key.index() < 2, "currently only K1 and R1 producer keys are supported" ); - check( !is_null_key( producer_key ), "public key should not be the default value" ); - register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); } @@ -104,26 +91,8 @@ namespace eosiosystem { require_auth( producer ); check( url.size() < 512, "url too long" ); - std::set unique_keys; std::visit( [&](auto&& auth ) { - uint32_t sum_weights = 0; - - for (const auto& kw: auth.keys ) { - check( kw.key.index() < 2, "currently only K1 and R1 producer keys are supported" ); - check( !is_null_key( kw.key ), "producer authority includes an invalid key" ); - - if( std::numeric_limits::max() - sum_weights <= kw.weight ) { - sum_weights = std::numeric_limits::max(); - } else { - sum_weights += kw.weight; - } - - unique_keys.insert(kw.key); - } - - check( auth.keys.size() == unique_keys.size(), "producer authority includes a duplicated key" ); - check( auth.threshold > 0, "producer authority has a threshold of 0" ); - check( sum_weights >= auth.threshold, "producer authority is unsatisfiable" ); + check( auth.is_valid(), "invalid producer authority" ); }, producer_authority ); register_producer( producer, producer_authority, url, location ); diff --git a/pipeline.jsonc b/pipeline.jsonc index bf1d2d23..95bd0cd1 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,8 +4,8 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "89166b5a314fa2bcda664329efcc13f505bd8eac", // eventually update to release/2.0.x - "eosio.cdt": "72cbc2b6cb045d744d241d53a78467d5b65b9191" // eventually update to release/1.7.x + "eosio": "329071ae8ae7c8e467f42079ebdb09e675d7e702", // eventually update to release/2.0.x + "eosio.cdt": "aad0c4729b848c9cbe409aa1fdd917797a4d91e7" // eventually update to release/1.7.x } } } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d59dd4d4..c78439a1 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -841,7 +841,8 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { alice_signing_authority.threshold = 0; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority has a threshold of 0"), + // Ensure an authority with a threshold of 0 is rejected. + BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -850,9 +851,10 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + // Ensure an authority that is not satisfiable is rejected. alice_signing_authority.threshold = 3; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority is unsatisfiable"), + BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -861,10 +863,11 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + // Ensure an authority with duplicate keys is rejected. alice_signing_authority.threshold = 1; alice_signing_authority.keys[1] = alice_signing_authority.keys[0]; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes a duplicated key"), + BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -873,9 +876,10 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + // However, an authority with an invalid key is okay. alice_signing_authority.keys[1] = {}; alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: producer authority includes an invalid key"), + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer2), mvo() ("producer", "alice1111111") ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) @@ -884,6 +888,14 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { ) ); + produce_block(); + produce_block( fc::minutes(2) ); + produce_blocks(2); + BOOST_REQUIRE_EQUAL( control->active_producers().version, 2u ); + produce_block(); + BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); + produce_block(); + } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { From fdd1653fa8045e42bc52d4a0c469b4bf3bdc7884 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 7 Oct 2019 12:37:02 -0400 Subject: [PATCH 0906/1048] bump version to v1.9.0-rc1 --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 52663847..0df69f59 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.8.0-rc1 +## Version : 1.9.0-rc1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. From 6c4a6c28bf80dffb56218c1410d528779e20d426 Mon Sep 17 00:00:00 2001 From: Bucky Kittinger Date: Mon, 7 Oct 2019 13:43:21 -0400 Subject: [PATCH 0907/1048] update pipeline.jsonc --- pipeline.jsonc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pipeline.jsonc b/pipeline.jsonc index 95bd0cd1..b9d36799 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,8 +4,8 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "329071ae8ae7c8e467f42079ebdb09e675d7e702", // eventually update to release/2.0.x - "eosio.cdt": "aad0c4729b848c9cbe409aa1fdd917797a4d91e7" // eventually update to release/1.7.x + "eosio": "release/2.0.x", + "eosio.cdt": "release/1.7.x" } } } From ca5afe93dfcd34f804c4fbbda5be308db09bd190 Mon Sep 17 00:00:00 2001 From: ovi Date: Fri, 18 Oct 2019 17:21:25 +0800 Subject: [PATCH 0908/1048] Update the README.md build section --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index c610475d..81bed834 100644 --- a/README.md +++ b/README.md @@ -18,10 +18,7 @@ Dependencies: * [eosio v1.8.x](https://github.com/EOSIO/eos/releases/tag/v1.8.0-rc2) * [eosio.cdt v1.6.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.6.1) -To build the contracts and the unit tests: -* First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to. -* Second, make sure that you have ```sudo make install```ed __eosio__. -* Then just run the ```build.sh``` in the top directory to build all the contracts and the unit tests for these contracts. +To build the contracts follow the instructions in [`Compile and deploy` section](./docs/02_compile-and-deploy.md). After build: * The unit tests executable is placed in the _build/tests_ and is named __unit_test__. From 15ba163b88fa592db3ee261ff8a59281cbdb1519 Mon Sep 17 00:00:00 2001 From: ovi Date: Fri, 18 Oct 2019 18:46:54 +0800 Subject: [PATCH 0909/1048] clean up README.md, the referenced build section has the after build status. --- README.md | 5 ----- 1 file changed, 5 deletions(-) diff --git a/README.md b/README.md index f32e9620..04e491a6 100644 --- a/README.md +++ b/README.md @@ -20,11 +20,6 @@ Dependencies: To build the contracts follow the instructions in [`Compile and deploy` section](./docs/02_compile-and-deploy.md). -After build: -* If the build was configured to also build unit tests, the unit tests executable is placed in the _build/tests_ folder and is named __unit_test__. -* The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. -* Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. - ## Contributing [Contributing Guide](./CONTRIBUTING.md) From 222907aaf6b5e76898c8f3b0b816a83f45968c90 Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 19 Oct 2019 10:28:20 -0400 Subject: [PATCH 0910/1048] change pronoun in buyrex Ricardian summary --- contracts/eosio.system/ricardian/eosio.system.contracts.md.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 296094e4..9ab33cd8 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -75,7 +75,7 @@ icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ --- spec_version: "0.2.0" title: Buy REX Tokens -summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and his vote stake increases by {{nowrap amount}}' +summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}' icon: @ICON_BASE_URL@/@REX_ICON_URI@ --- From c5185789683fb6d440231c32d61caa53eceb3507 Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 19 Oct 2019 10:28:20 -0400 Subject: [PATCH 0911/1048] change pronoun in buyrex Ricardian summary --- contracts/eosio.system/ricardian/eosio.system.contracts.md.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in index 296094e4..9ab33cd8 100644 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in @@ -75,7 +75,7 @@ icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ --- spec_version: "0.2.0" title: Buy REX Tokens -summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and his vote stake increases by {{nowrap amount}}' +summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}' icon: @ICON_BASE_URL@/@REX_ICON_URI@ --- From cf5db63e7fb2a769582c314678329ee432c5a83e Mon Sep 17 00:00:00 2001 From: ovi Date: Tue, 22 Oct 2019 22:09:44 +0300 Subject: [PATCH 0912/1048] update the token issue guide since now the token can be issued only to the account creator --- ...ow-to-create-issue-and-transfer-a-token.md | 36 +++++++++---------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md index 584e4a64..3693d37e 100644 --- a/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -14,7 +14,7 @@ git clone https://github.com/EOSIO/eosio.contracts --branch master --single-bran ``` ```text -cd eosio.contracts/eosio.token +cd eosio.contracts/contracts/eosio.token ``` ## Step 2: Create Account for Contract @@ -34,7 +34,7 @@ eosio-cpp -I include -o eosio.token.wasm src/eosio.token.cpp --abigen ## Step 4: Deploy the Token Contract ```shell -cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/eosio.token --abi eosio.token.abi -p eosio.token@active +cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/contracts/eosio.token --abi eosio.token.abi -p eosio.token@active ``` Result should look similar to the one below: @@ -74,38 +74,34 @@ This command created a new token `SYS` with a precision of 4 decimals and a maxi ## Step 6: Issue Tokens -The issuer can issue new tokens to the "alice" account created earlier. +The issuer can issue new tokens to the issuer account in our case `eosio`. ```text -cleos push action eosio.token issue '[ "alice", "100.0000 SYS", "memo" ]' -p eosio@active +cleos push action eosio.token issue '[ "eosio", "100.0000 SYS", "memo" ]' -p eosio@active ``` Result should look similar to the one below: ```shell -executed transaction: 822a607a9196112831ecc2dc14ffb1722634f1749f3ac18b73ffacd41160b019 268 bytes 1000 cycles -# eosio.token <= eosio.token::issue {"to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> issue -# eosio.token <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} ->> transfer -# eosio <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} -# user <= eosio.token::transfer {"from":"eosio","to":"user","quantity":"100.0000 SYS","memo":"memo"} +executed transaction: a26b29d66044ad95edf0fc04bad3073e99718bc26d27f3c006589adedb717936 128 bytes 337 us +# eosio.token <= eosio.token::issue {"to":"eosio","quantity":"100.0000 SYS","memo":"memo"} +warning: transaction executed locally, but may not be confirmed by the network yet ] ``` ## Step 7: Transfer Tokens -Now that account `alice` has been issued tokens, transfer some of them to account `bob`. It was previously indicated that `alice` authorized this action using the argument `-p alice@active`. +Now that account `eosio` has been issued tokens, transfer some of them to account `bob`. ```shell -cleos push action eosio.token transfer '[ "alice", "bob", "25.0000 SYS", "m" ]' -p alice@active +cleos push action eosio.token transfer '[ "eosio", "bob", "25.0000 SYS", "m" ]' -p eosio@active ``` Result should look similar to the one below: ```text -executed transaction: 06d0a99652c11637230d08a207520bf38066b8817ef7cafaab2f0344aafd7018 268 bytes 1000 cycles -# eosio.token <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} ->> transfer -# user <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} -# tester <= eosio.token::transfer {"from":"alice","to":"bob","quantity":"25.0000 SYS","memo":"Here you go bob!"} +executed transaction: 60d334850151cb95c35fe31ce2e8b536b51441c5fd4c3f2fea98edcc6d69f39d 128 bytes 497 us +# eosio.token <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} +# eosio <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} +# bob <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} +warning: transaction executed locally, but may not be confirmed by the network yet ] ``` Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) @@ -118,10 +114,10 @@ Result: 25.00 SYS ``` -Check "alice's" balance, notice that tokens were deducted from the account +Check "eosio's" balance, notice that tokens were deducted from the account ```shell -cleos get currency balance eosio.token alice SYS +cleos get currency balance eosio.token eosio SYS ``` Result: From 2f710850064dfcddd9ecd4b1cede21b7f23cb80f Mon Sep 17 00:00:00 2001 From: ovi Date: Wed, 23 Oct 2019 22:06:51 +0300 Subject: [PATCH 0913/1048] correct problems introduced after merging with develop branch and resolving conflicts --- .../include/eosio.bios/eosio.bios.hpp | 31 ------------------- .../include/eosio.system/exchange_state.hpp | 3 +- 2 files changed, 2 insertions(+), 32 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index c036eecb..37c387ab 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -7,37 +7,6 @@ #include #include -// This header is needed until `is_feature_activiated` and `preactivate_feature` are added to `eosio.cdt` -#include - -namespace eosio { - namespace internal_use_do_not_use { - extern "C" { - __attribute__((eosio_wasm_import)) - bool is_feature_activated( const ::capi_checksum256* feature_digest ); - - __attribute__((eosio_wasm_import)) - void preactivate_feature( const ::capi_checksum256* feature_digest ); - } - } -} - -namespace eosio { - bool is_feature_activated( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - return internal_use_do_not_use::is_feature_activated( - reinterpret_cast( feature_digest_data.data() ) - ); - } - - void preactivate_feature( const eosio::checksum256& feature_digest ) { - auto feature_digest_data = feature_digest.extract_as_byte_array(); - internal_use_do_not_use::preactivate_feature( - reinterpret_cast( feature_digest_data.data() ) - ); - } -} - /** * EOSIO Contracts * diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 64a23822..03782cb1 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -59,4 +59,5 @@ namespace eosiosystem { }; typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; -} + /** @}*/ // enf of @addtogroup eosiosystem +} /// namespace eosiosystem \ No newline at end of file From fdddaff6b1f40b6564d1000941a3f318c6e9207e Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 24 Oct 2019 14:14:12 +0300 Subject: [PATCH 0914/1048] update the compile/build steps to include compilation of the tests as well if wanted by the user --- docs/02_compile-and-deploy.md | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/docs/02_compile-and-deploy.md b/docs/02_compile-and-deploy.md index b7502b3f..06fbd861 100644 --- a/docs/02_compile-and-deploy.md +++ b/docs/02_compile-and-deploy.md @@ -1,12 +1,23 @@ ## How to compile the eosio.contracts ### Preconditions -`eosio.cdt` should be installed already, if you do not have it already follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases). To verify if you have `eosio.cdt` installed and its version run the following command +Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases) to install it. To verify if you have `eosio.cdt` installed and its version run the following command ```sh eosio-cpp -v ``` +#### Build contracts using the build script + +##### To build contracts alone +Run the `build.sh` script in the top directory to build all the contracts. + +##### To build the contracts and unit tests +1. Ensure an appropriate version of `eosio` has been built from source and installed. Installing `eosio` from binaries `is not` sufficient. You can find instructions on how to do it [here](https://github.com/EOSIO/eos/blob/master/README.md) in section `Building from Sources`. +2. Run the `build.sh` script in the top directory with the `-t` flag to build all the contracts and the unit tests for these contracts. + +#### Build contracts manually + To compile the `eosio.contracts` execute the following commands. On all platforms except macOS: @@ -20,7 +31,7 @@ make -j$( nproc ) cd .. ``` -For macOS +For macOS: ```sh cd you_local_path_to/eosio.contracts/ rm -fr build From 66945740dcf7fe5777c5acd4a1a2b005b8434267 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 24 Oct 2019 14:44:44 -0400 Subject: [PATCH 0915/1048] Fix for broken test metrics. --- .cicd/test.sh | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/.cicd/test.sh b/.cicd/test.sh index 43083b6f..d4e45617 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -11,6 +11,24 @@ fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" -TEST_COMMANDS="ctest -j $JOBS --output-on-failure" +TEST_COMMANDS="ctest -j $JOBS --output-on-failure -T Test" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" +set +e eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" +EXIT_STATUS=$? +# buildkite +if [[ "$BUILDKITE" == 'true' ]]; then + cd build + # upload artifacts + echo '+++ :arrow_up: Uploading Artifacts' + echo 'Exporting xUnit XML' + mv -f ./tests/Testing/$(ls ./tests/Testing/ | grep '2' | tail -n 1)/Test.xml test-results.xml + echo 'Uploading artifacts' + buildkite-agent artifact upload test-results.xml + echo 'Done uploading artifacts.' +fi +# re-throw +if [[ "$EXIT_STATUS" != 0 ]]; then + echo "Failing due to non-zero exit status from ctest: $EXIT_STATUS" + exit $EXIT_STATUS +fi \ No newline at end of file From adbbc6640465dc8845da2b00c9705ddc857f6397 Mon Sep 17 00:00:00 2001 From: dskvr Date: Tue, 29 Oct 2019 12:46:20 -0400 Subject: [PATCH 0916/1048] Remove documentation from private functions --- .../include/eosio.token/eosio.token.hpp | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index 08d14609..d5e20164 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -96,12 +96,6 @@ namespace eosio { [[eosio::action]] void close( const name& owner, const symbol& symbol ); - /** - * Gets the supply for token `sym_code`, created by `token_contract_account` account. - * - * @param token_contract_account - the account to get the supply for, - * @param sym_code - the symbol to get the supply for. - */ static asset get_supply( const name& token_contract_account, const symbol_code& sym_code ) { stats statstable( token_contract_account, sym_code.raw() ); @@ -109,14 +103,6 @@ namespace eosio { return st.supply; } - /** - * Get the balance for a token `sym_code` created by `token_contract_account` account, - * for account `owner`. - * - * @param token_contract_account - the token creator account, - * @param owner - the account for which the token balance is returned, - * @param sym_code - the token for which the balance is returned. - */ static asset get_balance( const name& token_contract_account, const name& owner, const symbol_code& sym_code ) { accounts accountstable( token_contract_account, owner.value ); From b816cc453dd2a418669ca75cd8dcad151116b17a Mon Sep 17 00:00:00 2001 From: dskvr Date: Tue, 29 Oct 2019 12:47:11 -0400 Subject: [PATCH 0917/1048] remove documentation from private method --- .../include/eosio.system/exchange_state.hpp | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 03782cb1..e0715356 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -38,16 +38,7 @@ namespace eosiosystem { asset convert_from_exchange( connector& reserve, const asset& tokens ); asset convert( const asset& from, const symbol& to ); asset direct_convert( const asset& from, const symbol& to ); - /** - * Given two connector balances (inp_reserve and out_reserve), and an incoming amount - * of inp, this function calculates the delta out using Banacor equation. - * - * @param inp - input amount, same units as inp_reserve - * @param inp_reserve - the input connector balance - * @param out_reserve - the output connector balance - * - * @return int64_t - conversion output amount - */ + static int64_t get_bancor_output( int64_t inp_reserve, int64_t out_reserve, int64_t inp ); @@ -60,4 +51,4 @@ namespace eosiosystem { typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; /** @}*/ // enf of @addtogroup eosiosystem -} /// namespace eosiosystem \ No newline at end of file +} /// namespace eosiosystem From 418c654c5522059fefc3499cf6dcd04da867720a Mon Sep 17 00:00:00 2001 From: dskvr Date: Tue, 29 Oct 2019 12:50:43 -0400 Subject: [PATCH 0918/1048] Remove private methods and struct documentation for first iteration, only need action reference --- .../include/eosio.bios/eosio.bios.hpp | 68 +------------------ 1 file changed, 1 insertion(+), 67 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 37c387ab..76a2215e 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -36,14 +36,6 @@ namespace eosiobios { using eosio::permission_level; using eosio::public_key; - /** - * A weighted permission. - * - * @details Defines a weighted permission, that is a permission which has a weight associated. - * A permission is defined by an account name plus a permission name. The weight is going to be - * used against a threshold, if the weight is equal or greater than the threshold set then authorization - * will pass. - */ struct permission_level_weight { permission_level permission; uint16_t weight; @@ -52,11 +44,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) }; - /** - * Weighted key. - * - * @details A weighted key is defined by a public key and an associated weight. - */ struct key_weight { eosio::public_key key; uint16_t weight; @@ -65,11 +52,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( key_weight, (key)(weight) ) }; - /** - * Wait weight. - * - * @details A wait weight is defined by a number of seconds to wait for and a weight. - */ struct wait_weight { uint32_t wait_sec; uint16_t weight; @@ -78,15 +60,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) }; - /** - * Blockchain authority. - * - * @details An authority is defined by: - * - a vector of key_weights (a key_weight is a public key plus a weight), - * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) - * - a vector of wait_weights (a wait_weight is defined by a number of seconds to wait and a weight) - * - a threshold value - */ struct authority { uint32_t threshold = 0; std::vector keys; @@ -97,19 +70,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) }; - /** - * Blockchain block header. - * - * @details A block header is defined by: - * - a timestamp, - * - the producer that created it, - * - a confirmed flag default as zero, - * - a link to previous block, - * - a link to the transaction merkel root, - * - a link to action root, - * - a schedule version, - * - and a producers' schedule. - */ struct block_header { uint32_t timestamp; name producer; @@ -125,26 +85,9 @@ namespace eosiobios { (schedule_version)(new_producers)) }; - /** - * @defgroup eosiobios eosio.bios - * @ingroup eosiocontracts - * - * eosio.bios is a minimalistic system contract that only supplies the actions that are absolutely - * critical to bootstrap a chain and nothing more. - * - * @{ - */ class [[eosio::contract("eosio.bios")]] bios : public eosio::contract { public: using contract::contract; - /** - * @{ - * These actions map one-on-one with the ones defined in - * [Native Action Handlers](@ref native_action_handlers) section. - * They are present here so they can show up in the abi file and thus user can send them - * to this contract, but they have no specific implementation at this contract level, - * they will execute the implementation at the core level and nothing else. - */ /** * New account action * @@ -358,11 +301,6 @@ namespace eosiobios { [[eosio::action]] void reqactivated( const eosio::checksum256& feature_digest ); - /** - * Abi hash structure - * - * @details Abi hash structure is defined by contract owner and the contract hash. - */ struct [[eosio::table]] abi_hash { name owner; checksum256 hash; @@ -371,9 +309,6 @@ namespace eosiobios { EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) }; - /** - * Multi index table that stores the contracts' abi index by their owners/accounts. - */ typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; using newaccount_action = action_wrapper<"newaccount"_n, &bios::newaccount>; @@ -392,5 +327,4 @@ namespace eosiobios { using activate_action = action_wrapper<"activate"_n, &bios::activate>; using reqactivated_action = action_wrapper<"reqactivated"_n, &bios::reqactivated>; }; - /** @}*/ // end of @defgroup eosiobios eosio.bios -} /// namespace eosiobios +} From 241022403e8319052b3b2280702b7d6ef4e85902 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 31 Oct 2019 16:45:43 +0200 Subject: [PATCH 0919/1048] Re-do the three tutorials to not have reference to cleos documentation cause it is not deployed yet --- docs/03_guides/02_how-to-buy-ram.md | 25 +++++++++++++++++----- docs/03_guides/03_how-to-stake.md | 30 ++++++++++++++++++++++----- docs/03_guides/04_how-to-vote.md | 32 ++++++++++++++++++++++++----- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/docs/03_guides/02_how-to-buy-ram.md b/docs/03_guides/02_how-to-buy-ram.md index 878757e3..2885c514 100644 --- a/docs/03_guides/02_how-to-buy-ram.md +++ b/docs/03_guides/02_how-to-buy-ram.md @@ -1,8 +1,23 @@ -## How buy RAM +## Goal -You can buy RAM using `cleos` command line tool or using a wallet that implements the buy RAM functionality. +Setup an account that require multiple signatures for signing a transaction -TO DO: verify and correct the next url -To buy ram using `cleos` check [how to buy ram](https://eosio.github.io/eos/cleos/how-to-buy-ram) +## Before you begin -To buy ram using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file +* You have an account + +* Ensure the reference system contracts from `eosio.contracts` repository is deployed and used to manage system resources + +* You have sufficient token allocated to your account + +* Install the currently supported version of cleos + +* Unlock your wallet + +## Steps + +Buys RAM in value of 0.1 SYS tokens for account `alice`: + +```shell +cleos system buyram alice alice "0.1 SYS" -p alice@active +``` \ No newline at end of file diff --git a/docs/03_guides/03_how-to-stake.md b/docs/03_guides/03_how-to-stake.md index bf2a1f38..83f3a8da 100644 --- a/docs/03_guides/03_how-to-stake.md +++ b/docs/03_guides/03_how-to-stake.md @@ -1,8 +1,28 @@ -## How to stake tokens for CPU and/or NET bandwidth +## Goal -You can stake tokens for CPU and/or NET bandwidth using `cleos` command line tool or using a wallet that implements this functionality. +Stake resource for your account -TO DO: verify and correct the next url -To stake tokens for CPU and/or NET bandwidth using `cleos` check [how to stake resource](https://eosio.github.io/eos/cleos/how-to-stake-resource) +## Before you begin -To stake tokens for CPU and/or NET bandwidth using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file +* Install the currently supported version of cleos + +* Ensure the reference system contracts from `eosio.contracts` repository is deployed and used to manage system resources + +* Understand the following: + * What is an account + * What is network bandwidth + * What is CPU bandwidth + +## Steps + +Stake 0.01 SYS network bandwidth for `alice` + +```shell +cleos system delegatebw alice alice "0 SYS" "0.01 SYS" +``` + +Stake 0.01 SYS CPU bandwidth for `alice`: + +```shell +cleos system delegatebw alice alice "0.01 SYS" "0 SYS" +``` \ No newline at end of file diff --git a/docs/03_guides/04_how-to-vote.md b/docs/03_guides/04_how-to-vote.md index d27cccac..62654ba7 100644 --- a/docs/03_guides/04_how-to-vote.md +++ b/docs/03_guides/04_how-to-vote.md @@ -1,8 +1,30 @@ -## How to vote +## Goal -You can vote using `cleos` command line tool or using a wallet that implements the vote functionality. +Vote for a block producer -TO DO: verify and correct the next url -To vote using `cleos` check [how to vote](https://eosio.github.io/eos/cleos/how-to-vote) +## Before you begin -To vote using a wallet check the wallet user's manual for each wallet has its own implementation. \ No newline at end of file +* Install the current supported version of cleos + +* Ensure the reference system contracts from `eosio.contracts` repository is deployed and used to manage system resources + +* Understand the following: + * What is a block producer + * How does voting works + +* Unlock your wallet + +## Steps + +Assume you are going to vote for blockproducer1 and blockproducer2 from an account called `eosiotestts2`, execute the following: + +```bash +cleos system voteproducer prods eosiotestts2 blockproducer1 blockproducer2 +``` + +You should see something like below: + +```bash +executed transaction: 2d8b58f7387aef52a1746d7a22d304bbbe0304481d7751fc4a50b619df62676d 128 bytes 374 us +# eosio <= eosio::voteproducer {"voter":"eosiotestts2","proxy":"","producers":["blockproducer1","blockproducer2"]} +``` \ No newline at end of file From 321929954bedcf5ec8ddcf1044dc37f246566811 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 31 Oct 2019 16:47:54 +0200 Subject: [PATCH 0920/1048] clean up one remaining TO DO. --- docs/03_guides/01_upgrading-the-eosio.system-contract.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/03_guides/01_upgrading-the-eosio.system-contract.md b/docs/03_guides/01_upgrading-the-eosio.system-contract.md index 953ce073..2bd712fb 100644 --- a/docs/03_guides/01_upgrading-the-eosio.system-contract.md +++ b/docs/03_guides/01_upgrading-the-eosio.system-contract.md @@ -73,8 +73,6 @@ Then each of the top 21 block producers should do the following: 5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: -TO DO: Shouldn't one of the files be upgrade_system_contract_trx.json? - ``` $ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json 2,4c2,4 From d1cf46b9c9424399617c3256db950dcf93d39d80 Mon Sep 17 00:00:00 2001 From: ovi Date: Thu, 31 Oct 2019 17:41:00 +0200 Subject: [PATCH 0921/1048] final touches: use build everywhere instead of a mix of build and compile, fix some headings --- README.md | 2 +- ...le-and-deploy.md => 02_build-and-deploy.md} | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) rename docs/{02_compile-and-deploy.md => 02_build-and-deploy.md} (85%) diff --git a/README.md b/README.md index 04e491a6..510178dd 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) * [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) (optional dependency only needed to build unit tests) -To build the contracts follow the instructions in [`Compile and deploy` section](./docs/02_compile-and-deploy.md). +To build the contracts follow the instructions in [`Build and deploy` section](./docs/02_build-and-deploy.md). ## Contributing diff --git a/docs/02_compile-and-deploy.md b/docs/02_build-and-deploy.md similarity index 85% rename from docs/02_compile-and-deploy.md rename to docs/02_build-and-deploy.md index 06fbd861..b61b1513 100644 --- a/docs/02_compile-and-deploy.md +++ b/docs/02_build-and-deploy.md @@ -1,4 +1,4 @@ -## How to compile the eosio.contracts +## How to build the eosio.contracts ### Preconditions Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases) to install it. To verify if you have `eosio.cdt` installed and its version run the following command @@ -18,7 +18,7 @@ Run the `build.sh` script in the top directory to build all the contracts. #### Build contracts manually -To compile the `eosio.contracts` execute the following commands. +To build the `eosio.contracts` execute the following commands. On all platforms except macOS: ```sh @@ -42,36 +42,38 @@ make -j$(sysctl -n hw.ncpu) cd .. ``` -### After build: +#### After build: * If the build was configured to also build unit tests, the unit tests executable is placed in the _build/tests_ folder and is named __unit_test__. * The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. * Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. -## To deploy eosio.bios contract execute the following command: +## How to deploy the eosio.contracts + +### To deploy eosio.bios contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testerbios` ``` cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios ``` -## To deploy eosio.msig contract execute the following command: +### To deploy eosio.msig contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testermsig` ``` cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig ``` -## To deploy eosio.system contract execute the following command: +### To deploy eosio.system contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testersystem` ``` cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem ``` -## To deploy eosio.token contract execute the following command: +### To deploy eosio.token contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testertoken` ``` cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken ``` -## To deploy eosio.wrap contract execute the following command: +### To deploy eosio.wrap contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testerwrap` ``` cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap From 4292fc1c10087cd7da0c26bf5dbe7b42a2717822 Mon Sep 17 00:00:00 2001 From: dskvr Date: Fri, 1 Nov 2019 09:10:17 -0400 Subject: [PATCH 0922/1048] Do not provide documentation for get_core_symbol during this release. --- .../eosio.system/include/eosio.system/eosio.system.hpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index fa567ec0..32cd6236 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -85,7 +85,6 @@ namespace eosiosystem { * - Users can bid on premium names. * - A resource exchange system (REX) allows token holders to lend their tokens, * and users to rent CPU and Network resources in return for a market-determined fee. - * @{ */ // A name bid, which consists of: @@ -471,11 +470,8 @@ namespace eosiosystem { system_contract( name s, name code, datastream ds ); ~system_contract(); - /** - * Returns the core symbol by system account name - * - * @param system_account - the system account to get the core symbol for. - */ + // Returns the core symbol by system account name + // @param system_account - the system account to get the core symbol for. static symbol get_core_symbol( name system_account = "eosio"_n ) { rammarket rm(system_account, system_account.value); const static auto sym = get_core_symbol( rm ); From d76c92ceb4718df2f006449eace9a16bb3b15c15 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 6 Nov 2019 11:40:44 -0500 Subject: [PATCH 0923/1048] Fix for determining eosio and cdt versions required for forked PRs. --- .cicd/build.sh | 3 ++- .cicd/helpers/dependency-info.sh | 17 ++++++++++------- .travis.yml | 5 +---- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index bf97c186..eb222859 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -15,7 +15,7 @@ else export DOCKER_IMAGE fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" +CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/\\\$(ls /usr/opt/eosio.cdt/)/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" @@ -31,4 +31,5 @@ while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMA sleep 60 done # run +echo "docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\"" eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" \ No newline at end of file diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index d24f74b3..940241d5 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -14,15 +14,18 @@ else exit 1 fi # search GitHub for commit hash by tag and branch, preferring tag if both match -if [[ $TRAVIS ]]; then - CDT_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') - EOSIO_COMMIT=$((curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -H "Authorization: token $key" -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') -else +if [[ "$BUILDKITE" == 'true' ]]; then CDT_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/tags/$CDT_VERSION && curl -s https://api.github.com/repos/EOSIO/eosio.cdt/git/refs/heads/$CDT_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') EOSIO_COMMIT=$((curl -s https://api.github.com/repos/EOSIO/eos/git/refs/tags/$EOSIO_VERSION && curl -s https://api.github.com/repos/EOSIO/eos/git/refs/heads/$EOSIO_VERSION) | jq '.object.sha' | sed "s/null//g" | sed "/^$/d" | tr -d '"' | sed -n '1p') + test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already + test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already +else + git clone https://github.com/EOSIO/eosio.cdt && cd eosio.cdt + git pull && git checkout $CDT_VERSION + CDT_COMMIT=$(git rev-parse --verify HEAD) + EOSIO_COMMIT=$(echo $EOSIO_VERSION | sed 's/\//\_/') + cd .. fi -test -z "$CDT_COMMIT" && CDT_COMMIT=$(echo $CDT_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already -echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." -test -z "$EOSIO_COMMIT" && EOSIO_COMMIT=$(echo $EOSIO_VERSION | tr -d '"' | tr -d "''" | cut -d ' ' -f 1) # if both searches returned nothing, the version is probably specified by commit hash already echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." +echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt-ubuntu-18.04_amd64.deb" \ No newline at end of file diff --git a/.travis.yml b/.travis.yml index 51635525..c1d0e8ee 100644 --- a/.travis.yml +++ b/.travis.yml @@ -10,7 +10,4 @@ matrix: script: ". ./.cicd/build.sh && ./.cicd/test.sh" notifications: webhooks: - secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= -env: - global: - secure: jE/hVrQwgGs4KDdBqtiaGb9QE7xg8tn9NK2xMyedsi1CzqSZwl1iLjoefD4nH2wYRCGWfTBFES7QtJbj7SZK0+eobwQMO+jyXSOBd8D8HqcT37UMOPYW72YY2UuZpSCinuLHkZxZnb5dGfMqXDIZ3Y3GIgxOAd2+a0Y6xLt0dfZvh4OH8KVc/wWtuAjh0kMYEoQV9gEyok7xnXNjSLbAbkVslQBKHv451oi8saIGQbFC3b1KSGlE9LBv0QAR9MLXlkYMF3tAfegTGzx/NUIwdOOJ6XoPWoUGWV/u/nWexjHwsb1MwqQHN+LWHRM39ehL46na4m32S/ro3wHmBXnxlF3ys8QH0PEpfJL+r8aKGOv3pmWE//x+Ias6K6RWzTMLRFqlDPGTAGgMRGFiyGhT1aRHXD+mC2RppXptBST9brhE7+lyVqzKYFFHi0SHxfRsSQLgGhIJTMBr2Jj5ORlT86BWdxj3P8VOitKif/RP1zuJBKr78EyLGDPvsJhmot/gPg3VAo2R+cyFqVBWig2PC2ylneSS2DptMV6qLlujA+Fr38diYacsMqhej3ukqVZGaOecSIJXweJQ+7Y9SvGQDeAH8gEzgLLlkNrwpaFtLpxUqHrGWKJHUS8oKtleTznoK1Ck9Es2JTG2Tr4gVHk0OCIfc3hZRQl5Kj7AVi20Tec= \ No newline at end of file + secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= \ No newline at end of file From b4d0ed186111012af28a9a207fa9ebc454b06329 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 6 Nov 2019 15:09:01 -0500 Subject: [PATCH 0924/1048] Determine EOSIO version same way as CDT. --- .cicd/helpers/dependency-info.sh | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index 940241d5..c0f526ac 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -23,7 +23,10 @@ else git clone https://github.com/EOSIO/eosio.cdt && cd eosio.cdt git pull && git checkout $CDT_VERSION CDT_COMMIT=$(git rev-parse --verify HEAD) - EOSIO_COMMIT=$(echo $EOSIO_VERSION | sed 's/\//\_/') + cd .. + git clone https://github.com/EOSIO/eos && cd eos + git pull && git checkout $EOSIO_VERSION + EOSIO_COMMIT=$(git rev-parse --verify HEAD) cd .. fi echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." From 44c532b4a9c0773c49bb591aafea8502e042d390 Mon Sep 17 00:00:00 2001 From: Nathan Pierce Date: Thu, 7 Nov 2019 10:15:58 -0500 Subject: [PATCH 0925/1048] gke -> eks --- .cicd/pipeline.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 009fe0ef..801c8d33 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -7,7 +7,7 @@ steps: tar -pczf build.tar.gz build buildkite-agent artifact upload build.tar.gz agents: - queue: "automation-eos-builder-fleet" + queue: "automation-eks-eos-builder-fleet" timeout: "${TIMEOUT:-40}" skip: "$SKIP_UBUNTU_18" @@ -19,7 +19,7 @@ steps: tar -xzf build.tar.gz ./.cicd/test.sh agents: - queue: "automation-eos-builder-fleet" + queue: "automation-eks-eos-builder-fleet" timeout: "${TIMEOUT:-10}" skip: "$SKIP_UBUNTU_18" @@ -33,6 +33,6 @@ steps: echo '+++ :javascript: Running test-metrics.js' node --max-old-space-size=32768 test-metrics.js agents: - queue: "automation-eos-builder-fleet" + queue: "automation-eks-eos-builder-fleet" timeout: 10 soft_fail: true \ No newline at end of file From 1c9029ca2f085d525de11b8f1be4136b5e00b262 Mon Sep 17 00:00:00 2001 From: Nathan Pierce Date: Thu, 7 Nov 2019 10:53:54 -0500 Subject: [PATCH 0926/1048] testers --- .cicd/pipeline.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 801c8d33..9c9a4ab2 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -19,7 +19,7 @@ steps: tar -xzf build.tar.gz ./.cicd/test.sh agents: - queue: "automation-eks-eos-builder-fleet" + queue: "automation-eks-eos-tester-fleet" timeout: "${TIMEOUT:-10}" skip: "$SKIP_UBUNTU_18" @@ -33,6 +33,6 @@ steps: echo '+++ :javascript: Running test-metrics.js' node --max-old-space-size=32768 test-metrics.js agents: - queue: "automation-eks-eos-builder-fleet" + queue: "automation-eks-eos-tester-fleet" timeout: 10 soft_fail: true \ No newline at end of file From e71acbe194fc86188ca1dc28f736c35b8603cd0a Mon Sep 17 00:00:00 2001 From: arhag Date: Sun, 10 Nov 2019 22:40:28 -0500 Subject: [PATCH 0927/1048] use authorization of bidder for bidrefund deferred transaction --- contracts/eosio.system/src/name_bidding.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/name_bidding.cpp b/contracts/eosio.system/src/name_bidding.cpp index d08aed65..4c01f353 100644 --- a/contracts/eosio.system/src/name_bidding.cpp +++ b/contracts/eosio.system/src/name_bidding.cpp @@ -50,7 +50,7 @@ namespace eosiosystem { } eosio::transaction t; - t.actions.emplace_back( permission_level{get_self(), active_permission}, + t.actions.emplace_back( permission_level{current->high_bidder, active_permission}, get_self(), "bidrefund"_n, std::make_tuple( current->high_bidder, newname ) ); From ee98a92a2c49d7ec5d47a4718a62a3ac99955752 Mon Sep 17 00:00:00 2001 From: arhag Date: Tue, 12 Nov 2019 15:13:42 -0500 Subject: [PATCH 0928/1048] bump version to v1.9.0-rc2 --- CMakeLists.txt | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ef311a3..058632c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc1) +set(VERSION_SUFFIX rc2) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 32867637..482359d6 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc1 +## Version : 1.9.0-rc2 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. @@ -16,7 +16,7 @@ The following unprivileged contract(s) are also part of the system. Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) -* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc1) (optional dependency only needed to build unit tests) +* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc2) (optional dependency only needed to build unit tests) To build the contracts follow the instructions in [`Build and deploy` section](./docs/02_build-and-deploy.md). From 61436b0a35793b530767a9ea7686df091c1d7385 Mon Sep 17 00:00:00 2001 From: arhag Date: Sat, 30 Nov 2019 18:07:41 -0500 Subject: [PATCH 0929/1048] avoid updating total_activated_stake after activation --- contracts/eosio.system/src/delegate_bandwidth.cpp | 2 +- contracts/eosio.system/src/producer_pay.cpp | 6 +++--- contracts/eosio.system/src/voting.cpp | 8 ++++---- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index e1ecbd1f..d15a8202 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -392,7 +392,7 @@ namespace eosiosystem { check( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); check( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); check( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); - check( _gstate.total_activated_stake >= min_activated_stake, + check( _gstate.thresh_activated_stake_time != time_point(), "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp index cf7e2dde..4db2f774 100644 --- a/contracts/eosio.system/src/producer_pay.cpp +++ b/contracts/eosio.system/src/producer_pay.cpp @@ -21,8 +21,8 @@ namespace eosiosystem { // is eventually completely removed, at which point this line can be removed. _gstate2.last_block_num = timestamp; - /** until activated stake crosses this threshold no new rewards are paid */ - if( _gstate.total_activated_stake < min_activated_stake ) + /** until activation, no new rewards are paid */ + if( _gstate.thresh_activated_stake_time == time_point() ) return; if( _gstate.last_pervote_bucket_fill == time_point() ) /// start the presses @@ -71,7 +71,7 @@ namespace eosiosystem { const auto& prod = _producers.get( owner.value ); check( prod.active(), "producer does not have an active key" ); - check( _gstate.total_activated_stake >= min_activated_stake, + check( _gstate.thresh_activated_stake_time != time_point(), "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" ); const auto ct = current_time_point(); diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index d26e187c..a42239db 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -231,13 +231,13 @@ namespace eosiosystem { check( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" ); /** - * The first time someone votes we calculate and set last_vote_weight, since they cannot unstake until - * after total_activated_stake hits threshold, we can use last_vote_weight to determine that this is + * The first time someone votes we calculate and set last_vote_weight. Since they cannot unstake until + * after the chain has been activated, we can use last_vote_weight to determine that this is * their first vote and should consider their stake activated. */ - if( voter->last_vote_weight <= 0.0 ) { + if( _gstate.thresh_activated_stake_time == time_point() && voter->last_vote_weight <= 0.0 ) { _gstate.total_activated_stake += voter->staked; - if( _gstate.total_activated_stake >= min_activated_stake && _gstate.thresh_activated_stake_time == time_point() ) { + if( _gstate.total_activated_stake >= min_activated_stake ) { _gstate.thresh_activated_stake_time = current_time_point(); } } From 2dc0c72639f18b9bd35c72ee7c5a28ae71786c7e Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 2 Dec 2019 14:42:53 -0500 Subject: [PATCH 0930/1048] bump version to v1.9.0-rc3 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 058632c4..944d08c2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc2) +set(VERSION_SUFFIX rc3) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 482359d6..4649af9d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc2 +## Version : 1.9.0-rc3 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. From 01e941eab3729da1333ace60dec0401ac4e940fc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 13 Nov 2019 17:16:53 -0500 Subject: [PATCH 0931/1048] REX changes - initial commit --- .../include/eosio.system/eosio.system.hpp | 14 ++++++ contracts/eosio.system/src/eosio.system.cpp | 2 +- contracts/eosio.system/src/rex.cpp | 50 +++++++++++++++++++ 3 files changed, 65 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 32cd6236..cdedbae0 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -337,6 +337,17 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; + struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { + uint8_t version = 0; + int64_t current_rate_of_increase = 0; + time_point_sec last_update_time; + std::map return_buckets; + + uint64_t primary_key()const { return 0; } + }; + + typedef eosio::multi_index< "rexretpool"_n, rex_return_pool > rex_return_pool_table; + // `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: // - `version` defaulted to zero, // - `owner` the owner of the rex fund, @@ -447,6 +458,7 @@ namespace eosiosystem { eosio_global_state4 _gstate4; rammarket _rammarket; rex_pool_table _rexpool; + rex_return_pool_table _rexretpool; rex_fund_table _rexfunds; rex_balance_table _rexbalance; rex_order_table _rexorders; @@ -1143,6 +1155,7 @@ namespace eosiosystem { // defined in rex.cpp void runrex( uint16_t max ); + void update_rex_pool(); void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); void check_voting_requirement( const name& owner, const char* error_msg = "must vote for at least 21 producers or for a proxy before buying REX" )const; @@ -1164,6 +1177,7 @@ namespace eosiosystem { static time_point_sec get_rex_maturity(); asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); asset add_to_rex_pool( const asset& payment ); + void add_to_rex_return_pool( const asset& fee ); void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, const asset& rex_in_sell_order ); diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index b05c5f01..a6af9e0d 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -26,11 +26,11 @@ namespace eosiosystem { _global4(get_self(), get_self().value), _rammarket(get_self(), get_self().value), _rexpool(get_self(), get_self().value), + _rexretpool(get_self(), get_self().value), _rexfunds(get_self(), get_self().value), _rexbalance(get_self(), get_self().value), _rexorders(get_self(), get_self().value) { - //print( "construct system\n" ); _gstate = _global.exists() ? _global.get() : get_default_parameters(); _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 4a4596e2..c55c798a 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -513,6 +513,8 @@ namespace eosiosystem { { check( rex_system_initialized(), "rex system not initialized yet" ); + update_rex_pool(); + const auto& pool = _rexpool.begin(); auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { @@ -616,6 +618,43 @@ namespace eosiosystem { } + void system_contract::update_rex_pool() + { + const int32_t num_of_days = 30; + const time_point_sec ct = current_time_point(); + const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / ( num_of_days * seconds_per_day ); + const auto time_threshold = ct - eosio::days(num_of_days); + + int64_t change = change_estimate; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { + auto& return_buckets = return_pool.return_buckets; + auto iter= return_buckets.begin(); + while ( iter!= return_buckets.begin() && iter->first <= time_threshold ) { + auto next = iter; + ++next; + const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); + const int64_t rate = iter->second; + int64_t surplus = ( uint128_t(overtime) * rate ) / ( num_of_days * seconds_per_day ); + change -= surplus; + return_pool.current_rate_of_increase -= rate; + return_buckets.erase(iter); + iter = next; + } + return_pool.last_update_time = ct; + }); + + if ( change <= 0 ) { + return; + } + + _rexpool.modify(_rexpool.begin(), same_payer, [&](auto& pool) { + pool.total_unlent.amount += change; + pool.total_lendable = pool.total_unlent + pool.total_lent; + }); + } + template int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) { @@ -961,6 +1000,17 @@ namespace eosiosystem { return rex_received; } + void system_contract::add_to_rex_return_pool( const asset& fee ) + { + update_rex_pool(); + const uint32_t cts = current_time_point().sec_since_epoch(); + time_point_sec effective_time{ cts - cts % seconds_per_day }; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { + return_pool.return_buckets[effective_time] += fee.amount; + return_pool.current_rate_of_increase += fee.amount; + }); + } + /** * @brief Updates owner REX balance upon buying REX tokens * From 5348617d847bf98d329e956c8ebd86223d8ea2ef Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 15 Nov 2019 18:06:42 -0500 Subject: [PATCH 0932/1048] REX changes --- .../include/eosio.system/eosio.system.hpp | 1 + contracts/eosio.system/src/rex.cpp | 69 +++++++++++++++---- 2 files changed, 56 insertions(+), 14 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index cdedbae0..566362f7 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,6 +340,7 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; int64_t current_rate_of_increase = 0; + int64_t residue = 0; time_point_sec last_update_time; std::map return_buckets; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index c55c798a..f9ba8cab 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -452,15 +452,13 @@ namespace eosiosystem { */ void system_contract::add_loan_to_rex_pool( const asset& payment, int64_t rented_tokens, bool new_loan ) { + add_to_rex_return_pool( payment ); _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rt ) { // add payment to total_rent rt.total_rent.amount += payment.amount; // move rented_tokens from total_unlent to total_lent rt.total_unlent.amount -= rented_tokens; rt.total_lent.amount += rented_tokens; - // add payment to total_unlent - rt.total_unlent.amount += payment.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; // increment loan_num if a new loan is being created if ( new_loan ) { rt.loan_num++; @@ -620,18 +618,39 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - const int32_t num_of_days = 30; - const time_point_sec ct = current_time_point(); + const int32_t num_of_days = 30; + const time_point_sec ct = current_time_point(); + + if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { + return; + } + + if ( _rexretpool.begin()->residue > 0 ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { + pool.total_unlent.amount += _rexretpool.begin()->residue; + pool.total_lendable = pool.total_unlent + pool.total_lent; + }); + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + return_pool.residue = 0; + }); + } + + if ( _rexretpool.begin()->return_buckets.empty() || ct <= _rexretpool.begin()->return_buckets.begin()->first ) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + return_pool.last_update_time = ct; + }); + return; + } const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / ( num_of_days * seconds_per_day ); const auto time_threshold = ct - eosio::days(num_of_days); int64_t change = change_estimate; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { auto& return_buckets = return_pool.return_buckets; - auto iter= return_buckets.begin(); - while ( iter!= return_buckets.begin() && iter->first <= time_threshold ) { + auto iter = return_buckets.begin(); + while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); @@ -649,7 +668,7 @@ namespace eosiosystem { return; } - _rexpool.modify(_rexpool.begin(), same_payer, [&](auto& pool) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { pool.total_unlent.amount += change; pool.total_lendable = pool.total_unlent + pool.total_lent; }); @@ -1003,11 +1022,33 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - const uint32_t cts = current_time_point().sec_since_epoch(); - time_point_sec effective_time{ cts - cts % seconds_per_day }; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&](auto& return_pool) { - return_pool.return_buckets[effective_time] += fee.amount; - return_pool.current_rate_of_increase += fee.amount; + const uint32_t num_of_days = 30; + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + + if ( _rexretpool.begin() == _rexretpool.end() ) { + _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { + return_pool.last_update_time = ct; + }); + } + + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + time_point_sec effective_time{ cts - cts % seconds_per_day }; + auto& return_buckets = return_pool.return_buckets; + auto& current_rate_of_increase = return_pool.current_rate_of_increase; + auto iter = return_buckets.find( effective_time ); + if ( iter != return_buckets.end() ) { + iter->second += fee.amount; + } else { + int64_t residue = 0; + if ( !return_buckets.empty() ) { + uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); + residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / ( num_of_days * seconds_per_day ); + } + return_pool.residue += residue; + current_rate_of_increase += return_buckets.rbegin()->second; + return_buckets[effective_time] = fee.amount; + } }); } From 1a998d4dacaacc5836ee064da4bbd0fa6ca348e1 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 19 Nov 2019 10:23:31 -0500 Subject: [PATCH 0933/1048] Changes to REX return buckets --- .../include/eosio.system/eosio.system.hpp | 2 ++ contracts/eosio.system/src/rex.cpp | 27 ++++++++++--------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 566362f7..b488caae 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -61,6 +61,7 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_year = 52 * 7 * 24 * 3600; static constexpr uint32_t seconds_per_day = 24 * 3600; + static constexpr uint32_t seconds_per_hour = 3600; static constexpr int64_t useconds_per_year = int64_t(seconds_per_year) * 1000'000ll; static constexpr int64_t useconds_per_day = int64_t(seconds_per_day) * 1000'000ll; static constexpr uint32_t blocks_per_day = 2 * seconds_per_day; // half seconds per day @@ -339,6 +340,7 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; + uint8_t hours_per_bucket = 12; int64_t current_rate_of_increase = 0; int64_t residue = 0; time_point_sec last_update_time; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index f9ba8cab..58937b59 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -618,8 +618,8 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - const int32_t num_of_days = 30; - const time_point_sec ct = current_time_point(); + constexpr int32_t total_duration = 30 * seconds_per_day; + const time_point_sec ct = current_time_point(); if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { return; @@ -641,10 +641,10 @@ namespace eosiosystem { }); return; } - const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / ( num_of_days * seconds_per_day ); - const auto time_threshold = ct - eosio::days(num_of_days); + const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / total_duration; + const time_point_sec time_threshold{ ct.sec_since_epoch() - total_duration }; int64_t change = change_estimate; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { @@ -655,7 +655,7 @@ namespace eosiosystem { ++next; const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); const int64_t rate = iter->second; - int64_t surplus = ( uint128_t(overtime) * rate ) / ( num_of_days * seconds_per_day ); + const int64_t surplus = ( uint128_t(overtime) * rate ) / total_duration; change -= surplus; return_pool.current_rate_of_increase -= rate; return_buckets.erase(iter); @@ -1022,9 +1022,9 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - const uint32_t num_of_days = 30; - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); + constexpr uint32_t total_duration = 30 * seconds_per_day; + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { @@ -1032,8 +1032,11 @@ namespace eosiosystem { }); } + const uint8_t hours_per_bucket = _rexretpool.begin()->hours_per_bucket; + const uint32_t bucket_interval = hours_per_bucket * seconds_per_hour; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - time_point_sec effective_time{ cts - cts % seconds_per_day }; + time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; auto& return_buckets = return_pool.return_buckets; auto& current_rate_of_increase = return_pool.current_rate_of_increase; auto iter = return_buckets.find( effective_time ); @@ -1043,7 +1046,7 @@ namespace eosiosystem { int64_t residue = 0; if ( !return_buckets.empty() ) { uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); - residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / ( num_of_days * seconds_per_day ); + residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / total_duration; } return_pool.residue += residue; current_rate_of_increase += return_buckets.rbegin()->second; From c255aa89e1c127d2becfd946a6a61646b3c972fd Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 19 Nov 2019 18:26:40 -0500 Subject: [PATCH 0934/1048] REX changes testing --- contracts/eosio.system/src/rex.cpp | 8 ++++---- tests/eosio.system_tester.hpp | 21 +++++++++++++++++++++ tests/eosio.system_tests.cpp | 17 ++++++++++++++++- 3 files changed, 41 insertions(+), 5 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 58937b59..aa268529 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -1032,8 +1032,7 @@ namespace eosiosystem { }); } - const uint8_t hours_per_bucket = _rexretpool.begin()->hours_per_bucket; - const uint32_t bucket_interval = hours_per_bucket * seconds_per_hour; + const uint32_t bucket_interval = _rexretpool.begin()->hours_per_bucket * seconds_per_hour; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; @@ -1047,9 +1046,10 @@ namespace eosiosystem { if ( !return_buckets.empty() ) { uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / total_duration; + current_rate_of_increase += return_buckets.rbegin()->second; } - return_pool.residue += residue; - current_rate_of_increase += return_buckets.rbegin()->second; + return_pool.residue += residue; + // current_rate_of_increase += return_buckets.rbegin()->second; return_buckets[effective_time] = fee.amount; } }); diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index 753df1a1..a4795c03 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -666,6 +666,27 @@ class eosio_system_tester : public TESTER { return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer_max_time ); } + fc::variant get_rex_return_pool() const { + vector data; + const auto& db = control->db(); + namespace chain = eosio::chain; + const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(rexretpool) ) ); + if ( !t_id ) { + return fc::variant(); + } + + const auto& idx = db.get_index(); + + auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); + if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { + return fc::variant(); + } + + data.resize( itr->value.size() ); + memcpy( data.data(), itr->value.data(), data.size() ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer_max_time ); + } + void setup_rex_accounts( const std::vector& accounts, const asset& init_balance, const asset& net = core_sym::from_string("80.0000"), diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index c78439a1..82821a15 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3708,6 +3708,7 @@ BOOST_FIXTURE_TEST_CASE( rex_auth, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { const int64_t ratio = 10000; @@ -3945,13 +3946,15 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); + BOOST_REQUIRE( get_rex_return_pool().is_null() ); + { // bob rents cpu for carol const asset fee = core_sym::from_string("17.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); BOOST_REQUIRE_EQUAL( init_balance - fee, get_rex_fund(bob) ); rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); // 65 + 17 + BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); // 65 BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); BOOST_REQUIRE_EQUAL( expected_total_lent, @@ -3959,6 +3962,12 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), rex_pool["total_lendable"].as() ); + auto rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE( !rex_return_pool.is_null() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + + // test that carol's resource limits have been updated properly BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); @@ -3973,6 +3982,12 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { produce_block( fc::days(20) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); + + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE( !rex_return_pool.is_null() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + produce_block( fc::days(10) ); // alice is finally able to sellrex, she gains the fee paid by bob BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); From 9f9e62d479723fa7ae70d2d7b47f0fa4815a1776 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 21 Nov 2019 09:51:50 -0500 Subject: [PATCH 0935/1048] REX changes testing - 2 --- .../include/eosio.system/eosio.system.hpp | 4 +- contracts/eosio.system/src/rex.cpp | 46 +++++++++++-------- tests/eosio.system_tests.cpp | 11 +++-- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index b488caae..1f05f34d 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,12 +340,14 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; - uint8_t hours_per_bucket = 12; int64_t current_rate_of_increase = 0; int64_t residue = 0; time_point_sec last_update_time; std::map return_buckets; + static constexpr uint32_t total_duration = 30 * seconds_per_day; + static constexpr uint8_t hours_per_bucket = 12; + uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index aa268529..7d4951a1 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -618,8 +618,7 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - constexpr int32_t total_duration = 30 * seconds_per_day; - const time_point_sec ct = current_time_point(); + const time_point_sec ct = current_time_point(); if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { return; @@ -634,17 +633,24 @@ namespace eosiosystem { return_pool.residue = 0; }); } - + /* if ( _rexretpool.begin()->return_buckets.empty() || ct <= _rexretpool.begin()->return_buckets.begin()->first ) { _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { return_pool.last_update_time = ct; }); return; } - const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + */ + if ( _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first ) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { + return_pool.current_rate_of_increase += return_pool.return_buckets.rbegin()->second; + }); + } + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / total_duration; - const time_point_sec time_threshold{ ct.sec_since_epoch() - total_duration }; + const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; int64_t change = change_estimate; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { @@ -655,7 +661,7 @@ namespace eosiosystem { ++next; const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); const int64_t rate = iter->second; - const int64_t surplus = ( uint128_t(overtime) * rate ) / total_duration; + const int64_t surplus = ( uint128_t(overtime) * rate ) / rex_return_pool::total_duration; change -= surplus; return_pool.current_rate_of_increase -= rate; return_buckets.erase(iter); @@ -1022,35 +1028,39 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - constexpr uint32_t total_duration = 30 * seconds_per_day; - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; + const time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { - return_pool.last_update_time = ct; + return_pool.last_update_time = effective_time; }); } - const uint32_t bucket_interval = _rexretpool.begin()->hours_per_bucket * seconds_per_hour; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; auto& return_buckets = return_pool.return_buckets; auto& current_rate_of_increase = return_pool.current_rate_of_increase; auto iter = return_buckets.find( effective_time ); if ( iter != return_buckets.end() ) { iter->second += fee.amount; } else { + // create a new bucket + // but first process the previous bucket if it exists int64_t residue = 0; if ( !return_buckets.empty() ) { uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); - residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / total_duration; - current_rate_of_increase += return_buckets.rbegin()->second; + if ( interval < rex_return_pool::total_duration ) { + residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / rex_return_pool::total_duration; + current_rate_of_increase += return_buckets.rbegin()->second; + } else { + residue = return_buckets.rbegin()->second; + // erase rbegin + } } return_pool.residue += residue; - // current_rate_of_increase += return_buckets.rbegin()->second; - return_buckets[effective_time] = fee.amount; + return_buckets.emplace( effective_time, fee.amount ); } }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 82821a15..0915cd2a 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3985,14 +3985,17 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(10) ); // alice is finally able to sellrex, she gains the fee paid by bob BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( init_balance + fee, get_rex_fund(alice) ); + auto expected_rex_fund = (init_balance + fee).get_amount(); + auto actual_rex_fund = get_rex_fund(alice).get_amount(); + BOOST_REQUIRE_EQUAL( true, within_one( expected_rex_fund, actual_rex_fund ) ); + BOOST_REQUIRE( actual_rex_fund <= expected_rex_fund ); // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); @@ -4050,7 +4053,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { const asset fee = core_sym::from_string("7.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable + fee, rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); produce_block( fc::days(5) ); From 457d0ad7448922cfc09a09fe3d4ff8a703b067c5 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 27 Nov 2019 23:27:34 -0700 Subject: [PATCH 0936/1048] REX changes - fix unit tests --- .../include/eosio.system/eosio.system.hpp | 3 +- contracts/eosio.system/src/rex.cpp | 79 ++++++------------- tests/eosio.system_tests.cpp | 70 ++++++++++------ 3 files changed, 69 insertions(+), 83 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 1f05f34d..a8e17831 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -340,9 +340,8 @@ namespace eosiosystem { struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; - int64_t current_rate_of_increase = 0; - int64_t residue = 0; time_point_sec last_update_time; + int64_t current_rate_of_increase = 0; std::map return_buckets; static constexpr uint32_t total_duration = 30 * seconds_per_day; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 7d4951a1..86b33c61 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -624,50 +624,40 @@ namespace eosiosystem { return; } - if ( _rexretpool.begin()->residue > 0 ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { - pool.total_unlent.amount += _rexretpool.begin()->residue; - pool.total_lendable = pool.total_unlent + pool.total_lent; - }); - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - return_pool.residue = 0; - }); - } - /* - if ( _rexretpool.begin()->return_buckets.empty() || ct <= _rexretpool.begin()->return_buckets.begin()->first ) { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - return_pool.last_update_time = ct; - }); - return; - } - */ - if ( _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first ) { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - return_pool.current_rate_of_increase += return_pool.return_buckets.rbegin()->second; + const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() + && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first + && _rexretpool.begin()->return_buckets.rbegin()->first <= ct; + int64_t new_bucket_overestimate = 0; + if ( new_return_bucket ) { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; + const uint32_t dt = rp.return_buckets.rbegin()->first.sec_since_epoch() - rp.last_update_time.sec_since_epoch(); + new_bucket_overestimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; }); } const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const int32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration + - new_bucket_overestimate; const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; int64_t change = change_estimate; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - auto& return_buckets = return_pool.return_buckets; + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + auto& return_buckets = rp.return_buckets; auto iter = return_buckets.begin(); while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; - const uint32_t overtime = time_threshold.sec_since_epoch() - iter->first.sec_since_epoch(); + const uint32_t overtime = ct.sec_since_epoch() - ( iter->first.sec_since_epoch() + rex_return_pool::total_duration ); const int64_t rate = iter->second; const int64_t surplus = ( uint128_t(overtime) * rate ) / rex_return_pool::total_duration; - change -= surplus; - return_pool.current_rate_of_increase -= rate; + change -= surplus; + rp.current_rate_of_increase -= rate; return_buckets.erase(iter); iter = next; } - return_pool.last_update_time = ct; + rp.last_update_time = ct; }); if ( change <= 0 ) { @@ -1029,39 +1019,18 @@ namespace eosiosystem { { update_rex_pool(); - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); + const uint32_t cts = current_time_point().sec_since_epoch(); const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; const time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; + if ( _rexretpool.begin() == _rexretpool.end() ) { - _rexretpool.emplace( get_self(), [&]( auto& return_pool ) { - return_pool.last_update_time = effective_time; + _rexretpool.emplace( get_self(), [&]( auto& rp ) { + rp.last_update_time = effective_time; }); } - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& return_pool ) { - auto& return_buckets = return_pool.return_buckets; - auto& current_rate_of_increase = return_pool.current_rate_of_increase; - auto iter = return_buckets.find( effective_time ); - if ( iter != return_buckets.end() ) { - iter->second += fee.amount; - } else { - // create a new bucket - // but first process the previous bucket if it exists - int64_t residue = 0; - if ( !return_buckets.empty() ) { - uint32_t interval = cts - return_buckets.rbegin()->first.sec_since_epoch(); - if ( interval < rex_return_pool::total_duration ) { - residue = ( uint128_t(return_buckets.rbegin()->second) * interval ) / rex_return_pool::total_duration; - current_rate_of_increase += return_buckets.rbegin()->second; - } else { - residue = return_buckets.rbegin()->second; - // erase rbegin - } - } - return_pool.residue += residue; - return_buckets.emplace( effective_time, fee.amount ); - } + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.return_buckets[effective_time] += fee.amount; }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 0915cd2a..538fd609 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3964,9 +3964,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); // test that carol's resource limits have been updated properly BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); @@ -3985,7 +3983,6 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["residue"].as() ); BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(10) ); @@ -4113,30 +4110,31 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("20000.0000") ) ); } - const asset rent_payment = core_sym::from_string("40000.0000"); + produce_block( fc::days(25) ); + const asset rent_payment = core_sym::from_string("40000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); + produce_block( fc::days(4) ); + + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); + const auto init_rex_pool = get_rex_pool(); const int64_t total_lendable = init_rex_pool["total_lendable"].as().get_amount(); const int64_t total_rex = init_rex_pool["total_rex"].as().get_amount(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * total_lendable ) / total_rex; - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); - produce_block( fc::days(5) ); - init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); @@ -4153,7 +4151,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); // wait for 30 days minus 1 hour - produce_block( fc::hours(19*24 + 23) ); + produce_block( fc::hours(23) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); @@ -4176,21 +4174,28 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { } { + BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); + BOOST_TEST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); } + produce_blocks(2); + produce_block( fc::hours(13) ); + produce_blocks(2); + produce_block( fc::days(30) ); + produce_blocks(2); + { auto trace1 = base_tester::push_action( config::system_account_name, N(updaterex), bob, mvo()("owner", bob) ); auto trace2 = base_tester::push_action( config::system_account_name, N(updaterex), carol, mvo()("owner", carol) ); @@ -4318,7 +4323,8 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { } // wait for 30 days, frank's loan will be renewed at the current price - produce_block( fc::hours(30*24 + 1) ); + produce_block( fc::minutes(30*24*60 - 1) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); rex_pool = get_rex_pool(); { int64_t unlent_tokens = bancor_convert( rex_pool["total_unlent"].as().get_amount(), @@ -4330,6 +4336,8 @@ BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { payment.get_amount() ); } + produce_block( fc::minutes(2) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); loan_info = get_cpu_loan(1); @@ -4818,15 +4826,17 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const int64_t init_stake = get_voter_info( alice )["staked"].as(); + // alice buys rex const asset payment = core_sym::from_string("25000.0000"); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); + // emily rents cpu const asset fee = core_sym::from_string("50.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, fee ) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( payment + fee, get_rex_vote_stake(alice) ); + BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers @@ -4846,9 +4856,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); + vote( alice, { producer_names.begin(), producer_names.begin() + 20 } ) ); BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4856,23 +4866,25 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to == get_producer_info(producer_names[20])["total_votes"].as() ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - produce_block( fc::days(20) ); + produce_block( fc::days(10) ); BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); + BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); + produce_block( fc::hours(19 * 24 + 23) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); const int64_t total_lendable = current_rex_pool["total_lendable"].as().get_amount(); const int64_t total_rex = current_rex_pool["total_rex"].as().get_amount(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_rex.get_amount()) * total_lendable ) / total_rex; - produce_block( fc::days(5) ); const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); - BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ); + BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ) ); BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4922,18 +4934,20 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( purchase.get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); const auto init_rex_pool = get_rex_pool(); const asset rent = core_sym::from_string("25.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); + + produce_block( fc::days(31) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const auto curr_rex_pool = get_rex_pool(); BOOST_REQUIRE_EQUAL( curr_rex_pool["total_lendable"].as(), init_rex_pool["total_lendable"].as() + rent ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); + + BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); BOOST_REQUIRE_EQUAL( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); BOOST_REQUIRE_EQUAL( purchase + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == @@ -4945,11 +4959,15 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const asset to_cpu_stake = core_sym::from_string("40.0000"); transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); + produce_block( fc::hours(30 * 24 + 12) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); + produce_block( fc::hours(30 * 24 + 12) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + rent) == From bfe33f3f0ad6bc4445d029537553874a2144a1fc Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 29 Nov 2019 14:49:48 -0700 Subject: [PATCH 0937/1048] REX changes - distribute ramfee and namebids --- contracts/eosio.system/src/rex.cpp | 26 +++++++------- tests/eosio.system_tests.cpp | 54 +++++++++++++++++++----------- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 86b33c61..b33e597b 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -624,25 +624,25 @@ namespace eosiosystem { return; } + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; + const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first && _rexretpool.begin()->return_buckets.rbegin()->first <= ct; - int64_t new_bucket_overestimate = 0; + int64_t new_bucket_estimate = 0; if ( new_return_bucket ) { _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; - const uint32_t dt = rp.return_buckets.rbegin()->first.sec_since_epoch() - rp.last_update_time.sec_since_epoch(); - new_bucket_overestimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; + const uint32_t dt = ct.sec_since_epoch() - rp.return_buckets.rbegin()->first.sec_since_epoch(); + new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; }); } - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration - - new_bucket_overestimate; - const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; + int64_t change = change_estimate + new_bucket_estimate; - int64_t change = change_estimate; _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { auto& return_buckets = rp.return_buckets; auto iter = return_buckets.begin(); @@ -651,7 +651,8 @@ namespace eosiosystem { ++next; const uint32_t overtime = ct.sec_since_epoch() - ( iter->first.sec_since_epoch() + rex_return_pool::total_duration ); const int64_t rate = iter->second; - const int64_t surplus = ( uint128_t(overtime) * rate ) / rex_return_pool::total_duration; + const int64_t surplus = ( uint128_t(overtime) * rate + rex_return_pool::total_duration - 1 ) + / rex_return_pool::total_duration; change -= surplus; rp.current_rate_of_increase -= rate; return_buckets.erase(iter); @@ -872,10 +873,7 @@ namespace eosiosystem { { #if CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX if ( rex_available() ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { - rp.total_unlent.amount += amount.amount; - rp.total_lendable.amount += amount.amount; - }); + add_to_rex_return_pool( amount ); // inline transfer to rex_account token::transfer_action transfer_act{ token_account, { from, active_permission } }; transfer_act.send( from, rex_account, amount, diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 538fd609..c39a16c7 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -27,7 +27,8 @@ using namespace eosio_system; BOOST_AUTO_TEST_SUITE(eosio_system_tests) -bool within_one(int64_t a, int64_t b) { return std::abs(a - b) <= 1; } +bool within_error(int64_t a, int64_t b, int64_t err) { return std::abs(a - b) <= err; }; +bool within_one(int64_t a, int64_t b) { return within_error(a, b, 1); } BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { @@ -3991,8 +3992,8 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); auto expected_rex_fund = (init_balance + fee).get_amount(); auto actual_rex_fund = get_rex_fund(alice).get_amount(); - BOOST_REQUIRE_EQUAL( true, within_one( expected_rex_fund, actual_rex_fund ) ); - BOOST_REQUIRE( actual_rex_fund <= expected_rex_fund ); + BOOST_REQUIRE_EQUAL( true, within_error( expected_rex_fund, actual_rex_fund, 2 ) ); + BOOST_TEST_REQUIRE( actual_rex_fund <= expected_rex_fund ); // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); @@ -4422,12 +4423,20 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("0.3500") ); cur_rex_balance = get_balance( N(eosio.rex) ); + + produce_blocks( 1 ); + produce_block( fc::hours(30*24 + 12) ); + produce_blocks( 1 ); + + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); auto cur_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( cur_rex_balance, cur_rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["total_lent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, cur_rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); + BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_unlent"].as().get_amount() ) ); + BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["total_lent"].as().get_amount() ); + BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_lendable"].as().get_amount() ) ); + BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); // required for closing namebids cross_15_percent_threshold(); @@ -4449,8 +4458,14 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_unlent"].as() ); + produce_block( fc::hours(30*24 + 13) ); + produce_blocks( 1 ); + + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); + + BOOST_TEST_REQUIRE( within_error( cur_rex_balance.get_amount(), get_rex_pool()["total_lendable"].as().get_amount(), 4 ) ); + BOOST_TEST_REQUIRE( cur_rex_balance.get_amount() >= get_rex_pool()["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), get_rex_pool()["total_unlent"].as() ); } FC_LOG_AND_RETHROW() @@ -4884,7 +4899,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); - BOOST_TEST_REQUIRE( within_one( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount() ) ); + BOOST_TEST_REQUIRE( within_error( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount(), 2 ) ); BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4899,7 +4914,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { +BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_test::tolerance(1e-8) ) try { cross_15_percent_threshold(); @@ -4945,11 +4960,12 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes produce_block( fc::days(31) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const auto curr_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( curr_rex_pool["total_lendable"].as(), init_rex_pool["total_lendable"].as() + rent ); + BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), + init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); - BOOST_REQUIRE_EQUAL( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); - BOOST_REQUIRE_EQUAL( purchase + rent, get_rex_vote_stake(alice) ); + BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); + BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == @@ -4959,18 +4975,18 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes const asset to_cpu_stake = core_sym::from_string("40.0000"); transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 12) ); + produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); + BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 2 ) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 12) ); + produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); - BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + rent) == + BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 3 ) ); + BOOST_TEST_REQUIRE ( stake2votes(init_stake + get_rex_vote_stake(alice) ) == get_producer_info(producer_names[0])["total_votes"].as_double() ); } FC_LOG_AND_RETHROW() From 72e583657ba6023d7e77add569ea90219a5efae8 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Sun, 1 Dec 2019 23:28:36 -0500 Subject: [PATCH 0938/1048] REX changes - more testing --- tests/eosio.system_tests.cpp | 105 +++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index c39a16c7..91f30683 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5252,6 +5252,111 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { + + BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); + + const asset init_balance = core_sym::from_string("100000.0000"); + const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; + account_name alice = accounts[0], bob = accounts[1]; + setup_rex_accounts( accounts, init_balance ); + + const asset payment = core_sym::from_string("100000.0000"); + { + BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); + auto rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( payment, rex_pool["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( payment, rex_pool["total_unlent"].as() ); + + BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); + } + + { + const asset fee = core_sym::from_string("30.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + auto rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + + produce_block( fc::hours(12) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + + uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600); + int64_t expected = payment.get_amount() + change; + + auto rex_pool = get_rex_pool(); + BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); + + produce_blocks( 1 ); + produce_block( fc::days(25) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + uint32_t t2 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600); + expected = payment.get_amount() + change; + + rex_pool = get_rex_pool(); + BOOST_TEST_REQUIRE( within_one( expected, rex_pool["total_lendable"].as().get_amount() ) ); + + produce_blocks( 1 ); + produce_block( fc::days(5) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + + rex_pool = get_rex_pool(); + expected = payment.get_amount() + fee.get_amount(); + BOOST_TEST_REQUIRE( within_error( expected, rex_pool["total_lendable"].as().get_amount(), 2 ) ); + BOOST_TEST_REQUIRE( expected >= rex_pool["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( rex_pool["total_lendable"].as(), + rex_pool["total_unlent"].as() ); + } + + produce_block( fc::hours(1) ); + + { + const asset init_lendable = get_rex_pool()["total_lendable"].as(); + const asset fee = core_sym::from_string("15.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + auto rex_return_pool = get_rex_return_pool(); + uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + produce_block( fc::hours(1) ); + BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + BOOST_REQUIRE_EQUAL( t0 + 3600, t1 ); + + produce_block( fc::hours(12) ); + BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); + produce_block( fc::hours(8) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + + produce_block( fc::days(30) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_TEST_REQUIRE( (init_lendable + fee + fee).get_amount() < get_rex_pool()["total_lendable"].as().get_amount() ); + + produce_block( fc::days(1) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_TEST_REQUIRE( within_error( init_lendable.get_amount() + 3 * fee.get_amount(), + get_rex_pool()["total_lendable"].as().get_amount(), 3 ) ); + } + +} FC_LOG_AND_RETHROW() + + BOOST_AUTO_TEST_CASE( setabi_bios ) try { fc::temp_directory tempdir; validating_tester t( tempdir, true ); From a9895b94b7b4b4519ffa7ad1fc80d2284ba29cef Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 2 Dec 2019 01:06:15 -0500 Subject: [PATCH 0939/1048] REX changes - unlent lower bound --- contracts/eosio.system/src/rex.cpp | 2 +- tests/eosio.system_tests.cpp | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index b33e597b..774f8816 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -733,7 +733,7 @@ namespace eosiosystem { asset stake_change( 0, core_symbol() ); bool success = false; - const int64_t unlent_lower_bound = ( uint128_t(2) * rexitr->total_lent.amount ) / 10; + const int64_t unlent_lower_bound = rexitr->total_lent.amount / 10; const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible if ( proceeds.amount <= available_unlent ) { const int64_t init_vote_stake_amount = bitr->vote_stake.amount; diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 91f30683..4e1bf9d5 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4088,8 +4088,8 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { setup_rex_accounts( accounts, init_balance ); const auto purchase1 = core_sym::from_string("50000.0000"); - const auto purchase2 = core_sym::from_string("235500.0000"); - const auto purchase3 = core_sym::from_string("234500.0000"); + const auto purchase2 = core_sym::from_string("105500.0000"); + const auto purchase3 = core_sym::from_string("104500.0000"); const auto init_stake = get_voter_info(alice)["staked"].as(); BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); @@ -4108,12 +4108,12 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( core_sym::from_string("20000.0000"), get_rex_pool()["total_rent"].as() ); for (uint8_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("20000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("12000.0000") ) ); } produce_block( fc::days(25) ); - const asset rent_payment = core_sym::from_string("40000.0000"); + const asset rent_payment = core_sym::from_string("46000.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); produce_block( fc::days(4) ); @@ -4770,7 +4770,7 @@ BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("2000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("3000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 9 * rex_bucket_amount / 10, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); @@ -5043,11 +5043,11 @@ BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { const int64_t tot_lent = rex_pool["total_lent"].as().get_amount(); const int64_t tot_lendable = rex_pool["total_lendable"].as().get_amount(); double rex_per_eos = double(tot_rex) / double(tot_lendable); - int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.19 * tot_lent ); + int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.09 * tot_lent ); produce_block( fc::days(5) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - sell_amount = rex_per_eos * ( tot_unlent - 0.2 * tot_lent ); + sell_amount = rex_per_eos * ( tot_unlent - 0.1 * tot_lent ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("no sellrex order is scheduled"), cancelrexorder( alice ) ); From 2fa92a36eda290b620950aded7e38f10a787eb53 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 2 Dec 2019 17:32:23 -0500 Subject: [PATCH 0940/1048] REX changes - use microseconds instead of seconds --- .../include/eosio.system/eosio.system.hpp | 13 ++++---- contracts/eosio.system/src/rex.cpp | 20 ++++++------ tests/eosio.system_tests.cpp | 31 ++++++++++--------- 3 files changed, 33 insertions(+), 31 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index a8e17831..2054a845 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -64,6 +64,7 @@ namespace eosiosystem { static constexpr uint32_t seconds_per_hour = 3600; static constexpr int64_t useconds_per_year = int64_t(seconds_per_year) * 1000'000ll; static constexpr int64_t useconds_per_day = int64_t(seconds_per_day) * 1000'000ll; + static constexpr int64_t useconds_per_hour = int64_t(seconds_per_hour) * 1000'000ll; static constexpr uint32_t blocks_per_day = 2 * seconds_per_day; // half seconds per day static constexpr int64_t min_activated_stake = 150'000'000'0000; @@ -339,13 +340,13 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { - uint8_t version = 0; - time_point_sec last_update_time; - int64_t current_rate_of_increase = 0; - std::map return_buckets; + uint8_t version = 0; + time_point last_update_time; + int64_t current_rate_of_increase = 0; + std::map return_buckets; - static constexpr uint32_t total_duration = 30 * seconds_per_day; - static constexpr uint8_t hours_per_bucket = 12; + static constexpr int64_t total_duration = 30 * useconds_per_day; + static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 774f8816..5bf02df1 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -618,16 +618,16 @@ namespace eosiosystem { void system_contract::update_rex_pool() { - const time_point_sec ct = current_time_point(); + const time_point ct = current_time_point(); if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { return; } - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const uint32_t time_interval = ct.sec_since_epoch() - _rexretpool.begin()->last_update_time.sec_since_epoch(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; - const time_point_sec time_threshold{ ct.sec_since_epoch() - rex_return_pool::total_duration }; + const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; + const uint64_t time_interval = ct.time_since_epoch().count() - _rexretpool.begin()->last_update_time.time_since_epoch().count(); + const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; + const time_point time_threshold = ct - eosio::microseconds{rex_return_pool::total_duration}; const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first @@ -636,7 +636,7 @@ namespace eosiosystem { if ( new_return_bucket ) { _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; - const uint32_t dt = ct.sec_since_epoch() - rp.return_buckets.rbegin()->first.sec_since_epoch(); + const uint64_t dt = ct.time_since_epoch().count() - rp.return_buckets.rbegin()->first.time_since_epoch().count() ; new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; }); } @@ -649,7 +649,7 @@ namespace eosiosystem { while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; - const uint32_t overtime = ct.sec_since_epoch() - ( iter->first.sec_since_epoch() + rex_return_pool::total_duration ); + const uint64_t overtime = ct.time_since_epoch().count() - ( iter->first.time_since_epoch().count() + rex_return_pool::total_duration ); const int64_t rate = iter->second; const int64_t surplus = ( uint128_t(overtime) * rate + rex_return_pool::total_duration - 1 ) / rex_return_pool::total_duration; @@ -1017,9 +1017,9 @@ namespace eosiosystem { { update_rex_pool(); - const uint32_t cts = current_time_point().sec_since_epoch(); - const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; - const time_point_sec effective_time{ cts - cts % bucket_interval + bucket_interval }; + const int64_t cts = current_time_point().time_since_epoch().count(); + const int64_t bucket_interval = rex_return_pool::hours_per_bucket * useconds_per_hour; + const time_point effective_time{ eosio::microseconds{cts - cts % bucket_interval + bucket_interval} }; if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& rp ) { diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 4e1bf9d5..e69fcc2e 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4119,23 +4119,24 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { produce_block( fc::days(4) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - + const auto init_rex_pool = get_rex_pool(); const int64_t total_lendable = init_rex_pool["total_lendable"].as().get_amount(); const int64_t total_rex = init_rex_pool["total_rex"].as().get_amount(); const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * total_lendable ) / total_rex; - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol(SY(4,REX)) ) ) ); + BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol{SY(4,REX)} ) ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); - BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); + // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); + // BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ); + // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - + BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); @@ -4151,7 +4152,7 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); - // wait for 30 days minus 1 hour + // wait for a total of 30 days minus 1 hour produce_block( fc::hours(23) ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); @@ -5277,15 +5278,15 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - produce_block( fc::hours(12) ); + produce_block( fc::hours(13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); - int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600); + int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); int64_t expected = payment.get_amount() + change; auto rex_pool = get_rex_pool(); @@ -5296,8 +5297,8 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t2 = rex_return_pool["last_update_time"].as().sec_since_epoch(); - change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600); + int64_t t2 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); expected = payment.get_amount() + change; rex_pool = get_rex_pool(); @@ -5325,13 +5326,13 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { const asset fee = core_sym::from_string("15.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); auto rex_return_pool = get_rex_return_pool(); - uint32_t t0 = rex_return_pool["last_update_time"].as().sec_since_epoch(); + int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); produce_block( fc::hours(1) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - uint32_t t1 = rex_return_pool["last_update_time"].as().sec_since_epoch(); - BOOST_REQUIRE_EQUAL( t0 + 3600, t1 ); + int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + BOOST_REQUIRE_EQUAL( t1, t0 + 3600 * 1000000ll + 500000 ); produce_block( fc::hours(12) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); From 300e00722e0621578aec8e9037664556c4acda2e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 2 Dec 2019 18:12:17 -0500 Subject: [PATCH 0941/1048] REX changes - comments --- .../eosio.system/include/eosio.system/eosio.system.hpp | 7 ++++++- contracts/eosio.system/src/rex.cpp | 8 ++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 2054a845..72750ad0 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -339,13 +339,18 @@ namespace eosiosystem { typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; + // `rex_return_pool` structure underlying the rex return pool table. A rex return pool table entry is defined by: + // - `version` defaulted to zero, + // - `last_update_time` the last time returns from renting, ram fees, and name bids were added to the rex pool, + // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, + // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; time_point last_update_time; int64_t current_rate_of_increase = 0; std::map return_buckets; - static constexpr int64_t total_duration = 30 * useconds_per_day; + static constexpr int64_t total_duration = 30 * useconds_per_day; static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 5bf02df1..4aeef7d5 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -616,6 +616,9 @@ namespace eosiosystem { } + /** + * @brief Adds returns from the REX return pool to the REX pool + */ void system_contract::update_rex_pool() { const time_point ct = current_time_point(); @@ -1013,6 +1016,11 @@ namespace eosiosystem { return rex_received; } + /** + * @brief Adds an amount of core tokens to the REX return pool + * + * @param fee - amount to be added + */ void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); From 8d6760bc68793165ae47ba2191b4f0461fc3ed0e Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 9 Dec 2019 16:16:12 -0500 Subject: [PATCH 0942/1048] REX changes - time interval between REX pool updates --- .../include/eosio.system/eosio.system.hpp | 6 ++++ contracts/eosio.system/src/rex.cpp | 11 ++++++- tests/eosio.system_tests.cpp | 32 +++++++++++++++++++ 3 files changed, 48 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 72750ad0..1bb0c27f 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -343,14 +343,20 @@ namespace eosiosystem { // - `version` defaulted to zero, // - `last_update_time` the last time returns from renting, ram fees, and name bids were added to the rex pool, // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, + // - `cummulative_proceeds` bookkeeping variable that tracks fees added to rex pool up to current time, + // - `proceeds` bookkeeping variable that tracks fees added to rex return pool up to current time, // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; + time_point last_update_time; int64_t current_rate_of_increase = 0; + int64_t cummulative_proceeds = 0; + int64_t proceeds = 0; std::map return_buckets; static constexpr int64_t total_duration = 30 * useconds_per_day; + static constexpr int64_t dist_interval = 10 * 60 * 1000'000; static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 4aeef7d5..d47017f4 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -623,7 +623,8 @@ namespace eosiosystem { { const time_point ct = current_time_point(); - if ( _rexretpool.begin() == _rexretpool.end() || ct <= _rexretpool.begin()->last_update_time ) { + if ( _rexretpool.begin() == _rexretpool.end() || + ct < _rexretpool.begin()->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { return; } @@ -672,6 +673,9 @@ namespace eosiosystem { pool.total_unlent.amount += change; pool.total_lendable = pool.total_unlent + pool.total_lent; }); + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.cummulative_proceeds += change; + }); } template @@ -1032,6 +1036,11 @@ namespace eosiosystem { if ( _rexretpool.begin() == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& rp ) { rp.last_update_time = effective_time; + rp.proceeds += fee.amount; + }); + } else { + _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + rp.proceeds += fee.amount; }); } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index e69fcc2e..61355abc 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5278,6 +5278,7 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); produce_block( fc::hours(13) ); @@ -5310,6 +5311,7 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); rex_pool = get_rex_pool(); expected = payment.get_amount() + fee.get_amount(); @@ -5331,11 +5333,15 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); BOOST_REQUIRE_EQUAL( t1, t0 + 3600 * 1000000ll + 500000 ); produce_block( fc::hours(12) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); + rex_return_pool = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( 2, rex_return_pool["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::hours(8) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); @@ -5351,10 +5357,36 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); BOOST_TEST_REQUIRE( within_error( init_lendable.get_amount() + 3 * fee.get_amount(), get_rex_pool()["total_lendable"].as().get_amount(), 3 ) ); } + { + const asset fee = core_sym::from_string("25.0000"); + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + produce_block( fc::hours(13) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + auto rex_pool_0 = get_rex_pool(); + auto rex_return_pool_0 = get_rex_return_pool(); + produce_block( fc::minutes(9) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + auto rex_pool_1 = get_rex_pool(); + auto rex_return_pool_1 = get_rex_return_pool(); + BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_update_time"].as().time_since_epoch().count(), + rex_return_pool_1["last_update_time"].as().time_since_epoch().count()); + BOOST_REQUIRE_EQUAL( rex_pool_0["total_lendable"].as(), + rex_pool_1["total_lendable"].as()); + produce_block( fc::minutes(1) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + auto rex_pool_2 = get_rex_pool(); + auto rex_return_pool_2 = get_rex_return_pool(); + BOOST_TEST_REQUIRE( rex_return_pool_1["last_update_time"].as().time_since_epoch().count() < + rex_return_pool_2["last_update_time"].as().time_since_epoch().count()); + BOOST_TEST_REQUIRE( rex_pool_1["total_lendable"].as().get_amount() < + rex_pool_2["total_lendable"].as().get_amount()); + } + } FC_LOG_AND_RETHROW() From a78e2eef9a1247358f6f9a33f100d5121b8c34af Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Mon, 9 Dec 2019 17:06:53 -0500 Subject: [PATCH 0943/1048] REX changes - larryk85's PR review --- contracts/eosio.system/src/rex.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index d47017f4..380cd8cc 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -622,23 +622,24 @@ namespace eosiosystem { void system_contract::update_rex_pool() { const time_point ct = current_time_point(); + const auto ret_pool_elem = _rexretpool.begin(); - if ( _rexretpool.begin() == _rexretpool.end() || - ct < _rexretpool.begin()->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { + if ( ret_pool_elem == _rexretpool.end() || + ct < ret_pool_elem->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { return; } - const int64_t current_rate = _rexretpool.begin()->current_rate_of_increase; - const uint64_t time_interval = ct.time_since_epoch().count() - _rexretpool.begin()->last_update_time.time_since_epoch().count(); + const int64_t current_rate = ret_pool_elem->current_rate_of_increase; + const uint64_t time_interval = ct.time_since_epoch().count() - ret_pool_elem->last_update_time.time_since_epoch().count(); const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; const time_point time_threshold = ct - eosio::microseconds{rex_return_pool::total_duration}; - const bool new_return_bucket = !_rexretpool.begin()->return_buckets.empty() - && _rexretpool.begin()->last_update_time <= _rexretpool.begin()->return_buckets.rbegin()->first - && _rexretpool.begin()->return_buckets.rbegin()->first <= ct; + const bool new_return_bucket = !ret_pool_elem->return_buckets.empty() + && ret_pool_elem->last_update_time <= ret_pool_elem->return_buckets.rbegin()->first + && ret_pool_elem->return_buckets.rbegin()->first <= ct; int64_t new_bucket_estimate = 0; if ( new_return_bucket ) { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; const uint64_t dt = ct.time_since_epoch().count() - rp.return_buckets.rbegin()->first.time_since_epoch().count() ; new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; @@ -647,7 +648,7 @@ namespace eosiosystem { int64_t change = change_estimate + new_bucket_estimate; - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { auto& return_buckets = rp.return_buckets; auto iter = return_buckets.begin(); while ( iter != return_buckets.end() && iter->first <= time_threshold ) { @@ -673,7 +674,7 @@ namespace eosiosystem { pool.total_unlent.amount += change; pool.total_lendable = pool.total_unlent + pool.total_lent; }); - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { rp.cummulative_proceeds += change; }); } From bed60a901f75b7b1c237cd5db99c5bc94268d9bb Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Tue, 10 Dec 2019 18:02:50 -0500 Subject: [PATCH 0944/1048] REX changes - arhag's PR review --- .../include/eosio.system/eosio.system.hpp | 67 ++++---- contracts/eosio.system/src/eosio.system.cpp | 1 + contracts/eosio.system/src/rex.cpp | 147 +++++++++++------- 3 files changed, 130 insertions(+), 85 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 1bb0c27f..037b3a9d 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -345,25 +345,33 @@ namespace eosiosystem { // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, // - `cummulative_proceeds` bookkeeping variable that tracks fees added to rex pool up to current time, // - `proceeds` bookkeeping variable that tracks fees added to rex return pool up to current time, - // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective + // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { - uint8_t version = 0; - - time_point last_update_time; - int64_t current_rate_of_increase = 0; - int64_t cummulative_proceeds = 0; - int64_t proceeds = 0; - std::map return_buckets; - - static constexpr int64_t total_duration = 30 * useconds_per_day; - static constexpr int64_t dist_interval = 10 * 60 * 1000'000; - static constexpr uint8_t hours_per_bucket = 12; + uint8_t version = 0; + time_point_sec last_dist_time; + time_point_sec pending_bucket_time = time_point_sec::maximum(); + time_point_sec oldest_bucket_time = time_point_sec::min(); + int64_t pending_bucket_proceeds = 0; + int64_t current_rate_of_increase = 0; + + static constexpr int32_t total_intervals = 30 * 144; // 30 days + static constexpr int32_t dist_interval = 10 * 60; // 10 minutes + static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } }; typedef eosio::multi_index< "rexretpool"_n, rex_return_pool > rex_return_pool_table; + struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_buckets { + uint8_t version = 0; + std::map return_buckets; + + uint64_t primary_key()const { return 0; } + }; + + typedef eosio::multi_index< "retbuckets"_n, rex_return_buckets > rex_return_buckets_table; + // `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: // - `version` defaulted to zero, // - `owner` the owner of the rex fund, @@ -461,23 +469,24 @@ namespace eosiosystem { class [[eosio::contract("eosio.system")]] system_contract : public native { private: - voters_table _voters; - producers_table _producers; - producers_table2 _producers2; - global_state_singleton _global; - global_state2_singleton _global2; - global_state3_singleton _global3; - global_state4_singleton _global4; - eosio_global_state _gstate; - eosio_global_state2 _gstate2; - eosio_global_state3 _gstate3; - eosio_global_state4 _gstate4; - rammarket _rammarket; - rex_pool_table _rexpool; - rex_return_pool_table _rexretpool; - rex_fund_table _rexfunds; - rex_balance_table _rexbalance; - rex_order_table _rexorders; + voters_table _voters; + producers_table _producers; + producers_table2 _producers2; + global_state_singleton _global; + global_state2_singleton _global2; + global_state3_singleton _global3; + global_state4_singleton _global4; + eosio_global_state _gstate; + eosio_global_state2 _gstate2; + eosio_global_state3 _gstate3; + eosio_global_state4 _gstate4; + rammarket _rammarket; + rex_pool_table _rexpool; + rex_return_pool_table _rexretpool; + rex_return_buckets_table _rexretbuckets; + rex_fund_table _rexfunds; + rex_balance_table _rexbalance; + rex_order_table _rexorders; public: static constexpr eosio::name active_permission{"active"_n}; diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp index a6af9e0d..202210c7 100644 --- a/contracts/eosio.system/src/eosio.system.cpp +++ b/contracts/eosio.system/src/eosio.system.cpp @@ -27,6 +27,7 @@ namespace eosiosystem { _rammarket(get_self(), get_self().value), _rexpool(get_self(), get_self().value), _rexretpool(get_self(), get_self().value), + _rexretbuckets(get_self(), get_self().value), _rexfunds(get_self(), get_self().value), _rexbalance(get_self(), get_self().value), _rexorders(get_self(), get_self().value) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 380cd8cc..663336d2 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -621,62 +621,92 @@ namespace eosiosystem { */ void system_contract::update_rex_pool() { - const time_point ct = current_time_point(); - const auto ret_pool_elem = _rexretpool.begin(); + auto get_elapsed_intervals = [&](const time_point_sec& t1, const time_point_sec& t0) -> uint32_t { + return (t1.sec_since_epoch() - t0.sec_since_epoch()) / rex_return_pool::dist_interval; + }; + + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + const time_point_sec effective_time{cts - cts % rex_return_pool::dist_interval}; - if ( ret_pool_elem == _rexretpool.end() || - ct < ret_pool_elem->last_update_time + eosio::microseconds{rex_return_pool::dist_interval}) { + const auto ret_pool_elem = _rexretpool.begin(); + const auto ret_buckets_elem = _rexretbuckets.begin(); + + if ( ret_pool_elem == _rexretpool.end() || effective_time <= ret_pool_elem->last_dist_time ) { return; } - const int64_t current_rate = ret_pool_elem->current_rate_of_increase; - const uint64_t time_interval = ct.time_since_epoch().count() - ret_pool_elem->last_update_time.time_since_epoch().count(); - const int64_t change_estimate = ( uint128_t(time_interval) * current_rate ) / rex_return_pool::total_duration; - const time_point time_threshold = ct - eosio::microseconds{rex_return_pool::total_duration}; + const int64_t current_rate = ret_pool_elem->current_rate_of_increase; + const uint32_t elapsed_intervals = get_elapsed_intervals(effective_time, ret_pool_elem->last_dist_time); + int64_t change_estimate = current_rate * elapsed_intervals; - const bool new_return_bucket = !ret_pool_elem->return_buckets.empty() - && ret_pool_elem->last_update_time <= ret_pool_elem->return_buckets.rbegin()->first - && ret_pool_elem->return_buckets.rbegin()->first <= ct; - int64_t new_bucket_estimate = 0; - if ( new_return_bucket ) { + { + const bool new_return_bucket = ret_pool_elem->pending_bucket_time < effective_time; + int64_t new_bucket_rate = 0; + time_point_sec new_bucket_time{0}; _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - rp.current_rate_of_increase += rp.return_buckets.rbegin()->second; - const uint64_t dt = ct.time_since_epoch().count() - rp.return_buckets.rbegin()->first.time_since_epoch().count() ; - new_bucket_estimate = ( uint128_t(dt) * rp.return_buckets.rbegin()->second ) / rex_return_pool::total_duration; + if ( new_return_bucket ) { + int64_t remainder = rp.pending_bucket_proceeds % rex_return_pool::total_intervals; + new_bucket_rate = ( rp.pending_bucket_proceeds - remainder ) / rex_return_pool::total_intervals; + new_bucket_time = rp.pending_bucket_time; + rp.current_rate_of_increase += new_bucket_rate; + change_estimate += remainder + new_bucket_rate * get_elapsed_intervals( effective_time, rp.pending_bucket_time ); + rp.pending_bucket_proceeds = 0; + rp.pending_bucket_time = time_point_sec::maximum(); + if ( new_bucket_time < rp.oldest_bucket_time ) { + rp.oldest_bucket_time = new_bucket_time; + } + } + rp.last_dist_time = effective_time; }); + + if ( new_return_bucket ) { + _rexretbuckets.modify( ret_buckets_elem, same_payer, [&]( auto& rb ) { + rb.return_buckets[new_bucket_time] = new_bucket_rate; + }); + } } - int64_t change = change_estimate + new_bucket_estimate; + const time_point_sec time_threshold = effective_time - eosio::seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval); + if ( ret_pool_elem->oldest_bucket_time <= time_threshold ) { + int64_t expired_rate = 0; + int64_t surplus = 0; + _rexretbuckets.modify( ret_buckets_elem, same_payer, [&]( auto& rb ) { + auto& return_buckets = rb.return_buckets; + auto iter = return_buckets.begin(); + while ( iter != return_buckets.end() && iter->first <= time_threshold ) { + auto next = iter; + ++next; + const uint32_t overtime = get_elapsed_intervals( effective_time, iter->first + rex_return_pool::total_intervals ); + surplus += iter->second * overtime; + expired_rate += iter->second; + return_buckets.erase(iter); + } + }); - _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - auto& return_buckets = rp.return_buckets; - auto iter = return_buckets.begin(); - while ( iter != return_buckets.end() && iter->first <= time_threshold ) { - auto next = iter; - ++next; - const uint64_t overtime = ct.time_since_epoch().count() - ( iter->first.time_since_epoch().count() + rex_return_pool::total_duration ); - const int64_t rate = iter->second; - const int64_t surplus = ( uint128_t(overtime) * rate + rex_return_pool::total_duration - 1 ) - / rex_return_pool::total_duration; - change -= surplus; - rp.current_rate_of_increase -= rate; - return_buckets.erase(iter); - iter = next; - } - rp.last_update_time = ct; - }); + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { + if ( !ret_buckets_elem->return_buckets.empty() ) { + rp.oldest_bucket_time = ret_buckets_elem->return_buckets.begin()->first; + } else { + rp.oldest_bucket_time = time_point_sec::min(); + } - if ( change <= 0 ) { - return; + if ( expired_rate > 0) { + rp.current_rate_of_increase -= expired_rate; + } + }); + + if ( surplus > 0 ) { + change_estimate -= surplus; + } } - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { - pool.total_unlent.amount += change; - pool.total_lendable = pool.total_unlent + pool.total_lent; - }); - _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - rp.cummulative_proceeds += change; - }); + if ( change_estimate > 0 ) { + _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { + pool.total_unlent.amount += change_estimate; + pool.total_lendable = pool.total_unlent + pool.total_lent; + }); + } } template @@ -1029,25 +1059,30 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); + if ( fee.amount <= 0) { + return; + } - const int64_t cts = current_time_point().time_since_epoch().count(); - const int64_t bucket_interval = rex_return_pool::hours_per_bucket * useconds_per_hour; - const time_point effective_time{ eosio::microseconds{cts - cts % bucket_interval + bucket_interval} }; - - if ( _rexretpool.begin() == _rexretpool.end() ) { + const time_point_sec ct = current_time_point(); + const uint32_t cts = ct.sec_since_epoch(); + const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; + const time_point_sec effective_time{cts - cts % bucket_interval + bucket_interval}; + const auto return_pool_elem = _rexretpool.begin(); + if ( return_pool_elem == _rexretpool.end() ) { _rexretpool.emplace( get_self(), [&]( auto& rp ) { - rp.last_update_time = effective_time; - rp.proceeds += fee.amount; + rp.last_dist_time = effective_time; + rp.pending_bucket_proceeds = fee.amount; + rp.pending_bucket_time = effective_time; }); + _rexretbuckets.emplace( get_self(), [&]( auto& rb ) { } ); } else { - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { - rp.proceeds += fee.amount; + _rexretpool.modify( return_pool_elem, same_payer, [&]( auto& rp ) { + rp.pending_bucket_proceeds += fee.amount; + if ( rp.pending_bucket_time == time_point_sec::maximum() ) { + rp.pending_bucket_time = effective_time; + } }); } - - _rexretpool.modify( _rexretpool.begin(), same_payer, [&]( auto& rp ) { - rp.return_buckets[effective_time] += fee.amount; - }); } /** From e1dfd528bbfa59afb39fc7c77b0967024170dde7 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 00:47:04 -0500 Subject: [PATCH 0945/1048] REX changes - tests --- contracts/eosio.system/src/rex.cpp | 18 ++--- tests/eosio.system_tester.hpp | 21 ++++++ tests/eosio.system_tests.cpp | 105 +++++++++++++++++------------ 3 files changed, 94 insertions(+), 50 deletions(-) diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 663336d2..c775a25b 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -6,6 +6,7 @@ namespace eosiosystem { using eosio::current_time_point; using eosio::token; + using eosio::seconds; void system_contract::deposit( const name& owner, const asset& amount ) { @@ -621,8 +622,8 @@ namespace eosiosystem { */ void system_contract::update_rex_pool() { - auto get_elapsed_intervals = [&](const time_point_sec& t1, const time_point_sec& t0) -> uint32_t { - return (t1.sec_since_epoch() - t0.sec_since_epoch()) / rex_return_pool::dist_interval; + auto get_elapsed_intervals = [&]( const time_point_sec& t1, const time_point_sec& t0 ) -> uint32_t { + return ( t1.sec_since_epoch() - t0.sec_since_epoch() ) / rex_return_pool::dist_interval; }; const time_point_sec ct = current_time_point(); @@ -637,13 +638,13 @@ namespace eosiosystem { } const int64_t current_rate = ret_pool_elem->current_rate_of_increase; - const uint32_t elapsed_intervals = get_elapsed_intervals(effective_time, ret_pool_elem->last_dist_time); + const uint32_t elapsed_intervals = get_elapsed_intervals( effective_time, ret_pool_elem->last_dist_time ); int64_t change_estimate = current_rate * elapsed_intervals; { const bool new_return_bucket = ret_pool_elem->pending_bucket_time < effective_time; int64_t new_bucket_rate = 0; - time_point_sec new_bucket_time{0}; + time_point_sec new_bucket_time = time_point_sec::min(); _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { if ( new_return_bucket ) { int64_t remainder = rp.pending_bucket_proceeds % rex_return_pool::total_intervals; @@ -667,7 +668,7 @@ namespace eosiosystem { } } - const time_point_sec time_threshold = effective_time - eosio::seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval); + const time_point_sec time_threshold = effective_time - seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval); if ( ret_pool_elem->oldest_bucket_time <= time_threshold ) { int64_t expired_rate = 0; int64_t surplus = 0; @@ -677,10 +678,12 @@ namespace eosiosystem { while ( iter != return_buckets.end() && iter->first <= time_threshold ) { auto next = iter; ++next; - const uint32_t overtime = get_elapsed_intervals( effective_time, iter->first + rex_return_pool::total_intervals ); + const uint32_t overtime = get_elapsed_intervals( effective_time, + iter->first + seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval) ); surplus += iter->second * overtime; expired_rate += iter->second; return_buckets.erase(iter); + iter = next; } }); @@ -690,7 +693,6 @@ namespace eosiosystem { } else { rp.oldest_bucket_time = time_point_sec::min(); } - if ( expired_rate > 0) { rp.current_rate_of_increase -= expired_rate; } @@ -1059,7 +1061,7 @@ namespace eosiosystem { void system_contract::add_to_rex_return_pool( const asset& fee ) { update_rex_pool(); - if ( fee.amount <= 0) { + if ( fee.amount <= 0 ) { return; } diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp index a4795c03..baf82bfd 100644 --- a/tests/eosio.system_tester.hpp +++ b/tests/eosio.system_tester.hpp @@ -687,6 +687,27 @@ class eosio_system_tester : public TESTER { return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer_max_time ); } + fc::variant get_rex_return_buckets() const { + vector data; + const auto& db = control->db(); + namespace chain = eosio::chain; + const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(retbuckets) ) ); + if ( !t_id ) { + return fc::variant(); + } + + const auto& idx = db.get_index(); + + auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); + if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { + return fc::variant(); + } + + data.resize( itr->value.size() ); + memcpy( data.data(), itr->value.data(), data.size() ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_buckets", data, abi_serializer_max_time ); + } + void setup_rex_accounts( const std::vector& accounts, const asset& init_balance, const asset& net = core_sym::from_string("80.0000"), diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 61355abc..d09ee6bf 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -3984,7 +3984,8 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + int64_t rate = fee.get_amount() / (30 * 144); + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(10) ); // alice is finally able to sellrex, she gains the fee paid by bob @@ -3992,8 +3993,7 @@ BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); auto expected_rex_fund = (init_balance + fee).get_amount(); auto actual_rex_fund = get_rex_fund(alice).get_amount(); - BOOST_REQUIRE_EQUAL( true, within_error( expected_rex_fund, actual_rex_fund, 2 ) ); - BOOST_TEST_REQUIRE( actual_rex_fund <= expected_rex_fund ); + BOOST_REQUIRE_EQUAL( expected_rex_fund, actual_rex_fund ); // test that carol's resource limits have been updated properly when loan expires BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); @@ -4463,10 +4463,9 @@ BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - - BOOST_TEST_REQUIRE( within_error( cur_rex_balance.get_amount(), get_rex_pool()["total_lendable"].as().get_amount(), 4 ) ); - BOOST_TEST_REQUIRE( cur_rex_balance.get_amount() >= get_rex_pool()["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), get_rex_pool()["total_unlent"].as() ); + BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); + BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), + get_rex_pool()["total_unlent"].as() ); } FC_LOG_AND_RETHROW() @@ -4899,8 +4898,8 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_rex.get_amount()) * total_lendable ) / total_rex; const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); - BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance( alice ) + rex_sell_amount ); - BOOST_TEST_REQUIRE( within_error( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake( alice ).get_amount(), 2 ) ); + BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance(alice) + rex_sell_amount ); + BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake(alice).get_amount() ); BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4979,14 +4978,14 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 2 ) ); + BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == get_producer_info(producer_names[0])["total_votes"].as_double() ); BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); produce_block( fc::hours(30 * 24 + 13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_TEST_REQUIRE( within_error( (purchase + rent + rent + rent).get_amount(), get_rex_vote_stake(alice).get_amount(), 3 ) ); + BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); BOOST_TEST_REQUIRE ( stake2votes(init_stake + get_rex_vote_stake(alice) ) == get_producer_info(producer_names[0])["total_votes"].as_double() ); @@ -5255,6 +5254,8 @@ BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { + constexpr uint32_t total_intervals = 30 * 144; + constexpr uint32_t dist_interval = 10 * 60; BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); const asset init_balance = core_sym::from_string("100000.0000"); @@ -5278,16 +5279,17 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); - int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + int32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); produce_block( fc::hours(13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + int64_t rate = fee.get_amount() / total_intervals; + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - int64_t change = (eosio::chain::uint128_t(t1-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); + int32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + int64_t change = rate * ((t1-t0) / dist_interval) + fee.get_amount() % total_intervals; int64_t expected = payment.get_amount() + change; auto rex_pool = get_rex_pool(); @@ -5297,13 +5299,14 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { produce_block( fc::days(25) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); - int64_t t2 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - change = (eosio::chain::uint128_t(t2-t0) * fee.get_amount()) / (30 * 24 * 3600 * 1000000ll); + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); + int64_t t2 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + change = rate * ((t2-t0) / dist_interval) + fee.get_amount() % total_intervals; expected = payment.get_amount() + change; rex_pool = get_rex_pool(); - BOOST_TEST_REQUIRE( within_one( expected, rex_pool["total_lendable"].as().get_amount() ) ); + BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); produce_blocks( 1 ); produce_block( fc::days(5) ); @@ -5311,12 +5314,11 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); rex_pool = get_rex_pool(); expected = payment.get_amount() + fee.get_amount(); - BOOST_TEST_REQUIRE( within_error( expected, rex_pool["total_lendable"].as().get_amount(), 2 ) ); - BOOST_TEST_REQUIRE( expected >= rex_pool["total_lendable"].as().get_amount() ); + BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); BOOST_REQUIRE_EQUAL( rex_pool["total_lendable"].as(), rex_pool["total_unlent"].as() ); } @@ -5328,38 +5330,39 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { const asset fee = core_sym::from_string("15.0000"); BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); auto rex_return_pool = get_rex_return_pool(); - int64_t t0 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); + uint32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); produce_block( fc::hours(1) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 1, rex_return_pool["return_buckets"].get_array().size() ); - int64_t t1 = rex_return_pool["last_update_time"].as().time_since_epoch().count(); - BOOST_REQUIRE_EQUAL( t1, t0 + 3600 * 1000000ll + 500000 ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + uint32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + BOOST_REQUIRE_EQUAL( t1, t0 + 6 * dist_interval ); produce_block( fc::hours(12) ); BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 2, rex_return_pool["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); + int64_t rate = 2 * fee.get_amount() / total_intervals; + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::hours(8) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); produce_block( fc::days(30) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount(), rex_return_pool["current_rate_of_increase"].as() ); + BOOST_REQUIRE_EQUAL( fee.get_amount() / total_intervals, rex_return_pool["current_rate_of_increase"].as() ); BOOST_TEST_REQUIRE( (init_lendable + fee + fee).get_amount() < get_rex_pool()["total_lendable"].as().get_amount() ); produce_block( fc::days(1) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["return_buckets"].get_array().size() ); - BOOST_TEST_REQUIRE( within_error( init_lendable.get_amount() + 3 * fee.get_amount(), - get_rex_pool()["total_lendable"].as().get_amount(), 3 ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( init_lendable.get_amount() + 3 * fee.get_amount(), + get_rex_pool()["total_lendable"].as().get_amount() ); } { @@ -5369,24 +5372,42 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); auto rex_pool_0 = get_rex_pool(); auto rex_return_pool_0 = get_rex_return_pool(); - produce_block( fc::minutes(9) ); + produce_block( fc::minutes(2) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); auto rex_pool_1 = get_rex_pool(); auto rex_return_pool_1 = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_update_time"].as().time_since_epoch().count(), - rex_return_pool_1["last_update_time"].as().time_since_epoch().count()); + BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_dist_time"].as().sec_since_epoch(), + rex_return_pool_1["last_dist_time"].as().sec_since_epoch() ); BOOST_REQUIRE_EQUAL( rex_pool_0["total_lendable"].as(), - rex_pool_1["total_lendable"].as()); - produce_block( fc::minutes(1) ); + rex_pool_1["total_lendable"].as() ); + produce_block( fc::minutes(9) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); auto rex_pool_2 = get_rex_pool(); auto rex_return_pool_2 = get_rex_return_pool(); - BOOST_TEST_REQUIRE( rex_return_pool_1["last_update_time"].as().time_since_epoch().count() < - rex_return_pool_2["last_update_time"].as().time_since_epoch().count()); + BOOST_TEST_REQUIRE( rex_return_pool_1["last_dist_time"].as().sec_since_epoch() < + rex_return_pool_2["last_dist_time"].as().sec_since_epoch() ); BOOST_TEST_REQUIRE( rex_pool_1["total_lendable"].as().get_amount() < - rex_pool_2["total_lendable"].as().get_amount()); + rex_pool_2["total_lendable"].as().get_amount() ); + produce_block( fc::days(31) ); + produce_blocks( 1 ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_pool()["current_rate_of_increase"].as() ); } + { + const asset fee = core_sym::from_string("30.0000"); + for ( uint8_t i = 0; i < 5; ++i ) { + BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); + produce_block( fc::days(1) ); + } + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + BOOST_REQUIRE_EQUAL( 5, get_rex_return_buckets()["return_buckets"].get_array().size() ); + produce_block( fc::days(30) ); + BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); + BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); + } + } FC_LOG_AND_RETHROW() From c7a62d725c2b5597785d389615e831e2a1eb0e79 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 11:16:53 -0500 Subject: [PATCH 0946/1048] REX changes - updated comments --- .../include/eosio.system/eosio.system.hpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 037b3a9d..3886d4a5 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -341,11 +341,11 @@ namespace eosiosystem { // `rex_return_pool` structure underlying the rex return pool table. A rex return pool table entry is defined by: // - `version` defaulted to zero, - // - `last_update_time` the last time returns from renting, ram fees, and name bids were added to the rex pool, - // - `current_rate_of_increase` current amount to be added to the rex pool at a rate of per 30 days, - // - `cummulative_proceeds` bookkeeping variable that tracks fees added to rex pool up to current time, - // - `proceeds` bookkeeping variable that tracks fees added to rex return pool up to current time, - // - `return_buckets` 12-hour buckets containing amounts to be added to the rex pool and the times they become effective + // - `last_dist_time` the last time proceeds from renting, ram fees, and name bids were added to the rex pool, + // - `pending_bucket_time` timestamp of the pending 12-hour return bucket, + // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, + // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, + // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; time_point_sec last_dist_time; @@ -354,15 +354,18 @@ namespace eosiosystem { int64_t pending_bucket_proceeds = 0; int64_t current_rate_of_increase = 0; - static constexpr int32_t total_intervals = 30 * 144; // 30 days - static constexpr int32_t dist_interval = 10 * 60; // 10 minutes - static constexpr uint8_t hours_per_bucket = 12; + static constexpr uint32_t total_intervals = 30 * 144; // 30 days + static constexpr uint32_t dist_interval = 10 * 60; // 10 minutes + static constexpr uint8_t hours_per_bucket = 12; uint64_t primary_key()const { return 0; } }; typedef eosio::multi_index< "rexretpool"_n, rex_return_pool > rex_return_pool_table; + // `rex_return_buckets` structure underlying the rex return buckets table. A rex return buckets table is defined by: + // - `version` defaulted to zero, + // - `return_buckets` buckets of proceeds accumulated in 12-hour intervals struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_buckets { uint8_t version = 0; std::map return_buckets; From d9ccc2268dcca67489936de58caa78a0ee4b167d Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 15:20:49 -0500 Subject: [PATCH 0947/1048] REX changes - additional checks --- .../include/eosio.system/eosio.system.hpp | 5 ++++- contracts/eosio.system/src/rex.cpp | 20 ++++++++++++++----- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 3886d4a5..fb7e8cdb 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -345,7 +345,8 @@ namespace eosiosystem { // - `pending_bucket_time` timestamp of the pending 12-hour return bucket, // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, - // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool + // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool, + // - `proceeds` the maximum amount of proceeds that can be added to the rex pool at any given time struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { uint8_t version = 0; time_point_sec last_dist_time; @@ -353,10 +354,12 @@ namespace eosiosystem { time_point_sec oldest_bucket_time = time_point_sec::min(); int64_t pending_bucket_proceeds = 0; int64_t current_rate_of_increase = 0; + int64_t proceeds = 0; static constexpr uint32_t total_intervals = 30 * 144; // 30 days static constexpr uint32_t dist_interval = 10 * 60; // 10 minutes static constexpr uint8_t hours_per_bucket = 12; + static_assert( total_intervals * dist_interval == 30 * seconds_per_day ); uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index c775a25b..8e9d881f 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -642,7 +642,7 @@ namespace eosiosystem { int64_t change_estimate = current_rate * elapsed_intervals; { - const bool new_return_bucket = ret_pool_elem->pending_bucket_time < effective_time; + const bool new_return_bucket = ret_pool_elem->pending_bucket_time <= effective_time; int64_t new_bucket_rate = 0; time_point_sec new_bucket_time = time_point_sec::min(); _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { @@ -658,6 +658,7 @@ namespace eosiosystem { rp.oldest_bucket_time = new_bucket_time; } } + rp.proceeds -= change_estimate; rp.last_dist_time = effective_time; }); @@ -696,11 +697,18 @@ namespace eosiosystem { if ( expired_rate > 0) { rp.current_rate_of_increase -= expired_rate; } + if ( surplus > 0 ) { + change_estimate -= surplus; + rp.proceeds += surplus; + } }); + } - if ( surplus > 0 ) { - change_estimate -= surplus; - } + if ( change_estimate > 0 && ret_pool_elem->proceeds < 0 ) { + _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { + change_estimate += rp.proceeds; + rp.proceeds = 0; + }); } if ( change_estimate > 0 ) { @@ -1074,12 +1082,14 @@ namespace eosiosystem { _rexretpool.emplace( get_self(), [&]( auto& rp ) { rp.last_dist_time = effective_time; rp.pending_bucket_proceeds = fee.amount; - rp.pending_bucket_time = effective_time; + rp.pending_bucket_time = effective_time; + rp.proceeds = fee.amount; }); _rexretbuckets.emplace( get_self(), [&]( auto& rb ) { } ); } else { _rexretpool.modify( return_pool_elem, same_payer, [&]( auto& rp ) { rp.pending_bucket_proceeds += fee.amount; + rp.proceeds += fee.amount; if ( rp.pending_bucket_time == time_point_sec::maximum() ) { rp.pending_bucket_time = effective_time; } From 8759a624c817516a51b4dbae7f3f95e592818d38 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 18:59:46 -0500 Subject: [PATCH 0948/1048] REX changes - fix build issues --- tests/eosio.system_tests.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d09ee6bf..4a15fc12 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4871,9 +4871,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, { producer_names.begin(), producer_names.begin() + 20 } ) ); + vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 20 ) ) ); BOOST_REQUIRE_EQUAL( success(), - vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); + vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4907,7 +4907,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to produce_block( fc::days(31) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names[0], producer_names[4] ) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); @@ -4963,7 +4963,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == From e3d637bc03c2ceef1d2a7e701f07a88ffa338202 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 19:08:50 -0500 Subject: [PATCH 0949/1048] REX changes - fix build issues --- tests/eosio.system_tests.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 4a15fc12..120cfb05 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4871,9 +4871,9 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to } BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 20 ) ) ); + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); + vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); @@ -4907,7 +4907,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to produce_block( fc::days(31) ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names[0], producer_names[4] ) ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names[0], producer_names[4]) ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); @@ -4949,7 +4949,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names.begin(), producer_names.begin() + 21 } ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); BOOST_REQUIRE_EQUAL( purchase.get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); @@ -4963,7 +4963,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_tes BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector( producer_names.begin(), producer_names.begin() + 21 ) ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == From 705462c6060a378d816135da08af7814b41c3270 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 19:38:54 -0500 Subject: [PATCH 0950/1048] REX changes - tests --- tests/eosio.system_tests.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 120cfb05..d247085c 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4128,9 +4128,6 @@ BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol{SY(4,REX)} ) ) ); BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ) ); - // BOOST_REQUIRE_EQUAL( init_alice_rex_stake / 4, get_rex_vote_stake( alice ).get_amount() ); - // BOOST_TEST_REQUIRE( within_one( init_alice_rex_stake / 4, get_voter_info(alice)["staked"].as() - init_stake ) ); init_alice_rex = get_rex_balance(alice); BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); @@ -4881,7 +4878,11 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to == get_producer_info(producer_names[20])["total_votes"].as() ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); + + produce_blocks( 1 ); produce_block( fc::days(10) ); + produce_blocks( 1 ); + BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); @@ -4889,7 +4890,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); + produce_blocks( 1 ); produce_block( fc::hours(19 * 24 + 23) ); + produce_blocks( 1 ); + BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); @@ -4903,8 +4907,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); - + + produce_blocks( 1 ); produce_block( fc::days(31) ); + produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names[0], producer_names[4]) ) ); From 3647ed9e93811a7663d605acae3bdfe1b8267500 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Wed, 11 Dec 2019 19:47:03 -0500 Subject: [PATCH 0951/1048] REX changes - tests --- tests/eosio.system_tests.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index d247085c..f076a2aa 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4913,7 +4913,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names[0], producer_names[4]) ) ); + std::vector two_producers; + two_producers.push_back( producer_names[0] ); + two_producers.push_back( producer_names[4] ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, two_producers ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); From b3cf026153d107776c1018e839440e65d2ff57d1 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Thu, 12 Dec 2019 10:34:37 -0500 Subject: [PATCH 0952/1048] REX changes - code cleaning --- tests/eosio.system_tests.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index f076a2aa..e06bc5bb 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -4878,11 +4878,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to == get_producer_info(producer_names[20])["total_votes"].as() ); BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - - produce_blocks( 1 ); produce_block( fc::days(10) ); - produce_blocks( 1 ); - BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); @@ -4890,10 +4886,7 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[20])["total_votes"].as() ); - produce_blocks( 1 ); produce_block( fc::hours(19 * 24 + 23) ); - produce_blocks( 1 ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); const asset init_rex = get_rex_balance( alice ); const auto current_rex_pool = get_rex_pool(); @@ -4907,16 +4900,10 @@ BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::to BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) == get_producer_info(producer_names[0])["total_votes"].as() ); - - produce_blocks( 1 ); produce_block( fc::days(31) ); - produce_blocks( 1 ); BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - std::vector two_producers; - two_producers.push_back( producer_names[0] ); - two_producers.push_back( producer_names[4] ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, two_producers ) ); + BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), buyrex( alice, core_sym::from_string("1.0000") ) ); From 282534d2a1855837c302ba0fef38f1dc788a6133 Mon Sep 17 00:00:00 2001 From: Khaled Al-Hassanieh Date: Fri, 13 Dec 2019 14:41:28 -0500 Subject: [PATCH 0953/1048] REX changes - arhag's PR review --- tests/eosio.system_tests.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index e06bc5bb..c2eab2cc 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -5270,13 +5270,18 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { } { - const asset fee = core_sym::from_string("30.0000"); + const asset fee = core_sym::from_string("30.0000"); + const uint32_t bucket_interval_sec = fc::hours(12).to_seconds(); + const uint32_t current_time_sec = control->pending_block_time().sec_since_epoch(); + const time_point_sec expected_pending_bucket_time{current_time_sec - current_time_sec % bucket_interval_sec + bucket_interval_sec}; BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); auto rex_return_pool = get_rex_return_pool(); BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - int32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); + BOOST_REQUIRE_EQUAL( expected_pending_bucket_time.sec_since_epoch(), + rex_return_pool["pending_bucket_time"].as().sec_since_epoch() ); + int32_t t0 = rex_return_pool["pending_bucket_time"].as().sec_since_epoch(); produce_block( fc::hours(13) ); BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); From 5905369fd5a0386c9d3b66edb245f8ec6f458ed4 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Dec 2019 10:25:21 -0500 Subject: [PATCH 0954/1048] bump version to v1.9.0-rc4 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 944d08c2..fbf5e4f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc3) +set(VERSION_SUFFIX rc4) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index 4649af9d..a33f7032 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc3 +## Version : 1.9.0-rc4 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. From 9a5df11867019a75933efac63d10e55aac0ec2b5 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 27 Nov 2019 11:24:28 -0500 Subject: [PATCH 0955/1048] resource31 --- contracts/eosio.system/CMakeLists.txt | 1 + .../include/eosio.system/eosio.system.hpp | 99 +++++++++++++++++++ contracts/eosio.system/src/resource31.cpp | 31 ++++++ tests/eosio.resource31_tests.cpp | 24 +++++ 4 files changed, 155 insertions(+) create mode 100644 contracts/eosio.system/src/resource31.cpp create mode 100644 tests/eosio.resource31_tests.cpp diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index 3f909084..d8d62b1d 100644 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -4,6 +4,7 @@ add_contract(eosio.system eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/exchange_state.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/resource31.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/voting.cpp ) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index fb7e8cdb..753e235c 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -87,6 +87,7 @@ namespace eosiosystem { * - Users can bid on premium names. * - A resource exchange system (REX) allows token holders to lend their tokens, * and users to rent CPU and Network resources in return for a market-determined fee. + * - A resource market separate from REX: `buycpu31`, `buynet31` */ // A name bid, which consists of: @@ -469,6 +470,46 @@ namespace eosiosystem { asset stake_change; }; + enum resource31_type: uint8_t { + cpu = 0, + net = 1, + }; + + struct [[eosio::table,eosio::contract("eosio.system")]] resource31_state { + uint8_t version = 0; + uint8_t type; // resource31_type + int64_t weight; + int64_t initial_weight; + int64_t target_weight; + time_point_sec initial_timestamp; + time_point_sec target_timestamp; + time_point_sec last_update; + double exponent; + uint32_t window; + asset peak_price; + asset min_purchase_price; + int64_t sold; + + uint64_t primary_key()const { return type; } + }; + + typedef eosio::multi_index<"res31.state"_n, resource31_state> resource31_state_table; + + struct [[eosio::table,eosio::contract("eosio.system")]] resource31_order { + uint8_t version = 0; + uint64_t id; + name owner; + uint8_t type; // resource31_type + int64_t weight; + time_point_sec expires; + + uint64_t primary_key()const { return id; } + uint64_t by_owner()const { return owner.value; } + }; + + typedef eosio::multi_index< "res31.order"_n, resource31_order, + indexed_by<"byowner"_n, const_mem_fun>> resource31_order_table; + /** * The EOSIO system contract. The EOSIO system contract governs ram market, voters, producers, global state. */ @@ -1122,6 +1163,60 @@ namespace eosiosystem { [[eosio::action]] void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); + /** + * Configure or modify the `buycpu31` market. The market becomes available the first time this + * action is invoked. + * + * @param delta_weight - immediately adjust the market cap by this amount. 1 represents the same amount of + * resources as 1 satoshi of SYS staked. + * @param target_weight - linearly grow the market cap to this amount. + * @param target_timestamp - stop automatic market growth at this time. Once this time hits, the market + * cap will be `target_weight`. + */ + [[eosio::action]] + void configcpu31( int64_t delta_weight, int64_t target_weight, const time_point_sec& target_timestamp, + double exponent, uint32_t window, const asset& peak_price, const asset& min_purchase_price ); + + /** + * Configure or modify the `buynet31` market. The market becomes available the first time this + * action is invoked. + * + * @param delta_weight - immediately adjust the market cap by this amount. 1 represents the same amount of + * resources as 1 satoshi of SYS staked. + * @param target_weight - linearly grow the market cap to this amount. + * @param target_timestamp - stop automatic market growth at this time. Once this time hits, the market + * cap will be `target_weight`. + */ + [[eosio::action]] + void confignet31( int64_t delta_weight, int64_t target_weight, const time_point_sec& target_timestamp, + double exponent, uint32_t window, const asset& peak_price, const asset& min_purchase_price ); + + /** + * Buy CPU for 31 days. + * + * @param payer - the resource buyer + * @param receiver - the resource receiver + * @param amount - the amount of resource to buy. 1 has the same amount of resources as + * 1 satoshi of SYS staked. + * @param max_payment - the maximum amount `payer` is willing to pay. Tokens are withdrawn from + * `payer`'s token balance. + */ + [[eosio::action]] + void buycpu31( const name& payer, const name& receiver, int64_t amount, const asset& max_payment ); + + /** + * Buy NET for 31 days. + * + * @param payer - the resource buyer + * @param receiver - the resource receiver + * @param amount - the amount of resource to buy. 1 has the same amount of resources as + * 1 satoshi of SYS staked. + * @param max_payment - the maximum amount `payer` is willing to pay. Tokens are withdrawn from + * `payer`'s token balance. + */ + [[eosio::action]] + void buynet31( const name& payer, const name& receiver, int64_t amount, const asset& max_payment ); + using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; using setacctnet_action = eosio::action_wrapper<"setacctnet"_n, &system_contract::setacctnet>; @@ -1168,6 +1263,10 @@ namespace eosiosystem { using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; + using configcpu31_action = eosio::action_wrapper<"configcpu31"_n, &system_contract::configcpu31>; + using confignet31_action = eosio::action_wrapper<"confignet31"_n, &system_contract::confignet31>; + using buycpu31_action = eosio::action_wrapper<"buycpu31"_n, &system_contract::buycpu31>; + using buynet31_action = eosio::action_wrapper<"buynet31"_n, &system_contract::buynet31>; private: // Implementation details: diff --git a/contracts/eosio.system/src/resource31.cpp b/contracts/eosio.system/src/resource31.cpp new file mode 100644 index 00000000..fc0134a8 --- /dev/null +++ b/contracts/eosio.system/src/resource31.cpp @@ -0,0 +1,31 @@ +#include + +namespace eosiosystem { + +void system_contract::configcpu31(int64_t delta_weight, int64_t target_weight, + const time_point_sec& target_timestamp, + double exponent, uint32_t window, + const asset& peak_price, + const asset& min_purchase_price) { + // +} + +void system_contract::confignet31(int64_t delta_weight, int64_t target_weight, + const time_point_sec& target_timestamp, + double exponent, uint32_t window, + const asset& peak_price, + const asset& min_purchase_price) { + // +} + +void system_contract::buycpu31(const name& payer, const name& receiver, + int64_t amount, const asset& max_payment) { + // +} + +void system_contract::buynet31(const name& payer, const name& receiver, + int64_t amount, const asset& max_payment) { + // +} + +} // namespace eosiosystem diff --git a/tests/eosio.resource31_tests.cpp b/tests/eosio.resource31_tests.cpp new file mode 100644 index 00000000..b25261a7 --- /dev/null +++ b/tests/eosio.resource31_tests.cpp @@ -0,0 +1,24 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "eosio.system_tester.hpp" + +using namespace eosio_system; + +BOOST_AUTO_TEST_SUITE(eosio_system_resource31_tests) + +BOOST_FIXTURE_TEST_CASE(foo, eosio_system_tester) try { + // +} +FC_LOG_AND_RETHROW() + +BOOST_AUTO_TEST_SUITE_END() From 6994ec3c7cfb1366145ad410a0f172e2f24e023d Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 27 Nov 2019 16:00:30 -0500 Subject: [PATCH 0956/1048] buybandwidth --- contracts/eosio.system/CMakeLists.txt | 2 +- .../include/eosio.system/eosio.system.hpp | 121 ++++++++---------- contracts/eosio.system/src/buybandwidth.cpp | 14 ++ contracts/eosio.system/src/resource31.cpp | 31 ----- ...tests.cpp => eosio.buybandwidth_tests.cpp} | 4 +- 5 files changed, 69 insertions(+), 103 deletions(-) create mode 100644 contracts/eosio.system/src/buybandwidth.cpp delete mode 100644 contracts/eosio.system/src/resource31.cpp rename tests/{eosio.resource31_tests.cpp => eosio.buybandwidth_tests.cpp} (90%) diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index d8d62b1d..825a02d7 100644 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -1,10 +1,10 @@ add_contract(eosio.system eosio.system + ${CMAKE_CURRENT_SOURCE_DIR}/src/buybandwidth.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/delegate_bandwidth.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/exchange_state.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/resource31.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/voting.cpp ) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 753e235c..44d03d90 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -87,7 +87,7 @@ namespace eosiosystem { * - Users can bid on premium names. * - A resource exchange system (REX) allows token holders to lend their tokens, * and users to rent CPU and Network resources in return for a market-determined fee. - * - A resource market separate from REX: `buycpu31`, `buynet31` + * - A resource market separate from REX: `buybandwidth` */ // A name bid, which consists of: @@ -470,45 +470,62 @@ namespace eosiosystem { asset stake_change; }; - enum resource31_type: uint8_t { - cpu = 0, - net = 1, + struct buybw_config_resource { + int64_t current_weight; // Immediately set the resource market weight to this amount. 1 represents the same amount of resources as 1 satoshi of SYS staked. + int64_t target_weight; // Linearly grow the resource market weight to this amount. 1 represents the same amount of resources as 1 satoshi of SYS staked. + time_point_sec target_timestamp; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. + // Ignored if current_weight == target_weight. + double exponent; // Exponent of resource price curve. Must be >= 1. + uint32_t decay_days; // Number of days for adjusted resource utilization to decay to instantaneous utilization within exp(-1). + asset total_price; // Total price needed to buy the entire resource market weight. + asset min_purchase_price; // Minimum purchase. This needs to be large enough to cover RAM costs. }; - struct [[eosio::table,eosio::contract("eosio.system")]] resource31_state { + struct buybw_config { + buybw_config_resource net; // NET market configuration + buybw_config_resource cpu; // CPU market configuration + uint32_t purchase_days; // `buybandwidth` `days` argument must match this. + }; + + struct buybw_state_resource { + uint8_t version = 0; + int64_t weight; // resource market weight + int64_t initial_weight; // Initial resource market weight used for linear growth + int64_t target_weight; // Linearly grow the resource market weight to this amount + time_point_sec initial_timestamp; // When resource market weight growth started + time_point_sec target_timestamp; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. + double exponent; // Exponent of resource price curve. + uint32_t decay_days; // Number of days for adjusted resource utilization to decay to instantaneous utilization within exp(-1). + asset total_price; // Total price needed to buy the entire resource market weight. + asset min_purchase_price; // Minimum purchase + int64_t utilization; // Instantaneous resource utilization. This is the current amount sold. + int64_t adjusted_utilization; // Adjusted resource utilization. This >= utilization. It grows instantly but decays exponentially. + }; + + struct [[eosio::table("buybw.state"),eosio::contract("eosio.system")]] buybw_state { uint8_t version = 0; - uint8_t type; // resource31_type - int64_t weight; - int64_t initial_weight; - int64_t target_weight; - time_point_sec initial_timestamp; - time_point_sec target_timestamp; - time_point_sec last_update; - double exponent; - uint32_t window; - asset peak_price; - asset min_purchase_price; - int64_t sold; - - uint64_t primary_key()const { return type; } + buybw_state_resource net; // NET market state + buybw_state_resource cpu; // CPU market state + + uint64_t primary_key()const { return 0; } }; - typedef eosio::multi_index<"res31.state"_n, resource31_state> resource31_state_table; + typedef eosio::singleton<"buybw.state"_n, buybw_state> buybw_state_singleton; - struct [[eosio::table,eosio::contract("eosio.system")]] resource31_order { + struct [[eosio::table("buybw.order"),eosio::contract("eosio.system")]] buybw_order { uint8_t version = 0; uint64_t id; name owner; - uint8_t type; // resource31_type - int64_t weight; + int64_t net_weight; + int64_t cpu_weight; time_point_sec expires; uint64_t primary_key()const { return id; } uint64_t by_owner()const { return owner.value; } }; - typedef eosio::multi_index< "res31.order"_n, resource31_order, - indexed_by<"byowner"_n, const_mem_fun>> resource31_order_table; + typedef eosio::multi_index< "buybw.order"_n, buybw_order, + indexed_by<"byowner"_n, const_mem_fun>> buybw_order_table; /** * The EOSIO system contract. The EOSIO system contract governs ram market, voters, producers, global state. @@ -546,6 +563,7 @@ namespace eosiosystem { static constexpr eosio::name names_account{"eosio.names"_n}; static constexpr eosio::name saving_account{"eosio.saving"_n}; static constexpr eosio::name rex_account{"eosio.rex"_n}; + static constexpr eosio::name reserv_account{"eosio.reserv"_n}; static constexpr eosio::name null_account{"eosio.null"_n}; static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); @@ -1164,58 +1182,25 @@ namespace eosiosystem { void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); /** - * Configure or modify the `buycpu31` market. The market becomes available the first time this + * Configure the `buybandwidth` market. The market becomes available the first time this * action is invoked. - * - * @param delta_weight - immediately adjust the market cap by this amount. 1 represents the same amount of - * resources as 1 satoshi of SYS staked. - * @param target_weight - linearly grow the market cap to this amount. - * @param target_timestamp - stop automatic market growth at this time. Once this time hits, the market - * cap will be `target_weight`. - */ - [[eosio::action]] - void configcpu31( int64_t delta_weight, int64_t target_weight, const time_point_sec& target_timestamp, - double exponent, uint32_t window, const asset& peak_price, const asset& min_purchase_price ); - - /** - * Configure or modify the `buynet31` market. The market becomes available the first time this - * action is invoked. - * - * @param delta_weight - immediately adjust the market cap by this amount. 1 represents the same amount of - * resources as 1 satoshi of SYS staked. - * @param target_weight - linearly grow the market cap to this amount. - * @param target_timestamp - stop automatic market growth at this time. Once this time hits, the market - * cap will be `target_weight`. - */ - [[eosio::action]] - void confignet31( int64_t delta_weight, int64_t target_weight, const time_point_sec& target_timestamp, - double exponent, uint32_t window, const asset& peak_price, const asset& min_purchase_price ); - - /** - * Buy CPU for 31 days. - * - * @param payer - the resource buyer - * @param receiver - the resource receiver - * @param amount - the amount of resource to buy. 1 has the same amount of resources as - * 1 satoshi of SYS staked. - * @param max_payment - the maximum amount `payer` is willing to pay. Tokens are withdrawn from - * `payer`'s token balance. */ [[eosio::action]] - void buycpu31( const name& payer, const name& receiver, int64_t amount, const asset& max_payment ); + void configbuybw(const buybw_config& args); /** - * Buy NET for 31 days. + * Buy NET and CPU * * @param payer - the resource buyer * @param receiver - the resource receiver - * @param amount - the amount of resource to buy. 1 has the same amount of resources as - * 1 satoshi of SYS staked. + * @param days - number of days of resource availability. Must match market configuration. + * @param net - fraction of net (100% = 10^18) managed by this market + * @param cpu - fraction of cpu (100% = 10^18) managed by this market * @param max_payment - the maximum amount `payer` is willing to pay. Tokens are withdrawn from * `payer`'s token balance. */ [[eosio::action]] - void buynet31( const name& payer, const name& receiver, int64_t amount, const asset& max_payment ); + void buybandwidth( const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, const asset& max_payment ); using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; @@ -1263,10 +1248,8 @@ namespace eosiosystem { using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; - using configcpu31_action = eosio::action_wrapper<"configcpu31"_n, &system_contract::configcpu31>; - using confignet31_action = eosio::action_wrapper<"confignet31"_n, &system_contract::confignet31>; - using buycpu31_action = eosio::action_wrapper<"buycpu31"_n, &system_contract::buycpu31>; - using buynet31_action = eosio::action_wrapper<"buynet31"_n, &system_contract::buynet31>; + using configcpu_action = eosio::action_wrapper<"configbuybw"_n, &system_contract::configbuybw>; + using buybandwidth_action = eosio::action_wrapper<"buybandwidth"_n, &system_contract::buybandwidth>; private: // Implementation details: diff --git a/contracts/eosio.system/src/buybandwidth.cpp b/contracts/eosio.system/src/buybandwidth.cpp new file mode 100644 index 00000000..c25e5b7d --- /dev/null +++ b/contracts/eosio.system/src/buybandwidth.cpp @@ -0,0 +1,14 @@ +#include + +namespace eosiosystem { + +void system_contract::configbuybw(const buybw_config& args) { + // +} + +void system_contract::buybandwidth(const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, + const asset& max_payment) { + // +} + +} // namespace eosiosystem diff --git a/contracts/eosio.system/src/resource31.cpp b/contracts/eosio.system/src/resource31.cpp deleted file mode 100644 index fc0134a8..00000000 --- a/contracts/eosio.system/src/resource31.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include - -namespace eosiosystem { - -void system_contract::configcpu31(int64_t delta_weight, int64_t target_weight, - const time_point_sec& target_timestamp, - double exponent, uint32_t window, - const asset& peak_price, - const asset& min_purchase_price) { - // -} - -void system_contract::confignet31(int64_t delta_weight, int64_t target_weight, - const time_point_sec& target_timestamp, - double exponent, uint32_t window, - const asset& peak_price, - const asset& min_purchase_price) { - // -} - -void system_contract::buycpu31(const name& payer, const name& receiver, - int64_t amount, const asset& max_payment) { - // -} - -void system_contract::buynet31(const name& payer, const name& receiver, - int64_t amount, const asset& max_payment) { - // -} - -} // namespace eosiosystem diff --git a/tests/eosio.resource31_tests.cpp b/tests/eosio.buybandwidth_tests.cpp similarity index 90% rename from tests/eosio.resource31_tests.cpp rename to tests/eosio.buybandwidth_tests.cpp index b25261a7..41ecadcb 100644 --- a/tests/eosio.resource31_tests.cpp +++ b/tests/eosio.buybandwidth_tests.cpp @@ -14,10 +14,10 @@ using namespace eosio_system; -BOOST_AUTO_TEST_SUITE(eosio_system_resource31_tests) +BOOST_AUTO_TEST_SUITE(eosio_system_buybandwidth_tests) BOOST_FIXTURE_TEST_CASE(foo, eosio_system_tester) try { - // + // } FC_LOG_AND_RETHROW() From 334ab305ca97f7f19aec82954532c0ee42a52f11 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 27 Nov 2019 17:33:02 -0500 Subject: [PATCH 0957/1048] buybandwidth --- .../include/eosio.system/eosio.system.hpp | 35 ++++++++--------- contracts/eosio.system/src/buybandwidth.cpp | 38 ++++++++++++++++++- 2 files changed, 54 insertions(+), 19 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 44d03d90..539f5908 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -476,7 +476,7 @@ namespace eosiosystem { time_point_sec target_timestamp; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. // Ignored if current_weight == target_weight. double exponent; // Exponent of resource price curve. Must be >= 1. - uint32_t decay_days; // Number of days for adjusted resource utilization to decay to instantaneous utilization within exp(-1). + uint32_t decay_secs; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). asset total_price; // Total price needed to buy the entire resource market weight. asset min_purchase_price; // Minimum purchase. This needs to be large enough to cover RAM costs. }; @@ -488,24 +488,25 @@ namespace eosiosystem { }; struct buybw_state_resource { - uint8_t version = 0; - int64_t weight; // resource market weight - int64_t initial_weight; // Initial resource market weight used for linear growth - int64_t target_weight; // Linearly grow the resource market weight to this amount - time_point_sec initial_timestamp; // When resource market weight growth started - time_point_sec target_timestamp; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. - double exponent; // Exponent of resource price curve. - uint32_t decay_days; // Number of days for adjusted resource utilization to decay to instantaneous utilization within exp(-1). - asset total_price; // Total price needed to buy the entire resource market weight. - asset min_purchase_price; // Minimum purchase - int64_t utilization; // Instantaneous resource utilization. This is the current amount sold. - int64_t adjusted_utilization; // Adjusted resource utilization. This >= utilization. It grows instantly but decays exponentially. + uint8_t version = 0; + int64_t weight = 0; // resource market weight + int64_t initial_weight = 0; // Initial resource market weight used for linear growth + int64_t target_weight = 0; // Linearly grow the resource market weight to this amount + time_point_sec initial_timestamp = {}; // When resource market weight growth started + time_point_sec target_timestamp = {}; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. + double exponent = 0; // Exponent of resource price curve. + uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). + asset total_price = {}; // Total price needed to buy the entire resource market weight. + asset min_purchase_price = {}; // Minimum purchase + int64_t utilization = 0; // Instantaneous resource utilization. This is the current amount sold. + int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It grows instantly but decays exponentially. }; struct [[eosio::table("buybw.state"),eosio::contract("eosio.system")]] buybw_state { - uint8_t version = 0; - buybw_state_resource net; // NET market state - buybw_state_resource cpu; // CPU market state + uint8_t version = 0; + buybw_state_resource net = {}; // NET market state + buybw_state_resource cpu = {}; // CPU market state + uint32_t purchase_days = 0; // `buybandwidth` `days` argument must match this. uint64_t primary_key()const { return 0; } }; @@ -1186,7 +1187,7 @@ namespace eosiosystem { * action is invoked. */ [[eosio::action]] - void configbuybw(const buybw_config& args); + void configbuybw(buybw_config& args); /** * Buy NET and CPU diff --git a/contracts/eosio.system/src/buybandwidth.cpp b/contracts/eosio.system/src/buybandwidth.cpp index c25e5b7d..f994e482 100644 --- a/contracts/eosio.system/src/buybandwidth.cpp +++ b/contracts/eosio.system/src/buybandwidth.cpp @@ -2,8 +2,42 @@ namespace eosiosystem { -void system_contract::configbuybw(const buybw_config& args) { - // +void system_contract::configbuybw(buybw_config& args) { + time_point_sec now = eosio::current_time_point(); + auto core_symbol = get_core_symbol(); + buybw_state_singleton state_sing{ get_self(), 0 }; + auto state = state_sing.get_or_default(); + + auto update = [&](auto& state, auto& args) { + if (args.current_weight == args.target_weight) + args.target_timestamp = now; + else + eosio::check(args.target_timestamp > now, "target_timestamp must be in the future"); + eosio::check(args.target_weight >= args.current_weight, "weight can't shrink over time"); + eosio::check(args.current_weight >= state.utilization, "weight can't shrink below utilization"); + eosio::check(args.exponent >= 1, "exponent must be >= 1"); + eosio::check(args.decay_secs >= 1, "decay_secs must be >= 1"); + eosio::check(args.total_price.symbol == core_symbol, "total_price doesn't match core symbol"); + eosio::check(args.total_price.amount > 0, "total_price must be positive"); + eosio::check(args.min_purchase_price.symbol == core_symbol, "min_purchase_price doesn't match core symbol"); + + state.weight = args.current_weight; + state.initial_weight = args.current_weight; + state.target_weight = args.target_weight; + state.initial_timestamp = now; + state.target_timestamp = args.target_timestamp; + state.exponent = args.exponent; + state.decay_secs = args.decay_secs; + state.total_price = args.total_price; + state.min_purchase_price = args.min_purchase_price; + }; + + eosio::check(args.purchase_days > 0, "purchase_days must be > 0"); + update(state.net, args.net); + update(state.cpu, args.cpu); + state.purchase_days = args.purchase_days; + + state_sing.set(state, get_self()); } void system_contract::buybandwidth(const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, From 0a158b5ab85130df61d5fc9c581bc202a1c53faf Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 27 Nov 2019 18:03:34 -0500 Subject: [PATCH 0958/1048] buybandwidth --- .../include/eosio.system/eosio.system.hpp | 3 + contracts/eosio.system/src/buybandwidth.cpp | 63 ++++++++++++++++++- 2 files changed, 63 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 539f5908..cf7c2ac8 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1351,6 +1351,9 @@ namespace eosiosystem { }; registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; + + // defined in buybandwidth.cpp + void adjust_resources(name payer, name account, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); }; } diff --git a/contracts/eosio.system/src/buybandwidth.cpp b/contracts/eosio.system/src/buybandwidth.cpp index f994e482..3126b7d1 100644 --- a/contracts/eosio.system/src/buybandwidth.cpp +++ b/contracts/eosio.system/src/buybandwidth.cpp @@ -2,13 +2,64 @@ namespace eosiosystem { +void system_contract::adjust_resources(name payer, name account, int64_t net_delta, int64_t cpu_delta, + bool must_not_be_managed) { + if (!net_delta && !cpu_delta) + return; + + user_resources_table totals_tbl(get_self(), account.value); + auto tot_itr = totals_tbl.find(account.value); + if (tot_itr == totals_tbl.end()) { + tot_itr = totals_tbl.emplace(payer, [&](auto& tot) { + tot.owner = account; + tot.net_weight = net_delta; + tot.cpu_weight = cpu_delta; + }); + } else { + totals_tbl.modify(tot_itr, same_payer, [&](auto& tot) { + tot.net_weight += net_delta; + tot.cpu_weight += cpu_delta; + }); + } + check(0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth"); + check(0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth"); + + { + bool ram_managed = false; + bool net_managed = false; + bool cpu_managed = false; + + auto voter_itr = _voters.find(account.value); + if (voter_itr != _voters.end()) { + ram_managed = has_field(voter_itr->flags1, voter_info::flags1_fields::ram_managed); + net_managed = has_field(voter_itr->flags1, voter_info::flags1_fields::net_managed); + cpu_managed = has_field(voter_itr->flags1, voter_info::flags1_fields::cpu_managed); + } + + if (must_not_be_managed) + eosio::check(!net_managed && !cpu_managed, "something is managed which shouldn't be"); + + if (!(net_managed && cpu_managed)) { + int64_t ram_bytes, net, cpu; + get_resource_limits(account, ram_bytes, net, cpu); + set_resource_limits( + account, ram_managed ? ram_bytes : std::max(tot_itr->ram_bytes + ram_gift_bytes, ram_bytes), + net_managed ? net : tot_itr->net_weight.amount, cpu_managed ? cpu : tot_itr->cpu_weight.amount); + } + } + + if (tot_itr->is_empty()) { + totals_tbl.erase(tot_itr); + } +} // system_contract::adjust_resources + void system_contract::configbuybw(buybw_config& args) { time_point_sec now = eosio::current_time_point(); auto core_symbol = get_core_symbol(); buybw_state_singleton state_sing{ get_self(), 0 }; auto state = state_sing.get_or_default(); - auto update = [&](auto& state, auto& args) { + auto update = [&](auto& state, auto& args, auto& delta_weight) { if (args.current_weight == args.target_weight) args.target_timestamp = now; else @@ -21,6 +72,8 @@ void system_contract::configbuybw(buybw_config& args) { eosio::check(args.total_price.amount > 0, "total_price must be positive"); eosio::check(args.min_purchase_price.symbol == core_symbol, "min_purchase_price doesn't match core symbol"); + delta_weight = args.current_weight - state.weight; + state.weight = args.current_weight; state.initial_weight = args.current_weight; state.target_weight = args.target_weight; @@ -33,10 +86,14 @@ void system_contract::configbuybw(buybw_config& args) { }; eosio::check(args.purchase_days > 0, "purchase_days must be > 0"); - update(state.net, args.net); - update(state.cpu, args.cpu); state.purchase_days = args.purchase_days; + int64_t net_delta = 0; + int64_t cpu_delta = 0; + update(state.net, args.net, net_delta); + update(state.cpu, args.cpu, cpu_delta); + + adjust_resources(get_self(), reserv_account, net_delta, cpu_delta, true); state_sing.set(state, get_self()); } From cd035917b357d4209f2ef17b89d2c0ced1a36a9b Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 27 Nov 2019 18:56:26 -0500 Subject: [PATCH 0959/1048] buybandwidth --- .../include/eosio.system/eosio.system.hpp | 9 +++- contracts/eosio.system/src/buybandwidth.cpp | 51 +++++++++++++++---- 2 files changed, 49 insertions(+), 11 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index cf7c2ac8..d497311d 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -523,10 +523,13 @@ namespace eosiosystem { uint64_t primary_key()const { return id; } uint64_t by_owner()const { return owner.value; } + uint64_t by_expires()const { return expires.utc_seconds; } }; typedef eosio::multi_index< "buybw.order"_n, buybw_order, - indexed_by<"byowner"_n, const_mem_fun>> buybw_order_table; + indexed_by<"byowner"_n, const_mem_fun>, + indexed_by<"byexpires"_n, const_mem_fun> + > buybw_order_table; /** * The EOSIO system contract. The EOSIO system contract governs ram market, voters, producers, global state. @@ -1353,7 +1356,9 @@ namespace eosiosystem { registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; // defined in buybandwidth.cpp - void adjust_resources(name payer, name account, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); + void adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); + void process_buybw_queue(symbol core_symbol, buybw_state& state, buybw_order_table& orders, uint32_t max_items); + void update_buybw_state(buybw_state& state); }; } diff --git a/contracts/eosio.system/src/buybandwidth.cpp b/contracts/eosio.system/src/buybandwidth.cpp index 3126b7d1..2f4d1a43 100644 --- a/contracts/eosio.system/src/buybandwidth.cpp +++ b/contracts/eosio.system/src/buybandwidth.cpp @@ -2,8 +2,8 @@ namespace eosiosystem { -void system_contract::adjust_resources(name payer, name account, int64_t net_delta, int64_t cpu_delta, - bool must_not_be_managed) { +void system_contract::adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, + int64_t cpu_delta, bool must_not_be_managed) { if (!net_delta && !cpu_delta) return; @@ -12,13 +12,13 @@ void system_contract::adjust_resources(name payer, name account, int64_t net_del if (tot_itr == totals_tbl.end()) { tot_itr = totals_tbl.emplace(payer, [&](auto& tot) { tot.owner = account; - tot.net_weight = net_delta; - tot.cpu_weight = cpu_delta; + tot.net_weight = asset{ net_delta, core_symbol }; + tot.cpu_weight = asset{ cpu_delta, core_symbol }; }); } else { totals_tbl.modify(tot_itr, same_payer, [&](auto& tot) { - tot.net_weight += net_delta; - tot.cpu_weight += cpu_delta; + tot.net_weight.amount += net_delta; + tot.cpu_weight.amount += cpu_delta; }); } check(0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth"); @@ -53,7 +53,32 @@ void system_contract::adjust_resources(name payer, name account, int64_t net_del } } // system_contract::adjust_resources +void system_contract::process_buybw_queue(symbol core_symbol, buybw_state& state, buybw_order_table& orders, + uint32_t max_items) { + time_point_sec now = eosio::current_time_point(); + auto idx = orders.get_index<"byexpires"_n>(); + int64_t total_net = 0; + int64_t total_cpu = 0; + while (max_items--) { + auto it = idx.begin(); + if (it == idx.end() || it->expires > now) + break; + total_net = it->net_weight; + total_cpu = it->cpu_weight; + adjust_resources(get_self(), it->owner, core_symbol, -it->net_weight, -it->cpu_weight); + idx.erase(it); + } + state.net.utilization -= total_net; + state.cpu.utilization -= total_cpu; + adjust_resources(get_self(), reserv_account, core_symbol, total_net, total_cpu, true); +} + +void system_contract::update_buybw_state(buybw_state& state) { + // +} + void system_contract::configbuybw(buybw_config& args) { + require_auth(get_self()); time_point_sec now = eosio::current_time_point(); auto core_symbol = get_core_symbol(); buybw_state_singleton state_sing{ get_self(), 0 }; @@ -93,13 +118,21 @@ void system_contract::configbuybw(buybw_config& args) { update(state.net, args.net, net_delta); update(state.cpu, args.cpu, cpu_delta); - adjust_resources(get_self(), reserv_account, net_delta, cpu_delta, true); + adjust_resources(get_self(), reserv_account, core_symbol, net_delta, cpu_delta, true); state_sing.set(state, get_self()); -} +} // system_contract::configbuybw void system_contract::buybandwidth(const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, const asset& max_payment) { - // + require_auth(payer); + buybw_state_singleton state_sing{ get_self(), 0 }; + buybw_order_table orders{ get_self(), 0 }; + eosio::check(state_sing.exists(), "buybandwidth hasn't been initialized"); + auto state = state_sing.get(); + auto core_symbol = get_core_symbol(); + process_buybw_queue(core_symbol, state, orders, 2); + update_buybw_state(state); + state_sing.set(state, get_self()); } } // namespace eosiosystem From 7721480e845ac116026fd8dfdd51b49dc179a63c Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 2 Dec 2019 11:14:40 -0500 Subject: [PATCH 0960/1048] buybandwidth --- .../include/eosio.system/eosio.system.hpp | 33 ++++++++++--------- contracts/eosio.system/src/buybandwidth.cpp | 28 +++++++++++++++- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index d497311d..696267ee 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -488,25 +488,26 @@ namespace eosiosystem { }; struct buybw_state_resource { - uint8_t version = 0; - int64_t weight = 0; // resource market weight - int64_t initial_weight = 0; // Initial resource market weight used for linear growth - int64_t target_weight = 0; // Linearly grow the resource market weight to this amount - time_point_sec initial_timestamp = {}; // When resource market weight growth started - time_point_sec target_timestamp = {}; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. - double exponent = 0; // Exponent of resource price curve. - uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). - asset total_price = {}; // Total price needed to buy the entire resource market weight. - asset min_purchase_price = {}; // Minimum purchase - int64_t utilization = 0; // Instantaneous resource utilization. This is the current amount sold. - int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It grows instantly but decays exponentially. + uint8_t version = 0; + int64_t weight = 0; // resource market weight + int64_t initial_weight = 0; // Initial resource market weight used for linear growth + int64_t target_weight = 0; // Linearly grow the resource market weight to this amount + time_point_sec initial_timestamp = {}; // When resource market weight growth started + time_point_sec target_timestamp = {}; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. + double exponent = 0; // Exponent of resource price curve. + uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). + asset total_price = {}; // Total price needed to buy the entire resource market weight. + asset min_purchase_price = {}; // Minimum purchase + int64_t utilization = 0; // Instantaneous resource utilization. This is the current amount sold. + int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It grows instantly but decays exponentially. + time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated }; struct [[eosio::table("buybw.state"),eosio::contract("eosio.system")]] buybw_state { - uint8_t version = 0; - buybw_state_resource net = {}; // NET market state - buybw_state_resource cpu = {}; // CPU market state - uint32_t purchase_days = 0; // `buybandwidth` `days` argument must match this. + uint8_t version = 0; + buybw_state_resource net = {}; // NET market state + buybw_state_resource cpu = {}; // CPU market state + uint32_t purchase_days = 0; // `buybandwidth` `days` argument must match this. uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/buybandwidth.cpp b/contracts/eosio.system/src/buybandwidth.cpp index 2f4d1a43..eae4abb7 100644 --- a/contracts/eosio.system/src/buybandwidth.cpp +++ b/contracts/eosio.system/src/buybandwidth.cpp @@ -1,4 +1,5 @@ #include +#include namespace eosiosystem { @@ -73,8 +74,33 @@ void system_contract::process_buybw_queue(symbol core_symbol, buybw_state& state adjust_resources(get_self(), reserv_account, core_symbol, total_net, total_cpu, true); } +void update_weight(time_point_sec now, buybw_state_resource& res) { + if (now >= res.target_timestamp) + res.weight = res.target_weight; + else + res.weight = res.initial_weight + // + int128_t(res.target_weight - res.initial_weight) * + (now.utc_seconds - res.initial_timestamp.utc_seconds) / + (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); +} + +void update_utilization(time_point_sec now, buybw_state_resource& res) { + if (res.utilization >= res.adjusted_utilization) + res.adjusted_utilization = res.utilization; + else + res.adjusted_utilization = // + res.utilization + + (res.adjusted_utilization - res.utilization) * + exp((now.utc_seconds - res.utilization_timestamp.utc_seconds) / double(-res.decay_secs)); + res.utilization_timestamp = now; +} + void system_contract::update_buybw_state(buybw_state& state) { - // + time_point_sec now = eosio::current_time_point(); + update_weight(now, state.net); + update_weight(now, state.cpu); + update_utilization(now, state.net); + update_utilization(now, state.cpu); } void system_contract::configbuybw(buybw_config& args) { From 7244d2041810883ed72e395fb699949e9cd5b2df Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 2 Dec 2019 11:54:25 -0500 Subject: [PATCH 0961/1048] rentbw --- contracts/eosio.system/CMakeLists.txt | 2 +- .../include/eosio.system/eosio.system.hpp | 58 +++++++++--------- .../src/{buybandwidth.cpp => rentbw.cpp} | 60 +++++++++---------- ...width_tests.cpp => eosio.rentbw_tests.cpp} | 2 +- 4 files changed, 61 insertions(+), 61 deletions(-) rename contracts/eosio.system/src/{buybandwidth.cpp => rentbw.cpp} (73%) rename tests/{eosio.buybandwidth_tests.cpp => eosio.rentbw_tests.cpp} (90%) diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index 825a02d7..33f7d486 100644 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -1,10 +1,10 @@ add_contract(eosio.system eosio.system - ${CMAKE_CURRENT_SOURCE_DIR}/src/buybandwidth.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/delegate_bandwidth.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/exchange_state.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/rentbw.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/voting.cpp ) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 696267ee..f3b708e5 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -87,7 +87,7 @@ namespace eosiosystem { * - Users can bid on premium names. * - A resource exchange system (REX) allows token holders to lend their tokens, * and users to rent CPU and Network resources in return for a market-determined fee. - * - A resource market separate from REX: `buybandwidth` + * - A resource market separate from REX: `rentbw` */ // A name bid, which consists of: @@ -470,7 +470,7 @@ namespace eosiosystem { asset stake_change; }; - struct buybw_config_resource { + struct rentbw_config_resource { int64_t current_weight; // Immediately set the resource market weight to this amount. 1 represents the same amount of resources as 1 satoshi of SYS staked. int64_t target_weight; // Linearly grow the resource market weight to this amount. 1 represents the same amount of resources as 1 satoshi of SYS staked. time_point_sec target_timestamp; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. @@ -478,16 +478,16 @@ namespace eosiosystem { double exponent; // Exponent of resource price curve. Must be >= 1. uint32_t decay_secs; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). asset total_price; // Total price needed to buy the entire resource market weight. - asset min_purchase_price; // Minimum purchase. This needs to be large enough to cover RAM costs. + asset min_rent_price; // Rents below this amount are rejected. This needs to be large enough to cover RAM costs. }; - struct buybw_config { - buybw_config_resource net; // NET market configuration - buybw_config_resource cpu; // CPU market configuration - uint32_t purchase_days; // `buybandwidth` `days` argument must match this. + struct rentbw_config { + rentbw_config_resource net; // NET market configuration + rentbw_config_resource cpu; // CPU market configuration + uint32_t rent_days; // `rentbw` `days` argument must match this. }; - struct buybw_state_resource { + struct rentbw_state_resource { uint8_t version = 0; int64_t weight = 0; // resource market weight int64_t initial_weight = 0; // Initial resource market weight used for linear growth @@ -497,24 +497,24 @@ namespace eosiosystem { double exponent = 0; // Exponent of resource price curve. uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). asset total_price = {}; // Total price needed to buy the entire resource market weight. - asset min_purchase_price = {}; // Minimum purchase + asset min_rent_price = {}; // Rents below this amount are rejected int64_t utilization = 0; // Instantaneous resource utilization. This is the current amount sold. int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It grows instantly but decays exponentially. time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated }; - struct [[eosio::table("buybw.state"),eosio::contract("eosio.system")]] buybw_state { - uint8_t version = 0; - buybw_state_resource net = {}; // NET market state - buybw_state_resource cpu = {}; // CPU market state - uint32_t purchase_days = 0; // `buybandwidth` `days` argument must match this. + struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { + uint8_t version = 0; + rentbw_state_resource net = {}; // NET market state + rentbw_state_resource cpu = {}; // CPU market state + uint32_t rent_days = 0; // `rentbw` `days` argument must match this. uint64_t primary_key()const { return 0; } }; - typedef eosio::singleton<"buybw.state"_n, buybw_state> buybw_state_singleton; + typedef eosio::singleton<"rent.state"_n, rentbw_state> rentbw_state_singleton; - struct [[eosio::table("buybw.order"),eosio::contract("eosio.system")]] buybw_order { + struct [[eosio::table("rentbw.order"),eosio::contract("eosio.system")]] rentbw_order { uint8_t version = 0; uint64_t id; name owner; @@ -527,10 +527,10 @@ namespace eosiosystem { uint64_t by_expires()const { return expires.utc_seconds; } }; - typedef eosio::multi_index< "buybw.order"_n, buybw_order, - indexed_by<"byowner"_n, const_mem_fun>, - indexed_by<"byexpires"_n, const_mem_fun> - > buybw_order_table; + typedef eosio::multi_index< "rentbw.order"_n, rentbw_order, + indexed_by<"byowner"_n, const_mem_fun>, + indexed_by<"byexpires"_n, const_mem_fun> + > rentbw_order_table; /** * The EOSIO system contract. The EOSIO system contract governs ram market, voters, producers, global state. @@ -1187,14 +1187,14 @@ namespace eosiosystem { void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); /** - * Configure the `buybandwidth` market. The market becomes available the first time this + * Configure the `rentbw` market. The market becomes available the first time this * action is invoked. */ [[eosio::action]] - void configbuybw(buybw_config& args); + void configrentbw(rentbw_config& args); /** - * Buy NET and CPU + * Rent NET and CPU * * @param payer - the resource buyer * @param receiver - the resource receiver @@ -1205,7 +1205,7 @@ namespace eosiosystem { * `payer`'s token balance. */ [[eosio::action]] - void buybandwidth( const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, const asset& max_payment ); + void rentbw( const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, const asset& max_payment ); using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; @@ -1253,8 +1253,8 @@ namespace eosiosystem { using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; - using configcpu_action = eosio::action_wrapper<"configbuybw"_n, &system_contract::configbuybw>; - using buybandwidth_action = eosio::action_wrapper<"buybandwidth"_n, &system_contract::buybandwidth>; + using configcpu_action = eosio::action_wrapper<"configrentbw"_n, &system_contract::configrentbw>; + using rentbw_action = eosio::action_wrapper<"rentbw"_n, &system_contract::rentbw>; private: // Implementation details: @@ -1356,10 +1356,10 @@ namespace eosiosystem { registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; - // defined in buybandwidth.cpp + // defined in rentbw.cpp void adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); - void process_buybw_queue(symbol core_symbol, buybw_state& state, buybw_order_table& orders, uint32_t max_items); - void update_buybw_state(buybw_state& state); + void process_rentbw_queue(symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, uint32_t max_items); + void update_rentbw_state(rentbw_state& state); }; } diff --git a/contracts/eosio.system/src/buybandwidth.cpp b/contracts/eosio.system/src/rentbw.cpp similarity index 73% rename from contracts/eosio.system/src/buybandwidth.cpp rename to contracts/eosio.system/src/rentbw.cpp index eae4abb7..3817131b 100644 --- a/contracts/eosio.system/src/buybandwidth.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -54,8 +54,8 @@ void system_contract::adjust_resources(name payer, name account, symbol core_sym } } // system_contract::adjust_resources -void system_contract::process_buybw_queue(symbol core_symbol, buybw_state& state, buybw_order_table& orders, - uint32_t max_items) { +void system_contract::process_rentbw_queue(symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, + uint32_t max_items) { time_point_sec now = eosio::current_time_point(); auto idx = orders.get_index<"byexpires"_n>(); int64_t total_net = 0; @@ -74,7 +74,7 @@ void system_contract::process_buybw_queue(symbol core_symbol, buybw_state& state adjust_resources(get_self(), reserv_account, core_symbol, total_net, total_cpu, true); } -void update_weight(time_point_sec now, buybw_state_resource& res) { +void update_weight(time_point_sec now, rentbw_state_resource& res) { if (now >= res.target_timestamp) res.weight = res.target_weight; else @@ -84,7 +84,7 @@ void update_weight(time_point_sec now, buybw_state_resource& res) { (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); } -void update_utilization(time_point_sec now, buybw_state_resource& res) { +void update_utilization(time_point_sec now, rentbw_state_resource& res) { if (res.utilization >= res.adjusted_utilization) res.adjusted_utilization = res.utilization; else @@ -95,7 +95,7 @@ void update_utilization(time_point_sec now, buybw_state_resource& res) { res.utilization_timestamp = now; } -void system_contract::update_buybw_state(buybw_state& state) { +void system_contract::update_rentbw_state(rentbw_state& state) { time_point_sec now = eosio::current_time_point(); update_weight(now, state.net); update_weight(now, state.cpu); @@ -103,12 +103,12 @@ void system_contract::update_buybw_state(buybw_state& state) { update_utilization(now, state.cpu); } -void system_contract::configbuybw(buybw_config& args) { +void system_contract::configrentbw(rentbw_config& args) { require_auth(get_self()); - time_point_sec now = eosio::current_time_point(); - auto core_symbol = get_core_symbol(); - buybw_state_singleton state_sing{ get_self(), 0 }; - auto state = state_sing.get_or_default(); + time_point_sec now = eosio::current_time_point(); + auto core_symbol = get_core_symbol(); + rentbw_state_singleton state_sing{ get_self(), 0 }; + auto state = state_sing.get_or_default(); auto update = [&](auto& state, auto& args, auto& delta_weight) { if (args.current_weight == args.target_weight) @@ -121,23 +121,23 @@ void system_contract::configbuybw(buybw_config& args) { eosio::check(args.decay_secs >= 1, "decay_secs must be >= 1"); eosio::check(args.total_price.symbol == core_symbol, "total_price doesn't match core symbol"); eosio::check(args.total_price.amount > 0, "total_price must be positive"); - eosio::check(args.min_purchase_price.symbol == core_symbol, "min_purchase_price doesn't match core symbol"); + eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); delta_weight = args.current_weight - state.weight; - state.weight = args.current_weight; - state.initial_weight = args.current_weight; - state.target_weight = args.target_weight; - state.initial_timestamp = now; - state.target_timestamp = args.target_timestamp; - state.exponent = args.exponent; - state.decay_secs = args.decay_secs; - state.total_price = args.total_price; - state.min_purchase_price = args.min_purchase_price; + state.weight = args.current_weight; + state.initial_weight = args.current_weight; + state.target_weight = args.target_weight; + state.initial_timestamp = now; + state.target_timestamp = args.target_timestamp; + state.exponent = args.exponent; + state.decay_secs = args.decay_secs; + state.total_price = args.total_price; + state.min_rent_price = args.min_rent_price; }; - eosio::check(args.purchase_days > 0, "purchase_days must be > 0"); - state.purchase_days = args.purchase_days; + eosio::check(args.rent_days > 0, "rent_days must be > 0"); + state.rent_days = args.rent_days; int64_t net_delta = 0; int64_t cpu_delta = 0; @@ -146,18 +146,18 @@ void system_contract::configbuybw(buybw_config& args) { adjust_resources(get_self(), reserv_account, core_symbol, net_delta, cpu_delta, true); state_sing.set(state, get_self()); -} // system_contract::configbuybw +} // system_contract::configrentbw -void system_contract::buybandwidth(const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, - const asset& max_payment) { +void system_contract::rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, + const asset& max_payment) { require_auth(payer); - buybw_state_singleton state_sing{ get_self(), 0 }; - buybw_order_table orders{ get_self(), 0 }; - eosio::check(state_sing.exists(), "buybandwidth hasn't been initialized"); + rentbw_state_singleton state_sing{ get_self(), 0 }; + rentbw_order_table orders{ get_self(), 0 }; + eosio::check(state_sing.exists(), "rentbw hasn't been initialized"); auto state = state_sing.get(); auto core_symbol = get_core_symbol(); - process_buybw_queue(core_symbol, state, orders, 2); - update_buybw_state(state); + process_rentbw_queue(core_symbol, state, orders, 2); + update_rentbw_state(state); state_sing.set(state, get_self()); } diff --git a/tests/eosio.buybandwidth_tests.cpp b/tests/eosio.rentbw_tests.cpp similarity index 90% rename from tests/eosio.buybandwidth_tests.cpp rename to tests/eosio.rentbw_tests.cpp index 41ecadcb..d71cdb8c 100644 --- a/tests/eosio.buybandwidth_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -14,7 +14,7 @@ using namespace eosio_system; -BOOST_AUTO_TEST_SUITE(eosio_system_buybandwidth_tests) +BOOST_AUTO_TEST_SUITE(eosio_system_rentbw_tests) BOOST_FIXTURE_TEST_CASE(foo, eosio_system_tester) try { // From db44b3547c96bc1d157f87cc5bcb65f586684948 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 2 Dec 2019 18:45:20 -0500 Subject: [PATCH 0962/1048] rentbw --- .../include/eosio.system/eosio.system.hpp | 65 +++++++--- contracts/eosio.system/src/rentbw.cpp | 122 +++++++++++------- 2 files changed, 119 insertions(+), 68 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index f3b708e5..15c20fa4 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -40,6 +40,8 @@ namespace eosiosystem { using eosio::time_point_sec; using eosio::unsigned_int; + inline constexpr int64_t rentbw_ratio_frac = 1000000000000000ll; // 1.0 = 10^15 + template static inline auto has_field( F flags, E field ) -> std::enable_if_t< std::is_integral_v && std::is_unsigned_v && @@ -471,14 +473,28 @@ namespace eosiosystem { }; struct rentbw_config_resource { - int64_t current_weight; // Immediately set the resource market weight to this amount. 1 represents the same amount of resources as 1 satoshi of SYS staked. - int64_t target_weight; // Linearly grow the resource market weight to this amount. 1 represents the same amount of resources as 1 satoshi of SYS staked. - time_point_sec target_timestamp; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. - // Ignored if current_weight == target_weight. + int64_t current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. Set this + // to 0 to preserve the existing setting or use the default; this avoids sudden + // price jumps. For new chains which don't need to gradually phase out staking + // and REX, 0.01x (10^13) is a good value for both current_weight_ratio and + // target_weight_ratio. + int64_t target_weight_ratio; // Linearly shrink weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. Set this + // to 0 to preserve the existing setting or use the default. + int64_t assumed_stake_weight; // Assumed stake weight for ratio calculations. Use the sum of total staked and + // total rented by REX at the time the rentbw market is first activated. Set + // this to 0 to preserve the existing setting; this avoids sudden price jumps. + // For new chains which don't need to phase out staking and REX, 10^12 is + // probably a good value. + time_point_sec target_timestamp; // Stop automatic weight_ratio shrinkage at this time. Once this + // time hits, weight_ratio will be target_weight_ratio. Ignored if + // current_weight_ratio == target_weight_ratio. Set this to 0 to preserve the + // existing setting. double exponent; // Exponent of resource price curve. Must be >= 1. - uint32_t decay_secs; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). + uint32_t decay_secs; // Number of seconds for adjusted resource utilization to decay to instantaneous + // utilization within exp(-1). asset total_price; // Total price needed to buy the entire resource market weight. - asset min_rent_price; // Rents below this amount are rejected. This needs to be large enough to cover RAM costs. + asset min_rent_price; // Rents below this amount are rejected. This needs to be large enough to cover + // RAM costs. }; struct rentbw_config { @@ -489,18 +505,28 @@ namespace eosiosystem { struct rentbw_state_resource { uint8_t version = 0; - int64_t weight = 0; // resource market weight - int64_t initial_weight = 0; // Initial resource market weight used for linear growth - int64_t target_weight = 0; // Linearly grow the resource market weight to this amount - time_point_sec initial_timestamp = {}; // When resource market weight growth started - time_point_sec target_timestamp = {}; // Stop automatic resource market weight growth at this time. Once this time hits, the market weight will be target_weight. - double exponent = 0; // Exponent of resource price curve. - uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to decay to instantaneous utilization within exp(-1). - asset total_price = {}; // Total price needed to buy the entire resource market weight. - asset min_rent_price = {}; // Rents below this amount are rejected - int64_t utilization = 0; // Instantaneous resource utilization. This is the current amount sold. - int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It grows instantly but decays exponentially. - time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated + int64_t weight = 0; // resource market weight. calculated; varies over time. + // 1 represents the same amount of resources as 1 + // satoshi of SYS staked. + int64_t weight_ratio = 0; // resource market weight ratio: + // assumed_stake_weight / (assumed_stake_weight + weight). + // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. + int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. + int64_t initial_weight_ratio = rentbw_ratio_frac; // Initial weight_ratio used for linear shrinkage. + int64_t target_weight_ratio = rentbw_ratio_frac / 100; // Linearly shrink the weight_ratio to this amount. + time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started + time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this + // time hits, weight_ratio will be target_weight_ratio. + double exponent = 0; // Exponent of resource price curve. + uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to + // decay to instantaneous utilization within exp(-1). + asset total_price = {}; // Total price needed to buy the entire resource market weight. + asset min_rent_price = {}; // Rents below this amount are rejected + int64_t utilization = 0; // Instantaneous resource utilization. This is the current + // amount sold. + int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It + // grows instantly but decays exponentially. + time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated }; struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { @@ -1358,8 +1384,7 @@ namespace eosiosystem { // defined in rentbw.cpp void adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); - void process_rentbw_queue(symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, uint32_t max_items); - void update_rentbw_state(rentbw_state& state); + void process_rentbw_queue(symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available); }; } diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 3817131b..5fc0f18d 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -55,33 +55,36 @@ void system_contract::adjust_resources(name payer, name account, symbol core_sym } // system_contract::adjust_resources void system_contract::process_rentbw_queue(symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, - uint32_t max_items) { - time_point_sec now = eosio::current_time_point(); - auto idx = orders.get_index<"byexpires"_n>(); - int64_t total_net = 0; - int64_t total_cpu = 0; + uint32_t max_items, int64_t& net_delta_available, + int64_t& cpu_delta_available) { + time_point_sec now = eosio::current_time_point(); + auto idx = orders.get_index<"byexpires"_n>(); while (max_items--) { auto it = idx.begin(); if (it == idx.end() || it->expires > now) break; - total_net = it->net_weight; - total_cpu = it->cpu_weight; + net_delta_available += it->net_weight; + cpu_delta_available += it->cpu_weight; adjust_resources(get_self(), it->owner, core_symbol, -it->net_weight, -it->cpu_weight); idx.erase(it); } - state.net.utilization -= total_net; - state.cpu.utilization -= total_cpu; - adjust_resources(get_self(), reserv_account, core_symbol, total_net, total_cpu, true); + state.net.utilization -= net_delta_available; + state.cpu.utilization -= cpu_delta_available; } -void update_weight(time_point_sec now, rentbw_state_resource& res) { +void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delta_available) { if (now >= res.target_timestamp) - res.weight = res.target_weight; + res.weight_ratio = res.target_weight_ratio; else - res.weight = res.initial_weight + // - int128_t(res.target_weight - res.initial_weight) * - (now.utc_seconds - res.initial_timestamp.utc_seconds) / - (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); + res.weight_ratio = res.initial_weight_ratio + // + int128_t(res.target_weight_ratio - res.initial_weight_ratio) * + (now.utc_seconds - res.initial_timestamp.utc_seconds) / + (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); + + int64_t new_weight = + res.assumed_stake_weight * int128_t(rentbw_ratio_frac) / res.weight_ratio - res.assumed_stake_weight; + delta_available += new_weight - res.weight; + res.weight = new_weight; } void update_utilization(time_point_sec now, rentbw_state_resource& res) { @@ -95,14 +98,6 @@ void update_utilization(time_point_sec now, rentbw_state_resource& res) { res.utilization_timestamp = now; } -void system_contract::update_rentbw_state(rentbw_state& state) { - time_point_sec now = eosio::current_time_point(); - update_weight(now, state.net); - update_weight(now, state.cpu); - update_utilization(now, state.net); - update_utilization(now, state.cpu); -} - void system_contract::configrentbw(rentbw_config& args) { require_auth(get_self()); time_point_sec now = eosio::current_time_point(); @@ -110,41 +105,59 @@ void system_contract::configrentbw(rentbw_config& args) { rentbw_state_singleton state_sing{ get_self(), 0 }; auto state = state_sing.get_or_default(); - auto update = [&](auto& state, auto& args, auto& delta_weight) { - if (args.current_weight == args.target_weight) + int64_t net_delta_available = 0; + int64_t cpu_delta_available = 0; + update_weight(now, state.net, net_delta_available); + update_weight(now, state.cpu, cpu_delta_available); + + auto update = [&](auto& state, auto& args) { + if (!args.current_weight_ratio) + args.current_weight_ratio = state.weight_ratio; + if (!args.target_weight_ratio) + args.target_weight_ratio = state.target_weight_ratio; + if (!args.assumed_stake_weight) + args.assumed_stake_weight = state.assumed_stake_weight; + if (!args.target_timestamp.utc_seconds) + args.target_timestamp = state.target_timestamp; + + if (args.current_weight_ratio == args.target_weight_ratio) args.target_timestamp = now; else eosio::check(args.target_timestamp > now, "target_timestamp must be in the future"); - eosio::check(args.target_weight >= args.current_weight, "weight can't shrink over time"); - eosio::check(args.current_weight >= state.utilization, "weight can't shrink below utilization"); + eosio::check(args.current_weight_ratio > 0, "current_weight_ratio is too small"); + eosio::check(args.current_weight_ratio <= rentbw_ratio_frac, "current_weight_ratio is too large"); + eosio::check(args.target_weight_ratio <= args.current_weight_ratio, "weight can't grow over time"); + eosio::check(args.assumed_stake_weight >= 1, + "assumed_stake_weight must be at least 1; a much larger value is recommended"); eosio::check(args.exponent >= 1, "exponent must be >= 1"); eosio::check(args.decay_secs >= 1, "decay_secs must be >= 1"); eosio::check(args.total_price.symbol == core_symbol, "total_price doesn't match core symbol"); eosio::check(args.total_price.amount > 0, "total_price must be positive"); eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); - delta_weight = args.current_weight - state.weight; - - state.weight = args.current_weight; - state.initial_weight = args.current_weight; - state.target_weight = args.target_weight; - state.initial_timestamp = now; - state.target_timestamp = args.target_timestamp; - state.exponent = args.exponent; - state.decay_secs = args.decay_secs; - state.total_price = args.total_price; - state.min_rent_price = args.min_rent_price; + state.assumed_stake_weight = args.assumed_stake_weight; + state.initial_weight_ratio = args.current_weight_ratio; + state.target_weight_ratio = args.target_weight_ratio; + state.initial_timestamp = now; + state.target_timestamp = args.target_timestamp; + state.exponent = args.exponent; + state.decay_secs = args.decay_secs; + state.total_price = args.total_price; + state.min_rent_price = args.min_rent_price; }; eosio::check(args.rent_days > 0, "rent_days must be > 0"); state.rent_days = args.rent_days; - int64_t net_delta = 0; - int64_t cpu_delta = 0; - update(state.net, args.net, net_delta); - update(state.cpu, args.cpu, cpu_delta); + update(state.net, args.net); + update(state.cpu, args.cpu); - adjust_resources(get_self(), reserv_account, core_symbol, net_delta, cpu_delta, true); + update_weight(now, state.net, net_delta_available); + update_weight(now, state.cpu, cpu_delta_available); + eosio::check(state.net.weight >= state.net.utilization, "weight can't shrink below utilization"); + eosio::check(state.cpu.weight >= state.cpu.utilization, "weight can't shrink below utilization"); + + adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); state_sing.set(state, get_self()); } // system_contract::configrentbw @@ -154,10 +167,23 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d rentbw_state_singleton state_sing{ get_self(), 0 }; rentbw_order_table orders{ get_self(), 0 }; eosio::check(state_sing.exists(), "rentbw hasn't been initialized"); - auto state = state_sing.get(); - auto core_symbol = get_core_symbol(); - process_rentbw_queue(core_symbol, state, orders, 2); - update_rentbw_state(state); + auto state = state_sing.get(); + time_point_sec now = eosio::current_time_point(); + auto core_symbol = get_core_symbol(); + eosio::check(max_payment.symbol == core_symbol, "max_payment doesn't match core symbol"); + + int64_t net_delta_available = 0; + int64_t cpu_delta_available = 0; + process_rentbw_queue(core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); + update_weight(now, state.net, net_delta_available); + update_weight(now, state.cpu, cpu_delta_available); + update_utilization(now, state.net); + update_utilization(now, state.cpu); + + // todo: rent + // todo: check against min_rent_price + + adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); state_sing.set(state, get_self()); } From 04a98eb5c15f79df6e2c2086bd4ad55a9f20363e Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Tue, 3 Dec 2019 13:56:38 -0500 Subject: [PATCH 0963/1048] rentbw --- .../include/eosio.system/eosio.system.hpp | 18 ++++++--- contracts/eosio.system/src/rentbw.cpp | 40 ++++++++++++++----- 2 files changed, 41 insertions(+), 17 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 15c20fa4..6b7d4191 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -489,18 +489,21 @@ namespace eosiosystem { // time hits, weight_ratio will be target_weight_ratio. Ignored if // current_weight_ratio == target_weight_ratio. Set this to 0 to preserve the // existing setting. - double exponent; // Exponent of resource price curve. Must be >= 1. + double exponent; // Exponent of resource price curve. Must be >= 1. Set this to 0 to preserve the + // existing setting. uint32_t decay_secs; // Number of seconds for adjusted resource utilization to decay to instantaneous - // utilization within exp(-1). - asset total_price; // Total price needed to buy the entire resource market weight. + // utilization within exp(-1). Set this to 0 to preserve the existing setting. + asset total_price; // Total price needed to buy the entire resource market weight. Set this to 0 to + // preserve the existing setting. asset min_rent_price; // Rents below this amount are rejected. This needs to be large enough to cover - // RAM costs. + // RAM costs. Set this to 0 to preserve the existing setting. }; struct rentbw_config { rentbw_config_resource net; // NET market configuration rentbw_config_resource cpu; // CPU market configuration - uint32_t rent_days; // `rentbw` `days` argument must match this. + uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the + // existing setting. }; struct rentbw_state_resource { @@ -1384,7 +1387,10 @@ namespace eosiosystem { // defined in rentbw.cpp void adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); - void process_rentbw_queue(symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available); + void process_rentbw_queue( + time_point_sec now, symbol core_symbol, rentbw_state& state, + rentbw_order_table& orders, uint32_t max_items, int64_t& net_delta_available, + int64_t& cpu_delta_available); }; } diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 5fc0f18d..593c831d 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -54,11 +54,10 @@ void system_contract::adjust_resources(name payer, name account, symbol core_sym } } // system_contract::adjust_resources -void system_contract::process_rentbw_queue(symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, - uint32_t max_items, int64_t& net_delta_available, +void system_contract::process_rentbw_queue(time_point_sec now, symbol core_symbol, rentbw_state& state, + rentbw_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available) { - time_point_sec now = eosio::current_time_point(); - auto idx = orders.get_index<"byexpires"_n>(); + auto idx = orders.get_index<"byexpires"_n>(); while (max_items--) { auto it = idx.begin(); if (it == idx.end() || it->expires > now) @@ -80,7 +79,7 @@ void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delt int128_t(res.target_weight_ratio - res.initial_weight_ratio) * (now.utc_seconds - res.initial_timestamp.utc_seconds) / (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); - + // !!! check bounds of weight_ratio int64_t new_weight = res.assumed_stake_weight * int128_t(rentbw_ratio_frac) / res.weight_ratio - res.assumed_stake_weight; delta_available += new_weight - res.weight; @@ -107,25 +106,41 @@ void system_contract::configrentbw(rentbw_config& args) { int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; - update_weight(now, state.net, net_delta_available); - update_weight(now, state.cpu, cpu_delta_available); + if (state_sing.exists()) { + update_weight(now, state.net, net_delta_available); + update_weight(now, state.cpu, cpu_delta_available); + } auto update = [&](auto& state, auto& args) { - if (!args.current_weight_ratio) - args.current_weight_ratio = state.weight_ratio; + if (!args.current_weight_ratio) { + if (state.weight_ratio) + args.current_weight_ratio = state.weight_ratio; + else + args.current_weight_ratio = state.initial_weight_ratio; + } if (!args.target_weight_ratio) args.target_weight_ratio = state.target_weight_ratio; if (!args.assumed_stake_weight) args.assumed_stake_weight = state.assumed_stake_weight; if (!args.target_timestamp.utc_seconds) args.target_timestamp = state.target_timestamp; - + if (!args.exponent) + args.exponent = state.exponent; + if (!args.decay_secs) + args.decay_secs = state.decay_secs; + if (!args.total_price.amount) + args.total_price = state.total_price; + if (!args.min_rent_price.amount) + args.min_rent_price = state.min_rent_price; + + // !!! examine checks if (args.current_weight_ratio == args.target_weight_ratio) args.target_timestamp = now; else eosio::check(args.target_timestamp > now, "target_timestamp must be in the future"); eosio::check(args.current_weight_ratio > 0, "current_weight_ratio is too small"); eosio::check(args.current_weight_ratio <= rentbw_ratio_frac, "current_weight_ratio is too large"); + eosio::check(args.target_weight_ratio > 0, "target_weight_ratio is too small"); eosio::check(args.target_weight_ratio <= args.current_weight_ratio, "weight can't grow over time"); eosio::check(args.assumed_stake_weight >= 1, "assumed_stake_weight must be at least 1; a much larger value is recommended"); @@ -134,6 +149,7 @@ void system_contract::configrentbw(rentbw_config& args) { eosio::check(args.total_price.symbol == core_symbol, "total_price doesn't match core symbol"); eosio::check(args.total_price.amount > 0, "total_price must be positive"); eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); + eosio::check(args.min_rent_price.amount > 0, "min_rent_price must be positive"); state.assumed_stake_weight = args.assumed_stake_weight; state.initial_weight_ratio = args.current_weight_ratio; @@ -146,6 +162,8 @@ void system_contract::configrentbw(rentbw_config& args) { state.min_rent_price = args.min_rent_price; }; + if (!args.rent_days) + args.rent_days = state.rent_days; eosio::check(args.rent_days > 0, "rent_days must be > 0"); state.rent_days = args.rent_days; @@ -174,7 +192,7 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; - process_rentbw_queue(core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); + process_rentbw_queue(now, core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); update_weight(now, state.net, net_delta_available); update_weight(now, state.cpu, cpu_delta_available); update_utilization(now, state.net); From 04cf097e9b0f71c4ae1babfb111d7a1e10fe29be Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Tue, 3 Dec 2019 18:13:12 -0500 Subject: [PATCH 0964/1048] rentbw --- .../include/eosio.system/eosio.system.hpp | 70 +++++++++---------- contracts/eosio.system/src/rentbw.cpp | 69 +++++++++++++----- contracts/eosio.system/src/rex.cpp | 4 +- 3 files changed, 90 insertions(+), 53 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 6b7d4191..94dae362 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -40,8 +40,8 @@ namespace eosiosystem { using eosio::time_point_sec; using eosio::unsigned_int; - inline constexpr int64_t rentbw_ratio_frac = 1000000000000000ll; // 1.0 = 10^15 - + inline constexpr int64_t rentbw_frac = 1000000000000000ll; // 1.0 = 10^15 + template static inline auto has_field( F flags, E field ) -> std::enable_if_t< std::is_integral_v && std::is_unsigned_v && @@ -493,43 +493,42 @@ namespace eosiosystem { // existing setting. uint32_t decay_secs; // Number of seconds for adjusted resource utilization to decay to instantaneous // utilization within exp(-1). Set this to 0 to preserve the existing setting. - asset total_price; // Total price needed to buy the entire resource market weight. Set this to 0 to + asset target_price; // Fee needed to rent the entire resource market weight. Set this to 0 to // preserve the existing setting. - asset min_rent_price; // Rents below this amount are rejected. This needs to be large enough to cover - // RAM costs. Set this to 0 to preserve the existing setting. }; struct rentbw_config { - rentbw_config_resource net; // NET market configuration - rentbw_config_resource cpu; // CPU market configuration - uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the - // existing setting. + rentbw_config_resource net; // NET market configuration + rentbw_config_resource cpu; // CPU market configuration + uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the + // existing setting. + asset min_rent_price; // Rents below this amount are rejected. This needs to be large enough to cover + // RAM costs. Set this to 0 to preserve the existing setting. }; struct rentbw_state_resource { uint8_t version = 0; - int64_t weight = 0; // resource market weight. calculated; varies over time. - // 1 represents the same amount of resources as 1 - // satoshi of SYS staked. - int64_t weight_ratio = 0; // resource market weight ratio: - // assumed_stake_weight / (assumed_stake_weight + weight). - // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. - int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. - int64_t initial_weight_ratio = rentbw_ratio_frac; // Initial weight_ratio used for linear shrinkage. - int64_t target_weight_ratio = rentbw_ratio_frac / 100; // Linearly shrink the weight_ratio to this amount. - time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started - time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this - // time hits, weight_ratio will be target_weight_ratio. - double exponent = 0; // Exponent of resource price curve. - uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to - // decay to instantaneous utilization within exp(-1). - asset total_price = {}; // Total price needed to buy the entire resource market weight. - asset min_rent_price = {}; // Rents below this amount are rejected - int64_t utilization = 0; // Instantaneous resource utilization. This is the current - // amount sold. - int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It - // grows instantly but decays exponentially. - time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated + int64_t weight = 0; // resource market weight. calculated; varies over time. + // 1 represents the same amount of resources as 1 + // satoshi of SYS staked. + int64_t weight_ratio = 0; // resource market weight ratio: + // assumed_stake_weight / (assumed_stake_weight + weight). + // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. + int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. + int64_t initial_weight_ratio = rentbw_frac; // Initial weight_ratio used for linear shrinkage. + int64_t target_weight_ratio = rentbw_frac / 100; // Linearly shrink the weight_ratio to this amount. + time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started + time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this + // time hits, weight_ratio will be target_weight_ratio. + double exponent = 0; // Exponent of resource price curve. + uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to + // decay to instantaneous utilization within exp(-1). + asset target_price = {}; // Fee needed to rent the entire resource market weight. + int64_t utilization = 0; // Instantaneous resource utilization. This is the current + // amount sold. utilization <= weight. + int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It + // grows instantly but decays exponentially. + time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated }; struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { @@ -537,6 +536,7 @@ namespace eosiosystem { rentbw_state_resource net = {}; // NET market state rentbw_state_resource cpu = {}; // CPU market state uint32_t rent_days = 0; // `rentbw` `days` argument must match this. + asset min_rent_price = {}; // Rents below this amount are rejected uint64_t primary_key()const { return 0; } }; @@ -1228,13 +1228,13 @@ namespace eosiosystem { * @param payer - the resource buyer * @param receiver - the resource receiver * @param days - number of days of resource availability. Must match market configuration. - * @param net - fraction of net (100% = 10^18) managed by this market - * @param cpu - fraction of cpu (100% = 10^18) managed by this market + * @param net_frac - fraction of net (100% = 10^15) managed by this market + * @param cpu_frac - fraction of cpu (100% = 10^15) managed by this market * @param max_payment - the maximum amount `payer` is willing to pay. Tokens are withdrawn from * `payer`'s token balance. */ [[eosio::action]] - void rentbw( const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, const asset& max_payment ); + void rentbw( const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment ); using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; @@ -1308,7 +1308,7 @@ namespace eosiosystem { const char* error_msg = "must vote for at least 21 producers or for a proxy before buying REX" )const; rex_order_outcome fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); - void channel_to_rex( const name& from, const asset& amount ); + void channel_to_rex( const name& from, const asset& amount, bool required = false ); void channel_namebid_to_rex( const int64_t highest_bid ); template int64_t rent_rex( T& table, const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 593c831d..cca3173e 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -80,8 +80,7 @@ void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delt (now.utc_seconds - res.initial_timestamp.utc_seconds) / (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); // !!! check bounds of weight_ratio - int64_t new_weight = - res.assumed_stake_weight * int128_t(rentbw_ratio_frac) / res.weight_ratio - res.assumed_stake_weight; + int64_t new_weight = res.assumed_stake_weight * int128_t(rentbw_frac) / res.weight_ratio - res.assumed_stake_weight; delta_available += new_weight - res.weight; res.weight = new_weight; } @@ -128,10 +127,8 @@ void system_contract::configrentbw(rentbw_config& args) { args.exponent = state.exponent; if (!args.decay_secs) args.decay_secs = state.decay_secs; - if (!args.total_price.amount) - args.total_price = state.total_price; - if (!args.min_rent_price.amount) - args.min_rent_price = state.min_rent_price; + if (!args.target_price.amount) + args.target_price = state.target_price; // !!! examine checks if (args.current_weight_ratio == args.target_weight_ratio) @@ -139,17 +136,15 @@ void system_contract::configrentbw(rentbw_config& args) { else eosio::check(args.target_timestamp > now, "target_timestamp must be in the future"); eosio::check(args.current_weight_ratio > 0, "current_weight_ratio is too small"); - eosio::check(args.current_weight_ratio <= rentbw_ratio_frac, "current_weight_ratio is too large"); + eosio::check(args.current_weight_ratio <= rentbw_frac, "current_weight_ratio is too large"); eosio::check(args.target_weight_ratio > 0, "target_weight_ratio is too small"); eosio::check(args.target_weight_ratio <= args.current_weight_ratio, "weight can't grow over time"); eosio::check(args.assumed_stake_weight >= 1, "assumed_stake_weight must be at least 1; a much larger value is recommended"); eosio::check(args.exponent >= 1, "exponent must be >= 1"); eosio::check(args.decay_secs >= 1, "decay_secs must be >= 1"); - eosio::check(args.total_price.symbol == core_symbol, "total_price doesn't match core symbol"); - eosio::check(args.total_price.amount > 0, "total_price must be positive"); - eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); - eosio::check(args.min_rent_price.amount > 0, "min_rent_price must be positive"); + eosio::check(args.target_price.symbol == core_symbol, "target_price doesn't match core symbol"); + eosio::check(args.target_price.amount > 0, "target_price must be positive"); state.assumed_stake_weight = args.assumed_stake_weight; state.initial_weight_ratio = args.current_weight_ratio; @@ -158,14 +153,20 @@ void system_contract::configrentbw(rentbw_config& args) { state.target_timestamp = args.target_timestamp; state.exponent = args.exponent; state.decay_secs = args.decay_secs; - state.total_price = args.total_price; - state.min_rent_price = args.min_rent_price; + state.target_price = args.target_price; }; if (!args.rent_days) args.rent_days = state.rent_days; + if (!args.min_rent_price.amount) + args.min_rent_price = state.min_rent_price; + eosio::check(args.rent_days > 0, "rent_days must be > 0"); - state.rent_days = args.rent_days; + eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); + eosio::check(args.min_rent_price.amount > 0, "min_rent_price must be positive"); + + state.rent_days = args.rent_days; + state.min_rent_price = args.min_rent_price; update(state.net, args.net); update(state.cpu, args.cpu); @@ -179,7 +180,11 @@ void system_contract::configrentbw(rentbw_config& args) { state_sing.set(state, get_self()); } // system_contract::configrentbw -void system_contract::rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net, int64_t cpu, +int64_t calc_rentbw_price(const rentbw_state_resource& state, double utilization) { + return ceil(state.target_price.amount * pow(utilization / state.weight, state.exponent)); +} + +void system_contract::rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment) { require_auth(payer); rentbw_state_singleton state_sing{ get_self(), 0 }; @@ -189,6 +194,11 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d time_point_sec now = eosio::current_time_point(); auto core_symbol = get_core_symbol(); eosio::check(max_payment.symbol == core_symbol, "max_payment doesn't match core symbol"); + eosio::check(days == state.rent_days, "days doesn't match configuration"); + eosio::check(net_frac >= 0, "net_frac can't be negative"); + eosio::check(cpu_frac >= 0, "cpu_frac can't be negative"); + eosio::check(net_frac <= rentbw_frac, "net can't be more than 100%"); + eosio::check(cpu_frac <= rentbw_frac, "cpu can't be more than 100%"); int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; @@ -198,10 +208,35 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d update_utilization(now, state.net); update_utilization(now, state.cpu); - // todo: rent - // todo: check against min_rent_price + eosio::asset fee{ 0, core_symbol }; + auto process = [&](int64_t frac, int64_t& amount, rentbw_state_resource& state) { + if (!frac) + return; + amount = int128_t(frac) * state.weight / rentbw_frac; + fee += calc_rentbw_price(state, state.adjusted_utilization + amount) - + calc_rentbw_price(state, state.adjusted_utilization); + state.utilization += amount; + eosio::check(state.utilization <= state.weight, "market doesn't have enough resources available"); + }; + int64_t net_amount = 0; + int64_t cpu_amount = 0; + process(net_frac, net_amount, state.net); + process(cpu_frac, cpu_amount, state.cpu); + eosio::check(fee <= max_payment, "calculated fee exceeds max_payment"); + eosio::check(fee >= state.min_rent_price, "calculated fee is below minimum; try renting more"); + + orders.emplace([&](payer, auto& order) { + order.id = orders.available_primary_key(); + order.owner = receiver; + order.net_weight = net_amount; + order.cpu_weight = cpu_amount; + order.expires = now + eosio::days(days); + }); + + adjust_resources(payer, receiver, core_symbol, net, cpu, true); adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); + channel_to_rex(payer, fee, true); state_sing.set(state, get_self()); } diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index 8e9d881f..bcc8868d 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -917,7 +917,7 @@ namespace eosiosystem { * @param from - account from which asset is transfered to REX pool * @param amount - amount of tokens to be transfered */ - void system_contract::channel_to_rex( const name& from, const asset& amount ) + void system_contract::channel_to_rex( const name& from, const asset& amount, bool required ) { #if CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX if ( rex_available() ) { @@ -926,8 +926,10 @@ namespace eosiosystem { token::transfer_action transfer_act{ token_account, { from, active_permission } }; transfer_act.send( from, rex_account, amount, std::string("transfer from ") + from.to_string() + " to eosio.rex" ); + return; } #endif + eosio::check( !required, "can't channel fees to rex" ); } /** From 3c6f5823b3cf1c959ce55e7902d5caa8e725550e Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 4 Dec 2019 13:59:49 -0500 Subject: [PATCH 0965/1048] testing --- .../include/eosio.system/eosio.system.hpp | 2 +- contracts/eosio.system/src/rentbw.cpp | 12 +- tests/eosio.rentbw_tests.cpp | 126 +++++++++++++++++- 3 files changed, 131 insertions(+), 9 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 94dae362..2e219cd0 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -41,7 +41,7 @@ namespace eosiosystem { using eosio::unsigned_int; inline constexpr int64_t rentbw_frac = 1000000000000000ll; // 1.0 = 10^15 - + template static inline auto has_field( F flags, E field ) -> std::enable_if_t< std::is_integral_v && std::is_unsigned_v && diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index cca3173e..cad25115 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -127,7 +127,7 @@ void system_contract::configrentbw(rentbw_config& args) { args.exponent = state.exponent; if (!args.decay_secs) args.decay_secs = state.decay_secs; - if (!args.target_price.amount) + if (!args.target_price.amount && state.target_price.amount) args.target_price = state.target_price; // !!! examine checks @@ -158,7 +158,7 @@ void system_contract::configrentbw(rentbw_config& args) { if (!args.rent_days) args.rent_days = state.rent_days; - if (!args.min_rent_price.amount) + if (!args.min_rent_price.amount && state.min_rent_price.amount) args.min_rent_price = state.min_rent_price; eosio::check(args.rent_days > 0, "rent_days must be > 0"); @@ -213,8 +213,8 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d if (!frac) return; amount = int128_t(frac) * state.weight / rentbw_frac; - fee += calc_rentbw_price(state, state.adjusted_utilization + amount) - - calc_rentbw_price(state, state.adjusted_utilization); + fee.amount += calc_rentbw_price(state, state.adjusted_utilization + amount) - + calc_rentbw_price(state, state.adjusted_utilization); state.utilization += amount; eosio::check(state.utilization <= state.weight, "market doesn't have enough resources available"); }; @@ -226,7 +226,7 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d eosio::check(fee <= max_payment, "calculated fee exceeds max_payment"); eosio::check(fee >= state.min_rent_price, "calculated fee is below minimum; try renting more"); - orders.emplace([&](payer, auto& order) { + orders.emplace(payer, [&](auto& order) { order.id = orders.available_primary_key(); order.owner = receiver; order.net_weight = net_amount; @@ -234,7 +234,7 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d order.expires = now + eosio::days(days); }); - adjust_resources(payer, receiver, core_symbol, net, cpu, true); + adjust_resources(payer, receiver, core_symbol, net_amount, cpu_amount, true); adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); channel_to_rex(payer, fee, true); state_sing.set(state, get_self()); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index d71cdb8c..b3c38a9d 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -12,13 +12,135 @@ #include "eosio.system_tester.hpp" +inline constexpr int64_t rentbw_frac = 1000000000000000ll; // 1.0 = 10^15 +inline constexpr int64_t stake_weight = 1000000000000ll; // 10^12 + +struct rentbw_config_resource { + int64_t current_weight_ratio = {}; + int64_t target_weight_ratio = {}; + int64_t assumed_stake_weight = {}; + time_point_sec target_timestamp = {}; + double exponent = {}; + uint32_t decay_secs = {}; + asset target_price = asset{}; +}; +FC_REFLECT(rentbw_config_resource, // + (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight)(target_timestamp) // + (exponent)(decay_secs)(target_price)) + +struct rentbw_config { + rentbw_config_resource net = {}; + rentbw_config_resource cpu = {}; + uint32_t rent_days = {}; + asset min_rent_price = asset{}; +}; +FC_REFLECT(rentbw_config, (net)(cpu)(rent_days)(min_rent_price)) + using namespace eosio_system; +struct rentbw_tester : eosio_system_tester { + + template + rentbw_config make_config(F f) { + rentbw_config config; + + config.net.current_weight_ratio = rentbw_frac; + config.net.target_weight_ratio = rentbw_frac / 100; + config.net.assumed_stake_weight = stake_weight; + config.net.target_timestamp = control->head_block_time() + fc::days(100); + config.net.exponent = 2; + config.net.decay_secs = fc::days(1).to_seconds(); + config.net.target_price = asset::from_string("1000000.0000 TST"); + + config.cpu.current_weight_ratio = rentbw_frac; + config.cpu.target_weight_ratio = rentbw_frac / 100; + config.cpu.assumed_stake_weight = stake_weight; + config.cpu.target_timestamp = control->head_block_time() + fc::days(100); + config.cpu.exponent = 2; + config.cpu.decay_secs = fc::days(1).to_seconds(); + config.cpu.target_price = asset::from_string("1000000.0000 TST"); + + config.rent_days = 30; + config.min_rent_price = asset::from_string("1.0000 TST"); + + f(config); + return config; + } + + rentbw_config make_config() { + return make_config([](auto&) {}); + } + + action_result configbw(const rentbw_config& config) { + return push_action(N(eosio), N(configrentbw), mvo()("args", config)); + } +}; + BOOST_AUTO_TEST_SUITE(eosio_system_rentbw_tests) -BOOST_FIXTURE_TEST_CASE(foo, eosio_system_tester) try { - // +BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { + BOOST_REQUIRE_EQUAL("missing authority of eosio", + push_action(N(alice1111111), N(configrentbw), mvo()("args", make_config()))); + + BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), + configbw(make_config([&](auto& c) { c.rent_days = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.min_rent_price = asset::from_string("1000000.000 TST"); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), + configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("0.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), + configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("-1.0000 TST"); }))); + + // net assertions + BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), + configbw(make_config([](auto& c) { c.net.current_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), + configbw(make_config([](auto& c) { c.net.target_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), + configbw(make_config([](auto& c) { c.net.assumed_stake_weight = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), + configbw(make_config([&](auto& c) { c.net.target_timestamp = control->head_block_time(); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { + c.net.target_timestamp = control->head_block_time() - fc::seconds(1); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), + configbw(make_config([&](auto& c) { c.net.exponent = .999; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), + configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.net.target_price = asset::from_string("1000000.000 TST"); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("0.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("-1.0000 TST"); }))); + + // cpu assertions + BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), + configbw(make_config([](auto& c) { c.cpu.current_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), + configbw(make_config([](auto& c) { c.cpu.target_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), + configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), + configbw(make_config([&](auto& c) { c.cpu.target_timestamp = control->head_block_time(); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { + c.cpu.target_timestamp = control->head_block_time() - fc::seconds(1); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), + configbw(make_config([&](auto& c) { c.cpu.exponent = .999; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), + configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.cpu.target_price = asset::from_string("1000000.000 TST"); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("-1.0000 TST"); }))); } + FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_SUITE_END() From e9aed5f45ade5a3f5b05f1c0eba3ce0185a9c5c7 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 4 Dec 2019 18:54:29 -0500 Subject: [PATCH 0966/1048] testing --- .../include/eosio.system/eosio.system.hpp | 11 ++- contracts/eosio.system/src/rentbw.cpp | 21 ++++++ tests/eosio.rentbw_tests.cpp | 69 ++++++++++++++++++- 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 2e219cd0..8a2859df 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1220,7 +1220,16 @@ namespace eosiosystem { * action is invoked. */ [[eosio::action]] - void configrentbw(rentbw_config& args); + void configrentbw( rentbw_config& args ); + + /** + * Process rentbw queue and update state. Action does not execute anything related to a specific user. + * + * @param user - any account can execute this action + * @param max - number of queue items to process + */ + [[eosio::action]] + void rentbwexec( const name& user, uint16_t max ); /** * Rent NET and CPU diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index cad25115..2d5d43ed 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -184,6 +184,27 @@ int64_t calc_rentbw_price(const rentbw_state_resource& state, double utilization return ceil(state.target_price.amount * pow(utilization / state.weight, state.exponent)); } +void system_contract::rentbwexec(const name& user, uint16_t max) { + require_auth(user); + rentbw_state_singleton state_sing{ get_self(), 0 }; + rentbw_order_table orders{ get_self(), 0 }; + eosio::check(state_sing.exists(), "rentbw hasn't been initialized"); + auto state = state_sing.get(); + time_point_sec now = eosio::current_time_point(); + auto core_symbol = get_core_symbol(); + + int64_t net_delta_available = 0; + int64_t cpu_delta_available = 0; + process_rentbw_queue(now, core_symbol, state, orders, max, net_delta_available, cpu_delta_available); + update_weight(now, state.net, net_delta_available); + update_weight(now, state.cpu, cpu_delta_available); + update_utilization(now, state.net); + update_utilization(now, state.cpu); + + adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); + state_sing.set(state, get_self()); +} + void system_contract::rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment) { require_auth(payer); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index b3c38a9d..60515068 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -36,10 +36,42 @@ struct rentbw_config { }; FC_REFLECT(rentbw_config, (net)(cpu)(rent_days)(min_rent_price)) +struct rentbw_state_resource { + uint8_t version; + int64_t weight; + int64_t weight_ratio; + int64_t assumed_stake_weight; + int64_t initial_weight_ratio; + int64_t target_weight_ratio; + time_point_sec initial_timestamp; + time_point_sec target_timestamp; + double exponent; + uint32_t decay_secs; + asset target_price; + int64_t utilization; + int64_t adjusted_utilization; + time_point_sec utilization_timestamp; +}; +FC_REFLECT(rentbw_state_resource, // + (version)(weight)(weight_ratio)(assumed_stake_weight)(initial_weight_ratio)(target_weight_ratio) // + (initial_timestamp)(target_timestamp)(exponent)(decay_secs)(target_price)(utilization) // + (adjusted_utilization)(utilization_timestamp)) + +struct rentbw_state { + uint8_t version; + rentbw_state_resource net; + rentbw_state_resource cpu; + uint32_t rent_days; + asset min_rent_price; +}; +FC_REFLECT(rentbw_state, (version)(net)(cpu)(rent_days)(min_rent_price)) + using namespace eosio_system; struct rentbw_tester : eosio_system_tester { + rentbw_tester() { create_accounts_with_resources({ N(eosio.reserv) }); } + template rentbw_config make_config(F f) { rentbw_config config; @@ -72,7 +104,16 @@ struct rentbw_tester : eosio_system_tester { } action_result configbw(const rentbw_config& config) { - return push_action(N(eosio), N(configrentbw), mvo()("args", config)); + return push_action(config::system_account_name, N(configrentbw), mvo()("args", config)); + } + + action_result rentbwexec(name user, uint16_t max) { + return push_action(user, N(rentbwexec), mvo()("user", user)("max", max)); + } + + rentbw_state get_state() { + vector data = get_row_by_account(config::system_account_name, {}, N(rent.state), N(rent.state)); + return fc::raw::unpack(data); } }; @@ -81,6 +122,7 @@ BOOST_AUTO_TEST_SUITE(eosio_system_rentbw_tests) BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL("missing authority of eosio", push_action(N(alice1111111), N(configrentbw), mvo()("args", make_config()))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("rentbw hasn't been initialized"), rentbwexec(N(alice1111111), 10)); BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), configbw(make_config([&](auto& c) { c.rent_days = 0; }))); @@ -139,8 +181,33 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("-1.0000 TST"); }))); + + // TODO: "weight can't shrink below utilization" } +FC_LOG_AND_RETHROW() + +BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { + produce_block(); + + BOOST_REQUIRE_EQUAL("", configbw(make_config([&](rentbw_config& config) { + config.net.current_weight_ratio = (rentbw_frac * 11) / 100; + config.net.target_weight_ratio = (rentbw_frac * 1) / 100; + config.net.assumed_stake_weight = stake_weight; + config.net.target_timestamp = control->head_block_time() + fc::days(10); + config.cpu.current_weight_ratio = (rentbw_frac * 11) / 1000; + config.cpu.target_weight_ratio = (rentbw_frac * 1) / 1000; + config.cpu.assumed_stake_weight = stake_weight; + config.cpu.target_timestamp = control->head_block_time() + fc::days(10); + }))); + + for (int i = 11; i >= 1; --i) { + BOOST_REQUIRE_EQUAL(get_state().net.weight_ratio, (rentbw_frac * i) / 100); + BOOST_REQUIRE_EQUAL(get_state().cpu.weight_ratio, (rentbw_frac * i) / 1000); + produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + } +} FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_SUITE_END() From 93a8c08da7b0d2bbbb8ddc83304cb7245db0c500 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Thu, 5 Dec 2019 15:50:41 -0500 Subject: [PATCH 0967/1048] tests --- tests/eosio.rentbw_tests.cpp | 126 ++++++++++++++++++++++++++++++++--- 1 file changed, 116 insertions(+), 10 deletions(-) diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 60515068..518c56c7 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -103,6 +103,13 @@ struct rentbw_tester : eosio_system_tester { return make_config([](auto&) {}); } + template + rentbw_config make_default_config(F f) { + rentbw_config config; + f(config); + return config; + } + action_result configbw(const rentbw_config& config) { return push_action(config::system_account_name, N(configrentbw), mvo()("args", config)); } @@ -117,6 +124,14 @@ struct rentbw_tester : eosio_system_tester { } }; +template +bool near(A a, B b, D delta) { + if (abs(a - b) <= delta) + return true; + elog("near: ${a} ${b}", ("a", a)("b", b)); + return false; +} + BOOST_AUTO_TEST_SUITE(eosio_system_rentbw_tests) BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { @@ -183,31 +198,122 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("-1.0000 TST"); }))); // TODO: "weight can't shrink below utilization" -} +} // config_tests FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { produce_block(); + auto net_start = (rentbw_frac * 11) / 100; + auto net_target = (rentbw_frac * 1) / 100; + auto cpu_start = (rentbw_frac * 11) / 1000; + auto cpu_target = (rentbw_frac * 1) / 1000; + BOOST_REQUIRE_EQUAL("", configbw(make_config([&](rentbw_config& config) { - config.net.current_weight_ratio = (rentbw_frac * 11) / 100; - config.net.target_weight_ratio = (rentbw_frac * 1) / 100; + config.net.current_weight_ratio = net_start; + config.net.target_weight_ratio = net_target; config.net.assumed_stake_weight = stake_weight; config.net.target_timestamp = control->head_block_time() + fc::days(10); - config.cpu.current_weight_ratio = (rentbw_frac * 11) / 1000; - config.cpu.target_weight_ratio = (rentbw_frac * 1) / 1000; + config.cpu.current_weight_ratio = cpu_start; + config.cpu.target_weight_ratio = cpu_target; config.cpu.assumed_stake_weight = stake_weight; - config.cpu.target_timestamp = control->head_block_time() + fc::days(10); + config.cpu.target_timestamp = control->head_block_time() + fc::days(20); }))); - for (int i = 11; i >= 1; --i) { - BOOST_REQUIRE_EQUAL(get_state().net.weight_ratio, (rentbw_frac * i) / 100); - BOOST_REQUIRE_EQUAL(get_state().cpu.weight_ratio, (rentbw_frac * i) / 1000); + int64_t net; + int64_t cpu; + + for (int i = 0; i <= 6; ++i) { + if (i == 2) { + // Leaves everything as-is, but may introduce slight rounding + produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", configbw({})); + } else if (i) { + produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + } + net = net_start + i * (net_target - net_start) / 10; + cpu = cpu_start + i * (cpu_target - cpu_start) / 20; + BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); + BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + } + + // Extend transition time + { + int i = 7; + produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](rentbw_config& config) { + config.net.target_timestamp = control->head_block_time() + fc::days(30); + config.cpu.target_timestamp = control->head_block_time() + fc::days(40); + }))); + net_start = net = net_start + i * (net_target - net_start) / 10; + cpu_start = cpu = cpu_start + i * (cpu_target - cpu_start) / 20; + BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); + BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + } + + for (int i = 0; i <= 5; ++i) { + if (i) { + produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + } + net = net_start + i * (net_target - net_start) / 30; + cpu = cpu_start + i * (cpu_target - cpu_start) / 40; + BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); + BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + } + + // Change target, keep existing transition time + { + int i = 6; + produce_block(fc::days(1) - fc::milliseconds(500)); + auto new_net_target = net_target / 10; + auto new_cpu_target = cpu_target / 20; + BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](rentbw_config& config) { + config.net.target_weight_ratio = new_net_target; + config.cpu.target_weight_ratio = new_cpu_target; + }))); + net_start = net = net_start + i * (net_target - net_start) / 30; + cpu_start = cpu = cpu_start + i * (cpu_target - cpu_start) / 40; + net_target = new_net_target; + cpu_target = new_cpu_target; + BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); + BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + } + + for (int i = 0; i <= 10; ++i) { + if (i) { + produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + } + net = net_start + i * (net_target - net_start) / (30 - 6); + cpu = cpu_start + i * (cpu_target - cpu_start) / (40 - 6); + BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); + BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + } + + // Move transition time to immediate future + { produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](rentbw_config& config) { + config.net.target_timestamp = control->head_block_time() + fc::milliseconds(1000); + config.cpu.target_timestamp = control->head_block_time() + fc::milliseconds(1000); + }))); + produce_blocks(2); + } + + // Verify targets hold as time advances + for (int i = 0; i <= 10; ++i) { BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE(near(get_state().net.weight_ratio, net_target, 1)); + BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu_target, 1)); + produce_block(fc::days(1)); } -} + + // todo: verify calculated weight + +} // weight_tests FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_SUITE_END() From 518381f97562a0f37a98c0d7533e311b53770976 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Thu, 5 Dec 2019 16:14:02 -0500 Subject: [PATCH 0968/1048] tests --- tests/eosio.rentbw_tests.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 518c56c7..f1bd0c6c 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -224,9 +224,18 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { int64_t net; int64_t cpu; + auto check_weight = [&] { + auto state = get_state(); + BOOST_REQUIRE(near( // + state.net.weight_ratio, // + int64_t(state.net.assumed_stake_weight * eosio::chain::int128_t(rentbw_frac) / + (state.net.weight + state.net.assumed_stake_weight)), + 10)); + }; + for (int i = 0; i <= 6; ++i) { if (i == 2) { - // Leaves everything as-is, but may introduce slight rounding + // Leaves config as-is, but may introduce slight rounding produce_block(fc::days(1) - fc::milliseconds(500)); BOOST_REQUIRE_EQUAL("", configbw({})); } else if (i) { @@ -237,6 +246,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { cpu = cpu_start + i * (cpu_target - cpu_start) / 20; BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + check_weight(); } // Extend transition time @@ -251,6 +261,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { cpu_start = cpu = cpu_start + i * (cpu_target - cpu_start) / 20; BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + check_weight(); } for (int i = 0; i <= 5; ++i) { @@ -262,6 +273,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { cpu = cpu_start + i * (cpu_target - cpu_start) / 40; BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + check_weight(); } // Change target, keep existing transition time @@ -280,6 +292,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { cpu_target = new_cpu_target; BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + check_weight(); } for (int i = 0; i <= 10; ++i) { @@ -291,6 +304,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { cpu = cpu_start + i * (cpu_target - cpu_start) / (40 - 6); BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); + check_weight(); } // Move transition time to immediate future @@ -308,11 +322,9 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); BOOST_REQUIRE(near(get_state().net.weight_ratio, net_target, 1)); BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu_target, 1)); + check_weight(); produce_block(fc::days(1)); } - - // todo: verify calculated weight - } // weight_tests FC_LOG_AND_RETHROW() From a02c3efd8bf8b4c67e9383d4986b01bb6e388191 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Fri, 6 Dec 2019 14:37:12 -0500 Subject: [PATCH 0969/1048] tests --- contracts/eosio.system/src/rentbw.cpp | 9 +- tests/eosio.rentbw_tests.cpp | 136 ++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 2d5d43ed..73d5da5b 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -234,10 +234,13 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d if (!frac) return; amount = int128_t(frac) * state.weight / rentbw_frac; - fee.amount += calc_rentbw_price(state, state.adjusted_utilization + amount) - - calc_rentbw_price(state, state.adjusted_utilization); + eosio::check(state.weight, "market doesn't have resources available"); + eosio::check(state.utilization + amount <= state.weight, "market doesn't have enough resources available"); + int64_t f = calc_rentbw_price(state, state.adjusted_utilization + amount) - + calc_rentbw_price(state, state.adjusted_utilization); + eosio::check(f > 0, "calculated fee is below minimum; try renting more"); + fee.amount += f; state.utilization += amount; - eosio::check(state.utilization <= state.weight, "market doesn't have enough resources available"); }; int64_t net_amount = 0; diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index f1bd0c6c..ee9fa720 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -72,6 +72,23 @@ struct rentbw_tester : eosio_system_tester { rentbw_tester() { create_accounts_with_resources({ N(eosio.reserv) }); } + void start_rex() { + create_account_with_resources(N(rexholder111), config::system_account_name, core_sym::from_string("1.0000"), + false); + transfer(config::system_account_name, N(rexholder111), core_sym::from_string("1001.0000")); + BOOST_REQUIRE_EQUAL("", stake(N(rexholder111), N(rexholder111), core_sym::from_string("500.0000"), + core_sym::from_string("500.0000"))); + create_account_with_resources(N(proxyaccount), config::system_account_name, core_sym::from_string("1.0000"), + false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); + BOOST_REQUIRE_EQUAL("", + push_action(N(proxyaccount), N(regproxy), mvo()("proxy", "proxyaccount")("isproxy", true))); + BOOST_REQUIRE_EQUAL("", vote(N(rexholder111), {}, N(proxyaccount))); + BOOST_REQUIRE_EQUAL("", push_action(N(rexholder111), N(deposit), + mvo()("owner", "rexholder111")("amount", asset::from_string("1.0000 TST")))); + BOOST_REQUIRE_EQUAL("", push_action(N(rexholder111), N(buyrex), + mvo()("from", "rexholder111")("amount", asset::from_string("1.0000 TST")))); + } + template rentbw_config make_config(F f) { rentbw_config config; @@ -118,10 +135,53 @@ struct rentbw_tester : eosio_system_tester { return push_action(user, N(rentbwexec), mvo()("user", user)("max", max)); } + action_result rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, + const asset& max_payment) { + return push_action(payer, N(rentbw), + mvo()("payer", payer)("receiver", receiver)("days", days)("net_frac", net_frac)( + "cpu_frac", cpu_frac)("max_payment", max_payment)); + } + rentbw_state get_state() { vector data = get_row_by_account(config::system_account_name, {}, N(rent.state), N(rent.state)); return fc::raw::unpack(data); } + + struct account_info { + int64_t ram = 0; + int64_t net = 0; + int64_t cpu = 0; + asset liquid; + }; + + account_info get_account_info(account_name acc) { + account_info info; + control->get_resource_limits_manager().get_account_limits(acc, info.ram, info.net, info.cpu); + info.liquid = get_balance(acc); + return info; + }; + + void check_rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, + const asset& max_payment) { + auto before_payer = get_account_info(payer); + auto before_receiver = get_account_info(receiver); + auto before_state = get_state(); + BOOST_REQUIRE_EQUAL("", rentbw(payer, receiver, days, net_frac, cpu_frac, max_payment)); + auto after_payer = get_account_info(payer); + auto after_receiver = get_account_info(receiver); + auto after_state = get_state(); + + if (payer != receiver) { + BOOST_REQUIRE(before_payer.ram == after_payer.ram); + BOOST_REQUIRE(before_payer.net == after_payer.net); + BOOST_REQUIRE(before_payer.cpu == after_payer.cpu); + BOOST_REQUIRE(before_receiver.liquid == after_receiver.liquid); + } + BOOST_REQUIRE(before_receiver.ram == after_receiver.ram); + // BOOST_REQUIRE(before_receiver.net == after_receiver.net); + // BOOST_REQUIRE(before_receiver.cpu == after_receiver.cpu); + // BOOST_REQUIRE(before_payer.liquid == after_payer.liquid); + } }; template @@ -328,4 +388,80 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { } // weight_tests FC_LOG_AND_RETHROW() +BOOST_AUTO_TEST_CASE(rent_tests) try { + rentbw_tester t; + t.produce_block(); + + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("rentbw hasn't been initialized"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 4, rentbw_frac / 8, + asset::from_string("1.000 TST"))); + + BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { + config.net.current_weight_ratio = rentbw_frac; + config.net.target_weight_ratio = rentbw_frac; + config.net.assumed_stake_weight = stake_weight; + config.net.exponent = 1; + config.net.target_price = asset::from_string("1000000.0000 TST"); + + config.cpu.current_weight_ratio = rentbw_frac; + config.cpu.target_weight_ratio = rentbw_frac; + config.cpu.assumed_stake_weight = stake_weight; + config.cpu.exponent = 1; + config.cpu.target_price = asset::from_string("1000000.0000 TST"); + + config.rent_days = 30; + config.min_rent_price = asset::from_string("1.0000 TST"); + }))); + + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("max_payment doesn't match core symbol"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.000 TST"))); + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("market doesn't have resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, 0, rentbw_frac, asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("market doesn't have resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, 0, asset::from_string("1.0000 TST"))); + + BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { + // weight = stake_weight * 3/4 + config.net.current_weight_ratio = rentbw_frac / 4; + config.net.target_weight_ratio = rentbw_frac / 4; + config.net.assumed_stake_weight = stake_weight; + config.net.exponent = 2; + config.net.target_price = asset::from_string("1000000.0000 TST"); + + // weight = stake_weight * 4/5 * 1/2 + config.cpu.current_weight_ratio = rentbw_frac / 5; + config.cpu.target_weight_ratio = rentbw_frac / 5; + config.cpu.assumed_stake_weight = stake_weight / 2; + config.cpu.exponent = 3; + config.cpu.target_price = asset::from_string("2000000.0000 TST"); + + config.rent_days = 30; + config.min_rent_price = asset::from_string("1.0000 TST"); + }))); + + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("calculated fee exceeds max_payment"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("can't channel fees to rex"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, + asset::from_string("3000000.0000 TST"))); + + t.start_rex(); + t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), false, + core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); + t.create_account_with_resources(N(bbbbbbbbbbbb), config::system_account_name, core_sym::from_string("1.0000"), false, + core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); + + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); + BOOST_REQUIRE_EQUAL("", t.rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + asset::from_string("3000000.0000 TST"))); + + // todo: calculated fee is below minimum; try renting more + +} // rent_tests +FC_LOG_AND_RETHROW() + BOOST_AUTO_TEST_SUITE_END() From 07dd2d374a18afb6266fc695cc5e683502592518 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Fri, 6 Dec 2019 16:57:24 -0500 Subject: [PATCH 0970/1048] tests --- tests/eosio.rentbw_tests.cpp | 210 ++++++++++++++++++++++------------- 1 file changed, 131 insertions(+), 79 deletions(-) diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index ee9fa720..ee1d7ce7 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -13,7 +13,7 @@ #include "eosio.system_tester.hpp" inline constexpr int64_t rentbw_frac = 1000000000000000ll; // 1.0 = 10^15 -inline constexpr int64_t stake_weight = 1000000000000ll; // 10^12 +inline constexpr int64_t stake_weight = 100'000'000'0000ll; // 10^12 struct rentbw_config_resource { int64_t current_weight_ratio = {}; @@ -162,25 +162,40 @@ struct rentbw_tester : eosio_system_tester { }; void check_rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, - const asset& max_payment) { + const asset& expected_fee, int64_t expected_net, int64_t expected_cpu) { auto before_payer = get_account_info(payer); auto before_receiver = get_account_info(receiver); auto before_state = get_state(); - BOOST_REQUIRE_EQUAL("", rentbw(payer, receiver, days, net_frac, cpu_frac, max_payment)); + BOOST_REQUIRE_EQUAL("", rentbw(payer, receiver, days, net_frac, cpu_frac, expected_fee)); auto after_payer = get_account_info(payer); auto after_receiver = get_account_info(receiver); auto after_state = get_state(); + if (false) { + ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); + ilog("before_state.net.weight_ratio: ${x}", + ("x", before_state.net.weight_ratio / double(rentbw_frac))); + ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); + ilog("before_state.net.weight: ${x}", ("x", before_state.net.weight)); + + ilog("before_receiver.net: ${x}", ("x", before_receiver.net)); + ilog("after_receiver.net: ${x}", ("x", after_receiver.net)); + ilog("after_receiver.net - before_receiver.net: ${x}", ("x", after_receiver.net - before_receiver.net)); + ilog("expected_net: ${x}", ("x", expected_net)); + ilog("before_payer.liquid - after_payer.liquid: ${x}", ("x", before_payer.liquid - after_payer.liquid)); + ilog("expected_fee: ${x}", ("x", expected_fee)); + } + if (payer != receiver) { - BOOST_REQUIRE(before_payer.ram == after_payer.ram); - BOOST_REQUIRE(before_payer.net == after_payer.net); - BOOST_REQUIRE(before_payer.cpu == after_payer.cpu); - BOOST_REQUIRE(before_receiver.liquid == after_receiver.liquid); + BOOST_REQUIRE_EQUAL(before_payer.ram, after_payer.ram); + BOOST_REQUIRE_EQUAL(before_payer.net, after_payer.net); + BOOST_REQUIRE_EQUAL(before_payer.cpu, after_payer.cpu); + BOOST_REQUIRE_EQUAL(before_receiver.liquid, after_receiver.liquid); } - BOOST_REQUIRE(before_receiver.ram == after_receiver.ram); - // BOOST_REQUIRE(before_receiver.net == after_receiver.net); - // BOOST_REQUIRE(before_receiver.cpu == after_receiver.cpu); - // BOOST_REQUIRE(before_payer.liquid == after_payer.liquid); + BOOST_REQUIRE_EQUAL(before_receiver.ram, after_receiver.ram); + BOOST_REQUIRE_EQUAL(before_receiver.net, after_receiver.net - expected_net); + BOOST_REQUIRE_EQUAL(before_receiver.cpu, after_receiver.cpu - expected_cpu); + BOOST_REQUIRE_EQUAL(before_payer.liquid - after_payer.liquid, expected_fee); } }; @@ -389,78 +404,115 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_CASE(rent_tests) try { - rentbw_tester t; - t.produce_block(); - - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("rentbw hasn't been initialized"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 4, rentbw_frac / 8, - asset::from_string("1.000 TST"))); - - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { - config.net.current_weight_ratio = rentbw_frac; - config.net.target_weight_ratio = rentbw_frac; - config.net.assumed_stake_weight = stake_weight; - config.net.exponent = 1; - config.net.target_price = asset::from_string("1000000.0000 TST"); - - config.cpu.current_weight_ratio = rentbw_frac; - config.cpu.target_weight_ratio = rentbw_frac; - config.cpu.assumed_stake_weight = stake_weight; - config.cpu.exponent = 1; - config.cpu.target_price = asset::from_string("1000000.0000 TST"); - - config.rent_days = 30; - config.min_rent_price = asset::from_string("1.0000 TST"); - }))); - - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("max_payment doesn't match core symbol"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("market doesn't have resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, 0, rentbw_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("market doesn't have resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, 0, asset::from_string("1.0000 TST"))); - - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { - // weight = stake_weight * 3/4 - config.net.current_weight_ratio = rentbw_frac / 4; - config.net.target_weight_ratio = rentbw_frac / 4; - config.net.assumed_stake_weight = stake_weight; - config.net.exponent = 2; - config.net.target_price = asset::from_string("1000000.0000 TST"); - - // weight = stake_weight * 4/5 * 1/2 - config.cpu.current_weight_ratio = rentbw_frac / 5; - config.cpu.target_weight_ratio = rentbw_frac / 5; - config.cpu.assumed_stake_weight = stake_weight / 2; - config.cpu.exponent = 3; - config.cpu.target_price = asset::from_string("2000000.0000 TST"); - - config.rent_days = 30; - config.min_rent_price = asset::from_string("1.0000 TST"); - }))); - - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("calculated fee exceeds max_payment"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("can't channel fees to rex"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, - asset::from_string("3000000.0000 TST"))); + { + rentbw_tester t; + t.produce_block(); + + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("rentbw hasn't been initialized"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 4, rentbw_frac / 8, + asset::from_string("1.000 TST"))); + + BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { + config.net.current_weight_ratio = rentbw_frac; + config.net.target_weight_ratio = rentbw_frac; + config.net.assumed_stake_weight = stake_weight; + config.net.exponent = 1; + config.net.target_price = asset::from_string("1000000.0000 TST"); + + config.cpu.current_weight_ratio = rentbw_frac; + config.cpu.target_weight_ratio = rentbw_frac; + config.cpu.assumed_stake_weight = stake_weight; + config.cpu.exponent = 1; + config.cpu.target_price = asset::from_string("1000000.0000 TST"); + + config.rent_days = 30; + config.min_rent_price = asset::from_string("1.0000 TST"); + }))); + + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("max_payment doesn't match core symbol"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.000 TST"))); + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("market doesn't have resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, 0, rentbw_frac, asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("market doesn't have resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, 0, asset::from_string("1.0000 TST"))); + } - t.start_rex(); - t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), false, - core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - t.create_account_with_resources(N(bbbbbbbbbbbb), config::system_account_name, core_sym::from_string("1.0000"), false, - core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); + auto init = [](auto& t, bool rex) { + t.produce_block(); + BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { + // weight = stake_weight * 3 + config.net.current_weight_ratio = rentbw_frac / 4; + config.net.target_weight_ratio = rentbw_frac / 4; + config.net.assumed_stake_weight = stake_weight; + config.net.exponent = 2; + config.net.target_price = asset::from_string("1000000.0000 TST"); + + // weight = stake_weight * 4 / 2 + config.cpu.current_weight_ratio = rentbw_frac / 5; + config.cpu.target_weight_ratio = rentbw_frac / 5; + config.cpu.assumed_stake_weight = stake_weight / 2; + config.cpu.exponent = 3; + config.cpu.target_price = asset::from_string("2000000.0000 TST"); + + config.rent_days = 30; + config.min_rent_price = asset::from_string("1.0000 TST"); + }))); + + if (rex) + t.start_rex(); + + t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), + false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); + t.create_account_with_resources(N(bbbbbbbbbbbb), config::system_account_name, core_sym::from_string("1.0000"), + false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); + }; + auto net_weight = stake_weight * 3; + auto cpu_weight = stake_weight * 4 / 2; - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); - BOOST_REQUIRE_EQUAL("", t.rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, - asset::from_string("3000000.0000 TST"))); + { + rentbw_tester t; + init(t, false); + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("calculated fee exceeds max_payment"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("can't channel fees to rex"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, + asset::from_string("3000000.0000 TST"))); + } - // todo: calculated fee is below minimum; try renting more + // net:100%, cpu:100% + { + rentbw_tester t; + init(t, true); + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("calculated fee is below minimum; try renting more"), + t.rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, 10, 10, asset::from_string("3000000.0000 TST"))); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); + } + // net:30%, cpu:40%, then net:5%, cpu:10% + { + rentbw_tester t; + init(t, true); + // (.3 ^ 2) * 1000000.0000 = 90000.0000 + // (.4 ^ 3) * 2000000.0000 = 128000.0000 + // total = 218000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("218000.0001")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .3, rentbw_frac * .4, + asset::from_string("218000.0001 TST"), net_weight * .3, cpu_weight * .4); + + // (.35 ^ 2) * 1000000.0000 - 90000.0000 = 32500.0000 + // (.5 ^ 3) * 2000000.0000 - 128000.0000 = 122000.0000 + // total = 154500.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("154499.9999")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .05, rentbw_frac * .10, + asset::from_string("154499.9999 TST"), net_weight * .05, cpu_weight * .10); + } } // rent_tests FC_LOG_AND_RETHROW() From 0a6ca897a45ae56910f1cb9ee3f7485d322dbec9 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Fri, 6 Dec 2019 17:36:09 -0500 Subject: [PATCH 0971/1048] Fix eosio.reserve --- contracts/eosio.system/src/rentbw.cpp | 2 ++ tests/eosio.rentbw_tests.cpp | 16 +++++++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 73d5da5b..fbf13566 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -257,6 +257,8 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d order.cpu_weight = cpu_amount; order.expires = now + eosio::days(days); }); + net_delta_available -= net_amount; + cpu_delta_available -= cpu_amount; adjust_resources(payer, receiver, core_symbol, net_amount, cpu_amount, true); adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index ee1d7ce7..23f85def 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -165,13 +165,15 @@ struct rentbw_tester : eosio_system_tester { const asset& expected_fee, int64_t expected_net, int64_t expected_cpu) { auto before_payer = get_account_info(payer); auto before_receiver = get_account_info(receiver); + auto before_reserve = get_account_info(N(eosio.reserv)); auto before_state = get_state(); BOOST_REQUIRE_EQUAL("", rentbw(payer, receiver, days, net_frac, cpu_frac, expected_fee)); auto after_payer = get_account_info(payer); auto after_receiver = get_account_info(receiver); + auto after_reserve = get_account_info(N(eosio.reserv)); auto after_state = get_state(); - if (false) { + if (true) { ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); ilog("before_state.net.weight_ratio: ${x}", ("x", before_state.net.weight_ratio / double(rentbw_frac))); @@ -184,6 +186,11 @@ struct rentbw_tester : eosio_system_tester { ilog("expected_net: ${x}", ("x", expected_net)); ilog("before_payer.liquid - after_payer.liquid: ${x}", ("x", before_payer.liquid - after_payer.liquid)); ilog("expected_fee: ${x}", ("x", expected_fee)); + + ilog("before_reserve.net: ${x}", ("x", before_reserve.net)); + ilog("after_reserve.net: ${x}", ("x", after_reserve.net)); + ilog("before_reserve.cpu: ${x}", ("x", before_reserve.cpu)); + ilog("after_reserve.cpu: ${x}", ("x", after_reserve.cpu)); } if (payer != receiver) { @@ -193,9 +200,12 @@ struct rentbw_tester : eosio_system_tester { BOOST_REQUIRE_EQUAL(before_receiver.liquid, after_receiver.liquid); } BOOST_REQUIRE_EQUAL(before_receiver.ram, after_receiver.ram); - BOOST_REQUIRE_EQUAL(before_receiver.net, after_receiver.net - expected_net); - BOOST_REQUIRE_EQUAL(before_receiver.cpu, after_receiver.cpu - expected_cpu); + BOOST_REQUIRE_EQUAL(after_receiver.net - before_receiver.net, expected_net); + BOOST_REQUIRE_EQUAL(after_receiver.cpu - before_receiver.cpu, expected_cpu); BOOST_REQUIRE_EQUAL(before_payer.liquid - after_payer.liquid, expected_fee); + + BOOST_REQUIRE_EQUAL(before_reserve.net - after_reserve.net, expected_net); + BOOST_REQUIRE_EQUAL(before_reserve.cpu - after_reserve.cpu, expected_cpu); } }; From 9673ab0d6b0d9f0049a870a4b1f4fc9b61952cfe Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 9 Dec 2019 11:40:33 -0500 Subject: [PATCH 0972/1048] fix utilization update order --- contracts/eosio.system/src/rentbw.cpp | 15 +++++++-------- tests/eosio.rentbw_tests.cpp | 4 +++- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index fbf13566..f40db80e 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -3,6 +3,9 @@ namespace eosiosystem { +void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delta_available); +void update_utilization(time_point_sec now, rentbw_state_resource& res); + void system_contract::adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed) { if (!net_delta && !cpu_delta) @@ -57,6 +60,8 @@ void system_contract::adjust_resources(name payer, name account, symbol core_sym void system_contract::process_rentbw_queue(time_point_sec now, symbol core_symbol, rentbw_state& state, rentbw_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available) { + update_utilization(now, state.net); + update_utilization(now, state.cpu); auto idx = orders.get_index<"byexpires"_n>(); while (max_items--) { auto it = idx.begin(); @@ -69,6 +74,8 @@ void system_contract::process_rentbw_queue(time_point_sec now, symbol core_symbo } state.net.utilization -= net_delta_available; state.cpu.utilization -= cpu_delta_available; + update_weight(now, state.net, net_delta_available); + update_weight(now, state.cpu, cpu_delta_available); } void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delta_available) { @@ -196,10 +203,6 @@ void system_contract::rentbwexec(const name& user, uint16_t max) { int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; process_rentbw_queue(now, core_symbol, state, orders, max, net_delta_available, cpu_delta_available); - update_weight(now, state.net, net_delta_available); - update_weight(now, state.cpu, cpu_delta_available); - update_utilization(now, state.net); - update_utilization(now, state.cpu); adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); state_sing.set(state, get_self()); @@ -224,10 +227,6 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; process_rentbw_queue(now, core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); - update_weight(now, state.net, net_delta_available); - update_weight(now, state.cpu, cpu_delta_available); - update_utilization(now, state.net); - update_utilization(now, state.cpu); eosio::asset fee{ 0, core_symbol }; auto process = [&](int64_t frac, int64_t& amount, rentbw_state_resource& state) { diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 23f85def..b2705b1c 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -173,7 +173,7 @@ struct rentbw_tester : eosio_system_tester { auto after_reserve = get_account_info(N(eosio.reserv)); auto after_state = get_state(); - if (true) { + if (false) { ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); ilog("before_state.net.weight_ratio: ${x}", ("x", before_state.net.weight_ratio / double(rentbw_frac))); @@ -206,6 +206,8 @@ struct rentbw_tester : eosio_system_tester { BOOST_REQUIRE_EQUAL(before_reserve.net - after_reserve.net, expected_net); BOOST_REQUIRE_EQUAL(before_reserve.cpu - after_reserve.cpu, expected_cpu); + BOOST_REQUIRE_EQUAL(after_state.net.utilization - before_state.net.utilization, expected_net); + BOOST_REQUIRE_EQUAL(after_state.cpu.utilization - before_state.cpu.utilization, expected_cpu); } }; From b86accc2f3aa511c2beea5e3d07c26fb19079390 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 9 Dec 2019 17:48:14 -0500 Subject: [PATCH 0973/1048] Fix adjusted_utilization --- contracts/eosio.system/src/rentbw.cpp | 2 +- tests/eosio.rentbw_tests.cpp | 69 +++++++++++++++++++++++++++ 2 files changed, 70 insertions(+), 1 deletion(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index f40db80e..9c6699a6 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -99,7 +99,7 @@ void update_utilization(time_point_sec now, rentbw_state_resource& res) { res.adjusted_utilization = // res.utilization + (res.adjusted_utilization - res.utilization) * - exp((now.utc_seconds - res.utilization_timestamp.utc_seconds) / double(-res.decay_secs)); + exp(-double(now.utc_seconds - res.utilization_timestamp.utc_seconds) / double(res.decay_secs)); res.utilization_timestamp = now; } diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index b2705b1c..1ae7872a 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -525,6 +525,75 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .05, rentbw_frac * .10, asset::from_string("154499.9999 TST"), net_weight * .05, cpu_weight * .10); } + + { + // net:100%, cpu:100% + rentbw_tester t; + init(t, true); + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); + + // No more available for 30 days + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + asset::from_string("1.0000 TST"))); + t.produce_block(fc::days(29)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + asset::from_string("1.0000 TST"))); + t.produce_block(fc::days(1) - fc::milliseconds(1500)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + asset::from_string("1.0000 TST"))); + t.produce_block(fc::milliseconds(500)); + + // immediate renewal: adjusted_utilization doesn't have time to fall + // + // (2.0 ^ 2) * 1000000.0000 - 1000000.0000 = 3000000.0000 + // (2.0 ^ 3) * 2000000.0000 - 2000000.0000 = 14000000.0000 + // total = 17000000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("17000000.0000")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + asset::from_string("17000000.0000 TST"), 0, 0); + + // No more available for 30 days + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + asset::from_string("1.0000 TST"))); + t.produce_block(fc::days(29)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + asset::from_string("1.0000 TST"))); + t.produce_block(fc::days(1) - fc::milliseconds(1000)); + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + asset::from_string("1.0000 TST"))); + + // Start decay + t.produce_block(fc::milliseconds(1000)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, net_weight, net_weight / 1000)); + BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, cpu_weight, cpu_weight / 1000)); + + // 1 day of decay + t.produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-1)), + int64_t(net_weight * exp(-1)) / 1000)); + BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-1)), + int64_t(cpu_weight * exp(-1)) / 1000)); + + // 1 day of decay + t.produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-2)), + int64_t(net_weight * exp(-2)) / 1000)); + BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-2)), + int64_t(cpu_weight * exp(-2)) / 1000)); + } + } // rent_tests FC_LOG_AND_RETHROW() From cc7ab5225356dd890a4ce9a4cecc2b0dc63f05d6 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Mon, 9 Dec 2019 19:03:30 -0500 Subject: [PATCH 0974/1048] tests --- tests/eosio.rentbw_tests.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 1ae7872a..a92dcf0f 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -592,6 +592,15 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { int64_t(net_weight * exp(-2)) / 1000)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-2)), int64_t(cpu_weight * exp(-2)) / 1000)); + + // 100% after 2 days of decay + // + // [((e^-2 + 1.0) ^ 2) - ((e^-2) ^ 2) ] * 1000000.0000 = 1270670.5664 + // [((e^-2 + 1.0) ^ 3) - ((e^-2) ^ 3) ] * 2000000.0000 = 2921905.5327 + // total = 4192576.0991 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("4192561.0244")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + asset::from_string("4192561.0244 TST"), net_weight, cpu_weight); } } // rent_tests From 1030f8427242cf17f0d48fe467964a5db226d3c7 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Tue, 10 Dec 2019 13:36:22 -0500 Subject: [PATCH 0975/1048] tests --- tests/eosio.rentbw_tests.cpp | 46 ++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index a92dcf0f..fece8839 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -603,6 +603,52 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { asset::from_string("4192561.0244 TST"), net_weight, cpu_weight); } + { + rentbw_tester t; + init(t, true); + + // 10%, 20% + // (.1 ^ 2) * 1000000.0000 = 10000.0000 + // (.2 ^ 3) * 2000000.0000 = 16000.0000 + // total = 26000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("26000.0002")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .1, rentbw_frac * .2, + asset::from_string("26000.0002 TST"), net_weight * .1, cpu_weight * .2); + + t.produce_block(fc::days(15) - fc::milliseconds(500)); + + // 20%, 20% + // (.3 ^ 2) * 1000000.0000 - 10000.0000 = 80000.0000 + // (.4 ^ 3) * 2000000.0000 - 16000.0000 = 112000.0000 + // total = 192000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("191999.9999")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .2, rentbw_frac * .2, + asset::from_string("191999.9999 TST"), net_weight * .2, cpu_weight * .2); + + // Start decay + t.produce_block(fc::days(15) - fc::milliseconds(1000)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .3 * net_weight, 0)); + BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .4 * cpu_weight, 0)); + + // 1 day of decay from (30%, 40%) to (20%, 20%) + t.produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE( + near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-1) + .2 * net_weight), 0)); + BOOST_REQUIRE( + near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-1) + .2 * cpu_weight), 0)); + + // 2 days of decay from (30%, 40%) to (20%, 20%) + t.produce_block(fc::days(1) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE( + near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2) + .2 * net_weight), 0)); + BOOST_REQUIRE( + near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-2) + .2 * cpu_weight), 0)); + } + } // rent_tests FC_LOG_AND_RETHROW() From f87dae900a452aaef599108c4ff65218b2dcf8a7 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Tue, 10 Dec 2019 18:13:23 -0500 Subject: [PATCH 0976/1048] prevent weight from getting too large --- contracts/eosio.system/src/rentbw.cpp | 5 +++-- tests/eosio.rentbw_tests.cpp | 22 ++++++++++++++++++++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 9c6699a6..4476b5ba 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -86,7 +86,6 @@ void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delt int128_t(res.target_weight_ratio - res.initial_weight_ratio) * (now.utc_seconds - res.initial_timestamp.utc_seconds) / (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); - // !!! check bounds of weight_ratio int64_t new_weight = res.assumed_stake_weight * int128_t(rentbw_frac) / res.weight_ratio - res.assumed_stake_weight; delta_available += new_weight - res.weight; res.weight = new_weight; @@ -137,7 +136,6 @@ void system_contract::configrentbw(rentbw_config& args) { if (!args.target_price.amount && state.target_price.amount) args.target_price = state.target_price; - // !!! examine checks if (args.current_weight_ratio == args.target_weight_ratio) args.target_timestamp = now; else @@ -148,6 +146,9 @@ void system_contract::configrentbw(rentbw_config& args) { eosio::check(args.target_weight_ratio <= args.current_weight_ratio, "weight can't grow over time"); eosio::check(args.assumed_stake_weight >= 1, "assumed_stake_weight must be at least 1; a much larger value is recommended"); + eosio::check(args.assumed_stake_weight * int128_t(rentbw_frac) / args.target_weight_ratio <= + std::numeric_limits::max(), + "assumed_stake_weight/target_weight_ratio is too large"); eosio::check(args.exponent >= 1, "exponent must be >= 1"); eosio::check(args.decay_secs >= 1, "decay_secs must be >= 1"); eosio::check(args.target_price.symbol == core_symbol, "target_price doesn't match core symbol"); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index fece8839..04b10437 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -239,6 +239,11 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { // net assertions BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), configbw(make_config([](auto& c) { c.net.current_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), + configbw(make_config([](auto& c) { + c.net.assumed_stake_weight = 100000; + c.net.target_weight_ratio = 10; + }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), configbw(make_config([](auto& c) { c.net.target_weight_ratio = rentbw_frac + 1; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), @@ -263,6 +268,11 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { // cpu assertions BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), configbw(make_config([](auto& c) { c.cpu.current_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), + configbw(make_config([](auto& c) { + c.cpu.assumed_stake_weight = 100000; + c.cpu.target_weight_ratio = 10; + }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), configbw(make_config([](auto& c) { c.cpu.target_weight_ratio = rentbw_frac + 1; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), @@ -283,11 +293,19 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("-1.0000 TST"); }))); - - // TODO: "weight can't shrink below utilization" } // config_tests FC_LOG_AND_RETHROW() +/* TODO: + +eosio::check(days == state.rent_days, "days doesn't match configuration"); +eosio::check(net_frac >= 0, "net_frac can't be negative"); +eosio::check(cpu_frac >= 0, "cpu_frac can't be negative"); +eosio::check(net_frac <= rentbw_frac, "net can't be more than 100%"); +eosio::check(cpu_frac <= rentbw_frac, "cpu can't be more than 100%"); +eosio::check(state.net.weight >= state.net.utilization, "weight can't shrink below utilization"); +*/ + BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { produce_block(); From e5889cdfb1bfd02826e4455db86e13c523e457b2 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 11 Dec 2019 11:20:12 -0500 Subject: [PATCH 0977/1048] tests --- tests/eosio.rentbw_tests.cpp | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 04b10437..6af22523 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -298,11 +298,6 @@ FC_LOG_AND_RETHROW() /* TODO: -eosio::check(days == state.rent_days, "days doesn't match configuration"); -eosio::check(net_frac >= 0, "net_frac can't be negative"); -eosio::check(cpu_frac >= 0, "cpu_frac can't be negative"); -eosio::check(net_frac <= rentbw_frac, "net can't be more than 100%"); -eosio::check(cpu_frac <= rentbw_frac, "cpu can't be more than 100%"); eosio::check(state.net.weight >= state.net.utilization, "weight can't shrink below utilization"); */ @@ -505,6 +500,25 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { { rentbw_tester t; init(t, false); + BOOST_REQUIRE_EQUAL( + t.wasm_assert_msg("days doesn't match configuration"), // + t.rentbw(N(bob111111111), N(alice1111111), 20, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL( // + t.wasm_assert_msg("net_frac can't be negative"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, -rentbw_frac, rentbw_frac, + asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL( // + t.wasm_assert_msg("cpu_frac can't be negative"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, -rentbw_frac, + asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL( // + t.wasm_assert_msg("net can't be more than 100%"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac + 1, rentbw_frac, + asset::from_string("1.0000 TST"))); + BOOST_REQUIRE_EQUAL( // + t.wasm_assert_msg("cpu can't be more than 100%"), // + t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac + 1, + asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("calculated fee exceeds max_payment"), // t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); From 5b7f15ed09280d43c4813466fbe3ac6995edbd8e Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 11 Dec 2019 11:35:42 -0500 Subject: [PATCH 0978/1048] tests --- tests/eosio.rentbw_tests.cpp | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 6af22523..4306ce38 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -296,11 +296,6 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { } // config_tests FC_LOG_AND_RETHROW() -/* TODO: - -eosio::check(state.net.weight >= state.net.utilization, "weight can't shrink below utilization"); -*/ - BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { produce_block(); @@ -537,6 +532,31 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { t.rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, 10, 10, asset::from_string("3000000.0000 TST"))); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); + + BOOST_REQUIRE_EQUAL( // + t.wasm_assert_msg("weight can't shrink below utilization"), + t.configbw(t.make_default_config([&](auto& config) { + config.net.current_weight_ratio = rentbw_frac / 4 + 1; + config.net.target_weight_ratio = rentbw_frac / 4 + 1; + config.cpu.current_weight_ratio = rentbw_frac / 5; + config.cpu.target_weight_ratio = rentbw_frac / 5; + }))); + BOOST_REQUIRE_EQUAL( // + t.wasm_assert_msg("weight can't shrink below utilization"), + t.configbw(t.make_default_config([&](auto& config) { + config.net.current_weight_ratio = rentbw_frac / 4; + config.net.target_weight_ratio = rentbw_frac / 4; + config.cpu.current_weight_ratio = rentbw_frac / 5 + 1; + config.cpu.target_weight_ratio = rentbw_frac / 5 + 1; + }))); + BOOST_REQUIRE_EQUAL( // + "", // + t.configbw(t.make_default_config([&](auto& config) { + config.net.current_weight_ratio = rentbw_frac / 4; + config.net.target_weight_ratio = rentbw_frac / 4; + config.cpu.current_weight_ratio = rentbw_frac / 5; + config.cpu.target_weight_ratio = rentbw_frac / 5; + }))); } // net:30%, cpu:40%, then net:5%, cpu:10% From 21e0d9a08014c0f3a7de30614cea8e689c7e0080 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Wed, 11 Dec 2019 13:04:55 -0500 Subject: [PATCH 0979/1048] Missing action wrapper --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 8a2859df..6436b7cb 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1292,6 +1292,7 @@ namespace eosiosystem { using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; using configcpu_action = eosio::action_wrapper<"configrentbw"_n, &system_contract::configrentbw>; + using rentbwexec_action = eosio::action_wrapper<"rentbwexec"_n, &system_contract::rentbwexec>; using rentbw_action = eosio::action_wrapper<"rentbw"_n, &system_contract::rentbw>; private: From 70e6c558d4bc8772f6207ef20139ab4731737975 Mon Sep 17 00:00:00 2001 From: Todd Fleming Date: Fri, 13 Dec 2019 10:41:02 -0500 Subject: [PATCH 0980/1048] Adjust min_rent_price description --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 6436b7cb..a0e58f8e 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -502,8 +502,8 @@ namespace eosiosystem { rentbw_config_resource cpu; // CPU market configuration uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the // existing setting. - asset min_rent_price; // Rents below this amount are rejected. This needs to be large enough to cover - // RAM costs. Set this to 0 to preserve the existing setting. + asset min_rent_price; // Rents below this amount are rejected. Set this to 0 to preserve the + // existing setting. }; struct rentbw_state_resource { From 21a78feaef26cdfd59407f0b402c57c1e523e7e3 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Dec 2019 20:55:31 -0500 Subject: [PATCH 0981/1048] minor changes to rentbw system --- .../include/eosio.system/eosio.system.hpp | 13 +++--- contracts/eosio.system/src/rentbw.cpp | 44 ++++++++++++++----- contracts/eosio.system/src/rex.cpp | 1 + 3 files changed, 41 insertions(+), 17 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index a0e58f8e..7ce3bb13 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -484,15 +484,16 @@ namespace eosiosystem { // total rented by REX at the time the rentbw market is first activated. Set // this to 0 to preserve the existing setting; this avoids sudden price jumps. // For new chains which don't need to phase out staking and REX, 10^12 is - // probably a good value. + // probably a good value. time_point_sec target_timestamp; // Stop automatic weight_ratio shrinkage at this time. Once this // time hits, weight_ratio will be target_weight_ratio. Ignored if // current_weight_ratio == target_weight_ratio. Set this to 0 to preserve the // existing setting. double exponent; // Exponent of resource price curve. Must be >= 1. Set this to 0 to preserve the // existing setting. - uint32_t decay_secs; // Number of seconds for adjusted resource utilization to decay to instantaneous - // utilization within exp(-1). Set this to 0 to preserve the existing setting. + uint32_t decay_secs; // Number of seconds for the gap between adjusted resource utilization and + // instantaneous utilization to shrink by 63%. Set this to 0 to preserve the + // existing setting. asset target_price; // Fee needed to rent the entire resource market weight. Set this to 0 to // preserve the existing setting. }; @@ -526,8 +527,8 @@ namespace eosiosystem { asset target_price = {}; // Fee needed to rent the entire resource market weight. int64_t utilization = 0; // Instantaneous resource utilization. This is the current // amount sold. utilization <= weight. - int64_t adjusted_utilization = 0; // Adjusted resource utilization. This >= utilization. It - // grows instantly but decays exponentially. + int64_t adjusted_utilization = 0; // Adjusted resource utilization. This is >= utilization and + // <= weight. It grows instantly but decays exponentially. time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated }; @@ -1233,7 +1234,7 @@ namespace eosiosystem { /** * Rent NET and CPU - * + * * @param payer - the resource buyer * @param receiver - the resource receiver * @param days - number of days of resource availability. Must match market configuration. diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 4476b5ba..4b2af9db 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -1,9 +1,18 @@ #include -#include +#include +#include +#include namespace eosiosystem { void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delta_available); + +/** + * @pre now >= res.utilization_timestamp + * @post res.utilization <= new res.adjusted_utilization + * @post if res.utilization < old res.adjusted_utilization, then new res.adjusted_utilization <= old res.adjusted_utilization + * @post if res.utilization >= old res.adjusted_utilization, then new res.adjusted_utilization == res.utilization + */ void update_utilization(time_point_sec now, rentbw_state_resource& res); void system_contract::adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, @@ -79,26 +88,30 @@ void system_contract::process_rentbw_queue(time_point_sec now, symbol core_symbo } void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delta_available) { - if (now >= res.target_timestamp) + if (now >= res.target_timestamp) { res.weight_ratio = res.target_weight_ratio; - else + } else { res.weight_ratio = res.initial_weight_ratio + // int128_t(res.target_weight_ratio - res.initial_weight_ratio) * (now.utc_seconds - res.initial_timestamp.utc_seconds) / (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); - int64_t new_weight = res.assumed_stake_weight * int128_t(rentbw_frac) / res.weight_ratio - res.assumed_stake_weight; + } + int64_t new_weight = res.assumed_stake_weight * int128_t(rentbw_frac) / res.weight_ratio - res.assumed_stake_weight; delta_available += new_weight - res.weight; res.weight = new_weight; } void update_utilization(time_point_sec now, rentbw_state_resource& res) { - if (res.utilization >= res.adjusted_utilization) + if (now <= res.utilization_timestamp) return; + + if (res.utilization >= res.adjusted_utilization) { res.adjusted_utilization = res.utilization; - else - res.adjusted_utilization = // - res.utilization + - (res.adjusted_utilization - res.utilization) * - exp(-double(now.utc_seconds - res.utilization_timestamp.utc_seconds) / double(res.decay_secs)); + } else { + int64_t diff = res.adjusted_utilization - res.utilization; + int64_t delta = diff * std::exp(-double(now.utc_seconds - res.utilization_timestamp.utc_seconds) / double(res.decay_secs)); + delta = std::clamp( delta, 0ll, diff); + res.adjusted_utilization = res.utilization + delta; + } res.utilization_timestamp = now; } @@ -109,11 +122,18 @@ void system_contract::configrentbw(rentbw_config& args) { rentbw_state_singleton state_sing{ get_self(), 0 }; auto state = state_sing.get_or_default(); + eosio::check(eosio::is_account(reserv_account), "eosio.reserv account must first be created"); + int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; if (state_sing.exists()) { + update_utilization(now, state.net); + update_utilization(now, state.cpu); update_weight(now, state.net, net_delta_available); update_weight(now, state.cpu, cpu_delta_available); + } else { + state.net.utilization_timestamp = now; + state.cpu.utilization_timestamp = now; } auto update = [&](auto& state, auto& args) { @@ -183,13 +203,15 @@ void system_contract::configrentbw(rentbw_config& args) { update_weight(now, state.cpu, cpu_delta_available); eosio::check(state.net.weight >= state.net.utilization, "weight can't shrink below utilization"); eosio::check(state.cpu.weight >= state.cpu.utilization, "weight can't shrink below utilization"); + state.net.adjusted_utilization = std::min(state.net.adjusted_utilization, state.net.weight); + state.cpu.adjusted_utilization = std::min(state.cpu.adjusted_utilization, state.cpu.weight); adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); state_sing.set(state, get_self()); } // system_contract::configrentbw int64_t calc_rentbw_price(const rentbw_state_resource& state, double utilization) { - return ceil(state.target_price.amount * pow(utilization / state.weight, state.exponent)); + return std::ceil(state.target_price.amount * std::pow(utilization / state.weight, state.exponent)); } void system_contract::rentbwexec(const name& user, uint16_t max) { diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp index bcc8868d..dee9c0ab 100644 --- a/contracts/eosio.system/src/rex.cpp +++ b/contracts/eosio.system/src/rex.cpp @@ -916,6 +916,7 @@ namespace eosiosystem { * * @param from - account from which asset is transfered to REX pool * @param amount - amount of tokens to be transfered + * @param required - if true, asserts when the system is not configured to channel fees into REX */ void system_contract::channel_to_rex( const name& from, const asset& amount, bool required ) { From a78cccd6d8b89980c6b018397930e7f93fe668ca Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Dec 2019 21:49:53 -0500 Subject: [PATCH 0982/1048] move comment (with the rentbw addition) to its proper place --- .../include/eosio.system/eosio.system.hpp | 28 ++++++++----------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 7ce3bb13..50fb3f2e 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -80,18 +80,6 @@ namespace eosiosystem { static constexpr int64_t default_inflation_pay_factor = 50000; // producers pay share = 10000 / 50000 = 20% of the inflation static constexpr int64_t default_votepay_factor = 40000; // per-block pay share = 10000 / 40000 = 25% of the producer pay - /** - * eosio.system contract defines the structures and actions needed for blockchain's core functionality. - * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or - * delegate their vote to a proxy. - * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. - * - Users can buy and sell RAM at a market-determined price. - * - Users can bid on premium names. - * - A resource exchange system (REX) allows token holders to lend their tokens, - * and users to rent CPU and Network resources in return for a market-determined fee. - * - A resource market separate from REX: `rentbw` - */ - // A name bid, which consists of: // - a `newname` name that the bid is for // - a `high_bidder` account name that is the one with the highest bid so far @@ -346,8 +334,8 @@ namespace eosiosystem { // - `version` defaulted to zero, // - `last_dist_time` the last time proceeds from renting, ram fees, and name bids were added to the rex pool, // - `pending_bucket_time` timestamp of the pending 12-hour return bucket, - // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, - // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, + // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, + // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool, // - `proceeds` the maximum amount of proceeds that can be added to the rex pool at any given time struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { @@ -371,7 +359,7 @@ namespace eosiosystem { // `rex_return_buckets` structure underlying the rex return buckets table. A rex return buckets table is defined by: // - `version` defaulted to zero, - // - `return_buckets` buckets of proceeds accumulated in 12-hour intervals + // - `return_buckets` buckets of proceeds accumulated in 12-hour intervals struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_buckets { uint8_t version = 0; std::map return_buckets; @@ -563,7 +551,15 @@ namespace eosiosystem { > rentbw_order_table; /** - * The EOSIO system contract. The EOSIO system contract governs ram market, voters, producers, global state. + * eosio.system contract defines the structures and actions needed for blockchain's core functionality. + * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or + * delegate their vote to a proxy. + * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. + * - Users can buy and sell RAM at a market-determined price. + * - Users can bid on premium names. + * - A resource exchange system (REX) allows token holders to lend their tokens, + * and users to rent CPU and Network resources in return for a market-determined fee. + * - A resource market separate from REX: `rentbw`. */ class [[eosio::contract("eosio.system")]] system_contract : public native { From fed41410e824f4df0efbec9f88f8eade61502285 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Dec 2019 22:14:36 -0500 Subject: [PATCH 0983/1048] also change description of decay_secs in rentbw_state_resource to reflect the change in rentbw_config_resource --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 50fb3f2e..5ab49de4 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -510,8 +510,8 @@ namespace eosiosystem { time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this // time hits, weight_ratio will be target_weight_ratio. double exponent = 0; // Exponent of resource price curve. - uint32_t decay_secs = 0; // Number of seconds for adjusted resource utilization to - // decay to instantaneous utilization within exp(-1). + uint32_t decay_secs; = 0; // Number of seconds for the gap between adjusted resource + // utilization and instantaneous utilization to shrink by 63%. asset target_price = {}; // Fee needed to rent the entire resource market weight. int64_t utilization = 0; // Instantaneous resource utilization. This is the current // amount sold. utilization <= weight. From 614579b126fe6743bcf087b5fa934f3de6cf5e6a Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 16 Dec 2019 22:18:54 -0500 Subject: [PATCH 0984/1048] fix typo in previous commit --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 5ab49de4..4ff4bc1d 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -510,7 +510,7 @@ namespace eosiosystem { time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this // time hits, weight_ratio will be target_weight_ratio. double exponent = 0; // Exponent of resource price curve. - uint32_t decay_secs; = 0; // Number of seconds for the gap between adjusted resource + uint32_t decay_secs = 0; // Number of seconds for the gap between adjusted resource // utilization and instantaneous utilization to shrink by 63%. asset target_price = {}; // Fee needed to rent the entire resource market weight. int64_t utilization = 0; // Instantaneous resource utilization. This is the current From 929a53a86ea56a16f78f6d2591bcea45da36a60f Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 14:46:12 -0500 Subject: [PATCH 0985/1048] replace calc_rentbw_price with calc_rentbw_fee --- contracts/eosio.system/src/rentbw.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 4b2af9db..f75118af 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -210,8 +210,11 @@ void system_contract::configrentbw(rentbw_config& args) { state_sing.set(state, get_self()); } // system_contract::configrentbw -int64_t calc_rentbw_price(const rentbw_state_resource& state, double utilization) { - return std::ceil(state.target_price.amount * std::pow(utilization / state.weight, state.exponent)); +int64_t calc_rentbw_fee(const rentbw_state_resource& state, int64_t utilization_increase) { + double start_utilization = state.adjusted_utilization; + double end_utilization = state.adjusted_utilization + utilization_increase; + return std::ceil(state.target_price.amount * std::pow(end_utilization / state.weight, state.exponent)) + - std::ceil(state.target_price.amount * std::pow(start_utilization / state.weight, state.exponent)); } void system_contract::rentbwexec(const name& user, uint16_t max) { @@ -258,8 +261,7 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d amount = int128_t(frac) * state.weight / rentbw_frac; eosio::check(state.weight, "market doesn't have resources available"); eosio::check(state.utilization + amount <= state.weight, "market doesn't have enough resources available"); - int64_t f = calc_rentbw_price(state, state.adjusted_utilization + amount) - - calc_rentbw_price(state, state.adjusted_utilization); + int64_t f = calc_rentbw_fee(state, amount); eosio::check(f > 0, "calculated fee is below minimum; try renting more"); fee.amount += f; state.utilization += amount; From 8a5620631fa96725f8ce65e625944ffb072c1d37 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 14:51:29 -0500 Subject: [PATCH 0986/1048] prefer rounding in a way that ensures fee calculation does not give advantage to very small rentals under particular situations (but still under the condition of utilization >= adjusted_utilization) Also add calculated fee to the error message when it exceeds max_payment. --- contracts/eosio.system/src/rentbw.cpp | 13 ++++++++++--- tests/eosio.rentbw_tests.cpp | 14 +++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index f75118af..cb94c98d 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -213,8 +213,11 @@ void system_contract::configrentbw(rentbw_config& args) { int64_t calc_rentbw_fee(const rentbw_state_resource& state, int64_t utilization_increase) { double start_utilization = state.adjusted_utilization; double end_utilization = state.adjusted_utilization + utilization_increase; - return std::ceil(state.target_price.amount * std::pow(end_utilization / state.weight, state.exponent)) - - std::ceil(state.target_price.amount * std::pow(start_utilization / state.weight, state.exponent)); + + double fee = state.target_price.amount * std::pow(end_utilization / state.weight, state.exponent) - + state.target_price.amount * std::pow(start_utilization / state.weight, state.exponent); + + return std::ceil(fee); } void system_contract::rentbwexec(const name& user, uint16_t max) { @@ -271,7 +274,11 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d int64_t cpu_amount = 0; process(net_frac, net_amount, state.net); process(cpu_frac, cpu_amount, state.cpu); - eosio::check(fee <= max_payment, "calculated fee exceeds max_payment"); + if (fee > max_payment) { + std::string error_msg = "max_payment is less than calculated fee: "; + error_msg += fee.to_string(); + eosio::check(false, error_msg); + } eosio::check(fee >= state.min_rent_price, "calculated fee is below minimum; try renting more"); orders.emplace(payer, [&](auto& order) { diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 4306ce38..b05120a9 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -515,7 +515,7 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac + 1, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("calculated fee exceeds max_payment"), // + t.wasm_assert_msg("max_payment is less than calculated fee: 3000000.0000 TST"), // t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("can't channel fees to rex"), // t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, @@ -573,9 +573,9 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // (.35 ^ 2) * 1000000.0000 - 90000.0000 = 32500.0000 // (.5 ^ 3) * 2000000.0000 - 128000.0000 = 122000.0000 // total = 154500.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("154499.9999")); + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("154500.0000")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .05, rentbw_frac * .10, - asset::from_string("154499.9999 TST"), net_weight * .05, cpu_weight * .10); + asset::from_string("154500.0000 TST"), net_weight * .05, cpu_weight * .10); } { @@ -650,9 +650,9 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // [((e^-2 + 1.0) ^ 2) - ((e^-2) ^ 2) ] * 1000000.0000 = 1270670.5664 // [((e^-2 + 1.0) ^ 3) - ((e^-2) ^ 3) ] * 2000000.0000 = 2921905.5327 // total = 4192576.0991 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("4192561.0244")); + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("4192561.0246")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, - asset::from_string("4192561.0244 TST"), net_weight, cpu_weight); + asset::from_string("4192561.0246 TST"), net_weight, cpu_weight); } { @@ -673,9 +673,9 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // (.3 ^ 2) * 1000000.0000 - 10000.0000 = 80000.0000 // (.4 ^ 3) * 2000000.0000 - 16000.0000 = 112000.0000 // total = 192000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("191999.9999")); + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("192000.0001")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .2, rentbw_frac * .2, - asset::from_string("191999.9999 TST"), net_weight * .2, cpu_weight * .2); + asset::from_string("192000.0001 TST"), net_weight * .2, cpu_weight * .2); // Start decay t.produce_block(fc::days(15) - fc::milliseconds(1000)); From b728e01965e9e6b2e3307a0e5b10b1b09778652c Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 16:24:37 -0500 Subject: [PATCH 0987/1048] fix name of configrentbw action wrapper type --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 4ff4bc1d..764174a1 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -1288,7 +1288,7 @@ namespace eosiosystem { using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; - using configcpu_action = eosio::action_wrapper<"configrentbw"_n, &system_contract::configrentbw>; + using configrentbw_action = eosio::action_wrapper<"configrentbw"_n, &system_contract::configrentbw>; using rentbwexec_action = eosio::action_wrapper<"rentbwexec"_n, &system_contract::rentbwexec>; using rentbw_action = eosio::action_wrapper<"rentbw"_n, &system_contract::rentbw>; From 826a6cd6fc2a4b7cf8256ea44a79061021d171e1 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 17:35:20 -0500 Subject: [PATCH 0988/1048] add default values for rent_days, decay_secs, and exponent --- .../include/eosio.system/eosio.system.hpp | 64 +++++++++++-------- tests/eosio.rentbw_tests.cpp | 12 ++-- 2 files changed, 44 insertions(+), 32 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 764174a1..89e428a8 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -40,7 +40,7 @@ namespace eosiosystem { using eosio::time_point_sec; using eosio::unsigned_int; - inline constexpr int64_t rentbw_frac = 1000000000000000ll; // 1.0 = 10^15 + inline constexpr int64_t rentbw_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 template static inline auto has_field( F flags, E field ) @@ -496,36 +496,48 @@ namespace eosiosystem { }; struct rentbw_state_resource { + static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to rent a + // tiny amount of resources increases linearly + // with utilization. + static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a + // single loan, then, assuming no further renting, + // 1 day after it expires the adjusted utilization + // will be at approximately 37% and after 3 days the + // adjusted utilization will be at least than 5%. + + uint8_t version = 0; - int64_t weight = 0; // resource market weight. calculated; varies over time. - // 1 represents the same amount of resources as 1 - // satoshi of SYS staked. - int64_t weight_ratio = 0; // resource market weight ratio: - // assumed_stake_weight / (assumed_stake_weight + weight). - // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. - int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. - int64_t initial_weight_ratio = rentbw_frac; // Initial weight_ratio used for linear shrinkage. - int64_t target_weight_ratio = rentbw_frac / 100; // Linearly shrink the weight_ratio to this amount. - time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started - time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this - // time hits, weight_ratio will be target_weight_ratio. - double exponent = 0; // Exponent of resource price curve. - uint32_t decay_secs = 0; // Number of seconds for the gap between adjusted resource - // utilization and instantaneous utilization to shrink by 63%. - asset target_price = {}; // Fee needed to rent the entire resource market weight. - int64_t utilization = 0; // Instantaneous resource utilization. This is the current - // amount sold. utilization <= weight. - int64_t adjusted_utilization = 0; // Adjusted resource utilization. This is >= utilization and - // <= weight. It grows instantly but decays exponentially. - time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated + int64_t weight = 0; // resource market weight. calculated; varies over time. + // 1 represents the same amount of resources as 1 + // satoshi of SYS staked. + int64_t weight_ratio = 0; // resource market weight ratio: + // assumed_stake_weight / (assumed_stake_weight + weight). + // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. + int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. + int64_t initial_weight_ratio = rentbw_frac; // Initial weight_ratio used for linear shrinkage. + int64_t target_weight_ratio = rentbw_frac / 100; // Linearly shrink the weight_ratio to this amount. + time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started + time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this + // time hits, weight_ratio will be target_weight_ratio. + double exponent = default_exponent; // Exponent of resource price curve. + uint32_t decay_secs = default_decay_secs; // Number of seconds for the gap between adjusted resource + // utilization and instantaneous utilization to shrink by 63%. + asset target_price = {}; // Fee needed to rent the entire resource market weight. + int64_t utilization = 0; // Instantaneous resource utilization. This is the current + // amount sold. utilization <= weight. + int64_t adjusted_utilization = 0; // Adjusted resource utilization. This is >= utilization and + // <= weight. It grows instantly but decays exponentially. + time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated }; struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { + static constexpr uint32_t default_rent_days = 30 * seconds_per_day; // 30 day resource rentals + uint8_t version = 0; - rentbw_state_resource net = {}; // NET market state - rentbw_state_resource cpu = {}; // CPU market state - uint32_t rent_days = 0; // `rentbw` `days` argument must match this. - asset min_rent_price = {}; // Rents below this amount are rejected + rentbw_state_resource net = {}; // NET market state + rentbw_state_resource cpu = {}; // CPU market state + uint32_t rent_days = default_rent_days; // `rentbw` `days` argument must match this. + asset min_rent_price = {}; // Rents below this amount are rejected uint64_t primary_key()const { return 0; } }; diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index b05120a9..d04c8102 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -226,8 +226,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { push_action(N(alice1111111), N(configrentbw), mvo()("args", make_config()))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("rentbw hasn't been initialized"), rentbwexec(N(alice1111111), 10)); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), - configbw(make_config([&](auto& c) { c.rent_days = 0; }))); + //BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), + // configbw(make_config([&](auto& c) { c.rent_days = 0; }))); // needed only if rent_days does not have default BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("1000000.000 TST"); }))); @@ -255,8 +255,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), configbw(make_config([&](auto& c) { c.net.exponent = .999; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); + //BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), + // configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); // needed only if decay_secs does not have default BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("1000000.000 TST"); }))); @@ -284,8 +284,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), configbw(make_config([&](auto& c) { c.cpu.exponent = .999; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); + //BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), + // configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); // needed only if decay_secs does not have default BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("1000000.000 TST"); }))); From 0194167262a5039a77b2271b7a7b81639e2929bc Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 18:47:03 -0500 Subject: [PATCH 0989/1048] add default values for min_rent_price and target_price as well --- .../include/eosio.system/eosio.system.hpp | 23 +++++++++++-------- contracts/eosio.system/src/rentbw.cpp | 16 +++++++++---- tests/eosio.rentbw_tests.cpp | 12 +++++----- 3 files changed, 31 insertions(+), 20 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 89e428a8..7e646718 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -496,15 +496,16 @@ namespace eosiosystem { }; struct rentbw_state_resource { - static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to rent a - // tiny amount of resources increases linearly - // with utilization. - static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a - // single loan, then, assuming no further renting, - // 1 day after it expires the adjusted utilization - // will be at approximately 37% and after 3 days the - // adjusted utilization will be at least than 5%. - + static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to rent a + // tiny amount of resources increases linearly + // with utilization. + static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a + // single loan, then, assuming no further renting, + // 1 day after it expires the adjusted utilization + // will be at approximately 37% and after 3 days the + // adjusted utilization will be at least than 5%. + static constexpr int64_t default_target_price = 100'000'000'0000ll; // 100000000.0000 SYS + // (assuming get_core_symbol() == symbol("SYS", 4)); uint8_t version = 0; int64_t weight = 0; // resource market weight. calculated; varies over time. @@ -531,7 +532,9 @@ namespace eosiosystem { }; struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { - static constexpr uint32_t default_rent_days = 30 * seconds_per_day; // 30 day resource rentals + static constexpr uint32_t default_rent_days = 30 * seconds_per_day; // 30 day resource rentals + static constexpr int64_t default_min_rent_price = 100ll; // 0.0100 SYS + // (assuming get_core_symbol() == symbol("SYS", 4)) uint8_t version = 0; rentbw_state_resource net = {}; // NET market state diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index cb94c98d..02d70fc1 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -153,8 +153,12 @@ void system_contract::configrentbw(rentbw_config& args) { args.exponent = state.exponent; if (!args.decay_secs) args.decay_secs = state.decay_secs; - if (!args.target_price.amount && state.target_price.amount) - args.target_price = state.target_price; + if (!args.target_price.amount) { + if (state.target_price.amount) + args.target_price = state.target_price; + else + args.target_price.amount = rentbw_state_resource::default_target_price; + } if (args.current_weight_ratio == args.target_weight_ratio) args.target_timestamp = now; @@ -186,8 +190,12 @@ void system_contract::configrentbw(rentbw_config& args) { if (!args.rent_days) args.rent_days = state.rent_days; - if (!args.min_rent_price.amount && state.min_rent_price.amount) - args.min_rent_price = state.min_rent_price; + if (!args.min_rent_price.amount) { + if (state.min_rent_price.amount) + args.min_rent_price = state.min_rent_price; + else + args.min_rent_price.amount = rentbw_state::default_min_rent_price; + } eosio::check(args.rent_days > 0, "rent_days must be > 0"); eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index d04c8102..8d982b4e 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -231,8 +231,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("1000000.000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), - configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("0.0000 TST"); }))); + //BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), + // configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("0.0000 TST"); }))); // needed only if min_rent_price does not have default BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("-1.0000 TST"); }))); @@ -260,8 +260,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("1000000.000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("0.0000 TST"); }))); + //BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + // configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("0.0000 TST"); }))); // needed only if target_price does not have default BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("-1.0000 TST"); }))); @@ -289,8 +289,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("1000000.000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); + //BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + // configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); // needed only if target_price does not have default BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("-1.0000 TST"); }))); } // config_tests From abb52c323a3e4bc646477f50acc9a4c5d6247ec9 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 18:52:33 -0500 Subject: [PATCH 0990/1048] fix wrong default value for rent_days --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 7e646718..c07aa274 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -532,9 +532,8 @@ namespace eosiosystem { }; struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { - static constexpr uint32_t default_rent_days = 30 * seconds_per_day; // 30 day resource rentals - static constexpr int64_t default_min_rent_price = 100ll; // 0.0100 SYS - // (assuming get_core_symbol() == symbol("SYS", 4)) + static constexpr uint32_t default_rent_days = 30; // 30 day resource rentals + static constexpr int64_t default_min_rent_price = 100ll; // 0.0100 SYS (assuming get_core_symbol() == symbol("SYS", 4)) uint8_t version = 0; rentbw_state_resource net = {}; // NET market state From 8328052ada7db9c7f7dd137e0bdb8645b14f5306 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 19:46:33 -0500 Subject: [PATCH 0991/1048] fix comment --- .../eosio.system/include/eosio.system/eosio.system.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index c07aa274..81f5c0c7 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -502,10 +502,10 @@ namespace eosiosystem { static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a // single loan, then, assuming no further renting, // 1 day after it expires the adjusted utilization - // will be at approximately 37% and after 3 days the - // adjusted utilization will be at least than 5%. + // will be at approximately 37% and after 3 days + // the adjusted utilization will be less than 5%. static constexpr int64_t default_target_price = 100'000'000'0000ll; // 100000000.0000 SYS - // (assuming get_core_symbol() == symbol("SYS", 4)); + // (assuming get_core_symbol() == symbol("SYS", 4)) uint8_t version = 0; int64_t weight = 0; // resource market weight. calculated; varies over time. From ae8230d980a7ad9f1fc8a48c186531190f1a9dde Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 19:58:01 -0500 Subject: [PATCH 0992/1048] fix comment description of some configuration options --- .../include/eosio.system/eosio.system.hpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 81f5c0c7..bb5d7903 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -478,21 +478,21 @@ namespace eosiosystem { // current_weight_ratio == target_weight_ratio. Set this to 0 to preserve the // existing setting. double exponent; // Exponent of resource price curve. Must be >= 1. Set this to 0 to preserve the - // existing setting. + // existing setting or use the default. uint32_t decay_secs; // Number of seconds for the gap between adjusted resource utilization and // instantaneous utilization to shrink by 63%. Set this to 0 to preserve the - // existing setting. - asset target_price; // Fee needed to rent the entire resource market weight. Set this to 0 to - // preserve the existing setting. + // existing setting or use the default. + asset target_price; // Fee needed to rent the entire resource market weight. Set the amount of this + // asset to 0 to preserve the existing setting or use the default. }; struct rentbw_config { rentbw_config_resource net; // NET market configuration rentbw_config_resource cpu; // CPU market configuration uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the - // existing setting. - asset min_rent_price; // Rents below this amount are rejected. Set this to 0 to preserve the - // existing setting. + // existing setting or use the default. + asset min_rent_price; // Rents below this amount are rejected. Set the amount of this asset to 0 to + // preserve the existing setting or use the default. }; struct rentbw_state_resource { From 92362d8b4dc8b7ea15a52b3eef0e9bfb9fb8eff3 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 18 Dec 2019 20:31:09 -0500 Subject: [PATCH 0993/1048] remove defaults for min_rent_price and target_price since values that are resonable dependent heavily on the attributes of the core token --- .../include/eosio.system/eosio.system.hpp | 7 ++----- contracts/eosio.system/src/rentbw.cpp | 16 ++++------------ tests/eosio.rentbw_tests.cpp | 14 +++++++------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index bb5d7903..9d5ded4b 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -483,7 +483,7 @@ namespace eosiosystem { // instantaneous utilization to shrink by 63%. Set this to 0 to preserve the // existing setting or use the default. asset target_price; // Fee needed to rent the entire resource market weight. Set the amount of this - // asset to 0 to preserve the existing setting or use the default. + // asset to 0 to preserve the existing setting. }; struct rentbw_config { @@ -492,7 +492,7 @@ namespace eosiosystem { uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the // existing setting or use the default. asset min_rent_price; // Rents below this amount are rejected. Set the amount of this asset to 0 to - // preserve the existing setting or use the default. + // preserve the existing setting. }; struct rentbw_state_resource { @@ -504,8 +504,6 @@ namespace eosiosystem { // 1 day after it expires the adjusted utilization // will be at approximately 37% and after 3 days // the adjusted utilization will be less than 5%. - static constexpr int64_t default_target_price = 100'000'000'0000ll; // 100000000.0000 SYS - // (assuming get_core_symbol() == symbol("SYS", 4)) uint8_t version = 0; int64_t weight = 0; // resource market weight. calculated; varies over time. @@ -533,7 +531,6 @@ namespace eosiosystem { struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { static constexpr uint32_t default_rent_days = 30; // 30 day resource rentals - static constexpr int64_t default_min_rent_price = 100ll; // 0.0100 SYS (assuming get_core_symbol() == symbol("SYS", 4)) uint8_t version = 0; rentbw_state_resource net = {}; // NET market state diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 02d70fc1..cb94c98d 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -153,12 +153,8 @@ void system_contract::configrentbw(rentbw_config& args) { args.exponent = state.exponent; if (!args.decay_secs) args.decay_secs = state.decay_secs; - if (!args.target_price.amount) { - if (state.target_price.amount) - args.target_price = state.target_price; - else - args.target_price.amount = rentbw_state_resource::default_target_price; - } + if (!args.target_price.amount && state.target_price.amount) + args.target_price = state.target_price; if (args.current_weight_ratio == args.target_weight_ratio) args.target_timestamp = now; @@ -190,12 +186,8 @@ void system_contract::configrentbw(rentbw_config& args) { if (!args.rent_days) args.rent_days = state.rent_days; - if (!args.min_rent_price.amount) { - if (state.min_rent_price.amount) - args.min_rent_price = state.min_rent_price; - else - args.min_rent_price.amount = rentbw_state::default_min_rent_price; - } + if (!args.min_rent_price.amount && state.min_rent_price.amount) + args.min_rent_price = state.min_rent_price; eosio::check(args.rent_days > 0, "rent_days must be > 0"); eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 8d982b4e..9ca41b56 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -12,7 +12,7 @@ #include "eosio.system_tester.hpp" -inline constexpr int64_t rentbw_frac = 1000000000000000ll; // 1.0 = 10^15 +inline constexpr int64_t rentbw_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 inline constexpr int64_t stake_weight = 100'000'000'0000ll; // 10^12 struct rentbw_config_resource { @@ -231,8 +231,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("1000000.000 TST"); }))); - //BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), - // configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("0.0000 TST"); }))); // needed only if min_rent_price does not have default + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), + configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("0.0000 TST"); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("-1.0000 TST"); }))); @@ -260,8 +260,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("1000000.000 TST"); }))); - //BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - // configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("0.0000 TST"); }))); // needed only if target_price does not have default + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("0.0000 TST"); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("-1.0000 TST"); }))); @@ -289,8 +289,8 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("1000000.000 TST"); }))); - //BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - // configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); // needed only if target_price does not have default + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), + configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("-1.0000 TST"); }))); } // config_tests From 5fc0dac07ec150248b8e2c964fbbbe0382c4fb51 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 19 Dec 2019 13:29:51 -0500 Subject: [PATCH 0994/1048] modify fee calculation to not give advantage to very small rentals even under the scenario of utilization <= adjusted_utilization --- contracts/eosio.system/src/rentbw.cpp | 49 ++++++++++++++++++++++++--- tests/eosio.rentbw_tests.cpp | 20 +++++------ 2 files changed, 55 insertions(+), 14 deletions(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index cb94c98d..cacd5e53 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -210,12 +210,53 @@ void system_contract::configrentbw(rentbw_config& args) { state_sing.set(state, get_self()); } // system_contract::configrentbw +/** + * @pre 0 < state.target_price.amount + * @pre 1.0 <= state.exponent + * @pre 0 <= state.utilization <= state.adjusted_utilization <= state.weight + * @pre 0 <= utilization_increase <= (state.weight - state.utilization) + */ int64_t calc_rentbw_fee(const rentbw_state_resource& state, int64_t utilization_increase) { - double start_utilization = state.adjusted_utilization; - double end_utilization = state.adjusted_utilization + utilization_increase; + if( utilization_increase <= 0 ) return 0; + + // Let p(u) = price as a function of the utilization fraction u which is defined for u in [0.0, 1.0]. + // Let f(u) = integral of the price function p(x) from x = 0.0 to x = u, again defined for u in [0.0, 1.0]. + + // Returns f(double(end_utilization)/state.weight) - f(double(start_utilization)/state.weight) which is equivalent to + // the integral of p(x) from x = double(start_utilization)/state.weight to x = double(end_utilization)/state.weight. + // @pre 0 <= start_utilization <= end_utilization <= state.weight + auto price_integral_delta = [&state](int64_t start_utilization, int64_t end_utilization) -> double { + return state.target_price.amount * std::pow(double(end_utilization) / state.weight, state.exponent) - + state.target_price.amount * std::pow(double(start_utilization) / state.weight, state.exponent); + }; + + // Returns p(double(utilization)/state.weight). + // @pre 0 <= utilization <= state.weight + auto price_function = [&state](int64_t utilization) -> double { + // state.exponent >= 1.0, therefore the exponent passed into std::pow is >= 0.0. + // Since the exponent passed into std::pow could be 0.0 and simultaneously so could double(utilization)/state.weight, + // the safest thing to do is handle that as a special case explicitly rather than relying on std::pow to return 1.0 + // instead of triggering a domain error. + double new_exponent = state.exponent - 1.0; + if (new_exponent <= 0.0) + return state.target_price.amount; + else + return state.exponent * state.target_price.amount * std::pow(double(utilization) / state.weight, new_exponent); + }; + + double fee = 0.0; + int64_t start_utilization = state.utilization; + int64_t end_utilization = start_utilization + utilization_increase; - double fee = state.target_price.amount * std::pow(end_utilization / state.weight, state.exponent) - - state.target_price.amount * std::pow(start_utilization / state.weight, state.exponent); + if (start_utilization < state.adjusted_utilization) { + fee += price_function(state.adjusted_utilization) * + std::min(utilization_increase, state.adjusted_utilization - start_utilization) / state.weight; + start_utilization = state.adjusted_utilization; + } + + if (start_utilization < end_utilization) { + fee += price_integral_delta(start_utilization, end_utilization); + } return std::ceil(fee); } diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 9ca41b56..23f3fb9a 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -602,12 +602,12 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // immediate renewal: adjusted_utilization doesn't have time to fall // - // (2.0 ^ 2) * 1000000.0000 - 1000000.0000 = 3000000.0000 - // (2.0 ^ 3) * 2000000.0000 - 2000000.0000 = 14000000.0000 - // total = 17000000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("17000000.0000")); + // 2 * (1.0 ^ 1) * 1000000.0000 = 2000000.0000 + // 3 * (1.0 ^ 2) * 2000000.0000 = 6000000.0000 + // total = 8000000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("8000000.0000")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, - asset::from_string("17000000.0000 TST"), 0, 0); + asset::from_string("8000000.0000 TST"), 0, 0); // No more available for 30 days BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // @@ -647,12 +647,12 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // 100% after 2 days of decay // - // [((e^-2 + 1.0) ^ 2) - ((e^-2) ^ 2) ] * 1000000.0000 = 1270670.5664 - // [((e^-2 + 1.0) ^ 3) - ((e^-2) ^ 3) ] * 2000000.0000 = 2921905.5327 - // total = 4192576.0991 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("4192561.0246")); + // [ [2 * ((e^-2) ^ 1)]*(e^-2 - 0.0) + ((1.0) ^ 2) - ((e^-2) ^ 2) ] * 1000000.0000 = 1018315.6389 + // [ [3 * ((e^-2) ^ 2)]*(e^-2 - 0.0) + ((1.0) ^ 3) - ((e^-2) ^ 3) ] * 2000000.0000 = 2009915.0087 + // total = 3028230.6476 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3028229.8795")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, - asset::from_string("4192561.0246 TST"), net_weight, cpu_weight); + asset::from_string("3028229.8795 TST"), net_weight, cpu_weight); } { From 49c6b09d8657d6d1b8cdc83a5e1077eff6c01615 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 19 Dec 2019 13:37:21 -0500 Subject: [PATCH 0995/1048] rename min_rent_price to min_rent_fee --- .../include/eosio.system/eosio.system.hpp | 24 ++++++------ contracts/eosio.system/src/rentbw.cpp | 14 +++---- tests/eosio.rentbw_tests.cpp | 38 +++++++++---------- 3 files changed, 38 insertions(+), 38 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 9d5ded4b..f61c746a 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -487,12 +487,12 @@ namespace eosiosystem { }; struct rentbw_config { - rentbw_config_resource net; // NET market configuration - rentbw_config_resource cpu; // CPU market configuration - uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the - // existing setting or use the default. - asset min_rent_price; // Rents below this amount are rejected. Set the amount of this asset to 0 to - // preserve the existing setting. + rentbw_config_resource net; // NET market configuration + rentbw_config_resource cpu; // CPU market configuration + uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the + // existing setting or use the default. + asset min_rent_fee; // Rental fees below this amount are rejected. Set the amount of this asset to 0 + // to preserve the existing setting. }; struct rentbw_state_resource { @@ -530,13 +530,13 @@ namespace eosiosystem { }; struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { - static constexpr uint32_t default_rent_days = 30; // 30 day resource rentals + static constexpr uint32_t default_rent_days = 30; // 30 day resource rentals - uint8_t version = 0; - rentbw_state_resource net = {}; // NET market state - rentbw_state_resource cpu = {}; // CPU market state - uint32_t rent_days = default_rent_days; // `rentbw` `days` argument must match this. - asset min_rent_price = {}; // Rents below this amount are rejected + uint8_t version = 0; + rentbw_state_resource net = {}; // NET market state + rentbw_state_resource cpu = {}; // CPU market state + uint32_t rent_days = default_rent_days; // `rentbw` `days` argument must match this. + asset min_rent_fee = {}; // Rental fees below this amount are rejected uint64_t primary_key()const { return 0; } }; diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index cacd5e53..6add2ee7 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -186,15 +186,15 @@ void system_contract::configrentbw(rentbw_config& args) { if (!args.rent_days) args.rent_days = state.rent_days; - if (!args.min_rent_price.amount && state.min_rent_price.amount) - args.min_rent_price = state.min_rent_price; + if (!args.min_rent_fee.amount && state.min_rent_fee.amount) + args.min_rent_fee = state.min_rent_fee; eosio::check(args.rent_days > 0, "rent_days must be > 0"); - eosio::check(args.min_rent_price.symbol == core_symbol, "min_rent_price doesn't match core symbol"); - eosio::check(args.min_rent_price.amount > 0, "min_rent_price must be positive"); + eosio::check(args.min_rent_fee.symbol == core_symbol, "min_rent_fee doesn't match core symbol"); + eosio::check(args.min_rent_fee.amount > 0, "min_rent_fee must be positive"); - state.rent_days = args.rent_days; - state.min_rent_price = args.min_rent_price; + state.rent_days = args.rent_days; + state.min_rent_fee = args.min_rent_fee; update(state.net, args.net); update(state.cpu, args.cpu); @@ -320,7 +320,7 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d error_msg += fee.to_string(); eosio::check(false, error_msg); } - eosio::check(fee >= state.min_rent_price, "calculated fee is below minimum; try renting more"); + eosio::check(fee >= state.min_rent_fee, "calculated fee is below minimum; try renting more"); orders.emplace(payer, [&](auto& order) { order.id = orders.available_primary_key(); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 23f3fb9a..d1d0f98c 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -29,12 +29,12 @@ FC_REFLECT(rentbw_config_resource, (exponent)(decay_secs)(target_price)) struct rentbw_config { - rentbw_config_resource net = {}; - rentbw_config_resource cpu = {}; - uint32_t rent_days = {}; - asset min_rent_price = asset{}; + rentbw_config_resource net = {}; + rentbw_config_resource cpu = {}; + uint32_t rent_days = {}; + asset min_rent_fee = asset{}; }; -FC_REFLECT(rentbw_config, (net)(cpu)(rent_days)(min_rent_price)) +FC_REFLECT(rentbw_config, (net)(cpu)(rent_days)(min_rent_fee)) struct rentbw_state_resource { uint8_t version; @@ -62,9 +62,9 @@ struct rentbw_state { rentbw_state_resource net; rentbw_state_resource cpu; uint32_t rent_days; - asset min_rent_price; + asset min_rent_fee; }; -FC_REFLECT(rentbw_state, (version)(net)(cpu)(rent_days)(min_rent_price)) +FC_REFLECT(rentbw_state, (version)(net)(cpu)(rent_days)(min_rent_fee)) using namespace eosio_system; @@ -109,8 +109,8 @@ struct rentbw_tester : eosio_system_tester { config.cpu.decay_secs = fc::days(1).to_seconds(); config.cpu.target_price = asset::from_string("1000000.0000 TST"); - config.rent_days = 30; - config.min_rent_price = asset::from_string("1.0000 TST"); + config.rent_days = 30; + config.min_rent_fee = asset::from_string("1.0000 TST"); f(config); return config; @@ -228,13 +228,13 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { //BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), // configbw(make_config([&](auto& c) { c.rent_days = 0; }))); // needed only if rent_days does not have default - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.min_rent_price = asset::from_string("1000000.000 TST"); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.min_rent_fee = asset::from_string("1000000.000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), - configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_price must be positive"), - configbw(make_config([&](auto& c) { c.min_rent_price = asset::from_string("-1.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee must be positive"), + configbw(make_config([&](auto& c) { c.min_rent_fee = asset::from_string("0.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee must be positive"), + configbw(make_config([&](auto& c) { c.min_rent_fee = asset::from_string("-1.0000 TST"); }))); // net assertions BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), @@ -445,8 +445,8 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { config.cpu.exponent = 1; config.cpu.target_price = asset::from_string("1000000.0000 TST"); - config.rent_days = 30; - config.min_rent_price = asset::from_string("1.0000 TST"); + config.rent_days = 30; + config.min_rent_fee = asset::from_string("1.0000 TST"); }))); BOOST_REQUIRE_EQUAL( @@ -477,8 +477,8 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { config.cpu.exponent = 3; config.cpu.target_price = asset::from_string("2000000.0000 TST"); - config.rent_days = 30; - config.min_rent_price = asset::from_string("1.0000 TST"); + config.rent_days = 30; + config.min_rent_fee = asset::from_string("1.0000 TST"); }))); if (rex) From 58fb95fff6827749501f51e81da4344c2e697383 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 19 Dec 2019 17:25:54 -0500 Subject: [PATCH 0996/1048] use optionals rather than 0 for config parameters to signal that it should preserve the existing value (or use default when appropriate) --- .../include/eosio.system/eosio.system.hpp | 59 +++++---- contracts/eosio.system/src/rentbw.cpp | 121 +++++++++++------- tests/eosio.rentbw_tests.cpp | 74 ++++++++--- 3 files changed, 164 insertions(+), 90 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index f61c746a..b8abe590 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -461,38 +461,45 @@ namespace eosiosystem { }; struct rentbw_config_resource { - int64_t current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. Set this - // to 0 to preserve the existing setting or use the default; this avoids sudden - // price jumps. For new chains which don't need to gradually phase out staking - // and REX, 0.01x (10^13) is a good value for both current_weight_ratio and - // target_weight_ratio. - int64_t target_weight_ratio; // Linearly shrink weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. Set this - // to 0 to preserve the existing setting or use the default. - int64_t assumed_stake_weight; // Assumed stake weight for ratio calculations. Use the sum of total staked and - // total rented by REX at the time the rentbw market is first activated. Set - // this to 0 to preserve the existing setting; this avoids sudden price jumps. - // For new chains which don't need to phase out staking and REX, 10^12 is - // probably a good value. - time_point_sec target_timestamp; // Stop automatic weight_ratio shrinkage at this time. Once this - // time hits, weight_ratio will be target_weight_ratio. Ignored if - // current_weight_ratio == target_weight_ratio. Set this to 0 to preserve the - // existing setting. - double exponent; // Exponent of resource price curve. Must be >= 1. Set this to 0 to preserve the - // existing setting or use the default. - uint32_t decay_secs; // Number of seconds for the gap between adjusted resource utilization and - // instantaneous utilization to shrink by 63%. Set this to 0 to preserve the - // existing setting or use the default. - asset target_price; // Fee needed to rent the entire resource market weight. Set the amount of this - // asset to 0 to preserve the existing setting. + std::optional current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. + // Do not specify to preserve the existing setting or use the default; + // this avoids sudden price jumps. For new chains which don't need + // to gradually phase out staking and REX, 0.01x (10^13) is a good + // value for both current_weight_ratio and target_weight_ratio. + std::optional target_weight_ratio; // Linearly shrink weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. + // Do not specify to preserve the existing setting or use the default. + std::optional assumed_stake_weight; // Assumed stake weight for ratio calculations. Use the sum of total + // staked and total rented by REX at the time the rentbw market + // is first activated. Do not specify to preserve the existing + // setting (no default exists); this avoids sudden price jumps. + // For new chains which don't need to phase out staking and REX, + // 10^12 is probably a good value. + std::optional target_timestamp; // Stop automatic weight_ratio shrinkage at this time. Once this + // time hits, weight_ratio will be target_weight_ratio. Ignored + // if current_weight_ratio == target_weight_ratio. Do not specify + // this to preserve the existing setting (no default exists). + std::optional exponent; // Exponent of resource price curve. Must be >= 1. Do not specify + // to preserve the existing setting or use the default. + std::optional decay_secs; // Number of seconds for the gap between adjusted resource + // utilization and instantaneous resource utilization to shrink + // by 63%. Do not specify to preserve the existing setting or + // use the default. + std::optional target_price; // Fee needed to rent the entire resource market weight. Do not + // specify to preserve the existing setting (no default exists). + + EOSLIB_SERIALIZE( rentbw_config_resource, (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight) + (target_timestamp)(exponent)(decay_secs)(target_price) ) }; struct rentbw_config { rentbw_config_resource net; // NET market configuration rentbw_config_resource cpu; // CPU market configuration - uint32_t rent_days; // `rentbw` `days` argument must match this. Set this to 0 to preserve the + std::optional rent_days; // `rentbw` `days` argument must match this. Do not specify to preserve the // existing setting or use the default. - asset min_rent_fee; // Rental fees below this amount are rejected. Set the amount of this asset to 0 - // to preserve the existing setting. + std::optional min_rent_fee; // Rental fees below this amount are rejected. Do not specify to preserve the + // existing setting (no default exists). + + EOSLIB_SERIALIZE( rentbw_config, (net)(cpu)(rent_days)(min_rent_fee) ) }; struct rentbw_state_resource { diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 6add2ee7..98513d96 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -136,65 +136,90 @@ void system_contract::configrentbw(rentbw_config& args) { state.cpu.utilization_timestamp = now; } + auto is_default_asset = []( const eosio::asset& a ) -> bool { + return a.amount == 0 && a.symbol == symbol{}; + }; + auto update = [&](auto& state, auto& args) { if (!args.current_weight_ratio) { - if (state.weight_ratio) - args.current_weight_ratio = state.weight_ratio; - else - args.current_weight_ratio = state.initial_weight_ratio; + if (state.weight_ratio) { + *args.current_weight_ratio = state.weight_ratio; + } else { + *args.current_weight_ratio = state.initial_weight_ratio; + } } - if (!args.target_weight_ratio) - args.target_weight_ratio = state.target_weight_ratio; - if (!args.assumed_stake_weight) - args.assumed_stake_weight = state.assumed_stake_weight; - if (!args.target_timestamp.utc_seconds) - args.target_timestamp = state.target_timestamp; - if (!args.exponent) - args.exponent = state.exponent; - if (!args.decay_secs) - args.decay_secs = state.decay_secs; - if (!args.target_price.amount && state.target_price.amount) - args.target_price = state.target_price; - - if (args.current_weight_ratio == args.target_weight_ratio) - args.target_timestamp = now; - else - eosio::check(args.target_timestamp > now, "target_timestamp must be in the future"); - eosio::check(args.current_weight_ratio > 0, "current_weight_ratio is too small"); - eosio::check(args.current_weight_ratio <= rentbw_frac, "current_weight_ratio is too large"); - eosio::check(args.target_weight_ratio > 0, "target_weight_ratio is too small"); - eosio::check(args.target_weight_ratio <= args.current_weight_ratio, "weight can't grow over time"); - eosio::check(args.assumed_stake_weight >= 1, + + if (!args.target_weight_ratio) { + *args.target_weight_ratio = state.target_weight_ratio; + } + + if (!args.assumed_stake_weight) { + eosio::check(state.assumed_stake_weight != 0, "assumed_stake_weight does not have a default value"); + *args.assumed_stake_weight = state.assumed_stake_weight; + } + + if (*args.current_weight_ratio == *args.target_weight_ratio) { + *args.target_timestamp = now; + } else { + if (!args.target_timestamp) { + eosio::check(state.target_timestamp.utc_seconds != 0, "target_timestamp does not have a default value"); + *args.target_timestamp = state.target_timestamp; + } + eosio::check(*args.target_timestamp > now, "target_timestamp must be in the future"); + } + + if (!args.exponent) { + *args.exponent = state.exponent; + } + + if (!args.decay_secs) { + *args.decay_secs = state.decay_secs; + } + + if (!args.target_price) { + eosio::check(!is_default_asset(state.target_price), "target_price does not have a default value"); + *args.target_price = state.target_price; + } + + eosio::check(*args.current_weight_ratio > 0, "current_weight_ratio is too small"); + eosio::check(*args.current_weight_ratio <= rentbw_frac, "current_weight_ratio is too large"); + eosio::check(*args.target_weight_ratio > 0, "target_weight_ratio is too small"); + eosio::check(*args.target_weight_ratio <= *args.current_weight_ratio, "weight can't grow over time"); + eosio::check(*args.assumed_stake_weight >= 1, "assumed_stake_weight must be at least 1; a much larger value is recommended"); - eosio::check(args.assumed_stake_weight * int128_t(rentbw_frac) / args.target_weight_ratio <= + eosio::check(*args.assumed_stake_weight * int128_t(rentbw_frac) / *args.target_weight_ratio <= std::numeric_limits::max(), "assumed_stake_weight/target_weight_ratio is too large"); - eosio::check(args.exponent >= 1, "exponent must be >= 1"); - eosio::check(args.decay_secs >= 1, "decay_secs must be >= 1"); - eosio::check(args.target_price.symbol == core_symbol, "target_price doesn't match core symbol"); - eosio::check(args.target_price.amount > 0, "target_price must be positive"); - - state.assumed_stake_weight = args.assumed_stake_weight; - state.initial_weight_ratio = args.current_weight_ratio; - state.target_weight_ratio = args.target_weight_ratio; + eosio::check(*args.exponent >= 1, "exponent must be >= 1"); + eosio::check(*args.decay_secs >= 1, "decay_secs must be >= 1"); + eosio::check(args.target_price->symbol == core_symbol, "target_price doesn't match core symbol"); + eosio::check(args.target_price->amount > 0, "target_price must be positive"); + + state.assumed_stake_weight = *args.assumed_stake_weight; + state.initial_weight_ratio = *args.current_weight_ratio; + state.target_weight_ratio = *args.target_weight_ratio; state.initial_timestamp = now; - state.target_timestamp = args.target_timestamp; - state.exponent = args.exponent; - state.decay_secs = args.decay_secs; - state.target_price = args.target_price; + state.target_timestamp = *args.target_timestamp; + state.exponent = *args.exponent; + state.decay_secs = *args.decay_secs; + state.target_price = *args.target_price; }; - if (!args.rent_days) - args.rent_days = state.rent_days; - if (!args.min_rent_fee.amount && state.min_rent_fee.amount) - args.min_rent_fee = state.min_rent_fee; + if (!args.rent_days) { + *args.rent_days = state.rent_days; + } + + if (!args.min_rent_fee) { + eosio::check(!is_default_asset(state.min_rent_fee), "min_rent_fee does not have a default value"); + *args.min_rent_fee = state.min_rent_fee; + } - eosio::check(args.rent_days > 0, "rent_days must be > 0"); - eosio::check(args.min_rent_fee.symbol == core_symbol, "min_rent_fee doesn't match core symbol"); - eosio::check(args.min_rent_fee.amount > 0, "min_rent_fee must be positive"); + eosio::check(*args.rent_days > 0, "rent_days must be > 0"); + eosio::check(args.min_rent_fee->symbol == core_symbol, "min_rent_fee doesn't match core symbol"); + eosio::check(args.min_rent_fee->amount > 0, "min_rent_fee must be positive"); - state.rent_days = args.rent_days; - state.min_rent_fee = args.min_rent_fee; + state.rent_days = *args.rent_days; + state.min_rent_fee = *args.min_rent_fee; update(state.net, args.net); update(state.cpu, args.cpu); diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index d1d0f98c..1bef8815 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -16,13 +16,13 @@ inline constexpr int64_t rentbw_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 inline constexpr int64_t stake_weight = 100'000'000'0000ll; // 10^12 struct rentbw_config_resource { - int64_t current_weight_ratio = {}; - int64_t target_weight_ratio = {}; - int64_t assumed_stake_weight = {}; - time_point_sec target_timestamp = {}; - double exponent = {}; - uint32_t decay_secs = {}; - asset target_price = asset{}; + fc::optional current_weight_ratio = {}; + fc::optional target_weight_ratio = {}; + fc::optional assumed_stake_weight = {}; + fc::optional target_timestamp = {}; + fc::optional exponent = {}; + fc::optional decay_secs = {}; + fc::optional target_price = {}; }; FC_REFLECT(rentbw_config_resource, // (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight)(target_timestamp) // @@ -31,8 +31,8 @@ FC_REFLECT(rentbw_config_resource, struct rentbw_config { rentbw_config_resource net = {}; rentbw_config_resource cpu = {}; - uint32_t rent_days = {}; - asset min_rent_fee = asset{}; + fc::optional rent_days = {}; + fc::optional min_rent_fee = {}; }; FC_REFLECT(rentbw_config, (net)(cpu)(rent_days)(min_rent_fee)) @@ -128,7 +128,35 @@ struct rentbw_tester : eosio_system_tester { } action_result configbw(const rentbw_config& config) { - return push_action(config::system_account_name, N(configrentbw), mvo()("args", config)); + // Verbose solution needed to work around bug in abi_serializer that fails if optional values aren't explicitly + // specified with a null value. + + auto optional_to_variant = []( const auto& v ) -> fc::variant { + return (!v ? fc::variant() : fc::variant(*v)); + }; + + auto resource_conf_vo = [&optional_to_variant](const rentbw_config_resource& c ) { + return mvo("current_weight_ratio", optional_to_variant(c.current_weight_ratio)) + ("target_weight_ratio", optional_to_variant(c.target_weight_ratio)) + ("assumed_stake_weight", optional_to_variant(c.assumed_stake_weight)) + ("target_timestamp", optional_to_variant(c.target_timestamp)) + ("exponent", optional_to_variant(c.exponent)) + ("decay_secs", optional_to_variant(c.decay_secs)) + ("target_price", optional_to_variant(c.target_price)) + ; + }; + + auto conf = mvo("net", resource_conf_vo(config.net)) + ("cpu", resource_conf_vo(config.cpu)) + ("rent_days", optional_to_variant(config.rent_days)) + ("min_rent_fee", optional_to_variant(config.min_rent_fee)) + ; + + //idump((fc::json::to_pretty_string(conf))); + return push_action(config::system_account_name, N(configrentbw), mvo()("args", std::move(conf))); + + // If abi_serializer worked correctly, the following is all that would be needed: + //return push_action(config::system_account_name, N(configrentbw), mvo()("args", config)); } action_result rentbwexec(name user, uint16_t max) { @@ -226,11 +254,13 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { push_action(N(alice1111111), N(configrentbw), mvo()("args", make_config()))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("rentbw hasn't been initialized"), rentbwexec(N(alice1111111), 10)); - //BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), - // configbw(make_config([&](auto& c) { c.rent_days = 0; }))); // needed only if rent_days does not have default + BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), + configbw(make_config([&](auto& c) { c.rent_days = 0; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee doesn't match core symbol"), configbw(make_config([&](auto& c) { c.min_rent_fee = asset::from_string("1000000.000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee does not have a default value"), + configbw(make_config([&](auto& c) { c.min_rent_fee = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee must be positive"), configbw(make_config([&](auto& c) { c.min_rent_fee = asset::from_string("0.0000 TST"); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee must be positive"), @@ -246,8 +276,12 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), configbw(make_config([](auto& c) { c.net.target_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), + configbw(make_config([](auto& c) { c.net.assumed_stake_weight = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), configbw(make_config([](auto& c) { c.net.assumed_stake_weight = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp does not have a default value"), + configbw(make_config([&](auto& c) { c.net.target_timestamp = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { c.net.target_timestamp = control->head_block_time(); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { @@ -255,8 +289,10 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), configbw(make_config([&](auto& c) { c.net.exponent = .999; }))); - //BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - // configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); // needed only if decay_secs does not have default + BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), + configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price does not have a default value"), + configbw(make_config([&](auto& c) { c.net.target_price = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("1000000.000 TST"); }))); @@ -275,8 +311,12 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), configbw(make_config([](auto& c) { c.cpu.target_weight_ratio = rentbw_frac + 1; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), + configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp does not have a default value"), + configbw(make_config([&](auto& c) { c.cpu.target_timestamp = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { c.cpu.target_timestamp = control->head_block_time(); }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { @@ -284,8 +324,10 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), configbw(make_config([&](auto& c) { c.cpu.exponent = .999; }))); - //BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - // configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); // needed only if decay_secs does not have default + BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), + configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price does not have a default value"), + configbw(make_config([&](auto& c) { c.cpu.target_price = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("1000000.000 TST"); }))); From 9be23747626259ad974b928f2fec180ac6aec87c Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 19 Dec 2019 20:59:30 -0500 Subject: [PATCH 0997/1048] replace target_price with the more meaningful max_price; also change pricing model to now also include a min_price Note: Assuming min_price is 0, this new price model can be directly compared to the prior one. In fact, under that condition, max_price can be thought of as target_price * exponent. --- .../include/eosio.system/eosio.system.hpp | 15 +- contracts/eosio.system/src/rentbw.cpp | 56 +++-- tests/eosio.rentbw_tests.cpp | 201 ++++++++++++++---- 3 files changed, 208 insertions(+), 64 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index b8abe590..98b9bf08 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -484,11 +484,15 @@ namespace eosiosystem { // utilization and instantaneous resource utilization to shrink // by 63%. Do not specify to preserve the existing setting or // use the default. - std::optional target_price; // Fee needed to rent the entire resource market weight. Do not - // specify to preserve the existing setting (no default exists). + std::optional min_price; // Fee needed to rent the entire resource market weight at the + // minimum price. Do not specify to preserve the existing + // setting or use the default. + std::optional max_price; // Fee needed to rent the entire resource market weight at the + // maximum price. Do not specify to preserve the existing + // setting (no default exists). EOSLIB_SERIALIZE( rentbw_config_resource, (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight) - (target_timestamp)(exponent)(decay_secs)(target_price) ) + (target_timestamp)(exponent)(decay_secs)(min_price)(max_price) ) }; struct rentbw_config { @@ -528,7 +532,10 @@ namespace eosiosystem { double exponent = default_exponent; // Exponent of resource price curve. uint32_t decay_secs = default_decay_secs; // Number of seconds for the gap between adjusted resource // utilization and instantaneous utilization to shrink by 63%. - asset target_price = {}; // Fee needed to rent the entire resource market weight. + asset min_price = {}; // Fee needed to rent the entire resource market weight at + // the minimum price (defaults to 0). + asset max_price = {}; // Fee needed to rent the entire resource market weight at + // the maximum price. int64_t utilization = 0; // Instantaneous resource utilization. This is the current // amount sold. utilization <= weight. int64_t adjusted_utilization = 0; // Adjusted resource utilization. This is >= utilization and diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 98513d96..6d5d385f 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -176,9 +176,18 @@ void system_contract::configrentbw(rentbw_config& args) { *args.decay_secs = state.decay_secs; } - if (!args.target_price) { - eosio::check(!is_default_asset(state.target_price), "target_price does not have a default value"); - *args.target_price = state.target_price; + if (!args.max_price) { + eosio::check(!is_default_asset(state.max_price), "max_price does not have a default value"); + *args.max_price = state.max_price; + } + + if (!args.min_price) { + if (is_default_asset(state.min_price)) { + *args.min_price = *args.max_price; // just to copy symbol of max_price + args.min_price->amount = 0; // min_price has a default of zero. + } else { + *args.min_price = state.min_price; + } } eosio::check(*args.current_weight_ratio > 0, "current_weight_ratio is too small"); @@ -190,10 +199,16 @@ void system_contract::configrentbw(rentbw_config& args) { eosio::check(*args.assumed_stake_weight * int128_t(rentbw_frac) / *args.target_weight_ratio <= std::numeric_limits::max(), "assumed_stake_weight/target_weight_ratio is too large"); - eosio::check(*args.exponent >= 1, "exponent must be >= 1"); + eosio::check(*args.exponent >= 1.0, "exponent must be >= 1"); eosio::check(*args.decay_secs >= 1, "decay_secs must be >= 1"); - eosio::check(args.target_price->symbol == core_symbol, "target_price doesn't match core symbol"); - eosio::check(args.target_price->amount > 0, "target_price must be positive"); + eosio::check(args.max_price->symbol == core_symbol, "max_price doesn't match core symbol"); + eosio::check(args.max_price->amount > 0, "max_price must be positive"); + eosio::check(args.min_price->symbol == core_symbol, "min_price doesn't match core symbol"); + eosio::check(args.min_price->amount >= 0, "min_price must be non-negative"); + eosio::check(args.min_price->amount <= args.max_price->amount, "min_price cannot exceed max_price"); + if (*args.exponent == 1.0) { + eosio::check(args.min_price->amount == args.max_price->amount, "min_price and max_price must be the same if the exponent is 1"); + } state.assumed_stake_weight = *args.assumed_stake_weight; state.initial_weight_ratio = *args.current_weight_ratio; @@ -202,7 +217,8 @@ void system_contract::configrentbw(rentbw_config& args) { state.target_timestamp = *args.target_timestamp; state.exponent = *args.exponent; state.decay_secs = *args.decay_secs; - state.target_price = *args.target_price; + state.min_price = *args.min_price; + state.max_price = *args.max_price; }; if (!args.rent_days) { @@ -236,7 +252,9 @@ void system_contract::configrentbw(rentbw_config& args) { } // system_contract::configrentbw /** - * @pre 0 < state.target_price.amount + * @pre 0 == state.min_price.amount (for now) + * @pre 0 <= state.min_price.amount <= state.max_price.amount + * @pre 0 < state.max_price.amount * @pre 1.0 <= state.exponent * @pre 0 <= state.utilization <= state.adjusted_utilization <= state.weight * @pre 0 <= utilization_increase <= (state.weight - state.utilization) @@ -247,26 +265,36 @@ int64_t calc_rentbw_fee(const rentbw_state_resource& state, int64_t utilization_ // Let p(u) = price as a function of the utilization fraction u which is defined for u in [0.0, 1.0]. // Let f(u) = integral of the price function p(x) from x = 0.0 to x = u, again defined for u in [0.0, 1.0]. + // In particular we choose f(u) = min_price * u + ((max_price - min_price) / exponent) * (u ^ exponent). + // And so p(u) = min_price + (max_price - min_price) * (u ^ (exponent - 1.0)). + // Returns f(double(end_utilization)/state.weight) - f(double(start_utilization)/state.weight) which is equivalent to // the integral of p(x) from x = double(start_utilization)/state.weight to x = double(end_utilization)/state.weight. // @pre 0 <= start_utilization <= end_utilization <= state.weight auto price_integral_delta = [&state](int64_t start_utilization, int64_t end_utilization) -> double { - return state.target_price.amount * std::pow(double(end_utilization) / state.weight, state.exponent) - - state.target_price.amount * std::pow(double(start_utilization) / state.weight, state.exponent); + double coefficient = (state.max_price.amount - state.min_price.amount) / state.exponent; + double start_u = double(start_utilization) / state.weight; + double end_u = double(end_utilization) / state.weight; + return state.min_price.amount * end_u - state.min_price.amount * start_u + + coefficient * std::pow(end_u, state.exponent) - coefficient * std::pow(start_u, state.exponent); }; // Returns p(double(utilization)/state.weight). // @pre 0 <= utilization <= state.weight auto price_function = [&state](int64_t utilization) -> double { + double price = state.min_price.amount; // state.exponent >= 1.0, therefore the exponent passed into std::pow is >= 0.0. // Since the exponent passed into std::pow could be 0.0 and simultaneously so could double(utilization)/state.weight, // the safest thing to do is handle that as a special case explicitly rather than relying on std::pow to return 1.0 // instead of triggering a domain error. double new_exponent = state.exponent - 1.0; - if (new_exponent <= 0.0) - return state.target_price.amount; - else - return state.exponent * state.target_price.amount * std::pow(double(utilization) / state.weight, new_exponent); + if (new_exponent <= 0.0) { + return state.max_price.amount; + } else { + price += (state.max_price.amount - state.min_price.amount) * std::pow(double(utilization) / state.weight, new_exponent); + } + + return price; }; double fee = 0.0; diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.rentbw_tests.cpp index 1bef8815..115bfa83 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.rentbw_tests.cpp @@ -22,11 +22,12 @@ struct rentbw_config_resource { fc::optional target_timestamp = {}; fc::optional exponent = {}; fc::optional decay_secs = {}; - fc::optional target_price = {}; + fc::optional min_price = {}; + fc::optional max_price = {}; }; FC_REFLECT(rentbw_config_resource, // (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight)(target_timestamp) // - (exponent)(decay_secs)(target_price)) + (exponent)(decay_secs)(min_price)(max_price)) struct rentbw_config { rentbw_config_resource net = {}; @@ -47,14 +48,15 @@ struct rentbw_state_resource { time_point_sec target_timestamp; double exponent; uint32_t decay_secs; - asset target_price; + asset min_price; + asset max_price; int64_t utilization; int64_t adjusted_utilization; time_point_sec utilization_timestamp; }; FC_REFLECT(rentbw_state_resource, // (version)(weight)(weight_ratio)(assumed_stake_weight)(initial_weight_ratio)(target_weight_ratio) // - (initial_timestamp)(target_timestamp)(exponent)(decay_secs)(target_price)(utilization) // + (initial_timestamp)(target_timestamp)(exponent)(decay_secs)(min_price)(max_price)(utilization) // (adjusted_utilization)(utilization_timestamp)) struct rentbw_state { @@ -99,7 +101,8 @@ struct rentbw_tester : eosio_system_tester { config.net.target_timestamp = control->head_block_time() + fc::days(100); config.net.exponent = 2; config.net.decay_secs = fc::days(1).to_seconds(); - config.net.target_price = asset::from_string("1000000.0000 TST"); + config.net.min_price = asset::from_string("0.0000 TST"); + config.net.max_price = asset::from_string("1000000.0000 TST"); config.cpu.current_weight_ratio = rentbw_frac; config.cpu.target_weight_ratio = rentbw_frac / 100; @@ -107,7 +110,8 @@ struct rentbw_tester : eosio_system_tester { config.cpu.target_timestamp = control->head_block_time() + fc::days(100); config.cpu.exponent = 2; config.cpu.decay_secs = fc::days(1).to_seconds(); - config.cpu.target_price = asset::from_string("1000000.0000 TST"); + config.cpu.min_price = asset::from_string("0.0000 TST"); + config.cpu.max_price = asset::from_string("1000000.0000 TST"); config.rent_days = 30; config.min_rent_fee = asset::from_string("1.0000 TST"); @@ -142,7 +146,8 @@ struct rentbw_tester : eosio_system_tester { ("target_timestamp", optional_to_variant(c.target_timestamp)) ("exponent", optional_to_variant(c.exponent)) ("decay_secs", optional_to_variant(c.decay_secs)) - ("target_price", optional_to_variant(c.target_price)) + ("min_price", optional_to_variant(c.min_price)) + ("max_price", optional_to_variant(c.max_price)) ; }; @@ -291,15 +296,25 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { configbw(make_config([&](auto& c) { c.net.exponent = .999; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price does not have a default value"), - configbw(make_config([&](auto& c) { c.net.target_price = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.net.target_price = asset::from_string("1000000.000 TST"); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price does not have a default value"), + configbw(make_config([&](auto& c) { c.net.max_price = {}; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.net.max_price = asset::from_string("1000000.000 TST"); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), + configbw(make_config([&](auto& c) { c.net.max_price = asset::from_string("0.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), + configbw(make_config([&](auto& c) { c.net.max_price = asset::from_string("-1.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.net.min_price = asset::from_string("1000000.000 TST"); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price must be non-negative"), + configbw(make_config([&](auto& c) { c.net.min_price = asset::from_string("-1.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price cannot exceed max_price"), + configbw(make_config([&](auto& c) { + c.net.min_price = asset::from_string("3.0000 TST"); + c.net.max_price = asset::from_string("2.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - configbw(make_config([&](auto& c) { c.net.target_price = asset::from_string("-1.0000 TST"); }))); // cpu assertions BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), @@ -326,15 +341,25 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { configbw(make_config([&](auto& c) { c.cpu.exponent = .999; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price does not have a default value"), - configbw(make_config([&](auto& c) { c.cpu.target_price = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.cpu.target_price = asset::from_string("1000000.000 TST"); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price does not have a default value"), + configbw(make_config([&](auto& c) { c.cpu.max_price = {}; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.cpu.max_price = asset::from_string("1000000.000 TST"); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), + configbw(make_config([&](auto& c) { c.cpu.max_price = asset::from_string("0.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), + configbw(make_config([&](auto& c) { c.cpu.max_price = asset::from_string("-1.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.cpu.min_price = asset::from_string("1000000.000 TST"); + }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price must be non-negative"), + configbw(make_config([&](auto& c) { c.cpu.min_price = asset::from_string("-1.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price cannot exceed max_price"), + configbw(make_config([&](auto& c) { + c.cpu.min_price = asset::from_string("3.0000 TST"); + c.cpu.max_price = asset::from_string("2.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_price must be positive"), - configbw(make_config([&](auto& c) { c.cpu.target_price = asset::from_string("-1.0000 TST"); }))); } // config_tests FC_LOG_AND_RETHROW() @@ -479,13 +504,15 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { config.net.target_weight_ratio = rentbw_frac; config.net.assumed_stake_weight = stake_weight; config.net.exponent = 1; - config.net.target_price = asset::from_string("1000000.0000 TST"); + config.net.min_price = asset::from_string("1000000.0000 TST"); + config.net.max_price = asset::from_string("1000000.0000 TST"); config.cpu.current_weight_ratio = rentbw_frac; config.cpu.target_weight_ratio = rentbw_frac; config.cpu.assumed_stake_weight = stake_weight; config.cpu.exponent = 1; - config.cpu.target_price = asset::from_string("1000000.0000 TST"); + config.cpu.min_price = asset::from_string("1000000.0000 TST"); + config.cpu.max_price = asset::from_string("1000000.0000 TST"); config.rent_days = 30; config.min_rent_fee = asset::from_string("1.0000 TST"); @@ -500,6 +527,53 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("market doesn't have resources available"), // t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, 0, asset::from_string("1.0000 TST"))); + + BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { + // weight = stake_weight + config.net.current_weight_ratio = rentbw_frac/2; + config.net.target_weight_ratio = rentbw_frac/2; + + // weight = stake_weight + config.cpu.current_weight_ratio = rentbw_frac/2; + config.cpu.target_weight_ratio = rentbw_frac/2; + }))); + + auto net_weight = stake_weight; + auto cpu_weight = stake_weight; + + t.start_rex(); + t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), + false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); + + // 10%, 20% + // (.1) * 1000000.0000 = 100000.0000 + // (.2) * 1000000.0000 = 200000.0000 + // total = 300000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("300000.0000")); + t.check_rentbw(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, rentbw_frac * .1, rentbw_frac * .2, + asset::from_string("300000.0000 TST"), net_weight * .1, cpu_weight * .2); + + // Start decay + t.produce_block(fc::days(30) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .1 * net_weight, 0)); + BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .2 * cpu_weight, 0)); + + // 2 days of decay from (10%, 20%) to (1.35%, 2.71%) + t.produce_block(fc::days(2) - fc::milliseconds(500)); + BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2)), + int64_t(.1 * net_weight * exp(-2)) / 1000)); + BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-2)), + int64_t(.2 * cpu_weight * exp(-2)) / 1000)); + + // 2%, 2% + // (0.0135 + 0.02 - 0.0135) * 1000000.0000 = 20000.0000 + // (.02) * 1000000.0000 = 20000.0000 + // total = 40000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("40000.0001")); + t.check_rentbw(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, rentbw_frac * .02, rentbw_frac * .02, + asset::from_string("40000.0001 TST"), net_weight * .02, cpu_weight * .02); } auto init = [](auto& t, bool rex) { @@ -510,14 +584,14 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { config.net.target_weight_ratio = rentbw_frac / 4; config.net.assumed_stake_weight = stake_weight; config.net.exponent = 2; - config.net.target_price = asset::from_string("1000000.0000 TST"); + config.net.max_price = asset::from_string("2000000.0000 TST"); // weight = stake_weight * 4 / 2 config.cpu.current_weight_ratio = rentbw_frac / 5; config.cpu.target_weight_ratio = rentbw_frac / 5; config.cpu.assumed_stake_weight = stake_weight / 2; config.cpu.exponent = 3; - config.cpu.target_price = asset::from_string("2000000.0000 TST"); + config.cpu.max_price = asset::from_string("6000000.0000 TST"); config.rent_days = 30; config.min_rent_fee = asset::from_string("1.0000 TST"); @@ -605,21 +679,57 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { { rentbw_tester t; init(t, true); - // (.3 ^ 2) * 1000000.0000 = 90000.0000 - // (.4 ^ 3) * 2000000.0000 = 128000.0000 - // total = 218000.0000 + // (.3 ^ 2) * 2000000.0000 / 2 = 90000.0000 + // (.4 ^ 3) * 6000000.0000 / 3 = 128000.0000 + // total = 218000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("218000.0001")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .3, rentbw_frac * .4, asset::from_string("218000.0001 TST"), net_weight * .3, cpu_weight * .4); - // (.35 ^ 2) * 1000000.0000 - 90000.0000 = 32500.0000 - // (.5 ^ 3) * 2000000.0000 - 128000.0000 = 122000.0000 - // total = 154500.0000 + // (.35 ^ 2) * 2000000.0000 / 2 - 90000.0000 = 32500.0000 + // (.5 ^ 3) * 6000000.0000 / 3 - 128000.0000 = 122000.0000 + // total = 154500.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("154500.0000")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .05, rentbw_frac * .10, asset::from_string("154500.0000 TST"), net_weight * .05, cpu_weight * .10); } + // net:50%, cpu:50% (but with non-zero min_price and also an exponent of 2 to simplify the math) + { + rentbw_tester t; + init(t, true); + BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { + config.cpu.exponent = 2; + config.net.min_price = asset::from_string("1200000.0000 TST"); + config.net.max_price = asset::from_string("2000000.0000 TST"); + + config.cpu.exponent = 2; + config.cpu.min_price = asset::from_string("4000000.0000 TST"); + config.cpu.max_price = asset::from_string("6000000.0000 TST"); + }))); + + // At 0% utilization for both NET and CPU, the cost (in TST) for renting an infinitesimal amount of resources (dr) is + // 1200000.0000 * dr for NET and 4000000.0000 * dr for CPU. + // At 50% utilization for both NET and CPU, the cost (in TST for renting an infinitesimal amount of resources (dr) is + // 1600000.0000 * dr for NET and 5000000.0000 * dr for CPU. + + // The fee for renting 50% of NET (starting from 0% utilization) is expected to be somewhere between + // 1200000.0000 * 0.5 (= 600000.0000) and 1600000.0000 * 0.5 (= 800000.0000). + // In fact, the cost ends up being 700000.0000. + + // The fee for renting 50% of CPU (starting from 0% utilization) is expected to be somewhere between + // 4000000.0000 * 0.5 (= 2000000.0000) and 5000000.0000 * 0.5 (= 2500000.0000). + // In fact, the cost ends up being 2250000.0000. + + + // 1200000.0000 * .5 + (800000.0000 / 2) * (.5 ^ 2) = 700000.0000 + // 4000000.0000 * .5 + (2000000.0000 / 2) * (.5 ^ 2) = 2250000.0000 + // total = 2950000.0000 + t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("2950000.0000")); + t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .5, rentbw_frac * .5, + asset::from_string("2950000.0000 TST"), net_weight * .5, cpu_weight * .5); + } + { // net:100%, cpu:100% rentbw_tester t; @@ -644,9 +754,9 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // immediate renewal: adjusted_utilization doesn't have time to fall // - // 2 * (1.0 ^ 1) * 1000000.0000 = 2000000.0000 - // 3 * (1.0 ^ 2) * 2000000.0000 = 6000000.0000 - // total = 8000000.0000 + // (1.0 ^ 1) * 2000000.0000 = 2000000.0000 + // (1.0 ^ 2) * 6000000.0000 = 6000000.0000 + // total = 8000000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("8000000.0000")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, asset::from_string("8000000.0000 TST"), 0, 0); @@ -689,9 +799,9 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // 100% after 2 days of decay // - // [ [2 * ((e^-2) ^ 1)]*(e^-2 - 0.0) + ((1.0) ^ 2) - ((e^-2) ^ 2) ] * 1000000.0000 = 1018315.6389 - // [ [3 * ((e^-2) ^ 2)]*(e^-2 - 0.0) + ((1.0) ^ 3) - ((e^-2) ^ 3) ] * 2000000.0000 = 2009915.0087 - // total = 3028230.6476 + // [ ((e^-2) ^ 1)*(e^-2 - 0.0) + ((1.0) ^ 2)/2 - ((e^-2) ^ 2)/2 ] * 2000000.0000 = 1018315.6389 + // [ ((e^-2) ^ 2)*(e^-2 - 0.0) + ((1.0) ^ 3)/3 - ((e^-2) ^ 3)/3 ] * 6000000.0000 = 2009915.0087 + // total = 3028230.6476 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3028229.8795")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, asset::from_string("3028229.8795 TST"), net_weight, cpu_weight); @@ -702,9 +812,9 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { init(t, true); // 10%, 20% - // (.1 ^ 2) * 1000000.0000 = 10000.0000 - // (.2 ^ 3) * 2000000.0000 = 16000.0000 - // total = 26000.0000 + // (.1 ^ 2) * 2000000.0000 / 2 = 10000.0000 + // (.2 ^ 3) * 6000000.0000 / 3 = 16000.0000 + // total = 26000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("26000.0002")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .1, rentbw_frac * .2, asset::from_string("26000.0002 TST"), net_weight * .1, cpu_weight * .2); @@ -712,9 +822,9 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { t.produce_block(fc::days(15) - fc::milliseconds(500)); // 20%, 20% - // (.3 ^ 2) * 1000000.0000 - 10000.0000 = 80000.0000 - // (.4 ^ 3) * 2000000.0000 - 16000.0000 = 112000.0000 - // total = 192000.0000 + // (.3 ^ 2) * 2000000.0000 / 2 - 10000.0000 = 80000.0000 + // (.4 ^ 3) * 6000000.0000 / 3 - 16000.0000 = 112000.0000 + // total = 192000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("192000.0001")); t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .2, rentbw_frac * .2, asset::from_string("192000.0001 TST"), net_weight * .2, cpu_weight * .2); @@ -722,7 +832,6 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // Start decay t.produce_block(fc::days(15) - fc::milliseconds(1000)); BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .3 * net_weight, 0)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .4 * cpu_weight, 0)); From f19746782a1d703885cac23e2dafb017599eab26 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 19 Dec 2019 22:58:18 -0500 Subject: [PATCH 0998/1048] remove unnecessary precondition comment --- contracts/eosio.system/src/rentbw.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/rentbw.cpp index 6d5d385f..195f53d3 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/rentbw.cpp @@ -252,7 +252,6 @@ void system_contract::configrentbw(rentbw_config& args) { } // system_contract::configrentbw /** - * @pre 0 == state.min_price.amount (for now) * @pre 0 <= state.min_price.amount <= state.max_price.amount * @pre 0 < state.max_price.amount * @pre 1.0 <= state.exponent From 2703fda5e1b3a8b58cead3b081d01a09d33d8283 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 20 Dec 2019 15:26:55 -0500 Subject: [PATCH 0999/1048] small tweaks to comments --- .../eosio.system/include/eosio.system/eosio.system.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 98b9bf08..06810802 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -485,10 +485,12 @@ namespace eosiosystem { // by 63%. Do not specify to preserve the existing setting or // use the default. std::optional min_price; // Fee needed to rent the entire resource market weight at the - // minimum price. Do not specify to preserve the existing + // minimum price. For example, this could be set to 0.005% of + // total token supply. Do not specify to preserve the existing // setting or use the default. std::optional max_price; // Fee needed to rent the entire resource market weight at the - // maximum price. Do not specify to preserve the existing + // maximum price. For example, this could be set to 10% of total + // total token supply. Do not specify to preserve the existing // setting (no default exists). EOSLIB_SERIALIZE( rentbw_config_resource, (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight) @@ -499,9 +501,9 @@ namespace eosiosystem { rentbw_config_resource net; // NET market configuration rentbw_config_resource cpu; // CPU market configuration std::optional rent_days; // `rentbw` `days` argument must match this. Do not specify to preserve the - // existing setting or use the default. + // existing setting or use the default. std::optional min_rent_fee; // Rental fees below this amount are rejected. Do not specify to preserve the - // existing setting (no default exists). + // existing setting (no default exists). EOSLIB_SERIALIZE( rentbw_config, (net)(cpu)(rent_days)(min_rent_fee) ) }; From 64cc02ddae2dc2a4ac055d47ca1501d00a540a01 Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 20 Dec 2019 15:27:59 -0500 Subject: [PATCH 1000/1048] quick fix to comment --- contracts/eosio.system/include/eosio.system/eosio.system.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 06810802..5bee876e 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -490,7 +490,7 @@ namespace eosiosystem { // setting or use the default. std::optional max_price; // Fee needed to rent the entire resource market weight at the // maximum price. For example, this could be set to 10% of total - // total token supply. Do not specify to preserve the existing + // token supply. Do not specify to preserve the existing // setting (no default exists). EOSLIB_SERIALIZE( rentbw_config_resource, (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight) From 5eb391bc989a0914a10f0858cb0e337283b247fa Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 10 Jan 2020 10:26:38 -0500 Subject: [PATCH 1001/1048] bump version to v1.9.0 --- CMakeLists.txt | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fbf5e4f3..08c995ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) set(VERSION_PATCH 0) -set(VERSION_SUFFIX rc4) +#set(VERSION_SUFFIX rc4) if (VERSION_SUFFIX) set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}") diff --git a/README.md b/README.md index a33f7032..46070ba1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0-rc4 +## Version : 1.9.0 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. From 6cdab759cf6924c873e378665860c29442cdb29c Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Fri, 17 Jan 2020 16:43:47 -0500 Subject: [PATCH 1002/1048] Wait for CDT binary. --- .cicd/build.sh | 13 ++++++++++++- .cicd/pipeline.yml | 2 +- .cicd/test.sh | 3 ++- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index eb222859..1be513f8 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -15,10 +15,21 @@ else export DOCKER_IMAGE fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/\\\$(ls /usr/opt/eosio.cdt/)/bin:\\\$PATH" +CDT_COMMANDS="dpkg -i $MOUNTED_DIR/eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/\\\$(ls /usr/opt/eosio.cdt/)/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" +# Test CDT binary download to prevent failures due to eosio.cdt pipeline. +INDEX='1' +echo "$ curl -sSf $CDT_URL --output eosio.cdt.deb" +while ! $(curl -sSf $CDT_URL --output eosio.cdt.deb); do + echo "ERROR: Expected CDT binary for commit ${CDT_COMMIT:0:7} from $CDT_VERSION. It does not exist at $CDT_URL!" + printf "There must be a successful build against ${CDT_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio-dot-cdt/builds?commit=$CDT_COMMIT;content=here\a for this package to exist.\n" + echo "Attempt $INDEX, retry in 60 seconds..." + echo '' + INDEX=$(( $INDEX + 1 )) + sleep 60 +done # retry docker pull to protect against failures due to race conditions with eosio pipeline INDEX='1' echo "$ docker pull $DOCKER_IMAGE" diff --git a/.cicd/pipeline.yml b/.cicd/pipeline.yml index 9c9a4ab2..7d283984 100644 --- a/.cicd/pipeline.yml +++ b/.cicd/pipeline.yml @@ -8,7 +8,7 @@ steps: buildkite-agent artifact upload build.tar.gz agents: queue: "automation-eks-eos-builder-fleet" - timeout: "${TIMEOUT:-40}" + timeout: "${TIMEOUT:-60}" skip: "$SKIP_UBUNTU_18" - wait diff --git a/.cicd/test.sh b/.cicd/test.sh index d4e45617..bdb8473e 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -9,10 +9,11 @@ if [[ "$BUILDKITE" == 'true' ]]; then DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} -CDT_COMMANDS="apt-get install -y wget && wget -q $CDT_URL -O eosio.cdt.deb && dpkg -i eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" +CDT_COMMANDS="dpkg -i $MOUNTED_DIR/eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build/tests" TEST_COMMANDS="ctest -j $JOBS --output-on-failure -T Test" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" +curl -sSf $CDT_URL --output eosio.cdt.deb set +e eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" EXIT_STATUS=$? From 3cbe918e57781542c1b0b706621c723f2229a1f1 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 21 Jan 2020 19:43:40 +0200 Subject: [PATCH 1003/1048] clean up @details and other arrangements to suppot the mdjavadoc generetor --- .../include/eosio.bios/eosio.bios.hpp | 66 ++++---------- .../include/eosio.msig/eosio.msig.hpp | 26 ++---- .../include/eosio.system/eosio.system.hpp | 87 +++++++++---------- .../include/eosio.system/exchange_state.hpp | 2 +- .../include/eosio.system/native.hpp | 62 +++++-------- .../include/eosio.token/eosio.token.hpp | 2 +- .../include/eosio.wrap/eosio.wrap.hpp | 4 +- 7 files changed, 87 insertions(+), 162 deletions(-) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 76a2215e..88094b68 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -10,7 +10,7 @@ /** * EOSIO Contracts * - * @details The design of the EOSIO blockchain calls for a number of smart contracts that are run at a + * The design of the EOSIO blockchain calls for a number of smart contracts that are run at a * privileged permission level in order to support functions such as block producer registration and * voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart * contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. @@ -89,9 +89,7 @@ namespace eosiobios { public: using contract::contract; /** - * New account action - * - * @details Called after a new account is created. This code enforces resource-limits rules + * New account action, called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. * * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 @@ -108,9 +106,7 @@ namespace eosiobios { ignore owner, ignore active){} /** - * Update authorization action. - * - * @details Updates pemission for an account. + * Update authorization action updates pemission for an account. * * @param account - the account for which the permission is updated, * @param pemission - the permission name which is updated, @@ -124,9 +120,7 @@ namespace eosiobios { ignore auth ) {} /** - * Delete authorization action. - * - * @details Deletes the authorization for an account's permision. + * Delete authorization action deletes the authorization for an account's permission. * * @param account - the account for which the permission authorization is deleted, * @param permission - the permission name been deleted. @@ -136,9 +130,7 @@ namespace eosiobios { ignore permission ) {} /** - * Link authorization action. - * - * @details Assigns a specific action from a contract to a permission you have created. Five system + * Link authorization action assigns a specific action from a contract to a permission you have created. Five system * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the * action needed to be authorized (and the contract belonging to), and looks up which permission @@ -159,9 +151,7 @@ namespace eosiobios { ignore requirement ) {} /** - * Unlink authorization action. - * - * @details It's doing the reverse of linkauth action, by unlinking the given action. + * Unlink authorization action it's doing the reverse of linkauth action, by unlinking the given action. * * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, * @param code - the owner of the action to be unlinked, @@ -173,9 +163,7 @@ namespace eosiobios { ignore type ) {} /** - * Cancel delay action. - * - * @details Cancels a deferred transaction. + * Cancel delay action cancels a deferred transaction. * * @param canceling_auth - the permission that authorizes this action, * @param trx_id - the deferred transaction id to be cancelled. @@ -184,9 +172,7 @@ namespace eosiobios { void canceldelay( ignore canceling_auth, ignore trx_id ) {} /** - * Set code action. - * - * @details Sets the contract code for an account. + * Set code action sets the contract code for an account. * * @param account - the account for which to set the contract code. * @param vmtype - reserved, set it to zero. @@ -199,9 +185,7 @@ namespace eosiobios { /** @}*/ /** - * Set abi for contract. - * - * @details Set the abi for contract identified by `account` name. Creates an entry in the abi_hash_table + * Set abi action sets the abi for contract identified by `account` name. Creates an entry in the abi_hash_table * index, with `account` name as key, if it is not already present and sets its value with the abi hash. * Otherwise it is updating the current abi hash value for the existing `account` key. * @@ -212,9 +196,7 @@ namespace eosiobios { void setabi( name account, const std::vector& abi ); /** - * On error action. - * - * @details Notification of this action is delivered to the sender of a deferred transaction + * On error action, notification of this action is delivered to the sender of a deferred transaction * when an objective error occurs while executing the deferred transaction. * This action is not meant to be called directly. * @@ -225,9 +207,7 @@ namespace eosiobios { void onerror( ignore sender_id, ignore> sent_trx ); /** - * Set privilege status for an account. - * - * @details Allows to set privilege status for an account (turn it on/off). + * Set privilege action allows to set privilege status for an account (turn it on/off). * @param account - the account to set the privileged status for. * @param is_priv - 0 for false, > 0 for true. */ @@ -235,9 +215,7 @@ namespace eosiobios { void setpriv( name account, uint8_t is_priv ); /** - * Set the resource limits of an account - * - * @details Set the resource limits of an account + * Sets the resource limits of an account * * @param account - name of the account whose resource limit to be set * @param ram_bytes - ram limit in absolute bytes @@ -248,9 +226,7 @@ namespace eosiobios { void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); /** - * Set a new list of active producers, that is, a new producers' schedule. - * - * @details Set a new list of active producers, by proposing a schedule change, once the block that + * Set producers action, sets a new list of active producers, by proposing a schedule change, once the block that * contains the proposal becomes irreversible, the schedule is promoted to "pending" * automatically. Once the block that promotes the schedule is irreversible, the schedule will * become "active". @@ -261,9 +237,7 @@ namespace eosiobios { void setprods( const std::vector& schedule ); /** - * Set the blockchain parameters - * - * @details Set the blockchain parameters. By tuning these parameters, various degrees of customization can be achieved. + * Set params action, sets the blockchain parameters. By tuning these parameters, various degrees of customization can be achieved. * * @param params - New blockchain parameters to set */ @@ -271,9 +245,7 @@ namespace eosiobios { void setparams( const eosio::blockchain_parameters& params ); /** - * Check if an account has authorization to access current action. - * - * @details Checks if the account name `from` passed in as param has authorization to access + * Require authorization action, checks if the account name `from` passed in as param has authorization to access * current action, that is, if it is listed in the action’s allowed permissions vector. * * @param from - the account name to authorize @@ -282,9 +254,7 @@ namespace eosiobios { void reqauth( name from ); /** - * Activates a protocol feature. - * - * @details Activates a protocol feature + * Activate action, activates a protocol feature * * @param feature_digest - hash of the protocol feature to activate. */ @@ -292,9 +262,7 @@ namespace eosiobios { void activate( const eosio::checksum256& feature_digest ); /** - * Asserts that a protocol feature has been activated. - * - * @details Asserts that a protocol feature has been activated + * Require activated action, asserts that a protocol feature has been activated * * @param feature_digest - hash of the protocol feature to check for activation. */ diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index 465433ec..25c46221 100644 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -18,9 +18,7 @@ namespace eosio { using contract::contract; /** - * Create proposal - * - * @details Creates a proposal containing one transaction. + * Propose action, creates a proposal containing one transaction. * Allows an account `proposer` to make a proposal `proposal_name` which has `requested` * permission levels expected to approve the proposal, and if approved by all expected * permission levels then `trx` transaction can we executed by this proposal. @@ -39,10 +37,7 @@ namespace eosio { void propose(ignore proposer, ignore proposal_name, ignore> requested, ignore trx); /** - * Approve proposal - * - * @details Approves an existing proposal - * Allows an account, the owner of `level` permission, to approve a proposal `proposal_name` + * Approve action approves an existing proposal. Allows an account, the owner of `level` permission, to approve a proposal `proposal_name` * proposed by `proposer`. If the proposal's requested approval list contains the `level` * permission then the `level` permission is moved from internal `requested_approvals` list to * internal `provided_approvals` list of the proposal, thus persisting the approval for @@ -57,10 +52,7 @@ namespace eosio { void approve( name proposer, name proposal_name, permission_level level, const eosio::binary_extension& proposal_hash ); /** - * Revoke proposal - * - * @details Revokes an existing proposal - * This action is the reverse of the `approve` action: if all validations pass + * Unapprove action revokes an existing proposal. This action is the reverse of the `approve` action: if all validations pass * the `level` permission is erased from internal `provided_approvals` and added to the internal * `requested_approvals` list, and thus un-approve or revoke the proposal. * @@ -71,9 +63,7 @@ namespace eosio { [[eosio::action]] void unapprove( name proposer, name proposal_name, permission_level level ); /** - * Cancel proposal - * - * @details Cancels an existing proposal + * Cancel action cancels an existing proposal. * * @param proposer - The account proposing a transaction * @param proposal_name - The name of the proposal (should be an existing proposal) @@ -86,9 +76,7 @@ namespace eosio { [[eosio::action]] void cancel( name proposer, name proposal_name, name canceler ); /** - * Execute proposal - * - * @details Allows an `executer` account to execute a proposal. + * Exec action allows an `executer` account to execute a proposal. * * Preconditions: * - `executer` has authorization, @@ -107,9 +95,7 @@ namespace eosio { [[eosio::action]] void exec( name proposer, name proposal_name, name executer ); /** - * Invalidate proposal - * - * @details Allows an `account` to invalidate itself, that is, its name is added to + * Invalidate action allows an `account` to invalidate itself, that is, its name is added to * the invalidations table and this table will be cross referenced when exec is performed. * * @param account - The account invalidating the transaction diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index fb7e8cdb..f5ce3d11 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -79,6 +79,8 @@ namespace eosiosystem { static constexpr int64_t default_votepay_factor = 40000; // per-block pay share = 10000 / 40000 = 25% of the producer pay /** + * eosio.system contract + * * eosio.system contract defines the structures and actions needed for blockchain's core functionality. * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or * delegate their vote to a proxy. @@ -588,7 +590,7 @@ namespace eosiosystem { /** - * Activates a protocol feature + * The activate action, activates a protocol feature * * @param feature_digest - hash of the protocol feature to activate. */ @@ -615,9 +617,7 @@ namespace eosiosystem { const asset& stake_net_quantity, const asset& stake_cpu_quantity, bool transfer ); /** - * Setrex action. - * - * @details Sets total_rent balance of REX pool to the passed value. + * Setrex action, sets total_rent balance of REX pool to the passed value. * @param balance - amount to set the REX pool balance. */ [[eosio::action]] @@ -638,9 +638,7 @@ namespace eosiosystem { void deposit( const name& owner, const asset& amount ); /** - * Withdraw from REX fund action. - * - * @details Withdraws core tokens from user REX fund. + * Withdraw from REX fund action, withdraws core tokens from user REX fund. * An inline token transfer to user balance is executed. * * @param owner - REX fund owner account, @@ -650,7 +648,7 @@ namespace eosiosystem { void withdraw( const name& owner, const asset& amount ); /** - * Buyrex action. Buys REX in exchange for tokens taken out of user's REX fund by transfering + * Buyrex action, buys REX in exchange for tokens taken out of user's REX fund by transfering * core tokens from user REX fund and converts them to REX stake. By buying REX, user is * lending tokens in order to be rented as CPU or NET resourses. * Storage change is billed to 'from' account. @@ -669,7 +667,7 @@ namespace eosiosystem { void buyrex( const name& from, const asset& amount ); /** - * Unstaketorex action. Use staked core tokens to buy REX. + * Unstaketorex action, uses staked core tokens to buy REX. * Storage change is billed to 'owner' account. * * @param owner - owner of staked tokens, @@ -688,7 +686,7 @@ namespace eosiosystem { void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); /** - * Sellrex action. Sells REX in exchange for core tokens by converting REX stake back into core tokens + * Sellrex action, sells REX in exchange for core tokens by converting REX stake back into core tokens * at current exchange rate. If order cannot be processed, it gets queued until there is enough * in REX pool to fill order, and will be processed within 30 days at most. If successful, user * votes are updated, that is, proceeds are deducted from user's voting power. In case sell order @@ -701,7 +699,7 @@ namespace eosiosystem { void sellrex( const name& from, const asset& rex ); /** - * Cnclrexorder action. Cancels unfilled REX sell order by owner if one exists. + * Cnclrexorder action, cancels unfilled REX sell order by owner if one exists. * * @param owner - owner account name. * @@ -711,7 +709,7 @@ namespace eosiosystem { void cnclrexorder( const name& owner ); /** - * Rentcpu action. Use payment to rent as many SYS tokens as possible as determined by market price and + * Rentcpu action, uses payment to rent as many SYS tokens as possible as determined by market price and * stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user @@ -731,7 +729,7 @@ namespace eosiosystem { void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Rentnet action. Use payment to rent as many SYS tokens as possible as determined by market price and + * Rentnet action, uses payment to rent as many SYS tokens as possible as determined by market price and * stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user @@ -751,7 +749,7 @@ namespace eosiosystem { void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); /** - * Fundcpuloan action. Transfers tokens from REX fund to the fund of a specific CPU loan in order to + * Fundcpuloan action, transfers tokens from REX fund to the fund of a specific CPU loan in order to * be used for loan renewal at expiry. * * @param from - loan creator account, @@ -762,7 +760,7 @@ namespace eosiosystem { void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); /** - * Fundnetloan action. Transfers tokens from REX fund to the fund of a specific NET loan in order to + * Fundnetloan action, transfers tokens from REX fund to the fund of a specific NET loan in order to * be used for loan renewal at expiry. * * @param from - loan creator account, @@ -773,7 +771,7 @@ namespace eosiosystem { void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); /** - * Defcpuloan action. Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. + * Defcpuloan action, withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. * * @param from - loan creator account, * @param loan_num - loan id, @@ -783,7 +781,7 @@ namespace eosiosystem { void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); /** - * Defnetloan action. Withdraws tokens from the fund of a specific NET loan and adds them to REX fund. + * Defnetloan action, withdraws tokens from the fund of a specific NET loan and adds them to REX fund. * * @param from - loan creator account, * @param loan_num - loan id, @@ -793,7 +791,7 @@ namespace eosiosystem { void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); /** - * Updaterex action. Updates REX owner vote weight to current value of held REX tokens. + * Updaterex action, updates REX owner vote weight to current value of held REX tokens. * * @param owner - REX owner account. */ @@ -801,7 +799,7 @@ namespace eosiosystem { void updaterex( const name& owner ); /** - * Rexexec action. Processes max CPU loans, max NET loans, and max queued sellrex orders. + * Rexexec action, processes max CPU loans, max NET loans, and max queued sellrex orders. * Action does not execute anything related to a specific user. * * @param user - any account can execute this action, @@ -811,7 +809,7 @@ namespace eosiosystem { void rexexec( const name& user, uint16_t max ); /** - * Consolidate action. Consolidates REX maturity buckets into one bucket that can be sold after 4 days + * Consolidate action, consolidates REX maturity buckets into one bucket that can be sold after 4 days * starting from the end of the day. * * @param owner - REX owner account name. @@ -820,7 +818,7 @@ namespace eosiosystem { void consolidate( const name& owner ); /** - * Mvtosavings action. Moves a specified amount of REX into savings bucket. REX savings bucket + * Mvtosavings action, moves a specified amount of REX into savings bucket. REX savings bucket * never matures. In order for it to be sold, it has to be moved explicitly * out of that bucket. Then the moved amount will have the regular maturity * period of 4 days starting from the end of the day. @@ -832,7 +830,7 @@ namespace eosiosystem { void mvtosavings( const name& owner, const asset& rex ); /** - * Mvfrsavings action. Moves a specified amount of REX out of savings bucket. The moved amount + * Mvfrsavings action, moves a specified amount of REX out of savings bucket. The moved amount * will have the regular REX maturity period of 4 days. * * @param owner - REX owner account name. @@ -842,7 +840,7 @@ namespace eosiosystem { void mvfrsavings( const name& owner, const asset& rex ); /** - * Closerex action. Deletes owner records from REX tables and frees used RAM. Owner must not have + * Closerex action, deletes owner records from REX tables and frees used RAM. Owner must not have * an outstanding REX balance. * * @param owner - user account name. @@ -856,7 +854,7 @@ namespace eosiosystem { void closerex( const name& owner ); /** - * Undelegate bandwitdh action. Decreases the total tokens delegated by `from` to `receiver` and/or + * Undelegate bandwitdh action, decreases the total tokens delegated by `from` to `receiver` and/or * frees the memory associated with the delegation if there is nothing * left to delegate. * This will cause an immediate reduction in net/cpu bandwidth of the @@ -887,7 +885,7 @@ namespace eosiosystem { const asset& unstake_net_quantity, const asset& unstake_cpu_quantity ); /** - * Buy ram action. Increases receiver's ram quota based upon current price and quantity of + * Buy ram action, increases receiver's ram quota based upon current price and quantity of * tokens provided. An inline transfer from receiver to system contract of * tokens will be executed. * @@ -910,7 +908,7 @@ namespace eosiosystem { void buyrambytes( const name& payer, const name& receiver, uint32_t bytes ); /** - * Sell ram action. Reduces quota by bytes and then performs an inline transfer of tokens + * Sell ram action, reduces quota by bytes and then performs an inline transfer of tokens * to receiver based upon the average purchase price of the original quota. * * @param account - the ram seller account, @@ -920,7 +918,7 @@ namespace eosiosystem { void sellram( const name& account, int64_t bytes ); /** - * Refund action. This action is called after the delegation-period to claim all pending + * Refund action, this action is called after the delegation-period to claim all pending * unstaked tokens belonging to owner. * * @param owner - the owner of the tokens claimed. @@ -931,7 +929,7 @@ namespace eosiosystem { // functions defined in voting.cpp /** - * Register producer action. Register producer action, indicates that a particular account wishes to become a producer, + * Register producer action, indicates that a particular account wishes to become a producer, * this action will create a `producer_config` and a `producer_info` object for `producer` scope * in producers tables. * @@ -947,9 +945,7 @@ namespace eosiosystem { void regproducer( const name& producer, const public_key& producer_key, const std::string& url, uint16_t location ); /** - * Register producer action. - * - * @details Register producer action, indicates that a particular account wishes to become a producer, + * Register producer action, indicates that a particular account wishes to become a producer, * this action will create a `producer_config` and a `producer_info` object for `producer` scope * in producers tables. * @@ -965,23 +961,23 @@ namespace eosiosystem { void regproducer2( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ); /** - * Unregister producer action. Deactivate the block producer with account name `producer`. + * Unregister producer action, deactivates the block producer with account name `producer`. * - * @details Deactivate the block producer with account name `producer`. + * Deactivate the block producer with account name `producer`. * @param producer - the block producer account to unregister. */ [[eosio::action]] void unregprod( const name& producer ); /** - * Set ram action sets the ram supply + * Set ram action sets the ram supply. * @param max_ram_size - the amount of ram supply to set. */ [[eosio::action]] void setram( uint64_t max_ram_size ); /** - * Set ram rate action. Sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to + * Set ram rate action, sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to * a maximum rate of 3 TB per year. If update_ram_supply hasn't been called for the most recent block, * then new ram will be allocated at the old rate up to the present block before switching the rate. * @@ -991,7 +987,7 @@ namespace eosiosystem { void setramrate( uint16_t bytes_per_block ); /** - * Vote producer action. Votes for a set of producers. This action updates the list of `producers` voted for, + * Vote producer action, votes for a set of producers. This action updates the list of `producers` voted for, * for `voter` account. If voting for a `proxy`, the producer votes will not change until the * proxy updates their own vote. Voter can vote for a proxy __or__ a list of at most 30 producers. * Storage change is billed to `voter`. @@ -1017,7 +1013,7 @@ namespace eosiosystem { void voteproducer( const name& voter, const name& proxy, const std::vector& producers ); /** - * Register proxy action. Set `proxy` account as proxy. + * Register proxy action, sets `proxy` account as proxy. * An account marked as a proxy can vote with the weight of other accounts which * have selected it as a proxy. Other accounts must refresh their voteproducer to * update the proxy's weight. @@ -1033,7 +1029,7 @@ namespace eosiosystem { void regproxy( const name& proxy, bool isproxy ); /** - * Set the blockchain parameters Set the blockchain parameters. By tunning these parameters a degree of + * Set the blockchain parameters. By tunning these parameters a degree of * customization can be achieved. * @param params - New blockchain parameters to set. */ @@ -1041,7 +1037,7 @@ namespace eosiosystem { void setparams( const eosio::blockchain_parameters& params ); /** - * Claim rewards action. Claim block producing and vote rewards. + * Claim rewards action, claims block producing and vote rewards. * @param owner - producer account claiming per-block and per-vote rewards. */ [[eosio::action]] @@ -1056,14 +1052,14 @@ namespace eosiosystem { void setpriv( const name& account, uint8_t is_priv ); /** - * Remove producer action. Deactivates a producer by name, if not found asserts. + * Remove producer action, deactivates a producer by name, if not found asserts. * @param producer - the producer account to deactivate. */ [[eosio::action]] void rmvproducer( const name& producer ); /** - * Update revision action. Updates the current revision. + * Update revision action, updates the current revision. * @param revision - it has to be incremented by 1 compared with current revision. * * @pre Current revision can not be higher than 254, and has to be smaller @@ -1073,7 +1069,7 @@ namespace eosiosystem { void updtrevision( uint8_t revision ); /** - * Bid name action. Allows an account `bidder` to place a bid for a name `newname`. + * Bid name action, allows an account `bidder` to place a bid for a name `newname`. * @param bidder - the account placing the bid, * @param newname - the name the bid is placed for, * @param bid - the amount of system tokens payed for the bid. @@ -1092,7 +1088,7 @@ namespace eosiosystem { void bidname( const name& bidder, const name& newname, const asset& bid ); /** - * Bid refund action. Allows the account `bidder` to get back the amount it bid so far on a `newname` name. + * Bid refund action, allows the account `bidder` to get back the amount it bid so far on a `newname` name. * * @param bidder - the account that gets refunded, * @param newname - the name for which the bid was placed and now it gets refunded for. @@ -1102,18 +1098,15 @@ namespace eosiosystem { /** * Change the annual inflation rate of the core token supply and specify how - * the new issued tokens will be distributed based on the following structure. - + * the new issued tokens will be distributed based on the following structure. * * @param annual_rate - Annual inflation rate of the core token supply. * (eg. For 5% Annual inflation => annual_rate=500 * For 1.5% Annual inflation => annual_rate=150 - * * @param inflation_pay_factor - Inverse of the fraction of the inflation used to reward block producers. * The remaining inflation will be sent to the `eosio.saving` account. * (eg. For 20% of inflation going to block producer rewards => inflation_pay_factor = 50000 * For 100% of inflation going to block producer rewards => inflation_pay_factor = 10000). - * * @param votepay_factor - Inverse of the fraction of the block producer rewards to be distributed proportional to blocks produced. * The remaining rewards will be distributed proportional to votes received. * (eg. For 25% of block producer rewards going towards block pay => votepay_factor = 40000 diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index e0715356..4e5ba817 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -16,7 +16,7 @@ namespace eosiosystem { /** * Uses Bancor math to create a 50/50 relay between two asset types. * - * @details The state of the bancor exchange is entirely contained within this struct. + * The state of the bancor exchange is entirely contained within this struct. * There are no external side effects associated with using this API. */ struct [[eosio::table, eosio::contract("eosio.system")]] exchange_state { diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index 854a0544..b5cb33e2 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -24,7 +24,7 @@ namespace eosiosystem { /** * A weighted permission. * - * @details Defines a weighted permission, that is a permission which has a weight associated. + * Defines a weighted permission, that is a permission which has a weight associated. * A permission is defined by an account name plus a permission name. */ struct permission_level_weight { @@ -38,7 +38,7 @@ namespace eosiosystem { /** * Weighted key. * - * @details A weighted key is defined by a public key and an associated weight. + * A weighted key is defined by a public key and an associated weight. */ struct key_weight { eosio::public_key key; @@ -51,7 +51,7 @@ namespace eosiosystem { /** * Wait weight. * - * @details A wait weight is defined by a number of seconds to wait for and a weight. + * A wait weight is defined by a number of seconds to wait for and a weight. */ struct wait_weight { uint32_t wait_sec; @@ -64,7 +64,7 @@ namespace eosiosystem { /** * Blockchain authority. * - * @details An authority is defined by: + * An authority is defined by: * - a vector of key_weights (a key_weight is a public key plus a wieght), * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) * - a vector of wait_weights (a wait_weight is defined by a number of seconds to wait and a weight) @@ -83,7 +83,7 @@ namespace eosiosystem { /** * Blockchain block header. * - * @details A block header is defined by: + * A block header is defined by: * - a timestamp, * - the producer that created it, * - a confirmed flag default as zero, @@ -109,9 +109,7 @@ namespace eosiosystem { }; /** - * abi_hash - * - * @details abi_hash is the structure underlying the abihash table and consists of: + * abi_hash is the structure underlying the abihash table and consists of: * - `owner`: the account owner of the contract's abi * - `hash`: is the sha256 hash of the abi/binary */ @@ -125,9 +123,7 @@ namespace eosiosystem { // Method parameters commented out to prevent generation of code that parses input data. /** - * The EOSIO core native contract that governs authorization and contracts' abi. - * - * @details + * The EOSIO core `native` contract that governs authorization and contracts' abi. */ class [[eosio::contract("eosio.system")]] native : public eosio::contract { public: @@ -136,16 +132,14 @@ namespace eosiosystem { /** * @{ - * These actions map one-on-one with the ones defined in - * [Native Action Handlers](@ref native_action_handlers) section. - * They are present here so they can show up in the abi file and thus user can send them + * These actions map one-on-one with the ones defined in core layer of EOSIO, that's where their implementation + * actually is done. + * They are present here only so they can show up in the abi file and thus user can send them * to this contract, but they have no specific implementation at this contract level, - * they will execute the implementation at the core level and nothing else. + * they will execute the implementation at the core layer and nothing else. */ /** - * New account action - * - * @details Called after a new account is created. This code enforces resource-limits rules + * New account action is called after a new account is created. This code enforces resource-limits rules * for new accounts as well as new account naming conventions. * * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 @@ -163,9 +157,7 @@ namespace eosiosystem { ignore active); /** - * Update authorization action. - * - * @details Updates pemission for an account + * Update authorization action updates pemission for an account. * * @param account - the account for which the permission is updated * @param pemission - the permission name which is updated @@ -179,9 +171,7 @@ namespace eosiosystem { ignore auth ) {} /** - * Delete authorization action. - * - * @details Deletes the authorization for an account's permision. + * Delete authorization action deletes the authorization for an account's permission. * * @param account - the account for which the permission authorization is deleted, * @param permission - the permission name been deleted. @@ -191,9 +181,7 @@ namespace eosiosystem { ignore permission ) {} /** - * Link authorization action. - * - * @details Assigns a specific action from a contract to a permission you have created. Five system + * Link authorization action assigns a specific action from a contract to a permission you have created. Five system * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the * action needed to be authorized (and the contract belonging to), and looks up which permission @@ -214,9 +202,7 @@ namespace eosiosystem { ignore requirement ) {} /** - * Unlink authorization action. - * - * @details It's doing the reverse of linkauth action, by unlinking the given action. + * Unlink authorization action it's doing the reverse of linkauth action, by unlinking the given action. * * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, * @param code - the owner of the action to be unlinked, @@ -228,9 +214,7 @@ namespace eosiosystem { ignore type ) {} /** - * Cancel delay action. - * - * @details Cancels a deferred transaction. + * Cancel delay action cancels a deferred transaction. * * @param canceling_auth - the permission that authorizes this action, * @param trx_id - the deferred transaction id to be cancelled. @@ -239,9 +223,7 @@ namespace eosiosystem { void canceldelay( ignore canceling_auth, ignore trx_id ) {} /** - * On error action. - * - * @details Notification of this action is delivered to the sender of a deferred transaction + * On error action, notification of this action is delivered to the sender of a deferred transaction * when an objective error occurs while executing the deferred transaction. * This action is not meant to be called directly. * @@ -252,9 +234,7 @@ namespace eosiosystem { void onerror( ignore sender_id, ignore> sent_trx ); /** - * Set abi action. - * - * @details Sets the contract abi for an account. + * Set abi action sets the contract abi for an account. * * @param account - the account for which to set the contract abi. * @param abi - the abi content to be set, in the form of a blob binary. @@ -263,9 +243,7 @@ namespace eosiosystem { void setabi( const name& account, const std::vector& abi ); /** - * Set code action. - * - * @details Sets the contract code for an account. + * Set code action sets the contract code for an account. * * @param account - the account for which to set the contract code. * @param vmtype - reserved, set it to zero. diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index d5e20164..380d11b1 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -15,7 +15,7 @@ namespace eosio { /** * eosio.token contract defines the structures and actions that allow users to create, issue, and manage - * tokens on eosio based blockchains. + * tokens on EOSIO based blockchains. */ class [[eosio::contract("eosio.token")]] token : public contract { public: diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp index 6833c94a..c6fdbe24 100644 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -10,7 +10,7 @@ namespace eosio { * @ingroup eosiocontracts * eosio.wrap contract simplifies Block Producer superuser actions by making them more readable and easier to audit. - * @details It does not grant block producers any additional powers that do not already exist within the + * It does not grant block producers any additional powers that do not already exist within the * system. Currently, 15/21 block producers can already change an account's keys or modify an * account's contract at the request of ECAF or an account's owner. However, the current method * is opaque and leaves undesirable side effects on specific system accounts. @@ -24,7 +24,7 @@ namespace eosio { /** * Execute action. * - * @details Execute a transaction while bypassing regular authorization checks. + * Execute a transaction while bypassing regular authorization checks. * * @param executer - account executing the transaction, * @param trx - the transaction to be executed. From 121aab88b4e51d6856b969400b7573c1915892a1 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Fri, 24 Jan 2020 16:17:10 -0500 Subject: [PATCH 1004/1048] Testing Actions. --- .github/workflows/main.yml | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100644 .github/workflows/main.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..36e3b701 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,48 @@ +name: Pull Request +on: [push] + +jobs: + start-job: + name: Start Job + runs-on: ubuntu-latest + steps: + - name: Start Job. + run: echo "PR created. Builds will be triggered here for forked PRs or Buildkite for internal PRs." + + + ubuntu-1804-build: + # if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + name: Ubuntu 18.04 | Build + runs-on: ubuntu-latest + needs: start-job + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Build + run: | + ./.cicd/build.sh + tar -pczf build.tar.gz build + - name: Upload Build Artifact + uses: actions/upload-artifact@v1 + with: + name: ubuntu-1804-build + path: build.tar.gz + ubuntu-1804-parallel-test: + name: Ubuntu 18.04 | Unit Test + runs-on: ubuntu-latest + needs: ubuntu-1804-build + steps: + - name: Checkout + uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e + with: + submodules: recursive + - name: Download Build Artifact + uses: actions/download-artifact@v1 + with: + name: ubuntu-1804-build + - name: Parallel Test + run: | + tar -xzf ubuntu-1804-build/build.tar.gz + ./.cicd/test.sh \ No newline at end of file From 46eab655dec2a2901f6c606f3a042942b53c8cb5 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Fri, 24 Jan 2020 16:24:46 -0500 Subject: [PATCH 1005/1048] Debug test step in Actions. --- .github/workflows/main.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 36e3b701..c852368c 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,4 +45,5 @@ jobs: - name: Parallel Test run: | tar -xzf ubuntu-1804-build/build.tar.gz + ./.cicd/helpers/dependency-info.sh ./.cicd/test.sh \ No newline at end of file From c8e9be50c6e5ea09417d220a54f857caedac19a2 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Fri, 24 Jan 2020 16:31:13 -0500 Subject: [PATCH 1006/1048] Debug test step in Actions. --- .cicd/test.sh | 3 +++ .github/workflows/main.yml | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/.cicd/test.sh b/.cicd/test.sh index bdb8473e..61389035 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -7,6 +7,9 @@ if [[ "$BUILDKITE" == 'true' ]]; then CDT_URL="$(buildkite-agent meta-data get cdt-url)" CDT_VERSION="$(buildkite-agent meta-data get cdt-version)" DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" +else # Actions + . ./.cicd/helpers/dependency-info.sh + DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="dpkg -i $MOUNTED_DIR/eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c852368c..3ed0cad2 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -45,5 +45,4 @@ jobs: - name: Parallel Test run: | tar -xzf ubuntu-1804-build/build.tar.gz - ./.cicd/helpers/dependency-info.sh - ./.cicd/test.sh \ No newline at end of file + ./.cicd/test.sh From 5b057c14d60953ceb403ad764e925d4b0a37adcd Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Fri, 24 Jan 2020 16:50:45 -0500 Subject: [PATCH 1007/1048] Remove Travis. --- .travis.yml | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index c1d0e8ee..00000000 --- a/.travis.yml +++ /dev/null @@ -1,13 +0,0 @@ -language: cpp -git: - depth: false -if: fork = true OR type = api OR type = cron -matrix: - include: - - os: linux - dist: xenial - services: docker -script: ". ./.cicd/build.sh && ./.cicd/test.sh" -notifications: - webhooks: - secure: CEIaN/RNCYALwL+QgBhVlyq5DvomyMcmB+gUfdDabxJk55misbIAXkj7l3+1dvq4EeB8Vw3vSKAimfjpj0hGCopOPxPsE5SPYWx3czI7cBPvuu3S4NSmx6WEe+pjI3IexUVQXRLazhvvwB6D/vZnFlr3ECYj59K0fGoYOKW14oG2RLVP7Clx3qoo1O8y7F+Ia6fEp/Q4pvwgFKnUL4hJrCUefJwSKDH8Nxf4FF5U41RLE8Xhdqxo1zbZBpT30gaPERzBnTCO3ko5NIEI/WPruQgcRr/PVDTG1xYZ2XqImDb/fHZKqkOJSoOTH+2U2KBxfXCwLPzkz6CkpJ7v14VL4qoV/F5DA9/fTSB4+B6IWusFF8NhstMmeCw0vkfaO/8WW8VEYHXnlTPFAQZJEiEyIYDcyVnUXur0yFEkvr4ZdGDmUEv/AdClVJ7Ig7T4MF2K66Yqtj930VQhI5PSWMKIWFG+2eboBrmXet+Z+2GRhwCGm5knB4/bcDcg9E80cwUWVol6AxVO07n70Qx57qX9Tvz/Ay9ugtEY+xSDQQ+HkFw62MiPDsNhSFoUD+TNY+SnEe1qnciKhb2/1bNTkKMPjifjJmDWkfC07qrXsDBcj4cIgfj6vh8lBj7U6kg7vCjXeJeljgu0wcTDd+EprDHpfRwkoXi9UsnSw2HXAveZMP4= \ No newline at end of file From 429bb40eec3bc91c2f3693ef0402e8f7a37fb554 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Mon, 27 Jan 2020 11:22:06 -0500 Subject: [PATCH 1008/1048] Setup to only run on forked PRs. --- .github/workflows/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3ed0cad2..a669a810 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,5 +1,5 @@ name: Pull Request -on: [push] +on: [pull_request] jobs: start-job: @@ -11,7 +11,7 @@ jobs: ubuntu-1804-build: - # if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id + if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id name: Ubuntu 18.04 | Build runs-on: ubuntu-latest needs: start-job From 1f819150bd2d1e3d7c53d39f57ff82e5d24fe376 Mon Sep 17 00:00:00 2001 From: arhag Date: Thu, 30 Jan 2020 15:13:57 -0500 Subject: [PATCH 1009/1048] move old (v1.2.1) eosio.msig and eosio.system contracts to new location; add v1.8.3 eosio.system contract --- tests/contracts.hpp.in | 10 +- .../v1.2.1/eosio.msig}/Readme.txt | 0 .../v1.2.1/eosio.msig}/eosio.msig.abi | 0 .../v1.2.1/eosio.msig}/eosio.msig.wasm | Bin .../v1.2.1/eosio.system/README.txt} | 0 .../v1.2.1/eosio.system/Readme.txt | 3 + .../v1.2.1/eosio.system}/eosio.system.abi | 0 .../v1.2.1/eosio.system}/eosio.system.wasm | Bin .../v1.8.3/eosio.system/README.txt | 3 + .../v1.8.3/eosio.system/eosio.system.abi | 2097 +++++++++++++++++ .../v1.8.3/eosio.system/eosio.system.wasm | Bin 0 -> 263877 bytes 11 files changed, 2109 insertions(+), 4 deletions(-) rename tests/test_contracts/{eosio.msig.old => old_versions/v1.2.1/eosio.msig}/Readme.txt (100%) rename tests/test_contracts/{eosio.msig.old => old_versions/v1.2.1/eosio.msig}/eosio.msig.abi (100%) rename tests/test_contracts/{eosio.msig.old => old_versions/v1.2.1/eosio.msig}/eosio.msig.wasm (100%) rename tests/test_contracts/{eosio.system.old/Readme.txt => old_versions/v1.2.1/eosio.system/README.txt} (100%) create mode 100644 tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt rename tests/test_contracts/{eosio.system.old => old_versions/v1.2.1/eosio.system}/eosio.system.abi (100%) rename tests/test_contracts/{eosio.system.old => old_versions/v1.2.1/eosio.system}/eosio.system.wasm (100%) create mode 100644 tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt create mode 100644 tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi create mode 100755 tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm diff --git a/tests/contracts.hpp.in b/tests/contracts.hpp.in index f7780d3e..ad6e090d 100644 --- a/tests/contracts.hpp.in +++ b/tests/contracts.hpp.in @@ -18,10 +18,12 @@ struct contracts { struct util { static std::vector reject_all_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/reject_all.wasm"); } static std::vector exchange_wasm() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/exchange.wasm"); } - static std::vector system_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/eosio.system.old/eosio.system.wasm"); } - static std::vector system_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.system.old/eosio.system.abi"); } - static std::vector msig_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old/eosio.msig.wasm"); } - static std::vector msig_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/eosio.msig.old/eosio.msig.abi"); } + static std::vector system_wasm_v1_8() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm"); } + static std::vector system_abi_v1_8() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi"); } + static std::vector system_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm"); } + static std::vector system_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi"); } + static std::vector msig_wasm_old() { return read_wasm("${CMAKE_SOURCE_DIR}/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.wasm"); } + static std::vector msig_abi_old() { return read_abi("${CMAKE_SOURCE_DIR}/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.abi"); } }; }; }} //ns eosio::testing diff --git a/tests/test_contracts/eosio.msig.old/Readme.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.msig/Readme.txt similarity index 100% rename from tests/test_contracts/eosio.msig.old/Readme.txt rename to tests/test_contracts/old_versions/v1.2.1/eosio.msig/Readme.txt diff --git a/tests/test_contracts/eosio.msig.old/eosio.msig.abi b/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.abi similarity index 100% rename from tests/test_contracts/eosio.msig.old/eosio.msig.abi rename to tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.abi diff --git a/tests/test_contracts/eosio.msig.old/eosio.msig.wasm b/tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.wasm similarity index 100% rename from tests/test_contracts/eosio.msig.old/eosio.msig.wasm rename to tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.wasm diff --git a/tests/test_contracts/eosio.system.old/Readme.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt similarity index 100% rename from tests/test_contracts/eosio.system.old/Readme.txt rename to tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt new file mode 100644 index 00000000..a9aa16fb --- /dev/null +++ b/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt @@ -0,0 +1,3 @@ +Compiled with +eosio.contracts: bf28f8bbf9ee753966c95c586906e82d72f9dfac (v1.2.1) +eosio.wasmsdk: 2c106a018f2e69d34325ef2376cf085426068e93, CORE_SYMBOL_NAME = "SYS" diff --git a/tests/test_contracts/eosio.system.old/eosio.system.abi b/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi similarity index 100% rename from tests/test_contracts/eosio.system.old/eosio.system.abi rename to tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi diff --git a/tests/test_contracts/eosio.system.old/eosio.system.wasm b/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm similarity index 100% rename from tests/test_contracts/eosio.system.old/eosio.system.wasm rename to tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt b/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt new file mode 100644 index 00000000..61c7b168 --- /dev/null +++ b/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt @@ -0,0 +1,3 @@ +Compiled with +eosio.contracts: 7109f002fa9afff18edcafce5c32b224a21eef98 (v1.8.3) +eosio.cdt: 263e41cbb3e58dca71117401f43be104f1e58ae4 (v1.6.3) diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi b/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi new file mode 100644 index 00000000..65afebad --- /dev/null +++ b/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi @@ -0,0 +1,2097 @@ +{ + "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", + "version": "eosio::abi/1.1", + "types": [], + "structs": [ + { + "name": "abi_hash", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "hash", + "type": "checksum256" + } + ] + }, + { + "name": "activate", + "base": "", + "fields": [ + { + "name": "feature_digest", + "type": "checksum256" + } + ] + }, + { + "name": "authority", + "base": "", + "fields": [ + { + "name": "threshold", + "type": "uint32" + }, + { + "name": "keys", + "type": "key_weight[]" + }, + { + "name": "accounts", + "type": "permission_level_weight[]" + }, + { + "name": "waits", + "type": "wait_weight[]" + } + ] + }, + { + "name": "bid_refund", + "base": "", + "fields": [ + { + "name": "bidder", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "bidname", + "base": "", + "fields": [ + { + "name": "bidder", + "type": "name" + }, + { + "name": "newname", + "type": "name" + }, + { + "name": "bid", + "type": "asset" + } + ] + }, + { + "name": "bidrefund", + "base": "", + "fields": [ + { + "name": "bidder", + "type": "name" + }, + { + "name": "newname", + "type": "name" + } + ] + }, + { + "name": "block_header", + "base": "", + "fields": [ + { + "name": "timestamp", + "type": "uint32" + }, + { + "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": "blockchain_parameters", + "base": "", + "fields": [ + { + "name": "max_block_net_usage", + "type": "uint64" + }, + { + "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": "uint32" + }, + { + "name": "max_inline_action_depth", + "type": "uint16" + }, + { + "name": "max_authority_depth", + "type": "uint16" + } + ] + }, + { + "name": "buyram", + "base": "", + "fields": [ + { + "name": "payer", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "quant", + "type": "asset" + } + ] + }, + { + "name": "buyrambytes", + "base": "", + "fields": [ + { + "name": "payer", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "bytes", + "type": "uint32" + } + ] + }, + { + "name": "buyrex", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "canceldelay", + "base": "", + "fields": [ + { + "name": "canceling_auth", + "type": "permission_level" + }, + { + "name": "trx_id", + "type": "checksum256" + } + ] + }, + { + "name": "claimrewards", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "closerex", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "cnclrexorder", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "connector", + "base": "", + "fields": [ + { + "name": "balance", + "type": "asset" + }, + { + "name": "weight", + "type": "float64" + } + ] + }, + { + "name": "consolidate", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "defcpuloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "defnetloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "delegatebw", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "stake_net_quantity", + "type": "asset" + }, + { + "name": "stake_cpu_quantity", + "type": "asset" + }, + { + "name": "transfer", + "type": "bool" + } + ] + }, + { + "name": "delegated_bandwidth", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "to", + "type": "name" + }, + { + "name": "net_weight", + "type": "asset" + }, + { + "name": "cpu_weight", + "type": "asset" + } + ] + }, + { + "name": "deleteauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "permission", + "type": "name" + } + ] + }, + { + "name": "deposit", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + }, + { + "name": "eosio_global_state", + "base": "blockchain_parameters", + "fields": [ + { + "name": "max_ram_size", + "type": "uint64" + }, + { + "name": "total_ram_bytes_reserved", + "type": "uint64" + }, + { + "name": "total_ram_stake", + "type": "int64" + }, + { + "name": "last_producer_schedule_update", + "type": "block_timestamp_type" + }, + { + "name": "last_pervote_bucket_fill", + "type": "time_point" + }, + { + "name": "pervote_bucket", + "type": "int64" + }, + { + "name": "perblock_bucket", + "type": "int64" + }, + { + "name": "total_unpaid_blocks", + "type": "uint32" + }, + { + "name": "total_activated_stake", + "type": "int64" + }, + { + "name": "thresh_activated_stake_time", + "type": "time_point" + }, + { + "name": "last_producer_schedule_size", + "type": "uint16" + }, + { + "name": "total_producer_vote_weight", + "type": "float64" + }, + { + "name": "last_name_close", + "type": "block_timestamp_type" + } + ] + }, + { + "name": "eosio_global_state2", + "base": "", + "fields": [ + { + "name": "new_ram_per_block", + "type": "uint16" + }, + { + "name": "last_ram_increase", + "type": "block_timestamp_type" + }, + { + "name": "last_block_num", + "type": "block_timestamp_type" + }, + { + "name": "total_producer_votepay_share", + "type": "float64" + }, + { + "name": "revision", + "type": "uint8" + } + ] + }, + { + "name": "eosio_global_state3", + "base": "", + "fields": [ + { + "name": "last_vpay_state_update", + "type": "time_point" + }, + { + "name": "total_vpay_share_change_rate", + "type": "float64" + } + ] + }, + { + "name": "eosio_global_state4", + "base": "", + "fields": [ + { + "name": "continuous_rate", + "type": "float64" + }, + { + "name": "inflation_pay_factor", + "type": "int64" + }, + { + "name": "votepay_factor", + "type": "int64" + } + ] + }, + { + "name": "exchange_state", + "base": "", + "fields": [ + { + "name": "supply", + "type": "asset" + }, + { + "name": "base", + "type": "connector" + }, + { + "name": "quote", + "type": "connector" + } + ] + }, + { + "name": "fundcpuloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "payment", + "type": "asset" + } + ] + }, + { + "name": "fundnetloan", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "payment", + "type": "asset" + } + ] + }, + { + "name": "init", + "base": "", + "fields": [ + { + "name": "version", + "type": "varuint32" + }, + { + "name": "core", + "type": "symbol" + } + ] + }, + { + "name": "key_weight", + "base": "", + "fields": [ + { + "name": "key", + "type": "public_key" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "linkauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "code", + "type": "name" + }, + { + "name": "type", + "type": "name" + }, + { + "name": "requirement", + "type": "name" + } + ] + }, + { + "name": "mvfrsavings", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "rex", + "type": "asset" + } + ] + }, + { + "name": "mvtosavings", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "rex", + "type": "asset" + } + ] + }, + { + "name": "name_bid", + "base": "", + "fields": [ + { + "name": "newname", + "type": "name" + }, + { + "name": "high_bidder", + "type": "name" + }, + { + "name": "high_bid", + "type": "int64" + }, + { + "name": "last_bid_time", + "type": "time_point" + } + ] + }, + { + "name": "newaccount", + "base": "", + "fields": [ + { + "name": "creator", + "type": "name" + }, + { + "name": "name", + "type": "name" + }, + { + "name": "owner", + "type": "authority" + }, + { + "name": "active", + "type": "authority" + } + ] + }, + { + "name": "onblock", + "base": "", + "fields": [ + { + "name": "header", + "type": "block_header" + } + ] + }, + { + "name": "onerror", + "base": "", + "fields": [ + { + "name": "sender_id", + "type": "uint128" + }, + { + "name": "sent_trx", + "type": "bytes" + } + ] + }, + { + "name": "pair_time_point_sec_int64", + "base": "", + "fields": [ + { + "name": "key", + "type": "time_point_sec" + }, + { + "name": "value", + "type": "int64" + } + ] + }, + { + "name": "permission_level", + "base": "", + "fields": [ + { + "name": "actor", + "type": "name" + }, + { + "name": "permission", + "type": "name" + } + ] + }, + { + "name": "permission_level_weight", + "base": "", + "fields": [ + { + "name": "permission", + "type": "permission_level" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "producer_info", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "total_votes", + "type": "float64" + }, + { + "name": "producer_key", + "type": "public_key" + }, + { + "name": "is_active", + "type": "bool" + }, + { + "name": "url", + "type": "string" + }, + { + "name": "unpaid_blocks", + "type": "uint32" + }, + { + "name": "last_claim_time", + "type": "time_point" + }, + { + "name": "location", + "type": "uint16" + } + ] + }, + { + "name": "producer_info2", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "votepay_share", + "type": "float64" + }, + { + "name": "last_votepay_share_update", + "type": "time_point" + } + ] + }, + { + "name": "producer_key", + "base": "", + "fields": [ + { + "name": "producer_name", + "type": "name" + }, + { + "name": "block_signing_key", + "type": "public_key" + } + ] + }, + { + "name": "producer_schedule", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint32" + }, + { + "name": "producers", + "type": "producer_key[]" + } + ] + }, + { + "name": "refund", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "refund_request", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "request_time", + "type": "time_point_sec" + }, + { + "name": "net_amount", + "type": "asset" + }, + { + "name": "cpu_amount", + "type": "asset" + } + ] + }, + { + "name": "regproducer", + "base": "", + "fields": [ + { + "name": "producer", + "type": "name" + }, + { + "name": "producer_key", + "type": "public_key" + }, + { + "name": "url", + "type": "string" + }, + { + "name": "location", + "type": "uint16" + } + ] + }, + { + "name": "regproxy", + "base": "", + "fields": [ + { + "name": "proxy", + "type": "name" + }, + { + "name": "isproxy", + "type": "bool" + } + ] + }, + { + "name": "rentcpu", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "loan_payment", + "type": "asset" + }, + { + "name": "loan_fund", + "type": "asset" + } + ] + }, + { + "name": "rentnet", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "loan_payment", + "type": "asset" + }, + { + "name": "loan_fund", + "type": "asset" + } + ] + }, + { + "name": "rex_balance", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "owner", + "type": "name" + }, + { + "name": "vote_stake", + "type": "asset" + }, + { + "name": "rex_balance", + "type": "asset" + }, + { + "name": "matured_rex", + "type": "int64" + }, + { + "name": "rex_maturities", + "type": "pair_time_point_sec_int64[]" + } + ] + }, + { + "name": "rex_fund", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "owner", + "type": "name" + }, + { + "name": "balance", + "type": "asset" + } + ] + }, + { + "name": "rex_loan", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "payment", + "type": "asset" + }, + { + "name": "balance", + "type": "asset" + }, + { + "name": "total_staked", + "type": "asset" + }, + { + "name": "loan_num", + "type": "uint64" + }, + { + "name": "expiration", + "type": "time_point" + } + ] + }, + { + "name": "rex_order", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "owner", + "type": "name" + }, + { + "name": "rex_requested", + "type": "asset" + }, + { + "name": "proceeds", + "type": "asset" + }, + { + "name": "stake_change", + "type": "asset" + }, + { + "name": "order_time", + "type": "time_point" + }, + { + "name": "is_open", + "type": "bool" + } + ] + }, + { + "name": "rex_pool", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "total_lent", + "type": "asset" + }, + { + "name": "total_unlent", + "type": "asset" + }, + { + "name": "total_rent", + "type": "asset" + }, + { + "name": "total_lendable", + "type": "asset" + }, + { + "name": "total_rex", + "type": "asset" + }, + { + "name": "namebid_proceeds", + "type": "asset" + }, + { + "name": "loan_num", + "type": "uint64" + } + ] + }, + { + "name": "rex_return_buckets", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "return_buckets", + "type": "pair_time_point_sec_int64[]" + } + ] + }, + { + "name": "rex_return_pool", + "base": "", + "fields": [ + { + "name": "version", + "type": "uint8" + }, + { + "name": "last_dist_time", + "type": "time_point_sec" + }, + { + "name": "pending_bucket_time", + "type": "time_point_sec" + }, + { + "name": "oldest_bucket_time", + "type": "time_point_sec" + }, + { + "name": "pending_bucket_proceeds", + "type": "int64" + }, + { + "name": "current_rate_of_increase", + "type": "int64" + }, + { + "name": "proceeds", + "type": "int64" + } + ] + }, + { + "name": "rexexec", + "base": "", + "fields": [ + { + "name": "user", + "type": "name" + }, + { + "name": "max", + "type": "uint16" + } + ] + }, + { + "name": "rmvproducer", + "base": "", + "fields": [ + { + "name": "producer", + "type": "name" + } + ] + }, + { + "name": "sellram", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "bytes", + "type": "int64" + } + ] + }, + { + "name": "sellrex", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "rex", + "type": "asset" + } + ] + }, + { + "name": "setabi", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "abi", + "type": "bytes" + } + ] + }, + { + "name": "setacctcpu", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "cpu_weight", + "type": "int64?" + } + ] + }, + { + "name": "setacctnet", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "net_weight", + "type": "int64?" + } + ] + }, + { + "name": "setacctram", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "ram_bytes", + "type": "int64?" + } + ] + }, + { + "name": "setalimits", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "ram_bytes", + "type": "int64" + }, + { + "name": "net_weight", + "type": "int64" + }, + { + "name": "cpu_weight", + "type": "int64" + } + ] + }, + { + "name": "setcode", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "vmtype", + "type": "uint8" + }, + { + "name": "vmversion", + "type": "uint8" + }, + { + "name": "code", + "type": "bytes" + } + ] + }, + { + "name": "setinflation", + "base": "", + "fields": [ + { + "name": "annual_rate", + "type": "int64" + }, + { + "name": "inflation_pay_factor", + "type": "int64" + }, + { + "name": "votepay_factor", + "type": "int64" + } + ] + }, + { + "name": "setparams", + "base": "", + "fields": [ + { + "name": "params", + "type": "blockchain_parameters" + } + ] + }, + { + "name": "setpriv", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "is_priv", + "type": "uint8" + } + ] + }, + { + "name": "setram", + "base": "", + "fields": [ + { + "name": "max_ram_size", + "type": "uint64" + } + ] + }, + { + "name": "setramrate", + "base": "", + "fields": [ + { + "name": "bytes_per_block", + "type": "uint16" + } + ] + }, + { + "name": "setrex", + "base": "", + "fields": [ + { + "name": "balance", + "type": "asset" + } + ] + }, + { + "name": "undelegatebw", + "base": "", + "fields": [ + { + "name": "from", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "unstake_net_quantity", + "type": "asset" + }, + { + "name": "unstake_cpu_quantity", + "type": "asset" + } + ] + }, + { + "name": "unlinkauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "code", + "type": "name" + }, + { + "name": "type", + "type": "name" + } + ] + }, + { + "name": "unregprod", + "base": "", + "fields": [ + { + "name": "producer", + "type": "name" + } + ] + }, + { + "name": "unstaketorex", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "receiver", + "type": "name" + }, + { + "name": "from_net", + "type": "asset" + }, + { + "name": "from_cpu", + "type": "asset" + } + ] + }, + { + "name": "updateauth", + "base": "", + "fields": [ + { + "name": "account", + "type": "name" + }, + { + "name": "permission", + "type": "name" + }, + { + "name": "parent", + "type": "name" + }, + { + "name": "auth", + "type": "authority" + } + ] + }, + { + "name": "updaterex", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + } + ] + }, + { + "name": "updtrevision", + "base": "", + "fields": [ + { + "name": "revision", + "type": "uint8" + } + ] + }, + { + "name": "user_resources", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "net_weight", + "type": "asset" + }, + { + "name": "cpu_weight", + "type": "asset" + }, + { + "name": "ram_bytes", + "type": "int64" + } + ] + }, + { + "name": "voteproducer", + "base": "", + "fields": [ + { + "name": "voter", + "type": "name" + }, + { + "name": "proxy", + "type": "name" + }, + { + "name": "producers", + "type": "name[]" + } + ] + }, + { + "name": "voter_info", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "proxy", + "type": "name" + }, + { + "name": "producers", + "type": "name[]" + }, + { + "name": "staked", + "type": "int64" + }, + { + "name": "last_vote_weight", + "type": "float64" + }, + { + "name": "proxied_vote_weight", + "type": "float64" + }, + { + "name": "is_proxy", + "type": "bool" + }, + { + "name": "flags1", + "type": "uint32" + }, + { + "name": "reserved2", + "type": "uint32" + }, + { + "name": "reserved3", + "type": "asset" + } + ] + }, + { + "name": "wait_weight", + "base": "", + "fields": [ + { + "name": "wait_sec", + "type": "uint32" + }, + { + "name": "weight", + "type": "uint16" + } + ] + }, + { + "name": "withdraw", + "base": "", + "fields": [ + { + "name": "owner", + "type": "name" + }, + { + "name": "amount", + "type": "asset" + } + ] + } + ], + "actions": [ + { + "name": "activate", + "type": "activate", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Activate Protocol Feature\nsummary: 'Activate protocol feature {{nowrap feature_digest}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} activates the protocol feature with a digest of {{feature_digest}}." + }, + { + "name": "bidname", + "type": "bidname", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Bid On a Premium Account Name\nsummary: '{{nowrap bidder}} bids on the premium account name {{nowrap newname}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{bidder}} bids {{bid}} on an auction to own the premium account name {{newname}}.\n\n{{bidder}} transfers {{bid}} to the system to cover the cost of the bid, which will be returned to {{bidder}} only if {{bidder}} is later outbid in the auction for {{newname}} by another account.\n\nIf the auction for {{newname}} closes with {{bidder}} remaining as the highest bidder, {{bidder}} will be authorized to create the account with name {{newname}}.\n\n## Bid refund behavior\n\nIf {{bidder}}’s bid on {{newname}} is later outbid by another account, {{bidder}} will be able to claim back the transferred amount of {{bid}}. The system will attempt to automatically do this on behalf of {{bidder}}, but the automatic refund may occasionally fail which will then require {{bidder}} to manually claim the refund with the bidrefund action.\n\n## Auction close criteria\n\nThe system should automatically close the auction for {{newname}} if it satisfies the condition that over a period of two minutes the following two properties continuously hold:\n\n- no one has bid on {{newname}} within the last 24 hours;\n- and, the value of the latest bid on {{newname}} is greater than the value of the bids on each of the other open auctions.\n\nBe aware that the condition to close the auction described above are sufficient but not necessary. The auction for {{newname}} cannot close unless both of the properties are simultaneously satisfied, but it may be closed without requiring the properties to hold for a period of 2 minutes." + }, + { + "name": "bidrefund", + "type": "bidrefund", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Refund on Name Bid\nsummary: 'Claim refund on {{nowrap newname}} bid'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{bidder}} claims refund on {{newname}} bid after being outbid by someone else." + }, + { + "name": "buyram", + "type": "buyram", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy RAM\nsummary: '{{nowrap payer}} buys RAM on behalf of {{nowrap receiver}} by paying {{nowrap quant}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{payer}} buys RAM on behalf of {{receiver}} by paying {{quant}}. This transaction will incur a 0.5% fee out of {{quant}} and the amount of RAM delivered will depend on market rates." + }, + { + "name": "buyrambytes", + "type": "buyrambytes", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy RAM\nsummary: '{{nowrap payer}} buys {{nowrap bytes}} bytes of RAM on behalf of {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{payer}} buys approximately {{bytes}} bytes of RAM on behalf of {{receiver}} by paying market rates for RAM. This transaction will incur a 0.5% fee and the cost will depend on market rates." + }, + { + "name": "buyrex", + "type": "buyrex", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy REX Tokens\nsummary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{amount}} is taken out of {{from}}’s REX fund and used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{from}} must have voted for a proxy or at least 21 block producers. {{amount}} is added to {{from}}’s vote stake.\n\nA sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately." + }, + { + "name": "canceldelay", + "type": "canceldelay", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cancel Delayed Transaction\nsummary: '{{nowrap canceling_auth.actor}} cancels a delayed transaction'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{canceling_auth.actor}} cancels the delayed transaction with id {{trx_id}}." + }, + { + "name": "claimrewards", + "type": "claimrewards", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Block Producer Rewards\nsummary: '{{nowrap owner}} claims block and vote rewards'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{owner}} claims block and vote rewards from the system." + }, + { + "name": "closerex", + "type": "closerex", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cleanup Unused REX Data\nsummary: 'Delete REX related DB entries and free associated RAM'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nDelete REX related DB entries and free associated RAM for {{owner}}.\n\nTo fully delete all REX related DB entries, {{owner}} must ensure that their REX balance and REX fund amounts are both zero and they have no outstanding loans." + }, + { + "name": "cnclrexorder", + "type": "cnclrexorder", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cancel Scheduled REX Sell Order\nsummary: '{{nowrap owner}} cancels a scheduled sell order if not yet filled'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} cancels their open sell order." + }, + { + "name": "consolidate", + "type": "consolidate", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Consolidate REX Maturity Buckets Into One\nsummary: 'Consolidate REX maturity buckets into one'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nConsolidate REX maturity buckets into one bucket that {{owner}} will not be able to sell until 4 to 5 days later." + }, + { + "name": "defcpuloan", + "type": "defcpuloan", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from the Fund of a Specific CPU Loan\nsummary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of CPU loan number {{nowrap loan_num}} back to REX fund'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{amount}} from the fund of CPU loan number {{loan_num}} back to REX fund." + }, + { + "name": "defnetloan", + "type": "defnetloan", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from the Fund of a Specific NET Loan\nsummary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of NET loan number {{nowrap loan_num}} back to REX fund'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{amount}} from the fund of NET loan number {{loan_num}} back to REX fund." + }, + { + "name": "delegatebw", + "type": "delegatebw", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Stake Tokens for NET and/or CPU\nsummary: 'Stake tokens for NET and/or CPU and optionally transfer ownership'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{#if transfer}} {{from}} stakes on behalf of {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth.\n\nStaked tokens will also be transferred to {{receiver}}. The sum of these two quantities will be deducted from {{from}}’s liquid balance and add to the vote weight of {{receiver}}.\n{{else}}\n{{from}} stakes to self and delegates to {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth.\n\nThe sum of these two quantities add to the vote weight of {{from}}.\n{{/if}}" + }, + { + "name": "deleteauth", + "type": "deleteauth", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Delete Account Permission\nsummary: 'Delete the {{nowrap permission}} permission of {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDelete the {{permission}} permission of {{account}}." + }, + { + "name": "deposit", + "type": "deposit", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit Into REX Fund\nsummary: 'Add to {{nowrap owner}}’s REX fund by transferring {{nowrap amount}} from {{nowrap owner}}’s liquid balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nTransfer {{amount}} from {{owner}}’s liquid balance to {{owner}}’s REX fund. All proceeds and expenses related to REX are added to or taken out of this fund." + }, + { + "name": "fundcpuloan", + "type": "fundcpuloan", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit into the Fund of a Specific CPU Loan\nsummary: '{{nowrap from}} funds a CPU loan'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{payment}} from REX fund to the fund of CPU loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time." + }, + { + "name": "fundnetloan", + "type": "fundnetloan", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit into the Fund of a Specific NET Loan\nsummary: '{{nowrap from}} funds a NET loan'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{payment}} from REX fund to the fund of NET loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time." + }, + { + "name": "init", + "type": "init", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Initialize System Contract\nsummary: 'Initialize system contract'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\nInitialize system contract. The core token symbol will be set to {{core}}." + }, + { + "name": "linkauth", + "type": "linkauth", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Link Action to Permission\nsummary: '{{nowrap account}} sets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract to {{nowrap requirement}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{account}} sets the minimum required permission for the {{#if type}}{{type}} action of the{{/if}} {{code}} contract to {{requirement}}.\n\n{{#if type}}{{else}}Any links explicitly associated to specific actions of {{code}} will take precedence.{{/if}}" + }, + { + "name": "mvfrsavings", + "type": "mvfrsavings", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unlock REX Tokens\nsummary: '{{nowrap owner}} unlocks REX Tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} unlocks {{rex}} by moving it out of the REX savings bucket. The unlocked REX tokens cannot be sold until 4 to 5 days later." + }, + { + "name": "mvtosavings", + "type": "mvtosavings", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Lock REX Tokens\nsummary: '{{nowrap owner}} locks REX Tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} locks {{rex}} by moving it into the REX savings bucket. The locked REX tokens cannot be sold directly and will have to be unlocked explicitly before selling." + }, + { + "name": "newaccount", + "type": "newaccount", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Create New Account\nsummary: '{{nowrap creator}} creates a new account with the name {{nowrap name}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{creator}} creates a new account with the name {{name}} and the following permissions:\n\nowner permission with authority:\n{{to_json owner}}\n\nactive permission with authority:\n{{to_json active}}" + }, + { + "name": "onblock", + "type": "onblock", + "ricardian_contract": "" + }, + { + "name": "onerror", + "type": "onerror", + "ricardian_contract": "" + }, + { + "name": "refund", + "type": "refund", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Unstaked Tokens\nsummary: 'Return previously unstaked tokens to {{nowrap owner}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nReturn previously unstaked tokens to {{owner}} after the unstaking period has elapsed." + }, + { + "name": "regproducer", + "type": "regproducer", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Register as a Block Producer Candidate\nsummary: 'Register {{nowrap producer}} account as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\nRegister {{producer}} account as a block producer candidate.\n\n{{$clauses.BlockProducerAgreement}}" + }, + { + "name": "regproxy", + "type": "regproxy", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Register/unregister as a Proxy\nsummary: 'Register/unregister {{nowrap proxy}} as a proxy account'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{#if isproxy}}\n{{proxy}} registers as a proxy that can vote on behalf of accounts that appoint it as their proxy.\n{{else}}\n{{proxy}} unregisters as a proxy that can vote on behalf of accounts that appoint it as their proxy.\n{{/if}}" + }, + { + "name": "rentcpu", + "type": "rentcpu", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Rent CPU Bandwidth for 30 Days\nsummary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent CPU bandwidth for {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} pays {{loan_payment}} to rent CPU bandwidth on behalf of {{receiver}} for a period of 30 days.\n\n{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s CPU resources. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan.\n\nAt expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s CPU bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s CPU bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund." + }, + { + "name": "rentnet", + "type": "rentnet", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Rent NET Bandwidth for 30 Days\nsummary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent NET bandwidth for {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} pays {{loan_payment}} to rent NET bandwidth on behalf of {{receiver}} for a period of 30 days.\n\n{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s NET resources for 30 days. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan.\n\nAt expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s NET bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s NET bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund." + }, + { + "name": "rexexec", + "type": "rexexec", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Perform REX Maintenance\nsummary: 'Process sell orders and expired loans'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nPerforms REX maintenance by processing a maximum of {{max}} REX sell orders and expired loans. Any account can execute this action." + }, + { + "name": "rmvproducer", + "type": "rmvproducer", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Forcibly Unregister a Block Producer Candidate\nsummary: '{{nowrap producer}} is unregistered as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} unregisters {{producer}} as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered." + }, + { + "name": "sellram", + "type": "sellram", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Sell RAM From Account\nsummary: 'Sell unused RAM from {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\nSell {{bytes}} bytes of unused RAM from account {{account}} at market price. This transaction will incur a 0.5% fee on the proceeds which depend on market rates." + }, + { + "name": "sellrex", + "type": "sellrex", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Sell REX Tokens in Exchange for EOS\nsummary: '{{nowrap from}} sells {{nowrap rex}} tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} initiates a sell order to sell {{rex}} tokens at the market exchange rate during the time at which the order is ultimately executed. If {{from}} already has an open sell order in the sell queue, {{rex}} will be added to the amount of the sell order without change the position of the sell order within the queue. Once the sell order is executed, proceeds are added to {{from}}’s REX fund, the value of sold REX tokens is deducted from {{from}}’s vote stake, and votes are updated accordingly.\n\nDepending on the market conditions, it may not be possible to fill the entire sell order immediately. In such a case, the sell order is added to the back of a sell queue. A sell order at the front of the sell queue will automatically be executed when the market conditions allow for the entire order to be filled. Regardless of the market conditions, the system is designed to execute this sell order within 30 days. {{from}} can cancel the order at any time before it is filled using the cnclrexorder action." + }, + { + "name": "setabi", + "type": "setabi", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deploy Contract ABI\nsummary: 'Deploy contract ABI on account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDeploy the ABI file associated with the contract on account {{account}}." + }, + { + "name": "setacctcpu", + "type": "setacctcpu", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the CPU Quota of Account\nsummary: 'Explicitly manage the CPU bandwidth quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value cpu_weight}}\nExplicitly manage the CPU bandwidth quota of account {{account}} by pinning it to a weight of {{cpu_weight}}.\n\n{{account}} can stake and unstake, however, it will not change their CPU bandwidth quota as long as it remains pinned.\n{{else}}\nUnpin the CPU bandwidth quota of account {{account}}. The CPU bandwidth quota of {{account}} will be driven by the current tokens staked for CPU bandwidth by {{account}}.\n{{/if_has_value}}" + }, + { + "name": "setacctnet", + "type": "setacctnet", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the NET Quota of Account\nsummary: 'Explicitly manage the NET bandwidth quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value net_weight}}\nExplicitly manage the network bandwidth quota of account {{account}} by pinning it to a weight of {{net_weight}}.\n\n{{account}} can stake and unstake, however, it will not change their NET bandwidth quota as long as it remains pinned.\n{{else}}\nUnpin the NET bandwidth quota of account {{account}}. The NET bandwidth quota of {{account}} will be driven by the current tokens staked for NET bandwidth by {{account}}.\n{{/if_has_value}}" + }, + { + "name": "setacctram", + "type": "setacctram", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the RAM Quota of Account\nsummary: 'Explicitly manage the RAM quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value ram_bytes}}\nExplicitly manage the RAM quota of account {{account}} by pinning it to {{ram_bytes}} bytes.\n\n{{account}} can buy and sell RAM, however, it will not change their RAM quota as long as it remains pinned.\n{{else}}\nUnpin the RAM quota of account {{account}}. The RAM quota of {{account}} will be driven by the current RAM holdings of {{account}}.\n{{/if_has_value}}" + }, + { + "name": "setalimits", + "type": "setalimits", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Adjust Resource Limits of Account\nsummary: 'Adjust resource limits of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} updates {{account}}’s resource limits to have a RAM quota of {{ram_bytes}} bytes, a NET bandwidth quota of {{net_weight}} and a CPU bandwidth quota of {{cpu_weight}}." + }, + { + "name": "setcode", + "type": "setcode", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deploy Contract Code\nsummary: 'Deploy contract code on account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDeploy compiled contract code to the account {{account}}." + }, + { + "name": "setinflation", + "type": "setinflation", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set Inflation Parameters\nsummary: 'Set inflation parameters'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets the inflation parameters as follows:\n\n* Annual inflation rate (in units of a hundredth of a percent): {{annual_rate}}\n* Fraction of inflation used to reward block producers: 10000/{{inflation_pay_factor}}\n* Fraction of block producer rewards to be distributed proportional to blocks produced: 10000/{{votepay_factor}}" + }, + { + "name": "setparams", + "type": "setparams", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set System Parameters\nsummary: 'Set System Parameters'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets system parameters to:\n{{to_json params}}" + }, + { + "name": "setpriv", + "type": "setpriv", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Make an Account Privileged or Unprivileged\nsummary: '{{#if is_priv}}Make {{nowrap account}} privileged{{else}}Remove privileged status of {{nowrap account}}{{/if}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if is_priv}}\n{{$action.account}} makes {{account}} privileged.\n{{else}}\n{{$action.account}} removes privileged status of {{account}}.\n{{/if}}" + }, + { + "name": "setram", + "type": "setram", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Configure the Available RAM\nsummary: 'Configure the available RAM'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} configures the available RAM to {{max_ram_size}} bytes." + }, + { + "name": "setramrate", + "type": "setramrate", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set the Rate of Increase of RAM\nsummary: 'Set the rate of increase of RAM per block'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets the rate of increase of RAM to {{bytes_per_block}} bytes/block." + }, + { + "name": "setrex", + "type": "setrex", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Adjust REX Pool Virtual Balance\nsummary: 'Adjust REX Pool Virtual Balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} adjusts REX loan rate by setting REX pool virtual balance to {{balance}}. No token transfer or issue is executed in this action." + }, + { + "name": "undelegatebw", + "type": "undelegatebw", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unstake Tokens for NET and/or CPU\nsummary: 'Unstake tokens for NET and/or CPU from {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{from}} unstakes from {{receiver}} {{unstake_net_quantity}} for NET bandwidth and {{unstake_cpu_quantity}} for CPU bandwidth.\n\nThe sum of these two quantities will be removed from the vote weight of {{receiver}} and will be made available to {{from}} after an uninterrupted 3 day period without further unstaking by {{from}}. After the uninterrupted 3 day period passes, the system will attempt to automatically return the funds to {{from}}’s regular token balance. However, this automatic refund may occasionally fail which will then require {{from}} to manually claim the funds with the refund action." + }, + { + "name": "unlinkauth", + "type": "unlinkauth", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unlink Action from Permission\nsummary: '{{nowrap account}} unsets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{account}} removes the association between the {{#if type}}{{type}} action of the{{/if}} {{code}} contract and its minimum required permission.\n\n{{#if type}}{{else}}This will not remove any links explicitly associated to specific actions of {{code}}.{{/if}}" + }, + { + "name": "unregprod", + "type": "unregprod", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unregister as a Block Producer Candidate\nsummary: '{{nowrap producer}} unregisters as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{producer}} unregisters as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered." + }, + { + "name": "unstaketorex", + "type": "unstaketorex", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy REX Tokens Using Staked Tokens\nsummary: '{{nowrap owner}} buys REX tokens in exchange for tokens currently staked to NET and/or CPU'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from_net}} and {{from_cpu}} are withdrawn from {{receiver}}’s NET and CPU bandwidths respectively. These funds are used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{owner}} must have voted for a proxy or at least 21 block producers.\n\nA sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately." + }, + { + "name": "updateauth", + "type": "updateauth", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Modify Account Permission\nsummary: 'Add or update the {{nowrap permission}} permission of {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nModify, and create if necessary, the {{permission}} permission of {{account}} to have a parent permission of {{parent}} and the following authority:\n{{to_json auth}}" + }, + { + "name": "updaterex", + "type": "updaterex", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Update REX Owner Vote Weight\nsummary: 'Update vote weight to current value of held REX tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nUpdate vote weight of {{owner}} account to current value of held REX tokens." + }, + { + "name": "updtrevision", + "type": "updtrevision", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Update System Contract Revision Number\nsummary: 'Update system contract revision number'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} advances the system contract revision number to {{revision}}." + }, + { + "name": "voteproducer", + "type": "voteproducer", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Vote for Block Producers\nsummary: '{{nowrap voter}} votes for {{#if proxy}}the proxy {{nowrap proxy}}{{else}}up to 30 block producer candidates{{/if}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{#if proxy}}\n{{voter}} votes for the proxy {{proxy}}.\nAt the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the producers voted by {{proxy}}.\n{{else}}\n{{voter}} votes for the following block producer candidates:\n\n{{#each producers}}\n + {{this}}\n{{/each}}\n\nAt the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the above producers.\n{{/if}}" + }, + { + "name": "withdraw", + "type": "withdraw", + "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from REX Fund\nsummary: 'Withdraw {{nowrap amount}} from {{nowrap owner}}’s REX fund by transferring to {{owner}}’s liquid balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nWithdraws {{amount}} from {{owner}}’s REX fund and transfer them to {{owner}}’s liquid balance." + } + ], + "tables": [ + { + "name": "abihash", + "type": "abi_hash", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "bidrefunds", + "type": "bid_refund", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "cpuloan", + "type": "rex_loan", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "delband", + "type": "delegated_bandwidth", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "global", + "type": "eosio_global_state", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "global2", + "type": "eosio_global_state2", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "global3", + "type": "eosio_global_state3", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "global4", + "type": "eosio_global_state4", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "namebids", + "type": "name_bid", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "netloan", + "type": "rex_loan", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "producers", + "type": "producer_info", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "producers2", + "type": "producer_info2", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "rammarket", + "type": "exchange_state", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "refunds", + "type": "refund_request", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "retbuckets", + "type": "rex_return_buckets", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "rexbal", + "type": "rex_balance", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "rexfund", + "type": "rex_fund", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "rexpool", + "type": "rex_pool", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "rexqueue", + "type": "rex_order", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "rexretpool", + "type": "rex_return_pool", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "userres", + "type": "user_resources", + "index_type": "i64", + "key_names": [], + "key_types": [] + }, + { + "name": "voters", + "type": "voter_info", + "index_type": "i64", + "key_names": [], + "key_types": [] + } + ], + "ricardian_clauses": [ + { + "id": "UserAgreement", + "body": "User agreement for the chain can go here." + }, + { + "id": "BlockProducerAgreement", + "body": "I, {{producer}}, hereby nominate myself for consideration as an elected block producer.\n\nIf {{producer}} is selected to produce blocks by the system contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure.\n\nIf {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key.\n\nI acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules.\n\n{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios:\n\n* proposing an objectively valid block at the time appointed by the block scheduling algorithm;\n* pre-confirming a block produced by another producer in the schedule when I find said block objectively valid;\n* and, confirming a block for which {{producer}} has received pre-confirmation messages from more than two-thirds of the active block producers.\n\nI hereby accept liability for any and all provable damages that result from my:\n\n* signing two different block proposals with the same timestamp with {{producer_key}};\n* signing two different block proposals with the same block number with {{producer_key}};\n* signing any block proposal which builds off of an objectively invalid block;\n* signing a pre-confirmation for an objectively invalid block;\n* or, signing a confirmation for a block for which I do not possess pre-confirmation messages from more than two-thirds of the active block producers.\n\nI hereby agree that double-signing for a timestamp or block number in concert with two or more other block producers shall automatically be deemed malicious and cause {{producer}} to be subject to:\n\n* a fine equal to the past year of compensation received,\n* immediate disqualification from being a producer,\n* and/or other damages.\n\nAn exception may be made if {{producer}} can demonstrate that the double-signing occurred due to a bug in the reference software; the burden of proof is on {{producer}}.\n\nI hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract.\n\nI hereby acknowledge that more than two-thirds of the active block producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among block producers.\n\nIf {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least one validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among block producers, said method and reports to be made public.\n\nThe community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers.\n\nI agree to process transactions on a FIFO (first in, first out) best-effort basis and to honestly bill transactions for measured execution time.\n\nI {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: the order in which transactions are included, or the hash of the block that is produced.\n\nI, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my business entity who own more than 10% and all direct shareholders.\n\nI, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain.\n\nI, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract.\n\nI, {{producer}}, agree to set the location value of {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer.\n\nI, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among block producers.\n\nI, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior block producer.\n\nI, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either NET or CPU bandwidth metrics.\n\nI, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by more than two-thirds of active block producers, as shown in the system parameters." + } + ], + "variants": [] +} \ No newline at end of file diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm b/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm new file mode 100755 index 0000000000000000000000000000000000000000..7934a4a9790a1c53055b6df8af1fb95a7f213f98 GIT binary patch literal 263877 zcmeFa3!Gh5dH26B=QeX@l1;cclCi7RK)nP+K`2V`mZGgeQBl#NfLGLLQBhIj`--Af^8fyxwf5QjoH;YO z5Ku4)Wbd>0TF-jcv!2^}*0a_QPF;6q7z9E1q4=rGgJ5}OGk>^j;!n7Fd88jPkKDcg zchmA9+_XI06fBQ6<%Lzpsz#e%9xShJ769IF-l#&G!j1Ot%kAII22pKoQuV5uR0HlN zSYA_IdlFcKz@exxsp^IBiuoNZ5B0x(>iH&t2pt@UiIvuan75SN2o^P(a(8<~BhiHOC+Nq*iqkZ4?^9h}Y_| z%KBpY6N(u`;SNTw1_1b}8isgYWpnhM=Ck9KXPw(z@seeyuR3eRvQ>+Z2_iiiT6y-m zRc9|db=|s^Yu5*{9;NG6u3z?&)n}hJaoQQDt~zVknp4-FdgjXYE7z{$_OywWD_pVK znJdpcZOu!Aiq-jFyQ@=GvBLy<&DyiqoV{-43f-(Y=QQ93HNC8!`jWH3A<(^mQ`P|= zI_;dbYgeANe%bm}XRZwDdVh%8JN2~ntIl0n0%L6qtz9{J&Z@O5mz{df`ZI!tO3!i4 zt~z(s>XrWs{0H>#U_D&Ba^2bItUYbzvem23T(y2(FlcWCy!TC0Z;~97wJT3sN!x23 zHg&K)^Xzk1I&_DZEnB%^{mQdetUG=E=|=}cs@Pn%?DW-VpSphCs`aNk@->z%JM)~? z>ra1TFsuSpvI6Iv)m3E0s&hL#1;a|ESM)01k{#+F~JSC)UBRr~_j zx^rIA0XDR3+4{BToORmz(^pV?u7?F3a#%%ybv#N`ps{A{sFZVn2dT<{Jt}^SAJ2kV#*a37!;TY|tvln?qo1@mn5SCJ;@K12 zlTxWCJ>h8gEb*n*u3EG5%oR^qyvRMSl_Amosq4;Iy?)gbgM$UR!b=ZQ-vvsbJPMpS%|ro^gh$fR(X2j{E- zsB8R@Ds(u{R;}2uY{l8hm-9MWCD)eq+DmEf&iDbBVw7URYi27j#Lb5A?< ztkYJmUbbT8=_}C#D}o~oHzR82S!yLa)yus&g!WHgdFuLeq!XkvppOS~@ER!YALV5n zCSE*Y6cbMv=N!pm{`=rgORLZRo0V%{Lg!WlE#YtwZ;EF|HxowDl5v1;Vt6;O^W3w1 zY>F2ieEy^$Fq8^g&1* zx^UqUpmTH_hDXm^7(aI2!lRFVqOgb;#;(B8^XA1z9~vJ`-A4<~qmBum^d$A2>W3c9 z<8a>5M^pA_kf#Sn&pWyrFPz7pLt~!s$R6{1!91!Q5zkw=SpV?<5#c=Arv^V&mBI@T zJ$B(d{$IERdinpCETkUq1k)~1O)!mI_H4wzkN*r(cK(E-an+ER$Cbf~`L7xuT3r}F zIev<0f5g1_IB+o74u1USk3OU_uTl-yP#tOoVePPZbC^wS51N~U?AsTF`K3M(R!?2C zX7x*hzZhtQK^8WnRTG21e$U*y<4Ta6)V#bIB+pKRG<<$#>DbiNuWozy`4``D$>ucT zw;m_|9#(mN&6ocEP5=Dv7Z#8Iqx1OcFMK8_o`2MyPu+FhkGJ3YcO@{}^YYuS|Jlh! z@f-B`-gn*h#Vaqp^@b9dk2x??@A>sNe|UKb%*Xxnsb607)v*H1jsEd%H(pkL{K>rZ z)SW;1c?tTb{PV3he)9We=r`H(ZNIqupDrnb`LsR$;=jG`{EN$vKVy%-dP&dY&)Vbb zKXF}m>6`8G)GgP&@52`#U10t>d;FU(T=(&JchT|luK3jU_k5$==70Lf*S-4I+skCX z#XaBgxqtq^S5GUTf1!Z#&8HTRzsTcTuKuUbz3Hwy?=20+t-kd2_k8jTCF0)3S^RF75TQ7abH!k~ZxvyXI&;RRRKG*g9>-K!>m*3OPsdw1psi_NZzxo?xG{2$e zSAO-=cii-yH+-Um&NuaZ$K5~w;CZ+H>dmEYeXH~QTR$p4-{Iijb^F!det(%f-{$%D zw_o+ai{5nA4@yM-jw?Pj^@BUgL-Jn+{imP4_{|`S~?$h`5 z{EpXr@eRNJ(#_@P-?#ExFZ=0d-u=rGE(SRgQW}k)^ZeQ`{=+Xmc+dCBYUv&i<&8hM`O{A+aQuZm-g?PB@BBvj@h=U?dp`J` z4_sev^WLzU1}HuLY`^}Z+k+QWmS*<*tGB-I$FKZpkR09I$3OI?12tEGK-BjJ}StPiB^~f|K5(q(k)lC;%I69H;u-EzZ?$IIQ!N4KfEt~ zj@|Cs_0e7R=L}P0ZZlfSJ9@S2WzXbYa6({zc7F6F!*PDU%a;n*XS;Uo`gHx-21Ir0 zlTRD22#PNn1g#3-KJnYn-1oBQ4d=jkS{(|T1@PmywyPf3>^uMQC*$onJLKH#6&uD| zVF{372CA1-)L@WSFU=7;eye`wzdpM4Qre{8ROQ+8)9O1~m8ShZelmO84VUbS$FCVn zFMtl5)8H9mf-HHqP)nXWx0yUYJ8Us9jfYj3x0}ZqhHyN2Zd-ka zQZVOu8c(*Pr;FROjj$Scv@2PCvK>BcI8qThPql2rc)QBGRxORwFy+leyS|nN==R2O z07XJ1^iMX7r!|9-x-wO&#P%*op4Utx4HN%IK&9CY;{bLb11RW03KLqf-_0jNwCpe^ zxzM*FVFZih1ws?l)6n|biXpQ4PTl5`Fk-NQ&-?jph|&&*gLo;#3pD5#Ep11t8yyr- z-P5EAVvsrwl9QWr0@XG`fwX)2qUHop-S9<6sz8(tjSD0F|7@Dc+l!OGq-wNO4O(MB z;-wmMRZ>a}2SX7}M#czS;e(dmC*wzgL$kp@pms_xD*pLjH>*KX3!2Y!9JPZX38@!? z%2!0lhTSIIfgKNZr`JL9s_1b0ora@&2el@Wh$lM&8g9PWbO{*454~OHFt&P>Uv}CXDmJpC(v%IstY)wkwL90^sK<*=n$1#93@<;i=z>crsH9<{BVzj>LCMylExEB zRY=OV1ZhpZf)Ae@&_^qUY?;c>f+q)h#ie-VFw&^S$&17tsYc~Gracg@R&ZZw^o&R- z0`&l)&Kl!%B*-e`jtp0{>Ox+Wi=kY*k=56y^=wx#x%SDyTu~6L(#k{@Jj(|6+8d>^ zY9a*I0^!c)j%Q&KAD-6iDI?LYh?yET2yUnb7~_gWxg9bZy-1WAsrPSWAZwIbX!sTe zG?uZ(cGgbJDZ!ty6LV(nL^^;Rx9TM*X@4y1S*wI)E5}ky1p&lV8Zj@x3&U_zv@{DA z25(tv*5;`A%BAS1hE$OF;VryOVfrhVBJLBB92Qspt*-oNw3YH=upS_-0RHI*M-~Ub zZ#BSUchxuJvfuFTe_OF}?C0_3E86JEtq64UJ+X;lc1Ww1UHI{!RfocL{?@YSOxPn{ zPj}#=bl@mhH-1rjU_LC=;PvM5v@wwm%x~8uKNYx$>JwRfZky`au5c2AUwP(y-HDtK zl;85JxJfq_w|r$`)XCOd7mCIMp5;8{G8rE3!o}c?SwFPDT+Aq9&-t7&Bg0Jwz3!acj^$ zMh1EM3=>mGBdFP;91LCcHR;xP_BcHkWvoNgt3Fpa4GW^Ln+~QRGlle(F-oh?GE!id z8+1^O8&w;ol?G%bvxNda(7Z;jOB%F7*L7aRIG6Cw!oV4p40?vN7TSw24SCU$PDfPZ zRwzQ!Jq=$l0pJj;?aNoj+oo!xZ1Xx;ch_(K`)|f4v#D3S^85{ILhQ_7f|8&w48rM9 z9Y~Nd$XuFZW_u&dBM_)3H02-Yg64I2ffc+u-jcL<<@;BrZPG~T>o!?Wbk_!rA#2V&crXBmjs z&lQMQZVP45cM`)Kn! z?b;AaV$tTxrg)=ye%QUL%zFmr^ASG@A1+;5Zx2ks0dW>V5}tbN1`*>d7#HR05K|sS zI*>NUTSExOpU82mXCv#gk#o{89YV|34hn;GP~13}lQ&Kgy76|?0dYuU`U zF|PEYo}GmJhLhO6Tci;XA6fBd=;DP?R!u$u8PFo*nTw?ZC#PBWl5%!7z#|l}f;W zbVcI;EV>eDC>dJ~5Vh`N%E4&4riQcap#As= zrnTLXhaA`4U7>^Zv^_Wbf5)NztpSYJzfxMCb8>xmA&PKX0T|o=2^v9@_wGS3&}4$PbX3Gy3VEBTKY7LTA%TtpEVSvM(79>em* zL6@cnr3ZPn76hlY=gn^&1Y^~V|0d@%R*23JB8`&-%T?1k7+4fUZqOKD@eCRxkfdk| z>6k*MF-xD>Iv8lYoioIE4QFRhwuZC8)}ZcF30srt#?vKe&Fs!V3TY5P&Flx%?5^L_Iw?@5J16t~6$IJZ-LPHF;jb ze*paDEmqAXl2+tza8`Rb4OUOI2g~RW8v1he=$7#nC7*{~8V2Z~q3@J&3H`d7KG$P^ za2b0IXrJ*oY!Alc!5x4M<364E3!2%V_(7719;(O@mJYyVO}2*_g2-8a%$zxD2vICu zIv6j_(o)S7QI_>L!yQ0HhIxRIl1R6P@X4{|(~8$~YcQ;kBwohzxWwt;1g+qCj*BI& z6-^Y)g>W8vsTGE7qTr>&#q+JT7{s6>OTm0~h%SMZxEwdcNktdSXU9@yE>1pbsUM5; z^4YY*?DbqB*Pl%=$ytJ0YNUf@9(g3)7i*jU6U1O5=98Hho$!k$Kp170&Y@{}3*d)& z7(7?g8$S^ERU!|f1%c`lqHGILS-&xGyq(5!P26aKIAb$Ni-enohvqcXxuwBqy1~ON zc#%9*TyQY-p&(lPt(Ssvygs||lfk%j`^aVON2ZT_>!t0(bAR^u6@FUvNdIJKc3PU> z2f^u+M*52M?IW+&>>U)>`6>rpoI}Y@qZnFdY6IF1w=x`paSpmlKZa2%BXA3Jt880I zWhgOM95)v%D?>J2a_Un)qf@s%>QW;hJzCO`5^Jv^=RTO)B+F%SZkbIEDpZLE%ISQI z*1`tAPl!T$Cx^(Av6Nv50DV2NKx!c zHh7j4(`v$w7B%p0(Hv1}j$S{LUe+hiDD)wKne_Jc#vwmK>$P4qs7#{bw3`%k3z;|0pul1I?_2E zTs>RQU;_#}TrwC#)^(E%=U5N5hONuNxHHegxt*mme`u5I-*>kVCz!>a+o~*rFmQu% zrkadgHEpoOO0-`>3FTQ-^s-l#(Aevc*G`J9X3n71bYS+XyzZ%*C{mWI7vo3g`hb9V zfYvlG0x%b`TfziKbKYvUX`FwU8nWcc>a1Qdm2y{CG@_{MM(8^69a}SSy^!cD2x9oB zlWpSht}JRq9lp0u*_7~Ncd4&*O4(|!x$5YfE{gGnMtpAuB$fjZ+lgfjv4pEIC6ld& zSFw)pRH>;ogJq#i;jKj$0-xZ~!QI4k(8SbtQ({VAdP_S{5?lY0_@rQoSh~^J>*@z_ zAgwB>HoyuM52IGY3vmOP4iqW#;R-p7ZB0oOW+qNubXMX^;9G7uZ8yC5;z7ImWF^8oxP=it)1+AnS3KSPh)`+&7AL)<`J$@bJFD3fQ26&Ms62p7`zR6Dv&tGkFmQ!V|wwsfj7oUyukD@h1YV zo}G)=2&>nL7Ma-t$>GWn{Nh%tW#W^Hcu7)76!buc(}ZaD4EN|gD2y* za^~>@E1{$wtQTWg)s&@tmcp7BM7HRkouw8c2poZ8cSSK-BRjjL6|C>!LMZt|C|mPg zFNlpav!)dc*S80SHi2s{Ol6>A6YyY>jAv^mTlg#k$;n!&m+9s?>n9b~j>K9f6cNq~ zHm>HMv2Lj~^a=~>t~hVu2`Zr?DCmoY*`Nlmp`}59YTXoB%-qtujAhN%q(sMxqY?{F ztP<~x!g|31VYUXQ>JUO4AR3AhS}{Xz69^45Z`?3LORX+q69!vVx)7%tkWg#huHRY+ zrr%--=?a4lV}LBBVIxE%)6$P;0wb=%usFB~m?030EhO{MP3n@=mM{&Wxuw`>8s`zE zie`w6n;^hs9s=&1W=Q&bP*YM}%WV-^Xxj7fDAL3AYUaROQrbP@6D=4$U zlacbGdZyI@YE>r6)mT_@Lqv5Ak-auBV1_(}un)2&=^{01t)am%+V}_?a4||2lq1Ls zAF`^i&?QUU^}`KJM-Sxk#^RF68*Gqsnj?xr3&o=fg9xqU>H76<{sPl{1Ogy7^e^WoN9>k2cmUf6CO* z$k~zxI2ygGL6E>yjoWhNDtTkF2FHop8MbKLG?sWZALhspGgdnvK;v^$u%(C1Tivid zygK#%ep0OIXS*u0nmn4=cBB}QL#U-EYe>DhOvq(!F6COdzc>a+vKeR! zda`vkdd6;5KYG#-a%3oD3L+wm*s+w|FExe3^T3$SJv`TQxEwSAU(8h|2k($^=?E_5 z1`_y7qvy=G8gl=L3TkDo%nIlWlX&rrmu08&qz_9E$ykys12RfhBz)l`LM%0Ye9>%mqe`Px3rS?jq zCI$&Jc_nFetZ@NEuRS3M&Tm)7mTWnn?uO=Ir4`;88Kk+g)J-0&svJ4=`rB@>Y%HK0 z8_ObjIM7E;(+Q$qfiMvUpq<0fY;X0bC$Y zW6af2ygD}C4)!+CTq1R@q5-iqMU1cpgM!<`Ht!PpIl?)B z&FTJz$!;p@+)~u}N>OJ=SDm|5XJ=98-lEP_ z)M;mnw0sA*3z=7B7hzXCZd)nn>33yOXDS|diQ1m(*LGlJTXii z;^~#e?X|`2wxaCz;^|Gr?JX+slu#r2mE!4+q8cyn((L1Iduu~}Z&7f{`^glzu#zJy zoVS>d2a9sewxK0G4YpIt)8HnnU=VK+m=4{(qB=W@I(HRyb{2K+?W!|{1D9>V*Z1vQ zSnafP5x1Uqwlc3T+PPA7wiN}hEvj!X>fF>-=N8rZN>Ok}QT?u>&d#nn_o~hm^AV5R zmRbk53%T{UT|_!mf!kI&`&Slqt}W_p>lDmx)UAn6_K^-GWk27f>f6wgeqL#+K1@U7 zwC#7j<^6XCrQ0NElS_lLkCsyHA~YQH>f~jk5ela2wB$GLa#}Kbe`tA%f{%cWMvA>s zt(KkPp7*I#bLk-{&|~A1P{>+5nS$F-T$cQYCmb+hPxXT)M+2Gzyq3Bd}i@#nd z#Rq31{q}sT{azeh$u;@^lxbnzPy(K52X0E;E!}o{j?$*b?OKjLHYc+_;{{@VAW!zs zKQaI%M5q^|SOCRhPqBD3N_(grljuO3xE{K= zW?Wy;T6te?EJo4Y(iiNmvbw-1**G0+UsN=Bv!WtD>4d=lVMa(24gU}D|Dd^TqQRac zC!Y!Alq^53*9(IYdK*6`PMD!mV5o(8R2YMZljhIFh#wzDqW9xNS{MEAg8m}x4{^t; zPL18g?V!6wXQcy9Q|{!p;ckDDD`J#CX&*K zBPmujC+STEN!@KXNjHt+Eq9Mlko7^KhorrAs>EAs%@ZzRqs_$^zx(*)Ij#EGEf>VC zaBTaws1-Tl?iG5P=vR|XBJQ-t@R5lnLR^LLs;p*fDT1irpT!r+Hf}9!xEyD@>UWsnE2CPC=h{`GQS?{S z92tk45ha)A%cfPAb`6iB#+V5_5fi&7?WGXcDLDvS0ncG;B3_ zE`C1|C`EHulg?7xc*sn8~CtyR? zxXT9jZVLK(%VJk73w6x0*zc|O+bjz@V6iM>%*+L(e#_1bJpIMd`%QK=DT_;%MLso= z9Ky?v{f)NmI_ypWB>)6>icLpdbqMCE4poIX(>(2$VBnc|jMx^GTCQE>t((iPSy)U4 zesUinV~h4yv{49+IRf)II2sB?GD5{x@=^mgT=C!VrBDQ@tbDc!rl%j?{q!J8t2uvdfkg_xK$Vyv*heiviyn&~6P6(`1( zju=;RF?PF=y2ZGH7)QAn6ZAujvox31h8rDP(Xb>iD2bUYH=;0Z|Dn?YOjc!KV13)% z!iA*S8`+bt|LbsL2;i+C&8bS|q1P_?VLF9&PzP0vR;F#pxfmFZ^NSJlw)wRp&eu z>d4y+U9cHuoSCieJYEqnGbp3(vZ(vz5~s+P=Jw^kbNg~aM;Vzv*RJ>H^Tu??Af@PZ z_BQ>)kAF3{5_2Wz>lqUq{*{++&t9cx zxWN2-QU2_LP+Xc3vQYozgGds1Lb#&s_H){TdMv_u86a9~LP$}!`m6QB)JcG3%>lC= zGbwv*2sukdi)&J0iUIH0%$$0zh!S)?{3Wjo24~Ed_ArGoNadd z$SV%mEUn!%t+ku?y)_4Hme$;Sw=4(DMEA9C4%jTM5t#0wB+-n0ZOs9jr8O7ZD))`R z*S@yqfX&jHi#?WGBQUwItvO(`w6?{C@JjmYwfo+h12#)*JA&SEyEEA1zDa2=431+t zPZPdMcB2844EBh8St-_Mmf8AvyVoiiiiBMlEg=TQp0OZ+MGp=iVfd&s7~|(>gmJZz&tx{=#@EO;?cstrzinBAa4?9UzLYMxXpp{`c0z`RgdL2LV~(&) zWYIa`q1<&tnyS_fOQI)^6(ldhyO!z!VB6NHeH<;X8WB0ra=ej%#5MJp;~3a9n@zD` zpfwz3XC&-c&utD*X*!rIGS`R%S1p)oG8A%!m($XwUQ7}x$k9E~1pEH8jgyMZ30^oF zEpa(ccKV2^yP(<52Pma`Y6ut1?kc)dq2>n)1tG$*^6#J(s_gE&6%>hb%8OR>r&VR8&@ z0y`-MBwqv_l>ni0!o0?0{a<;8(t6GB#!PLQ4Q_YY3Wi`;4L!u_!DM;KMSeBKc1{Ebl0JI3EqQr^_!;8vX z3l$u8y;6U&IrH(SVau9^_I?v2ua)F)7bfl>;N%6tm-0bXR z7dPiY+k%@vkaKfj%M$&$dG}FfSTOY**y%Mm=Up=4%lk`k+Q!U?!OlVY1g9QMx0ZDH z^q9`wB3>^Nld88RCUsr$OzM9)K#oU`EVF1qiVlmGNMS5WJI0~;^F8O#yhb;NE}D%& z=}^I+Q%W-K<RBc zqG-`&9p#2yv3nY_Q?0V3o7J2<)5U6eFj=gIIQ=$qT9e4VDSA};G^N=uP7Y%kznFIL z;?c!eM#pN7DvZ=vi>7XHReoxTVH`r9Vf+tcn8Y#6A!UXsI@Dp9QiqITh>{z_>)ik~IqsXnUvek&yF&82oq-2nh@rU@P z;mPL2edY$|+4endAHM{jxwPcqa-(oNgdBm{im*fz^j~wR z<#{eOtvTetf?~~qjAt0p`!Agzynm%RzbFNkb&}WnUb}3%2rfmZelUz8cQhj8CRI5_ zZ-XpC1^L_@bat_p3ugxm(u0k1%H#q|=J4v{?%DX)R>hy@m7NUD*c ztDA(Bh95&bp1e^WzM@3(a`*G_KPh@JhySZOm@?XA`Tbdh+j45AIu7fQqK`zb)G&_9lJ>PuIi`exRu&vUkb;=K5f6klXQ&z6{;e^7i z_90?7f7W!07Q(efPa{^B`PN@X&BX!-xpOgvX0Aq>QX{r_HAJ1Xt_8~md3$W@%(cg0 zs?sUP^qyjycyobIhZLu*b3Bnt*i22w1=*~hv6!;_ zZ|52;j*fA@9c%xVJoq54hrVZT*F$$b?1qpe?tVk4d4<@$P%(Z8b&RMdQ8*U)!gzZ+GZL%uU*pE6}EU^91fAj?U7`fEhUOxU{8QW zUj*JoI$bQ0cMO%Bcswx<%7Nx~T6e;UiZFIV?Al1}f-)AnCQgr!xQD5`jJnGry%S?w z$>ZF^6W!$``6G+zu_6L=;SvSe$R9sR7qDvEW-;zZqZhYHG5-r2BJWRg&lCX5^1NYA zqj3Am>PkdU0Ed{J#6!zP*IB+Ut&{24NlJ5fuVIjZAGkj?}3@+{MP4<5o5;G3?QLL^F3nGHl_FGdkl)sjF+cG0yht$ z5wO@(&iCkWfEeA=@Xetd1zCh{??VI~9lLjMBP>5)UE+t``-8qsxU{Rx0L5CzND%WL znwc9xue`U2vyi;S3Z?Axdz!baci)-ae(e~ z`hgt2`WWY%*EtT5zS0+Ff0FqcA28r39FAi!>J4O1AeKS$rxt3I-8mo~pqPbE<{rTB zfi2*4CP|JwTr3~Z*d_Tp7wCBL82SVVtT-58mrxoYb8uJk*KWCXAbFmDz@gJpXf};% zXd2b<(_xd_?F znWR^f^-#;MzWu7(wJeccr5k@ho{(ctwu)7<+pfC(Pg#;fMzmj;r9^BKCk7x^j3hd5 zH3tRgWD|6kHWaxNGm;l;LdU?c2?$ju`628>;Wn{ZthyeArs<@8OtdMaAdnzxAC?vu zv@aMA)>5J5oGGU+X2Ns?4VJSN!uOF(sJK8YX09&74fuYI)N1?x?;0bfUQFw41g_r%|Ito7y?MsyU9v$H%R*}f) z2sk#<1!ZF&%2TYt2XBLny+4Xzbtmp9OlEl%X{;4@%iy)mi=~4(m`l~NJFK?lxfc=t z8nJRkZWTV?j+nBx6$rYgv z8?nQY?)(zwpd5YI+vZRIAXZQntJ4Z9JHNYDNuv`wtE4)Y;uN=7%F-xn2`q{Ky%tNe z&5NTIykO~TIUxpOg1>{6@qfrS!q0ee2)x8;*ZHopu(Yep0+5{*)3;S>teEn#K7EeU zK2^J&RnyW^M$V9Xkd$RcSwHuLGNG5km>PJaoZQ?iYA#ZJ8muCWn)B9So~ZK zKcCR5XEz|utomJ};WB8pDBaiYj0zlg$`j}}n~@#>faE@BAI zfgvR-rDtUIhso>QI?8g^QF!AL&OAsRHX+HkrIb?sSxqtjS||Uk4{;r7701!Ss?vv( zm2RaPZL>mW_&f`R5K1AL_R>GLJke1bS}Uz3PiiZ&O_~hY2~M(D>oePJjq9q|zAdkF zE}1B$?vP8T3ccH1f;9)xbW@N4Lp@|zcGIiWIkA#0X@Llj>q zD~p?Wem3>>fUlC*^+4H43goj+V5ep#EPdGUyXC%&WeQ5T`XOIM;Ve^)WfDRO{{u2u zAw}GI6y&=rS@YnLQLIWJcLrQOcE^K`S{Xza7xtx3Vtig4(@Qtbikh= zbtR8tiAtXx`%uCXrLSyMb2+vJH6Q<`w-P>M0T$=^DLcZkt2^WK^g&rt!G9CvcT-1n z?sn8Ww^R3q#r@P%OZVI7mVQhX5ZxkJ0oHyOuL%j7Cfx-evs zL(GAa^*>Cbx zoCcJ{K8{V%+rE`Qw03UVX*IJ~|15tzs)Jc1dPzGs=!RtomYiQ`_toTIY~D0#i`OC- z&mZfP`dEo_i<2%WQE@%WQses@N*Tsyn=$_ zj?|otD^eRn8NE#bYVDX`3M?9 zYS;4M=#_}3d?`zE;c+?hLk-(&4(!K+DnNBH5Vz zwNyvSjkYyB#dz8}D4DapUt_&q^IovD3Hl9AB~%GWHu-vSvCjQ?oeLhHnardBEdv8d%<}uh4G^04<-Mo^91pum2--8`C4T^ zS`c_s@zSaT1YFWG=>dT80?UHF1Qvmin`jc*Ie~B16L$;|b|bxhw|;b?2T3HXvVqp} zRkVN2@>TLp3u&J2^Q!;jRC(97-|zZ|t~Vy(2=@qEMy+GYYOv{ITD3#c{lS_j2&clx z(GHAoB%D=S12HRTN`_*oO<$4bgFjOBH9Utw0I618eye=ankIl}P=pWtP(f+iF&n&* z`S<)>rpLWLJs&DWBnHK5&g z1B^Q*tT;Is{O)WGC0mTqZ|j3fDoj=e`9q8>#Ys}ZPqr^c(WX%Y3L=_9-fOCJ1ApB#FZ|(*}AZ4^omQYS-Na*`Df5r?O z>~ZI>u2*Br>c?J~?pHQse_0^_2Tu=3} z9LQJXrI05!oqU5X`NX_N>b2?$Eez_wQZ5=dOMRj|ImUd;tt>wUty^J5f1p z%2omqttf+vt3IgewyOz3yzU-Jm$Uvj2n?2Jf(v_q{yAA6H2ULYgD`o6X2DujcS&+C^AsT}lH|k-i2JzL?ou;7>2JKlDpsklP5Se9<&1sf6^G$l54{@ zY_+K87-^fE@GzA%CHMbd%{?D!N6v@02vybc*x|dbJa#uP!CTi%BtY4;Yq}SSQrJGf z$GG`ic3RM^#2IiERD-r%u^s9{bZjEoAP(1zb|g<#)PWHE?(E}bB1PV@HDt*sZnkA* zM)9uBpfCDip-44Anxgx%kripMe6)fBJD86s8#lR*eUC!LEVB9bj)eGgbeOregUn`M zqF9nZJ>jqzQAUxe5E-l}ELACmr7+LSMN@;I-6uxo$NI5~<+)h`w4 z#(-=1m!lfYZBR04C&_+!O9@}b@K$vEsO9nqoPj?ImQ*@xk{8W&BR+<@u* z14c2w8*z7VN;T^~3>Y8H@gf&KTxTUVjN1oFvE%;4V12>{yRRf?d{m2j$SZ+`$AVUq zgm*=J*xwl8hTt)^*b^8p&CBs2S%YdH6dKY8h4@(R6ZAo$rhQOoNOKGYbDR305Me-h z7eMcPP>5JB!w)uZ{)KrJQ99&i6CMs?XDG-gY(>IID3sv11YRaOfGJRsc!7$VFTN>c z5=~{wBtPX<++AEWMvu{!Fpqag-C#)!fdiBl;YA-7A9Eh;I} zCu`aUJe1O#1zr+MQw>vFaIy<}P*gz=ih4;*`DNQ(ESnqcf=lRRj}JO99)1KQND@4k zBwq7J@}@Ru@JuR_$Y-xQ>2O@zXud6qwMWZ7AeHv){YGQDA(?gWH~pg#B7=0nogj!D zN~hMOQ|13NNF9oqm!ep+Czl;)!$zfsXonuM$691ylxxD-EQ$+SeeNg58QN2hd!xN% zwCc}+KsSmq(AY7$-kbulwBfvFs#Y_ z8K3*)V2<4--08#3#J#v1;;v%l*wXLI>8omRKW_>A`*Kjh)VFvrJ}!8Ke&WP=T=d;F zhs)u1CtMzBcfv(;ch|>*?M^t)vpbbL$nI2*egDE4y3_Pw{9x?3JJjxktj>7>S(f*X zuxBdw$DMM2)G3E(Xhw&MgL~THM0NxVCMbmKbPyIoVmlHn$ivu5E!i_HxZOfKHpOY` zxQ9$I4KraL(xg9yB|lt+6I9UJ>cGg@U3Jzb6l*jGc6)$iV$1ATzVB3CGVZj@t3Ln) zkkg1PV~T0u%c&j`zAypJ6F_=^^4lvov-Dfea1Cd8K+f<$$r;9o(uhog$kQHh{xA@7 zf7tlO9T-;w;4P+NWQWY#ZJ9gmp9 z#BqGfg^RU^*p12uK78@fZbl*Qr*)3TV)ez~ptGHQguZ4ewV=_4g%NWdqvv=?GVgwj zP2K#O%irh2UYY}d_!2H2vLolz_s!hUK(fu4PscBspKb03=D6%gzn4Xd+>s^#C+mwT zEl(AR7|Rn))tty}a|-O8?ukpVGVXmJ92w7ucfRZCI3&0Yo#~>w8zuk7R~1=;F)BJ2 z#Gk7V#zq`eyp`l1{~PkA!d}CX?{T0DZpU{qrBKA0(F$Op&O8{t&8HMLC1OfpONn3B z!Tr{dLV-qiD!cZy$fS4&n zk!@?>Dw}mPaey_zUQc)adk9rrYbL5!BauL5=aG&Qk2Se{&P@f||0d-_MnxG!7P5^8sKw??VKkN*~ zAo;LiaZJlDi)<3lv=Te27Fhe!nzUV(%Bn7oPNX81gnv<2A0cu=!;9L0!>eccFL^xh z-6Ly60CtVN?xTNnHCRp!$IngO` zoGQ0qC`*>FDryn&NOV+ZRZ(8I)U-`QSxfwt&X!`hSYK2jzlhktV?JJP+N8l*N94;vc7~MXsH!KD8_`y9GPxd@X5S9KFVb4o6@i z3_)ViOx{(fFSJ!52xMawi(@r#7jz)BS!SEcr_hKQ{gGu@lm=#dV1fjXP?@7F^Re_} z2Tzg%LRgaua!5H|#CAmIX3$&Go3DB&P8V}0K~_{WKSRMjOzhh3m}`YjNskLKlx7Tl zPeIFBR|O#OG|(Dwg`bnNzK{Okcts>vvn`n!4K`M7fl@h+(Y<0*HvS}XLIinvOYKf9 zbRtj4*5zLWIeBBGS2EhB7Oe7-Cb1MS*~7Goj@sA$A36-sc@H)OGNo>BdZist=o{#0 zD4~Ma!4Rgl&z`)Z$X3YeS~Wu_@+#6=*{;}au8*|2Uej>Dxt>^iot^dmJT1-w3{YmV zOIZvIx`I}Im-}X>7t9|jP1bLXIV@lw*e-m6?OJQYmZPvHI8KlGIPRMJWQv0qOWDfU zJ2(m>&>)@>#Fbks2DAQzsOgE8h(#5jQjB)j?AL}s%wS)A zv3wCgh;I6)g39i88}jKjG>~IZxFFDnb^w}p+y@YI|D)HJQE7cuM&|+;ln#KB^YJFN zLA>hCQS-;4lRYi!LJ&K$!;N&Z$el4%$)-3m14Ciio{{KnAB==zT}hw(PM)B&EQ#$X zz3u%ZnvqyR%u&saooD2f9lu<-i6d%zKaLi|gL(MW@<-8Y;x->EN6zFuxo3Q|N)ry+ zR|#uK)suJ2E4AgZ6WnRLbd{-_>!5M8>m>H9NNJs+cdW4;0HOo{lNmSS{Mh2%ZGxEl zi;tv3O|)#-#XbE-+3`X0ReUan8cco?*%)V2i0=MEMR=U-nC>K943|?JtDiWH)irBC zk75<~ zYST3nyW^N4Y9$E@i{6)MW*Tw|WGcIGVP_6@jpc_bW{th9TuPb}O zK8qkqajqC@9Q7MX$6LIe^HQ^2!6dTJHyzs1`fJVyZj_Xw_<__iPmJ6Y&B=XSxpzgRH}r#bLCwMJ3%NNSE^T_$p^Qj!{xo^incL9_yYImADtfzwY zK*B(LN?4=3X^DTBWFQM50;+f#vZU5i0`HFXOqqYootI>b15@>mw8L%{)9#%N(yE!T zfLI5g=C!>;xHiQnd^O{#nkM54d%?jRYh!#H8Q;PjC8o7cg21mFPb&Vz$;tT>29{qT zE{09v2+yLfclWZutzM3%^()MyAiRYefHRa6T0(_!WZ}UP74aNBHdZ|-!hb%zqyjKj z@f}J%7ZXr^#8D9_;(ep!-y#muCim9HllLQX$tz9GOw}d5Z})n8XRSj&XZ}0(5kA^W z2SAt_Kbl8m19ylUKgL;Zk~9#wT2ReK+;C0)wjCv3LvlQVJ8MGlYmswME-VK4ej}(+ z*dnL2TSP?uE%lB_NL|~h{PIeeUUYx774=6^KU8u-tY|GuN`hl1QhLycUleAcw@T~8 zF}n(*x@#Sf8an4v8UaPQ2;o@Fx&6DLq3;C*p0dNO#Xm>IJ8Q|C!VYaOw88)014P@Y z{Zx}&g2_b(=xl^|py~Y9 z19W~+=zM7}owrr0I#rf^a4vIU`=06Ms-@hJ(QC8Z&ismy51|G(d&Klg$S*;ec_InI_q!vd!T7$`;s z`Fc@i`7?vcpQ)uy%b%%P{>&in$e*z!-3vf*TK-JblRratxGXU#+YV0N8D)gG2GmXd zA1uLf`7;<2TSCoIQN|e{)O?XYW7!TWnubSbu44YSct_6Rs+%uR^BQ9+{CC>O5qu; zeAyg{wIOqdl&YLNie{EzT<0t3+jM0|vFt14O^)V;N4pAljAyxJX9znjM+~C1#0o)I zWpmK*Yt1EH7^E$^Glh}#)-mFARc9`DXD2l#aV9c5vN^AZwUTEfpDNe|&P6R;>>ZSn zcONZvfA3d#s-Q4Z-|GY#wG^ikh0ENdLEY0pRS$KIVqK9d<0eNjAE}22`gp_+kK`uY zzb?o9_6Nv!+r3}xHLugaP_pE+^^qu}W{(H#r$MvG(`X@tnzwinVKO9bgJp2*2}^PwLW9Oqo(17vlvCdB%Fko9K=$m+9J_ba#ls+X+4@hfKs z%&D{S=Hcv%Iqhhvy|Aj@F#4AJDf~i3x#_zWHpe?ZaWfyo~ zo$rT&w)od#^qsaiF#3N$qyK^4(f{w?*>qv{>B01=b1^rwDUzT4&Jb4bXRh~X-n}R0 zdLN?gnlmQb3gSD9a)9{VdiQ}O{zncFfBL#o+2}ox#NU2^_`f^if4rCY4;M%FlSRjz zBRlngg$4V#=FVq#@gl{#6bCh%ru~tXY}53FwO_P?S`LObXpL3P3E&YK^8cRt-R~LieRQC11vl)BeLFh?; zGp|Ug8VE+dUfx;Ht7ID|dlKQ|>^GL%R&idDvKo2}-61~6xtm>Fb@{a6G=Uet; z7Ksw6Z&U&d*X?#CD~O{8InPQ-&&sgaHa*Ei40xj*6BcLN;730{01A%3@}UJ%8O|4K z16!U2A7|Sw?Ss_uQeJTZ%d+8FGY1M;)nwZMg{-FDbacCdnpCRFn3a)++`Ws2GgjZO-&qw z*hx|;`V(jO!SQ5QIp|h8i}DuijC){qXp-+*aO?aKkwt&yscf(3AFgIUJ8qnErAt}P z(hM4duH=%(hxgTzH?mPe$rDW2NEMx8i{GTBl>6mEsN%B9Z!yt%Tg+}ZPQ%bv7Iq^> z8a_^A5eKldkKb(Hw(Rsg6~$e(7lX4_^ts}g{lIEKOrYA_sdm61ty?Na@!4aS7sq!B0?^|)$WUKhpnJe*#X2$4j)-4FCNi7kl+n$3Rh(%?W$6hWb%T$~ z=UOY;N8t{aRBy?v$C7Udp150h!wyTl~%1Mxw5oTOB~|3z!z4Yv>ngx zJznV(znbktFE`P!VAlfV?oISjB(Wv`2vc1!3U_f83^QYtM*&!sv>$s0_TpAz2HJB|9MI8vf4%4C0LXvjpp(VHqMdK*}6{<(-B zQZ#*XxL^^o3J_Kqvr($M4M3&s4u#DUY=N=tT9~4HlS;WdeB0p}(*_PPX^PS^POgx( zHu7WJdt%?Z03}%{xAWR*d48yKUf*9>*Vha5g9{lHTDz5|iM3ONpDv9{I9RS;a(PM3 zk48IdrHw;BCr!=i_^qbn**c_6YnA=DY0cwZ-n3S8o7QS>(^>@UlsBzO<7(R)`=uF| zHg-8?7rS<@MQ-OBDt;pQN$6jrGHu&hyV^Olk4|+qttqoLW}iE3fa1giaFP<6lk?ro zwC(of#nSXY&>{t__K%gY;V2+i0-rVwg6!7lemt#&C z?uB`F3xiSUmZ!W~f6yvg`6hEt2X2H2Z`hpfSm>qw&XwK^8ej`aPev)5ct~>i_JR zQ|G9@et<+JD#1ymV+G0{xOiS{hE!vsoN+gmz^sbr5@&y&0!}8ICXM~{0T`4n>ZlA# z<#n)t#@8nC9t7J?J%}OpM*yO4?HmyRNURJ%8Ib}CDfaglkwf+iBBT-AUqlw{7ev?r zaDNdwa=#$L?t=S^$Yb{lBJ5PSzla>OUl3Vx{}DNEzaX-mv!SMuq-!!>mS3|!UVfvF z{C*4=GE}($cU3P5u(lOD3nu3xH21`OXsp-6Chqjj-ni3ieveJ?FD;(vY_R-?!t%Pj zV_Dwa#1l2GSs47XG_Aot6ntAT6U3t4K2IfbJ z`KPAi?qESpy~6G(HnE&poFq3|yNc0@@ao-PKurNxpPFRP`Yt;?&W_Nag|ylKrHL>ih>e^1fWDN%zaidcN3bRFB^P6lFnEaEZKcX3ID+&JY(2jqEZHfPqkL%+Yc zHCn-5(T%`|>#otQV!;}Spq^^&0nR?~kspN}9~vL|x!xbJO15#-nLTs|*&jCcfz3g?TjQ~^S18bztPDOyMs{k^14KqVz0XQ7_Z zecXOehfHyeJ`K1SQK+-rdS+<7@mCu)A~l4(a&?yvyTz76eHXUqYj5?uuRyR+{`9`) zsO;#6N>{L_jEc+Ha2$vp_o&>pe^BA9y8BI)d-o42oMty2mA$0O7Ok(sFvg7gK0p`t zLuI;z&&n$o^`O#sHt%_*n9Y0LKv2Ms^Va=<%9X(A1Qwu57g0-Wi;5~m2GK}TdhXQ6 z12zvm2YDVEHt)+(pTP7?45(2r7;sutiY4o5fvqkEDhIau2d449AE3Z=mrRxsF+8wGOXO$Cmy}0^Nw=$oFVZgcQXa*Kkq2RDxJyb*9T<_q?NjlEo~L`e@`lL!zH)h|8dI7gE8B{=RH)l0~_8 z-X%|jVr@O0RKS*Yj%aEoa)OUVe2377;f1T7j zzb@DA>e628q^?ivl@T!|JI(d(nqN<3!HkH6Gf%PmPX+ox^0eJceZQAo>YWPoL&WR* zK8QGW`Tp!-{24)(ze7}bKW+)4=TnG9B)<&JOf<1~i)gcADI41ZXnOp<3?SzogV8s< zt{%EoG34U2U2B$I^SOOpYq9M&I)K+LUCy@JqJ2I6x)|k4o%U6!S(YfemTPSO()sMA zOn3JpkiOh)XCpo6h>?ZwmXc6Kicw8N3=7t7|atth%G3_v7MI*I>?u z+Vr6mY9U!2ZfQCQldNlWj}J=KL!hRbhDNncE?~dtby4|TF&Bb9jzRk z%%xZ#HDSnH0+VA#lKD*?gnTPV-|%6R<1>^O6!LxCVj%>U?~2%#q`KqimN^NY@=#@Q zr_rVhR*sxT%&e0qZvlgE8QpKGN^ng4X3^ftocx)6sC=2mo1zbs~kixm-j2-*#OWVeh&Jtm*B(?}PiYIBeK#IsLJs_WbJ#!RNR^uU%p^)+301TXk$^U{!~7q6Y@zv)5S)t z1`VYHJ-g9!ZXHkzV<2nwn$4Em;YNS0I(y-QJp0y6Qj5g1h;Mt*cDJE&2Hcscxg9el z<1irNnaN^HdmHxVLm@u3t=rT%UQr7JfOpnL4vh?e%w!2C<`d+ImOOl@zt7Nxbb^D)^V#MY(?OEqjd-eRYt?V+a zXCtfGh*xo6>(EID_LVjFHCCOnujmJ)3D=TAOn-yw)}yf!3ZwcXIvIWo--iQ8veGZI30~X+tQj4XUV* zX=`g~8P%>{SNf`teEw=~z>JopY~^xG;%&EEjCZRvrg%Z@xbft|sH8jO@|N++1=eg+ zS$Ft;N_3ru(t1rtcNn?!k-#!6BNs}DuUPjEhle5EAv)#NyFx=bDh7e%ew&m_cX(8K zbjQU}9NA9kUL&pz2AG0#We+CjUn3(fTaHQZvE>zK%PZoFN{1_^*>bE_7gq>*SuKUK z^ARX)d50?`N=`G_`4uQLP~xA-cHOoNquHg=iTLm_qxtqJY9R>lG@eLn&o%pT-A}dW zp^JIYZ#}k$uYxi}C5ujid2AcV16!_@qU&aXE|s6t9Tq57+C=xRiGk5ji@*B|8lOtt zkI;t9d>d|H>UW)nJ;p7kBbGrsqfKS#SsOP98bN*0@j!mWLuY~d-)9f3m9i4M;W^IAE>BVihSxIIqtX+X0lX7 zrzHq%yXun6Q8@+Npl4ijxad+LnU9GccZ04nysaQtUj;xZoPLPvyds$&Demde966ew z%8&ji2!cM#XQh?tvr-%zrlXwNP@0a`H63MJ-R#rR9_Gufm@!}B;Fv>FFHKANF14e4 z+jj5u*i*=n&waayVD{43oMSpff#UcMwXjFk{B*v%CeC=mu^(yJGok%S=s*13kC4C1 zxqWWmD-$^(oi*jOxW4w@5v^qJ-PkyLUr5nGVYmr~4aSatbvxXchOcUF8L7HcWFq$+ z%pH7kzQSZbv;!VAYjJB6Q@B*eS)v@6Dwz-n2>zy~q_0XF(k6+++T7Le< z(!;suo%A%f6|*|Vy({s9Pvs>LPmS%^&X{)r5WlQ5BMhRw>L5`~o=n?8vRT`|8nk57 zwd}{ARq^~WcxkKWPd>-PF*_^>%*KKj4o92@*7d;3o%f%VV}WN(r?O0a;KLUmtxwt` zOw>9yUX&%t$@+3KapR-nB|6K8`QuUXB6k+rZMbB7FxgJHV=kB76zVgd?vs;1y!kbk zzi<2X7u^n^n^-H*bnzCg8IZdponbRPrjvZOKJQ|7np;_3hLeJyPFYw`w`!e1+743DOe0CkVtx)IB=v<0C4d?o~2& z6c|Hj9AzX%#S;sIw5?{wu%0xpz$^7t7gRG@e`{HyF@=p>u?U2NNw9fv7RNcJG$v@0gF5-|6kbU@LQo zNmT_|-Gz22-)M9tbN2ipM-(}_gRgtKMnxlcejh!yW9@*T$4E7WN23jz^H;L%5XSXo zZ1b`4wG68Ud7D@s(%qyt-7ryPszS} zo9@J%iYWE}D?GM^?ExD5NN6EZ1z3!G>k6#My0jaBNUNxb6xPvaXBlfaNbxXNT0yxK z5R5Uk(IemaZ>JyJGfpT|Z%7f-xs)}XFNii^EGrqgS^$@9Y=6Tqul(Z0o55Tg*n<;? zLy=z~k-e+K_Fgps+lq_nNDA_aMCpZw*lo8<>*c*loDxMZ(!ZA@b%UE-v0r{EFV<>^ zNdVG7kxRXy$m!se>0!a)jXb4FMiyOZ9H;1=#&Jt${P-}ibc-pA=CSbxzV6$kKY36&>CbX^c*(`rnIuJ{8j^&Et1~O3#SlK*gE~~R67blW`t)6!*Z(5;}q~k<4C;I z8v23a@Q-zzfePp?B80BcEO5Qa8?3k#mJSF(MZ46u+!d zNL9o^n5_ShX*61c<7uM@KBy7K(#8!`QtCia-Xc$qsK89~0bNrbPZcxPpfo+m8AgM# zBpYR{iPjlDx?HA#AHg+c7x81r1jx=NX}WdO=nj)W)LD`qvZAA(oG-E9A!YI zc1@QxID*s!lI&Qj@Ih?rg^p28wp!(KQ>KjTXyW8lt#V{H2jfsdC}npPw|5q|V0aua zQO!$D!lM)1O6@ZUV%MtxgMw{6=DG zfPxo4oRjP}Nd*1pAL~)VU2-V`0-ZHU0hZwpdLSgCs|ncLwJpj$RkI^cMq?+=V!e!o zQD1d5dJ9MLQHdBEd}GJcAx|~aciZlB3f<{r30d+EZ(%PdcOA-aK}BO>%^`B!U?PAX zMsMLd)N*seIHTVgb%58Y0e@i!Q7q;`R5FIm`Xn>aaNjwXD%S|Z6K;q#YQCk8u<@_$*0s++4imTpJDEQ2|Kb!~||jc}3tMgHd`U9C0& zGR%h5q{SvD+Jox-U{*N?A4sebN=4KdA~{Nfh^JISg`)^fT51xZMW`n($CP1F8kp_D z306zP6Q%DkEq*FEz)DFQ@*N{;4q(huH%$?Hnc3ZT`>X!*d(V-G5^Q00Mg$pzPa3kz zQjNL{fw)F2t>T5XhRp)B<~XLC3)h>#@CBst6vHMOjDo)rE1hc((m86OmJXTSNQWg4 z;3<_55ZyOh%^d(-R~-#pn?})N9AOtx2t*ce!QnNO0(5U)(6n$`TZmT~%8}%s$@%R8 z%C^FE;2OFUWaJGGz>d7q!=|FsOmML3j-f)0$pGsy9}cY%(PO}>=`Mtf8chC&o~&+3 z+Ux>@t3M}lsb$-xYfsYc;^-896PV}UTd*OYlRH`ip@l(UuArk9u;FgK8jTjU4F`jI z42Zz>HP{Pwo2xr~+7}1SH%GBfn6*_Q4y+F0JR2e+-cFZ`tUz_kX6|Te810%Cu@!en zwEE8ho9e$!K-GT*-H}#?f6XMGzJ#xqQ=!eFg-mW1aLTpx4N-J}nOye)q@IY7u(JrM zKnrIV8FR_~gM1PH%c_Y)hqwz1#qQKd+r$$jAK~0ZRly?>0G*2ZcmTUc9=cSODF&sl zAdu%0ntxQ#4%J#3EDRd$I6Ii7ii4j$pS#1yvz_szkxSwTFrml-zg6Cmo*hy3HLwG3Y_-<_!Jxr&5 za5gJXp;^@}N~Xklun`;w$lYd}Egc1&?rz&{ie$ zs~Nv=P^2Z$;5wt#RE*+yn(k7te8`P2jicj=#e&Xh>KI{Li|L$m;|sw3Qe^N0V z6ABq5V>;Z1H7=cMMxZfh57;^IdNY)dBP6!jqLJJCTQG7;QOu``>Lg)0B?D{gWpd7( z_u=CKrhj5xrGJ_r^&tqAGGtN;O4vq%GxKI+Bk5Tij71qtF?mGo6*Ty;+ z)p!B69Z3U5mJ#{;T^bQ{+2jN`mu;s#ghUp7h2fdFF#2Ym5jc1u*=)3{j_vY)j^Eh1 z-6c;K&>y(h2D?7i*kX1EePb-wxFQ=_pQ+x<#&y*0mq{!L(}s#E5u!0Rbzgj*;!|ip zq9IXxPzoZ#Jk^+zXdcUBST`^D0uJT1+LWaTHY1`!yQwOQ1TNbl`f&rRf7Pb{v-GdPulTt=_#e55-tcQ+1J>+Tr~LNdFBv?V z{+hi;kc&gSe`>oPx^PT! z?2$y)7(K~&X|_Sq(>N23nkF2z&V)nmCyHYCYlkkt{aOtpT;(G17OC_Cr)PVIxv9613&msY$S4fK_x0m%`QYNncn91Y?)fQbY_IzE>p z9wSG2LCKNTRtN?;(j3I(h$F-Bk#drh2}oL)=J$1u zYG(q705`HxrG-_^`!FL^)$GHig;jB3M^_VAEQOX_K#BPQP6GB>6A3wEHi59E1XM7O z^>zVobAKN%3)XX!BR7qe!w{h>ay#HABg`-StYQISA^cIvK0XyXLH_mvPHJbm;1|_Q z@wz_93?hwwSrIn}lOS(LE_{eQ^;996#MGjwqFIo1f@tUT4)GwUh)*v6j(n+!mOSAQ zZGbJp>L9!_jZE0MLk?YcPC>e}Q;OgCii#|Pe3Y%hZ*+trYA-J`R+yYuAfuN|VU3Iy zN>T+Tlby;N)uek(X?;V$SC+FT@I0lA5-v3q%wlzsgUAIZ5~SL;IB4ig%X)L=)`VR$ zV5F2;=&Y)G@8*S4=$bAC5C!17-MNN&JWG*)q81u>|BTL;{p7CBcq4Hsrs^WzR}v-IUym@-c{wh7D6{d<*hxT;5&m z+4uiv?_IzxyQ+H6z1M!7v-hd06^L3=@v_dox&58AV3%zOCDtXi4<(k@a4oNh@izDS zitmD5ouHkHAz!+?LY+W>@DQRPgos+H011ykL{I{TlpumUG(p0{@F)QxfdEl?1VPfj z|9{N2_S*aGQ;(R01S$n*t-T&|%{k_n<2}agXhK^;Un?3Np|2w3(DiKNYVZMCV0$Nt zI|_CK5W-kwu^hHKA@kJgfKV=N}r{wHMsk1J^Ns=>!s}c*^AB z5!s1Hd?xAbsE<{7+wMFEFaD+LVV%BJg7O;?tML@#$ z6d6qjL4=(etIENOX~8|@9_e9*S)(Cd0dwe0Af3l8vc2SXJgAeuZw7U$2Zc1O)yhmc zpy$Xlm5kE@?_2^eHSGoA_R&EY0R&z<0pZ5rs@AFy88N8$yUL4gLB=RaTz5NQMq$-u zKu`*x4W-c@fuu2(Vbv+J2hqZ0LSfast|)t>6lYRk;&q7h~zc>LW<-(R-u6*1hs2^A8}9Ko^{x z(;mE}kF_QXYt6Mp@xa~S=*o3j!EI-GrzNlaImCd$C@(;N691I{YZvGC<)Vb`Hlc>~ z)f6f*P+ZxKu+g<-!9}pZp$pH~CWidR`iE)4zH%EyM|XYH#v8V{;_C>(y)a}%d=2cO z{_|3}`SQx4_r3YmDOlzbE|_gUvUM5OP}~QWvJkE>ZHmY9KINasrsH9uC>3wrbQ1TUwisOHy z*L+-&JB@neP9q|BXx+grf)#BzaHnBw4>#(8J1v|f3f$pA`4Nif*GZD$X&soi9wIRt zQ)Izl6pd1TKjsga!h%jMaK{r+^oC3sf=xgj3sj2SX-r1$&`nuH>GtZ#9qGokv7;qL zP#BX^_*Y5Y>|?N+9745MJYxgSH5!O|K zJ6bOpv%ZA4$$A5gTGDY(0>2ctBU{%NeS>1eS4$qGqY=A9>#uAM8zE9%t?ujn-%$7{v+KjtcgRl<l+#-{lCEr^Jj@KUd zY99A$N*CEKo&GeC=sxvozNBTZW((Vt1*B5VeeE-1O%bys_8WTXx6;Lun)41TV52;q zat5)W$aa(%jq1$3b|^!18=)4?%eBiBZ2^p~D z{U15>rT2d5x_z}a^G1GAQ;}DGACg>hv< z`)kZaf2J3qugAnX`ZX`YfZm$dV*P^4mRs0I#a(9#%vb`OBJXj&4P$@qljqL?eH_V5{(tG8*}*!3c zCh*;S*19bb6FWICb=xxyS%SWeRo8y~Q_p(>)&b0)9-2BOBxZmwZA$7-D;4OC$*+SG z6p~ z>4G{%hhSYof57|Mk*-qei8s}uh{F=yN{whJQjYUCvV6suR}`$Hi5I=nCm8RkG9d3Y zjM}5y5zNJ5nFd3dQzfBzBWtN=JeqTd0n(J!G;qvB$BS->%b1C)2SUwgkJxmBi&!N1 zONZK00P;7`ndukoeiIpC>WO(nnxM1VW;ykmzH0*tNQ)8C8#-XVV3tM4AQ0!;v0j3>il_fJ)H_+SdYurFjMhC@?+ElnIGPJD`vW~6+ zSdI*BgCq<{7yF8g>`zCA(#3jYD8wo(r)6X)Yj;*;DAeiRjtp(vOi{*%-rUTR{5Bng zwyjjE4i|(50+H3C2~pq~2!C-izd7n|CiKwCVcvKy2yqoa)f#O>ok2%11+Niugq4V% z`qPN(+`cUR3*xNsDc0Ad<8LZoBZ;POsSj(yCA#^jhNTXp1h9fwA#lT`SSoNG_}NZu z#rAG8TS7{k%I)Noce9zlIHJBzmAFi%%+W-B$w3LF*x&9@h=-UZN!6i6&4^o~OXk|5 zJbYa)h%QP>70Nd+iUNWjCX}xaD9Z>v>9>6e{X@s%%|{H84PabWJ2mBDPO3*J2#cXE z3>VOF2T~puv>@g=%m_ge9Z4ZbJrkA(LWei9#-Uv9u(_xrpM(qN_7y=Q7hjH|jz_?k_Q^F8XCn2_Qf#|6@d9>#$kG2etV90wmSmzR! zB%Mo+c1*jH&qU61C{(CkStEOF8q*GeEe$6Su$O0FAhVG15SmkvGUcTtF z7H;i6p&8-J5=8UxGW$HAGOEvuVauU4?5~#DyRy=ZlMw+suND2-GJ8LSha(vfBK5E# z*;EpH*;u2Lb+Fn>64=e51&cc^d#cY4N$5NWu=OqXrfiuWc^EB8Z}}ffdIwrd!)&=3 zDTZ(RoTPVMlYcj)cN|?zwZV$g3mdcmpRQ&XYU(sM*>Xx#y!9UqT;T`8p1S0Y?Bu4z0^to%0O=44vA7I!X?+O(m(4W7WqM2+KBTb< ziSH=ZVrVNG2Jy-W$7Qus~;5@dVM^HRlz8CD?)5f}N9zkVjN=dGZ8o7veSunB65Hg z-DVlem>L{uih&3f!k8$56xF0|w1?a}rB#Uj$?4(eI0kW~v$(0^=ad@Kml`sM4CQhb zC&!`S(03NMzn0fDk-1V6=}v1Rs}eajOJKW4H4&KoeWZyTw^?}RkJ~InVNy2h{l#W+ z95;{SCMt+s*Y`Kvd|p9BXY1+nvfkW?N7SkQ1rc-yn^=Z0yI8ykodn)A>|GqWlw3h% z<?b^8+FYgyK3};0}!y%dW1dOG)F`SC3CX; zM*C3!rOsc?F{}(k{1KJtrY>tHkYF6Ldi9~(UUAd=(5taA^h?iCSB7*79sDWTrZO`4 z_k@)J;YZeQausaNjpuoeK+Zptl+F8#gXMjTm}}AWq!!DSl*vbgCVgqM?j#x=lpmR4t(G3xeXetL;ctDpQ& zie3Crl1O<*LX%{je*RX>is{QC$<*QHf#Lp7ZRI~PTnM|8uI$IfKj3T1IvrqIno5>H z!gbyha+?LFA;XbFffiQE>FJJMPb2H#216AWV1_xB&k84k#4@aZZbS2)^NSW6#X3Z} zlsT=0XuTM>OWVJ~^gKF2fU_06H`g&=lTX`QHIVQ;Ya+cK{$7hkz8$8wD3aym&0i`n z0zigu8$E+`1y29a3&!qML3!Yr+yUUvaJUf8S%wG(;(l;1n2@(+`XZgZx;b1x5AbrV z0jggtgyztfb&3{MCj+Do&0!$T!J}Fz`gSLERpm-gMfixKN7f0fpjHeXs2_G+u?W4c z?2=_#s>Rhyiz|$f%~@*;10Gd*X0EN#LB4wkWz(o`EdQlVz?0Q9Yu!-Rh!t2yU0u=Q11r7w`YgVt?7Gd$uIpvS z8c$8c%H#D}D^II`yz=_7@~940TY2DIth|1G<>^JQy#C=<9-d;ayz$dsc?tO-c#D%0 z>6Q1Y+tVTg1lY^NW_kIS%`6sx)Zzvl0tC;=^@b_&gmB*{vJ$jEae&gO_#mDPr}Kd2 zV?}gOE}-E$AXz}Jp?55%2YKZ<65~OIo-UwJXBH>aoX%!=i|a7wu=0521U0bQs;D*b zAg%LeaYFGRSryBc8e@|#m$t%{x_d@s5YPkSd?|86VV*ss?0m27Y!BhhTDV$*0Nqp# z>K&wQT^f9`4!{aIa7uEE`x}bBR#ZG!KtS~iTja79*#^!vjD2m`36J!;JrR%N~CCP!$gg|7>TO|~|Bh$l46cUDC@|BWT!az&6!6hntFP2rY z&lW!__SsS!HQZPQqzXU!`3(tq=Pq8}_p36?TO_3ZRgA%8Pu%v=4^iTR#|7piFH(U{ z4+*U0fM7=+P&v%4JOK2-;91PXZ%eoekqR;v!jA0dNz@ZbCQTJiM*J`d;sz3 zFT4=zPgg{o%5}oPs&ZX-T)D10sw&r+Qvgy0SkQ5xkrCvr!{Y_#iOO{m>y;cN7G6Ub z76jxu7d+#cgI-HAUv-^36g}pLd(VvK@1)~;+kITQZG&UWH5Y1^>7`9Zsp51-o$6~^ zIJ#GoTEa3^t!!=M0YPoYhXf4Y>6 zn7I6zEl_?G6=jkb=!%3~w6Y~ER})p?V`KYU>2Op&mb|Smy7DnxH&s6F${D0ZCouv5 za;Eu>A5(r0BcEV_?1zuj>!1dVu1X`0Zv3WNc`K{=T?sID0nz0%qPCoCj)lxFZZA+_ zfiCZ<+HHRbjJOx-v~kY-X{49-+!-Yg3#txJYvj!jpPa;7;hrFn;DGE#nx=< zlg<+YxQQ?G&763pj%V6x^!Vr6YP5h$SKN>MF9qQn9ryJYE$`^%+H08i@A-0HGBD35 z_tlA1!p^8H_th!OeG#^T5Hwltt3$ajVzQ##m(1)xrA=5-r%#SUp+nJuYAyx2RAC2j z%?CcOU(^AMmFhzgzm^oNBSPJhxvG=ji2h1=jHtM)bSV!{;Su4jaM0sKl`dxkga;a> zNV+C*iu$sX;BkeDY*Q*Mf{#^RD(RX*9#fSroUGyYRh2I3mL`YoRHbVp)F#>ynn)va zd59JmCD0D`w;XPvfE)}u(;-qv7fZwt!%xU4RAWJ5FdLX1{CKgag*tvl2r5<{q=#FI$QmMu>VtN5ul`_RiPRq~CK{Xipn3igKgjIX z*I6ypi(r|L??>zN(*P+`N`b*)~8#@&zZWQ-yj zTs0`PFG*}O8z@0@G(9pZjeB&={Sm{+fDa4ocr_?7_WRY=b3p*1v@%JFz+|F|-eGPk z>#m}H_h{A~#7aEj7_;sWeSQ$L?oK7^?)qsKbvMFYVLFO-F&!BacO{Nt9ai=(j<*if{KZIbOS;eBDqeRrk2hC$ve-JUD{9vslK>fozl!c*={RQ5{ifNX zJMK%#{`ZOKF1yAtiSCzoI?8O2=w9xLIuT%1v9BZKH#m(?d=Np$CDOw5CgGYjB~uyJ zEDEC8F!E^ZNO}-$idR+(`LJgxb#`IyXvTHYZwu2fQxQAp-v;Kv=V7pbI9R6MHb6~AuCRdpFD$A+C+Usg?r)= z6>ty)&ii&msjQ#_?^1bWviy_sqj6<3#)Z#Ax{MoyZS$s9?>sV`rLJ1{6o^8>}Nbs%s~Q_ zhw54lrUOtlNCBf=keK+u8m&kY*5>hO`7u3O0zV^xGDbT|*CXkthaBjXT!M9t#T*8S zD!>VIQ-yKfPjVtnCI0kA4?D)hpW|hdA2^EgJAZJ?CeJDBRfU}wN`>)WS75IiJ$_IsTVTKh3iGOzi}aCZT!&^ zCB8=rAv2iL*i)4gI-ayH+-1s+C#|E++|L5Q|F&zd3|l;?)RZ!3WJ{L5(Y7!j1*dAN zR2f=?S2~3j%`QB}x<72aDT?Gwh8Ed-NTarihlR;WirSnK$xq=#mXhERcgAZ1BJiCS0TL-WNV?k&Y(v+g~ru_d0|8W(rOVJAJtL3n0( z*5>oSQcfvpd2$shqfuo~)eXk{L=^}fyY;rFEZsR^cF<{3^6TMDwALwcD*5#aE;`YV zx?jn!$EXWME33=g#uy-VR#VG0*6P^J_xm{YCLflL9ftNhwHBzZ2wDM_1iyIet2bNAKQ+G2EV-GTSfm` zE=iS_rhi+6@4yn~ql&bEpF`F)lsRn*4NqxuQ)~p=F8e~g3TIC^ItTC0*q+WA<&2T7e_yAaxOOU7?+lrxG3(noMsRG(!TQQsWwJ};ADUs+aq)g7Kh6Y9lnHw1b z1+W#%*JG!sC~Ix4BOCoBRdaA^|2+5PwRT96wk#QMW~JI7EUH>H3Eab#!v6eF*q^wJ zBtQ#9Xu9EWlmjVebp7|hEB0|p7anim0ki2XO^{pU#bRr(RCVIr84Bds+_ZM-1{V{E zaMZ(r3Z)@H)kb+tbyE%lD#}~6lY%x4sfpp$$jKQ*3JAZCS;zl_%2R?W@v7=!Mqj zRods+%)$mk5w5Tv+7xF8$oTy)nzY2liTC9Q!OmC4P>+B58`WzV9E=9QKp!c3dzTxs zNg&*5uyiLL<#(cQjsjruaqCt8q@F@6^rq;#X8A1{NWSXY;1ezOw=bs(PF$Ql?1&Tp z0M6N){#jr<<~gfgi#a3oR5QkWMZAY^iy~4xv!##`lSpRiW&a|2?@7YgqlzIS>{YZo za}A9Xe%OMen)On$)Pig~x~cET!ppSwL=9EN%?UFF@HG`# z3+v`Zeol&7jQX=*)2L~t^@wav_V%YQuN=JW1Mlwb&7TB<^Tfx#X}DxTw4!jsE;=?2 z4t`_{v4uXVh^mXBQ0F1>_p;6d5Fq<~q$&=IXVK!=Ws{iBToSUWv)vMMY%?oE9W$4$ z0(!#$i_A?4K=mpPidjOIE9iiNH8gMbPzp={Lfy-ehZv`7zFD-KaEoU8y3@9by?Tcy z^=u_8*j+IGxpv^10YERP;iwQn%_$wa^6QQKeSAaEi9(dP3eGFH(V;MO2%-v<;! z%c>^G0aDyq`S#3?q`0$jN08uYn9mQrm|+bC&r;zY)^V8_0$DZVwNiK0i@dw4Xl<%!x`X-6zhtZSltBfjy1%+i?^ zJ+Fz^|pfR+Az(qcQbWsD86YOO*P4!&TJAa z2LIP;QsUmM4jy%DF-ENpuNn!BmSI9}k*o;_v}h(e7jTL7SH`JUEeZUdL&=}{rOZHp zd+@wgtM&92iggk!scdulbB3M0Mdw-COc3aTuXmA)XF@)yrnA7goP0Lu{={=KFoQ~AP zPSFpW1y-Lzgrdm2S#r^2NARL$)lU`=J_%l7&!Cg#XNRp(5xb`F{bu#$zT2fMOr5*j z;5@3g(;aoQ=(wVLy<2gg1?{&Hk_l!GvluF1bMU2R9ntBVz^^}MGLw@XOI-9;Vzi1I>7*i*;{auq5?50RYo=F; zS&WxRauiLzDQOyXX5Iq%)@r7tR&FWdTeJEiBrI3?;QiX!550CaN3HL7PTx(>JlJyC z>Dp1omj8k!W$$rb1#?r{GkQ24Zeq&QvE}u*%Z|vnS2i%KBbm*?3Fd*6vovL_`$qUTeCZyF8^RQwZ}7H?daHK~y!>T^A*mc=Dk4bie!4&K$<69+ji_;;Xa>=)a) zO0o)1XBOuf{wRY}65!TC5O+M~10utq<0-moiU7k(mJ0`x-gb;-@%vt5Rym6c+TZDMS4-Q#`j z+JW54E7)S?&p3~}vf#5bHebiL%*pvh?_3w0WH_gL;0=D$_x9+b3)mXXyNih(HP548 z4?Ulo9Gf&H8!qAW%3XWt`F`MB1VmlgG0Zkul<|Js?1rPOPlq;c;@SUjK24rWIJ@7* z#Iwn79c-LC%(Uy6ip}!_5dbfW`WX;H1r$W-zWVWF(TF5IMvbUiz6tS10D@f8P2D@# zNH1pb;z{)v5v{8ip@0)F(vUxx-rH1vkF`*}Cta}qLE5Rm_mKK~qPJy7Q8p&tqn-MD zKU#lJYHazQWZq#N4=7USDke-D|ldJp+(;yv1_zxN}x_kdaTp5Qm}9_`fM`{CMq zwRxDDhUr=Oq1s!uNtl|0sVO+I_EK#IrY2wt{tvFbR0IDM^rwLTpxR3{*iV6e3i2n^ zUaA3p3hq;2&&My-pgs-sDVT27XQ;oLlW*?n+{^Ek0 zT6rFh_vT3H?SDdPrL%{F^Qny0+=GdYib?~_MUUOI2*=a6!(_v`U+9cp>=(M{E1=mg za0_#tUr=Y3z+>)=JoNW_GHn;GuGh%uv1>R z#;(52LZZZm!T8nY<>lLeHllQ5e*JL%cep#N8MHuAH1hvbQ@PeZ6>e7X6%_^YSI`L(&dbSD7^*a>Dt)LP@&*eO#b^t;7 z;thO(V1|{I7qx%U)hT!+D_bw`Xi0%mdhXyKIhLZ&^xtq7YD-o&v@e|)%Jc$g_DA1M z4;AaSzv5|)OSXRQkxxG`KI7`I{mY&2eCTh!s(E017K1S6IUa^)kadK<<+rvy=D;w! z-V2~V`h`UWDuAYF1b%W4Yuv~vp`<@L@o6k{2}hQpUi8Q7e;x>SNB?^JPcYt5bFqVw zZuS_2DKx;Ch1l7#j=`@>JlZCn9HAImH!Z}&(V=HG&-!t^oa>7@lLv+)`E8 zf$kkl_wy@;CzQQAogz;g_Fp-CkVh|+Ip>)-NO}cRhYwCq&28Jy3^w*t=jsIRhz`+( zm6hyVKK-Ec&f-U5igd&9!~<9G#D?O;BERB_16LdvZaARHKcFU&qRW5VzxrQ)_P;DW z{e7n&*#4AT{`$rL<=G!RegA>&&C!p&X4iQ)>GW~`%Zq;LSAOMYo!<4j|NE9d{f%36 z+WIN|_gPN&5A*%k+tcX&9vGg$NBKg=cp7E55AH7>OfU8iv--2TduaYWUpbx50hJpA zDjHyM!WCC+|F_noKH?a}WzuwUQXU$p;hvZ*4wqF8@LvEhov^`h7% zF5Pj%{-Hau>*s#xn|y|*w{QRS|G0DThQ~kJKsblMYh6CGw#s6v8R~*>> z-DmvxQ)u9Z>A~{V#q~C;Rsh(bkL2o0^FTqRE+&Dunsft_kHLRTFEFl4&9R7maU~ia z{PzEcO5g=Ob5((~ym6z{wSHGXl%!sEqe8pzAG?q{^w6;B>D ze+#0s)_0nI=qWq|8Pgi1^L$E}+|x3=Nc<0;VCCVU?Bqy=&$!?$IH5T4ScMU__szRD z?7`(HR`J8$7}ZCi_#GC=#<1_`2PR`=fVA*qt>6got?V zV~1Uvq}@2tGmZusfO`4|rt&#O>$@jvdgwwyGrnq@^WnZaE*|8sI&Sot?*tj>s$ZnPKwj zALa*M8qR*mXX@;UoY7fA*dOX^dhS2?OwavT_1sBCGhb$XIOMIbrSv)x*1@~FyT(99w6#DZ75E}Mfd^UuRV_|r%qF`M!;!?FMtK< zM#lb*cvX$kxMbqy2}qIZnJ?m;#} zdJ+@|8l*0XGoRAhRwit7@sMMpptX$=wE^jXH%ZU7!3DHMdJI!^xZDGjZBEA<ZoiMSg{GQ`L#wuQh~ zn0s1BLdqsPj!D*$Ij6a26CV7Y9-h0#(vGsJr(Vsr0ghfuLgwG83`G!*FtIIb*BC+P(E~<^<9VoV2@zR0G-b2(~H8t>sK`q$LvPquwaxyWSfp zP5!#3b}#fRbibrg+91xw1%>vw-U*mWIatgIu=r5G!d!Y1x7F6s;I(90f;A!-JHmgl za5}D-u7b)Ln$@nTL}6r73!iYBnm4s%QlhT!xDmOl-=tD(dJZF&PLp2RIx7VU+t zWk|#7SiY^ouP^_{o~pJewXXx!aDv~#iQsdQNB9*(6NtdH@}J0gFscrxiDyx$8~lf^ zdG{_yhj|0eHi;EQ4|N53zeFDN9wECi+2ya*R(LppQO-w zZEz0tV=Ox_BnV!tBT@!#khTDS#bUV+1nw00G5i zv`Q~Qg1a#N))PP8x(wSsMRTt^P_(Z*fVR7`^*1m7^W`gt^V?+?xa+P@KjtYO*h`c8 zk!|Cl_>YjN`Rd10HVx<360dFZE9S3_FaWao+KQ2S&hn*ygP@W>hCW9)z!uJ6&(;{# z`?h=EFZw*3Z|5esMQ4|WajEt`jF=mQ-SbHG{?+k5hShi<_W_h)IJj_;bVYg)KoO-V z>-S!U$Z5P5P`zK%3MQRZ%QX{f@+;E1vxy?UyTk;vRcP7x znK66Ab&qWA8%m9ZtDj|k9%0GSC&%|~WKbLKMZiQVOFGN3Fy=lTf4C0EKDb`!7w-|ULj z+C{Dum0Asw>pvbi>TOyK8oExl0e@NAqv!rjBmXqUOXI356+`r2Pt9gYA(@J2kFz!D zGB@{EH($B>=I-)EPl;y3X`W2NeKxi9a(zOmgh1sSGr5}M^)bimtBF1G9HR~d+#ev5 zJG$dp!ca}{)mVZK9pwZcetHLog({m^YUR{70IdLAZvQ#8avpF{y|aSqXE62LGf-VP zEL0Z)s^hIezYlSB<=G{!Uh<(v{ty3tTooFxL5R$V#YHYL>u8LwMyXB0>H^8s4Vc}v z<4XfwlGc6)QV<54DJe)~o||m@Dsc>_%;*JiIztk&_FYLr`B)O74z(m9g8nxa8){OJ z#AxkCLaRs=oIpdLQ7R8L(PslB_A{BH*8F}=^ucUQ#xN9*`u=AkYLyaHr125=u3gZ7 z73N{VeOPZE^N091p+EGEM!~RB@C=x{Bnf@?Udj$>6%KTNg9Pa$hqtzp999kl*gRF*umXh z%tN%qmvQm)6`2Ft#XvLUo|dyZYBGJ}IYX>nMozCpK@>I^x#!V%&De^$M`SymUUaV6 zH}xFv7IQz2b~rB;tdtS7r7;eM{6KqgUXUpN38HNo1Kd5oz@ycNtCRe)cIAj|G~^aL zcb$rGc;yMyedOH}t{k3Fmslrk`2%4g*`_VqAxfuiw1r1nT|RtkSqL8zK=v&TYCn|K z`pe!#qB!ANg;TJ-lm7q9n}!43)2_1883HIP_BF_nLTw4+HT& z=!xuRTmoT~D7E8kNk#LQFOEkd$ZDRrUxU9Oe*)VbU)Cl$gZbe1X&G3_kohIm;vZ${ zDuriV0ozF6uZddBWBsRuYJPv}H81ksJqgKULGEv&p|V=nlCr&A_j|ea_>LVH8eb`W z6QY%*Z)oL_L~oMT`^PSDOPsMrqG%zfUwjXQ?YUCew%0B;SFQ^FtroUNk{JNIWwCeQ z()s*R@;9b-ZDD(D4##VyoOVnY@n_$Aj7Z}7u?Ui5jQAePlIVM(el5}+CC4uBxeB2e{&p89k;`iv`0NUnrJGxSJ_}a zxm0+;mfBO3Br#9Rm{FYzt^_x%RbK2OGVWo)E65%eBk)uBjLlH6X*s*Doj)0i*f}s| zjl^Rah(qfE`V+OqTACuvS;-?JYlqwhqjQM5U_8#R>x@q3Y8un1c`nrh6c>s4n{JCY zs;VX4f799hw_WxP_lOU9OCi-_f)eAykmSZNIv7#_f!ovQfD!N}D_^_nau@6Dts>+) z<9S#r)^Pz|;NZnb{YShDUjjg&5#E+a&|xZ>TKP!x->?CIZM~j&JbfO)t2XHoLRLYLOyKVHX);7mho@7hZ;4 zFi2UW5SH29TL*1|4&vdHx+i`<$JSpvcY zzlk%i3cE<@sfP)>kYI%Z@`#~a`_P4DBq!QY*hM?SE{+Q*0ui$2dD3By3(wAx!SRRn zkA>&0a&_1ynNLd>+n&_0)3Tj9m8rdJ2dg)F%|9rnAdzpZ*h#>ION3&FU2t>MbaUg# ztWxYqbV-U`+lrlc*gdY;A#oqa&HJlj_kjq}%2FV;N?10;+%V5e*KLe;LsU+(wo54B z#v!&CXO2qSRkkU*t{C4&av_L$XpQ#CQd18lWDT~>oRsmewvn?!<&AnUs1=sdFxvAd zvKA@);!!?0yBh{2=D~YJGp7PNme3^FB>_=+{|JUGZDOz`81{IjF}mQasTUN3VL?tW zD7GvfO=C7BDyH9*-eF*93DMey8Q)5pp>!7F>IvUrW#l+ zR328ktv6Llw?L*G)0BWbE#21NF2(GC_^ghEboyd`1(5-Q?1AVe1eF3(CEOlJqI8M|d6()`Mx9uO^*eSPvkmEqf8CG%1mFd8}@zQM)9(UzeSh^;` zaVj6_jUDvsP+B^o;9BpaTRY+f_NU(-r?WSTz;dAgQaj$fdy1ovvD+zZg39|vxlzQs zz7t=zDUJ_(tdqhfR#rarnm2y(ZTm2E;EITdQEe6Re_)h-8Dt~U#}BEhFAE@FkmT%N8*z8Q843>JXJx~`WIp6U z)BWHUe6}_EQJBGIojHtH2gMb)kQZej#q%r9L~Ox!ol6AOrJS2Pf|&4k%UStX(e7pr zzpofph?2fUbOd`ooJ<=Xo;}ooIMR_aI-(<8tW)V?)z`ccnM)^o6ADzZG?~ocP%dt4 zu|&&wI^}#J7%`$g_*U9&0#~>CF5{^j$vT6IZd0JIq=juHHKu?C5QJ;c$OMD@4klyr zQKipn6A5N5W@+&8`?m@2_k^Q3ZcwYytk}8|W`LU^|0xx7wFuz@z|du&lN+;26JB6e zX~Gk_Z466ZVHnAfZPOii5)taK9o-W5Gct+NIyC(Sc5YM;C4(Q;9cAH$84`kDP3}n~ z+G=hIn&o}YG_}N`XlgO6RZ~mUZ}2%Gc1$f*DI$JDEY^HBdO+PzW>fVm(7Q1RXks@m z65Svikm%GDzqKwD*$_o%@R??&cy;Iy82~kFODzN7^LK{aFp=4E^|uW3rdA*^I`kh* zC$ft?B9;R}XKR=#@?Y`@5|HFEA7s|ZM*oi{fioF41l_Pp2ymPUy1Ee1wQWJB2`xcf zs0#eoQd80it8CKTF}1{!@!{QBz2;*QXax?zpQwNOl!}|C>aZX7#>!L0O6gD*Jg0vxHU2A^?G1awRLVW0!RL`58z#$nr*JJ2iJYschwX|xQrhqo79WR{NN z7L>86fO}{eIu4iB&gz(a#oZGN;+jn&D?P>JJ4{F=8EP^4H)#V42^y)lP3N8gYliw>ifIa<<)(si8t!*k0Ydfq=!sIatUfJwcX80kH6 zL<-A|a)gnRfhqngjFhTgVkDQRi%lR`$!C5x9EPxbR!RM>_DUdEwu|0 zD~i=hGLk~<9m?s*%#FHP!2dVOUaS7{do#ZUZS(=mxWchve2#wlb4331iN^c}LQ87V z{EVOC_qS&lD|o#lvO$yH1PrX@F7Z8oiHSxQTo}_G&1Nm1)9;v$MFtcPGfR{D)JMJq zu?T(2r{;X(fkH+YCAt+7y_Ad52XAlW-^AWr{tHEjwXlG>%QXU2ZbRR*FcMpwF$K3< zhN!Nmea_zbWj?Hxw6KU66G~Ad;5dCz2Dj1gTK1BlLp0KzTB&Bm$E_QZc#peNwC3+` z){VE;w(^iga-1@cIJ=Qlf@GEP)(NI`9Sp%DUal#Jcp$<@0maCO=C^DTx~RcQ&ps&A zLD5m^JTLYp3#F0&6zSOBi7B?jYfAPly{qk$d1A4P*2JTCLtP|0aUAk7Q(u&Cv6VtWA!DQFqZ&Ixvpj>fFH&_rLrF`_~e^+vz z?L|^K!(Mbtx>yov-ZQcx4PpWeE*fa00wDm%$Rsu;ZFLB5l~Re91iRScJbd4I_-to7 z+9}pOFO2Mx_|XRi^_EI3k*L53m0Yx&M@UwAEOcDKC>S8XvbWzwKhrI9ag_vxWvNW3 z_5vwrj}O5c8+_IKn8IPX>%t`Dq}VhObfg?ZMF zM3UVaPr2G0cSmu7=76uN7d9<1rmn05`p&$p1M{-`5PGL3WMw3r)`lgN#GUyg({lT8 zq^ZwGuDqr}yw6n$O3^~9By;DkkuT5qkTU30{?kf-G8223*mkrSgdusd>V!dXPcY9U z0Cgb%l%JkW9Q0^mDgyj%cr1_{#&r*(uC{usS+_qU*)TH%Ar)hl@C2i^6w;L`vuu&; zr73fw$$Qp*;?3^vfA*7`TNd7}NGiTmHXX@EGZe{pq#9`xisYS9!;6hyz-qq@|28+3FhQLp63u$y)!a5g9odh>8G--7c8l2Ts zX=Zw!17h-b1p$oCrAqerq3XAD%{k^a$yBZ~3Z} zANIC6`k1O?N9TlLACqbK5Mi1sV`3V7;C&xK8C`DVj}11_P#}4JR~FUwj9#;zrL3^_ z-Nf<1vkzg7`%`W<5}9qin>LWZlXrXHFrphQxXa< zhuR3~;+Y*vN~9b|=!5OO!&KelF)TXxA-IlDfW@Y7MwJi>f3%eDu%xvwS;QGzy4!WC zqbLHdveUAsCgPxMUhH99zLiYZ72PK}F!EKj$R#Vn(A^##L}XO=Z52q$WV{WTxv2iK zfF*0jR2ztpk~u|=Lgb`>yDfbg+`JSLSa|Gs5^IxWPSG(5p*o|ZL~xB(n)iSZEsRHq z)?sHH&WyvZIP3;Abm1I63)pZ1J%b)d0^Sv@!}74U14XJiBg93p z0kNk|pF!G_2$a(zaNQ-~ivojr@GG66xbL!F;@h3Dxim+2v_=0RwW%vD39|V!>CWWy zmXSL_m_3t&=d7O}Z%f=%6``vBSVydP)%L`#ZHF^>ITJRqHSs_8iZ14c)PR?G*su8C z^cK=EH(5@3R{Re)r}*DMuZaIqxm&LfX7E4tZ^5s!>aqV=$2*Kc?mq9|=uTYc>%2zC z2014F(y+i$I&$=qWS6sf4e$=60oY&HxBMT@^Fcw$?2_HBF9uRnQ4w|)>uT&yvi>?P zcw%8H3*5@VTVGLH;F9y461(}utzr3ojm`1NoJtAS=T78+XD6p3ZyySjpOrrg`oS?G zie+zN${-ICd&%t+g8B_K8#x!3ymr-}iFMm4)~QkUTRAP$CzL0L)(HBtX8W-W`l0yx zS6=wAF%Cr>mg2D42Yl;#1mfev4!X-HShMuC=;zO7Q5Jo<`Z$R0(Kmgc;Xi&jz+G6a zO{QYFeu=e-vNpQR^P;uMveeoH1>JG2&4OPv+0d+{wMmL!u}HgdJ1^HJGtD(jNbXIC z;HCUIbZGKnEljH?xhxLq!TKT}ZS~olrh1N_tm)wi+~X8gTn`P-LU8GxKl;vHcRh5E zuF!4v%~LWJ&R#E>^5(Fq+k@&h2-Iw`UbsYH6-HrhpFLVBKrx-S7iA}goq|#1PnL-1 zPAr~4QoRLCUT6GgkFuxH4{w5?PV=gV;n;Q|a{h#ZRm_Ptd9#WqC$4J1r&rku5EZbR z28=Tr36<)y(F&U`$a=a$$qKd0$TbZOo@RjSd6FfQKBBqM7wB#3!cbpjHcMFQdHTX! zj@U6_{n?{^zct#sN2FElQ6FNE@3$>JW7vD+xPaAqqT+o)@KyUQUZ}>ggwj{xDWkpv2rVabge{e_H z)m{GYeGD&6h4ctRVimMBJ{cYmDH{?gL5L|Ku5>rxu91)!7XR;jF*=*Spq0c@x5wK@ z*G#Gc%~tABW{9`H0S0(K@ZY9WlhPKmlD|+VnMI+DkLNE! zzEdep3ZgdiC!wzqbA@jPuSJ2X#GU+7>`nrO|3MGw47R{vZ_J zF2B-FDwuFQe8Yg6o|Nm5-na+(ive-e)(vp+O$i&mNv{N(x-`y1JFz;@!~7+}#|2i^ zx(kPN!3!#ZoM91-dlrv%^WSTUE-r|4(CR6zT`K5XaH&h(>9l3s=-Y~k65vmcvV_e2 zOBEgMujMZTAtk{L;XQY?_7v>*YFe-RE6t(W_AF+ji)Hi>y>1r^LD$<7g=Eo$rJ!`i zkOu0_Kte2WJ|^{W2^aK<>WB;KMXy-Uw73rMy}KM_un>vB?0DGaaM=TBIcOz_srAWyMu9|2|!FO#|ku1+WZe84G(V=8YF|`qPPc8&on7N z6T^*3TmDD94>zLB6|Lt3Bj*L#{h8-F*L^lB0xBqkTclkW!k zv?EBooE?b9w=LD1!xzL@rkA9JW}?>RsKwo29y`T6b_MGIBOGU??bIr!z*|(oBFf@l zn`MoOB3uA0PdgSX;T!d!Ug;)^uB*g^_BUIJN;kHHi<_ZW>T{{YgadRjv8cc7d{DLn z00n?9rFEjj1ZFYhDUgdN9m;zmDiJ7vJY)--K+aD=95|*k&Vjz=(fu!c%j-Y+sYm1E z`D#lxLl7~KOhML)KOKgcB3aag38V=AZM)f33fA|FKl?s2#epH1;ygEN`nqLBlesc% z4&m#z;nLU8ElXcFlr2K`J7H4XO1rFFhhBe0+7C0x)=SCXEwn87#l?1_K6VCMnvrX% z5N^UV<~$7*+!{y7T+k~rK(XPcUSC*kw#Jae4n#o- zlzULX>*>CVCOS4B9BW&-0 zhsmS@c4=WyHeGN7q6@=7F3=2Rn-SH(YI&)|J?~dizkfdmb^!WJhIOcsAe}L_qDUPm zl1cbN9OgI-5=E*rl9Cjez?;q|io}Jqd~{Yal8PefV#P=*iZo^; z6meLJ!)70{Epb5I;1MZG@+|Kxvhp)Fhn zmNIlUDZN>0bPvMw6Vh8J<;)f6%2sX)5q`9*Y@1HB#w9h7<(j-e5mLxcd4Z(ba*E)i zhcKH_v$S;d=vJe291tUbbT+`ti8H0+fD^EwKWT{(^L0;$uy>S4GV1nw?*ftq$R$wyEYYrN+PJ(=4EleM=suxkcdK5_7_k{#j!cx!E7kMf00N54tqm!xO_N)WI0-N{VoQ0)mi8o9IsBIa0NF8sW z<>Jk_9Lae3uvvufvZ^SlgXcMb~ zxneDE7e=QZez6Lp?F{EaiL`3SNb5ag2pXs%E$3}yL-_$0=VXS!s-*g_+PEk@j9k0O zTY0NAR!_DH5t0q6Axn{4j1K^Xs17L}9JIWFB7{Wxhm;8s91{RSw^%kJNoW~fK+1mB znI78iGtr_QJ`*iEg9eDalQ$#3ga`3IFXR2d98ZR+7ry!?HL)ujUH;!g4eaH=m@Yit zhI;U0dY3cW#1!VpoOCw0vfYw1%lu`$;}(;ub!`dTlZ#ge@FAzFa!bhE%6aiUEfOgx za+h03BxJ}x!Br8}T4_zja>lTC&Eg!$&_+m3WvAv;myASu#V}7GgZE4Tse}v^xd+9^ z^G$yUcqwOF@y_HrmE_GH0xp!d)sT@v(h%fMDtGC}=Df{<>IoU}j<$si?Ddl(jty`z zLG5NJF4wi;ipLT%kU1vga8$1kk``H?%%mhm!XCu?0tHle5rU*N?8qh#F;SRsvabmf z%w)`!usjId;%&wRX)X~ZoNS9sifxWsbwigYl_dE1geJkd#dCPCM3XLP5*LgnauS0k zbE*U|mns49!SH^jlfnL0vlDUA!V04T#e7B^e?vwvz&U!|&9A*#hKtc_brK;gdJJyo z$J(P0zxL+;75BXWL&-5n71gwVo*jCzX0q%?8=sm#9=}Y6Mbx2r+O!_O9EL7UzSOy< znFxynXX8_c&;^iAY_yq-YEp}3#1*(%j6CEWIDud6z-bP}eLgKz9x6|b2T3m`C>`#` zE4z~yNurK8mfH3K7;)PvA@Lh?VUI}n68+soA&P<#(7q-YIBJ&PltEjg@TgjHJkhpV z64#7jC>7daT;M;AsB^8dXU+UM+5m#seX+~1L5oU_H<27Xztd3|srb!|LWQzXAB_pe zQUipYzADbZ+*hat_{D?hLByIUoX6@57qQrkmz^HU%0f9kml7>WjD-egGnUR2V?nYOV*&7R5u<|+W-KfvnWBZ< zrXb=V;wmTU0v#zWHbF~tEoh0(#8ohdnRN4LjjPc1;kgPD=uvQ$L@rWwgTIMtGIJm! zW}E3M4o8QI!aAE|=)PoG3xO^XEhIFrmvuzKtpe2K`qhZ#MrSS0%N$ek0?pnyqG_Fe z3Y+;K0oe?WO*~;NT8?b+VHdQ{7YbZIgu>7fZ4U$*6J2CPl~@gy5*@?|6Rip>dRN^T ztvnqEi+-!aVkbR#nur>9A9|S37-BZEd?f02hUJTR27F!*J`Wg!?MlS+37^-`z-MpE z2?#<^Ivj6YP!`V^9-$YkEhuSxC2!<4P4?@FkBo-<~SGk1As@rf#0%K6El&*K9glz9yL-^JQ`0?<@$F_w4 z=u`32vgJeLmU;7I+dw+7{sY@aD_3^TIW7Az7orP?Xd$(KNbQ5Wdg_f2fjKSl93=a+ z>=Pp7EJd(mn2Pss^Ap?5nab;C=OvryvPMcaF`RekS`7_pr$$t@c!X8T`|h*mDy0Wa zT7fTRJ6`nWLQZOvYnV43Jrit3>zk-X9CYg|HnV;cD*%x}A%C<)9?SDZ7DF-SBziB0 zwBAM&NF(4Ata}<0J7zTFHKg8Fad+ORCa}A2sv+$^kuB2!5fueAh8|i`fyN{iKoLPt z8nFDkEPrPMX{uTNcx+d(Gv(C-D=+`-uzC_&5=^-whbEU}EsM(onOu?Wv6Xo*f zybVKD5(v=grsdyd`8$gc;kR7=bHUCSx|Y8~Iyn^Gdu{pCcD4M~ zu~o}|?rtpqYr1X8R#KDhE;}=hLjT3px{dO02&r6#_VF2?3b7(y!D#Jb(7NH zIxUxVGnPx8TgK?dD}wJK1eB^GDXaCBURu%0+tX%+!*I(a{UHtl$+TRuv|J8vR+!+H zGArC$-0}$0-_h9=Cb{KJon}vw2{L&#F@_P<>1gAtR0bbA)j7m!$OM9{qiPZA8Reb5{OKq0hW_qyjm|_TfX?#kL-Wt zAALNfaFOa2TN3s1Pqzq_EwJgy8e;`=3$I7IBAp9kTJLdurYW^jdV23{`uv;M;D+6- zi_&RZk9$-Dbd`~MiFK4z#qjYED#9fR<}!v@Qr88^;wSkQOIxD4E@CVU3z8TPV)>yK zooPP2;n;FLu*7{gNNe2c)T1=RWXoIsK&TiGKO);EFh3oW-}9gS-Z$^tn}E(x=QKuq zcST1Uc-e1tpI=MaR+)A9ntL|Y|LCKf%nT(4piUKQ_U1EKHtIdM?lA)tSSe%BpH=s% z%;LCLbrg%ILj&B7;3kzPJ^VRZPtPK-L_}pK3^FSM4Gt4{4XG3w;4x5)t~4*$Z%RN@ zm*Z2EXo!COqxu!*vcaq7O4t4h@!l=RMbtiKbJvuq70ZY}=RV55u4r$GR#GZt9-DgJ zrr8~3@NcGQ3P z9paire=z7|*}mYJ%UhR!hJGzPcGD$So%QgB8dEnVrO<8ZcfIA#v(=;oDC~4B&D!XZ z>NGekN9waH;kP_8iJYsRZH2E&PYmh5o{>3GBk#z3MJw3D7&&m)$YuVMSx}fNCqIL3 zFc=Lxji^!fS=0-b*AS!N0b(90x1gTz6T+uqwMG$4?#MALU6^Ex7DHCv_?}^VldNC7 zsdC%xP5F7uArh~&(CAO&l#J;vz!_EPR-=I*n;oI<#^1}_|JLmHHm`b5L7hf8R*5Sr z^K0{2`OB3k&b=yAoQ^0Ou%+#7g$K+J0d3hfb$54p@Ak=iy8H0PX2zvAAKoZ*=BjMG zv<2NeT_cNzX`(oD{)AC;(T@T~wpEL=7tD>y>ep{c&*9~~XsE$7$-pSu)MaZhw7F52 zq+2H(kMp=Ig<(7v#ztT{qVC06RDGI^$%De4b5zzhEypv9j9}3+4$A(=1+WM+q>!n7 zA4eUm83*Nww;y2~2bHc3o*xC`%bF=r%gA%p03hz-IxGa%wRjJzng}9)!mj=5cm37d z-pvcZl!{tETT)TwAty7gU&7?Jaflcf)s%-4?!xXP8?NL>k>ni_x0|6dqE521m~SO@ zSrjB#l}VQ+&)N>l zu2v~1@jK%}Unt?z(#jhYDn5D}U77@xVPs6@6Y{#52I1wWI6U;GS9t)_3r z^Ar5+uz}>6#@Pfk3M2;=97xV@OHf)93PQp-E)j`86cqX>QUKzN0=*>%%993cGcxev zbkrO?s|Ux<%CZUuJ;_xJQ%p3tY*xvoVD3$sso6~#(y1wTNT;0u%weQbHZV}mKk2QK zN+n(}8w4_>*-+*x7e$Fat{HGTH5~=oaF9$jrUk(;Y+t$J8q-@~@SunyAUT-y2N)bk zu_QX639nd;h7`%FNUM&U@CQf#32fNrp5&ZutQ$@*XNsiI1)&jy zh_eOGvpum_v#| zjwQ{5;EhoOZA%MyBRvXLO>2ju6xL7b#t*Pd)Q}eukR*Qiz1=uD$xA^3V11Q57UKB8 zi#5KcMX+{D__IFs6#9WcPRSMfyYF@l1J?{yyXIO#-2#rFExR<}QDYw~X|3qLKOEDUN04rBx8j5TSoC;PY@~+6bOQBqpn7C_Mca+3Ju~@#tYVB z$pP~T!pT!H&H8W&>{~@U&t#4vp5Al;2b@?0hWOwVKClymeid<8(g@s!hAlodm%p0v z$QHdzhXh0+7qB^1Hpep(Ks%#{r7{oLib(SX~u=2IOtGxW*adOaLPwt2r_$UinSW zfwqrubreD$q z^o-hjM%npxG-Z2Ga24I>MFF5S+f1Jh$Rg^oa4et;%H&a1CFIn&j?-k5pHuQjfz+>G z`GU|H&lCEwgpomY285S&wthBbQxO&9XX$!aE#-=y8HK4O)&(k;PKMEgJ`fL`=@20v(I>g2cLFy-+UU z%N?dTU(d#2!?^|ha^f)(3}x^f?UN(~-XYoV1Ij2z<&bR+3|P`e zCX_Zy>CC{6dvA(0II?&n}yEs4)!K8u)aQu9;l9S(&IQke-r zmi^E-tlUA~an@lQmvYx~b;x!ionj`*521lM%eXz!enX-G<9z`=e9V%v`dZH6atA922vhd!^vZWz&y0Ek3yAE!;W~MT zQLw8FaxSZ#TH$ZMEr%Bw@4{k0LAK=vV4(mRb0Dxv(PhcChhS%}JJ?u+uEmfTZDByX3s~<~fvP=UH)zTRIGT%1lAv&#$pstf*&9a&{x6>a2PZ-JyIDC%298itq;F zDUyWAN$tFWc4EQPZBPyzA&bLAi3(}5ArZylcm>%`*1D7uw0e z{GOJ#X;tBHEQwQPCd$QqpA zkvmirO@`*3h8z_o5TD~GQk2fRuLOg1_fU@>)~56q6KT`JpACN9X*x8z#| zXHmUlGiRH9jkT=IT>>2BsL=HC2Vda7+S0poSsL&=qg;pWq;(VTM07Xy8Wv%<^b2V8 z!Z1d!+%G%OxbN&reTB^jpJJm8U1pOBZ-s%GM;kN9)g>I`kL@5O(KLQ`&>FF6vpk{m z?r*+L#EWrY5WZRoRZO8`LNp(4ydN~Efa4-xcncB(u&Rm3Q|DqGXz zhbqLV(ys78%>;JJA`T}ru&OO4Q1oS7Dqs63Y6@DlaiF)qvgXuI!Ce`lVu<|2>Pybgw#pKji&a)_4XG_|A*Op3g`WR3vt?EYF`vIJlL43S>>8?Kq$ji^uH<b=S@q>>av0E2knuaIp^2Eo!oh}Ai@Ey7zy9NDgU3`ori?ligvGG53(&A{ zJj8PnWv_{)7F~zV#)P%eE2mo|d`*{g>U{0;7z0=uN33pX* z0dUaH`+08-buBw%LQ^}7)_tAzB7{W@sg61^S>H`_c(0*L_)p$-Z|nrM`51SCy6qJ= zy^q)obgfwdMpIM7Mqie3%E)Cv;Ws(p!j(+e=9*_eE-yC#>JNBN4I6R z4dur-n1s&4_9IF;6;5b|W4SA(S4y`+k$Z@M*224pT1EuSYiNwbCBvrVo7cYKI%^_{ zSpkvK{nneG^|zmYTu5~6{(@KwO(EoeEU%K1cz&2p_1ra0fJk)*jL_8-@F}CFC>+2B8+)^lZQj-1F<9E z)6P$bvXVz&v*ZXVh{T6&vL#C5Bh-F$P)Y;E#I-8Uh@0LVRXE-1sdNM`-xYU{@)-&&<~I?~)F`+o78+j4SZGS#f>N@msyHXHbw@dI zVomGF3+=^sd!c>1-HTEJ8KneLWf15`Dm+Eckh^P@L6{}flIWOBRWLm+pseTn7IFAO z$B)v4f>fotcIL8&DZ(d7012exvgVXzuYpD+Usfg*E=y{waoKsX@?gZoLuj*^;X1t{ zvCS43wgZ`ELXi&4gh-A+Pxo*Y+rT`0Uky=Fwh$N(F$11Z@;;h8MeoH?e9$kd6f2Os znH#~vZX*dZ!j3=yp@Q`dWamC4o_Zvr^6cseGr@4iqH)EMc~u;lPZdX$Y+)+@H*+oR zuV4rI{>Zg)W4TC1?7Zhy>;lq5=mTFH{RNw$UTrPLT1^V?g()e3?TIXF9>VM_G54mA zTV8HeJ7DbcGg?%1fz=Hi6VldAIwG0QZFsI!5{H24vw;tY z16LhLaae)_%B5z4|MqV|7v&Rw_(^?2_iT9bw%_9*j7GWF_dKvodwr|$h*zL%>LZOe zhJ69jdwpx0LbNj!9Y@k*J@wN}b0km~N+ssANf=?z4xV$26(3ktMV#eBy;JFBD7Zw= zV9M{ylt0-BMl=Ojk%J6Kn4kPLEooLUCMJ!$N|1m72rXel$~q!=@v>&7;Od6P?CDp> zQd}-*!IajyR6CF?`HB~pD-e=d6Y)6NB=tV_ClDP{UlLDv9B(6X4wkeZPd=! z@;xo4OPS+pgCX^TQSTJTegR!(qCFRp#DIi9I#}&51i?|StX3-ti^0;C_bfu10zo45 z4Ai*PxK=(8)8N_WElOvnF11E4AWZRfbZhzz$DhRpVCreEXwU+yP=$3~OE3GB@SYwg z45!&~YFS;FXJ!OY^_dyuFIL)a{`$1ys!Sp3n;E}HWYdHJNnKF;WYCoNzD5H!E=Bj2 zD3+bx!v0jdG1~8xoOj(Day;R#wV<~Gk~S8)XYA;jYBkN4<0%J^tl<`GOJ}0V!L^F^ zbuz=fV)Cu5yez6p+(+KXwaV^8%WjySS1%p8^fp&n- z4}=b*O~ZVn!(^>1JR6>5r-qF5L|6y2;UH$yw^Kv>CQ@dis@t56U?+1Go>b_7WK$M( z3(tnGg=a%&2g9?WQ&_%=2W_E2qydpr`!{6VoA5By#4MG4Ys>S2oV8Q4tcNXU$?`Q_ z*^Mp5Bngw;TuRaQ>eawB6Ec zxHw+>{Zun9^D2$nl=Yf%Ss9XwcOPX`x-i_`2cVCMW3pykHlt>o3VzJ28P^NSAOR1X zA%YZbt7S)^!f|v4BNfkM-YE}>@CC*?d|M^S7Rh~fm$++f+A1uclc8E{)nyN~|MK_8 zMjF?B_>aH-S2rym>qZ){yQlU&h+PgUmoKudGGZj4iH%|?gFXz8G4IIUtCM912`65p z7cA)lq_y;tDt9Biq!5tshgB8D_2jL(dXMaJ@T#^eVaYCF6>amBU2*5p*%gzegZ1Hn z7>LZIbunC%(zL?9ClY^p5!^uC#k(EK|NM` zCuH~4>OdJKuu2^enj$Bm2Gff(q++bq=-|W6EX9DZ06SyoDmNs!kX^wWOTQ3W_RlmQ z1|^aqU;Zs=ksPq(^37}+R$_@jKVb6h{7o%9k#qqro5O%gtYNRfzIp_}OJDqDQ>YP$HYv z+UGyR`_ag}E&iIsaH+t|Y!bwkut%7MzoS`7ZdjLhAq$Y^_UeUj!&YXQaKny&uI+{e zzK{?S8UIBKM*9Xz(3cd?43=s7>a?sq zUQAu%^^+!^km-lz+#9?nYdV?+(&f-6r7eSj80*9%Ch|b-I6N`LpPYk&JC#3wtBiEE zDM|Afmq75b+SOYv)S9MG+F52KO}JE22}R%g;OXwu5R4e^U`6%Gm;rEmJM z3}1?;B7T!Wig%b*5Ng#7$|kmn2rf*4F31XLb)evv)d6|nY@QPV3>}{r18s5lgY>$M4sqVK~M?ECK{j1doH+z zXhZ}QBmrd6u!s>*K}Er*=KcQPS9R{Wy-a4ZIl*M0&$)H#)T#RF+v}^ZGD}J&P*}Pp zjjR)TdZHhHC$0SpA9*(sRL6Jz-GeLwfxS#(IE4$qUk5!N6@ib6z;8Yg_#1GEM@1l9 z_)!tKtO)$i|1uGH@9~Sk_mvFIpicxtQ>ucicy&d^qVKv&fLN9(gocE&As3C}k}S$y z+EbJOo!^r6BMID<*fm*Nm-T~wlXQ{O7-#4Z_hJ389x1Dzc1zYzP1cWTu`*VA()=Tp zO0<`;==gfHYFr~SOGYXJd){Rg1Zh>vf8nK-&b#St{3n~O-E}LLAz~AeJe;0zux?f( zOcz@gJ^LSc3)d7?$H{}mbF^%p2NURzU)FnyrD%FyHN@}QE4@N9nTjl$G9?E(zpao? zGrIrac$VKTIf~g$gTd(5F8t_nGW_*SZuH~fQK=k2c$DUCu~C*URH=wa<@r0N1X>Rt&A@@$HYQ+v)!!LdmIln}_yI99B zg>$-ala!=*LuZ6&FjO%?E^%gZyzD78-9R2PnlN?8H3akDmou4>1Mi%Ti!WL-;QcuB;)kg2qzZiJhtL;UlzH zJPd^PhmQn8lT7`lAhbIkCA1S!qP?<5Xus2_)oyC~xtmG}Sz06Y6))B;S+~c;{5ttv z@lwO7^V>h8KxZwM?q<2uHehRw5*?h#FGKFcXwE@7QoO%YE_98lHP zI@tMfb%qtEeWXKLyI=(;rVYg49a?S$1Ddg_TEiIXTf-QF&01uB-6QiYmL(k@QcJ}e z27y%eA>Vna?Y-oh>rI9&#fneYckE)DGg!k{o!6mK6a=NCkk`z3E5WYHe5o zQ(GxKBY;J5Fxb^ zoV?n7L&N1%xs^8xS-!Zos3i?eDSiU*TIy2_kkk!!LYIYwr#l7SC=} zRbRzq!oq*HnY8yau43N)FTCm#b40hAkxd{lrmcaFzx2d*{l(PV-;NO|3=FWh=oKxk zE(3ekr(Ol z|H-*T5(PAAxTmA1ZBp(Gxiid|=GH`epXE%`gg!6wjvxK3^xIysF_gD_&hR#5=~p91 z=ch%?2|hW};XCqw`SWTdG6QGJpcFUDuaTpuEByizTWj_@A{N#bJZhFfoHb5kKSa5_ zPb6S^^G^peVo^l+v7R*{vLmC1q539JpRFq;)K@AG<;P~fC|_n#60WR^e5KWJ21U%R zfM=EWg(44SoLVg>zp(ZZ$>HR=b3!f+CDR8amOCEVahvgnj*+hdj<7cfA4&hHHlWxN z{okxFfo(aF%c{6Z+_Xauc+255M!9&Z~ZY zi-azWoFwTXW~y2^J8*BMxImug#5#SRDvx|Y+;+kU`ieu>yQ?K-+D8>Z``O-4YnyL z3&3_fucu?sxr4m}dXey!SHt2p6=SL64HaS1W`?Eq>0XLM5qk;D`57WF^^pc28P5GA z-jt^t(?gOcO${gU+R3|Qh0;%*#0%sJWXT2&(M6rs+a2`HP{ZU$3&q48DH^)}AAxhI znMrXxt8PBN#m^Oj>Id8AZfSsCb|h=gN9?#Y9m(o--Cwfev8z?p(y^=NZ5am7(Y#6`^@n-bLwt3xCw zS8x(19UtYqOr^?Zhj8q7*N%d2$DZ3MLNyQpv?P-WLu6nvte5*bM$)jtdWSVJ9E7Uv z^p^F-(1)@gwBw<5vZG~x5!V{kmi%4aL3CE+B&d$q^z0Yp zgB*nF1?6*)n_9nVhV>gnj^Z*Aup!{+i;W`syAYyM5oDW|H|Rzo8u#bA*(wS%-(~;) z+za9GyuWCFu1Q>$Wiw~(ieyFN636PNKp`mymX)|xO?+seBypQif1^wKHJz%)A-+W- zmI1X>lDPg6A_Fi)6~irT)hm*?O3T7MVc|<8u2i?1w3gfng6PEVZIrm$Uu5FLB<@zr zEFd|${^)X)CCUqn*k{j1)(CP`FoVTIHzr3{Ixm^${c==`fYL3s?HMiiW<;S%mx6zq;N_Fua49cP|l7csRMG=M@ zmw$!rSbrudEw!1xXvTq6HgF%(y7|QPH2lo*D!IpO@%jD=ZH(BSa0?>9 z!Wisq0h0qDyMzV|&bFhC4}lB-9qK^Xpm8TK)|A+RObM_!GeTkk-4o$Gva>tdmabZW7!zuJ-v}OxcROP-7#)WTO)g;owd;L0}PbVQj(@Sk`3?bb_&7O*^rIG zhmE<8;6hPxd-E(CE`4VgF_ zl{g#C^f-z$?(5?eNt|_LO(4#i95FGfcoq6XkD5W8H4$f{QbyQTAH~_Ii?dM|XIx|^ zj&f$SlQGLe3YulLzh@jiF#iE<7vfAETe3@K^nRS{{r-k!(+sg4W=KC2!mP(wQCXz+ ztz@8xPxKh8QD4pQys$<(3*po@UJ0FytN^(zZ9s+QMAKBSAWMhTry-Z6!Vt@u)x(z5xPLhl{L`vBbbXY4YeePB2kuLleza_2`~Kui2*wpi zChLUlb!H0QH$#`FsLar{pR?u+9Zy@q&?#P?q1T+D*Myl(Ic>$z&G9N#XsH=k^t9tW zWs_wzT7kfQiJynLw@eF*GWp$FVuq^+XKVDn+EQKIBUe=bH4AluzINLZK&_J%O@~H| zb2Omg+P1_B9)m4iMmCi?Md`dePQKs7#O^x(0{*Dh7``~#Sz4$=(;;Bg^ODAtdb@fLb*x`p55k?BLX{ z9(~zw`%__|t&m`g{$`xLYBdFWGq-HG0c5%HXKJjBufGe zACSAlR;&K}=l}Po+4(d;lp-Lxgmf!IIFbL3J(;1MB(|eN%m!yAHE#O>4qyPsjUox5trn-#_`b<&1fRT#S*rvw#n{&iB@!hBrk`+DU`kDGXH51=;w z!OApF&5?((TLLZ!Lc=zOu1#q^!Q0B;QM&Z|`5^)l>EZaYUjl~s+YxGVJN4PN94Ktb zvTPQA+;8vSEN<(cMIAPi&ko&H&TnUZvB7C#E4rPGWjq?l!;5br31s-%2Xz337= zE1`)|LR)+XMV=;|Ln3zTdg8#N^u$atae_hl!a`b_RssWii6YE2La~` z0O$Rtc(`9oyz!t=JSZ(S;J@@BtJl;k4aL7$EQ7Xioi40ofm-=Z3Q!~BUG?-_RJL~t zkC0}%Tcq;jxAYekIxz*aJ{wR16Vn@{((0KH=_kT4xtNo)zBLBm7z1wYfXX?v#82FA-&0A~@IX zv?+=70BAY7KwXeu$$C`YuTd^P8Y$Om_uVV){~@ zq0mKQhR7Mbe8|uO!}SCXK2PQx&g3Hw(-mWg2+XI<=Sg=yPrCDY(w)y!UGro|0DVGH z7iS4^w@Nj5+;PMSy}eEdnMfuqqjMwS2Uaq&ZhcptaLx~if2S=@*XXRO64YUSJ{^{$ zGBjy%L+nINDy?xUu>)&SYqg`aR$ttj@Yq^wJ*cg*;qyW4TW5vVnnxLFYw<|kh68SE z9@N&>o8tkLO_ZUC2pr96Wmn$UH-(L8PUVtgGOceGN@Ac_hCN~Tqsa^*_D4uE!=I@U z=u|muqEVrtE*Z1RQ`qZ_T-0Qf7{?D`fn@R3)#X2Ae|T>#j`a2L6gdpdLN)=|)bT$g zO-1WN)fsZ8KNK7QJZf1zjj@jC~wOm`gFIVA^)Ltzf1OYpwWjAq5 z^k(RJ-42LWV3y*al0g5HDJgPzI@CWM4kL3*vc76WJOn{OB!j zebZmymJrRzQz4&1L+M4=2n_I!!f6;nG3A&i;nd}7!F&_a?BLuUlIgY@K_tOwd-tPx zK~FSN0;3GuA&t(>r~xu*mdz9T0jU_ZWzHTv#<1g{TcGKivVkEf5+IzE4d)In}w0BsCwD(4#y-UAFiI*-+F^ptWzOk&ma}JEGJ~TsA_Mn1G zm4|f^=VMa7VT#o|6+9vB>2w7SV#G)O#0|~z9jSS(&TC;&ri`!QlW6t|!8U`ylyOVT zCE%fqOWZfgs<=+2kqe?v6$gn-yOO=$2-O%X=`~RwFdvR)cJ*@LIzU5& zqs_NXq#Kv=HR&fFDg`@rnFF1DFnGD|z9vC*UK<}0^`6Rw_3bK)k+m&q=HdI74UL>u zPpSirv^_jB+F7&qr1ht4*!Y-JPhK~+YISRH2!;nMsWJu}ckMZ zn}r3Oh?ftK=NlQ!xjYf)Kp+U|IUVp+{0u|wC!^4eSKAx7*ozkppO)7tKL=E^EH!G! z7E{#fWAc-E_QW*LU{r%(Ge}L8tnjND&I=TZucuG|7UvqYRc`D%A-O(*MSgaE3e7x0 z3o@32Tb~B@8z?+m%2`Vch~V2Fbu28!J&P*x0qUKlU{Z{I7R{)sK<5hSJsUhZQ(j0^ zQh29SQj2!pkT-eqtv04YEoHHNL*AnNj5HtQvI!WtdP-97Q}ZE;9$$>TI=rFHQbM1K zx-mbAI*(INq^aiX`E|P0ftsxd*#Nj*seKk-V?$#5vFe|Q8IU!eHM}-&Q^;yd%htC~ z$=C98oS%q|sy@j8-^azUr)~0@WNx{9CrH~ zUju4vK1%7SC1qCIU|g9crrMQR7!T9174XuTbFF`u53kQVytxrCZBSg-=VKIrKg#}S zfzDO5SbzHb;gj-JJUv-X-KfjPdLpj&Nt}PcWnF57w>Hfm!>=`7xY`R>rG|84so`ZO zwdo(_zyxZJqz1iVpTKr%0Oss&&D~I%uj4Z4g{{=4rnzl-5kdXJM;y{`Z&Xu{9=$)j35jYP2r(nVvj`6p08-65LIa;l>>Nm@!x`(MVE%X6 zaK-o+rFA=2l^UrZsG0_YiAOCf34tTRxnZg)=)RlUFQ}L0L$BoqlhL_CEO6QnONI$m z{gc_ytqS-#j0N+xZ~VsllSBG-mLB+t1QR!&0=dMVQ}aNmQd^UlPcUhGum-|4Yi%_hfC1(SfY(gEfPdv)z5W zwAjK>HX^n#(r>A@eUdagHRJVJTLC^R0iH(z@V;^4m;gT{swZy8hLf60n1C1G?=S?l zr?ONrLL;@Og{3+SWwR?sbZ(n-v}`_Pbe>v368p=`ma36BCrxNjW~plDcqH!OMZ_(u zlRbeped>)IuaUORC{0V`Ob3?|a-jV5>(#2xybI3sJ|TWw%9+3}H#4&;fz9kPppG4{ zj>yvS>e4$Eh$T@5`k}jNqY>pYgxE`k1PW{Et*-J&#|qSMOPEk(wZbczC!0onk_Yzq z^rv{FK%qu~3i6actoqYys-6yK$v)O&fxGdW2$kTb1~8K2QYVkkA^i}kleObgCtt2y zbITp|bc_~uz$5WtF}JuyL5_4`j-2O)RPOorwB<%WKo6~h7i{H4t1q_AzxOk4^Iv*q zG&pVMyCOlARUUT~pnpW~AO3K~b5zTJh&h6Ng9!=M0@N7A)+Kn!!+1*h*UNEiSZ5x| zh5;Or+VVCa#+{eFRl<76r^ImxFn(p7T9sM^EVbcVjIR^ zyAq-8I~FU&@ahVqH^zd{yyB5R$)EK2|A8L8*<6czoX<2U$O!KO!;J}0C=3Bc06z}_ zMv}X>z}nD?s%a>=O)*-vKHM~ct`m2#%;euN9SU<|TSf}e3KM5xVkSL>BT2qAuBc9U zSW|P3pM+>2;)>$?U_z0xvV@q#7%f3e9KuC_r4Bz)x&qV^a|A3?zl4}NzY)C|8c-Z& z-L}ODM92w6H-hm+e*5~e!Sz;6GOb<;uGb-AP2U8sy$vzAo?>*sSWyR%`A5+339eTX zbz(6GWCIg!fjMehm1WMSyCe{3;`Y{=(JJ0o)pGO+Fm zWCj&+hsa&_1(~E0$*h{9lByn+Ns;d_Khqx?tf*!?%MeRgj#b!j=WiiUy}T(Kx>0aF zKhw5vI>;%>WxS*0d?^(0lOzU>FN<>+QAfo&NOpOgvkjQe_y7G}KlOdEtv-xB|)LUXPL%^CCplf(Al`x66xN3|Mw>0)E^ienZrSxLlXs4Hg2%g-tMlKl$JytZ(w z3{Qv+w*|}3@C*5han-bB9JLDL2vZ6&fn^-Ho{iSHmrcA@^K;-J!E{k{ishtIAV^qb zLk8ILzS}H?Z$cp|@oZQ z=1K;wwI0;g+7GBT6fKPu=eIfc*%=1QaK%ljy?K@mEL#5W8>e(9j{sP9sGSqJb8AlI z&XpoD`Vjd3q1;C4W8w%&R|sf0ee}2vW?!q`OX51<9Htw;salX6&U-bOC zutv&*+U;z?Pf>iI9q{4%5s&#kwU+5ZPJFO|#JeGdMOsU1YhUDduN!C!-VME|l{(lS zWsABJ7VRHW0C^a8uV?>709xFQ;{wpj2MY|65uq7emLRbNP}+Ufv&4HOf9?mzzHH^z zdK`N(SCsNDTei#+S7@jzR3m`WLq^b5g@wF$JaS-#rZwV+yN@eMmlLRuD+-wtsE;ek zniHsxD~g;GsE;cOvT`3Kw8TyDU&}FjbU}vSDyBvo5F5%!1BZarVHNy>@>$hXv@ycU zf&=gfo>8?@!XpqZ@*Gw42n}1c!%G`^>2x*;>#<@i@=oWsE3l9d@GN$>5eZDIWr;3t zcaXfe!UFTKHEg}xAe?YXbp>nt5IsG3mZa~gSK{LOiN;xjW?j;S8w|`86Qo&BPj8mz zv&8kWP?qI^c4Az0F`urXx|SQV?I>n(yFMT$%^`^a&IQ-EIn#3ZiQBga#`F4SLBJO} zuIYRga0K=44?QB(P8|#$U8-OQZN;?*60`Iu-wLbJkcE=8FpJ11n!3~k?58bANl^jX z^jIST2MbiWif~5RTxlQCy~*|1nrs;FHs^1BncQ1Bn_1X9i8H5_AE{g~j}-**j?O>g z=rwB7AM()4O2y$rr}d}P#eP{S!ADm>!8O>B!_+#SCD#&V_s~`+e zaG_?o+uWsX{~^mkYXbnJn9q|Ouk{>(3wyb>tMgBk(?FbF->)=pJ zNU8nG>T?oocvePtb}PZ9OxrdHjnqt`PM3Y_MdyG?gcOsYKEjzmx1x_Q`jA;eUKPc- zF&txE^rgO#@hL)5LH$IHK@}npyY)khxg=F@KGPL!u&{ehW6%dG`MOM z-Gy`4;ynV-(o9r4|J+-#_;{x>qWH+n7GZoKy}v%kHks_yxL6%Uw(OU$$Oe}@tIHAJ z6-Z9g4Mp*c5oWDRH)!e=#!X-|&lJES=#o+~uP!iIZ2PD#fHu!z>MW^vf}zAr3B@R2 z(ujm60%k}k%2{AUqh%Tl3^oj6;@~BT!C(ZGefk z^+a(hwt-t58KmzpZ+SI8LP(R`RaH^1LZv!iV-&&? zOIbj`6wZ4iWQHkMzVOWm7ZL^6l>mVeIm_!-pgVryd2RDuE>MzCjF0aE#MK2NeBil! zo_ju$+gx{vY^b@65oGy(R_Tnwf@vmGMhwD&C?zgUY|2NB{i`&WhM>gts`UyjW|a+H z-{2G>smKX~B>6=&1iCGW=DCv9G}?5aIX(i!4*~dH zWWVAm#K^E{QXR5j7E!AkIAT9EM^dc3x__rNj}8V3sV-3(J_dpsz+`|V+>k|YrjuJbXa~fz1U-}1`G1l(+N${ke+&8R4BY|drDcu05!m%UH0&zVM!}sstdA9 zp(q-Iv3r_`78;e8%&KpIcpww12`DDiLg2vt(!3tigtB=*PUw(&j!@I(zh*)$E=3%G zDa2&(6OnkcK1f>RfJ8*o`)q*$lfxG%l7^E)^euX&VkmQW25GD~8ld+Wc2x^}Ut+ zNY%rVf;59AU%bJZ4qb=Mm~0`mhC7%!TYKTip*kU@j3dZIn1kil(X;ST*iRku>ef47 zHwHkzyF*4tQI5h24bl}LEvgZe)c`V}+LpZ`9ws&h3)B;F70rw`yx1cOgerPU45?Q# zUBZAgY!qU&1H^PH{-KJ@ARl0|A37AfnYR zUoX?2dWJF+P}gaZnbbh6ckVn?l&iB6K0-J8`RfTni4vEAwSLo5B8*(Btxs*Ik)%IU zucWrYsZQ_^_=wJ=%bG6p$7*t+Jz+ALaN-$(uvzuuZVSdPtrg2H>fE+CMOZTF3T*QP z@w~_q>0@z|yQ{e5*WYAJz0n)ek)vkS^5eF#wYJm&3Qs(NF zgmt6P@>HMNv=OyD#fmC%0$AUWvJpReB!e3maL}k--df|%*ra!(zY+3B>mqGHE~OwU z@0AVozP1w`*>Zsz<8#HF)j#8Z2~^lDQiO)YVlX7*(zGUc_cv(fkXRDU-Yc6ZC2Ce1 zbIMb1NJ8==v2PE#VPL$3;;9Qu^HPvd*w_Fd1qlx}|5$4(D@aYYHdrQ>rc2IhEYN$k}xR`evXB`<7_}B{r-ON?#&) zLNA~h+h-c)vqq88K((lEs*{qz)=E_>sho}~5l z_?!re&{tisKRh{IiI%D|EV1lBJN6%8>$`ysNl5=5aEkJ^UR8o4i_jJkjF@aN(hUD) zq=}KZtuNAXg0cKGHQ8@^77-StmUiOI-i!~?oQO$2p&F(_q$gi$r&}86fT*boPuR~! z2iYQM2Z5f1@xt>!PYg_&MAhg?DHTifB>re5AtHe<1^Oy=FVYh`LEuR!HRdQ}45s+> zNJ?KYj!3@>l6rKi9x+q(uEwK|@tsfs)cwut7(a2H_77|kFbMNv>16$~F&!|#VzoT- zWYpWLxE;Qt#W5Y)CxW4zRnJby5B4l25|YhFK-W(mBdwe$F;y!}d*4o(Afrs1YaC@A z$)Z5|m;6OB<+e;hXlcVh8y4VVFjbH?D=r|F8!9bsVKO}Qo#Na}G;zr^ncU{KW&_Tm z(LLOqT9GnVgjC2owNI5b*p2-?ZRFF z9@uG_*Kw<5-SevRx;wAB&kB^f>44oSb<-ic+r-@wjYp>qomYLC-|AE-l$x9UmmNm_ z!`$nvNB-WE?CgArWe$txvnb_|$C5rOL5X5PFF`F*HRgNxlkoHq+`(zuJzbcc-y4LwN!6dX~Z=wE` zUM5zCmo2)gSq{R|7Qdna&BSXfVo{H#7}8`P5cg;4z7r>J@bFOV7%FC!W=iAh2> zLFELaC<=zA;kU>0vM*c|U`|{;FKNlLK*11sb1achGj7|UDYjYo(_VhHW%HnXsmiAR zI;RPO9HJEKqujCqB^9pDtrYYMZYSO2Jzzv}For1FY;LdMezFIfsJ$68qgRm^6&Z-> zT--uYEex~Gj9TFS0gw^X;_5@{^EF{7bsO<)0j|7Y!` zeyXB&tW@c%MO5R8D$Yu3sGZVTN%l5%wJ}3-LkoqBx29DSRtzm5dzpDqaNi^BJ2{6y1iZ-VE=gKn<*XZJ&7_pSri(+tB{rzS-d0(tE!N;OBc=q z)kSACa6u2#Wg7|)WW)wC6K$5fi58_Wo~}i)n5R_=qjr;dPFBmhYJ289PpkAr&(n&! zXo*^>Xu9HsG>ee6oUJbjIa{yf(>Fa8{mj~5uZy%qawKKkqZiaA8j*dLzf~)WS_z^V z?ks<6MpZ2#Qgw0uRyoF{(&BqtnlZ{cLIlRYA9w!Nmo`t>5c0*=`ih%=$}wdnvrBW@ z3-(^z+M{9FvRGFDT~&H;fF5er(L(T7v^!U5x_?%RfYGpdN|bA{EOY>(u$@yYG;|z& zd|+YOi!tZH51@WXH@dw04(w5x_mAM6K#xi~7iy16x+v-HJ#I<&kP_MAZCsDU-DD3b zfW8^H&_fEKZw3td^<&&Mv&es3(%Ix4y&qc=kKe~F7s-j}#y>$9JZcy%S{69g1&^by zEy#>r(|Hxib;E+d?Y>oJ(T*!^%pe`z8inwn4i>v*u<+{dFlTv@LY+vW<~)v6w!_R` zkc`qTC`TII0lF@^B=0^`t3&3v<^5KF3~ zcrwctK_pcXj3hA1k;w}z0+$D`+b2H7a{m#t$n zBo|G|!$kXw?F?JiS!!ym$VX&s9L1Pi(KKDL!7_n7#GPBw(mfG6x8g3m6QOe}+O{V` z=T>(Ki`?VTkBy-pUu!a&%ALOKrbmX@?L$h16>nzz+T=c#AhE3|i-)R1^1@Ip*4g3}wPUXsDsduOFtrXabgd3jfL~Ud*~mVjjaLI3 z6ilq7t~qeQCCqs~80KrSUQK zO~7FEf|{awyNZxRo3NS+JMLDsg@k79p#?&Q*KB2%QdAPY4DzT4#43dSBi21F9jn;( zj|iJA_Biz1_RQ)jmZA3^S*yic9MRe>!n7y`&=-3^RH8QV&-HeTP{sH8>6na4*i}%B zwm^!1L1hXL4abOw5hg7UXXK8Mfyz#UYFvG!XcK zND*wR3A24%*?^yuWonR709egK24zt1hYg!_SAvb)l!k*W@H^(18rlaN+m!3DAz`1x zhVg)rq>NMd95!sL(taungatM%R38IubToLn1U9~NDZ-|pxjxuvd(u&1W3ln!@UVWc zD7^iB)nn7+%29G9B~Ea=9|qhCKHh$3@nT1;L)pv{@lvrhKWeMoTEu6BjCPUqgbXZI zh#_t+)Tl<+bC_;z$nA5FtG1A<$}3E!H3WXg3=^?6Ys=&RKCTFKE00_c=Ac%@M8qnX zCK0t!YAwIbQz;QR9uh7ZM^M!G2MASiLm+1viWaoVxMY}6BI74)#}_9rZ>*8NPeFXF zO)|ADd^%|PdK|TU?h$RYg_aL?L-9;A@`@lmb;34rh&r`caeIRi}B?hGC~` zitLC35B61*O19|Ld$r0`r6CTV&$9neBSGL*^CMMGb%X~UsYssIG;-qx)DDydg9#t$ zV=LALhbW{_1Tc0I3EgN&c(R0-1gy}08J;8GSxuYLt zSY{HnAXr2~(2p?*m9Yy>S_(|kU@Hu)GQ~#LJYfH}$Qo+w%N?<(wfk|7VVOxBb89P} zV|c$>Tk#yjqqJsxrwlib*@UmGc#h%yYOQ2m920Yu;?ZNS1@8%Yrt!7B-d&q=h z%(rgme(|1=fQnlaWUOTXGF6yUpiTCc@}r>6fGXwuD3QG@Aem5A+nG${9YTm)8$u|l zqrEIC1D+*iz_X+b@`acsMI7xNo}fV;LQG2#jJHu)hs9{b_Ovod);-jnMc5d7F&MkdiAR{ zJly6G1&(RCe0Z1xVn*7lc_LVH@V01}qpNXsQND`Q6dX^0gwbgg7jYU%ozhO44Qtwl zGj?ycRcSz{%Ot}?99=S^qf2y%4yjhPW1F<`(x36HX_66nrjvJcXHks=Ir6Hyg>BL1 zG@Ft3u&fEwA=T0II>@C1->`ojPf>qe2o zDKe5nTV){t6`kHRJk5S1D8xMSW2!vCk@BPZq4Gi)bHK}9hQ7U)5fIEXoH1Vz`(3Ho z2p%+T-!!n8tW}Scb_O}aESnD;!#5)M4u87r&@jfpB$_?hyxV`GJzKa-m-+Sbrw`s;VaIsKpQp1m(2q5*f_gYTB%GY;(!5~LuYAi z(RulwfU7=N%7x{7xr3ayx;<~1p0okj+(cLnIx`D2#=x>t%VZ#H!uJ8w-M~uw7?)48 zGcNb+2pD!?q06$sxM~J8Mq$`3+BIL0#x1{~ zNevS&4jH5I;6joB66mctgBBLMv2YOAc0IMaiA{u53P;`G#^a(HFn|hlxS<$=cPz9h zm!}?3?6ah?2zz}TyzM;_B+OWI*$V*dJSXZ|@9bsk57qnnLpq%T-a;Zi&jhH0f{}rB zK(O|y7nDRlqzV!!4KCIqlXbBUzp!U4FIu7d&%k^+wlve0SSaIKnupjhQ|m1oIvC*N z2ZSa*yv5@Za*l)1x-ftCSp%x!T@U?N9wqM@;PrWL%-R%y9q!!G_3ma--q_eR|~rzJLao2grsR?>5Fe6|6zQqyHV6bu+*76UYe~`@|jAn2s&z3?Wx> zq2Qv?Pd`0HRMY>DN_V@533r-ykqK-P&bFgxP`j24l0&qSHFfYu9qk?hK)#uu2$fva zI+TCP-qq1FQitCBSM-E+k_p8(dk3;14iQB$R&F@U8=fezns&AC?e~7-t?&5fTiH{> zp&($8G6CW^@4UUD^ha0Pfi|&K%!K}Cjl-Cp1z^O6h#dz)7vNu5Z+Eh(HqstmYRWr1 zJ3lGyhkbtvI56Pw^X7_;U10cOzhz)mghdYs)@y(Og7kn;Lq6MA^>Mg@K8^(SFRKq5 zi#}xB5%7IQbqmLks4+i=JireU^E?x;u0ptr#MB zim5?<++#C~y@~Z@@#=W-ZJg@CHVVafzzH2Usyh^|Z72tZqjZ8qa+pPWE<`~=B2NC| zVd>`qNrZuRE~fUU@x8A{ta!;1tiS|f1fPYqSR)K@Nh5~Pd>q^gLmt2-*!iDON`Jpx zbFle`S282|e0fIlO#-@4W`w=ri*^b!KJykju61_W*e|g;>&>3-0Br#L=Qz?sh_`fn za8{cLs;Z^V6Qn5?WRq!An@pR#T&Qa-=N8xk$PYxvr#hHNzJeP+jor#XJr=t%E{kxaen z4&Tz{ooqyJwX>1pxxY0Kk(8byRW1yyyq^D|5r;+?hAFl}`Ya}6+|h~=?OO(|a8|8% zLN#@Q`VRwILAMVCt$5wgDj=2l_E$hEsxC&VJ`PdFlKY8NU|r-K;VymUK&5h1j!h)Q z2hU9hmG2@sJ3-v@$A07kI}yi-f4h27BNW-yi<+Uxu3pp%MRxU~!BAvZFB%F(cJ-n( z6xr2_+M&pP4MUWLGa53q^MIqE(^Du3oe{6xr2_)`TLv zdePcYWLGa*7mDoaMJI(KyL!?3P-IsxIyn^C)r(FEMRxU~4WY=cUbHb3+0~0q4MleK zqQ`_HyL!=Sp~$XYl!YR@deL|&va1($Ly=v*=&_;5u3mI{D6;FbWRF+Vf2-Hg1rJsH z)W6N-jlxe`KRp32D^XPn$F|?`If;LhK-%B$tm23M+BLcSY+P5;$r|~oJI_dxryAOB zVr2~eY)SQn#stZ0aj*DI0ERpg;kPY=?i7z}z5%AHqzK&>_zyeO*6@Z^!;|U;qj4@6 z7(&xD)y`frJLsd;os)f)11wP*%i#psuA(A6#$(tg?V*OQ7aBjpwgkGEP%+GXB0vDe7` z+~5X>Z~BzAJ`q}n|N8f5Bal6>upmQ1r%WzPcqGRypJbz5IX21 zt+IwZpxGYmJjGmIN*yc{fMfB_V@T}lXJ|jBZKAcq71<#f`8LpUm2<-mtW^XGj1e~z z&<#^0MhSLSgliPz0K5OV)OoMN0?~;3ZTpL_WCJuTf&tmBP+wjLLv*FuThVX9e>W zOq49EQ^{T(*_9GNPo88sG6M6w(jC+@IbPB<#>ce4@K&4U`CA3YmL;@ zUSsPD*MRvqrR&Q*x_PHeO5JTL?$#?YvKP~5aYRMD%e(~KfHU4j-$bSGS5)v}WKBLO zS659k6lRh&Ic`x_s0g1mS`mJ6#v))?a+IQ&Uim0R zSez_vyJ#Oa&mrB6k-=ws+7CjUE4P>y(QT{RBnJ$fyhxptzrMzhHhE|Y zOLg+{cv_?U^@CWf_#i9|Qp}6=`avEasbp0#3H^6KTjyimBN=i!Vzu)#bq0cAJ?~lZ zRfa&2?9iRuYJRub*J`MF2)@hZz^?rKJ^7l;pd{$ORnYBZUYS$b*~$5sfxHZaP6hb@ z+WBg;p$t2)d;36xq0uBzEQZ*S5Vs;5jlV*ltjI?1MU2ggLL`qG zWM_ zYypS^eB^J?@BtMq^d21wk38F#=P!PBwI;W;osUd34$7}HXK6SdJCPvLMEznaT@_iB zV_ByVgChj}JEL&JRc5>C;!7+Nu7`-5LEQE`km)EASj{#hZmZ@yRodCI1Gyf>El1o` zqPP`av(-tj@~2M?ZgdifS5(L=?Nprj3T#3P?~_ti@Jphr_)?7+EBy4c)k>q#5PB(s z1#A!#N7+FBwjX=n>G;R;w{n%FXN=PEv>HvNX8xn^d+Vypm^_&va>EUY+6 zqUY!DCe7~vvl&8%%@1KIf~7d{{{f9E>0D_xNS*q4qYB)ti*Z0e5x45%9VJ|?i*b~2 z)i_xRR|AhM_=PR*m2eeuW*{UdzhsZT%&Hd(pWUJCf|ia4MUr^X38FLuL1z^B8lQ&d zZbB)lBF_XE718SHr>mBxCLR%2k<}Z)2*?eOW$V=Po0w~mfVunR-(nd?pmo6*dkh`% zRnSKmWZq#RUKuepG{fS~QxH`F=wcNhfEzpkw_SdBNa5$|88RheaQwg`B-Sdqt%6jg zGm4FrkhliqK#3j_+nV}AfW!r?#eg8)B>mE<4f4jDy4d!tinte`YSgDn{#uUm&>qE0 zED%CauNmxp1{VL#DjE8!STdNMCqgpna-+OQEdeDHUJnObEC+;lK{FrAR{Dc4Ix1e3Nkz(Awo?DQ{ z)^^mXx?~i8SvX)qyhO@qJ**0P35y?;py3vEq~+9QP821eK%vYvg*Q#ez$NVf*g~I$ z$#h5@Ok6~(Xo)L`n!9W)G=;llXSS;Nfd;a=_<<&-9Es``XEjMMXC3j&4$uW&Af0%@ z2-4k3*ELym2g*g&tqYlO4T!>UDME-@Qx_Sewh&mRZbk!D8$&Su za>@$T#4)Jwf8Ya)+X;`vBH|<14ab*gNlmlEln9GAUn+TnK)iSue*i`F2eYR!-mVb` z%vcCjg+Wy9Nzw!=LV(NK0DqRl)YQ80bBv!QOj^y)5)!TD zC-27gG)TG@n+iCvw!mThWue*C1%)h!4eJVQ5X1qiKm{^54r~Soh?Eeo!e&5(INabW z)ikgtTOu6}QU&%+Ozp`KH-X0|qXZvK%tf)6ojfvBt;vcRz0an4o`4;R za3#L~qTxEx!Y31KOgWsTO+fL{uVOu;Y_G?D%9wSEvOv zswNj;BM`~r&=}!7v=rvbu#S~aO>Gauz!60haOq(fh_Z?@E)gRP>o9hNGzD4+W!6!~ z<)rY9F~&ht>%-60{G^rG@>+hD(Do#L@@{Mo>8q~ArUKTTRNzo#=5aYTe;GA@g(%S*cBtxwMw44gH&j&-qO&WaPW=#<)`{;ZzlfYP7 z!gUOD7 zy#mby9SMjw&o}vSO^yYxOix@F%wts{YdeKJM$m?K)@D&)2|O-9Y}vej8e1lp4eT|5 z?N+U+k4y$lb;Y!uSGbsl{RglIBEJ-VBWgKcnw`NOEP$NhH)gHY#}oJwC9Y`n+FaaT zGct=x3U?AJDCR<)fDZW;24*t~Sqe(gAypIn+mvZyi+Y*_%D6 zm4Qg_V%1#`sy9u+{u5&DC0d z@@{NThp^JM*i<2CBg;np51?L-(e>1>o}e|BC;3Xq4a}_vZ*e+P%U#-npul%f$`DYl zcK&ZYa6rISvENuhEu#!=QpZ<_w@%mRio4k>x8UO{=1z~Z)`oE{tq}B>V=8YbW)rEz zA->Bwmo5_RJ*w zCl>+>!RFlUEyS5aKQV8My!bffyDg8?YV|D{*50BGyr|K(9&pRkl*?D1BMC0qVH%TE zR(a=icN%wzhGj9VzyDc_5x~>QLe0-n<4m0YsN>KT9j&E*QK_zoM zahNI0kKSx#HHQqo7CC?|(H|9%`*`qS^eiRr?7EbkhNzi^G0)wJKlTEfBX zahk|YYwEkqu?Hd_d4JORH};!N_v_pgf6sFs@x1T(iOFn@jmm{*))oG4HkV+5(%6PV=3mANw=CQge@O z?;F(7spx3+S`yJ?f>v0P&nx3*lOX(H-x4LLleQXwc0mt*loLWKcIqZ{B)_3;t)~WD z73Rl*(Ey#qE42mMH7g+7iMnBvIjCXLLFs++I7$t;(C*SWk*OxqLhqzRWP_T>7D@&3 zLwce%@3%9rt*N{s8|Ka41mNR2ulj5VZ}_|_@v8EzwHU;^1ToY*oSEM7btR{O!b zWfOhm-{199-$(FC0_?QNO-C`vI98>5`@oM%#E#fV9~#;$6F_ba=0A6r&AiV&rFr%eu&k~w@YnI zJMVzI@MU1ZzSjK9$@rMe;FOE)z8#Yp+~yZ}tPA}e9v=%{gb2+?uivZ?$i_x)s<(!d zO0C)+97>xbqn)u;>rPsK@~Mx>p7i8=>vvpo>33fCoabKty)XJ7S6;P!{=mT(A3A*F z4=n7z;p&OG@B982Uh(W5lT+7Rd)-sdf7%64|Mq8W`L+wE&)fFA=YQ7=zI)g1J$q-) zeah_h`@U!AGcUUMS*M+{VdLsGYsb5fJ^gW;&N}DpCp__tZ~d0XZ$5LNA?;^V^<3?L zKa8tqto@HLuntPN_IzNg!;U)LRWBNTS*86_p0s!}n5DA+toSfaoU!&-^h6|@4!^R} zeg(f)WrHsozA66?A^hL#sU#AlEy0*xG<+!kPd)iNp0vkX?L+!xOP@tvjkUj|VsGv+ zZlSUE7oiJna7aC%hvuZfAUPBoq(Y*1p!5rp4Ej^YwfdjZB17A(hME@*zodf4Y^?pa zv~6N#vwZ>yIYj9_Dg_L_&wj`RBGOOIkMRC@Q(bIzy;Bzr&*9G+Ykz^4QaFo;4W+W4 zVBZ9Y8H;?g;>Q#M0SCk1{sTtef6XgV4>&ARZ-1VWr2-Uob~qp5@#h%%DA&(YZ7IjR zDev&?GdwFe=Z)&A@x#OU7X{8h(F*ifpSnlz%}V{tI;m>B#TD(eIC2?GJnmeoDXT(+55( z)>`NJS{{Ft>gd#4qKr$fk*qwNujAQWdIqz-O%X-gvXtV#R+D#Hlg5wpllc7+>h;+2 zJ0n|e-{?(uNBbMUG5pteY%iC|Dd8jQ&FI!_f#+) zDEm{&Sg~?%e2`} zV!EwDI1P{9$D=0H^j@w`PR;xu^*{y4QjzEHSMq;W(H{Y&r4+?3mgOkQJrMmAMH~m? z{F>UjgXW1gLPxN#KvMsr;y+aJ@-(G6Wfk*xso^`&#S?zFlK+$5yPZ-aE6ec^$O>l# zgoS$I`YXC7*`H?e_0$(I*<~kfsi#zpuP&x_d`<6mt#Je_!p_CKeKK#~#@lY{$zz3r zDSIAL&MULy>$oG!5O*gPck9cI+2*tHlX>xOUew9ui2m^nUKu52BPHx;8b6gQ>xJWw z;mVrec*%NQ)1L9k(Xqs5C);eZ&i}6DpA;y5kIsqb_%oFG>xbV^Y5x?Z8$B%2PLq*R z1n+BQCo%cA=pn3v0JeSCca@Z+ttlPIGR7gUY0R(9ULe~4Z7S31&hZTDZ{>HW?A`h% z#sZBp7;Z2-6F5w> z%7lvEr`8!&SoJnyC@o|&#CjU|RnNPSfBfS~XU<<0Fv_p4kFSynhw>cOOO1?)J3Cpg zpiOD$eyeVOK;8Tex)~s?viGa(*S*XjywILsIwNnaT}p3nb8kA96u z8|_hh9}RSem;;QeAtWVw`YAjCYfsh%?mm@o;FVwDm8D#LD&NSnU*=iC)wj1N0#~2R zKdX=Z5>L|@hJ<4Lrb_-fmET%ozn@pZFRJ43R9i77Qh_({ryP`07)TTOW2pWvs$-%l zTnWB@rNR>?^3!Z>yp0xmkTJUz<8eBFEYIG`GeM>yBl4Q|6iXUs zCz)i-hcx21@Yt0X?fH0Bg+nkYeY5&c)IM&Cn-7eq`Jby$#Nud9I**<74Pz_(ci^R4 zFWmZcaK3%l{d6k4k)L4u`fTJ`!;|eDsjVhur}^v^n@x+^ zyE=ayFNrgZFngb^N>$+grxF`6eFzxb>x*wLusdyyCE7JTMAwHkk@0F|Qq-F92lX$U-QV#k`{YZYZx; z=TD)n|3zEP;a&N8-2WK&YqQZekFU*GVm`CB{+97IQtay8mea%9jJ=(da`jT9GRLK7 z=ig2fKSC3-PBpd98{VBigR=kGhe&Po4+>wSF&MuzL_$YC4n*3WzejESFm3ekXlH)A z3SUj(GHA3b|Dc}!kUm>r(MhcQ?OI$th=%ouhW$LFvP*`x)M;m>DBWer@KLq=N?JB# zSB|k({xOwFucvg0WI$TTQv@;25+OrHv`H$OVE7CDewj7aFBmj?$kqoW82;lg3c&!g zT3#?f_4g$hX7j&PFJ<0DxiFi5T17AMB8EpYgezgUl>H!O&gS!{^79Bk9epkuzC8a{ zN^Sy1CgZ@f=d_<~kG&upx_J2c`ID)G@;Sut;X~*03yodQx$A^eRf>vt^qp^id>@d-@8a?4ZiGhM${nrf>UY5V#`$M1C%q#Sw`9U0SLpQcMbF z=NI$?4NUPkxqK^giY6Fq&x+-bwXesK$z`9io{gby*{{6{KNxH8@hZC&p)dyZ*kz~E zq>Z(wQ$iEQ+SmDe*D7J%So@mPy*N{8KE}^UzwB@;ZF`#kt-d(nrB|m!obmIj)J&o8 z_sjRCX4_opm;d3H7o~0>eQ&s4;l(dR{iT8LNzIh`ZvXWHzkHWpo}cDsfjloYY}l6O zr|`z*etB-1pUSW2q^52>+kah_=ATiwzSDnRn&y9|pO>I?b9q+yd9nYzC^d=x%ryTt z9)5@a+Ul3wFI!SqfS%z$zdg-Qr|P$*Cde=JUr$f-3n;w6e?2WV+BrYXC5)cxm-EtG zqUtFaCS1<-%aham41PT+H8MCSH459D=1-#ViGF#47oP3E&hlSp`U~Ic1a?Mh$i6Af zg-DP0uYZeQ9_N?S{qk5TRn+OG`Jd_vg&Kp;Qs>8~rTHJI{4uF((5I%ZHE&E^2i}lk zL-72R)b+)aQ&%w8rywZhCk4%8UFvGW+BCmQPU;o` z2yUEdB+X5|BR%22>v=nM>oHC9uj=SvaAji~VTM-d!w$ z))v@c6_yxqa8zrooybVRKfJZP*9vvXqC%Vbf$Os>&vCTlpRVTTC^X*pzYef}(l+~Q zRj#}VYw@ZW3w`JnEbX&|^=e-gyK-wn1iJ0OvWC^BC!^2`88N;*KrPkiMW{a$|FwiTpq zO`Vj>$o3HUB9NBzd=Us$R#Vs0;uXb_)s&K^(B2dL-@s6xMAt)ffE4W8!J4lT_!@^u z7M|X1+Pe*DxH`g~utuQuBYN-^jO=L7_rwnlNVmroh$4G@jH~SNRlPO=0G-Bek=j=a z`!&0(Wz2vwAeYvHGwx6;PN&{#in5)ZU#$0h)Y+I@G@W44B-Z3oIA|#>STVj7X6iqy zWI^pW{8BKJ#jB!F7HWSju4+}Iy6^9>4l0>xxoQMf!ZmsdKKqiiDzjD!{u;$7amcz9 z{ActAzpmPIwJ|4avYM&*Clxgu5s>LMEvBEOo3dW?Lw9`P)!C2V78x^*&S)hP?JGQI| z3M|t`Zq8NB3JyAlx=bnjG7;*x$|X9;N|h@4IldVmB)q)h)ACCozTB*=`rq+DWq=m- zA#>+A|7``py|n?)xDg^-v?-<+9TMF-#}FYRzKN#{>lPQv8^EUWUVA0l1Kjz?Yx1QD z^3+vL0_C`vGgVt%8n+a9`8GLNIoC`cD_i5Y%oimIJSYilj*bLJk+6bhC8+v#N~6gXXXhARApInRyQCD(V-G(zj8XCl5oA8oq<^^TdtS_92`RG^8x(PFHdsM+{;49nG?&`YJ zUe@%VYKzk4JOrexfHX~Sw;#P;8eR{F=z=>iOH}FeO0o?im9q>@(cS0v`Txv*SydRFYya2p!(7k)_Gv^ zE9w?8E}1TLs!JEu4gA7a>g14k>ViydPnX$bMqL?`7-Z#CT_eE2y01QEiU8HfQ3q@> z1sH6qW;j}E{+KlsGdP7Al%c^0lKg4!?7WeP)BeixbwtoIF?5X6Xti6u1sQrWjHVJl zv{<_Kdg+5g?6w%KOkJ*&{I??ZJF2yY+(z-J8hL?;@2)8Hx-Ur@0W_4{C#ZN06B9MA z4%OG?VS^r5_OK~!8AQlz*B5)(EaN(^vZ%(9JWyn5IW6oWg2PE~Y8({k9ya+PEJ4B% zkJY6=LUyCnuGGDO4%x}B3@TpqzL7Gl=Y6Z=ee(iS@w7o5?^{b+ek*AChQ`JLgwJ&B z4Jlg+s)t7c&m@~#CLk(z-T+&2L%_Xw0alZ?v2=SqX*a2zq z1jbZsfU;<_Rg_^8#+^Fa8b(vS4OO;RD7Jj`E!8qt=vr(F&Y|9{R!D>O%a`y~w%mp) z^3#TTy)D%OVs}Wpd{_XZb$)3(vbIyPb&X4yYy&$sD-AgGtAhR-Stpiu3q;MDOu5n@ zpa}auDy&CUG8Yg_{hHANfDA)k3@)+r4S|Kax_E$-CImnaQzm#9?*idb%DBX>ga+s_ z$^dlSPZ;Jb0*e&QY9+QDW-2xsCMmWTa3D4n0L@m`&IGzGu zB`;YDW~G5CfDyo~R4|LdY}RW8O8~REI3jFt`>Cl28MXqbl?Ziw$C{^z?W_376u~eI zUx)Zf*W!-10OoZCnvlLJ)Eq4Kb*?G)b*?VJ4625D0!4QfvGM&Ep6qPLSb%82GF7HyCmOM%<$W0Er6# zEWl?lywuK;34FtzQH=;Ib%-+NA`aa4U$!Y@LLz^L z_VBZ*Yq2SEH>iiB1}oixgQ3?wW=vR7C?hp~xa$9FzCn!0&k9VAsExOxLq~CiD1w${vMpx6!fsVpb?9PvbnctKD!gf0S-XGjl-$I zWjQ2hM>@VfQu(Z68@k_hDT!sT*yce%E(?H?hxkT&d6OXa9r4D>=95I z&4X3YykyIgQ3w37p~tZr{@@SN_~RGLbk@Ta(T77K3J#+)0jq>RLNS_(Xa|u9l(A(Y zTL}Tj_{qDmJ^9s{m57P~PGbfB^x)JfU@}^Of24rUZ~vQ>^hrt?IZ ztWA0a{;)bD2DZww87bMwQbHUkW_7Tb^PytG(qi`8#dL~}0E?zXGalq=oPH-+mJ4T*YH7J}7O9rDnEBADmN=F*%>-`-h-37GyW>(VrFU~S zj@&Jqms2ePrhy&GDWI>(bsgS}%^G64Ast?M75bG+ba<07#$ZGD0-*bp%K+#;DTT>9FHU}(e;g~}r3G60&T@X&wE<8ZgOAktPrkUiy+TneF{ z5rZk0C{Bxsp$0JkWP>i+2(NTa6{?d97RNvUt?BLk$|aTUEun$fD|j2FO;9f5@Pl$0 z#~YN(INn9dWv!s_R>5!97F=dIHrAZrHAtmKfz(G+%%|^xs3a_Of z8RXonD*LwUhnsU|GW{jJOn+5$D7=7L*RK&7GhX!%lkZR4qr0ecx)@(F?nCMxm=VF@ z2u*Y^5sM1MTZ~CnoJkS8;I^{nw5b`D*oIBH$s54i6j!nbT2ig@t9XDQvhkSo1lInw*zGUw5dm2Fl@%t9)N;YEm*{CkctU@!3 z^8HmUqKx>MH8q);Xd)wE6xb#jFwbtSR#Su}r5vd%i!AC(0B~$dmh40%+6Df`T+(1>evd^~^Qq zrASCb@QH>rsDSLjoFp_f+yZF$d7FYAO95=WkG@-}^~S-GfO^b!4+;XNSyDg|*COjw zQz4}A2?g2KI2Vb-tO?K7QN~4R?e##hMFx_&t{^w*U6IF_>q=Y+Jc-H|$@kP$RK5f; z8jCICCsYHGXL@iz(H^PaL=Lej^YtfLr%3*WYb5m0yolCUmpz7?h2l0=BNWBkm_U0hwt3DW3%58Q}4z}w>Fv&42{3C7w7Q-yG#rF-vn6CB6I zLjIrpOkj;!9R@RyR~NbvlafxLn1Qn4HJGK`X|?%oouv|`-PLc)am=?sF`ZT+MnOt# zoC+BW43@o@kd-b~>2p?74cFDc5**rDgR#LZfV&NG;4*UZ+kmz3;BAbaLf7%Hh#~fY>imU}%W7d3{=i%6y#u(|3McGCK9rL^} zH9I@Q)4ka>(+8#|uiAcaerhh;F|&7Wes*EU{LE}JJFzF*GjTAR*}MB-wtb4KJ7%XQ z=B6f-gEI@+j)}eD$@C;Qd}H6)yQlU~?at=-?(~6#3VUbf)#CoC*?IME{<^7bZekCA z4({1Lvpdo6nZ4eRi5>IPv=Uz8Ydh#Jy_}q$rMtTi(({S!yQkF5HPd@1vt3gMlRXP_ z^V#IozL~jceP>orcTMe07G`&IHtwjzQ}dh7HrKfdCzTz}~M4qUW@k4(Pf*M9x(VH$W<{ju-;p(Ow1KTOiQ zDmTnd&rccb=cZo_(C4y+y?}l9^xXXP4g=ZLo_+HNv%LZ&PX*(NY(Etyvxyx$W)}9& z`!gW5-KHj)-s_KjD&~N5vTt@~a$yJ9F*(DmtBva>_D^NZsV0KECGefd49on5Cs_(7Ii@21&nAGdq=q|nX2Z&_iQT|*@?dt|^tIPbfjvNIa%vV*IhZ~FqARi+rsuEA=H@4M89{+db3I5g zi1)rXN&luYF+Z;<5Gu}1%|jvwppM-$H}Ju^soDL|$2m{Vc3d|x3n+oGCW;S(odWaH zi4u9nnTj;Cdt!PI&D}6DJE{4fp9Y};Dvd&~8ipnbN}tR&P0VMzq00H}oTof4o4H0z zz{y|^HZTj$Oz#s*;Jy7b^V55;JtK(}!)G<-YZmrS_C~2bUc>Z49{Df5FG+v4%J{CD zSeUtG2xfajd(t^sq?fsj2lh}!2Mz+I54>MUVN7yvVc)))Sw^?8 zclY!j=(r%sxd@#C1E&r^(G7jAxmUrCfbN4m$`LF&IL0Nfz{v0Ea(7h5jSlAo739B^e zwPRWg1m-}2Q>=?DBW8)BAZaIiz+W`3k~k{yivrLRPki%WF~T{z`JaE5q`y-!hEDr8 z05u!Je5Rfoh*ePFRwDLpVjwAfVs2skyf{zhaJEU9oR%h_AqB}Rn$Px4&7Qp-jbT@| zePPG0sd>j1P3aO&AEkx*AIOBcTi82&{epxB^8(sKtx5jw4=3pdE6<&pzhP#UhIw|w z^dxv7&U7@u8wX5c=Y`BYf-ib&;462wfM>ymjzX)T8#pz^Xb%RuPZ;d1Q@t_$SOZ>r z&^VOZXHc*FNW$4z5fx0N857t$HGkC&QxMvGBHZumek9|hz+s0qm>d9&riGwEcrOCC zCRqY$cIrUEHD;%-g)YZ)HL98+Rq?t;@h~$G(LKKUg>8Lh;npU#Bq! zNxftDj8x8E2Zs80H>yj_IpV5CuC^Q?jW8JEo=(qk+c< z=`QZV^cD2&EMpGcc>0=Y!{pC@G)WH>lh+%L35lo+8`^F^n4PovafvIk(l3Nwv48j7 z4WJ;HA3&!o3ExkBEJ=S#d=|_?|6Z!rWPBFwIhma@`sls8XX4tu)AI|HDAy33aoYe2 z>pFzHduk4NTu0ka`u_8tRHA}wrf0>L7Y+*dB3O4U%!+r=i5?b$TwnWmlD@H0K#Yg3 zZpGIQq8kN)$c)ih(_m&Miypgn8aP-at}>tPmlR9sgyC&MdY_e@dq&aOzAnD@6G^%c zGh|_6_f;kv0q5gQ?Ccdjqsuxe8nt2V7_%&KZp|eaQW6Oh`?0pn5OL}(&=tLA3MRW_ z9>^T|WRl(vx(Bg*6(n@kHLzq*&SpSU)i(>?i+#vPFn<}2Amvss3H!4t*lk2E5yGAs z*!w|YkmI>&np4;Ap1yV(gQ?&kO!s^SdpH{R*bYr&RrDCh?Vn20msZ3F?t2UYh)XHe zI~dVo5s_{`2L)m`w0;213Jq^A>XrdW2pE(cfO^NLlk^n`N5qI3D8e2iV$^Fhm#&$b zif{^Fbe=H>?PT*dXQBt%y$+_2Eo5S{e|kkpbJlD?dKYdxuA7=%kTvREq&M&X%Ori3 zD}DW@gozE)OoRPAi)3BQB^gEEpaq+`_>rXmjI+Hmt4s1b|0+pujQlggCBoc!Xa+?( zrUgS~spv`E`t0wVxbgO>DLD$vB$vDo2niN*w*&E@Df;l;N&3T46P6Fa+y}1WL;Yg# zt^&k)(s$s(PKvMygl%XzymU-681)ME6Ua)R-#)Qh-J(yQ{!Eg-ys`idn`+J+qG!u0 zv{{~pQ5r&F67ymA!Pxg>2RZ-2?TwJ&b|ZW!3- zlk|5>ti9CqB2>;c?L!eTGdtTejgM)5$8~2UCTfG50HE%eg405+Qq?u(5|45&fe`Md zxgin#2e=f%ya$AU6vso>B=PubY13ujGe0k1j6OD+Ahj)d z?`LAIWh$GU+Jhq^DAAGF&T_cgOV*u86URf#5bQlk`qPyq2z=i>5J>`zU0X5+EQMp5 z*_BTa+Z4J-O@j$e%+4jdXRgI{Wg6RAWr;Jh1I8aa-qX3tGM8!j#@{CCl`E)w!8PKD zvv+3i*)N`&MQFLptdE+5COQvIiwmL?L~Dsp-1WsIy?Ckq5#H&qT_PSy%@PV2%TMw* zehDwx9P_n%Y97wFNM~QJQ|P3n?ih+8F89vKp}g2!={LcX{3Tyb(wza_kH!y|`|fhU zu&*!Uv_c-Ctpckr^TFvQ7;{vXxAM39N8VS@v;)n}-(eZt51v#=I!#|t+XG@89m0qm zu@rru&wudmlXU6C%ZH8Z~Mm8iy33MAB$& z&cL0KlZz&5Ct8SU#E?R41S=I$un|+nPAe@ef+@s+B8U*h#ETmBH-C0#Hk;dXFLpP# zH*aQV-n{p{?@eBu3|wwJQ>k(Qjd{|`FjA{kweK)II0HYQm#8;S-v|^(9n!ahWkLz0 zT>B!?B`2l9!FNw}jO`byS|Zjf!*`nySQ{*dGn#DXA7i-{_}M5< z?5DEtwOUvu>OI4}h&enf-45DhtKtP9ytagZw-L}a|Cgl>+%OzzE}I2Y{Y|1$&;tjB zy?6Sj{rgzgMS~8tb;M73lECS|=9_gsK-*7Ce<#GO=b=R1SdgfHwKa7+P?(70KX)Q> zUj<~oZO6`CJ-bUMZT;lo)23eX$XQGr#g!?uoMM;4N!?uJ3R;oGUdXZ~G!=i7kDLy9 zJXyA25HHIBe*na2?VlI~BakcwM5lx6}xwxC$S)SQF+Zm*mB!3ZLD~q0Mza{CkNdi4Lu%Np6nCu1nKx%WGOcO>fiABl!C^T|DW!72H7FTw3OMk=>(Hd|Om-4ff$sd{>4U9=}}Ypk+ai~;His8La$>Ac@{ZUC5)jy_}v=x8SJfNGWl znf=StC;eJFdPdWeFs59(0D9CMHSi0mOGs62W(CyAi1q-0To&aw2U^k>pI5>W8oB0x zajAxz5R@M65K?;jR)eTpG!F-Z#LhVv@feX|mV{e9CS5M-9rCuvLehD(*jngBppoEd zvI**=c89$ZvmHdr20L9Ct9j~Rnr<7-dnC6y>b-by|FuZ_tCxMBmirHIStI%>S_7;>U20 Date: Thu, 30 Jan 2020 21:58:35 -0500 Subject: [PATCH 1010/1048] fix block_signing_authority binary_extension bug #435 --- .../include/eosio.system/eosio.system.hpp | 63 ++++++++++- contracts/eosio.system/src/voting.cpp | 7 +- tests/eosio.system_tests.cpp | 104 +++++++++++++++++- 3 files changed, 161 insertions(+), 13 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index fb7e8cdb..6a600a80 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -179,6 +179,10 @@ namespace eosiosystem { EOSLIB_SERIALIZE( eosio_global_state4, (continuous_rate)(inflation_pay_factor)(votepay_factor) ) }; + inline eosio::block_signing_authority convert_to_block_signing_authority( const eosio::public_key& producer_key ) { + return eosio::block_signing_authority_v0{ .threshold = 1, .keys = {{producer_key, 1}} }; + } + // Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { name owner; @@ -196,9 +200,56 @@ namespace eosiosystem { bool active()const { return is_active; } void deactivate() { producer_key = public_key(); producer_authority.reset(); is_active = false; } - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( producer_info, (owner)(total_votes)(producer_key)(is_active)(url) - (unpaid_blocks)(last_claim_time)(location)(producer_authority) ) + eosio::block_signing_authority get_producer_authority()const { + if( producer_authority.has_value() ) { + bool zero_threshold = std::visit( [](auto&& auth ) -> bool { + return (auth.threshold == 0); + }, *producer_authority ); + // zero_threshold could be true despite the validation done in regproducer2 because the v1.9.0 eosio.system + // contract has a bug which may have modified the producer table such that the producer_authority field + // contains a default constructed eosio::block_signing_authority (which has a 0 threshold and so is invalid). + if( !zero_threshold ) return *producer_authority; + } + return convert_to_block_signing_authority( producer_key ); + } + + // The unregprod and claimrewards actions modify unrelated fields of the producers table and under the default + // serialization behavior they would increase the size of the serialized table if the producer_authority field + // was not already present. This is acceptable (though not necessarily desired) because those two actions require + // the authority of the producer who pays for the table rows. + // However, the rmvproducer action and the onblock transaction would also modify the producer table in a similar + // way and increasing its serialized size is not acceptable in that context. + // So, a custom serialization is defined to handle the binary_extension producer_authority + // field in the desired way. (Note: v1.9.0 did not have this custom serialization behavior.) + + template + friend DataStream& operator << ( DataStream& ds, const producer_info& t ) { + ds << t.owner + << t.total_votes + << t.producer_key + << t.is_active + << t.url + << t.unpaid_blocks + << t.last_claim_time + << t.location; + + if( !t.producer_authority.has_value() ) return ds; + + return ds << t.producer_authority; + } + + template + friend DataStream& operator >> ( DataStream& ds, producer_info& t ) { + return ds >> t.owner + >> t.total_votes + >> t.producer_key + >> t.is_active + >> t.url + >> t.unpaid_blocks + >> t.last_claim_time + >> t.location + >> t.producer_authority; + } }; // Defines new producer info structure to be stored in new producer info table, added after version 1.3.0 @@ -343,8 +394,8 @@ namespace eosiosystem { // - `version` defaulted to zero, // - `last_dist_time` the last time proceeds from renting, ram fees, and name bids were added to the rex pool, // - `pending_bucket_time` timestamp of the pending 12-hour return bucket, - // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, - // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, + // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, + // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool, // - `proceeds` the maximum amount of proceeds that can be added to the rex pool at any given time struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { @@ -368,7 +419,7 @@ namespace eosiosystem { // `rex_return_buckets` structure underlying the rex return buckets table. A rex return buckets table is defined by: // - `version` defaulted to zero, - // - `return_buckets` buckets of proceeds accumulated in 12-hour intervals + // - `return_buckets` buckets of proceeds accumulated in 12-hour intervals struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_buckets { uint8_t version = 0; std::map return_buckets; diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp index a42239db..53bb2987 100644 --- a/contracts/eosio.system/src/voting.cpp +++ b/contracts/eosio.system/src/voting.cpp @@ -24,10 +24,6 @@ namespace eosiosystem { using eosio::microseconds; using eosio::singleton; - eosio::block_signing_authority convert_to_block_signing_authority( const eosio::public_key& producer_key ) { - return eosio::block_signing_authority_v0{ .threshold = 1, .keys = {{producer_key, 1}} }; - } - void system_contract::register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { auto prod = _producers.find( producer.value ); const auto ct = current_time_point(); @@ -120,8 +116,7 @@ namespace eosiosystem { top_producers.emplace_back( eosio::producer_authority{ .producer_name = it->owner, - .authority = it->producer_authority.has_value() ? *it->producer_authority - : convert_to_block_signing_authority( it->producer_key ) + .authority = it->get_producer_authority() }, it->location ); diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index c2eab2cc..a8366f52 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -899,6 +899,108 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { } FC_LOG_AND_RETHROW() +BOOST_FIXTURE_TEST_CASE( producer_wtmsig_transition, eosio_system_tester ) try { + cross_15_percent_threshold(); + + BOOST_REQUIRE_EQUAL( control->active_producers().version, 0u ); + + set_code( config::system_account_name, contracts::util::system_wasm_v1_8() ); + set_abi( config::system_account_name, contracts::util::system_abi_v1_8().data() ); + + issue_and_transfer( N(alice1111111), core_sym::from_string("200000000.0000"), config::system_account_name ); + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url","") + ("location", 0) + ) + ); + BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); + BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); + + auto alice_prod_info1 = get_producer_info( N(alice1111111) ); + wdump((alice_prod_info1)); + + produce_block(); + produce_block( fc::minutes(2) ); + produce_blocks(2); + BOOST_REQUIRE_EQUAL( control->active_producers().version, 1u ); + + const auto schedule_update1 = get_global_state()["last_producer_schedule_update"]; + + const auto& rlm = control->get_resource_limits_manager(); + + auto alice_initial_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); + + set_code( config::system_account_name, contracts::system_wasm() ); + set_abi( config::system_account_name, contracts::system_abi().data() ); + produce_block(); + BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); + + auto alice_prod_info2 = get_producer_info( N(alice1111111) ); + wdump((alice_prod_info2)); + BOOST_REQUIRE_EQUAL( alice_prod_info2["is_active"], true ); + + produce_block( fc::minutes(2) ); + const auto schedule_update2 = get_global_state()["last_producer_schedule_update"]; + BOOST_REQUIRE( schedule_update1 < schedule_update2 ); // Ensure last_producer_schedule_update is increasing. + + // Producing the above block would trigger the bug in v1.9.0 that sets the default block_signing_authority + // in the producer object of the currently active producer alice1111111. + // However, starting in v1.9.1, the producer object does not have a default block_signing_authority added to the + // serialization of the producer object if it was not already present in the binary extension field + // producer_authority to begin with. This is verified below by ensuring the RAM usage of alice (who pays for the + // producer object) does not increase. + + auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); + BOOST_CHECK_EQUAL( alice_initial_ram_usage, alice_ram_usage ); + + auto alice_prod_info3 = get_producer_info( N(alice1111111) ); + wdump((alice_prod_info3)); + if( alice_prod_info3.get_object().contains("producer_authority") ) { + BOOST_CHECK_EQUAL( alice_prod_info3["producer_authority"][1]["threshold"], 0 ); + } + + produce_block( fc::minutes(2) ); + const auto schedule_update3 = get_global_state()["last_producer_schedule_update"]; + wdump((schedule_update1)(schedule_update2)(schedule_update3)); + + // The bug in v1.9.0 would cause alice to have an invalid producer authority (the default block_signing_authority). + // The v1.9.0 system contract would have attempted to set a proposed producer schedule including this invalid + // authority which would be rejected by the EOSIO native system and cause the onblock transaction to continue to fail. + // This could be observed by noticing that last_producer_schedule_update was not being updated even though it should. + // However, starting in v1.9.1, update_elected_producers is smarter about the producer schedule it constructs to + // propose to the system. It will recognize the default constructed authority (which shouldn't be created by the + // v1.9.1 system contract but may still exist in the tables if it was constructed by the buggy v1.9.0 system contract) + // and instead resort to constructing the block signing authority from the single producer key in the table. + // So newer system contracts should see onblock continue to function, which is verified by the check below. + + BOOST_CHECK( schedule_update2 < schedule_update3 ); // Ensure last_producer_schedule_update is increasing. + + // But even if the buggy v1.9.0 system contract was running, it should always still be possible to recover + // by having the producer with the invalid authority simply call regproducer or regproducer2 to correct their + // block signing authority. + + BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() + ("producer", "alice1111111") + ("producer_key", get_public_key( N(alice1111111), "active") ) + ("url","") + ("location", 0) + ) + ); + + produce_block(); + produce_block( fc::minutes(2) ); + + auto alice_prod_info4 = get_producer_info( N(alice1111111) ); + wdump((alice_prod_info4)); + BOOST_REQUIRE_EQUAL( alice_prod_info4["is_active"], true ); + const auto schedule_update4 = get_global_state()["last_producer_schedule_update"]; + wdump((schedule_update1)(schedule_update2)(schedule_update3)(schedule_update4)); + BOOST_REQUIRE( schedule_update2 < schedule_update4 ); + +} FC_LOG_AND_RETHROW() + BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { cross_15_percent_threshold(); @@ -5408,7 +5510,7 @@ BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); } - + } FC_LOG_AND_RETHROW() From f212718d45d2b1085bca444be9a127987a9974ba Mon Sep 17 00:00:00 2001 From: arhag Date: Fri, 31 Jan 2020 17:59:04 -0500 Subject: [PATCH 1011/1048] remove wdump from test --- tests/eosio.system_tests.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index a8366f52..08497875 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -918,8 +918,8 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig_transition, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); - auto alice_prod_info1 = get_producer_info( N(alice1111111) ); - wdump((alice_prod_info1)); + //auto alice_prod_info1 = get_producer_info( N(alice1111111) ); + //wdump((alice_prod_info1)); produce_block(); produce_block( fc::minutes(2) ); @@ -938,7 +938,6 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig_transition, eosio_system_tester ) try { BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); auto alice_prod_info2 = get_producer_info( N(alice1111111) ); - wdump((alice_prod_info2)); BOOST_REQUIRE_EQUAL( alice_prod_info2["is_active"], true ); produce_block( fc::minutes(2) ); @@ -956,14 +955,12 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig_transition, eosio_system_tester ) try { BOOST_CHECK_EQUAL( alice_initial_ram_usage, alice_ram_usage ); auto alice_prod_info3 = get_producer_info( N(alice1111111) ); - wdump((alice_prod_info3)); if( alice_prod_info3.get_object().contains("producer_authority") ) { BOOST_CHECK_EQUAL( alice_prod_info3["producer_authority"][1]["threshold"], 0 ); } produce_block( fc::minutes(2) ); const auto schedule_update3 = get_global_state()["last_producer_schedule_update"]; - wdump((schedule_update1)(schedule_update2)(schedule_update3)); // The bug in v1.9.0 would cause alice to have an invalid producer authority (the default block_signing_authority). // The v1.9.0 system contract would have attempted to set a proposed producer schedule including this invalid @@ -993,10 +990,8 @@ BOOST_FIXTURE_TEST_CASE( producer_wtmsig_transition, eosio_system_tester ) try { produce_block( fc::minutes(2) ); auto alice_prod_info4 = get_producer_info( N(alice1111111) ); - wdump((alice_prod_info4)); BOOST_REQUIRE_EQUAL( alice_prod_info4["is_active"], true ); const auto schedule_update4 = get_global_state()["last_producer_schedule_update"]; - wdump((schedule_update1)(schedule_update2)(schedule_update3)(schedule_update4)); BOOST_REQUIRE( schedule_update2 < schedule_update4 ); } FC_LOG_AND_RETHROW() From b75481ea3fb1956728a5b20fb0f6e26427044941 Mon Sep 17 00:00:00 2001 From: arhag Date: Mon, 3 Feb 2020 10:12:14 -0500 Subject: [PATCH 1012/1048] bump version to v1.9.1 --- CMakeLists.txt | 2 +- README.md | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 08c995ed..adbdce0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) -set(VERSION_PATCH 0) +set(VERSION_PATCH 1) #set(VERSION_SUFFIX rc4) if (VERSION_SUFFIX) diff --git a/README.md b/README.md index 46070ba1..b8a32ae4 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.0 +## Version : 1.9.1 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. @@ -15,8 +15,8 @@ The following unprivileged contract(s) are also part of the system. * [eosio.token](./contracts/eosio.token) Dependencies: -* [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0-rc1) -* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.0-rc2) (optional dependency only needed to build unit tests) +* [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0) +* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.1) (optional dependency only needed to build unit tests) To build the contracts follow the instructions in [`Build and deploy` section](./docs/02_build-and-deploy.md). From 4c412311cc188438de2c5b4a7701921ec41c7ee8 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 6 Feb 2020 19:49:13 +0200 Subject: [PATCH 1013/1048] Spliting index.md file, the content thus moved into new sections, index.md has link to those new sections Fix outdated links Small corrections on emphasizing terms, e.g. system contracts or system accounts Some re-ordering of the sections was done due to introductions of the new ones No new content added, thus another tech review or content review is not needed; however annotations of the system contract's classes were added or updated. To avoid double listing of system contracts (in reference doc tree and under core concepts tree) on the main navigation, each system contract class was annotated more thoroughly; these annotations will make their way into the reference doc content. The core concepts subsection in the navigation tree is not needed anymore, core concept are covered by index.md with link to the reference doc --- .../include/eosio.bios/eosio.bios.hpp | 26 +-- .../include/eosio.msig/eosio.msig.hpp | 14 +- .../include/eosio.system/eosio.system.hpp | 27 +-- .../include/eosio.system/exchange_state.hpp | 6 - .../include/eosio.system/native.hpp | 5 - .../include/eosio.system/rex.results.hpp | 6 +- .../include/eosio.token/eosio.token.hpp | 9 +- .../include/eosio.wrap/eosio.wrap.hpp | 26 +-- docs/01_key-concepts/01_system.md | 24 ++ docs/01_key-concepts/02_ram.md | 12 + docs/01_key-concepts/03_cpu.md | 6 + docs/01_key-concepts/04_net.md | 6 + docs/01_key-concepts/05_stake.md | 6 + docs/01_key-concepts/06_vote.md | 6 + ...d-and-deploy.md => 03_build-and-deploy.md} | 37 +-- .../01_upgrading-the-eosio.system-contract.md | 11 +- .../02_how-to-buy-ram.md | 6 +- .../03_how-to-stake.md | 6 +- .../04_how-to-vote.md | 6 +- ...ow-to-create-issue-and-transfer-a-token.md | 8 +- ...-a-multisig-transaction-with-eosio.msig.md | 36 ++- .../07_how-to-use-eosio.wrap.md | 38 ++- docs/index.md | 220 ++---------------- 23 files changed, 200 insertions(+), 347 deletions(-) create mode 100644 docs/01_key-concepts/01_system.md create mode 100644 docs/01_key-concepts/02_ram.md create mode 100644 docs/01_key-concepts/03_cpu.md create mode 100644 docs/01_key-concepts/04_net.md create mode 100644 docs/01_key-concepts/05_stake.md create mode 100644 docs/01_key-concepts/06_vote.md rename docs/{02_build-and-deploy.md => 03_build-and-deploy.md} (67%) rename docs/{03_guides => 04_guides}/01_upgrading-the-eosio.system-contract.md (98%) rename docs/{03_guides => 04_guides}/02_how-to-buy-ram.md (92%) rename docs/{03_guides => 04_guides}/03_how-to-stake.md (93%) rename docs/{03_guides => 04_guides}/04_how-to-vote.md (95%) rename docs/{03_guides => 04_guides}/05_how-to-create-issue-and-transfer-a-token.md (98%) rename docs/{03_guides => 04_guides}/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md (89%) rename docs/{03_guides => 04_guides}/07_how-to-use-eosio.wrap.md (98%) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp index 88094b68..643e562c 100644 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp @@ -7,25 +7,6 @@ #include #include -/** - * EOSIO Contracts - * - * The design of the EOSIO blockchain calls for a number of smart contracts that are run at a - * privileged permission level in order to support functions such as block producer registration and - * voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart - * contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts. - * - * This repository contains examples of these privileged contracts that are useful when deploying, - * managing, and/or using an EOSIO blockchain. They are provided for reference purposes: - * - eosio.bios - * - eosio.system - * - eosio.msig - * - eosio.wrap - * - * The following unprivileged contract(s) are also part of the system. - * - eosio.token - */ - namespace eosiobios { using eosio::action_wrapper; @@ -85,6 +66,11 @@ namespace eosiobios { (schedule_version)(new_producers)) }; + /** + * The `eosio.bios` is the first sample of system contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. + * + * Just like in the `eosio.system` sample contract implementation, there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the `eosio.system` contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + */ class [[eosio::contract("eosio.bios")]] bios : public eosio::contract { public: using contract::contract; @@ -182,8 +168,6 @@ namespace eosiobios { [[eosio::action]] void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} - /** @}*/ - /** * Set abi action sets the abi for contract identified by `account` name. Creates an entry in the abi_hash_table * index, with `account` name as key, if it is not already present and sets its value with the abi hash. diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp index 25c46221..19f2600c 100644 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp @@ -6,12 +6,15 @@ #include namespace eosio { - + /** - * @defgroup eosiomsig eosio.msig - * @ingroup eosiocontracts - * eosio.msig contract defines the structures and actions needed to manage the proposals and approvals on blockchain. - * @{ + * The `eosio.msig` system contract allows for creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. + * + * In short, the workflow to propose, review, approve and then executed a transaction it can be described by the following: + * - first you create a transaction json file, + * - then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, + * - the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, + * - after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. */ class [[eosio::contract("eosio.msig")]] multisig : public contract { public: @@ -156,5 +159,4 @@ namespace eosio { typedef eosio::multi_index< "invals"_n, invalidation > invalidations; }; - /** @}*/ // end of @defgroup eosiomsig eosio.msig } /// namespace eosio diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 8dce115d..0c81cb95 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -78,19 +78,20 @@ namespace eosiosystem { static constexpr int64_t default_inflation_pay_factor = 50000; // producers pay share = 10000 / 50000 = 20% of the inflation static constexpr int64_t default_votepay_factor = 40000; // per-block pay share = 10000 / 40000 = 25% of the producer pay - /** - * eosio.system contract - * - * eosio.system contract defines the structures and actions needed for blockchain's core functionality. - * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or - * delegate their vote to a proxy. - * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. - * - Users can buy and sell RAM at a market-determined price. - * - Users can bid on premium names. - * - A resource exchange system (REX) allows token holders to lend their tokens, - * and users to rent CPU and Network resources in return for a market-determined fee. - */ - + /** + * The `eosio.system` smart contract is provided by `block.one` as a sample system contract, and it defines the structures and actions needed for blockchain's core functionality. + * + * Just like in the `eosio.bios` sample contract implementation, there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the `eosio.system` contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + * + * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or + * delegate their vote to a proxy. + * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. + * - Users can buy and sell RAM at a market-determined price. + * - Users can bid on premium names. + * - A resource exchange system (REX) allows token holders to lend their tokens, + * and users to rent CPU and Network resources in return for a market-determined fee. + */ + // A name bid, which consists of: // - a `newname` name that the bid is for // - a `high_bidder` account name that is the one with the highest bid so far diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp index 4e5ba817..c339b970 100644 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ b/contracts/eosio.system/include/eosio.system/exchange_state.hpp @@ -8,11 +8,6 @@ namespace eosiosystem { using eosio::asset; using eosio::symbol; - /** - * @addtogroup eosiosystem - * @{ - */ - /** * Uses Bancor math to create a 50/50 relay between two asset types. * @@ -50,5 +45,4 @@ namespace eosiosystem { }; typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; - /** @}*/ // enf of @addtogroup eosiosystem } /// namespace eosiosystem diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index b5cb33e2..ca885347 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -17,10 +17,6 @@ namespace eosiosystem { using eosio::permission_level; using eosio::public_key; - /** - * @addtogroup eosiosystem - * @{ - */ /** * A weighted permission. * @@ -264,5 +260,4 @@ namespace eosiosystem { using setcode_action = eosio::action_wrapper<"setcode"_n, &native::setcode>; using setabi_action = eosio::action_wrapper<"setabi"_n, &native::setabi>; }; - /** @}*/ // @addtogroup eosiosystem } diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp index 29af8533..378d6add 100644 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ b/contracts/eosio.system/include/eosio.system/rex.results.hpp @@ -9,9 +9,9 @@ using eosio::asset; using eosio::name; /** - * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. - * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. - * An inline convenience action does not have any effect, however, + * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. + * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. + * An inline convenience action does not have any effect, however, * its data includes the result of the parent action and appears in its trace. */ class [[eosio::contract("rex.results")]] rex_results : eosio::contract { diff --git a/contracts/eosio.token/include/eosio.token/eosio.token.hpp b/contracts/eosio.token/include/eosio.token/eosio.token.hpp index 380d11b1..050a685b 100644 --- a/contracts/eosio.token/include/eosio.token/eosio.token.hpp +++ b/contracts/eosio.token/include/eosio.token/eosio.token.hpp @@ -14,8 +14,13 @@ namespace eosio { using std::string; /** - * eosio.token contract defines the structures and actions that allow users to create, issue, and manage - * tokens on EOSIO based blockchains. + * The `eosio.token` sample system contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. It demonstrates one way to implement a smart contract which allows for creation and management of tokens. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the below listed actions, that one uses the `eosio.token` contract instead of developing their own. + * + * The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). + * + * The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. The `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. + * + * Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. */ class [[eosio::contract("eosio.token")]] token : public contract { public: diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp index c6fdbe24..c272c8e2 100644 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp @@ -6,16 +6,11 @@ namespace eosio { /** - * @defgroup eosiowrap eosio.wrap - * @ingroup eosiocontracts - * eosio.wrap contract simplifies Block Producer superuser actions by making them more readable and easier to audit. - - * It does not grant block producers any additional powers that do not already exist within the - * system. Currently, 15/21 block producers can already change an account's keys or modify an - * account's contract at the request of ECAF or an account's owner. However, the current method - * is opaque and leaves undesirable side effects on specific system accounts. - * eosio.wrap allows for a cleaner method of implementing these important governance actions. - * @{ + * The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. + * + * It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. + * + * The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. */ class [[eosio::contract("eosio.wrap")]] wrap : public contract { public: @@ -25,18 +20,19 @@ namespace eosio { * Execute action. * * Execute a transaction while bypassing regular authorization checks. + * + * Preconditions: + * - Requires authorization of eosio.wrap which needs to be a privileged account. * + * Postconditions: + * - Deferred transaction RAM usage is billed to 'executer' * + * * @param executer - account executing the transaction, * @param trx - the transaction to be executed. - * - * @pre Requires authorization of eosio.wrap which needs to be a privileged account. - * - * @post Deferred transaction RAM usage is billed to 'executer' */ [[eosio::action]] void exec( ignore executer, ignore trx ); using exec_action = eosio::action_wrapper<"exec"_n, &wrap::exec>; }; - /** @}*/ // end of @defgroup eosiowrap eosio.wrap } /// namespace eosio diff --git a/docs/01_key-concepts/01_system.md b/docs/01_key-concepts/01_system.md new file mode 100644 index 00000000..b3f6f2df --- /dev/null +++ b/docs/01_key-concepts/01_system.md @@ -0,0 +1,24 @@ +--- +content_title: System contracts, system accounts, privileged accounts +link_text: System contracts and accounts, privileged accounts +--- + +At the genesis of an EOSIO based blockchain, there is only one account present, `eosio` account, which is the main `system account`. There are other `system account`s, created by `eosio` account, which control specific actions of the `system contract`s [mentioned in previous section](../#system-contracts-defined-in-eosio.contracts). __Note__ the terms `system contract` and `system account`. `Privileged accounts` are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to `eosio.prods` system account. + +As you just learned the relation between a `system account` and a `system contract`, it is also important to remember that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: + +|Account|Privileged|Has contract|Description| +|---|---|---|---| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| +|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.names|No|No|The account which is holding funds from namespace auctions.| +|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| +|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| +|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| +|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| +|eosio.saving|No|No|The account which holds the 4% of network inflation.| +|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| +|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| \ No newline at end of file diff --git a/docs/01_key-concepts/02_ram.md b/docs/01_key-concepts/02_ram.md new file mode 100644 index 00000000..b7ecf26d --- /dev/null +++ b/docs/01_key-concepts/02_ram.md @@ -0,0 +1,12 @@ +--- +content_title: RAM as resource +link_text: RAM as resource +--- + +RAM is the memory, storage space, where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a `multi-index table`, which is explained [here](https://developers.eos.io/eosio-home/docs/data-persistence) or a `singleton`, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/master/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eosio.contracts/blob/master/contracts/eosio.system/include/eosio.system/eosio.system.hpp). + +The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM as the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. + +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. + +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). \ No newline at end of file diff --git a/docs/01_key-concepts/03_cpu.md b/docs/01_key-concepts/03_cpu.md new file mode 100644 index 00000000..43813698 --- /dev/null +++ b/docs/01_key-concepts/03_cpu.md @@ -0,0 +1,6 @@ +--- +content_title: CPU as resource +link_text: CPU as resource +--- + +CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as `cpu bandwidth` on the cleos get account command output and represents the amount of processing time an account has at its disposal when pushing actions to a contract. \ No newline at end of file diff --git a/docs/01_key-concepts/04_net.md b/docs/01_key-concepts/04_net.md new file mode 100644 index 00000000..a9b5aea1 --- /dev/null +++ b/docs/01_key-concepts/04_net.md @@ -0,0 +1,6 @@ +--- +content_title: NET as resource +link_text: NET as resource +--- + +As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is referred to as `net bandwidth` on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. \ No newline at end of file diff --git a/docs/01_key-concepts/05_stake.md b/docs/01_key-concepts/05_stake.md new file mode 100644 index 00000000..c0fb29b2 --- /dev/null +++ b/docs/01_key-concepts/05_stake.md @@ -0,0 +1,6 @@ +--- +content_title: Staking on EOSIO based blockchains +link_text: Staking on EOSIO based blockchains +--- + +On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, in spite of inflation caused by minting new tokens in order to reward BPs for their services every 24 hours. \ No newline at end of file diff --git a/docs/01_key-concepts/06_vote.md b/docs/01_key-concepts/06_vote.md new file mode 100644 index 00000000..5daaac72 --- /dev/null +++ b/docs/01_key-concepts/06_vote.md @@ -0,0 +1,6 @@ +--- +content_title: Voting on EOSIO based blockchains +link_text: Voting on EOSIO based blockchains +--- + +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these nodes are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. \ No newline at end of file diff --git a/docs/02_build-and-deploy.md b/docs/03_build-and-deploy.md similarity index 67% rename from docs/02_build-and-deploy.md rename to docs/03_build-and-deploy.md index b61b1513..15dab87b 100644 --- a/docs/02_build-and-deploy.md +++ b/docs/03_build-and-deploy.md @@ -1,22 +1,25 @@ -## How to build the eosio.contracts +--- +content_title: How to build eosio.contracts +link_text: How to build eosio.contracts +--- -### Preconditions -Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases) to install it. To verify if you have `eosio.cdt` installed and its version run the following command +## Preconditions +Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases) to install it. To verify if you have `eosio.cdt` installed and its version run the following command ```sh eosio-cpp -v ``` -#### Build contracts using the build script +### Build contracts using the build script -##### To build contracts alone +#### To build contracts alone Run the `build.sh` script in the top directory to build all the contracts. -##### To build the contracts and unit tests +#### To build the contracts and unit tests 1. Ensure an appropriate version of `eosio` has been built from source and installed. Installing `eosio` from binaries `is not` sufficient. You can find instructions on how to do it [here](https://github.com/EOSIO/eos/blob/master/README.md) in section `Building from Sources`. 2. Run the `build.sh` script in the top directory with the `-t` flag to build all the contracts and the unit tests for these contracts. -#### Build contracts manually +### Build contracts manually To build the `eosio.contracts` execute the following commands. @@ -42,38 +45,38 @@ make -j$(sysctl -n hw.ncpu) cd .. ``` -#### After build: -* If the build was configured to also build unit tests, the unit tests executable is placed in the _build/tests_ folder and is named __unit_test__. -* The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. -* Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. +### After build: +* If the build was configured to also build unit tests, the unit tests executable is placed in the _build/tests_ folder and is named __unit_test__. +* The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. +* Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. -## How to deploy the eosio.contracts +# How to deploy the eosio.contracts -### To deploy eosio.bios contract execute the following command: +## To deploy eosio.bios contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testerbios` ``` cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios ``` -### To deploy eosio.msig contract execute the following command: +## To deploy eosio.msig contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testermsig` ``` cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig ``` -### To deploy eosio.system contract execute the following command: +## To deploy eosio.system contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testersystem` ``` cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem ``` -### To deploy eosio.token contract execute the following command: +## To deploy eosio.token contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testertoken` ``` cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken ``` -### To deploy eosio.wrap contract execute the following command: +## To deploy eosio.wrap contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testerwrap` ``` cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap diff --git a/docs/03_guides/01_upgrading-the-eosio.system-contract.md b/docs/04_guides/01_upgrading-the-eosio.system-contract.md similarity index 98% rename from docs/03_guides/01_upgrading-the-eosio.system-contract.md rename to docs/04_guides/01_upgrading-the-eosio.system-contract.md index 2bd712fb..51f49375 100644 --- a/docs/03_guides/01_upgrading-the-eosio.system-contract.md +++ b/docs/04_guides/01_upgrading-the-eosio.system-contract.md @@ -1,6 +1,9 @@ -## Upgrading the system contract +--- +content_title: Upgrading the system contract +link_text: Upgrading the system contract +--- -### Indirect method using eosio.msig contract +# Indirect method using eosio.msig contract Cleos currently provides tools to propose an action with the eosio.msig contract, but it does not provide an easy interface to propose a custom transaction. @@ -12,7 +15,7 @@ The disadvantage of the eosio.msig method is that it requires the proposer to ha For now, it is recommended to use the direct method to upgrade the system contract. -### Direct method (avoids using eosio.msig contract) +# Direct method (avoids using eosio.msig contract) Each of the top 21 block producers should do the following: @@ -206,4 +209,4 @@ $ diff original_system_contract.abi new_system_contract.abi < },{ < "name": "unstaking", < "type": "asset" -``` +``` \ No newline at end of file diff --git a/docs/03_guides/02_how-to-buy-ram.md b/docs/04_guides/02_how-to-buy-ram.md similarity index 92% rename from docs/03_guides/02_how-to-buy-ram.md rename to docs/04_guides/02_how-to-buy-ram.md index 2885c514..cd808e21 100644 --- a/docs/03_guides/02_how-to-buy-ram.md +++ b/docs/04_guides/02_how-to-buy-ram.md @@ -1,8 +1,8 @@ -## Goal +# Goal Setup an account that require multiple signatures for signing a transaction -## Before you begin +# Before you begin * You have an account @@ -14,7 +14,7 @@ Setup an account that require multiple signatures for signing a transaction * Unlock your wallet -## Steps +# Steps Buys RAM in value of 0.1 SYS tokens for account `alice`: diff --git a/docs/03_guides/03_how-to-stake.md b/docs/04_guides/03_how-to-stake.md similarity index 93% rename from docs/03_guides/03_how-to-stake.md rename to docs/04_guides/03_how-to-stake.md index 83f3a8da..4cfd9893 100644 --- a/docs/03_guides/03_how-to-stake.md +++ b/docs/04_guides/03_how-to-stake.md @@ -1,8 +1,8 @@ -## Goal +# Goal Stake resource for your account -## Before you begin +# Before you begin * Install the currently supported version of cleos @@ -13,7 +13,7 @@ Stake resource for your account * What is network bandwidth * What is CPU bandwidth -## Steps +# Steps Stake 0.01 SYS network bandwidth for `alice` diff --git a/docs/03_guides/04_how-to-vote.md b/docs/04_guides/04_how-to-vote.md similarity index 95% rename from docs/03_guides/04_how-to-vote.md rename to docs/04_guides/04_how-to-vote.md index 62654ba7..f1a520f6 100644 --- a/docs/03_guides/04_how-to-vote.md +++ b/docs/04_guides/04_how-to-vote.md @@ -1,8 +1,8 @@ -## Goal +# Goal Vote for a block producer -## Before you begin +# Before you begin * Install the current supported version of cleos @@ -14,7 +14,7 @@ Vote for a block producer * Unlock your wallet -## Steps +# Steps Assume you are going to vote for blockproducer1 and blockproducer2 from an account called `eosiotestts2`, execute the following: diff --git a/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md similarity index 98% rename from docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md rename to docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md index 3693d37e..313e8139 100644 --- a/docs/03_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -1,5 +1,3 @@ -## How to create, issue and transfer a token - ## Step 1: Obtain Contract Source Navigate to your contracts directory. @@ -74,7 +72,7 @@ This command created a new token `SYS` with a precision of 4 decimals and a maxi ## Step 6: Issue Tokens -The issuer can issue new tokens to the issuer account in our case `eosio`. +The issuer can issue new tokens to the issuer account in our case `eosio`. ```text cleos push action eosio.token issue '[ "eosio", "100.0000 SYS", "memo" ]' -p eosio@active @@ -114,7 +112,7 @@ Result: 25.00 SYS ``` -Check "eosio's" balance, notice that tokens were deducted from the account +Check "eosio's" balance, notice that tokens were deducted from the account ```shell cleos get currency balance eosio.token eosio SYS @@ -123,4 +121,4 @@ cleos get currency balance eosio.token eosio SYS Result: ```text 75.00 SYS -``` +``` \ No newline at end of file diff --git a/docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md similarity index 89% rename from docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md rename to docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md index f68dff87..6c78c0e1 100644 --- a/docs/03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -1,14 +1,12 @@ -## eosio.msig examples +## Cleos usage example for issuing tokens. -### Cleos usage example for issuing tokens. - -#### Prerequisites: +### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' is the issuer of SYS token. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -#### One user creates a proposal: +### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester @@ -16,7 +14,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` -#### Another user reviews the transaction: +### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -57,7 +55,7 @@ $ cleos multisig review tester test } ```` -#### And then approves it: +### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -65,7 +63,7 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` -#### First user initiates execution: +### First user initiates execution: ```` $ cleos multisig exec tester test -p tester @@ -74,15 +72,15 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e ```` -### Cleos usage example for transferring tokens. +## Cleos usage example for transferring tokens. -#### Prerequisites: +### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. - account 'treasury' has at least 1.1000 SYS token balance. - account 'tester' exists. - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. -#### One user creates a proposal: +### One user creates a proposal: ```` $ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester @@ -90,7 +88,7 @@ executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... ```` -#### Another user reviews the transaction: +### Another user reviews the transaction: ```` $ cleos multisig review tester test { @@ -132,7 +130,7 @@ $ cleos multisig review tester test } ```` -#### And then approves it: +### And then approves it: ```` $ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury @@ -140,18 +138,18 @@ executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd951 # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} ```` -#### First user check account balance before executing the proposed transaction +### First user check account balance before executing the proposed transaction ```` $ cleos get account tester ... -SYS balances: +SYS balances: liquid: 1.0487 SYS staked: 2.0000 SYS unstaking: 0.0000 SYS total: 4.0487 SYS ```` -#### First user initiates execution of proposed transaction: +### First user initiates execution of proposed transaction: ```` $ cleos multisig exec tester test -p tester @@ -159,13 +157,13 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e # eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} ```` -#### First user can check account balance, it should be increased by 1.0000 SYS +### First user can check account balance, it should be increased by 1.0000 SYS ```` $ cleos get account tester ... -SYS balances: +SYS balances: liquid: 2.0487 SYS staked: 2.0000 SYS unstaking: 0.0000 SYS total: 4.0487 SYS -```` +```` \ No newline at end of file diff --git a/docs/03_guides/07_how-to-use-eosio.wrap.md b/docs/04_guides/07_how-to-use-eosio.wrap.md similarity index 98% rename from docs/03_guides/07_how-to-use-eosio.wrap.md rename to docs/04_guides/07_how-to-use-eosio.wrap.md index 0f3395fc..44c404f9 100644 --- a/docs/03_guides/07_how-to-use-eosio.wrap.md +++ b/docs/04_guides/07_how-to-use-eosio.wrap.md @@ -1,6 +1,4 @@ -# eosio.wrap - -## 1. Installing the eosio.wrap contract +# 1. Installing the eosio.wrap contract The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. @@ -10,9 +8,9 @@ The `eosio.wrap` account also needs to have sufficient RAM to host the contract This guide will be using cleos to carry out the process. -### 1.1 Create the eosio.wrap account +## 1.1 Create the eosio.wrap account -#### 1.1.1 Generate the transaction to create the eosio.wrap account +### 1.1.1 Generate the transaction to create the eosio.wrap account The transaction to create the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. @@ -275,7 +273,7 @@ $ cat producer_permissions.json ] ``` -#### 1.1.2 Propose the transaction to create the eosio.wrap account +### 1.1.2 Propose the transaction to create the eosio.wrap account Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same create_wrap_account_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. @@ -291,7 +289,7 @@ executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 1.1.3 Review and approve the transaction to create the eosio.wrap account +### 1.1.3 Review and approve the transaction to create the eosio.wrap account Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. @@ -350,7 +348,7 @@ executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 1.1.4 Execute the transaction to create the eosio.wrap account +### 1.1.4 Execute the transaction to create the eosio.wrap account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). @@ -389,9 +387,9 @@ producers: ``` -### 1.2 Deploy the eosio.wrap contract +## 1.2 Deploy the eosio.wrap contract -#### 1.2.1 Generate the transaction to deploy the eosio.wrap contract +### 1.2.1 Generate the transaction to deploy the eosio.wrap contract The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. @@ -452,7 +450,7 @@ $ head -n 9 deploy_wrap_contract_trx.json This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. The end of sub-section 2.1.1 displayed what the JSON of the active permissions of each of the active block producers would look like given the assumptions about the active block producer set. That JSON was stored in the file producer_permissions.json; if the approvers (i.e. block producers) have not created that file already, they should create that file now as shown at the end of sub-section 2.1.1. -#### 1.2.2 Propose the transaction to deploy the eosio.wrap contract +### 1.2.2 Propose the transaction to deploy the eosio.wrap contract Only one of the potential approvers will need to propose the transaction that was created in the previous sub-section. All the other approvers should still follow the steps in the previous sub-section to generate the same deploy_wrap_contract_trx.json file as all the other approvers. They will need this to compare to the actual proposed transaction prior to approving. @@ -468,7 +466,7 @@ executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract +### 1.2.3 Review and approve the transaction to deploy the eosio.wrap contract Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. @@ -543,7 +541,7 @@ executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e4648 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 1.2.4 Execute the transaction to create the eosio.wrap account +### 1.2.4 Execute the transaction to create the eosio.wrap account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). @@ -565,9 +563,9 @@ $ sha256sum contracts/eosio.wrap/eosio.wrap.wasm If the two hashes match then the local WebAssembly code is the one deployed on the blockchain. The retrieved ABI, which was stored in the file retrieved-eosio.wrap.abi, can then be compared to the original ABI of the contract (contracts/eosio.wrap/eosio.wrap.abi) to ensure they are semantically the same. -## 2. Using the eosio.wrap contract +# 2. Using the eosio.wrap contract -### 2.1 Example: Updating owner authority of an arbitrary account +## 2.1 Example: Updating owner authority of an arbitrary account This example will demonstrate how to use the deployed eosio.wrap contract together with the eosio.msig contract to allow a greater than two-thirds supermajority of block producers of an EOSIO blockchain to change the owner authority of an arbitrary account. The example will use cleos: in particular, the `cleos multisig` command, the `cleos set account permission` sub-command, and the `cleos wrap exec` sub-command. However, the guide also demonstrates what to do if the `cleos wrap exec` sub-command is not available. @@ -601,7 +599,7 @@ $ cat producer_permissions.json ] ``` -#### 2.1.1 Generate the transaction to change the owner permission of an account +### 2.1.1 Generate the transaction to change the owner permission of an account The goal of this example is for the block producers to change the owner permission of the account `alice`. @@ -742,7 +740,7 @@ Then modify the transaction in wrap_update_alice_owner_trx.json as follows: * append the hex data from update_alice_owner_trx_serialized.hex to the end of the existing hex data in the `data` field in wrap_update_alice_owner_trx.json. -#### 2.1.2 Propose the transaction to change the owner permission of an account +### 2.1.2 Propose the transaction to change the owner permission of an account The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: ``` @@ -752,7 +750,7 @@ executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26 warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.1.3 Review and approve the transaction to change the owner permission of an account +### 2.1.3 Review and approve the transaction to change the owner permission of an account Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. ``` @@ -835,7 +833,7 @@ executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c warning: transaction executed locally, but may not be confirmed by the network yet ``` -#### 2.1.4 Execute the transaction to change the owner permission of an account +### 2.1.4 Execute the transaction to change the owner permission of an account When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). @@ -871,4 +869,4 @@ cpu bandwidth: producers: -``` +``` \ No newline at end of file diff --git a/docs/index.md b/docs/index.md index 9ef07998..37759d12 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,211 +1,27 @@ -## About System Contracts +--- +content_title: About System Contracts +--- The EOSIO blockchain platform is unique in that the features and characteristics of the blockchain built on it are flexible, that is, they can be changed, or modified completely to suit each business case requirement. Core blockchain features such as consensus, fee schedules, account creation and modification, token economics, block producer registration, voting, multi-sig, etc., are implemented inside smart contracts which are deployed on the blockchain built on the EOSIO platform. -Block.one implements and maintains EOSIO open source platform which contains, as an example, the system contracts encapsulating the base functionality for an EOSIO based blockchain. This document will detail each one of them, [eosio.bios](#eosiobios-system-contract), [eosio.system](#eosiosystem-system-contract), [eosio.msig](#eosiomsig-system-contract), [eosio.token](#eosiotoken-system-contract), [eosio.wrap](#eosiowrap-system-contract) along with a few other main concepts. - -## Concepts - -### System contracts, system accounts, priviledged accounts - -At the genesis of an EOSIO based blockchain, there is only one account present: eosio, which is the main system account. There are other system accounts, which are created by eosio, and control specific actions of the system contracts mentioned earlier. Note that we are introducing the notion of system contract/s and system account/s. Also note that privileged accounts are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to eosio.prods. - -As you just learned the relation between an account and a contract, we are adding here that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: - -|Account|Priviledged|Has contract|Description| -|---|---|---|---| -|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| -|eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| -|eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| -|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| -|eosio.names|No|No|The account which is holding funds from namespace auctions.| -|eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| -|eosio.prods|No|No|The account representing the union of all current active block producers permissions.| -|eosio.ram|No|No|The account that keeps track of the SYS balances based on users actions of buying or selling RAM.| -|eosio.ramfee|No|No|The account that keeps track of the fees collected from users RAM trading actions: 0.5% from the value of each trade goes into this account.| -|eosio.saving|No|No|The account which holds the 4% of network inflation.| -|eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| -|eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| -|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| - -### RAM - -RAM is the memory (space, storage) where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a multi-index table, which can be found explained [here](https://developers.eos.io/eosio-cpp/v1.3.1/docs/db-api) and [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables) or a singleton, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/develop/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/contracts/eosio.system/eosio.system.hpp). -The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM as the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). - -### CPU - -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as "cpu bandwidth" on the cleos get account command output and represents the amount of processing time an account has at its disposal when pushing actions to a contract. - -### NET - -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is referred to as "net bandwidth" on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. - -### Stake - -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, in spite of inflation caused by minting new tokens in order to reward BPs for their services every 24 hours. - -### Vote - -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these nodes are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. - ## System contracts defined in eosio.contracts -1. [eosio.bios](#eosiobios-system-contract) -2. [eosio.system](#eosiosystem-system-contract) -3. [eosio.msig](#eosiomsig-system-contract) -4. [eosio.token](#eosiotoken-system-contract) -5. [eosio.wrap](#eosiowrap-system-contract) - -### eosio.bios system contract - -The `eosio.bios` is the first sample of system smart contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. - -The actions implemented and publicly exposed by `eosio.bios` system contract are: setpriv, setalimits, setglimits, setprods, setparams, reqauth, setabi. - -|Action name|Action description| -|---|---| -|setpriv|Set privilege status for an account.| -|setalimits|Set the resource limits of an account| -|setglimits|Not implemented yet.| -|setprods|Set a new list of active producers, that is, a new producers' schedule.| -|setparams|Set the blockchain parameters.| -|reqauth|Check if an account has authorization to access the current action.| -|setabi|Set the abi for a contract identified by an account name.| - -The above actions are enough to serve the functionality of a basic blockchain, however, a keen eye would notice that the actions listed above do not allow for creation of an account, nor updating permissions, and other important features. As we mentioned earlier, this sample system contract is minimalist in its implementation, therefore it relies also on some native EOSIO actions. These native actions are not implemented in the `eosio.bios` system contract, they are implemented at the EOSIO chain core level. In the `eosio.bios` contract they are simply declared and have no implementation, so they can show in the contracts ABI definition, and therefore users can push these actions to the account that holds the `eosio.bios` contract. When one of these actions are pushed to the chain, to the `eosio.bios` contract account holder, via a `cleos` command for example, the corresponding native action is executed by the blockchain first, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L58), and then the `eosio.bios` contract `apply` method is invoked, [see the code here](https://github.com/EOSIO/eos/blob/3fddb727b8f3615917707281dfd3dd3cc5d3d66d/libraries/chain/apply_context.cpp#L69), but having no implementation and not being part of the `EOSIO_DISPATCH`, at the contract level, this action will be a NOP, it will do nothing when called from core EOSIO code. - -Below are listed the actions which are declared in the `eosio.bios` contract, mapped one-to-one with the native EOSIO actions, but having no implementation at the contract level: - -|Action name|Description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limit rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setcode|Allows for update of the contract code of an account.| - -### eosio.system system contract - -The `eosio.system` contract is another smart contract that Block.one provides an implementation for as a sample system contract. It is a version of `eosio.bios` only this time it is not minimalist, it contains more elaborated structures, classes, methods, and actions needed for an EOSIO based blockchain core functionality: -- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. -- Producers can register in order to be voted for, and can claim per-block and per-vote rewards. -- Users can buy and sell RAM at a market-determined price. -- Users can bid on premium names. -- A resource exchange system, named REX, allows token holders to lend their tokens, and users to rent CPU and NET resources in return for a market-determined fee. - -The actions implemented and publicly exposed by the `eosio.system` system contract are presented in the table below. Just like the `eosio.bios` sample contract there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the 'eosio.system' contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - -|Action name|Action description| -|---|---| -|newaccount|Called after a new account is created. This code enforces resource-limits rules for new accounts as well as new account naming conventions.| -|updateauth|Updates the permission for an account.| -|deleteauth|Delete permission for an account.| -|linkauth|Assigns a specific action from a contract to a permission you have created.| -|unlinkauth|Assigns a specific action from a contract to a permission you have created.| -|canceldelay|Allows for cancellation of a deferred transaction.| -|onerror|Called every time an error occurs while a transaction was processed.| -|setabi|Allows for updates of the contract ABI of an account.| -|setcode|Allows for updates of the contract code of an account.| -|init|Initializes the system contract for a version and a symbol.| -|setram|Set the ram supply.| -|setramrate|Set the ram increase rate.| -|setparams|Set the blockchain parameters.| -|setpriv|Set privilege status for an account (turn it on/off).| -|setalimits|Set the resource limits of an account.| -|setacctram|Set the RAM limits of an account.| -|setacctnet|Set the NET limits of an account.| -|setacctcpu|Set the CPU limits of an account.| -|rmvproducer|Deactivates a producer by name, if not found asserts.| -|updtrevision|Updates the current revision.| -|bidname|Allows an account to place a bid for a name.| -|bidrefund|Allows an account to get back the amount it bid so far on a name.| -|deposit|Deposits core tokens to user REX fund.| -|withdraw|Withdraws core tokens from user REX fund.| -|buyrex|Buys REX in exchange for tokens taken out of user's REX fund by transferring core tokens from user REX fund and converting them to REX stake.| -|unstaketorex|Use staked core tokens to buy REX.| -|sellrex|Sells REX in exchange for core tokens by converting REX stake back into core tokens at current exchange rate.| -|cnclrexorder|Cancels unfilled REX sell order by owner if one exists.| -|rentcpu|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU will expire.| -|rentnet|Use payment to rent as many SYS tokens as possible as determined by market price and stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET will expire.| -|fundcpuloan|Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry.| -|fundnetloan|Transfers tokens from REX fund to the fund of a specific NET loan in order to be used for loan renewal at expiry.| -|defcpuloan|Withdraws tokens from the fund of a specific CPU loan and adds them to the REX fund.| -|defnetloan|Withdraws tokens from the fund of a specific NET loan and adds them to the REX fund.| -|updaterex|Updates REX owner vote weight to current value of held REX tokens.| -|consolidate|Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days.| -|mvtosavings|Moves a specified amount of REX to savings bucket.| -|mvfrsavings|Moves a specified amount of REX from savings bucket.| -|rexexec|Processes max CPU loans, max NET loans, and max queued sellrex orders. Action does not execute anything related to a specific user.| -|closerex|Deletes owner records from REX tables and frees used RAM. Owner must not have an outstanding REX balance.| -|buyrambytes|Increases receiver's ram in quantity of bytes provided.| -|buyram|Increases receiver's ram quota based upon current price and quantity of tokens provided.| -|sellram|Reduces quota my bytes and then performs an inline transfer of tokens to receiver based upon the average purchase price of the original quota.| -|delegatebw|Stakes SYS from the balance of one account for the benefit of another.| -|undelegatebw|Decreases the total tokens delegated by one account to another account and/or frees the memory associated with the delegation if there is nothing left to delegate.| -|refund|This action is called after the delegation-period to claim all pending unstaked tokens belonging to owner.| -|regproducer|Register producer action, indicates that a particular account wishes to become a producer.| -|unregprod|Deactivate the block producer with specified account.| -|voteproducer|Votes for a set of producers. This action updates the list of producers voted for, for given voter account.| -|regproxy|Set specified account as proxy.| -|onblock|This special action is triggered when a block is applied by the given producer and cannot be generated from any other source.| -|claimrewards|Claim block producing and vote rewards for block producer identified by an account.| - -### eosio.msig system contract - -The `eosio.msig` allows for the creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. - -The workflow to propose, review, approve and then executed a transaction is describe in details [here](./03_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md), and in short it can be described by the following: -- first you create a transaction json file, -- then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, -- the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, -- after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. - -These are the actions implemented and publicly exposed by the `eosio.msig` contract: -|Action name|Action description| -|---|---| -|propose|Creates a proposal containing one transaction.| -|approve|Approves an existing proposal.| -|unapprove|Revokes approval of an existing proposal.| -|cancel|Cancels an existing proposal.| -|exec|Allows an account to execute a proposal.| -|invalidate|Invalidate proposal.| - -### eosio.token system contract - -The `eosio.token` contract defines the structures and actions that allow users to create, issue, and manage tokens for EOSIO based blockchains. - -These are the public actions the `eosio.token` contract is implementing: -|Action name|Action description| -|---|---| -|create|Allows an account to create a token in a given supply amount.| -|issue|This action issues to an account a specific quantity of tokens.| -|open|Allows a first account to create another account with zero balance for specified token at the expense of first account.| -|close|This action is the opposite for `open` action, it closes the specified account for specified token.| -|transfer|Allows an account to transfer to another account the specified token quantity. One account is debited and the other is credited with the specified token quantity.| -|retire|This action is the opposite for `create` action. If all validations succeed, it debits the specified amount of tokens from the total balance.| - -The `eosio.token` sample contract demonstrates one way to implement a smart contract which allows for creation and management of tokens. This contract gives anyone the ability to create a token. It is possible for one to create a similar contract which suits different needs. However, it is recommended that if one only needs a token with the above listed actions, that one uses the `eosio.token` contract instead of developing their own. - -The `eosio.token` contract class also implements two useful public static methods: `get_supply` and `get_balance`. The first allows one to check the total supply of a specified token, created by an account and the second allows one to check the balance of a token for a specified account (the token creator account has to be specified as well). - -The `eosio.token` contract manages the set of tokens, accounts and their corresponding balances, by using two internal multi-index structures: the `accounts` and `stats`. The `accounts` multi-index table holds, for each row, instances of `account` object and the `account` object holds information about the balance of one token. If we remember how multi-index tables work, see [here](https://developers.eos.io/eosio-cpp/docs/using-multi-index-tables), then we understand also that the `accounts` table is scoped to an eosio account, and it keeps the rows indexed based on the token's symbol. This means that when one queries the `accounts` multi-index table for an account name the result is all the tokens that account holds at the moment. - -Similarly, the `stats` multi-index table, holds instances of `currency_stats` objects for each row, which contains information about current supply, maximum supply, and the creator account for a symbol token. The `stats` table is scoped to the token symbol. Therefore, when one queries the `stats` table for a token symbol the result is one single entry/row corresponding to the queried symbol token if it was previously created, or nothing, otherwise. - -### eosio.wrap system contract -The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. +Block.one implements and maintains EOSIO open source platform which contains, as an example, the system contracts encapsulating the base functionality for an EOSIO based blockchain. -It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. +1. [eosio.bios](action-reference/eosio.bios) +2. [eosio.system](action-reference/eosio.system) +3. [eosio.msig](action-reference/eosio.msig) +4. [eosio.token](action-reference/eosio.token) +5. [eosio.wrap](action-reference/eosio.wrap) -However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. +## Key Concepts Implemented by eosio.system -The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. +1. [System](01_key-concepts/01_system.md) +2. [RAM](01_key-concepts/02_ram.md) +3. [CPU](01_key-concepts/03_cpu.md) +4. [NET](01_key-concepts/04_net.md) +5. [Stake](01_key-concepts/05_stake.md) +6. [Vote](01_key-concepts/06_vote.md) -Why is it easier for governance actions to be executed via this contract? -The answer to this question is explained in detailed [here](./03_guides/07_how-to-use-eosio.wrap.md) \ No newline at end of file +## Build and deploy +To build and deploy the system contract follow the instruction from [Build and deploy](03_build-and-deploy.md) section. \ No newline at end of file From b4dd8ad970e846e447fe8cb0f77f82ea5f766768 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 6 Feb 2020 15:15:14 -0500 Subject: [PATCH 1014/1048] Improve environment logging. Use eosio dependency as declared. --- .cicd/build.sh | 12 ++++++------ .cicd/helpers/dependency-info.sh | 10 ++++++++-- .cicd/test.sh | 3 ++- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/.cicd/build.sh b/.cicd/build.sh index 1be513f8..42975cd0 100755 --- a/.cicd/build.sh +++ b/.cicd/build.sh @@ -4,7 +4,7 @@ set -eo pipefail . ./.cicd/helpers/general.sh . ./.cicd/helpers/dependency-info.sh mkdir -p $BUILD_DIR -DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} +DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$SANITIZED_EOSIO_VERSION} if [[ "$BUILDKITE" == 'true' ]]; then buildkite-agent meta-data set cdt-url "$CDT_URL" buildkite-agent meta-data set cdt-version "$CDT_VERSION" @@ -16,15 +16,15 @@ else fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="dpkg -i $MOUNTED_DIR/eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/\\\$(ls /usr/opt/eosio.cdt/)/bin:\\\$PATH" -PRE_COMMANDS="$CDT_COMMANDS && cd $MOUNTED_DIR/build" +PRE_COMMANDS="$CDT_COMMANDS && cd /root/eosio/ && printf \\\"EOSIO commit: \\\$(git rev-parse --verify HEAD). Click \033]1339;url=https://github.com/EOSIO/eos/commit/\\\$(git rev-parse --verify HEAD);content=here\a for details.\n\\\" && cd $MOUNTED_DIR/build" BUILD_COMMANDS="cmake -DBUILD_TESTS=true .. && make -j $JOBS" COMMANDS="$PRE_COMMANDS && $BUILD_COMMANDS" # Test CDT binary download to prevent failures due to eosio.cdt pipeline. INDEX='1' echo "$ curl -sSf $CDT_URL --output eosio.cdt.deb" while ! $(curl -sSf $CDT_URL --output eosio.cdt.deb); do - echo "ERROR: Expected CDT binary for commit ${CDT_COMMIT:0:7} from $CDT_VERSION. It does not exist at $CDT_URL!" - printf "There must be a successful build against ${CDT_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio-dot-cdt/builds?commit=$CDT_COMMIT;content=here\a for this package to exist.\n" + echo "ERROR: Expected CDT binary for commit ${CDT_COMMIT} from $CDT_VERSION. It does not exist at $CDT_URL!" + printf "There must be a successful build against ${CDT_COMMIT} \033]1339;url=https://buildkite.com/EOSIO/eosio-dot-cdt/builds?commit=$CDT_COMMIT;content=here\a for this package to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' INDEX=$(( $INDEX + 1 )) @@ -34,8 +34,8 @@ done INDEX='1' echo "$ docker pull $DOCKER_IMAGE" while [[ "$(docker pull $DOCKER_IMAGE 2>&1 | grep -ice "manifest for $DOCKER_IMAGE not found")" != '0' ]]; do - echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio commit ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\""'!' - printf "There must be a successful build against ${EOSIO_COMMIT:0:7} \033]1339;url=https://buildkite.com/EOSIO/eosio/builds?commit=$EOSIO_COMMIT;content=here\a for this container to exist.\n" + echo "ERROR: Docker image \"$DOCKER_IMAGE\" not found for eosio \"$EOSIO_VERSION\""'!' + printf "There must be a successful build against ${EOSIO_VERSION} \033]1339;url=${EOSIO_BK_URL};content=here\a for this container to exist.\n" echo "Attempt $INDEX, retry in 60 seconds..." echo '' INDEX=$(( $INDEX + 1 )) diff --git a/.cicd/helpers/dependency-info.sh b/.cicd/helpers/dependency-info.sh index c0f526ac..ef7e1d05 100755 --- a/.cicd/helpers/dependency-info.sh +++ b/.cicd/helpers/dependency-info.sh @@ -9,6 +9,7 @@ if [[ -f "$RAW_PIPELINE_CONFIG" ]]; then cat "$RAW_PIPELINE_CONFIG" | grep -Po '^[^"/]*("((?<=\\).|[^"])*"[^"/]*)*' | jq -c .\"eosio-dot-contracts\" > "$PIPELINE_CONFIG" CDT_VERSION=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies."eosio.cdt"') EOSIO_VERSION=$(cat "$PIPELINE_CONFIG" | jq -r '.dependencies.eosio') + SANITIZED_EOSIO_VERSION=$(echo $EOSIO_VERSION | sed 's/\//\_/') else echo 'ERROR: No pipeline configuration file or dependencies file found!' exit 1 @@ -29,6 +30,11 @@ else EOSIO_COMMIT=$(git rev-parse --verify HEAD) cd .. fi -echo "Using eosio ${EOSIO_COMMIT:0:7} from \"$EOSIO_VERSION\"..." -echo "Using cdt ${CDT_COMMIT:0:7} from \"$CDT_VERSION\"..." +if [[ "$EOSIO_COMMIT" == "$EOSIO_VERSION" ]]; then + EOSIO_BK_URL="https://buildkite.com/EOSIO/eosio/builds?commit=${EOSIO_COMMIT}" +else + EOSIO_BK_URL="https://buildkite.com/EOSIO/eosio/builds?branch=${EOSIO_VERSION}" +fi +echo "Using eosio \"$EOSIO_VERSION\"..." +echo "Using cdt ${CDT_COMMIT} from \"$CDT_VERSION\"..." export CDT_URL="https://eos-public-oss-binaries.s3-us-west-2.amazonaws.com/${CDT_COMMIT:0:7}-eosio.cdt-ubuntu-18.04_amd64.deb" \ No newline at end of file diff --git a/.cicd/test.sh b/.cicd/test.sh index 61389035..ea0d181e 100755 --- a/.cicd/test.sh +++ b/.cicd/test.sh @@ -9,7 +9,7 @@ if [[ "$BUILDKITE" == 'true' ]]; then DOCKER_IMAGE="$(buildkite-agent meta-data get docker-image)" else # Actions . ./.cicd/helpers/dependency-info.sh - DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$EOSIO_COMMIT} + DOCKER_IMAGE=${DOCKER_IMAGE:-eosio/ci-contracts-builder:base-ubuntu-18.04-$SANITIZED_EOSIO_VERSION} fi ARGS=${ARGS:-"--rm -v $(pwd):$MOUNTED_DIR"} CDT_COMMANDS="dpkg -i $MOUNTED_DIR/eosio.cdt.deb && export PATH=/usr/opt/eosio.cdt/$CDT_VERSION/bin:\\\$PATH" @@ -18,6 +18,7 @@ TEST_COMMANDS="ctest -j $JOBS --output-on-failure -T Test" COMMANDS="$PRE_COMMANDS && $TEST_COMMANDS" curl -sSf $CDT_URL --output eosio.cdt.deb set +e +echo "docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\"" eval docker run $ARGS $(buildkite-intrinsics) $DOCKER_IMAGE bash -c \"$COMMANDS\" EXIT_STATUS=$? # buildkite From df2d5d1b01221044202334f5dce46be5acc39405 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 7 Feb 2020 23:15:15 +0200 Subject: [PATCH 1015/1048] Add explicit titles --- docs/04_guides/02_how-to-buy-ram.md | 5 +++++ docs/04_guides/03_how-to-stake.md | 5 +++++ docs/04_guides/04_how-to-vote.md | 5 +++++ .../04_guides/05_how-to-create-issue-and-transfer-a-token.md | 5 +++++ .../06_how-to-sign-a-multisig-transaction-with-eosio.msig.md | 5 +++++ docs/04_guides/07_how-to-use-eosio.wrap.md | 5 +++++ 6 files changed, 30 insertions(+) diff --git a/docs/04_guides/02_how-to-buy-ram.md b/docs/04_guides/02_how-to-buy-ram.md index cd808e21..dee6776e 100644 --- a/docs/04_guides/02_how-to-buy-ram.md +++ b/docs/04_guides/02_how-to-buy-ram.md @@ -1,3 +1,8 @@ +--- +content_title: How to buy RAM +link_text: How to buy RAM +--- + # Goal Setup an account that require multiple signatures for signing a transaction diff --git a/docs/04_guides/03_how-to-stake.md b/docs/04_guides/03_how-to-stake.md index 4cfd9893..0413a01a 100644 --- a/docs/04_guides/03_how-to-stake.md +++ b/docs/04_guides/03_how-to-stake.md @@ -1,3 +1,8 @@ +--- +content_title: How to stake +link_text: How to stake +--- + # Goal Stake resource for your account diff --git a/docs/04_guides/04_how-to-vote.md b/docs/04_guides/04_how-to-vote.md index f1a520f6..0141d156 100644 --- a/docs/04_guides/04_how-to-vote.md +++ b/docs/04_guides/04_how-to-vote.md @@ -1,3 +1,8 @@ +--- +content_title: How to vote +link_text: How to vote +--- + # Goal Vote for a block producer diff --git a/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md index 313e8139..a09c63d2 100644 --- a/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -1,3 +1,8 @@ +--- +content_title: How to create, issue and transfer a token +link_text: How to create, issue and transfer a token +--- + ## Step 1: Obtain Contract Source Navigate to your contracts directory. diff --git a/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md index 6c78c0e1..89760cda 100644 --- a/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -1,3 +1,8 @@ +--- +content_title: How to sign a multisig transaction with eosio.msig +link_text: How to sign a multisig transaction with eosio.msig +--- + ## Cleos usage example for issuing tokens. ### Prerequisites: diff --git a/docs/04_guides/07_how-to-use-eosio.wrap.md b/docs/04_guides/07_how-to-use-eosio.wrap.md index 44c404f9..347be4e2 100644 --- a/docs/04_guides/07_how-to-use-eosio.wrap.md +++ b/docs/04_guides/07_how-to-use-eosio.wrap.md @@ -1,3 +1,8 @@ +--- +content_title: How to use eosio.wrap +link_text: How to use eosio.wrap +--- + # 1. Installing the eosio.wrap contract The eosio.wrap contract needs to be installed on a privileged account to function. It is recommended to use the account `eosio.wrap`. From fc3c66d7ee7b3f3330b3a983c68317dd0516d6b8 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Tue, 11 Feb 2020 18:55:20 +0200 Subject: [PATCH 1016/1048] fix a few broken links in eosio.contracts documentation --- docs/01_key-concepts/02_ram.md | 2 +- docs/03_build-and-deploy.md | 4 ++-- docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/01_key-concepts/02_ram.md b/docs/01_key-concepts/02_ram.md index b7ecf26d..63055a46 100644 --- a/docs/01_key-concepts/02_ram.md +++ b/docs/01_key-concepts/02_ram.md @@ -3,7 +3,7 @@ content_title: RAM as resource link_text: RAM as resource --- -RAM is the memory, storage space, where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a `multi-index table`, which is explained [here](https://developers.eos.io/eosio-home/docs/data-persistence) or a `singleton`, its definition can be found [here](https://github.com/EOSIO/eosio.cdt/blob/master/libraries/eosiolib/singleton.hpp) and a sample of its usage [here](https://github.com/EOSIO/eosio.contracts/blob/master/contracts/eosio.system/include/eosio.system/eosio.system.hpp). +RAM is the memory, storage space, where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a `multi-index table`, which is explained [here](https://developers.eos.io/manuals/eosio.cdt/latest/group__multiindex) and its usages [here](https://developers.eos.io/manuals/eosio.cdt/latest/how-to-guides/multi-index) or a `singleton`, with its definition found [here](https://developers.eos.io/manuals/eosio.cdt/latest/group__singleton/#singleton-table) and a sample of its usage [here](https://developers.eos.io/manuals/eosio.cdt/latest/how-to-guides/multi-index/how-to-define-a-singleton). The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM as the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. diff --git a/docs/03_build-and-deploy.md b/docs/03_build-and-deploy.md index 15dab87b..b2db104f 100644 --- a/docs/03_build-and-deploy.md +++ b/docs/03_build-and-deploy.md @@ -4,7 +4,7 @@ link_text: How to build eosio.contracts --- ## Preconditions -Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://github.com/EOSIO/eosio.cdt/tree/master/#binary-releases) to install it. To verify if you have `eosio.cdt` installed and its version run the following command +Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt` from binaries is sufficient, follow the [`eosio.cdt` installation instructions steps](https://developers.eos.io/manuals/eosio.cdt/latest/installation) to install it. To verify if you have `eosio.cdt` installed and its version run the following command ```sh eosio-cpp -v @@ -16,7 +16,7 @@ eosio-cpp -v Run the `build.sh` script in the top directory to build all the contracts. #### To build the contracts and unit tests -1. Ensure an appropriate version of `eosio` has been built from source and installed. Installing `eosio` from binaries `is not` sufficient. You can find instructions on how to do it [here](https://github.com/EOSIO/eos/blob/master/README.md) in section `Building from Sources`. +1. Ensure an appropriate version of `eosio` has been built from source and installed. Installing `eosio` from binaries `is not` sufficient. You can find instructions on how to do it [here](https://developers.eos.io/manuals/eos/latest/install/build-from-source) in section `Building from Sources`. 2. Run the `build.sh` script in the top directory with the `-t` flag to build all the contracts and the unit tests for these contracts. ### Build contracts manually diff --git a/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md index a09c63d2..ca08d5a5 100644 --- a/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -106,7 +106,7 @@ executed transaction: 60d334850151cb95c35fe31ce2e8b536b51441c5fd4c3f2fea98edcc6d # bob <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} warning: transaction executed locally, but may not be confirmed by the network yet ] ``` -Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/eosio-cleos/reference#currency-balance) +Now check if "bob" got the tokens using [cleos get currency balance](https://developers.eos.io/manuals/eos/latest/cleos/command-reference/get/currency-balance) ```shell cleos get currency balance eosio.token bob SYS From 66fccf6dc565fbeaa3ec3c77c2ac9a01aa883f46 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 12 Feb 2020 16:42:55 +0200 Subject: [PATCH 1017/1048] correct the msig how to title --- .../06_how-to-sign-a-multisig-transaction-with-eosio.msig.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md index 89760cda..9a20e7a1 100644 --- a/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -3,7 +3,7 @@ content_title: How to sign a multisig transaction with eosio.msig link_text: How to sign a multisig transaction with eosio.msig --- -## Cleos usage example for issuing tokens. +### eosio.msig ### Prerequisites: - eosio.token contract installed to eosio.token account, eosio.msig contract installed on eosio.msig account which is a priviliged account. From e4ed7639723106fbd889e8901077bd72f1e0d37c Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Mon, 24 Feb 2020 10:15:49 -0500 Subject: [PATCH 1018/1048] Actions now recognizes when all jobs are skipped. --- .github/workflows/main.yml | 9 --------- 1 file changed, 9 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a669a810..c5e10735 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -2,19 +2,10 @@ name: Pull Request on: [pull_request] jobs: - start-job: - name: Start Job - runs-on: ubuntu-latest - steps: - - name: Start Job. - run: echo "PR created. Builds will be triggered here for forked PRs or Buildkite for internal PRs." - - ubuntu-1804-build: if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id name: Ubuntu 18.04 | Build runs-on: ubuntu-latest - needs: start-job steps: - name: Checkout uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e From e9bd3a6154fffff140f539c6f4606681fdc6b7b3 Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Wed, 26 Feb 2020 16:22:46 -0500 Subject: [PATCH 1019/1048] Fix reruns on forked PRs. --- .github/workflows/main.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c5e10735..1aae0f2b 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -8,9 +8,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e - with: - submodules: recursive + run: | + git clone https://github.com/${GITHUB_REPOSITORY} . + git fetch -v --prune origin +refs/pull/${PR_NUMBER}/merge:refs/remotes/pull/${PR_NUMBER}/merge + git checkout --force --progress refs/remotes/pull/${PR_NUMBER}/merge + git submodule sync --recursive + git submodule update --init --force --recursive - name: Build run: | ./.cicd/build.sh @@ -26,9 +29,12 @@ jobs: needs: ubuntu-1804-build steps: - name: Checkout - uses: actions/checkout@50fbc622fc4ef5163becd7fab6573eac35f8462e - with: - submodules: recursive + run: | + git clone https://github.com/${GITHUB_REPOSITORY} . + git fetch -v --prune origin +refs/pull/${PR_NUMBER}/merge:refs/remotes/pull/${PR_NUMBER}/merge + git checkout --force --progress refs/remotes/pull/${PR_NUMBER}/merge + git submodule sync --recursive + git submodule update --init --force --recursive - name: Download Build Artifact uses: actions/download-artifact@v1 with: From 72a6bdd8443087882de50589272e3d9b0815758b Mon Sep 17 00:00:00 2001 From: Scott Arnette Date: Thu, 27 Feb 2020 11:27:38 -0500 Subject: [PATCH 1020/1048] Fix missing env for Actions. --- .github/workflows/main.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1aae0f2b..12bf291e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,9 @@ name: Pull Request on: [pull_request] +env: + PR_NUMBER: ${{ toJson(github.event.number) }} + jobs: ubuntu-1804-build: if: github.event.pull_request.base.repo.id != github.event.pull_request.head.repo.id From 84ca63e58ca8107a024705df589f874ede32b384 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Mon, 9 Mar 2020 14:42:23 +0200 Subject: [PATCH 1021/1048] resolves #1 delete README.md because is redundant with docs information and it is a reminiscence of the past docs structure --- contracts/eosio.system/README.md | 185 ------------------------------- 1 file changed, 185 deletions(-) delete mode 100755 contracts/eosio.system/README.md diff --git a/contracts/eosio.system/README.md b/contracts/eosio.system/README.md deleted file mode 100755 index 9e8c0fa6..00000000 --- a/contracts/eosio.system/README.md +++ /dev/null @@ -1,185 +0,0 @@ -eosio.system ----------- - -This contract provides multiple functionalities: -- Users can stake tokens for CPU and Network bandwidth, and then vote for producers or delegate their vote to a proxy. -- Producers register in order to be voted for, and can claim per-block and per-vote rewards. -- Users can buy and sell RAM at a market-determined price. -- Users can bid on premium names. -- A resource exchange system (REX) allows token holders to lend their tokens, and users to rent CPU and Network resources in return for a market-determined fee. - -Actions: -The naming convention is codeaccount::actionname followed by a list of paramters. - -## eosio::regproducer producer producer_key url location - - Indicates that a particular account wishes to become a producer - - **producer** account registering to be a producer candidate - - **producer_key** producer account public key - - **url** producer URL - - **location** currently unused index - -## eosio::voteproducer voter proxy producers - - **voter** the account doing the voting - - **proxy** proxy account to whom voter delegates vote - - **producers** list of producers voted for. A maximum of 30 producers is allowed - - Voter can vote for a proxy __or__ a list of at most 30 producers. Storage change is billed to `voter`. - -## eosio::regproxy proxy is_proxy - - **proxy** the account registering as voter proxy (or unregistering) - - **is_proxy** if true, proxy is registered; if false, proxy is unregistered - - Storage change is billed to `proxy`. - -## eosio::delegatebw from receiver stake\_net\_quantity stake\_cpu\_quantity transfer - - **from** account holding tokens to be staked - - **receiver** account to whose resources staked tokens are added - - **stake\_net\_quantity** tokens staked for NET bandwidth - - **stake\_cpu\_quantity** tokens staked for CPU bandwidth - - **transfer** if true, ownership of staked tokens is transfered to `receiver` - - All producers `from` account has voted for will have their votes updated immediately. - -## eosio::undelegatebw from receiver unstake\_net\_quantity unstake\_cpu\_quantity - - **from** account whose tokens will be unstaked - - **receiver** account to whose benefit tokens have been staked - - **unstake\_net\_quantity** tokens to be unstaked from NET bandwidth - - **unstake\_cpu\_quantity** tokens to be unstaked from CPU bandwidth - - Unstaked tokens are transferred to `from` liquid balance via a deferred transaction with a delay of 3 days. - - If called during the delay period of a previous `undelegatebw` action, pending action is canceled and timer is reset. - - All producers `from` account has voted for will have their votes updated immediately. - - Bandwidth and storage for the deferred transaction are billed to `from`. - -## eosio::onblock header - - This special action is triggered when a block is applied by a given producer, and cannot be generated from - any other source. It is used increment the number of unpaid blocks by a producer and update producer schedule. - -## eosio::claimrewards producer - - **producer** producer account claiming per-block and per-vote rewards - -## eosio::deposit owner amount - - Deposits tokens to user REX fund - - **owner** REX fund owner account - - **amount** amount of tokens to be deposited - - An inline transfer from 'owner' liquid balance is executed. - - All REX-related costs and proceeds are deducted from and added to 'owner' REX fund, with one exception being buying REX using staked tokens. - - Storage change is billed to 'owner'. - -## eosio::withdraw owner amount - - Withdraws tokens from user REX fund - - **owner** REX fund owner account - - **amount** amount of tokens to be withdrawn - - An inline transfer to 'owner' liquid balance is executed. - -## eosio::buyrex from amount - - Buys REX in exchange for tokens taken out of user REX fund - - **from** owner account name - - **amount** amount of tokens to be used for purchase - - 'amount' tokens are taken out of 'from' REX fund. - - User must vote for at least 21 producers or delegate vote to proxy before buying REX. - - Tokens used in purchase are added to user's voting power. - - Bought REX cannot be sold before 4 days counting from end of day of purchase. - - Storage change is billed to 'from' account. - - By buying REX, user is lending tokens in order to be rented as CPU or NET resourses. - -## eosio::unstaketorex owner receiver from\_net from\_cpu - - Buys REX using staked tokens - - **owner** owner of staked tokens - - **receiver** account name that tokens have previously been staked to - - **from_net** amount of tokens to be unstaked from NET bandwidth and used for REX purchase - - **from_cpu** amount of tokens to be unstaked from CPU bandwidth and used for REX purchase - - User must vote for at least 21 producers or delegate vote to proxy before buying REX. - - Tokens used in purchase are added to user's voting power. - - Bought REX cannot be sold before 4 days counting from end of day of purchase. - - Storage change is billed to 'owner' account. - -## eosio::sellrex from rex - - Sells REX in exchange for core tokens - - **from** owner account of REX - - **rex** amount of REX to be sold - - Proceeds are deducted from user's voting power. - - If cannot be processed immediately, sell order is added to a queue and will be processed within 30 days at most. - - In case sell order is queued, storage change is billed to 'from' account. - -## eosio::cnclrexorder owner - - Cancels unfilled REX sell order by owner if one exists. - - **owner** owner account name - -## eosio::mvtosavings owner rex - - Moves REX to owner's REX savings bucket - - REX held in savings bucket does not mature and cannot be sold directly - - REX is moved out from the owner's maturity buckets as necessary starting with the bucket with furthest maturity date - - **owner** owner account of REX - - **rex** amount of REX to be moved to savings bucket - -## eosio::mvfrsavings owner rex - - Moves REX from owner's savings bucket to a bucket with a maturity date that is 4 days after the end of the day - - This action is required if the owner wants to sell REX held in savings bucket - - **owner** owner account of REX - - **rex** amount of REX to be moved from savings bucket - -## eosio::rentcpu from receiver loan\_payment loan\_fund - - Rents CPU resources for 30 days in exchange for market-determined price - - **from** account creating and paying for CPU loan - - **receiver** account receiving rented CPU resources - - **loan_payment** tokens paid for the loan - - **loan_fund** additional tokens (can be zero) added to loan fund and used later for loan renewal - - Rents as many core tokens as determined by market price and stakes them for CPU bandwidth for the benefit of `receiver` account. - - `loan_payment` is used for renting, it has to be greater than zero. Amount of rented resources is calculated from `loan_payment`. - - After 30 days the rented core delegation of CPU will expire or be renewed at new market price depending on available loan fund. - - `loan_fund` can be zero, and is added to loan balance. Loan balance represents a reserve that is used at expiration for automatic loan renewal. - - 'from' account can add tokens to loan balance using action `fundcpuloan` and withdraw from loan balance using `defcpuloan`. - - At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user is refunded any remaining balance. - -## eosio::rentnet from receiver loan\_payment loan\_fund - - Rents Network resources for 30 days in exchange for market-determined price - - **from** account creating and paying for Network loan - - **receiver** account receiving rented Network resources - - **loan_payment** tokens paid for the loan - - **loan_fund** additional tokens (can be zero) added to loan fund and used later for loan renewal - - Rents as many core tokens as determined by market price and stakes them for Network bandwidth for the benefit of `receiver` account. - - `loan_payment` is used for renting, it has to be greater than zero. Amount of rented resources is calculated from `loan_payment`. - - After 30 days the rented core delegation of Network will expire or be renewed at new market price depending on available loan fund. - - `loan_fund` can be zero, and is added to loan balance. Loan balance represents a reserve that is used at expiration for automatic loan renewal. - - 'from' account can add tokens to loan balance using action `fundnetloan` and withdraw from loan balance using `defnetloan`. - - At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user is refunded any remaining balance. - -## eosio::fundcpuloan from loan\_num payment - - Transfers tokens from REX fund to the fund of a specific CPU loan in order to be used for loan renewal at expiry - - **from** loan creator account - - **loan_num** loan id - - **payment** tokens transfered from REX fund to loan fund - -## eosio::fundnetloan from loan\_num payment - - Transfers tokens from REX fund to the fund of a specific Network loan in order to be used for loan renewal at expiry - - **from** loan creator account - - **loan_num** loan id - - **payment** tokens transfered from REX fund to loan fund - -## eosio::defcpuloan from loan\_num amount - - Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund - - **from** loan creator account - - **loan_num** loan id - - **amount** tokens transfered from CPU loan fund to REX fund - -## eosio::defcpuloan from loan\_num amount - - Withdraws tokens from the fund of a specific CPU loan and adds them to REX fund - - **from** loan creator account - - **loan_num** loan id - - **amount** tokens transfered from NET loan fund to REX fund - -## eosio::updaterex owner - - Updates REX owner vote weight to current value of held REX - - **owner** REX owner account - -## eosio::rexexec user max - - Performs REX maintenance by processing a specified number of REX sell orders and expired loans - - **user** any account can execute this action - - **max** number of each of CPU loans, NET loans, and sell orders to be processed - -## eosio::consolidate owner - - Consolidates REX maturity buckets into one bucket that cannot be sold before 4 days - - **owner** REX owner account name - -## eosio::closerex owner - - Deletes unused REX-related database entries and frees occupied RAM - - **owner** user account name - - If owner has a non-zero REX balance, the action fails; otherwise, owner REX balance entry is deleted. - - If owner has no outstanding loans and a zero REX fund balance, REX fund entry is deleted. From 1a474c7f334a45ef3f6448cb657bce0716b77cc7 Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Mon, 9 Mar 2020 22:46:55 -0400 Subject: [PATCH 1022/1048] fix build and deploy link in README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b8a32ae4..21ecb632 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,9 @@ Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0) * [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.1) (optional dependency only needed to build unit tests) -To build the contracts follow the instructions in [`Build and deploy` section](./docs/02_build-and-deploy.md). +## Build + +To build the contracts follow the instructions in [Build and deploy](https://developers.eos.io/manuals/eosio.contracts/latest/build-and-deploy) section. ## Contributing From dd4f523c21cf431abcdf26e057fba80d500cd716 Mon Sep 17 00:00:00 2001 From: arhag Date: Wed, 20 May 2020 16:21:25 -0400 Subject: [PATCH 1023/1048] use yield function to fix tests to work with EOSIO v2.0.5 and later --- tests/eosio.msig_tests.cpp | 12 ++++---- tests/eosio.system_tester.hpp | 54 +++++++++++++++++------------------ tests/eosio.system_tests.cpp | 32 ++++++++++----------- tests/eosio.token_tests.cpp | 8 +++--- tests/eosio.wrap_tests.cpp | 6 ++-- 5 files changed, 56 insertions(+), 56 deletions(-) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp index cbc614b9..89f7dbc9 100644 --- a/tests/eosio.msig_tests.cpp +++ b/tests/eosio.msig_tests.cpp @@ -36,7 +36,7 @@ class eosio_msig_tester : public tester { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); } transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, @@ -138,7 +138,7 @@ class eosio_msig_tester : public tester { action act; act.account = N(eosio.msig); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); //std::cout << "test:\n" << fc::to_hex(act.data.data(), act.data.size()) << " size = " << act.data.size() << std::endl; return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : 0 ); @@ -174,7 +174,7 @@ transaction eosio_msig_tester::reqauth( account_name from, const vectordb().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi, abi_serializer_max_time); + token_abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); } } @@ -69,7 +69,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); } } @@ -273,7 +273,7 @@ class eosio_system_tester : public TESTER { action act; act.account = config::system_account_name; act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); } @@ -580,7 +580,7 @@ class eosio_system_tester : public TESTER { data.resize( itr->value.size() ); memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_last_cpu_loan() { @@ -594,7 +594,7 @@ class eosio_system_tester : public TESTER { fc::variant get_loan_info( const uint64_t& loan_num, bool cpu ) const { name table_name = cpu ? N(cpuloan) : N(netloan); vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, account_name(loan_num) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_cpu_loan( const uint64_t loan_num ) const { @@ -607,42 +607,42 @@ class eosio_system_tester : public TESTER { fc::variant get_dbw_obj( const account_name& from, const account_name& receiver ) const { vector data = get_row_by_account( config::system_account_name, from, N(delband), receiver ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant("delegated_bandwidth", data, abi_serializer_max_time); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant("delegated_bandwidth", data, abi_serializer::create_yield_function(abi_serializer_max_time)); } asset get_rex_balance( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["rex_balance"].as(); + return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time))["rex_balance"].as(); } fc::variant get_rex_balance_obj( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time)); } asset get_rex_fund( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); - return data.empty() ? asset(0, symbol{CORE_SYM}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer_max_time)["balance"].as(); + return data.empty() ? asset(0, symbol{CORE_SYM}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer::create_yield_function(abi_serializer_max_time))["balance"].as(); } fc::variant get_rex_fund_obj( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_fund", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_fund", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } asset get_rex_vote_stake( const account_name& act ) const { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? core_sym::from_string("0.0000") : abi_ser.binary_to_variant("rex_balance", data, abi_serializer_max_time)["vote_stake"].as(); + return data.empty() ? core_sym::from_string("0.0000") : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time))["vote_stake"].as(); } fc::variant get_rex_order( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); - return abi_ser.binary_to_variant( "rex_order", data, abi_serializer_max_time ); + return abi_ser.binary_to_variant( "rex_order", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_rex_order_obj( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_order", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_order", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_rex_pool() const { @@ -663,7 +663,7 @@ class eosio_system_tester : public TESTER { data.resize( itr->value.size() ); memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_rex_return_pool() const { @@ -684,7 +684,7 @@ class eosio_system_tester : public TESTER { data.resize( itr->value.size() ); memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_rex_return_buckets() const { @@ -705,7 +705,7 @@ class eosio_system_tester : public TESTER { data.resize( itr->value.size() ); memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_buckets", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_buckets", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } void setup_rex_accounts( const std::vector& accounts, @@ -793,7 +793,7 @@ class eosio_system_tester : public TESTER { asset get_balance( const account_name& act, symbol balance_symbol = symbol{CORE_SYM} ) { vector data = get_row_by_account( N(eosio.token), act, N(accounts), account_name(balance_symbol.to_symbol_code().value) ); - return data.empty() ? asset(0, balance_symbol) : token_abi_ser.binary_to_variant("account", data, abi_serializer_max_time)["balance"].as(); + return data.empty() ? asset(0, balance_symbol) : token_abi_ser.binary_to_variant("account", data, abi_serializer::create_yield_function(abi_serializer_max_time))["balance"].as(); } asset get_balance( std::string_view act, symbol balance_symbol = symbol{CORE_SYM} ) { @@ -802,7 +802,7 @@ class eosio_system_tester : public TESTER { fc::variant get_total_stake( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_total_stake( std::string_view act ) { return get_total_stake( account_name(act) ); @@ -810,7 +810,7 @@ class eosio_system_tester : public TESTER { fc::variant get_voter_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_voter_info( std::string_view act ) { return get_voter_info( account_name(act) ); @@ -818,7 +818,7 @@ class eosio_system_tester : public TESTER { fc::variant get_producer_info( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data, abi_serializer_max_time ); + return abi_ser.binary_to_variant( "producer_info", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_producer_info( std::string_view act ) { return get_producer_info( account_name(act) ); @@ -826,7 +826,7 @@ class eosio_system_tester : public TESTER { fc::variant get_producer_info2( const account_name& act ) { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers2), act ); - return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer_max_time ); + return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_producer_info2( std::string_view act ) { return get_producer_info2( account_name(act) ); @@ -920,7 +920,7 @@ class eosio_system_tester : public TESTER { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } asset get_token_supply() { @@ -934,22 +934,22 @@ class eosio_system_tester : public TESTER { fc::variant get_global_state() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); if (data.empty()) std::cout << "\nData is empty\n" << std::endl; - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_global_state2() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_global_state3() { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global3), N(global3) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_refund_request( name account ) { vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } abi_serializer initialize_multisig() { @@ -972,7 +972,7 @@ class eosio_system_tester : public TESTER { const auto& accnt = control->db().get( N(eosio.msig) ); abi_def msig_abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi, abi_serializer_max_time); + msig_abi_ser.set_abi(msig_abi, abi_serializer::create_yield_function(abi_serializer_max_time)); } return msig_abi_ser; } diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp index 08497875..dbbf46d4 100644 --- a/tests/eosio.system_tests.cpp +++ b/tests/eosio.system_tests.cpp @@ -133,7 +133,7 @@ BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ); BOOST_REQUIRE( !data.empty() ); - return abi_ser.binary_to_variant("exchange_state", data, abi_serializer_max_time); + return abi_ser.binary_to_variant("exchange_state", data, abi_serializer::create_yield_function(abi_serializer_max_time)); }; { @@ -1738,7 +1738,7 @@ BOOST_AUTO_TEST_CASE(extreme_inflation) try { asset current_supply; { vector data = t.get_row_by_account( N(eosio.token), name(core_symbol.to_symbol_code().value), N(stat), account_name(core_symbol.to_symbol_code().value) ); - current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, eosio_system_tester::abi_serializer_max_time)["supply"].template as(); + current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, abi_serializer::create_yield_function(eosio_system_tester::abi_serializer_max_time))["supply"].template as(); } t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply ); BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(std::numeric_limits::max(), 50000, 40000)); @@ -2658,7 +2658,7 @@ BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) const auto& accnt = t.control->db().get( config::system_account_name ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - t.abi_ser.set_abi(abi, eosio_system_tester::abi_serializer_max_time); + t.abi_ser.set_abi(abi, abi_serializer::create_yield_function(eosio_system_tester::abi_serializer_max_time)); } const asset net = old_core_from_string("80.0000"); const asset cpu = old_core_from_string("80.0000"); @@ -2732,7 +2732,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); }; @@ -2771,7 +2771,7 @@ BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -3514,7 +3514,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { action act; act.account = N(eosio.msig); act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer_max_time ); + act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); }; @@ -3550,7 +3550,7 @@ BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { ) }) ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer_max_time); + abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); } BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() @@ -5514,7 +5514,7 @@ BOOST_AUTO_TEST_CASE( setabi_bios ) try { validating_tester t( tempdir, true ); t.execute_setup_policy( setup_policy::full ); - abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), base_tester::abi_serializer_max_time); + abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); t.set_code( config::system_account_name, contracts::bios_wasm() ); t.set_abi( config::system_account_name, contracts::bios_abi().data() ); t.create_account(N(eosio.token)); @@ -5522,8 +5522,8 @@ BOOST_AUTO_TEST_CASE( setabi_bios ) try { { auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, base_tester::abi_serializer_max_time ); - abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), base_tester::abi_serializer_max_time); + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(base_tester::abi_serializer_max_time) ); + abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); @@ -5534,8 +5534,8 @@ BOOST_AUTO_TEST_CASE( setabi_bios ) try { { auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, base_tester::abi_serializer_max_time ); - abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), base_tester::abi_serializer_max_time); + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(base_tester::abi_serializer_max_time) ); + abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); @@ -5548,8 +5548,8 @@ BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { { auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(abi_serializer_max_time) ); + abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); @@ -5560,8 +5560,8 @@ BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { { auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer_max_time ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer_max_time); + auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(abi_serializer_max_time) ); + abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 9a1d8219..23de001a 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -33,7 +33,7 @@ class eosio_token_tester : public tester { const auto& accnt = control->db().get( N(eosio.token) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); } action_result push_action( const account_name& signer, const action_name &name, const variant_object &data ) { @@ -42,7 +42,7 @@ class eosio_token_tester : public tester { action act; act.account = N(eosio.token); act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data,abi_serializer_max_time ); + act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); return base_tester::push_action( std::move(act), signer.to_uint64_t() ); } @@ -52,7 +52,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } fc::variant get_account( account_name acc, const string& symbolname) @@ -60,7 +60,7 @@ class eosio_token_tester : public tester { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; vector data = get_row_by_account( N(eosio.token), acc, N(accounts), account_name(symbol_code) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer_max_time ); + return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } action_result create( account_name issuer, diff --git a/tests/eosio.wrap_tests.cpp b/tests/eosio.wrap_tests.cpp index e7b7cb03..1f462bb8 100644 --- a/tests/eosio.wrap_tests.cpp +++ b/tests/eosio.wrap_tests.cpp @@ -77,7 +77,7 @@ class eosio_wrap_tester : public tester { const auto& accnt = control->db().get( N(eosio.wrap) ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer_max_time); + abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); while( control->pending_block_producer().to_string() == "eosio" ) { produce_block(); @@ -134,7 +134,7 @@ transaction eosio_wrap_tester::wrap_exec( account_name executer, const transacti transaction trx2; set_transaction_headers(trx2, expiration); action act; - abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer_max_time ); + abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time) ); trx2.actions.push_back( std::move(act) ); return trx2; } @@ -155,7 +155,7 @@ transaction eosio_wrap_tester::reqauth( account_name from, const vector Date: Wed, 27 May 2020 15:06:42 +0300 Subject: [PATCH 1024/1048] fixes #481 --- docs/01_key-concepts/02_ram.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/01_key-concepts/02_ram.md b/docs/01_key-concepts/02_ram.md index 63055a46..d1c782b1 100644 --- a/docs/01_key-concepts/02_ram.md +++ b/docs/01_key-concepts/02_ram.md @@ -7,6 +7,6 @@ RAM is the memory, storage space, where the blockchain stores data. If your cont The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM as the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per day, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications; also RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per block, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications. RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). \ No newline at end of file From d44e7e8048349dd378180fb8cc391116cf872fbf Mon Sep 17 00:00:00 2001 From: iamveritas Date: Wed, 12 Feb 2020 16:40:51 +0200 Subject: [PATCH 1025/1048] update links and clean up annotations --- contracts/eosio.system/include/eosio.system/native.hpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp index ca885347..a0931cde 100644 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ b/contracts/eosio.system/include/eosio.system/native.hpp @@ -127,7 +127,6 @@ namespace eosiosystem { using eosio::contract::contract; /** - * @{ * These actions map one-on-one with the ones defined in core layer of EOSIO, that's where their implementation * actually is done. * They are present here only so they can show up in the abi file and thus user can send them @@ -249,8 +248,6 @@ namespace eosiosystem { [[eosio::action]] void setcode( const name& account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} - /** @}*/ - using newaccount_action = eosio::action_wrapper<"newaccount"_n, &native::newaccount>; using updateauth_action = eosio::action_wrapper<"updateauth"_n, &native::updateauth>; using deleteauth_action = eosio::action_wrapper<"deleteauth"_n, &native::deleteauth>; From ec98a8a92e979d826b293ddbd9a0fddfe37e1bd8 Mon Sep 17 00:00:00 2001 From: iamveritas Date: Thu, 4 Jun 2020 13:12:02 +0300 Subject: [PATCH 1026/1048] fixes #491 --- docs/01_key-concepts/02_ram.md | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/docs/01_key-concepts/02_ram.md b/docs/01_key-concepts/02_ram.md index d1c782b1..afa832f8 100644 --- a/docs/01_key-concepts/02_ram.md +++ b/docs/01_key-concepts/02_ram.md @@ -3,10 +3,30 @@ content_title: RAM as resource link_text: RAM as resource --- -RAM is the memory, storage space, where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a `multi-index table`, which is explained [here](https://developers.eos.io/manuals/eosio.cdt/latest/group__multiindex) and its usages [here](https://developers.eos.io/manuals/eosio.cdt/latest/how-to-guides/multi-index) or a `singleton`, with its definition found [here](https://developers.eos.io/manuals/eosio.cdt/latest/group__singleton/#singleton-table) and a sample of its usage [here](https://developers.eos.io/manuals/eosio.cdt/latest/how-to-guides/multi-index/how-to-define-a-singleton). +## What is RAM + +RAM is the memory, the storage space, where the blockchain stores data. If your contract needs to store data on the blockchain, like in a database, then it can store it in the blockchain's RAM using either a `multi-index table` or a `singleton`. + +### Related documentation articles + +- Multi-index table [explainer documentation page](https://developers.eos.io/manuals/eosio.cdt/latest/group__multiindex) + +- Multi-index table [how to documentation page](https://developers.eos.io/manuals/eosio.cdt/latest/how-to-guides/multi-index) + +- Singleton [reference documentation page](https://developers.eos.io/manuals/eosio.cdt/latest/group__singleton/#singleton-table) + +- Singleton [how to documentation page](https://developers.eos.io/manuals/eosio.cdt/latest/how-to-guides/multi-index/how-to-define-a-singleton) + +## RAM High Performance The EOSIO-based blockchains are known for their high performance, which is achieved also because the data stored on the blockchain is using RAM as the storage medium, and thus access to blockchain data is very fast, helping the performance benchmarks to reach levels no other blockchain has been able to. -RAM is a very important resource because of the following reasons: it is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM, for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KiB (1024 bytes) per block, thus increasing constantly the supply of RAM for the price of RAM to not grow too high because of the increased demand from blockchain applications. RAM it is used in executing many actions that are available on the blockchain, creating a new account for example (it needs to store in the blockchain memory the new account's information), also when an account accepts a new type of token a new record has to be created somewhere in the blockchain memory that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. +## RAM Importance + +RAM is a very important resource because of the following reasons + +- It is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM; for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KB per block, thus increasing constantly the supply of RAM for its price to not grow too high due to the increased demand from blockchain applications. + +- RAM is used in executing many actions sent to the blockchain; creating a new account action, for example, it needs to store in the blockchain memory the new account's information; also when an account accepts a new type of token a new record has to be created, somewhere in the blockchain memory, that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). \ No newline at end of file From 3c5c876ea8d55d4109744bc57f1bf4fb89b3d3c8 Mon Sep 17 00:00:00 2001 From: Jeffrey Smith II Date: Wed, 17 Jun 2020 15:19:58 -0400 Subject: [PATCH 1027/1048] Fix compilation with CDT develop --- contracts/eosio.system/src/delegate_bandwidth.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp index d15a8202..a64506c0 100644 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ b/contracts/eosio.system/src/delegate_bandwidth.cpp @@ -8,9 +8,6 @@ #include #include -#include "name_bidding.cpp" -// Unfortunately, this is needed until CDT fixes the duplicate symbol error with eosio::send_deferred - namespace eosiosystem { using eosio::asset; From 5bbbc650af32e4207fce67aa68d2d27c9f1f268f Mon Sep 17 00:00:00 2001 From: Jeffrey Smith II Date: Mon, 29 Jun 2020 15:46:58 -0400 Subject: [PATCH 1028/1048] Add missing file to CMakeLists --- contracts/eosio.system/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index 3f909084..a1642fa2 100644 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -2,6 +2,7 @@ add_contract(eosio.system eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/delegate_bandwidth.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/exchange_state.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/name_bidding.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp From 70c3b55fdec0d17835363fd905163b5f0c7aae04 Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Fri, 25 Sep 2020 17:40:38 -0400 Subject: [PATCH 1029/1048] fix shell prompt and codeblocks on upgrading system contract --- .../01_upgrading-the-eosio.system-contract.md | 47 +++++++++++++------ 1 file changed, 32 insertions(+), 15 deletions(-) diff --git a/docs/04_guides/01_upgrading-the-eosio.system-contract.md b/docs/04_guides/01_upgrading-the-eosio.system-contract.md index 51f49375..8196453f 100644 --- a/docs/04_guides/01_upgrading-the-eosio.system-contract.md +++ b/docs/04_guides/01_upgrading-the-eosio.system-contract.md @@ -21,8 +21,10 @@ Each of the top 21 block producers should do the following: 1. Get current system contract for later comparison (actual hash and ABI on the main-net blockchain will be different): +```sh +cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio ``` -$ cleos get code -c original_system_contract.wast -a original_system_contract.abi eosio +```console code hash: cc0ffc30150a07c487d8247a484ce1caf9c95779521d8c230040c2cb0e2a3a60 saving wast to original_system_contract.wast saving abi to original_system_contract.abi @@ -30,13 +32,13 @@ saving abi to original_system_contract.abi 2. Generate the unsigned transaction which upgrades the system contract: -``` -$ cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json +```sh +cleos set contract -s -j -d eosio contracts/eosio.system | tail -n +4 > upgrade_system_contract_trx.json ``` The first few lines of the generated file should be something similar to (except with very different numbers for `expiration`, `ref_block_num`, and `ref_block_prefix`): -``` +```json { "expiration": "2018-06-15T22:17:10", "ref_block_num": 4552, @@ -57,7 +59,7 @@ The first few lines of the generated file should be something similar to (except and the last few lines should be: -``` +```json } ], "transaction_extensions": [], @@ -76,8 +78,10 @@ Then each of the top 21 block producers should do the following: 5. Compare their generated `upgrade_system_contract_official_trx.json` file with the `upgrade_system_contract_official_trx.json` provided by the lead producer. The only difference should be in `expiration`, `ref_block_num`, `ref_block_prefix`, for example: +```sh +diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json ``` -$ diff upgrade_system_contract_official_trx.json upgrade_system_contract_trx.json +```json 2,4c2,4 < "expiration": "2018-06-15T22:17:10", < "ref_block_num": 4552, @@ -94,8 +98,10 @@ First, the block producer should collect all the necessary information. Let us a Then on a secure computer the producer can sign the transaction (the producer will need to paste in their private key when prompted): +```sh +cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 ``` -$ cleos sign --chain-id d0242fb30b71b82df9966d10ff6d09e4f5eb6be7ba85fd78f796937f1959315e upgrade_system_contract_trx.json | tail -n 5 +```json private key: "signatures": [ "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5" ], @@ -111,8 +117,10 @@ When the lead producer collects 15 producer signatures, the lead producer should 7. Make a copy of the `upgrade_system_contract_official_trx.json` and call it `upgrade_system_contract_official_trx_signed.json`, and then modify the `upgrade_system_contract_official_trx_signed.json` so that the `signatures` field includes all 15 collected signatures. So the tail end of `upgrade_system_contract_official_trx_signed.json` could look something like: +```sh +cat upgrade_system_contract_official_trx_signed.json | tail -n 20 ``` -$ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 +```json "transaction_extensions": [], "signatures": [ "SIG_K1_JzABB9gzDGwUHaRmox68UNcfxMVwMnEXqqS1MvtsyUX8KGTbsZ5aZQZjHD5vREQa5BkZ7ft8CceLBLAj8eZ5erZb9cHuy5", @@ -137,8 +145,10 @@ $ cat upgrade_system_contract_official_trx_signed.json | tail -n 20 8. Push the signed transaction to the blockchain: +```sh +cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json ``` -$ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed.json +```json { "transaction_id": "202888b32e7a0f9de1b8483befac8118188c786380f6e62ced445f93fb2b1041", "processed": { @@ -157,7 +167,7 @@ $ cleos push transaction --skip-sign upgrade_system_contract_official_trx_signed If you get an error message like the following: -``` +```console Error 3090003: provided keys, permissions, and delays do not satisfy declared authorizations Ensure that you have the related private keys inside your wallet and your wallet is unlocked. ``` @@ -166,7 +176,7 @@ That means that at least one of the signatures provided were bad. This may be be If you get an error message like the following: -``` +```console Error 3090002: irrelevant signature included Please remove the unnecessary signature from your transaction! ``` @@ -175,7 +185,7 @@ That means unnecessary signatures were included. If there are 21 active producer If you get an error message like the following: -``` +```console Error 3040006: Transaction Expiration Too Far Please decrease the expiration time of your transaction! ``` @@ -184,7 +194,7 @@ That means that the expiration time is more than 1 hour in the future and you ne If you get an error message like the following: -``` +```console Error 3040005: Expired Transaction Please increase the expiration time of your transaction! ``` @@ -193,12 +203,19 @@ That means the expiration time of the signed transaction has passed and this ent 9. Assuming the transaction successfully executes, everyone can then verify that the new contract is in place: +```sh +cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio ``` -$ cleos get code -c new_system_contract.wast -a new_system_contract.abi eosio +```console code hash: 9fd195bc5a26d3cd82ae76b70bb71d8ce83dcfeb0e5e27e4e740998fdb7b98f8 saving wast to new_system_contract.wast saving abi to new_system_contract.abi -$ diff original_system_contract.abi new_system_contract.abi +``` + +```sh +diff original_system_contract.abi new_system_contract.abi +``` +```json 584,592d583 < },{ < "name": "deferred_trx_id", From 1faf34ea9b1abe3532f9ebdaca3258e8bd58f84e Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Fri, 25 Sep 2020 17:43:49 -0400 Subject: [PATCH 1030/1048] fix shell prompt and codeblocks on how-to create issue transfer token --- ...ow-to-create-issue-and-transfer-a-token.md | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md index ca08d5a5..0a2bf436 100644 --- a/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md +++ b/docs/04_guides/05_how-to-create-issue-and-transfer-a-token.md @@ -7,16 +7,16 @@ link_text: How to create, issue and transfer a token Navigate to your contracts directory. -```text +```sh cd CONTRACTS_DIR ``` Pull the source -```text +```sh git clone https://github.com/EOSIO/eosio.contracts --branch master --single-branch ``` -```text +```sh cd eosio.contracts/contracts/eosio.token ``` @@ -41,7 +41,7 @@ cleos set contract eosio.token CONTRACTS_DIR/eosio.contracts/contracts/eosio.tok ``` Result should look similar to the one below: -```shell +```console Reading WASM from ... Publishing contract... executed transaction: 69c68b1bd5d61a0cc146b11e89e11f02527f24e4b240731c4003ad1dc0c87c2c 9696 bytes 6290 us @@ -57,7 +57,7 @@ cleos push action eosio.token create '[ "eosio", "1000000000.0000 SYS"]' -p eosi ``` Result should look similar to the one below: -```shell +```console executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} ``` @@ -69,7 +69,7 @@ cleos push action eosio.token create '{"issuer":"eosio", "maximum_supply":"10000 ``` Result should look similar to the one below: -```shell +```console executed transaction: 0e49a421f6e75f4c5e09dd738a02d3f51bd18a0cf31894f68d335cd70d9c0e12 120 bytes 1000 cycles # eosio.token <= eosio.token::create {"issuer":"eosio","maximum_supply":"1000000000.0000 SYS"} ``` @@ -79,12 +79,12 @@ This command created a new token `SYS` with a precision of 4 decimals and a maxi The issuer can issue new tokens to the issuer account in our case `eosio`. -```text +```sh cleos push action eosio.token issue '[ "eosio", "100.0000 SYS", "memo" ]' -p eosio@active ``` Result should look similar to the one below: -```shell +```console executed transaction: a26b29d66044ad95edf0fc04bad3073e99718bc26d27f3c006589adedb717936 128 bytes 337 us # eosio.token <= eosio.token::issue {"to":"eosio","quantity":"100.0000 SYS","memo":"memo"} warning: transaction executed locally, but may not be confirmed by the network yet ] @@ -99,7 +99,7 @@ cleos push action eosio.token transfer '[ "eosio", "bob", "25.0000 SYS", "m" ]' ``` Result should look similar to the one below: -```text +```console executed transaction: 60d334850151cb95c35fe31ce2e8b536b51441c5fd4c3f2fea98edcc6d69f39d 128 bytes 497 us # eosio.token <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} # eosio <= eosio.token::transfer {"from":"eosio","to":"bob","quantity":"25.0000 SYS","memo":"m"} @@ -113,7 +113,7 @@ cleos get currency balance eosio.token bob SYS ``` Result: -```text +```console 25.00 SYS ``` @@ -124,6 +124,6 @@ cleos get currency balance eosio.token eosio SYS ``` Result: -```text +```console 75.00 SYS ``` \ No newline at end of file From 8fa6b79d532e05b34104d964a7871615caed9bc9 Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Fri, 25 Sep 2020 18:14:53 -0400 Subject: [PATCH 1031/1048] fix shell prompt and codeblocks on how-to sign multisig --- ...-a-multisig-transaction-with-eosio.msig.md | 86 +++++++++++-------- 1 file changed, 50 insertions(+), 36 deletions(-) diff --git a/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md index 9a20e7a1..6014c9ba 100644 --- a/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md +++ b/docs/04_guides/06_how-to-sign-a-multisig-transaction-with-eosio.msig.md @@ -12,16 +12,19 @@ link_text: How to sign a multisig transaction with eosio.msig - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. ### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester - +```sh +cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token issue '{"to": "tester", "quantity": "1000.0000 SYS", "memo": ""}' -p tester +``` +```console executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` +``` ### Another user reviews the transaction: -```` -$ cleos multisig review tester test +```sh +cleos multisig review tester test +``` +```json { "proposal_name": "test", "requested_approvals": [{ @@ -58,23 +61,25 @@ $ cleos multisig review tester test ] } } -```` +``` ### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - +```sh +cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury +``` +```console executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` +``` ### First user initiates execution: -```` -$ cleos multisig exec tester test -p tester - +```sh +cleos multisig exec tester test -p tester +``` +```console executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles # eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` +``` ## Cleos usage example for transferring tokens. @@ -86,16 +91,19 @@ executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e - keys to accounts 'treasury' and 'tester' imported into local wallet, the wallet is unlocked. ### One user creates a proposal: -```` -$ cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester - +```sh +cleos multisig propose test '[{"actor": "treasury", "permission": "active"}]' '[{"actor": "treasury", "permission": "active"}]' eosio.token transfer '{"from": "treasury", "to": "tester", "quantity": "1.0000 SYS", "memo": ""}' -p tester +``` +```console executed transaction: e26f3a3a7cba524a7b15a0b6c77c7daa73d3ba9bf84e83f9c2cdf27fcb183d61 336 bytes 107520 cycles # eosio.msig <= eosio.msig::propose {"proposer":"tester","proposal_name":"test","requested":[{"actor":"treasury","permission":"active"}]... -```` +``` ### Another user reviews the transaction: -```` -$ cleos multisig review tester test +```sh +cleos multisig review tester test +``` +```json { "proposal_name": "test", "requested_approvals": [{ @@ -133,42 +141,48 @@ $ cleos multisig review tester test ] } } -```` +``` ### And then approves it: -```` -$ cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury - +```sh +cleos multisig approve tester test '{"actor": "treasury", "permission": "active"}' -p treasury +``` +```console executed transaction: 475970a4b0016368d0503d1ce01577376f91f5a5ba63dd4353683bd95101b88d 256 bytes 108544 cycles # eosio.msig <= eosio.msig::approve {"proposer":"tester","proposal_name":"test","level":{"actor":"treasury","permission":"active"}} -```` +``` ### First user check account balance before executing the proposed transaction -```` -$ cleos get account tester +```sh +cleos get account tester +``` +```console ... SYS balances: liquid: 1.0487 SYS staked: 2.0000 SYS unstaking: 0.0000 SYS total: 4.0487 SYS -```` +``` ### First user initiates execution of proposed transaction: -```` -$ cleos multisig exec tester test -p tester - +```sh +cleos multisig exec tester test -p tester +``` +```console executed transaction: 64e5eaceb77362694055f572ae35876111e87b637a55250de315b1b55e56d6c2 248 bytes 109568 cycles # eosio.msig <= eosio.msig::exec {"proposer":"tester","proposal_name":"test","executer":"tester"} -```` +``` ### First user can check account balance, it should be increased by 1.0000 SYS -```` -$ cleos get account tester +```sh +cleos get account tester +``` +```console ... SYS balances: liquid: 2.0487 SYS staked: 2.0000 SYS unstaking: 0.0000 SYS total: 4.0487 SYS -```` \ No newline at end of file +``` From da8ca230876e9a57482a8f56455eedc5ca2c6d66 Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Fri, 25 Sep 2020 18:15:53 -0400 Subject: [PATCH 1032/1048] fix shell prompt and codeblocks on how-to vote --- docs/04_guides/04_how-to-vote.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/04_guides/04_how-to-vote.md b/docs/04_guides/04_how-to-vote.md index 0141d156..ee9e1f96 100644 --- a/docs/04_guides/04_how-to-vote.md +++ b/docs/04_guides/04_how-to-vote.md @@ -29,7 +29,7 @@ cleos system voteproducer prods eosiotestts2 blockproducer1 blockproducer2 You should see something like below: -```bash +```console executed transaction: 2d8b58f7387aef52a1746d7a22d304bbbe0304481d7751fc4a50b619df62676d 128 bytes 374 us # eosio <= eosio::voteproducer {"voter":"eosiotestts2","proxy":"","producers":["blockproducer1","blockproducer2"]} ``` \ No newline at end of file From 8cd26a88c05101a986905b139e4c01a5dc047e31 Mon Sep 17 00:00:00 2001 From: Luis Paris Date: Fri, 25 Sep 2020 18:34:05 -0400 Subject: [PATCH 1033/1048] fix shell prompt and codeblocks on how-to use eosio wrap --- docs/04_guides/07_how-to-use-eosio.wrap.md | 214 +++++++++++++++------ 1 file changed, 154 insertions(+), 60 deletions(-) diff --git a/docs/04_guides/07_how-to-use-eosio.wrap.md b/docs/04_guides/07_how-to-use-eosio.wrap.md index 347be4e2..807441c2 100644 --- a/docs/04_guides/07_how-to-use-eosio.wrap.md +++ b/docs/04_guides/07_how-to-use-eosio.wrap.md @@ -24,11 +24,17 @@ A simple way to generate a transaction to create a new account is to use the `cl Three unsigned transactions will be generated using cleos and then the actions within those transactions will be appropriately stitched together into a single transaction which will later be proposed using the eosio.msig contract. First, generate a transaction to capture the necessary actions involved in creating a new account: +```sh +cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json ``` -$ cleos system newaccount -s -j -d --transfer --stake-net "1.000 SYS" --stake-cpu "1.000 SYS" --buy-ram-kbytes 50 eosio eosio.wrap EOS8MMUW11TAdTDxqdSwSqJodefSoZbFhcprndomgLi9MeR2o8MT4 > generated_account_creation_trx.json +```console 726964ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea305500c80000"} arg: {"code":"eosio","action":"buyrambytes","args":{"payer":"eosio","receiver":"eosio.wrap","bytes":51200}} 726967ms thread-0 main.cpp:429 create_action ] result: {"binargs":"0000000000ea305500004d1a03ea3055102700000000000004535953000000001027000000000000045359530000000001"} arg: {"code":"eosio","action":"delegatebw","args":{"from":"eosio","receiver":"eosio.wrap","stake_net_quantity":"1.0000 SYS","stake_cpu_quantity":"1.0000 SYS","transfer":true}} -$ cat generated_account_creation_trx.json +``` +```sh +cat generated_account_creation_trx.json +``` +```json { "expiration": "2018-06-29T17:11:36", "ref_block_num": 16349, @@ -71,12 +77,15 @@ $ cat generated_account_creation_trx.json "context_free_data": [] } ``` + Adjust the amount of delegated tokens and the amount of RAM bytes to gift as necessary. The actual public key used is not important since that data is only encoded into the `eosio::newaccount` action which will be replaced soon anyway. Second, create a file (e.g. newaccount_payload.json) with the JSON payload for the real `eosio::newaccount` action. It should look like: +```sh +cat newaccount_payload.json ``` -$ cat newaccount_payload.json +```json { "creator": "eosio", "name": "eosio.wrap", @@ -102,9 +111,11 @@ $ cat newaccount_payload.json ``` Third, generate a transaction containing the actual `eosio::newaccount` action that will be used in the final transaction: +```sh +cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json +cat generated_newaccount_trx.json ``` -$ cleos push action -s -j -d eosio newaccount newaccount_payload.json -p eosio > generated_newaccount_trx.json -$ cat generated_newaccount_trx.json +```json { "expiration": "2018-06-29T17:11:36", "ref_block_num": 16349, @@ -131,9 +142,11 @@ $ cat generated_newaccount_trx.json ``` Fourth, generate a transaction containing the `eosio::setpriv` action which will make the `eosio.wrap` account privileged: +```sh +cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json +cat generated_setpriv_trx.json ``` -$ cleos push action -s -j -d eosio setpriv '{"account": "eosio.wrap", "is_priv": 1}' -p eosio > generated_setpriv_trx.json -$ cat generated_setpriv_trx.json +```json { "expiration": "2018-06-29T17:11:36", "ref_block_num": 16349, @@ -160,8 +173,10 @@ $ cat generated_setpriv_trx.json ``` Next, the action JSONs of the previously generated transactions will be used to construct a unified transaction which will eventually be proposed with the eosio.msig contract. A good way to get started is to make a copy of the generated_newaccount_trx.json file (call the copied file create_wrap_account_trx.json) and edit the first three fields so it looks something like the following: +```sh +cat create_wrap_account_trx.json ``` -$ cat create_wrap_account_trx.json +```json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -190,8 +205,10 @@ $ cat create_wrap_account_trx.json The `ref_block_num` and `ref_block_prefix` values were set to 0. The proposed transaction does not need to have a valid TaPoS reference block because it will be reset anyway when scheduled as a deferred transaction during the `eosio.msig::exec` action. The `expiration` field, which was the only other field that was changed, will also be reset when the proposed transaction is scheduled as a deferred transaction during `eosio.msig::exec`. However, this field actually does matter during the propose-approve-exec lifecycle of the proposed transaction. If the present time passes the time in the `expiration` field of the proposed transaction, it will not be possible to execute the proposed transaction even if all necessary approvals are gathered. Therefore, it is important to set the expiration time to some point well enough in the future to give all necessary approvers enough time to review and approve the proposed transaction, but it is otherwise arbitrary. Generally, for reviewing/validation purposes it is important that all potential approvers of the transaction (i.e. the block producers) choose the exact same `expiration` time so that there is not any discrepancy in bytes of the serialized transaction if it was to later be included in payload data of some other action. Then, all but the first action JSON object of generated_account_creation_trx.json should be appended to the `actions` array of create_wrap_account_trx.json, and then the single action JSON object of generated_setpriv_trx.json should be appended to the `actions` array of create_wrap_account_trx.json. The final result is a create_wrap_account_trx.json file that looks like the following: +```sh +cat create_wrap_account_trx.json ``` -$ cat create_wrap_account_trx.json +```json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -251,8 +268,10 @@ It will be useful to have a JSON of the active permissions of each of the active This guide will assume that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. In that case, create a file producer_permissions.json with the content shown in the command below: +```sh +cat producer_permissions.json ``` -$ cat producer_permissions.json +```json [ {"actor": "blkproducera", "permission": "active"}, {"actor": "blkproducerb", "permission": "active"}, @@ -287,8 +306,10 @@ The approvers are typically going to be the active block producers of the chain, The guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. The lead block producer (`blkproducera`) should propose the transaction stored in create_wrap_account_trx.json: +```sh +cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera ``` -$ cleos multisig propose_trx createwrap producer_permissions.json create_wrap_account_trx.json blkproducera +```console executed transaction: bf6aaa06b40e2a35491525cb11431efd2b5ac94e4a7a9c693c5bf0cfed942393 744 bytes 772 us # eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"createwrap","requested":[{"actor":"blkproducera","permis... warning: transaction executed locally, but may not be confirmed by the network yet @@ -299,9 +320,11 @@ warning: transaction executed locally, but may not be confirmed by the network y Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. The proposed transaction can be reviewed using the `cleos multisig review` command: +```sh +cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json +head -n 30 create_wrap_account_trx_to_review.json ``` -$ cleos multisig review blkproducera createwrap > create_wrap_account_trx_to_review.json -$ head -n 30 create_wrap_account_trx_to_review.json +```json { "proposal_name": "createwrap", "packed_transaction": "c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100", @@ -335,19 +358,29 @@ $ head -n 30 create_wrap_account_trx_to_review.json ``` The approvers should go through the full human-readable transaction output and make sure everything looks fine. But they can also use tools to automatically compare the proposed transaction to the one they generated to make sure there are absolutely no differences: +```sh +cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex +cat expected_create_wrap_trx_serialized.hex ``` -$ cleos multisig propose_trx -j -s -d createwrap '[]' create_wrap_account_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_create_wrap_trx_serialized.hex -$ cat expected_create_wrap_trx_serialized.hex +```console c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex -$ cat proposed_create_wrap_trx_serialized.hex +``` +```sh +cat create_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_create_wrap_trx_serialized.hex +cat proposed_create_wrap_trx_serialized.hex +``` +```console c0593f5b00000000000000000000040000000000ea305500409e9a2264b89a010000000000ea305500000000a8ed3232420000000000ea305500004d1a03ea30550100000000010000000000ea305500000000a8ed32320100000100000000010000000000ea305500000000a8ed32320100000000000000ea305500b0cafe4873bd3e010000000000ea305500000000a8ed3232140000000000ea305500004d1a03ea3055002800000000000000ea305500003f2a1ba6a24a010000000000ea305500000000a8ed3232310000000000ea305500004d1a03ea30551027000000000000045359530000000010270000000000000453595300000000010000000000ea305500000060bb5bb3c2010000000000ea305500000000a8ed32320900004d1a03ea30550100 -$ diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex +``` +```sh +diff expected_create_wrap_trx_serialized.hex proposed_create_wrap_trx_serialized.hex ``` When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +```sh +cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb ``` -$ cleos multisig approve blkproducera createwrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +```console executed transaction: 03a907e2a3192aac0cd040c73db8273c9da7696dc7960de22b1a479ae5ee9f23 128 bytes 472 us # eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"createwrap","level":{"actor":"blkproducerb","permission"... warning: transaction executed locally, but may not be confirmed by the network yet @@ -357,16 +390,20 @@ warning: transaction executed locally, but may not be confirmed by the network y When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). +```sh +cleos multisig exec blkproducera createwrap blkproducera ``` -$ cleos multisig exec blkproducera createwrap blkproducera +```console executed transaction: 7ecc183b99915cc411f96dde7c35c3fe0df6e732507f272af3a039b706482e5a 160 bytes 850 us # eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"createwrap","executer":"blkproducera"} warning: transaction executed locally, but may not be confirmed by the network yet ``` Anyone can now verify that the `eosio.wrap` was created: +```sh +cleos get account eosio.wrap ``` -$ cleos get account eosio.wrap +```console privileged: true permissions: owner 1: 1 eosio@active, @@ -389,7 +426,6 @@ cpu bandwidth: limit: 460.8 ms producers: - ``` ## 1.2 Deploy the eosio.wrap contract @@ -399,12 +435,18 @@ producers: The transaction to deploy the contract to the `eosio.wrap` account will need to be proposed to get the necessary approvals from active block producers before executing it. This transaction needs to first be generated and stored as JSON into a file so that it can be used in the cleos command to propose the transaction to the eosio.msig contract. The easy way to generate this transaction is using cleos: +```sh +cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json ``` -$ cleos set contract -s -j -d eosio.wrap contracts/eosio.wrap/ > deploy_wrap_contract_trx.json +```console Reading WAST/WASM from contracts/eosio.wrap/eosio.wrap.wasm... Using already assembled WASM... Publishing contract... -$ cat deploy_wrap_contract_trx.json +``` +```sh +cat deploy_wrap_contract_trx.json +``` +```json { "expiration": "2018-06-29T19:55:26", "ref_block_num": 18544, @@ -440,8 +482,10 @@ $ cat deploy_wrap_contract_trx.json ``` Once again, as described in sub-section 2.1.1, edit the values of the `ref_block_num` and `ref_block_prefix` fields to be 0 and edit the time of the `expiration` field to some point in the future that provides enough time to approve and execute the proposed transaction. After editing deploy_wrap_contract_trx.json the first few lines of it may look something like the following: +```sh +head -n 9 deploy_wrap_contract_trx.json ``` -$ head -n 9 deploy_wrap_contract_trx.json +```json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -464,8 +508,10 @@ The approvers are typically going to be the active block producers of the chain, This guide will assume that `blkproducera` was chosen as the lead block producer to propose the transaction. The lead block producer (`blkproducera`) should propose the transaction stored in deploy_wrap_contract_trx.json: +```sh +cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera ``` -$ cleos multisig propose_trx deploywrap producer_permissions.json deploy_wrap_contract_trx.json blkproducera +```console executed transaction: 9e50dd40eba25583a657ee8114986a921d413b917002c8fb2d02e2d670f720a8 4312 bytes 871 us # eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"deploywrap","requested":[{"actor":"blkproducera","permis... warning: transaction executed locally, but may not be confirmed by the network yet @@ -476,9 +522,11 @@ warning: transaction executed locally, but may not be confirmed by the network y Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. The proposed transaction can be reviewed using the `cleos multisig review` command: +```sh +cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json +cat deploy_wrap_contract_trx_to_review.json ``` -$ cleos multisig review blkproducera deploywrap > deploy_wrap_contract_trx_to_review.json -$ cat deploy_wrap_contract_trx_to_review.json +```json { "proposal_name": "deploywrap", "packed_transaction": "c0593f5b00000000000000000000020000000000ea305500000040258ab2c20100004d1a03ea305500000000a8ed3232d41800004d1a03ea30550000c8180061736d01000000013e0c60017f006000017e60027e7e0060017e006000017f60027f7f017f60027f7f0060037f7f7f017f60057f7e7f7f7f0060000060037e7e7e0060017f017f029d010803656e7610616374696f6e5f646174615f73697a65000403656e760c63757272656e745f74696d65000103656e760c656f73696f5f617373657274000603656e76066d656d637079000703656e7610726561645f616374696f6e5f64617461000503656e760c726571756972655f61757468000303656e760d726571756972655f6175746832000203656e760d73656e645f64656665727265640008030f0e0505050400000a05070b050b000904050170010202050301000107c7010b066d656d6f72790200165f5a6571524b3131636865636b73756d32353653315f0008165f5a6571524b3131636865636b73756d31363053315f0009165f5a6e65524b3131636865636b73756d31363053315f000a036e6f77000b305f5a4e35656f73696f3132726571756972655f6175746845524b4e535f31367065726d697373696f6e5f6c6576656c45000c155f5a4e35656f73696f347375646f34657865634576000d056170706c79000e066d656d636d700010066d616c6c6f630011046672656500140908010041000b02150d0a9a130e0b002000200141201010450b0b002000200141201010450b0d0020002001412010104100470b0a00100142c0843d80a70b0e002000290300200029030810060b9e0102017e027f410028020441206b2202210341002002360204200029030010050240024010002200418104490d002000101121020c010b410020022000410f6a4170716b22023602040b2002200010041a200041074b41101002200341186a2002410810031a2003290318100520032903182101200310013703002003200137030820032003290318200241086a2000410010074100200341206a3602040bfd0403027f047e017f4100410028020441206b220936020442002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b024020072002520d0042002106423b2105413021044200210703400240024002400240024020064204560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b200720015141c00010020b0240024020012000510d0042002106423b2105412021044200210703400240024002400240024020064206560d0020042c00002203419f7f6a41ff017141194b0d01200341a5016a21030c020b420021082006420b580d020c030b200341d0016a41002003414f6a41ff01714105491b21030b2003ad42388642388721080b2008421f83200542ffffffff0f838621080b200441016a2104200642017c2106200820078421072005427b7c2205427a520d000b20072002520d010b20092000370318200242808080808080a0aad700520d00200941003602142009410136021020092009290310370208200941186a200941086a100f1a0b4100200941206a3602040b8c0101047f4100280204220521042001280204210220012802002101024010002203450d00024020034180044d0d00200310112205200310041a200510140c010b410020052003410f6a4170716b22053602042005200310041a0b200020024101756a210302402002410171450d00200328020020016a28020021010b200320011100004100200436020441010b4901037f4100210502402002450d000240034020002d0000220320012d00002204470d01200141016a2101200041016a21002002417f6a22020d000c020b0b200320046b21050b20050b0900418001200010120bcd04010c7f02402001450d00024020002802c041220d0d004110210d200041c0c1006a41103602000b200141086a200141046a41077122026b200120021b210202400240024020002802c441220a200d4f0d002000200a410c6c6a4180c0006a21010240200a0d0020004184c0006a220d2802000d0020014180c000360200200d20003602000b200241046a210a034002402001280208220d200a6a20012802004b0d002001280204200d6a220d200d28020041808080807871200272360200200141086a22012001280200200a6a360200200d200d28020041808080807872360200200d41046a22010d030b2000101322010d000b0b41fcffffff0720026b2104200041c8c1006a210b200041c0c1006a210c20002802c8412203210d03402000200d410c6c6a22014188c0006a28020020014180c0006a22052802004641d0c200100220014184c0006a280200220641046a210d0340200620052802006a2107200d417c6a2208280200220941ffffffff07712101024020094100480d000240200120024f0d000340200d20016a220a20074f0d01200a280200220a4100480d012001200a41ffffffff07716a41046a22012002490d000b0b20082001200220012002491b200941808080807871723602000240200120024d0d00200d20026a200420016a41ffffffff07713602000b200120024f0d040b200d20016a41046a220d2007490d000b41002101200b4100200b28020041016a220d200d200c280200461b220d360200200d2003470d000b0b20010f0b2008200828020041808080807872360200200d0f0b41000b870501087f20002802c44121010240024041002d00a643450d0041002802a84321070c010b3f002107410041013a00a6434100200741107422073602a8430b200721030240024002400240200741ffff036a41107622023f0022084d0d00200220086b40001a4100210820023f00470d0141002802a84321030b41002108410020033602a84320074100480d0020002001410c6c6a210220074180800441808008200741ffff037122084181f8034922061b6a2008200741ffff077120061b6b20076b2107024041002d00a6430d003f002103410041013a00a6434100200341107422033602a8430b20024180c0006a210220074100480d01200321060240200741076a417871220520036a41ffff036a41107622083f0022044d0d00200820046b40001a20083f00470d0241002802a84321060b4100200620056a3602a8432003417f460d0120002001410c6c6a22014184c0006a2802002206200228020022086a2003460d020240200820014188c0006a22052802002201460d00200620016a2206200628020041808080807871417c20016b20086a72360200200520022802003602002006200628020041ffffffff07713602000b200041c4c1006a2202200228020041016a220236020020002002410c6c6a22004184c0006a200336020020004180c0006a220820073602000b20080f0b02402002280200220820002001410c6c6a22034188c0006a22012802002207460d0020034184c0006a28020020076a2203200328020041808080807871417c20076b20086a72360200200120022802003602002003200328020041ffffffff07713602000b2000200041c4c1006a220728020041016a22033602c0412007200336020041000f0b2002200820076a36020020020b7b01037f024002402000450d0041002802c04222024101480d004180c10021032002410c6c4180c1006a21010340200341046a2802002202450d010240200241046a20004b0d00200220032802006a20004b0d030b2003410c6a22032001490d000b0b0f0b2000417c6a2203200328020041ffffffff07713602000b0300000b0bcf01060041040b04b04900000041100b0572656164000041200b086f6e6572726f72000041300b06656f73696f000041c0000b406f6e6572726f7220616374696f6e277320617265206f6e6c792076616c69642066726f6d207468652022656f73696f222073797374656d206163636f756e74000041d0c2000b566d616c6c6f635f66726f6d5f6672656564207761732064657369676e656420746f206f6e6c792062652063616c6c6564206166746572205f686561702077617320636f6d706c6574656c7920616c6c6f6361746564000000000000ea305500000000b863b2c20100004d1a03ea305500000000a8ed3232e90400004d1a03ea3055df040e656f73696f3a3a6162692f312e30030c6163636f756e745f6e616d65046e616d650f7065726d697373696f6e5f6e616d65046e616d650b616374696f6e5f6e616d65046e616d6506107065726d697373696f6e5f6c6576656c0002056163746f720c6163636f756e745f6e616d650a7065726d697373696f6e0f7065726d697373696f6e5f6e616d6506616374696f6e0004076163636f756e740c6163636f756e745f6e616d65046e616d650b616374696f6e5f6e616d650d617574686f72697a6174696f6e127065726d697373696f6e5f6c6576656c5b5d0464617461056279746573127472616e73616374696f6e5f68656164657200060a65787069726174696f6e0e74696d655f706f696e745f7365630d7265665f626c6f636b5f6e756d0675696e743136107265665f626c6f636b5f7072656669780675696e743332136d61785f6e65745f75736167655f776f7264730976617275696e743332106d61785f6370755f75736167655f6d730575696e74380964656c61795f7365630976617275696e74333209657874656e73696f6e000204747970650675696e74313604646174610562797465730b7472616e73616374696f6e127472616e73616374696f6e5f6865616465720314636f6e746578745f667265655f616374696f6e7308616374696f6e5b5d07616374696f6e7308616374696f6e5b5d167472616e73616374696f6e5f657874656e73696f6e730b657874656e73696f6e5b5d046578656300020865786563757465720c6163636f756e745f6e616d65037472780b7472616e73616374696f6e0100000000008054570465786563000000000000", @@ -528,19 +576,29 @@ $ cat deploy_wrap_contract_trx_to_review.json Each approver should be able to see that the proposed transaction is setting the code and ABI of the `eosio.wrap` contract. But the data is just hex data and therefore not very meaningful to the approver. And considering that `eosio.wrap` at this point should be a privileged contract, it would be very dangerous for block producers to just allow a contract to be deployed to a privileged account without knowing exactly which WebAssembly code they are deploying and also auditing the source code that generated that WebAssembly code to ensure it is safe to deploy. This guide assumes that each approver has already audited the source code of the contract to be deployed and has already compiled that code to generate the WebAssembly code that should be byte-for-byte identical to the code that every other approver following the same process should have generated. The guide also assumes that this generated code and its associated ABI were provided in the steps in sub-section 2.2.1 that generated the transaction in the deploy_wrap_contract_trx.json file. It then becomes quite simple to verify that the proposed transaction is identical to the one the potential approver could have proposed with the code and ABI that they already audited: +```sh +cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex +cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 ``` -$ cleos multisig propose_trx -j -s -d deploywrap '[]' deploy_wrap_contract_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_deploy_wrap_trx_serialized.hex -$ cat expected_deploy_wrap_trx_serialized.hex | cut -c -50 +```console c0593f5b00000000000000000000020000000000ea30550000 -$ cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex -$ cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 +``` +```sh +cat deploy_wrap_account_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_deploy_wrap_trx_serialized.hex +cat proposed_deploy_wrap_trx_serialized.hex | cut -c -50 +``` +```console c0593f5b00000000000000000000020000000000ea30550000 -$ diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex +``` +```sh +diff expected_deploy_wrap_trx_serialized.hex proposed_deploy_wrap_trx_serialized.hex ``` When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +```sh +cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb ``` -$ cleos multisig approve blkproducera deploywrap '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +```console executed transaction: d1e424e05ee4d96eb079fcd5190dd0bf35eca8c27dd7231b59df8e464881abfd 128 bytes 483 us # eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"deploywrap","level":{"actor":"blkproducerb","permission"... warning: transaction executed locally, but may not be confirmed by the network yet @@ -550,19 +608,27 @@ warning: transaction executed locally, but may not be confirmed by the network y When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). +```sh +cleos multisig exec blkproducera deploywrap blkproducera ``` -$ cleos multisig exec blkproducera deploywrap blkproducera +```console executed transaction: e8da14c6f1fdc3255b5413adccfd0d89b18f832a4cc18c4324ea2beec6abd483 160 bytes 1877 us # eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"deploywrap","executer":"blkproducera"} ``` Anyone can now verify that the `eosio.wrap` contract was deployed correctly. +```sh +cleos get code -a retrieved-eosio.wrap.abi eosio.wrap ``` -$ cleos get code -a retrieved-eosio.wrap.abi eosio.wrap +```console code hash: 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c saving abi to retrieved-eosio.wrap.abi -$ sha256sum contracts/eosio.wrap/eosio.wrap.wasm +``` +```sh +sha256sum contracts/eosio.wrap/eosio.wrap.wasm +``` +```console 1b3456a5eca28bcaca7a2a3360fbb2a72b9772a416c8e11a303bcb26bfe3263c contracts/eosio.wrap/eosio.wrap.wasm ``` @@ -577,8 +643,10 @@ This example will demonstrate how to use the deployed eosio.wrap contract togeth This guide assumes that there are 21 active block producers on the chain with account names: `blkproducera`, `blkproducerb`, ..., `blkproduceru`. Block producer `blkproducera` will act as the lead block producer handling the proposal of the transaction. The producer permissions will later come in handy when proposing a transaction that must be approved by a supermajority of the producers. So a file producer_permissions.json containing those permission (see contents below) should be created to be used later in this guide: +```sh +cat producer_permissions.json ``` -$ cat producer_permissions.json +```json [ {"actor": "blkproducera", "permission": "active"}, {"actor": "blkproducerb", "permission": "active"}, @@ -609,7 +677,7 @@ $ cat producer_permissions.json The goal of this example is for the block producers to change the owner permission of the account `alice`. The initial status of the `alice` account might be: -``` +```console permissions: owner 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV @@ -636,13 +704,15 @@ producers: Assume that none of the block producers know the private key corresponding to the public key `EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV` which, as can be seen above, is initially securing access to the `alice` account. The first step is to generate the transaction changing the owner permission of the `alice` account as if `alice` is authorizing the change: -``` -$ cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json +```sh +cleos set account permission -s -j -d alice owner '{"threshold": 1, "accounts": [{"permission": {"actor": "eosio", "permission": "active"}, "weight": 1}]}' > update_alice_owner_trx.json ``` Then modify update_alice_owner_trx.json so that the values for the `ref_block_num` and `ref_block_prefix` fields are both 0 and the value of the `expiration` field is `"1970-01-01T00:00:00"`: +```sh +cat update_alice_owner_trx.json ``` -$ cat update_alice_owner_trx.json +```console { "expiration": "1970-01-01T00:00:00", "ref_block_num": 0, @@ -670,13 +740,15 @@ $ cat update_alice_owner_trx.json The next step is to generate the transaction containing the `eosio.wrap::exec` action. This action will contain the transaction in update_alice_owner_trx.json as part of its action payload data. -``` -$ cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json +```sh +cleos wrap exec -s -j -d blkproducera update_alice_owner_trx.json > wrap_update_alice_owner_trx.json ``` Once again modify wrap_update_alice_owner_trx.json so that the value for the `ref_block_num` and `ref_block_prefix` fields are both 0. However, instead of changing the value of the expiration field to `"1970-01-01T00:00:00"`, it should be changed to a time that is far enough in the future to allow enough time for the proposed transaction to be approved and executed. +```sh +cat wrap_update_alice_owner_trx.json ``` -$ cat wrap_update_alice_owner_trx.json +```json { "expiration": "2018-07-06T12:00:00", "ref_block_num": 0, @@ -708,16 +780,20 @@ $ cat wrap_update_alice_owner_trx.json If the `cleos wrap` command is not available, there is an alternative way to generate the above transaction. There is no need to continue reading the remaining of sub-section 3.1.1 if the wrap_update_alice_owner_trx.json file was already generated with content similar to the above using the `cleos wrap exec` sub-command method. First the hex encoding of the binary serialization of the transaction in update_alice_owner_trx.json must be obtained. One way of obtaining this data is through the following command: +```sh +cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex +cat update_alice_owner_trx_serialized.hex ``` -$ cleos multisig propose_trx -s -j -d nothing '[]' update_alice_owner_trx.json nothing | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > update_alice_owner_trx_serialized.hex -$ cat update_alice_owner_trx_serialized.hex +```console 0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed323201000000 ``` Then generate the template for the transaction containing the `eosio.wrap::exec` action: +```sh +cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json +cat wrap_update_alice_owner_trx.json ``` -$ cleos push action -s -j -d eosio.wrap exec '{"executer": "blkproducera", "trx": ""}' > wrap_update_alice_owner_trx.json -$ cat wrap_update_alice_owner_trx.json +```json { "expiration": "2018-06-29T23:34:01", "ref_block_num": 23708, @@ -748,8 +824,10 @@ Then modify the transaction in wrap_update_alice_owner_trx.json as follows: ### 2.1.2 Propose the transaction to change the owner permission of an account The lead block producer (`blkproducera`) should propose the transaction stored in wrap_update_alice_owner_trx.json: +```sh +cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera ``` -$ cleos multisig propose_trx updatealice producer_permissions.json wrap_update_alice_owner_trx.json blkproducera +```console executed transaction: 10474f52c9e3fc8e729469a577cd2fc9e4330e25b3fd402fc738ddde26605c13 624 bytes 782 us # eosio.msig <= eosio.msig::propose {"proposer":"blkproducera","proposal_name":"updatealice","requested":[{"actor":"blkproducera","permi... warning: transaction executed locally, but may not be confirmed by the network yet @@ -758,9 +836,11 @@ warning: transaction executed locally, but may not be confirmed by the network y ### 2.1.3 Review and approve the transaction to change the owner permission of an account Each of the potential approvers of the proposed transaction (i.e. the active block producers) should first review the proposed transaction to make sure they are not approving anything that they do not agree to. +```sh +cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json +cat wrap_update_alice_owner_trx_to_review.json ``` -$ cleos multisig review blkproducera updatealice > wrap_update_alice_owner_trx_to_review.json -$ cat wrap_update_alice_owner_trx_to_review.json +```json { "proposal_name": "updatealice", "packed_transaction": "c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000", @@ -820,19 +900,29 @@ The approvers should go through the human-readable transaction output and make s Furthermore, even if this usability issue was fixed in nodeos/cleos, there will still be cases where there is no sensible human-readable version of an action data payload within a transaction. An example of this is the proposed transaction in sub-section 2.2.3 which used the `eosio::setcode` action to set the contract code of the `eosio.wrap` account. The best thing to do in such situations is for the reviewer to compare the proposed transaction to one generated by them through a process they trust. Since each block producer generated a transaction in sub-section 3.1.1 (stored in the file wrap_update_alice_owner_trx.json) which should be identical to the transaction proposed by the lead block producer, they can each simply check to see if the two transactions are identical: +```sh +cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex +cat expected_wrap_update_alice_owner_trx_serialized.hex ``` -$ cleos multisig propose_trx -j -s -d updatealice '[]' wrap_update_alice_owner_trx.json blkproducera | grep '"data":' | sed 's/^[ \t]*"data":[ \t]*//;s/[",]//g' | cut -c 35- > expected_wrap_update_alice_owner_trx_serialized.hex -$ cat expected_wrap_update_alice_owner_trx_serialized.hex +```console c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex -$ cat proposed_wrap_update_alice_owner_trx_serialized.hex +``` +```sh +cat wrap_update_alice_owner_trx_to_review.json | grep '"packed_transaction":' | sed 's/^[ \t]*"packed_transaction":[ \t]*//;s/[",]//g' > proposed_wrap_update_alice_owner_trx_serialized.hex +cat proposed_wrap_update_alice_owner_trx_serialized.hex +``` +```console c0593f5b000000000000000000000100004d1a03ea305500000000008054570260ae423ad15b613c00000000a8ed323200004d1a03ea305500000000a8ed32326b60ae423ad15b613c0000000000000000000000000000010000000000ea30550040cbdaa86c52d5010000000000855c3400000000a8ed3232310000000000855c340000000080ab26a700000000000000000100000000010000000000ea305500000000a8ed32320100000000 -$ diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex +``` +```sh +diff expected_wrap_update_alice_owner_trx_serialized.hex proposed_wrap_update_alice_owner_trx_serialized.hex ``` When an approver (e.g. `blkproducerb`) is satisfied with the proposed transaction, they can simply approve it: +```sh +cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb ``` -$ cleos multisig approve blkproducera updatealice '{"actor": "blkproducerb", "permission": "active"}' -p blkproducerb +```console executed transaction: 2bddc7747e0660ba26babf95035225895b134bfb2ede32ba0a2bb6091c7dab56 128 bytes 543 us # eosio.msig <= eosio.msig::approve {"proposer":"blkproducera","proposal_name":"updatealice","level":{"actor":"blkproducerb","permission... warning: transaction executed locally, but may not be confirmed by the network yet @@ -842,16 +932,20 @@ warning: transaction executed locally, but may not be confirmed by the network y When the necessary approvals are collected (in this example, with 21 block producers, at least 15 of their approvals were required), anyone can push the `eosio.msig::exec` action which executes the approved transaction. It makes a lot of sense for the lead block producer who proposed the transaction to also execute it (this will incur another temporary RAM cost for the deferred transaction that is generated by the eosio.msig contract). +```sh +cleos multisig exec blkproducera updatealice blkproducera ``` -$ cleos multisig exec blkproducera updatealice blkproducera +```console executed transaction: 7127a66ae307fbef6415bf60c3e91a88b79bcb46030da983c683deb2a1a8e0d0 160 bytes 820 us # eosio.msig <= eosio.msig::exec {"proposer":"blkproducera","proposal_name":"updatealice","executer":"blkproducera"} warning: transaction executed locally, but may not be confirmed by the network yet ``` Anyone can now verify that the owner authority of `alice` was successfully changed: +```sh +cleos get account alice ``` -$ cleos get account alice +```console permissions: owner 1: 1 eosio@active, active 1: 1 EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV From 42fd226b6feda8a8884742e6542b4d56de66bbca Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 6 Nov 2020 23:01:16 +0200 Subject: [PATCH 1034/1048] updates on cpu, net and ram documentation --- docs/01_key-concepts/01_system.md | 10 +++---- docs/01_key-concepts/02_ram.md | 17 +++++++---- docs/01_key-concepts/03_cpu.md | 10 +++++-- docs/01_key-concepts/04_net.md | 10 +++++-- docs/01_key-concepts/05_stake.md | 47 +++++++++++++++++++++++++++++-- docs/01_key-concepts/06_vote.md | 6 ++-- 6 files changed, 78 insertions(+), 22 deletions(-) diff --git a/docs/01_key-concepts/01_system.md b/docs/01_key-concepts/01_system.md index b3f6f2df..eb14bb6d 100644 --- a/docs/01_key-concepts/01_system.md +++ b/docs/01_key-concepts/01_system.md @@ -1,18 +1,18 @@ --- content_title: System contracts, system accounts, privileged accounts -link_text: System contracts and accounts, privileged accounts +link_text: System contracts, system accounts, privileged accounts --- -At the genesis of an EOSIO based blockchain, there is only one account present, `eosio` account, which is the main `system account`. There are other `system account`s, created by `eosio` account, which control specific actions of the `system contract`s [mentioned in previous section](../#system-contracts-defined-in-eosio.contracts). __Note__ the terms `system contract` and `system account`. `Privileged accounts` are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to `eosio.prods` system account. +At the genesis of an EOSIO-based blockchain, there is only one account present, `eosio` account, which is the main `system account`. There are other `system account`s, created by `eosio` account, which control specific actions of the `system contract`s [mentioned in previous section](../#system-contracts-defined-in-eosio.contracts). __Note__ the terms `system contract` and `system account`. `Privileged accounts` are accounts which can execute a transaction while skipping the standard authorization check. To ensure that this is not a security hole, the permission authority over these accounts is granted to `eosio.prods` system account. As you just learned the relation between a `system account` and a `system contract`, it is also important to remember that not all system accounts contain a system contract, but each system account has important roles in the blockchain functionality, as follows: |Account|Privileged|Has contract|Description| |---|---|---|---| -|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO based blockchain.| +|eosio|Yes|It contains the `eosio.system` contract|The main system account on an EOSIO-based blockchain.| |eosio.msig|Yes|It contains the `eosio.msig` contract|Allows the signing of a multi-sig transaction proposal for later execution if all required parties sign the proposal before the expiration time.| |eosio.wrap|Yes|It contains the `eosio.wrap` contract.|Simplifies block producer superuser actions by making them more readable and easier to audit.| -|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO based blockchains.| +|eosio.token|No|It contains the `eosio.token` contract.|Defines the structures and actions allowing users to create, issue, and manage tokens on EOSIO-based blockchains.| |eosio.names|No|No|The account which is holding funds from namespace auctions.| |eosio.bpay|No|No|The account that pays the block producers for producing blocks. It assigns 0.25% of the inflation based on the amount of blocks a block producer created in the last 24 hours.| |eosio.prods|No|No|The account representing the union of all current active block producers permissions.| @@ -21,4 +21,4 @@ As you just learned the relation between a `system account` and a `system contra |eosio.saving|No|No|The account which holds the 4% of network inflation.| |eosio.stake|No|No|The account that keeps track of all SYS tokens which have been staked for NET or CPU bandwidth.| |eosio.vpay|No|No|The account that pays the block producers accordingly with the votes won. It assigns 0.75% of inflation based on the amount of votes a block producer won in the last 24 hours.| -|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| \ No newline at end of file +|eosio.rex|No|No|The account that keeps track of fees and balances resulted from REX related actions execution.| diff --git a/docs/01_key-concepts/02_ram.md b/docs/01_key-concepts/02_ram.md index afa832f8..a9d96fcd 100644 --- a/docs/01_key-concepts/02_ram.md +++ b/docs/01_key-concepts/02_ram.md @@ -1,6 +1,6 @@ --- -content_title: RAM as resource -link_text: RAM as resource +content_title: RAM as system resource +link_text: RAM as system resource --- ## What is RAM @@ -23,10 +23,17 @@ The EOSIO-based blockchains are known for their high performance, which is achie ## RAM Importance -RAM is a very important resource because of the following reasons +RAM is a very important system resource because of the following reasons: -- It is a limited resource, each EOSIO-based blockchain can have a different policy and rules around RAM; for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KB per block, thus increasing constantly the supply of RAM for its price to not grow too high due to the increased demand from blockchain applications. +- It is a limited resource, each EOSIO-based blockchain can have different policies and rules around RAM; for example the public EOS blockchain started with 64GB of RAM and after that the block producers decided to increase the memory with 1KB per block, thus increasing constantly the supply of RAM for its price to not grow too high due to the increased demand from blockchain applications. - RAM is used in executing many actions sent to the blockchain; creating a new account action, for example, it needs to store in the blockchain memory the new account's information; also when an account accepts a new type of token a new record has to be created, somewhere in the blockchain memory, that holds the balance of the new token accepted, and that memory, the storage space on the blockchain, has to be purchased either by the account that transfers the token or by the account that accepts the new token type. -RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). \ No newline at end of file +- The smart contract can not store any additional information if it consumes all its allocated RAM. To continue to save data in the blockchain database, one, or both of the following conditions must be met: + + - A portion of the occupied RAM is freed by the smart contract. + - More RAM is allocated to the smart contract account through the RAM buying process. + +RAM is a scarce resource priced according to the unique Bancor liquidity algorithm which is implemented in the system contract [here](https://github.com/EOSIO/eos/blob/905e7c85714aee4286fa180ce946f15ceb4ce73c/contracts/eosio.system/exchange_state.hpp). + +The RAM system resource must be purchased using the system token. Refer to the [cleos manual](https://developers.eos.io/manuals/eos/v2.0/cleos/how-to-guides/how-to-buy-ram) to learn how to buy RAM via the command line interface. diff --git a/docs/01_key-concepts/03_cpu.md b/docs/01_key-concepts/03_cpu.md index 43813698..6f60577f 100644 --- a/docs/01_key-concepts/03_cpu.md +++ b/docs/01_key-concepts/03_cpu.md @@ -1,6 +1,10 @@ --- -content_title: CPU as resource -link_text: CPU as resource +content_title: CPU as system resource +link_text: CPU as system resource --- -CPU is processing power, the amount of CPU an account has is measured in microseconds, it is referred to as `cpu bandwidth` on the cleos get account command output and represents the amount of processing time an account has at its disposal when pushing actions to a contract. \ No newline at end of file +The system resource CPU provides processing power to blockchain accounts. The amount of CPU an account has is measured in microseconds and it is referred to as `cpu bandwidth` on the `cleos get account` command output. The `cpu bandwidth` represents the amount of processing time an account has at its disposal when actions sent to its contract are executed by the blockchain. When a transaction is executed by the blockchain it consumes CPU and NET, therefore sufficient CPU must be staked in order for transactions to complete. + +For more details about EOSIO staking refer to the following: +* [Staking Mechanism](https://developers.eos.io/welcome/latest/overview/technical_features#staking-mechanism). +* [Staking on EOSIO-based blockchains](05_stake.md) \ No newline at end of file diff --git a/docs/01_key-concepts/04_net.md b/docs/01_key-concepts/04_net.md index a9b5aea1..f4f5b146 100644 --- a/docs/01_key-concepts/04_net.md +++ b/docs/01_key-concepts/04_net.md @@ -1,6 +1,10 @@ --- -content_title: NET as resource -link_text: NET as resource +content_title: NET as system resource +link_text: NET as system resource --- -As CPU and RAM, NET is also a very important resource in EOSIO-based blockchains. NET is the network bandwidth measured in bytes of transactions and it is referred to as `net bandwidth` on the cleos get account command. This resource like CPU must be staked so that a contract's transactions can be executed. \ No newline at end of file +NET, as CPU and RAM, is a very important system resource in EOSIO-based blockchains. NET is measured by the byte size of the transactions saved in the blockchain database and it is referred to as `net bandwidth` on the cleos get account command result. When a transaction is executed by the blockchain it consumes CPU and NET, therefore sufficient NET must be staked in order for transactions to complete. + +For more details about EOSIO staking refer to the following: +* [Staking Mechanism](https://developers.eos.io/welcome/latest/overview/technical_features#staking-mechanism). +* [Staking on EOSIO-based blockchains](05_stake.md) diff --git a/docs/01_key-concepts/05_stake.md b/docs/01_key-concepts/05_stake.md index c0fb29b2..bda75448 100644 --- a/docs/01_key-concepts/05_stake.md +++ b/docs/01_key-concepts/05_stake.md @@ -1,6 +1,47 @@ --- -content_title: Staking on EOSIO based blockchains -link_text: Staking on EOSIO based blockchains +content_title: Staking on EOSIO-based blockchains +link_text: Staking on EOSIO-based blockchains --- -On EOSIO based blockchains, to be able to deploy and then interact with a smart contract via its implemented actions it needs to be backed up by resources allocated on the account where the smart contract is deployed to. The three resource types an EOSIO smart contract developer needs to know about are RAM, CPU and NET. You can __stake__ CPU and NET and you can __buy__ RAM. You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you'll hold the staked tokens, either for NET or CPU, for a pre-established period of time, in spite of inflation caused by minting new tokens in order to reward BPs for their services every 24 hours. \ No newline at end of file +## System Resources + +EOSIO-based blockchains work with three system resources: + +* [RAM](02_ram.md) +* [CPU](03_cpu.md) +* [NET](04_net.md) + +## How To Allocate System Resources + +EOSIO-based blockchain accounts need sufficient system resources, RAM, CPU and NET, to interact with the smart contracts deployed on the blockchain. + +### Stake NET and CPU + +The CPU and NET system resources are allocated by the account owner via the staking mechanism. Refer to the [cleos manual](https://developers.eos.io/manuals/eos/v2.0/cleos/how-to-guides/how-to-stake-resource) on how to do it via the command line interface. + +You will also find that staking/unstaking is at times referred to as delegating/undelegating. The economics of staking is also to provably commit to a promise that you will hold the staked tokens, either for NET or CPU, for a pre-established period of time, in spite of inflation caused by minting new tokens in order to reward BPs for their services every 24 hours. + +When you stake tokens for CPU and NET, you gain access to system resources proportional to the total amount of tokens staked by all other users for the same system resource at the same time. This means you can execute transactions at no cost but in the limits of the staked tokens. The staked tokens guarantee the proportional amount of resources regardless of any variations in the free market. + +If an account consumes all its allocated CPU and NET resources, it has two options: + +* It can wait for the blockchain to replenish the consumed resources. You can read more details below about the [system resources replenish algorithm].(05_stake.md#System-Resources-Replenish-Algorithm). +* It can allocate more resources through the staking mechanism. + +When an account uses the allocated resources, the amount that can be used in one transaction is limited by predefine [maximum CPU](https://developers.eos.io/manuals/eosio.cdt/latest/structeosio_1_1blockchain__parameters#variable-max_transaction_cpu_usage), [minimum CPU](https://developers.eos.io/manuals/eosio.cdt/latest/structeosio_1_1blockchain__parameters#variable-min_transaction_cpu_usage), and [maximum NET](https://developers.eos.io/manuals/eosio.cdt/latest/structeosio_1_1blockchain__parameters#variable-max_transaction_net_usage) limits. Transactions executed by the blockchain contain one or more actions, and each transaction must consume an amount of CPU and NET which is in the limits defined by the aforementioned blockchain settings. + +#### System Resources Replenish Algorithm + +EOSIO-based blockchains replenish automatically the consumed CPU and NET system resources. Before a transaction is executed, by the blockchain, it first calculates how many resources the account executing the transaction can consume. The calculation uses an exponential moving average with linear extrapolation when data is missing, and it multiplies the currently accumulated average by `(number of blocks in the window - number of blocks since last update) / (number of blocks in the window)`. The window is set as 24 hours window. + +This formula has the following outcomes: + +* If an account waited `number of blocks in the window` without executing any transaction it resets to zero usage. + +* If an account issues a transaction with every block it would always be `(number of blocks in the window - 1) / (number of blocks in the window)`, a very small value, very close to zero. Mathematically it _never_ reaches zero but the EOSIO implementation truncates off the tiny numbers to zero. + +* The accounts that execute transactions more often than the ones that execute less transactions, replenish their resources slower than the later. In other words, the more transactions an account executes the slower the replenish of resources. + +### Buy RAM + +The RAM resource must be bought using the system token. Refer to the [cleos manual](https://developers.eos.io/manuals/eos/v2.0/cleos/how-to-guides/how-to-buy-ram) to learn how to do it via the command line interface. When an account consumes all its allocated RAM can not store any additional information on the blockchain database until it frees some of the occupied RAM or more RAM is allocated to the account through the RAM buying process. diff --git a/docs/01_key-concepts/06_vote.md b/docs/01_key-concepts/06_vote.md index 5daaac72..4aa8ba6b 100644 --- a/docs/01_key-concepts/06_vote.md +++ b/docs/01_key-concepts/06_vote.md @@ -1,6 +1,6 @@ --- -content_title: Voting on EOSIO based blockchains -link_text: Voting on EOSIO based blockchains +content_title: Voting on EOSIO-based blockchains +link_text: Voting on EOSIO-based blockchains --- -In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected into a mesh, communicating with each other via peer to peer protocols. Some of these nodes are elected, via a __voting__ process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain memory. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' __votes__. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. \ No newline at end of file +In a EOSIO-based network the blockchain is kept alive by nodes which are interconnected between each other, communicating with each other via peer to peer protocols. Some of these nodes are elected, via a voting process, by the token holders to be producer nodes. They produce blocks, validate them and reach consensus on what transactions are allowed in each block, their order, and what blocks are finalized and stored forever in the blockchain. This way the governance, the mechanism by which collective decisions are made, of the blockchain is achieved through the 21 active block producers which are appointed by token holders' votes. It's the 21 active block producers which continuously create the blockchain by creating blocks, and securing them by validating them, and reaching consensus. Consensus is reached when 2/3+1 active block producers agree on validity of a block, that is all transactions contained in it and their order. The 21 producers is the default value however it can be configured to be higher or smaller to meet each business case requirements. From a726337233e00b335c00bf380350e76a583ed77a Mon Sep 17 00:00:00 2001 From: iamveritas Date: Fri, 6 Nov 2020 23:31:44 +0200 Subject: [PATCH 1035/1048] Add specific info for 1.9.x --- docs/01_key-concepts/05_stake.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/01_key-concepts/05_stake.md b/docs/01_key-concepts/05_stake.md index bda75448..d8904d9d 100644 --- a/docs/01_key-concepts/05_stake.md +++ b/docs/01_key-concepts/05_stake.md @@ -42,6 +42,9 @@ This formula has the following outcomes: * The accounts that execute transactions more often than the ones that execute less transactions, replenish their resources slower than the later. In other words, the more transactions an account executes the slower the replenish of resources. +[[info]] +| The blockchain calculates and updates the remaining resources, for the accounts which execute transactions, with each block, before each transaction is executed. As time passes, as explained above, the consumed system resources are gradually replenished, and the available system resources increase, or decrease, depending on how many transactions an account executes. After waiting for some time, if you check the available resources balance and expect to see it increased, because your account did not executed any transactions, you will not see it updated. That is because it gets updated only before a transaction is executed. Therefore in order to see the available resources you have to execute a transaction. This is counter intuitive and the next versions will improve this aspect. + ### Buy RAM The RAM resource must be bought using the system token. Refer to the [cleos manual](https://developers.eos.io/manuals/eos/v2.0/cleos/how-to-guides/how-to-buy-ram) to learn how to do it via the command line interface. When an account consumes all its allocated RAM can not store any additional information on the blockchain database until it frees some of the occupied RAM or more RAM is allocated to the account through the RAM buying process. From 7692a8af47aec48c7d3bb2944af1bcb0153c4034 Mon Sep 17 00:00:00 2001 From: deck Date: Mon, 30 Nov 2020 12:12:49 -0500 Subject: [PATCH 1036/1048] rename rentbw to powerup --- contracts/eosio.system/CMakeLists.txt | 11 +- .../include/eosio.system/eosio.system.hpp | 85 ++--- .../include/eosio.system/powerup.results.hpp | 33 ++ .../src/{rentbw.cpp => powerup.cpp} | 87 ++--- .../eosio.system/src/powerup.results.cpp | 5 + ...ntbw_tests.cpp => eosio.powerup_tests.cpp} | 304 +++++++++--------- 6 files changed, 289 insertions(+), 236 deletions(-) create mode 100644 contracts/eosio.system/include/eosio.system/powerup.results.hpp rename contracts/eosio.system/src/{rentbw.cpp => powerup.cpp} (81%) create mode 100644 contracts/eosio.system/src/powerup.results.cpp rename tests/{eosio.rentbw_tests.cpp => eosio.powerup_tests.cpp} (77%) diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt index 58552543..6b47d156 100644 --- a/contracts/eosio.system/CMakeLists.txt +++ b/contracts/eosio.system/CMakeLists.txt @@ -5,7 +5,7 @@ add_contract(eosio.system eosio.system ${CMAKE_CURRENT_SOURCE_DIR}/src/name_bidding.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/rentbw.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/powerup.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp ${CMAKE_CURRENT_SOURCE_DIR}/src/voting.cpp ) @@ -20,15 +20,24 @@ set_target_properties(eosio.system RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") add_contract(rex.results rex.results ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.results.cpp) +add_contract(powup.results powup.results ${CMAKE_CURRENT_SOURCE_DIR}/src/powerup.results.cpp) target_include_directories(rex.results PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) +target_include_directories(powup.results + PUBLIC + ${CMAKE_CURRENT_SOURCE_DIR}/include) + set_target_properties(rex.results PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.rex") +set_target_properties(powup.results + PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.powerup") + configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.system.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.system.contracts.md @ONLY ) target_compile_options( eosio.system PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index 2479205a..a70726f1 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -40,7 +40,7 @@ namespace eosiosystem { using eosio::time_point_sec; using eosio::unsigned_int; - inline constexpr int64_t rentbw_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 + inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 template static inline auto has_field( F flags, E field ) @@ -525,7 +525,7 @@ namespace eosiosystem { asset stake_change; }; - struct rentbw_config_resource { + struct powerup_config_resource { std::optional current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. // Do not specify to preserve the existing setting or use the default; // this avoids sudden price jumps. For new chains which don't need @@ -534,7 +534,7 @@ namespace eosiosystem { std::optional target_weight_ratio; // Linearly shrink weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. // Do not specify to preserve the existing setting or use the default. std::optional assumed_stake_weight; // Assumed stake weight for ratio calculations. Use the sum of total - // staked and total rented by REX at the time the rentbw market + // staked and total rented by REX at the time the power market // is first activated. Do not specify to preserve the existing // setting (no default exists); this avoids sudden price jumps. // For new chains which don't need to phase out staking and REX, @@ -558,22 +558,22 @@ namespace eosiosystem { // token supply. Do not specify to preserve the existing // setting (no default exists). - EOSLIB_SERIALIZE( rentbw_config_resource, (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight) + EOSLIB_SERIALIZE( powerup_config_resource, (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight) (target_timestamp)(exponent)(decay_secs)(min_price)(max_price) ) }; - struct rentbw_config { - rentbw_config_resource net; // NET market configuration - rentbw_config_resource cpu; // CPU market configuration - std::optional rent_days; // `rentbw` `days` argument must match this. Do not specify to preserve the + struct powerup_config { + powerup_config_resource net; // NET market configuration + powerup_config_resource cpu; // CPU market configuration + std::optional powerup_days; // `power` `days` argument must match this. Do not specify to preserve the // existing setting or use the default. - std::optional min_rent_fee; // Rental fees below this amount are rejected. Do not specify to preserve the + std::optional min_powerup_fee; // Rental fees below this amount are rejected. Do not specify to preserve the // existing setting (no default exists). - EOSLIB_SERIALIZE( rentbw_config, (net)(cpu)(rent_days)(min_rent_fee) ) + EOSLIB_SERIALIZE( powerup_config, (net)(cpu)(powerup_days)(min_powerup_fee) ) }; - struct rentbw_state_resource { + struct powerup_state_resource { static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to rent a // tiny amount of resources increases linearly // with utilization. @@ -591,8 +591,8 @@ namespace eosiosystem { // assumed_stake_weight / (assumed_stake_weight + weight). // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. - int64_t initial_weight_ratio = rentbw_frac; // Initial weight_ratio used for linear shrinkage. - int64_t target_weight_ratio = rentbw_frac / 100; // Linearly shrink the weight_ratio to this amount. + int64_t initial_weight_ratio = powerup_frac; // Initial weight_ratio used for linear shrinkage. + int64_t target_weight_ratio = powerup_frac / 100; // Linearly shrink the weight_ratio to this amount. time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this // time hits, weight_ratio will be target_weight_ratio. @@ -610,21 +610,21 @@ namespace eosiosystem { time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated }; - struct [[eosio::table("rent.state"),eosio::contract("eosio.system")]] rentbw_state { - static constexpr uint32_t default_rent_days = 30; // 30 day resource rentals + struct [[eosio::table("powup.state"),eosio::contract("eosio.system")]] powerup_state { + static constexpr uint32_t default_powerup_days = 30; // 30 day resource powerups - uint8_t version = 0; - rentbw_state_resource net = {}; // NET market state - rentbw_state_resource cpu = {}; // CPU market state - uint32_t rent_days = default_rent_days; // `rentbw` `days` argument must match this. - asset min_rent_fee = {}; // Rental fees below this amount are rejected + uint8_t version = 0; + powerup_state_resource net = {}; // NET market state + powerup_state_resource cpu = {}; // CPU market state + uint32_t powerup_days = default_powerup_days; // `powerup` `days` argument must match this. + asset min_powerup_fee = {}; // fees below this amount are rejected uint64_t primary_key()const { return 0; } }; - typedef eosio::singleton<"rent.state"_n, rentbw_state> rentbw_state_singleton; + typedef eosio::singleton<"powup.state"_n, powerup_state> powerup_state_singleton; - struct [[eosio::table("rentbw.order"),eosio::contract("eosio.system")]] rentbw_order { + struct [[eosio::table("powup.order"),eosio::contract("eosio.system")]] powerup_order { uint8_t version = 0; uint64_t id; name owner; @@ -637,13 +637,16 @@ namespace eosiosystem { uint64_t by_expires()const { return expires.utc_seconds; } }; - typedef eosio::multi_index< "rentbw.order"_n, rentbw_order, - indexed_by<"byowner"_n, const_mem_fun>, - indexed_by<"byexpires"_n, const_mem_fun> - > rentbw_order_table; + typedef eosio::multi_index< "powup.order"_n, powerup_order, + indexed_by<"byowner"_n, const_mem_fun>, + indexed_by<"byexpires"_n, const_mem_fun> + > powerup_order_table; /** - * eosio.system contract defines the structures and actions needed for blockchain's core functionality. + * The `eosio.system` smart contract is provided by `block.one` as a sample system contract, and it defines the structures and actions needed for blockchain's core functionality. + * + * Just like in the `eosio.bios` sample contract implementation, there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the `eosio.system` contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. + * * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or * delegate their vote to a proxy. * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. @@ -651,7 +654,7 @@ namespace eosiosystem { * - Users can bid on premium names. * - A resource exchange system (REX) allows token holders to lend their tokens, * and users to rent CPU and Network resources in return for a market-determined fee. - * - A resource market separate from REX: `rentbw`. + * - A resource market separate from REX: `power`. */ class [[eosio::contract("eosio.system")]] system_contract : public native { @@ -1296,23 +1299,23 @@ namespace eosiosystem { void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); /** - * Configure the `rentbw` market. The market becomes available the first time this + * Configure the `power` market. The market becomes available the first time this * action is invoked. */ [[eosio::action]] - void configrentbw( rentbw_config& args ); + void cfgpowerup( powerup_config& args ); /** - * Process rentbw queue and update state. Action does not execute anything related to a specific user. + * Process power queue and update state. Action does not execute anything related to a specific user. * * @param user - any account can execute this action * @param max - number of queue items to process */ [[eosio::action]] - void rentbwexec( const name& user, uint16_t max ); + void powerupexec( const name& user, uint16_t max ); /** - * Rent NET and CPU + * Rent NET and CPU by percentage * * @param payer - the resource buyer * @param receiver - the resource receiver @@ -1323,7 +1326,7 @@ namespace eosiosystem { * `payer`'s token balance. */ [[eosio::action]] - void rentbw( const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment ); + void powerup( const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment ); using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; @@ -1371,9 +1374,9 @@ namespace eosiosystem { using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; - using configrentbw_action = eosio::action_wrapper<"configrentbw"_n, &system_contract::configrentbw>; - using rentbwexec_action = eosio::action_wrapper<"rentbwexec"_n, &system_contract::rentbwexec>; - using rentbw_action = eosio::action_wrapper<"rentbw"_n, &system_contract::rentbw>; + using cfgpowerup_action = eosio::action_wrapper<"cfgpowerup"_n, &system_contract::cfgpowerup>; + using powerupexec_action = eosio::action_wrapper<"powerupexec"_n, &system_contract::powerupexec>; + using powerup_action = eosio::action_wrapper<"powerup"_n, &system_contract::powerup>; private: // Implementation details: @@ -1475,11 +1478,11 @@ namespace eosiosystem { registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; - // defined in rentbw.cpp + // defined in power.cpp void adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); - void process_rentbw_queue( - time_point_sec now, symbol core_symbol, rentbw_state& state, - rentbw_order_table& orders, uint32_t max_items, int64_t& net_delta_available, + void process_queue( + time_point_sec now, symbol core_symbol, powerup_state& state, + powerup_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available); }; diff --git a/contracts/eosio.system/include/eosio.system/powerup.results.hpp b/contracts/eosio.system/include/eosio.system/powerup.results.hpp new file mode 100644 index 00000000..52d86cd1 --- /dev/null +++ b/contracts/eosio.system/include/eosio.system/powerup.results.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include +#include +#include + +using eosio::action_wrapper; +using eosio::asset; +using eosio::name; + +/** + * The action `powerresult` of `power.results` is a no-op. + * It is added as an inline convenience action to `power` rental. + * This inline convenience action does not have any effect, however, + * its data includes the result of the parent action and appears in its trace. + */ +class [[eosio::contract("powup.results")]] powup_results : eosio::contract { + public: + + using eosio::contract::contract; + + /** + * powupresult action. + * + * @param fee - rental fee amount + * @param powup_net - amount of powup NET tokens + * @param powup_cpu - amount of powup CPU tokens + */ + [[eosio::action]] + void powupresult( const asset& fee, const asset& powup_net, const asset& powup_cpu ); + + using powupresult_action = action_wrapper<"powupresult"_n, &powup_results::powupresult>; +}; diff --git a/contracts/eosio.system/src/rentbw.cpp b/contracts/eosio.system/src/powerup.cpp similarity index 81% rename from contracts/eosio.system/src/rentbw.cpp rename to contracts/eosio.system/src/powerup.cpp index 195f53d3..ebab2615 100644 --- a/contracts/eosio.system/src/rentbw.cpp +++ b/contracts/eosio.system/src/powerup.cpp @@ -1,11 +1,12 @@ #include #include +#include #include #include namespace eosiosystem { -void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delta_available); +void update_weight(time_point_sec now, powerup_state_resource& res, int64_t& delta_available); /** * @pre now >= res.utilization_timestamp @@ -13,7 +14,7 @@ void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delt * @post if res.utilization < old res.adjusted_utilization, then new res.adjusted_utilization <= old res.adjusted_utilization * @post if res.utilization >= old res.adjusted_utilization, then new res.adjusted_utilization == res.utilization */ -void update_utilization(time_point_sec now, rentbw_state_resource& res); +void update_utilization(time_point_sec now, powerup_state_resource& res); void system_contract::adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed) { @@ -66,8 +67,8 @@ void system_contract::adjust_resources(name payer, name account, symbol core_sym } } // system_contract::adjust_resources -void system_contract::process_rentbw_queue(time_point_sec now, symbol core_symbol, rentbw_state& state, - rentbw_order_table& orders, uint32_t max_items, int64_t& net_delta_available, +void system_contract::process_queue(time_point_sec now, symbol core_symbol, powerup_state& state, + powerup_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available) { update_utilization(now, state.net); update_utilization(now, state.cpu); @@ -87,7 +88,7 @@ void system_contract::process_rentbw_queue(time_point_sec now, symbol core_symbo update_weight(now, state.cpu, cpu_delta_available); } -void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delta_available) { +void update_weight(time_point_sec now, powerup_state_resource& res, int64_t& delta_available) { if (now >= res.target_timestamp) { res.weight_ratio = res.target_weight_ratio; } else { @@ -96,12 +97,12 @@ void update_weight(time_point_sec now, rentbw_state_resource& res, int64_t& delt (now.utc_seconds - res.initial_timestamp.utc_seconds) / (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); } - int64_t new_weight = res.assumed_stake_weight * int128_t(rentbw_frac) / res.weight_ratio - res.assumed_stake_weight; + int64_t new_weight = res.assumed_stake_weight * int128_t(powerup_frac) / res.weight_ratio - res.assumed_stake_weight; delta_available += new_weight - res.weight; res.weight = new_weight; } -void update_utilization(time_point_sec now, rentbw_state_resource& res) { +void update_utilization(time_point_sec now, powerup_state_resource& res) { if (now <= res.utilization_timestamp) return; if (res.utilization >= res.adjusted_utilization) { @@ -115,11 +116,11 @@ void update_utilization(time_point_sec now, rentbw_state_resource& res) { res.utilization_timestamp = now; } -void system_contract::configrentbw(rentbw_config& args) { +void system_contract::cfgpowerup(powerup_config& args) { require_auth(get_self()); time_point_sec now = eosio::current_time_point(); auto core_symbol = get_core_symbol(); - rentbw_state_singleton state_sing{ get_self(), 0 }; + powerup_state_singleton state_sing{ get_self(), 0 }; auto state = state_sing.get_or_default(); eosio::check(eosio::is_account(reserv_account), "eosio.reserv account must first be created"); @@ -191,12 +192,12 @@ void system_contract::configrentbw(rentbw_config& args) { } eosio::check(*args.current_weight_ratio > 0, "current_weight_ratio is too small"); - eosio::check(*args.current_weight_ratio <= rentbw_frac, "current_weight_ratio is too large"); + eosio::check(*args.current_weight_ratio <= powerup_frac, "current_weight_ratio is too large"); eosio::check(*args.target_weight_ratio > 0, "target_weight_ratio is too small"); eosio::check(*args.target_weight_ratio <= *args.current_weight_ratio, "weight can't grow over time"); eosio::check(*args.assumed_stake_weight >= 1, "assumed_stake_weight must be at least 1; a much larger value is recommended"); - eosio::check(*args.assumed_stake_weight * int128_t(rentbw_frac) / *args.target_weight_ratio <= + eosio::check(*args.assumed_stake_weight * int128_t(powerup_frac) / *args.target_weight_ratio <= std::numeric_limits::max(), "assumed_stake_weight/target_weight_ratio is too large"); eosio::check(*args.exponent >= 1.0, "exponent must be >= 1"); @@ -221,21 +222,21 @@ void system_contract::configrentbw(rentbw_config& args) { state.max_price = *args.max_price; }; - if (!args.rent_days) { - *args.rent_days = state.rent_days; + if (!args.powerup_days) { + *args.powerup_days = state.powerup_days; } - if (!args.min_rent_fee) { - eosio::check(!is_default_asset(state.min_rent_fee), "min_rent_fee does not have a default value"); - *args.min_rent_fee = state.min_rent_fee; + if (!args.min_powerup_fee) { + eosio::check(!is_default_asset(state.min_powerup_fee), "min_powerup_fee does not have a default value"); + *args.min_powerup_fee = state.min_powerup_fee; } - eosio::check(*args.rent_days > 0, "rent_days must be > 0"); - eosio::check(args.min_rent_fee->symbol == core_symbol, "min_rent_fee doesn't match core symbol"); - eosio::check(args.min_rent_fee->amount > 0, "min_rent_fee must be positive"); + eosio::check(*args.powerup_days > 0, "powerup_days must be > 0"); + eosio::check(args.min_powerup_fee->symbol == core_symbol, "min_powerup_fee doesn't match core symbol"); + eosio::check(args.min_powerup_fee->amount > 0, "min_powerup_fee must be positive"); - state.rent_days = *args.rent_days; - state.min_rent_fee = *args.min_rent_fee; + state.powerup_days = *args.powerup_days; + state.min_powerup_fee = *args.min_powerup_fee; update(state.net, args.net); update(state.cpu, args.cpu); @@ -249,7 +250,7 @@ void system_contract::configrentbw(rentbw_config& args) { adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); state_sing.set(state, get_self()); -} // system_contract::configrentbw +} // system_contract::configpower /** * @pre 0 <= state.min_price.amount <= state.max_price.amount @@ -258,7 +259,7 @@ void system_contract::configrentbw(rentbw_config& args) { * @pre 0 <= state.utilization <= state.adjusted_utilization <= state.weight * @pre 0 <= utilization_increase <= (state.weight - state.utilization) */ -int64_t calc_rentbw_fee(const rentbw_state_resource& state, int64_t utilization_increase) { +int64_t calc_powerup_fee(const powerup_state_resource& state, int64_t utilization_increase) { if( utilization_increase <= 0 ) return 0; // Let p(u) = price as a function of the utilization fraction u which is defined for u in [0.0, 1.0]. @@ -278,8 +279,6 @@ int64_t calc_rentbw_fee(const rentbw_state_resource& state, int64_t utilization_ coefficient * std::pow(end_u, state.exponent) - coefficient * std::pow(start_u, state.exponent); }; - // Returns p(double(utilization)/state.weight). - // @pre 0 <= utilization <= state.weight auto price_function = [&state](int64_t utilization) -> double { double price = state.min_price.amount; // state.exponent >= 1.0, therefore the exponent passed into std::pow is >= 0.0. @@ -313,51 +312,51 @@ int64_t calc_rentbw_fee(const rentbw_state_resource& state, int64_t utilization_ return std::ceil(fee); } -void system_contract::rentbwexec(const name& user, uint16_t max) { +void system_contract::powerupexec(const name& user, uint16_t max) { require_auth(user); - rentbw_state_singleton state_sing{ get_self(), 0 }; - rentbw_order_table orders{ get_self(), 0 }; - eosio::check(state_sing.exists(), "rentbw hasn't been initialized"); + powerup_state_singleton state_sing{ get_self(), 0 }; + powerup_order_table orders{ get_self(), 0 }; + eosio::check(state_sing.exists(), "powerup hasn't been initialized"); auto state = state_sing.get(); time_point_sec now = eosio::current_time_point(); auto core_symbol = get_core_symbol(); int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; - process_rentbw_queue(now, core_symbol, state, orders, max, net_delta_available, cpu_delta_available); + process_queue(now, core_symbol, state, orders, max, net_delta_available, cpu_delta_available); adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); state_sing.set(state, get_self()); } -void system_contract::rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, +void system_contract::powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment) { require_auth(payer); - rentbw_state_singleton state_sing{ get_self(), 0 }; - rentbw_order_table orders{ get_self(), 0 }; - eosio::check(state_sing.exists(), "rentbw hasn't been initialized"); + powerup_state_singleton state_sing{ get_self(), 0 }; + powerup_order_table orders{ get_self(), 0 }; + eosio::check(state_sing.exists(), "powerup hasn't been initialized"); auto state = state_sing.get(); time_point_sec now = eosio::current_time_point(); auto core_symbol = get_core_symbol(); eosio::check(max_payment.symbol == core_symbol, "max_payment doesn't match core symbol"); - eosio::check(days == state.rent_days, "days doesn't match configuration"); + eosio::check(days == state.powerup_days, "days doesn't match configuration"); eosio::check(net_frac >= 0, "net_frac can't be negative"); eosio::check(cpu_frac >= 0, "cpu_frac can't be negative"); - eosio::check(net_frac <= rentbw_frac, "net can't be more than 100%"); - eosio::check(cpu_frac <= rentbw_frac, "cpu can't be more than 100%"); + eosio::check(net_frac <= powerup_frac, "net can't be more than 100%"); + eosio::check(cpu_frac <= powerup_frac, "cpu can't be more than 100%"); int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; - process_rentbw_queue(now, core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); + process_queue(now, core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); eosio::asset fee{ 0, core_symbol }; - auto process = [&](int64_t frac, int64_t& amount, rentbw_state_resource& state) { + auto process = [&](int64_t frac, int64_t& amount, powerup_state_resource& state) { if (!frac) return; - amount = int128_t(frac) * state.weight / rentbw_frac; + amount = int128_t(frac) * state.weight / powerup_frac; eosio::check(state.weight, "market doesn't have resources available"); eosio::check(state.utilization + amount <= state.weight, "market doesn't have enough resources available"); - int64_t f = calc_rentbw_fee(state, amount); + int64_t f = calc_powerup_fee(state, amount); eosio::check(f > 0, "calculated fee is below minimum; try renting more"); fee.amount += f; state.utilization += amount; @@ -372,7 +371,7 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d error_msg += fee.to_string(); eosio::check(false, error_msg); } - eosio::check(fee >= state.min_rent_fee, "calculated fee is below minimum; try renting more"); + eosio::check(fee >= state.min_powerup_fee, "calculated fee is below minimum; try renting more"); orders.emplace(payer, [&](auto& order) { order.id = orders.available_primary_key(); @@ -388,6 +387,10 @@ void system_contract::rentbw(const name& payer, const name& receiver, uint32_t d adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); channel_to_rex(payer, fee, true); state_sing.set(state, get_self()); + + // inline noop action + powup_results::powupresult_action powupresult_act{ reserv_account, std::vector{ } }; + powupresult_act.send( fee, asset{ net_amount, core_symbol }, asset{ cpu_amount, core_symbol } ); } } // namespace eosiosystem diff --git a/contracts/eosio.system/src/powerup.results.cpp b/contracts/eosio.system/src/powerup.results.cpp new file mode 100644 index 00000000..7b9c8026 --- /dev/null +++ b/contracts/eosio.system/src/powerup.results.cpp @@ -0,0 +1,5 @@ +#include + +void powup_results::powupresult( const asset& fee, const asset& powup_net, const asset& powup_cpu ) { } + +extern "C" void apply( uint64_t, uint64_t, uint64_t ) { } diff --git a/tests/eosio.rentbw_tests.cpp b/tests/eosio.powerup_tests.cpp similarity index 77% rename from tests/eosio.rentbw_tests.cpp rename to tests/eosio.powerup_tests.cpp index 115bfa83..fa12fc07 100644 --- a/tests/eosio.rentbw_tests.cpp +++ b/tests/eosio.powerup_tests.cpp @@ -12,10 +12,10 @@ #include "eosio.system_tester.hpp" -inline constexpr int64_t rentbw_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 +inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 inline constexpr int64_t stake_weight = 100'000'000'0000ll; // 10^12 -struct rentbw_config_resource { +struct powerup_config_resource { fc::optional current_weight_ratio = {}; fc::optional target_weight_ratio = {}; fc::optional assumed_stake_weight = {}; @@ -25,19 +25,19 @@ struct rentbw_config_resource { fc::optional min_price = {}; fc::optional max_price = {}; }; -FC_REFLECT(rentbw_config_resource, // +FC_REFLECT(powerup_config_resource, // (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight)(target_timestamp) // (exponent)(decay_secs)(min_price)(max_price)) -struct rentbw_config { - rentbw_config_resource net = {}; - rentbw_config_resource cpu = {}; - fc::optional rent_days = {}; - fc::optional min_rent_fee = {}; +struct powerup_config { + powerup_config_resource net = {}; + powerup_config_resource cpu = {}; + fc::optional powerup_days = {}; + fc::optional min_powerup_fee = {}; }; -FC_REFLECT(rentbw_config, (net)(cpu)(rent_days)(min_rent_fee)) +FC_REFLECT(powerup_config, (net)(cpu)(powerup_days)(min_powerup_fee)) -struct rentbw_state_resource { +struct powerup_state_resource { uint8_t version; int64_t weight; int64_t weight_ratio; @@ -54,25 +54,25 @@ struct rentbw_state_resource { int64_t adjusted_utilization; time_point_sec utilization_timestamp; }; -FC_REFLECT(rentbw_state_resource, // +FC_REFLECT(powerup_state_resource, // (version)(weight)(weight_ratio)(assumed_stake_weight)(initial_weight_ratio)(target_weight_ratio) // (initial_timestamp)(target_timestamp)(exponent)(decay_secs)(min_price)(max_price)(utilization) // (adjusted_utilization)(utilization_timestamp)) -struct rentbw_state { +struct powerup_state { uint8_t version; - rentbw_state_resource net; - rentbw_state_resource cpu; - uint32_t rent_days; - asset min_rent_fee; + powerup_state_resource net; + powerup_state_resource cpu; + uint32_t powerup_days; + asset min_powerup_fee; }; -FC_REFLECT(rentbw_state, (version)(net)(cpu)(rent_days)(min_rent_fee)) +FC_REFLECT(powerup_state, (version)(net)(cpu)(powerup_days)(min_powerup_fee)) using namespace eosio_system; -struct rentbw_tester : eosio_system_tester { +struct powerup_tester : eosio_system_tester { - rentbw_tester() { create_accounts_with_resources({ N(eosio.reserv) }); } + powerup_tester() { create_accounts_with_resources({ N(eosio.reserv) }); } void start_rex() { create_account_with_resources(N(rexholder111), config::system_account_name, core_sym::from_string("1.0000"), @@ -92,11 +92,11 @@ struct rentbw_tester : eosio_system_tester { } template - rentbw_config make_config(F f) { - rentbw_config config; + powerup_config make_config(F f) { + powerup_config config; - config.net.current_weight_ratio = rentbw_frac; - config.net.target_weight_ratio = rentbw_frac / 100; + config.net.current_weight_ratio = powerup_frac; + config.net.target_weight_ratio = powerup_frac / 100; config.net.assumed_stake_weight = stake_weight; config.net.target_timestamp = control->head_block_time() + fc::days(100); config.net.exponent = 2; @@ -104,8 +104,8 @@ struct rentbw_tester : eosio_system_tester { config.net.min_price = asset::from_string("0.0000 TST"); config.net.max_price = asset::from_string("1000000.0000 TST"); - config.cpu.current_weight_ratio = rentbw_frac; - config.cpu.target_weight_ratio = rentbw_frac / 100; + config.cpu.current_weight_ratio = powerup_frac; + config.cpu.target_weight_ratio = powerup_frac / 100; config.cpu.assumed_stake_weight = stake_weight; config.cpu.target_timestamp = control->head_block_time() + fc::days(100); config.cpu.exponent = 2; @@ -113,25 +113,25 @@ struct rentbw_tester : eosio_system_tester { config.cpu.min_price = asset::from_string("0.0000 TST"); config.cpu.max_price = asset::from_string("1000000.0000 TST"); - config.rent_days = 30; - config.min_rent_fee = asset::from_string("1.0000 TST"); + config.powerup_days = 30; + config.min_powerup_fee = asset::from_string("1.0000 TST"); f(config); return config; } - rentbw_config make_config() { + powerup_config make_config() { return make_config([](auto&) {}); } template - rentbw_config make_default_config(F f) { - rentbw_config config; + powerup_config make_default_config(F f) { + powerup_config config; f(config); return config; } - action_result configbw(const rentbw_config& config) { + action_result configbw(const powerup_config& config) { // Verbose solution needed to work around bug in abi_serializer that fails if optional values aren't explicitly // specified with a null value. @@ -139,7 +139,7 @@ struct rentbw_tester : eosio_system_tester { return (!v ? fc::variant() : fc::variant(*v)); }; - auto resource_conf_vo = [&optional_to_variant](const rentbw_config_resource& c ) { + auto resource_conf_vo = [&optional_to_variant](const powerup_config_resource& c ) { return mvo("current_weight_ratio", optional_to_variant(c.current_weight_ratio)) ("target_weight_ratio", optional_to_variant(c.target_weight_ratio)) ("assumed_stake_weight", optional_to_variant(c.assumed_stake_weight)) @@ -153,31 +153,31 @@ struct rentbw_tester : eosio_system_tester { auto conf = mvo("net", resource_conf_vo(config.net)) ("cpu", resource_conf_vo(config.cpu)) - ("rent_days", optional_to_variant(config.rent_days)) - ("min_rent_fee", optional_to_variant(config.min_rent_fee)) + ("powerup_days", optional_to_variant(config.powerup_days)) + ("min_powerup_fee", optional_to_variant(config.min_powerup_fee)) ; //idump((fc::json::to_pretty_string(conf))); - return push_action(config::system_account_name, N(configrentbw), mvo()("args", std::move(conf))); + return push_action(config::system_account_name, N(cfgpowerup), mvo()("args", std::move(conf))); // If abi_serializer worked correctly, the following is all that would be needed: - //return push_action(config::system_account_name, N(configrentbw), mvo()("args", config)); + //return push_action(config::system_account_name, N(cfgpowerup), mvo()("args", config)); } - action_result rentbwexec(name user, uint16_t max) { - return push_action(user, N(rentbwexec), mvo()("user", user)("max", max)); + action_result powerupexec(name user, uint16_t max) { + return push_action(user, N(powerupexec), mvo()("user", user)("max", max)); } - action_result rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, + action_result powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment) { - return push_action(payer, N(rentbw), + return push_action(payer, N(powerup), mvo()("payer", payer)("receiver", receiver)("days", days)("net_frac", net_frac)( "cpu_frac", cpu_frac)("max_payment", max_payment)); } - rentbw_state get_state() { - vector data = get_row_by_account(config::system_account_name, {}, N(rent.state), N(rent.state)); - return fc::raw::unpack(data); + powerup_state get_state() { + vector data = get_row_by_account(config::system_account_name, {}, N(powup.state), N(powup.state)); + return fc::raw::unpack(data); } struct account_info { @@ -194,13 +194,13 @@ struct rentbw_tester : eosio_system_tester { return info; }; - void check_rentbw(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, + void check_powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& expected_fee, int64_t expected_net, int64_t expected_cpu) { auto before_payer = get_account_info(payer); auto before_receiver = get_account_info(receiver); auto before_reserve = get_account_info(N(eosio.reserv)); auto before_state = get_state(); - BOOST_REQUIRE_EQUAL("", rentbw(payer, receiver, days, net_frac, cpu_frac, expected_fee)); + BOOST_REQUIRE_EQUAL("", powerup(payer, receiver, days, net_frac, cpu_frac, expected_fee)); auto after_payer = get_account_info(payer); auto after_receiver = get_account_info(receiver); auto after_reserve = get_account_info(N(eosio.reserv)); @@ -209,7 +209,7 @@ struct rentbw_tester : eosio_system_tester { if (false) { ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); ilog("before_state.net.weight_ratio: ${x}", - ("x", before_state.net.weight_ratio / double(rentbw_frac))); + ("x", before_state.net.weight_ratio / double(powerup_frac))); ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); ilog("before_state.net.weight: ${x}", ("x", before_state.net.weight)); @@ -252,35 +252,35 @@ bool near(A a, B b, D delta) { return false; } -BOOST_AUTO_TEST_SUITE(eosio_system_rentbw_tests) +BOOST_AUTO_TEST_SUITE(eosio_system_powerup_tests) -BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { +BOOST_FIXTURE_TEST_CASE(config_tests, powerup_tester) try { BOOST_REQUIRE_EQUAL("missing authority of eosio", - push_action(N(alice1111111), N(configrentbw), mvo()("args", make_config()))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("rentbw hasn't been initialized"), rentbwexec(N(alice1111111), 10)); + push_action(N(alice1111111), N(cfgpowerup), mvo()("args", make_config()))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("powerup hasn't been initialized"), powerupexec(N(alice1111111), 10)); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("rent_days must be > 0"), - configbw(make_config([&](auto& c) { c.rent_days = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.min_rent_fee = asset::from_string("1000000.000 TST"); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("powerup_days must be > 0"), + configbw(make_config([&](auto& c) { c.powerup_days = 0; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee doesn't match core symbol"), configbw(make_config([&](auto& c) { + c.min_powerup_fee = asset::from_string("1000000.000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee does not have a default value"), - configbw(make_config([&](auto& c) { c.min_rent_fee = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee must be positive"), - configbw(make_config([&](auto& c) { c.min_rent_fee = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_rent_fee must be positive"), - configbw(make_config([&](auto& c) { c.min_rent_fee = asset::from_string("-1.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee does not have a default value"), + configbw(make_config([&](auto& c) { c.min_powerup_fee = {}; }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee must be positive"), + configbw(make_config([&](auto& c) { c.min_powerup_fee = asset::from_string("0.0000 TST"); }))); + BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee must be positive"), + configbw(make_config([&](auto& c) { c.min_powerup_fee = asset::from_string("-1.0000 TST"); }))); // net assertions BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), - configbw(make_config([](auto& c) { c.net.current_weight_ratio = rentbw_frac + 1; }))); + configbw(make_config([](auto& c) { c.net.current_weight_ratio = powerup_frac + 1; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), configbw(make_config([](auto& c) { c.net.assumed_stake_weight = 100000; c.net.target_weight_ratio = 10; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), - configbw(make_config([](auto& c) { c.net.target_weight_ratio = rentbw_frac + 1; }))); + configbw(make_config([](auto& c) { c.net.target_weight_ratio = powerup_frac + 1; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), configbw(make_config([](auto& c) { c.net.assumed_stake_weight = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), @@ -318,14 +318,14 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { // cpu assertions BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), - configbw(make_config([](auto& c) { c.cpu.current_weight_ratio = rentbw_frac + 1; }))); + configbw(make_config([](auto& c) { c.cpu.current_weight_ratio = powerup_frac + 1; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = 100000; c.cpu.target_weight_ratio = 10; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), - configbw(make_config([](auto& c) { c.cpu.target_weight_ratio = rentbw_frac + 1; }))); + configbw(make_config([](auto& c) { c.cpu.target_weight_ratio = powerup_frac + 1; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = {}; }))); BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), @@ -363,15 +363,15 @@ BOOST_FIXTURE_TEST_CASE(config_tests, rentbw_tester) try { } // config_tests FC_LOG_AND_RETHROW() -BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { +BOOST_FIXTURE_TEST_CASE(weight_tests, powerup_tester) try { produce_block(); - auto net_start = (rentbw_frac * 11) / 100; - auto net_target = (rentbw_frac * 1) / 100; - auto cpu_start = (rentbw_frac * 11) / 1000; - auto cpu_target = (rentbw_frac * 1) / 1000; + auto net_start = (powerup_frac * 11) / 100; + auto net_target = (powerup_frac * 1) / 100; + auto cpu_start = (powerup_frac * 11) / 1000; + auto cpu_target = (powerup_frac * 1) / 1000; - BOOST_REQUIRE_EQUAL("", configbw(make_config([&](rentbw_config& config) { + BOOST_REQUIRE_EQUAL("", configbw(make_config([&](powerup_config& config) { config.net.current_weight_ratio = net_start; config.net.target_weight_ratio = net_target; config.net.assumed_stake_weight = stake_weight; @@ -390,7 +390,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { auto state = get_state(); BOOST_REQUIRE(near( // state.net.weight_ratio, // - int64_t(state.net.assumed_stake_weight * eosio::chain::int128_t(rentbw_frac) / + int64_t(state.net.assumed_stake_weight * eosio::chain::int128_t(powerup_frac) / (state.net.weight + state.net.assumed_stake_weight)), 10)); }; @@ -402,7 +402,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { BOOST_REQUIRE_EQUAL("", configbw({})); } else if (i) { produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); } net = net_start + i * (net_target - net_start) / 10; cpu = cpu_start + i * (cpu_target - cpu_start) / 20; @@ -415,7 +415,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { { int i = 7; produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](rentbw_config& config) { + BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { config.net.target_timestamp = control->head_block_time() + fc::days(30); config.cpu.target_timestamp = control->head_block_time() + fc::days(40); }))); @@ -429,7 +429,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { for (int i = 0; i <= 5; ++i) { if (i) { produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); } net = net_start + i * (net_target - net_start) / 30; cpu = cpu_start + i * (cpu_target - cpu_start) / 40; @@ -444,7 +444,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { produce_block(fc::days(1) - fc::milliseconds(500)); auto new_net_target = net_target / 10; auto new_cpu_target = cpu_target / 20; - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](rentbw_config& config) { + BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { config.net.target_weight_ratio = new_net_target; config.cpu.target_weight_ratio = new_cpu_target; }))); @@ -460,7 +460,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { for (int i = 0; i <= 10; ++i) { if (i) { produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); } net = net_start + i * (net_target - net_start) / (30 - 6); cpu = cpu_start + i * (cpu_target - cpu_start) / (40 - 6); @@ -472,7 +472,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { // Move transition time to immediate future { produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](rentbw_config& config) { + BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { config.net.target_timestamp = control->head_block_time() + fc::milliseconds(1000); config.cpu.target_timestamp = control->head_block_time() + fc::milliseconds(1000); }))); @@ -481,7 +481,7 @@ BOOST_FIXTURE_TEST_CASE(weight_tests, rentbw_tester) try { // Verify targets hold as time advances for (int i = 0; i <= 10; ++i) { - BOOST_REQUIRE_EQUAL("", rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); BOOST_REQUIRE(near(get_state().net.weight_ratio, net_target, 1)); BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu_target, 1)); check_weight(); @@ -492,50 +492,50 @@ FC_LOG_AND_RETHROW() BOOST_AUTO_TEST_CASE(rent_tests) try { { - rentbw_tester t; + powerup_tester t; t.produce_block(); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("rentbw hasn't been initialized"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 4, rentbw_frac / 8, + BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("powerup hasn't been initialized"), // + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 4, powerup_frac / 8, asset::from_string("1.000 TST"))); BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { - config.net.current_weight_ratio = rentbw_frac; - config.net.target_weight_ratio = rentbw_frac; + config.net.current_weight_ratio = powerup_frac; + config.net.target_weight_ratio = powerup_frac; config.net.assumed_stake_weight = stake_weight; config.net.exponent = 1; config.net.min_price = asset::from_string("1000000.0000 TST"); config.net.max_price = asset::from_string("1000000.0000 TST"); - config.cpu.current_weight_ratio = rentbw_frac; - config.cpu.target_weight_ratio = rentbw_frac; + config.cpu.current_weight_ratio = powerup_frac; + config.cpu.target_weight_ratio = powerup_frac; config.cpu.assumed_stake_weight = stake_weight; config.cpu.exponent = 1; config.cpu.min_price = asset::from_string("1000000.0000 TST"); config.cpu.max_price = asset::from_string("1000000.0000 TST"); - config.rent_days = 30; - config.min_rent_fee = asset::from_string("1.0000 TST"); + config.powerup_days = 30; + config.min_powerup_fee = asset::from_string("1.0000 TST"); }))); BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("max_payment doesn't match core symbol"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.000 TST"))); + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, asset::from_string("1.000 TST"))); BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("market doesn't have resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, 0, rentbw_frac, asset::from_string("1.0000 TST"))); + t.powerup(N(bob111111111), N(alice1111111), 30, 0, powerup_frac, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("market doesn't have resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, 0, asset::from_string("1.0000 TST"))); + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, 0, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { // weight = stake_weight - config.net.current_weight_ratio = rentbw_frac/2; - config.net.target_weight_ratio = rentbw_frac/2; + config.net.current_weight_ratio = powerup_frac/2; + config.net.target_weight_ratio = powerup_frac/2; // weight = stake_weight - config.cpu.current_weight_ratio = rentbw_frac/2; - config.cpu.target_weight_ratio = rentbw_frac/2; + config.cpu.current_weight_ratio = powerup_frac/2; + config.cpu.target_weight_ratio = powerup_frac/2; }))); auto net_weight = stake_weight; @@ -550,18 +550,18 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // (.2) * 1000000.0000 = 200000.0000 // total = 300000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("300000.0000")); - t.check_rentbw(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, rentbw_frac * .1, rentbw_frac * .2, + t.check_powerup(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, powerup_frac * .1, powerup_frac * .2, asset::from_string("300000.0000 TST"), net_weight * .1, cpu_weight * .2); // Start decay t.produce_block(fc::days(30) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .1 * net_weight, 0)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .2 * cpu_weight, 0)); // 2 days of decay from (10%, 20%) to (1.35%, 2.71%) t.produce_block(fc::days(2) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2)), int64_t(.1 * net_weight * exp(-2)) / 1000)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-2)), @@ -572,7 +572,7 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // (.02) * 1000000.0000 = 20000.0000 // total = 40000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("40000.0001")); - t.check_rentbw(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, rentbw_frac * .02, rentbw_frac * .02, + t.check_powerup(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, powerup_frac * .02, powerup_frac * .02, asset::from_string("40000.0001 TST"), net_weight * .02, cpu_weight * .02); } @@ -580,21 +580,21 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { t.produce_block(); BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { // weight = stake_weight * 3 - config.net.current_weight_ratio = rentbw_frac / 4; - config.net.target_weight_ratio = rentbw_frac / 4; + config.net.current_weight_ratio = powerup_frac / 4; + config.net.target_weight_ratio = powerup_frac / 4; config.net.assumed_stake_weight = stake_weight; config.net.exponent = 2; config.net.max_price = asset::from_string("2000000.0000 TST"); // weight = stake_weight * 4 / 2 - config.cpu.current_weight_ratio = rentbw_frac / 5; - config.cpu.target_weight_ratio = rentbw_frac / 5; + config.cpu.current_weight_ratio = powerup_frac / 5; + config.cpu.target_weight_ratio = powerup_frac / 5; config.cpu.assumed_stake_weight = stake_weight / 2; config.cpu.exponent = 3; config.cpu.max_price = asset::from_string("6000000.0000 TST"); - config.rent_days = 30; - config.min_rent_fee = asset::from_string("1.0000 TST"); + config.powerup_days = 30; + config.min_powerup_fee = asset::from_string("1.0000 TST"); }))); if (rex) @@ -609,94 +609,94 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { auto cpu_weight = stake_weight * 4 / 2; { - rentbw_tester t; + powerup_tester t; init(t, false); BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("days doesn't match configuration"), // - t.rentbw(N(bob111111111), N(alice1111111), 20, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); + t.powerup(N(bob111111111), N(alice1111111), 20, powerup_frac, powerup_frac, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( // t.wasm_assert_msg("net_frac can't be negative"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, -rentbw_frac, rentbw_frac, + t.powerup(N(bob111111111), N(alice1111111), 30, -powerup_frac, powerup_frac, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( // t.wasm_assert_msg("cpu_frac can't be negative"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, -rentbw_frac, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, -powerup_frac, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( // t.wasm_assert_msg("net can't be more than 100%"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac + 1, rentbw_frac, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac + 1, powerup_frac, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( // t.wasm_assert_msg("cpu can't be more than 100%"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac + 1, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac + 1, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("max_payment is less than calculated fee: 3000000.0000 TST"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, asset::from_string("1.0000 TST"))); + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, asset::from_string("1.0000 TST"))); BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("can't channel fees to rex"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac, rentbw_frac, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, asset::from_string("3000000.0000 TST"))); } // net:100%, cpu:100% { - rentbw_tester t; + powerup_tester t; init(t, true); t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); BOOST_REQUIRE_EQUAL( t.wasm_assert_msg("calculated fee is below minimum; try renting more"), - t.rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, 10, 10, asset::from_string("3000000.0000 TST"))); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + t.powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, 10, 10, asset::from_string("3000000.0000 TST"))); + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); BOOST_REQUIRE_EQUAL( // t.wasm_assert_msg("weight can't shrink below utilization"), t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = rentbw_frac / 4 + 1; - config.net.target_weight_ratio = rentbw_frac / 4 + 1; - config.cpu.current_weight_ratio = rentbw_frac / 5; - config.cpu.target_weight_ratio = rentbw_frac / 5; + config.net.current_weight_ratio = powerup_frac / 4 + 1; + config.net.target_weight_ratio = powerup_frac / 4 + 1; + config.cpu.current_weight_ratio = powerup_frac / 5; + config.cpu.target_weight_ratio = powerup_frac / 5; }))); BOOST_REQUIRE_EQUAL( // t.wasm_assert_msg("weight can't shrink below utilization"), t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = rentbw_frac / 4; - config.net.target_weight_ratio = rentbw_frac / 4; - config.cpu.current_weight_ratio = rentbw_frac / 5 + 1; - config.cpu.target_weight_ratio = rentbw_frac / 5 + 1; + config.net.current_weight_ratio = powerup_frac / 4; + config.net.target_weight_ratio = powerup_frac / 4; + config.cpu.current_weight_ratio = powerup_frac / 5 + 1; + config.cpu.target_weight_ratio = powerup_frac / 5 + 1; }))); BOOST_REQUIRE_EQUAL( // "", // t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = rentbw_frac / 4; - config.net.target_weight_ratio = rentbw_frac / 4; - config.cpu.current_weight_ratio = rentbw_frac / 5; - config.cpu.target_weight_ratio = rentbw_frac / 5; + config.net.current_weight_ratio = powerup_frac / 4; + config.net.target_weight_ratio = powerup_frac / 4; + config.cpu.current_weight_ratio = powerup_frac / 5; + config.cpu.target_weight_ratio = powerup_frac / 5; }))); } // net:30%, cpu:40%, then net:5%, cpu:10% { - rentbw_tester t; + powerup_tester t; init(t, true); // (.3 ^ 2) * 2000000.0000 / 2 = 90000.0000 // (.4 ^ 3) * 6000000.0000 / 3 = 128000.0000 // total = 218000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("218000.0001")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .3, rentbw_frac * .4, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .3, powerup_frac * .4, asset::from_string("218000.0001 TST"), net_weight * .3, cpu_weight * .4); // (.35 ^ 2) * 2000000.0000 / 2 - 90000.0000 = 32500.0000 // (.5 ^ 3) * 6000000.0000 / 3 - 128000.0000 = 122000.0000 // total = 154500.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("154500.0000")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .05, rentbw_frac * .10, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .05, powerup_frac * .10, asset::from_string("154500.0000 TST"), net_weight * .05, cpu_weight * .10); } // net:50%, cpu:50% (but with non-zero min_price and also an exponent of 2 to simplify the math) { - rentbw_tester t; + powerup_tester t; init(t, true); BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { config.cpu.exponent = 2; @@ -726,29 +726,29 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // 4000000.0000 * .5 + (2000000.0000 / 2) * (.5 ^ 2) = 2250000.0000 // total = 2950000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("2950000.0000")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .5, rentbw_frac * .5, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .5, powerup_frac * .5, asset::from_string("2950000.0000 TST"), net_weight * .5, cpu_weight * .5); } { // net:100%, cpu:100% - rentbw_tester t; + powerup_tester t; init(t, true); t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); // No more available for 30 days BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, asset::from_string("1.0000 TST"))); t.produce_block(fc::days(29)); BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, asset::from_string("1.0000 TST"))); t.produce_block(fc::days(1) - fc::milliseconds(1500)); BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, asset::from_string("1.0000 TST"))); t.produce_block(fc::milliseconds(500)); @@ -758,32 +758,32 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // (1.0 ^ 2) * 6000000.0000 = 6000000.0000 // total = 8000000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("8000000.0000")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, asset::from_string("8000000.0000 TST"), 0, 0); // No more available for 30 days BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, asset::from_string("1.0000 TST"))); t.produce_block(fc::days(29)); BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, asset::from_string("1.0000 TST"))); t.produce_block(fc::days(1) - fc::milliseconds(1000)); BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.rentbw(N(bob111111111), N(alice1111111), 30, rentbw_frac / 1000, rentbw_frac / 1000, + t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, asset::from_string("1.0000 TST"))); // Start decay t.produce_block(fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, net_weight, net_weight / 1000)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, cpu_weight, cpu_weight / 1000)); // 1 day of decay t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-1)), int64_t(net_weight * exp(-1)) / 1000)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-1)), @@ -791,7 +791,7 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // 1 day of decay t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-2)), int64_t(net_weight * exp(-2)) / 1000)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-2)), @@ -803,12 +803,12 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // [ ((e^-2) ^ 2)*(e^-2 - 0.0) + ((1.0) ^ 3)/3 - ((e^-2) ^ 3)/3 ] * 6000000.0000 = 2009915.0087 // total = 3028230.6476 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3028229.8795")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac, rentbw_frac, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, asset::from_string("3028229.8795 TST"), net_weight, cpu_weight); } { - rentbw_tester t; + powerup_tester t; init(t, true); // 10%, 20% @@ -816,7 +816,7 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // (.2 ^ 3) * 6000000.0000 / 3 = 16000.0000 // total = 26000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("26000.0002")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .1, rentbw_frac * .2, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .1, powerup_frac * .2, asset::from_string("26000.0002 TST"), net_weight * .1, cpu_weight * .2); t.produce_block(fc::days(15) - fc::milliseconds(500)); @@ -826,18 +826,18 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // (.4 ^ 3) * 6000000.0000 / 3 - 16000.0000 = 112000.0000 // total = 192000.0000 t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("192000.0001")); - t.check_rentbw(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, rentbw_frac * .2, rentbw_frac * .2, + t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .2, powerup_frac * .2, asset::from_string("192000.0001 TST"), net_weight * .2, cpu_weight * .2); // Start decay t.produce_block(fc::days(15) - fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .3 * net_weight, 0)); BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .4 * cpu_weight, 0)); // 1 day of decay from (30%, 40%) to (20%, 20%) t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE( near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-1) + .2 * net_weight), 0)); BOOST_REQUIRE( @@ -845,7 +845,7 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { // 2 days of decay from (30%, 40%) to (20%, 20%) t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.rentbwexec(config::system_account_name, 10)); + BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); BOOST_REQUIRE( near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2) + .2 * net_weight), 0)); BOOST_REQUIRE( From 280fe9eb8c3488b59a90c514b556b2d4ad38331e Mon Sep 17 00:00:00 2001 From: deck Date: Mon, 30 Nov 2020 12:13:03 -0500 Subject: [PATCH 1037/1048] Add configure and usage guide for powerup --- ...08_configure-use-powerup-resource-model.md | 248 ++++++++++++++++++ 1 file changed, 248 insertions(+) create mode 100644 docs/04_guides/08_configure-use-powerup-resource-model.md diff --git a/docs/04_guides/08_configure-use-powerup-resource-model.md b/docs/04_guides/08_configure-use-powerup-resource-model.md new file mode 100644 index 00000000..98eb1721 --- /dev/null +++ b/docs/04_guides/08_configure-use-powerup-resource-model.md @@ -0,0 +1,248 @@ +# Configure and Use the `PowerUp` Resource Model + +## Configuration + +### Definitions + +#### Configuration +``` +// configure the `powerup` market. The market becomes available the first time this action is invoked +void cfgpowerup( powerup_config& args ); + +struct powerup_config_resource { + std::optional current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. // Do not specify to preserve the existing setting or use the default; + // this avoids sudden price jumps. For new chains which don't need + // to gradually phase out staking and REX, 0.01x (10^13) is a good + // value for both current_weight_ratio and target_weight_ratio. + std::optional target_weight_ratio; // Linearly shrink weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. + // Do not specify to preserve the existing setting or use the default. + std::optional assumed_stake_weight; // Assumed stake weight for ratio calculations. Use the sum of total + // staked and total rented by REX at the time the power market + // is first activated. Do not specify to preserve the existing + // setting (no default exists); this avoids sudden price jumps. + // For new chains which don't need to phase out staking and REX, + // 10^12 is probably a good value. + std::optional target_timestamp; // Stop automatic weight_ratio shrinkage at this time. Once this + // time hits, weight_ratio will be target_weight_ratio. Ignored + // if current_weight_ratio == target_weight_ratio. Do not specify + // this to preserve the existing setting (no default exists). + std::optional exponent; // Exponent of resource price curve. Must be >= 1. Do not specify + // to preserve the existing setting or use the default. + std::optional decay_secs; // Number of seconds for the gap between adjusted resource + // utilization and instantaneous resource utilization to shrink + // by 63%. Do not specify to preserve the existing setting or + // use the default. + std::optional min_price; // Fee needed to rent the entire resource market weight at the + // minimum price. For example, this could be set to 0.005% of + // total token supply. Do not specify to preserve the existing + // setting or use the default. + std::optional max_price; // Fee needed to rent the entire resource market weight at the + // maximum price. For example, this could be set to 10% of total + // token supply. Do not specify to preserve the existing + // setting (no default exists). + + }; + +struct powerup_config { + powerup_config_resource net; // NET market configuration + powerup_config_resource cpu; // CPU market configuration + std::optional powerup_days; // `power` `days` argument must match this. Do not specify to preserve the + // existing setting or use the default. + std::optional min_powerup_fee; // Rental fees below this amount are rejected. Do not specify to preserve the + // existing setting (no default exists). +}; +``` +#### State + +Definitions useful to help understand the configuration, including defaults: +``` +inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 + +struct powerup_state_resource { + static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to rent a + // tiny amount of resources increases linearly + // with utilization. + static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a + // single loan, then, assuming no further renting, + // 1 day after it expires the adjusted utilization + // will be at approximately 37% and after 3 days + // the adjusted utilization will be less than 5%. + + uint8_t version = 0; + int64_t weight = 0; // resource market weight. calculated; varies over time. + // 1 represents the same amount of resources as 1 + // satoshi of SYS staked. + int64_t weight_ratio = 0; // resource market weight ratio: + // assumed_stake_weight / (assumed_stake_weight + weight). + // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. + int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. + int64_t initial_weight_ratio = powerup_frac; // Initial weight_ratio used for linear shrinkage. + int64_t target_weight_ratio = powerup_frac / 100; // Linearly shrink the weight_ratio to this amount. + time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started + time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this + // time hits, weight_ratio will be target_weight_ratio. + double exponent = default_exponent; // Exponent of resource price curve. + uint32_t decay_secs = default_decay_secs; // Number of seconds for the gap between adjusted resource + // utilization and instantaneous utilization to shrink by 63%. + asset min_price = {}; // Fee needed to rent the entire resource market weight at + // the minimum price (defaults to 0). + asset max_price = {}; // Fee needed to rent the entire resource market weight at + // the maximum price. + int64_t utilization = 0; // Instantaneous resource utilization. This is the current + // amount sold. utilization <= weight. + int64_t adjusted_utilization = 0; // Adjusted resource utilization. This is >= utilization and + // <= weight. It grows instantly but decays exponentially. + time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated +}; + +struct powerup_state { + static constexpr uint32_t default_powerup_days = 30; // 30 day resource powerups + + uint8_t version = 0; + powerup_state_resource net = {}; // NET market state + powerup_state_resource cpu = {}; // CPU market state + uint32_t powerup_days = default_powerup_days; // `powerup` `days` argument must match this. + asset min_powerup_fee = {}; // fees below this amount are rejected + + uint64_t primary_key()const { return 0; } +}; +``` + +### Preparation for Upgrade +1. Build [eosio.contracts](https://github.com/EOSIO/eosio.contracts) with `powerup` code. Version **1.9.2** or greater . +2. Deploy eosio.system contract to `eosio`. +3. Create account `eosio.reserv` and ensure the account has enough at least 4 KiB of RAM. +4. Deploy `powup.results.abi` to `eosio.reserv` account using `setabi`. The ABI can be found in the `build/contracts/eosio.system/.powerup/` directory. +5. Enable the REX system (if not enabled). + +### Configuring `PowerUp` + +#### Config file +``` +# config.json +{ + "net": { + "assumed_stake_weight": 944076307, + "current_weight_ratio": 1000000000000000, + "decay_secs": 86400, + "exponent": 2, + "max_price": "10000000.0000 TST", + "min_price": "0.0000 TST", + "target_timestamp": "2022-01-01T00:00:00.000", + "target_weight_ratio": 10000000000000 + }, + "cpu": { + "assumed_stake_weight": 3776305228, + "current_weight_ratio": 1000000000000000, + "decay_secs": 86400, + "exponent": 2, + "max_price": "10000000.0000 TST", + "min_price": "0.0000 TST", + "target_timestamp": "2022-01-01T00:00:00.000", + "target_weight_ratio": 10000000000000 + }, + "min_powerup_fee": "0.0001 TST", + "powerup_days": 1 +} +``` + +#### `cfgpowerup` Action Call +``` +# call to `cfgpowerup` +cleos push action eosio cfgpowerup "[`cat ./config.json`]" -p eosio +``` + +#### Check state +``` +cleos get table eosio 0 powup.state +{ + "rows": [{ + "version": 0, + "net": { + "version": 0, + "weight": 0, + "weight_ratio": "1000000000000000", + "assumed_stake_weight": 944076307, + "initial_weight_ratio": "1000000000000000", + "target_weight_ratio": "10000000000000", + "initial_timestamp": "2020-11-16T19:52:50", + "target_timestamp": "2022-01-01T00:00:00", + "exponent": "2.00000000000000000", + "decay_secs": 3600, + "min_price": "0.0000 EOS", + "max_price": "10000000.0000 EOS", + "utilization": 0, + "adjusted_utilization": 0, + "utilization_timestamp": "2020-11-16T19:52:50" + }, + "cpu": { + "version": 0, + "weight": 0, + "weight_ratio": "1000000000000000", + "assumed_stake_weight": 3776305228, + "initial_weight_ratio": "1000000000000000", + "target_weight_ratio": "10000000000000", + "initial_timestamp": "2020-11-16T19:52:50", + "target_timestamp": "2022-01-01T00:00:00", + "exponent": "2.00000000000000000", + "decay_secs": 3600, + "min_price": "0.0000 EOS", + "max_price": "10000000.0000 EOS", + "utilization": 0, + "adjusted_utilization": 0, + "utilization_timestamp": "2020-11-16T19:52:50" + }, + "powerup_days": 1, + "min_powerup_fee": "0.0001 EOS" + } + ], + "more": false, + "next_key": "" +} +``` + +### Using `PowerUp` + +#### Executing an order +The action to powerup an account is `powerup`. It takes a `payer` and a `receiver` of the resources. The `days` should always match `state.powerup_days`. `net_frac` and `cpu_frac` are the percentage of the resources that you need. The easiest way to caclulate the percentage is to multiple 10^15 (100%) by the desired percentage. For example: 10^15 * 1% = 10^13. +``` +cleos push action eosio powerup '[user, user, 1, 10000000000000, 10000000000000, "1000.0000 EOS"]' -p user +executed transaction: 82b7124601612b371b812e3bf65cf63bb44616802d3cd33a2c0422b58399f54f 144 bytes 521 us +# eosio <= eosio::powerup {"payer":"user","receiver":"user","days":1,"net_frac":"10000000000000","cpu_frac":"10000000000000","... +# eosio.token <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 EOS","memo":"transfer from user to eosio.rex"} +# eosio.reserv <= eosio.reserv::powupresult {"fee":"999.9901 EOS","powup_net":"1.6354 EOS","powup_cpu":"6.5416 EOS"} +# user <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 EOS","memo":"transfer from user to eosio.rex"} +# eosio.rex <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 EOS","memo":"transfer from user to eosio.rex"} +``` +You can see how many tokens were received for `NET` and `CPU` as well as the fee by looking at the `eosio.reserv::powupresult` informational action. + +*It is worth mentioning that the network being used for the example has not fully transitioned so the available resources are minimal therefore 1% of the resources are quite expensive. As the system continues the transition more resources are available to the `PowerUp` resource model and will become more affordable.* + +#### Clearing the orders queue + +The orders table `powup.order` can be viewed by calling: +``` +cleos get table eosio 0 powup.order +{ + "rows": [{ + "version": 0, + "id": 0, + "owner": "user", + "net_weight": 16354, + "cpu_weight": 65416, + "expires": "2020-11-18T13:04:33" + } + ], + "more": false, + "next_key": "" +} +``` + +The action `powerupexec` that takes a `name` of a user and the `max` number of orders that will be cleared if expired. It is worth noting that the call to `powerup` will also clear up to two expired orders per call. + +``` +cleos push action eosio powerupexec '[user, 2]' -p user +executed transaction: 93ab4ac900a7902e4e59e5e925e8b54622715328965150db10774aa09855dc98 104 bytes 363 us +# eosio <= eosio::powerupexec {"user":"user","max":2} +warning: transaction executed locally, but may not be confirmed by the network yet ] +``` \ No newline at end of file From b17f0d3a5975bcdd8bed68bb27303f42fecaef2f Mon Sep 17 00:00:00 2001 From: deck Date: Mon, 30 Nov 2020 14:18:03 -0500 Subject: [PATCH 1038/1048] add back a comment removed in error --- contracts/eosio.system/src/powerup.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/contracts/eosio.system/src/powerup.cpp b/contracts/eosio.system/src/powerup.cpp index ebab2615..fd32a9dd 100644 --- a/contracts/eosio.system/src/powerup.cpp +++ b/contracts/eosio.system/src/powerup.cpp @@ -279,6 +279,8 @@ int64_t calc_powerup_fee(const powerup_state_resource& state, int64_t utilizatio coefficient * std::pow(end_u, state.exponent) - coefficient * std::pow(start_u, state.exponent); }; + // Returns p(double(utilization)/state.weight). + // @pre 0 <= utilization <= state.weight auto price_function = [&state](int64_t utilization) -> double { double price = state.min_price.amount; // state.exponent >= 1.0, therefore the exponent passed into std::pow is >= 0.0. From 065e865d67f5d0e598ba8017503903e6980bbbfa Mon Sep 17 00:00:00 2001 From: deck Date: Tue, 1 Dec 2020 09:11:14 -0500 Subject: [PATCH 1039/1048] Removing the word `rent` from comments/error messages. Fixing some minor typos and comment blocks. Change `process_queue` to a more definitive `process_powerup_queue`. --- .../include/eosio.system/eosio.system.hpp | 28 +++++++++---------- .../include/eosio.system/powerup.results.hpp | 4 +-- contracts/eosio.system/src/powerup.cpp | 10 +++---- ...08_configure-use-powerup-resource-model.md | 16 +++++------ tests/eosio.powerup_tests.cpp | 2 +- 5 files changed, 30 insertions(+), 30 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp index a70726f1..d49834cd 100644 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ b/contracts/eosio.system/include/eosio.system/eosio.system.hpp @@ -549,11 +549,11 @@ namespace eosiosystem { // utilization and instantaneous resource utilization to shrink // by 63%. Do not specify to preserve the existing setting or // use the default. - std::optional min_price; // Fee needed to rent the entire resource market weight at the + std::optional min_price; // Fee needed to reserve the entire resource market weight at the // minimum price. For example, this could be set to 0.005% of // total token supply. Do not specify to preserve the existing // setting or use the default. - std::optional max_price; // Fee needed to rent the entire resource market weight at the + std::optional max_price; // Fee needed to reserve the entire resource market weight at the // maximum price. For example, this could be set to 10% of total // token supply. Do not specify to preserve the existing // setting (no default exists). @@ -563,22 +563,22 @@ namespace eosiosystem { }; struct powerup_config { - powerup_config_resource net; // NET market configuration - powerup_config_resource cpu; // CPU market configuration - std::optional powerup_days; // `power` `days` argument must match this. Do not specify to preserve the - // existing setting or use the default. - std::optional min_powerup_fee; // Rental fees below this amount are rejected. Do not specify to preserve the - // existing setting (no default exists). + powerup_config_resource net; // NET market configuration + powerup_config_resource cpu; // CPU market configuration + std::optional powerup_days; // `powerup` `days` argument must match this. Do not specify to preserve the + // existing setting or use the default. + std::optional min_powerup_fee; // Fees below this amount are rejected. Do not specify to preserve the + // existing setting (no default exists). EOSLIB_SERIALIZE( powerup_config, (net)(cpu)(powerup_days)(min_powerup_fee) ) }; struct powerup_state_resource { - static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to rent a + static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to reserve a // tiny amount of resources increases linearly // with utilization. static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a - // single loan, then, assuming no further renting, + // single loan, then, assuming no further powerup usage, // 1 day after it expires the adjusted utilization // will be at approximately 37% and after 3 days // the adjusted utilization will be less than 5%. @@ -599,9 +599,9 @@ namespace eosiosystem { double exponent = default_exponent; // Exponent of resource price curve. uint32_t decay_secs = default_decay_secs; // Number of seconds for the gap between adjusted resource // utilization and instantaneous utilization to shrink by 63%. - asset min_price = {}; // Fee needed to rent the entire resource market weight at + asset min_price = {}; // Fee needed to reserve the entire resource market weight at // the minimum price (defaults to 0). - asset max_price = {}; // Fee needed to rent the entire resource market weight at + asset max_price = {}; // Fee needed to reserve the entire resource market weight at // the maximum price. int64_t utilization = 0; // Instantaneous resource utilization. This is the current // amount sold. utilization <= weight. @@ -1315,7 +1315,7 @@ namespace eosiosystem { void powerupexec( const name& user, uint16_t max ); /** - * Rent NET and CPU by percentage + * Powerup NET and CPU resources by percentage * * @param payer - the resource buyer * @param receiver - the resource receiver @@ -1480,7 +1480,7 @@ namespace eosiosystem { // defined in power.cpp void adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); - void process_queue( + void process_powerup_queue( time_point_sec now, symbol core_symbol, powerup_state& state, powerup_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available); diff --git a/contracts/eosio.system/include/eosio.system/powerup.results.hpp b/contracts/eosio.system/include/eosio.system/powerup.results.hpp index 52d86cd1..d29ec87d 100644 --- a/contracts/eosio.system/include/eosio.system/powerup.results.hpp +++ b/contracts/eosio.system/include/eosio.system/powerup.results.hpp @@ -10,7 +10,7 @@ using eosio::name; /** * The action `powerresult` of `power.results` is a no-op. - * It is added as an inline convenience action to `power` rental. + * It is added as an inline convenience action to `powerup` reservation. * This inline convenience action does not have any effect, however, * its data includes the result of the parent action and appears in its trace. */ @@ -22,7 +22,7 @@ class [[eosio::contract("powup.results")]] powup_results : eosio::contract { /** * powupresult action. * - * @param fee - rental fee amount + * @param fee - powerup fee amount * @param powup_net - amount of powup NET tokens * @param powup_cpu - amount of powup CPU tokens */ diff --git a/contracts/eosio.system/src/powerup.cpp b/contracts/eosio.system/src/powerup.cpp index fd32a9dd..614d6745 100644 --- a/contracts/eosio.system/src/powerup.cpp +++ b/contracts/eosio.system/src/powerup.cpp @@ -67,7 +67,7 @@ void system_contract::adjust_resources(name payer, name account, symbol core_sym } } // system_contract::adjust_resources -void system_contract::process_queue(time_point_sec now, symbol core_symbol, powerup_state& state, +void system_contract::process_powerup_queue(time_point_sec now, symbol core_symbol, powerup_state& state, powerup_order_table& orders, uint32_t max_items, int64_t& net_delta_available, int64_t& cpu_delta_available) { update_utilization(now, state.net); @@ -325,7 +325,7 @@ void system_contract::powerupexec(const name& user, uint16_t max) { int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; - process_queue(now, core_symbol, state, orders, max, net_delta_available, cpu_delta_available); + process_powerup_queue(now, core_symbol, state, orders, max, net_delta_available, cpu_delta_available); adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); state_sing.set(state, get_self()); @@ -349,7 +349,7 @@ void system_contract::powerup(const name& payer, const name& receiver, uint32_t int64_t net_delta_available = 0; int64_t cpu_delta_available = 0; - process_queue(now, core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); + process_powerup_queue(now, core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); eosio::asset fee{ 0, core_symbol }; auto process = [&](int64_t frac, int64_t& amount, powerup_state_resource& state) { @@ -359,7 +359,7 @@ void system_contract::powerup(const name& payer, const name& receiver, uint32_t eosio::check(state.weight, "market doesn't have resources available"); eosio::check(state.utilization + amount <= state.weight, "market doesn't have enough resources available"); int64_t f = calc_powerup_fee(state, amount); - eosio::check(f > 0, "calculated fee is below minimum; try renting more"); + eosio::check(f > 0, "calculated fee is below minimum; try powering up with more resources"); fee.amount += f; state.utilization += amount; }; @@ -373,7 +373,7 @@ void system_contract::powerup(const name& payer, const name& receiver, uint32_t error_msg += fee.to_string(); eosio::check(false, error_msg); } - eosio::check(fee >= state.min_powerup_fee, "calculated fee is below minimum; try renting more"); + eosio::check(fee >= state.min_powerup_fee, "calculated fee is below minimum; try powering up with more resources"); orders.emplace(payer, [&](auto& order) { order.id = orders.available_primary_key(); diff --git a/docs/04_guides/08_configure-use-powerup-resource-model.md b/docs/04_guides/08_configure-use-powerup-resource-model.md index 98eb1721..5597acb4 100644 --- a/docs/04_guides/08_configure-use-powerup-resource-model.md +++ b/docs/04_guides/08_configure-use-powerup-resource-model.md @@ -32,11 +32,11 @@ struct powerup_config_resource { // utilization and instantaneous resource utilization to shrink // by 63%. Do not specify to preserve the existing setting or // use the default. - std::optional min_price; // Fee needed to rent the entire resource market weight at the + std::optional min_price; // Fee needed to reserve the entire resource market weight at the // minimum price. For example, this could be set to 0.005% of // total token supply. Do not specify to preserve the existing // setting or use the default. - std::optional max_price; // Fee needed to rent the entire resource market weight at the + std::optional max_price; // Fee needed to reserve the entire resource market weight at the // maximum price. For example, this could be set to 10% of total // token supply. Do not specify to preserve the existing // setting (no default exists). @@ -46,9 +46,9 @@ struct powerup_config_resource { struct powerup_config { powerup_config_resource net; // NET market configuration powerup_config_resource cpu; // CPU market configuration - std::optional powerup_days; // `power` `days` argument must match this. Do not specify to preserve the + std::optional powerup_days; // `powerup` `days` argument must match this. Do not specify to preserve the // existing setting or use the default. - std::optional min_powerup_fee; // Rental fees below this amount are rejected. Do not specify to preserve the + std::optional min_powerup_fee; // Powerup fees below this amount are rejected. Do not specify to preserve the // existing setting (no default exists). }; ``` @@ -59,11 +59,11 @@ Definitions useful to help understand the configuration, including defaults: inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 struct powerup_state_resource { - static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to rent a + static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to reserve a // tiny amount of resources increases linearly // with utilization. static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a - // single loan, then, assuming no further renting, + // single loan, then, assuming no further powerup usage, // 1 day after it expires the adjusted utilization // will be at approximately 37% and after 3 days // the adjusted utilization will be less than 5%. @@ -84,9 +84,9 @@ struct powerup_state_resource { double exponent = default_exponent; // Exponent of resource price curve. uint32_t decay_secs = default_decay_secs; // Number of seconds for the gap between adjusted resource // utilization and instantaneous utilization to shrink by 63%. - asset min_price = {}; // Fee needed to rent the entire resource market weight at + asset min_price = {}; // Fee needed to reserve the entire resource market weight at // the minimum price (defaults to 0). - asset max_price = {}; // Fee needed to rent the entire resource market weight at + asset max_price = {}; // Fee needed to reserve the entire resource market weight at // the maximum price. int64_t utilization = 0; // Instantaneous resource utilization. This is the current // amount sold. utilization <= weight. diff --git a/tests/eosio.powerup_tests.cpp b/tests/eosio.powerup_tests.cpp index fa12fc07..3c8f43e0 100644 --- a/tests/eosio.powerup_tests.cpp +++ b/tests/eosio.powerup_tests.cpp @@ -644,7 +644,7 @@ BOOST_AUTO_TEST_CASE(rent_tests) try { init(t, true); t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("calculated fee is below minimum; try renting more"), + t.wasm_assert_msg("calculated fee is below minimum; try powering up with more resources"), t.powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, 10, 10, asset::from_string("3000000.0000 TST"))); t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); From 0992ba3556b216bd41acfad191265cd18ed78f5b Mon Sep 17 00:00:00 2001 From: deck Date: Tue, 1 Dec 2020 10:38:19 -0500 Subject: [PATCH 1040/1048] Correctly provide weight over the asset received. This will be more useful information to the users. --- contracts/eosio.system/include/eosio.system/powerup.results.hpp | 2 +- contracts/eosio.system/src/powerup.cpp | 2 +- contracts/eosio.system/src/powerup.results.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/contracts/eosio.system/include/eosio.system/powerup.results.hpp b/contracts/eosio.system/include/eosio.system/powerup.results.hpp index d29ec87d..716be93a 100644 --- a/contracts/eosio.system/include/eosio.system/powerup.results.hpp +++ b/contracts/eosio.system/include/eosio.system/powerup.results.hpp @@ -27,7 +27,7 @@ class [[eosio::contract("powup.results")]] powup_results : eosio::contract { * @param powup_cpu - amount of powup CPU tokens */ [[eosio::action]] - void powupresult( const asset& fee, const asset& powup_net, const asset& powup_cpu ); + void powupresult( const asset& fee, const int64_t powup_net, const int64_t powup_cpu ); using powupresult_action = action_wrapper<"powupresult"_n, &powup_results::powupresult>; }; diff --git a/contracts/eosio.system/src/powerup.cpp b/contracts/eosio.system/src/powerup.cpp index 614d6745..335d9bb2 100644 --- a/contracts/eosio.system/src/powerup.cpp +++ b/contracts/eosio.system/src/powerup.cpp @@ -392,7 +392,7 @@ void system_contract::powerup(const name& payer, const name& receiver, uint32_t // inline noop action powup_results::powupresult_action powupresult_act{ reserv_account, std::vector{ } }; - powupresult_act.send( fee, asset{ net_amount, core_symbol }, asset{ cpu_amount, core_symbol } ); + powupresult_act.send( fee, net_amount, cpu_amount ); } } // namespace eosiosystem diff --git a/contracts/eosio.system/src/powerup.results.cpp b/contracts/eosio.system/src/powerup.results.cpp index 7b9c8026..2be2e981 100644 --- a/contracts/eosio.system/src/powerup.results.cpp +++ b/contracts/eosio.system/src/powerup.results.cpp @@ -1,5 +1,5 @@ #include -void powup_results::powupresult( const asset& fee, const asset& powup_net, const asset& powup_cpu ) { } +void powup_results::powupresult( const asset& fee, const int64_t powup_net_weight, const int64_t powup_cpu_weight ) { } extern "C" void apply( uint64_t, uint64_t, uint64_t ) { } From c357f9ba547fdbb73d081bee1bd07364fcb85f37 Mon Sep 17 00:00:00 2001 From: deck Date: Wed, 2 Dec 2020 10:25:56 -0500 Subject: [PATCH 1041/1048] Add an Overview and Processing Expired Orders section. --- ...08_configure-use-powerup-resource-model.md | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/docs/04_guides/08_configure-use-powerup-resource-model.md b/docs/04_guides/08_configure-use-powerup-resource-model.md index 5597acb4..82eb41b4 100644 --- a/docs/04_guides/08_configure-use-powerup-resource-model.md +++ b/docs/04_guides/08_configure-use-powerup-resource-model.md @@ -1,5 +1,14 @@ # Configure and Use the `PowerUp` Resource Model +## Overview +This new system will create a new optional NET and CPU rental market which displaces (over time) +the existing staking system and REX market. Under the old model, system token holders +own NET and CPU and may choose to use it themselves, delegate it to others, or make +it available for others to rent using the REX market. Under this new model, the chain +owns almost all NET and CPU resources and the only way to access these resources is +through the new `powerup` action. It channels fees to the REX pool to enable token holders +to profit off the new market. + ## Configuration ### Definitions @@ -109,9 +118,9 @@ struct powerup_state { ``` ### Preparation for Upgrade -1. Build [eosio.contracts](https://github.com/EOSIO/eosio.contracts) with `powerup` code. Version **1.9.2** or greater . +1. Build [eosio.contracts](https://github.com/EOSIO/eosio.contracts) with `powerup` code. Version **1.9.x** or greater . 2. Deploy eosio.system contract to `eosio`. -3. Create account `eosio.reserv` and ensure the account has enough at least 4 KiB of RAM. +3. Create account `eosio.reserv` and ensure the account has enough RAM, at least 4 KiB. 4. Deploy `powup.results.abi` to `eosio.reserv` account using `setabi`. The ABI can be found in the `build/contracts/eosio.system/.powerup/` directory. 5. Enable the REX system (if not enabled). @@ -169,8 +178,8 @@ cleos get table eosio 0 powup.state "target_timestamp": "2022-01-01T00:00:00", "exponent": "2.00000000000000000", "decay_secs": 3600, - "min_price": "0.0000 EOS", - "max_price": "10000000.0000 EOS", + "min_price": "0.0000 TST", + "max_price": "10000000.0000 TST", "utilization": 0, "adjusted_utilization": 0, "utilization_timestamp": "2020-11-16T19:52:50" @@ -186,14 +195,14 @@ cleos get table eosio 0 powup.state "target_timestamp": "2022-01-01T00:00:00", "exponent": "2.00000000000000000", "decay_secs": 3600, - "min_price": "0.0000 EOS", - "max_price": "10000000.0000 EOS", + "min_price": "0.0000 TST", + "max_price": "10000000.0000 TST", "utilization": 0, "adjusted_utilization": 0, "utilization_timestamp": "2020-11-16T19:52:50" }, "powerup_days": 1, - "min_powerup_fee": "0.0001 EOS" + "min_powerup_fee": "0.0001 TST" } ], "more": false, @@ -204,21 +213,22 @@ cleos get table eosio 0 powup.state ### Using `PowerUp` #### Executing an order -The action to powerup an account is `powerup`. It takes a `payer` and a `receiver` of the resources. The `days` should always match `state.powerup_days`. `net_frac` and `cpu_frac` are the percentage of the resources that you need. The easiest way to caclulate the percentage is to multiple 10^15 (100%) by the desired percentage. For example: 10^15 * 1% = 10^13. +The action to power up an account is `powerup`. It takes a `payer` of the fee and a `receiver` of the resources. The `days` must always match `state.powerup_days`. `net_frac` and `cpu_frac` are the percentage of the resources that you need. The easiest way to caclulate the percentage is to multiple 10^15 (100%) by the desired percentage. For example: 10^15 * 0.01 = 10^13. ``` -cleos push action eosio powerup '[user, user, 1, 10000000000000, 10000000000000, "1000.0000 EOS"]' -p user +cleos push action eosio powerup '[user, user, 1, 10000000000000, 10000000000000, "1000.0000 TST"]' -p user executed transaction: 82b7124601612b371b812e3bf65cf63bb44616802d3cd33a2c0422b58399f54f 144 bytes 521 us # eosio <= eosio::powerup {"payer":"user","receiver":"user","days":1,"net_frac":"10000000000000","cpu_frac":"10000000000000","... -# eosio.token <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 EOS","memo":"transfer from user to eosio.rex"} -# eosio.reserv <= eosio.reserv::powupresult {"fee":"999.9901 EOS","powup_net":"1.6354 EOS","powup_cpu":"6.5416 EOS"} -# user <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 EOS","memo":"transfer from user to eosio.rex"} -# eosio.rex <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 EOS","memo":"transfer from user to eosio.rex"} +# eosio.token <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 TST","memo":"transfer from user to eosio.rex"} +# eosio.reserv <= eosio.reserv::powupresult {"fee":"999.9901 TST","powup_net_weight":"16354","powup_cpu_weight":"65416"} +# user <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 TST","memo":"transfer from user to eosio.rex"} +# eosio.rex <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 TST","memo":"transfer from user to eosio.rex"} ``` -You can see how many tokens were received for `NET` and `CPU` as well as the fee by looking at the `eosio.reserv::powupresult` informational action. +You can see how much NET and CPU weight was received as well as the fee by looking at the `eosio.reserv::powupresult` informational action. *It is worth mentioning that the network being used for the example has not fully transitioned so the available resources are minimal therefore 1% of the resources are quite expensive. As the system continues the transition more resources are available to the `PowerUp` resource model and will become more affordable.* -#### Clearing the orders queue +#### Processing Expired Orders +The resources in loans that expire do not automatically get reclaimed by the system. The expired loans sit in a queue that must be processed. Anyone calling the `powerup` action will help with processing this queue (limited to processing at most two expired loans at a time) so that normally the expired loans will be automatically processed in a timely manner. However, in some cases it may be necessary to manual process expired loans in the queue to make resources available to the system again and thus make rental prices cheaper. In such a scenario, any account may process up to an arbitrary number of expired loans by calling the `powerupexec` action. The orders table `powup.order` can be viewed by calling: ``` @@ -238,7 +248,7 @@ cleos get table eosio 0 powup.order } ``` -The action `powerupexec` that takes a `name` of a user and the `max` number of orders that will be cleared if expired. It is worth noting that the call to `powerup` will also clear up to two expired orders per call. +Example `powerupexec` call: ``` cleos push action eosio powerupexec '[user, 2]' -p user From ce5588b5abf1b5d6201bb7bcbd4e450024022421 Mon Sep 17 00:00:00 2001 From: deck Date: Wed, 2 Dec 2020 13:50:08 -0500 Subject: [PATCH 1042/1048] Remove some rental language. --- docs/04_guides/08_configure-use-powerup-resource-model.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/04_guides/08_configure-use-powerup-resource-model.md b/docs/04_guides/08_configure-use-powerup-resource-model.md index 82eb41b4..7b39ee83 100644 --- a/docs/04_guides/08_configure-use-powerup-resource-model.md +++ b/docs/04_guides/08_configure-use-powerup-resource-model.md @@ -1,7 +1,7 @@ # Configure and Use the `PowerUp` Resource Model ## Overview -This new system will create a new optional NET and CPU rental market which displaces (over time) +This new system will create a new optional NET and CPU marketplace which displaces (over time) the existing staking system and REX market. Under the old model, system token holders own NET and CPU and may choose to use it themselves, delegate it to others, or make it available for others to rent using the REX market. Under this new model, the chain @@ -228,7 +228,7 @@ You can see how much NET and CPU weight was received as well as the fee by looki *It is worth mentioning that the network being used for the example has not fully transitioned so the available resources are minimal therefore 1% of the resources are quite expensive. As the system continues the transition more resources are available to the `PowerUp` resource model and will become more affordable.* #### Processing Expired Orders -The resources in loans that expire do not automatically get reclaimed by the system. The expired loans sit in a queue that must be processed. Anyone calling the `powerup` action will help with processing this queue (limited to processing at most two expired loans at a time) so that normally the expired loans will be automatically processed in a timely manner. However, in some cases it may be necessary to manual process expired loans in the queue to make resources available to the system again and thus make rental prices cheaper. In such a scenario, any account may process up to an arbitrary number of expired loans by calling the `powerupexec` action. +The resources in loans that expire do not automatically get reclaimed by the system. The expired loans sit in a queue that must be processed. Anyone calling the `powerup` action will help with processing this queue (limited to processing at most two expired loans at a time) so that normally the expired loans will be automatically processed in a timely manner. However, in some cases it may be necessary to manual process expired loans in the queue to make resources available to the system again and thus make prices cheaper. In such a scenario, any account may process up to an arbitrary number of expired loans by calling the `powerupexec` action. The orders table `powup.order` can be viewed by calling: ``` From 4fce5daaebcdb5d1299cca9a921178e18079bd8a Mon Sep 17 00:00:00 2001 From: deck Date: Tue, 8 Dec 2020 08:54:29 -0500 Subject: [PATCH 1043/1048] update powerup config/install docs --- ...08_configure-use-powerup-resource-model.md | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/docs/04_guides/08_configure-use-powerup-resource-model.md b/docs/04_guides/08_configure-use-powerup-resource-model.md index 7b39ee83..35a6c933 100644 --- a/docs/04_guides/08_configure-use-powerup-resource-model.md +++ b/docs/04_guides/08_configure-use-powerup-resource-model.md @@ -1,4 +1,8 @@ -# Configure and Use the `PowerUp` Resource Model +--- +content_title: How to configure PowerUp resource model +link_text: How to configure PowerUp resource model +--- +# Configure and Use the PowerUp Resource Model ## Overview This new system will create a new optional NET and CPU marketplace which displaces (over time) @@ -14,12 +18,13 @@ to profit off the new market. ### Definitions #### Configuration -``` +```c++ // configure the `powerup` market. The market becomes available the first time this action is invoked void cfgpowerup( powerup_config& args ); struct powerup_config_resource { - std::optional current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. // Do not specify to preserve the existing setting or use the default; + std::optional current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. + // Do not specify to preserve the existing setting or use the default; // this avoids sudden price jumps. For new chains which don't need // to gradually phase out staking and REX, 0.01x (10^13) is a good // value for both current_weight_ratio and target_weight_ratio. @@ -64,7 +69,7 @@ struct powerup_config { #### State Definitions useful to help understand the configuration, including defaults: -``` +```c++ inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 struct powerup_state_resource { @@ -124,10 +129,10 @@ struct powerup_state { 4. Deploy `powup.results.abi` to `eosio.reserv` account using `setabi`. The ABI can be found in the `build/contracts/eosio.system/.powerup/` directory. 5. Enable the REX system (if not enabled). -### Configuring `PowerUp` +### Configuring PowerUp #### Config file -``` +```json # config.json { "net": { @@ -155,15 +160,17 @@ struct powerup_state { } ``` -#### `cfgpowerup` Action Call -``` +#### cfgpowerup Action Call +```sh # call to `cfgpowerup` cleos push action eosio cfgpowerup "[`cat ./config.json`]" -p eosio ``` #### Check state -``` +```sh cleos get table eosio 0 powup.state +``` +```json { "rows": [{ "version": 0, @@ -210,12 +217,14 @@ cleos get table eosio 0 powup.state } ``` -### Using `PowerUp` +### Using PowerUp #### Executing an order The action to power up an account is `powerup`. It takes a `payer` of the fee and a `receiver` of the resources. The `days` must always match `state.powerup_days`. `net_frac` and `cpu_frac` are the percentage of the resources that you need. The easiest way to caclulate the percentage is to multiple 10^15 (100%) by the desired percentage. For example: 10^15 * 0.01 = 10^13. -``` +```sh cleos push action eosio powerup '[user, user, 1, 10000000000000, 10000000000000, "1000.0000 TST"]' -p user +``` +``` executed transaction: 82b7124601612b371b812e3bf65cf63bb44616802d3cd33a2c0422b58399f54f 144 bytes 521 us # eosio <= eosio::powerup {"payer":"user","receiver":"user","days":1,"net_frac":"10000000000000","cpu_frac":"10000000000000","... # eosio.token <= eosio.token::transfer {"from":"user","to":"eosio.rex","quantity":"999.9901 TST","memo":"transfer from user to eosio.rex"} @@ -231,8 +240,10 @@ You can see how much NET and CPU weight was received as well as the fee by looki The resources in loans that expire do not automatically get reclaimed by the system. The expired loans sit in a queue that must be processed. Anyone calling the `powerup` action will help with processing this queue (limited to processing at most two expired loans at a time) so that normally the expired loans will be automatically processed in a timely manner. However, in some cases it may be necessary to manual process expired loans in the queue to make resources available to the system again and thus make prices cheaper. In such a scenario, any account may process up to an arbitrary number of expired loans by calling the `powerupexec` action. The orders table `powup.order` can be viewed by calling: -``` +```sh cleos get table eosio 0 powup.order +``` +```json { "rows": [{ "version": 0, @@ -250,8 +261,10 @@ cleos get table eosio 0 powup.order Example `powerupexec` call: -``` +```sh cleos push action eosio powerupexec '[user, 2]' -p user +``` +```console executed transaction: 93ab4ac900a7902e4e59e5e925e8b54622715328965150db10774aa09855dc98 104 bytes 363 us # eosio <= eosio::powerupexec {"user":"user","max":2} warning: transaction executed locally, but may not be confirmed by the network yet ] From 5fdce694439d18f0789f3bb2100391cc288f03fb Mon Sep 17 00:00:00 2001 From: deck Date: Wed, 16 Dec 2020 09:28:47 -0500 Subject: [PATCH 1044/1048] Bump version to v1.9.2 --- CMakeLists.txt | 2 +- README.md | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index adbdce0a..7ddd2b13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,7 +4,7 @@ project(eosio_contracts) set(VERSION_MAJOR 1) set(VERSION_MINOR 9) -set(VERSION_PATCH 1) +set(VERSION_PATCH 2) #set(VERSION_SUFFIX rc4) if (VERSION_SUFFIX) diff --git a/README.md b/README.md index 21ecb632..cb90a374 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # eosio.contracts -## Version : 1.9.1 +## Version : 1.9.2 The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. @@ -16,7 +16,7 @@ The following unprivileged contract(s) are also part of the system. Dependencies: * [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0) -* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.1) (optional dependency only needed to build unit tests) +* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.8) (optional dependency only needed to build unit tests) ## Build From 42e697b936793095587b2c0e835564ac841c9c7f Mon Sep 17 00:00:00 2001 From: deck Date: Fri, 22 Jan 2021 10:23:15 -0500 Subject: [PATCH 1045/1048] fix missing merge --- .gitignore | 47 ++--------------------------------------------- 1 file changed, 2 insertions(+), 45 deletions(-) diff --git a/.gitignore b/.gitignore index 970e384b..dd0b045a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,49 +31,6 @@ *.out *.app -<<<<<<< HEAD -*.a -*.sw* -*.ll -*.bc -*.wast -*.wast.hpp -*.s -*.dot -*.abi.hpp -*.cmake -!.cicd -!CMakeModules/*.cmake -!CMakeModules/*.txt -*.ninja -\#* -\.#* -CMakeCache.txt -CMakeFiles -doxygen -eos.doxygen - -wallet.json -*.wallet -build/* - -.vscode -.idea/ -*.iws +build/ .DS_Store -!*.swagger.* - -# from eosjs -dist/ -dist-web/ -node_modules/ -docs-build/ -*.tgz - -#cypress artifacts -cypress/screenshots/ -cypress/videos/ -======= -build/* -.DS_Store ->>>>>>> adad69f87ae84c1896fd8dc798c239f01b09af26 +.vscode From 36b6b731a78247514b469afdee6cdccef7131f56 Mon Sep 17 00:00:00 2001 From: deck Date: Wed, 3 Mar 2021 09:12:12 -0500 Subject: [PATCH 1046/1048] Add stripped down version of eosio.contracts v1.9.2 into main --- CMakeLists.txt | 4 +- LICENSE | 2 +- build.sh | 84 - contracts/eosio.bios/CMakeLists.txt | 13 - .../include/eosio.bios/eosio.bios.hpp | 282 ---- .../ricardian/eosio.bios.contracts.md.in | 189 --- contracts/eosio.bios/src/eosio.bios.cpp | 57 - contracts/eosio.msig/CMakeLists.txt | 13 - .../include/eosio.msig/eosio.msig.hpp | 162 -- .../ricardian/eosio.msig.contracts.md.in | 73 - contracts/eosio.msig/src/eosio.msig.cpp | 207 --- contracts/eosio.system/CMakeLists.txt | 43 - .../include/eosio.system/eosio.system.hpp | 1489 ----------------- .../include/eosio.system/exchange_state.hpp | 48 - .../include/eosio.system/native.hpp | 260 --- .../include/eosio.system/powerup.results.hpp | 33 - .../include/eosio.system/rex.results.hpp | 59 - .../ricardian/eosio.system.clauses.md | 63 - .../ricardian/eosio.system.contracts.md.in | 703 -------- .../eosio.system/src/delegate_bandwidth.cpp | 413 ----- contracts/eosio.system/src/eosio.system.cpp | 400 ----- contracts/eosio.system/src/exchange_state.cpp | 110 -- contracts/eosio.system/src/name_bidding.cpp | 80 - contracts/eosio.system/src/native.cpp | 11 - contracts/eosio.system/src/powerup.cpp | 398 ----- .../eosio.system/src/powerup.results.cpp | 5 - contracts/eosio.system/src/producer_pay.cpp | 191 --- contracts/eosio.system/src/rex.cpp | 1221 -------------- contracts/eosio.system/src/rex.results.cpp | 11 - contracts/eosio.system/src/voting.cpp | 415 ----- contracts/eosio.wrap/CMakeLists.txt | 13 - .../include/eosio.wrap/eosio.wrap.hpp | 38 - .../ricardian/eosio.wrap.contracts.md.in | 13 - contracts/eosio.wrap/src/eosio.wrap.cpp | 16 - contracts/icons/account.png | Bin 3795 -> 0 bytes contracts/icons/account.svg | 1 - contracts/icons/admin.png | Bin 2937 -> 0 bytes contracts/icons/admin.svg | 1 - contracts/icons/multisig.png | Bin 1411 -> 0 bytes contracts/icons/multisig.svg | 1 - contracts/icons/resource.png | Bin 1913 -> 0 bytes contracts/icons/resource.svg | 1 - contracts/icons/rex.png | Bin 2770 -> 0 bytes contracts/icons/rex.svg | 1 - contracts/icons/voting.png | Bin 3238 -> 0 bytes contracts/icons/voting.svg | 1 - docs.json | 8 +- docs/03_build-and-deploy.md | 47 +- pipeline.jsonc | 4 +- 49 files changed, 14 insertions(+), 7170 deletions(-) delete mode 100755 build.sh delete mode 100644 contracts/eosio.bios/CMakeLists.txt delete mode 100644 contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp delete mode 100644 contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in delete mode 100644 contracts/eosio.bios/src/eosio.bios.cpp delete mode 100644 contracts/eosio.msig/CMakeLists.txt delete mode 100644 contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp delete mode 100644 contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in delete mode 100644 contracts/eosio.msig/src/eosio.msig.cpp delete mode 100644 contracts/eosio.system/CMakeLists.txt delete mode 100644 contracts/eosio.system/include/eosio.system/eosio.system.hpp delete mode 100644 contracts/eosio.system/include/eosio.system/exchange_state.hpp delete mode 100644 contracts/eosio.system/include/eosio.system/native.hpp delete mode 100644 contracts/eosio.system/include/eosio.system/powerup.results.hpp delete mode 100644 contracts/eosio.system/include/eosio.system/rex.results.hpp delete mode 100644 contracts/eosio.system/ricardian/eosio.system.clauses.md delete mode 100644 contracts/eosio.system/ricardian/eosio.system.contracts.md.in delete mode 100644 contracts/eosio.system/src/delegate_bandwidth.cpp delete mode 100644 contracts/eosio.system/src/eosio.system.cpp delete mode 100644 contracts/eosio.system/src/exchange_state.cpp delete mode 100644 contracts/eosio.system/src/name_bidding.cpp delete mode 100644 contracts/eosio.system/src/native.cpp delete mode 100644 contracts/eosio.system/src/powerup.cpp delete mode 100644 contracts/eosio.system/src/powerup.results.cpp delete mode 100644 contracts/eosio.system/src/producer_pay.cpp delete mode 100644 contracts/eosio.system/src/rex.cpp delete mode 100644 contracts/eosio.system/src/rex.results.cpp delete mode 100644 contracts/eosio.system/src/voting.cpp delete mode 100644 contracts/eosio.wrap/CMakeLists.txt delete mode 100644 contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp delete mode 100644 contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in delete mode 100644 contracts/eosio.wrap/src/eosio.wrap.cpp delete mode 100644 contracts/icons/account.png delete mode 100644 contracts/icons/account.svg delete mode 100644 contracts/icons/admin.png delete mode 100644 contracts/icons/admin.svg delete mode 100644 contracts/icons/multisig.png delete mode 100644 contracts/icons/multisig.svg delete mode 100644 contracts/icons/resource.png delete mode 100644 contracts/icons/resource.svg delete mode 100644 contracts/icons/rex.png delete mode 100644 contracts/icons/rex.svg delete mode 100644 contracts/icons/voting.png delete mode 100644 contracts/icons/voting.svg diff --git a/CMakeLists.txt b/CMakeLists.txt index 7ddd2b13..edc6e2ce 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,8 +19,8 @@ find_package(eosio.cdt) message(STATUS "Building eosio.contracts v${VERSION_FULL}") -set(EOSIO_CDT_VERSION_MIN "1.7") -set(EOSIO_CDT_VERSION_SOFT_MAX "1.7") +set(EOSIO_CDT_VERSION_MIN "1.8") +set(EOSIO_CDT_VERSION_SOFT_MAX "1.8") #set(EOSIO_CDT_VERSION_HARD_MAX "") ### Check the version of eosio.cdt diff --git a/LICENSE b/LICENSE index 22d36d65..df058142 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2017-2019 block.one and its contributors. All rights reserved. +Copyright (c) 2017-2021 block.one and its contributors. All rights reserved. The MIT License diff --git a/build.sh b/build.sh deleted file mode 100755 index 558736cc..00000000 --- a/build.sh +++ /dev/null @@ -1,84 +0,0 @@ -#!/usr/bin/env bash -set -eo pipefail - -function usage() { - printf "Usage: $0 OPTION... - -e DIR Directory where EOSIO is installed. (Default: $HOME/eosio/X.Y) - -c DIR Directory where EOSIO.CDT is installed. (Default: /usr/local/eosio.cdt) - -t Build unit tests. - -y Noninteractive mode (Uses defaults for each prompt.) - -h Print this help menu. - \\n" "$0" 1>&2 - exit 1 -} - -BUILD_TESTS=false - -if [ $# -ne 0 ]; then - while getopts "e:c:tyh" opt; do - case "${opt}" in - e ) - EOSIO_DIR_PROMPT=$OPTARG - ;; - c ) - CDT_DIR_PROMPT=$OPTARG - ;; - t ) - BUILD_TESTS=true - ;; - y ) - NONINTERACTIVE=true - PROCEED=true - ;; - h ) - usage - ;; - ? ) - echo "Invalid Option!" 1>&2 - usage - ;; - : ) - echo "Invalid Option: -${OPTARG} requires an argument." 1>&2 - usage - ;; - * ) - usage - ;; - esac - done -fi - -# Source helper functions and variables. -. ./scripts/.environment -. ./scripts/helper.sh - -if [[ ${BUILD_TESTS} == true ]]; then - # Prompt user for location of eosio. - eosio-directory-prompt -fi - -# Prompt user for location of eosio.cdt. -cdt-directory-prompt - -# Include CDT_INSTALL_DIR in CMAKE_FRAMEWORK_PATH -echo "Using EOSIO.CDT installation at: $CDT_INSTALL_DIR" -export CMAKE_FRAMEWORK_PATH="${CDT_INSTALL_DIR}:${CMAKE_FRAMEWORK_PATH}" - -if [[ ${BUILD_TESTS} == true ]]; then - # Ensure eosio version is appropriate. - nodeos-version-check - - # Include EOSIO_INSTALL_DIR in CMAKE_FRAMEWORK_PATH - echo "Using EOSIO installation at: $EOSIO_INSTALL_DIR" - export CMAKE_FRAMEWORK_PATH="${EOSIO_INSTALL_DIR}:${CMAKE_FRAMEWORK_PATH}" -fi - -printf "\t=========== Building eosio.contracts ===========\n\n" -RED='\033[0;31m' -NC='\033[0m' -CPU_CORES=$(getconf _NPROCESSORS_ONLN) -mkdir -p build -pushd build &> /dev/null -cmake -DBUILD_TESTS=${BUILD_TESTS} ../ -make -j $CPU_CORES -popd &> /dev/null diff --git a/contracts/eosio.bios/CMakeLists.txt b/contracts/eosio.bios/CMakeLists.txt deleted file mode 100644 index 3709f70c..00000000 --- a/contracts/eosio.bios/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_contract(eosio.bios eosio.bios ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.bios.cpp) - -target_include_directories(eosio.bios - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) - -set_target_properties(eosio.bios - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.bios.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.bios.contracts.md @ONLY ) - -target_compile_options( eosio.bios PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp b/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp deleted file mode 100644 index 643e562c..00000000 --- a/contracts/eosio.bios/include/eosio.bios/eosio.bios.hpp +++ /dev/null @@ -1,282 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace eosiobios { - - using eosio::action_wrapper; - using eosio::check; - using eosio::checksum256; - using eosio::ignore; - using eosio::name; - using eosio::permission_level; - using eosio::public_key; - - struct permission_level_weight { - permission_level permission; - uint16_t weight; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) - }; - - struct key_weight { - eosio::public_key key; - uint16_t weight; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( key_weight, (key)(weight) ) - }; - - struct wait_weight { - uint32_t wait_sec; - uint16_t weight; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) - }; - - struct authority { - uint32_t threshold = 0; - std::vector keys; - std::vector accounts; - std::vector waits; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) - }; - - struct block_header { - uint32_t timestamp; - name producer; - uint16_t confirmed = 0; - checksum256 previous; - checksum256 transaction_mroot; - checksum256 action_mroot; - uint32_t schedule_version = 0; - std::optional new_producers; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE(block_header, (timestamp)(producer)(confirmed)(previous)(transaction_mroot)(action_mroot) - (schedule_version)(new_producers)) - }; - - /** - * The `eosio.bios` is the first sample of system contract provided by `block.one` through the EOSIO platform. It is a minimalist system contract because it only supplies the actions that are absolutely critical to bootstrap a chain and nothing more. This allows for a chain agnostic approach to bootstrapping a chain. - * - * Just like in the `eosio.system` sample contract implementation, there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the `eosio.system` contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - */ - class [[eosio::contract("eosio.bios")]] bios : public eosio::contract { - public: - using contract::contract; - /** - * New account action, called after a new account is created. This code enforces resource-limits rules - * for new accounts as well as new account naming conventions. - * - * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 - * characters long without '.' until a future account auction process is implemented - * which prevents name squatting. - * - * 2. new accounts must stake a minimal number of tokens (as set in system parameters) - * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. - */ - [[eosio::action]] - void newaccount( name creator, - name name, - ignore owner, - ignore active){} - /** - * Update authorization action updates pemission for an account. - * - * @param account - the account for which the permission is updated, - * @param pemission - the permission name which is updated, - * @param parem - the parent of the permission which is updated, - * @param aut - the json describing the permission authorization. - */ - [[eosio::action]] - void updateauth( ignore account, - ignore permission, - ignore parent, - ignore auth ) {} - - /** - * Delete authorization action deletes the authorization for an account's permission. - * - * @param account - the account for which the permission authorization is deleted, - * @param permission - the permission name been deleted. - */ - [[eosio::action]] - void deleteauth( ignore account, - ignore permission ) {} - - /** - * Link authorization action assigns a specific action from a contract to a permission you have created. Five system - * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. - * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the - * action needed to be authorized (and the contract belonging to), and looks up which permission - * is needed to pass authorization validation. If a link is set, that permission is used for authoraization - * validation otherwise then active is the default, with the exception of `eosio.any`. - * `eosio.any` is an implicit permission which exists on every account; you can link actions to `eosio.any` - * and that will make it so linked actions are accessible to any permissions defined for the account. - * - * @param account - the permission's owner to be linked and the payer of the RAM needed to store this link, - * @param code - the owner of the action to be linked, - * @param type - the action to be linked, - * @param requirement - the permission to be linked. - */ - [[eosio::action]] - void linkauth( ignore account, - ignore code, - ignore type, - ignore requirement ) {} - - /** - * Unlink authorization action it's doing the reverse of linkauth action, by unlinking the given action. - * - * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, - * @param code - the owner of the action to be unlinked, - * @param type - the action to be unlinked. - */ - [[eosio::action]] - void unlinkauth( ignore account, - ignore code, - ignore type ) {} - - /** - * Cancel delay action cancels a deferred transaction. - * - * @param canceling_auth - the permission that authorizes this action, - * @param trx_id - the deferred transaction id to be cancelled. - */ - [[eosio::action]] - void canceldelay( ignore canceling_auth, ignore trx_id ) {} - - /** - * Set code action sets the contract code for an account. - * - * @param account - the account for which to set the contract code. - * @param vmtype - reserved, set it to zero. - * @param vmversion - reserved, set it to zero. - * @param code - the code content to be set, in the form of a blob binary.. - */ - [[eosio::action]] - void setcode( name account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} - - /** - * Set abi action sets the abi for contract identified by `account` name. Creates an entry in the abi_hash_table - * index, with `account` name as key, if it is not already present and sets its value with the abi hash. - * Otherwise it is updating the current abi hash value for the existing `account` key. - * - * @param account - the name of the account to set the abi for - * @param abi - the abi hash represented as a vector of characters - */ - [[eosio::action]] - void setabi( name account, const std::vector& abi ); - - /** - * On error action, notification of this action is delivered to the sender of a deferred transaction - * when an objective error occurs while executing the deferred transaction. - * This action is not meant to be called directly. - * - * @param sender_id - the id for the deferred transaction chosen by the sender, - * @param sent_trx - the deferred transaction that failed. - */ - [[eosio::action]] - void onerror( ignore sender_id, ignore> sent_trx ); - - /** - * Set privilege action allows to set privilege status for an account (turn it on/off). - * @param account - the account to set the privileged status for. - * @param is_priv - 0 for false, > 0 for true. - */ - [[eosio::action]] - void setpriv( name account, uint8_t is_priv ); - - /** - * Sets the resource limits of an account - * - * @param account - name of the account whose resource limit to be set - * @param ram_bytes - ram limit in absolute bytes - * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts) - * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts) - */ - [[eosio::action]] - void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); - - /** - * Set producers action, sets a new list of active producers, by proposing a schedule change, once the block that - * contains the proposal becomes irreversible, the schedule is promoted to "pending" - * automatically. Once the block that promotes the schedule is irreversible, the schedule will - * become "active". - * - * @param schedule - New list of active producers to set - */ - [[eosio::action]] - void setprods( const std::vector& schedule ); - - /** - * Set params action, sets the blockchain parameters. By tuning these parameters, various degrees of customization can be achieved. - * - * @param params - New blockchain parameters to set - */ - [[eosio::action]] - void setparams( const eosio::blockchain_parameters& params ); - - /** - * Require authorization action, checks if the account name `from` passed in as param has authorization to access - * current action, that is, if it is listed in the action’s allowed permissions vector. - * - * @param from - the account name to authorize - */ - [[eosio::action]] - void reqauth( name from ); - - /** - * Activate action, activates a protocol feature - * - * @param feature_digest - hash of the protocol feature to activate. - */ - [[eosio::action]] - void activate( const eosio::checksum256& feature_digest ); - - /** - * Require activated action, asserts that a protocol feature has been activated - * - * @param feature_digest - hash of the protocol feature to check for activation. - */ - [[eosio::action]] - void reqactivated( const eosio::checksum256& feature_digest ); - - struct [[eosio::table]] abi_hash { - name owner; - checksum256 hash; - uint64_t primary_key()const { return owner.value; } - - EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) - }; - - typedef eosio::multi_index< "abihash"_n, abi_hash > abi_hash_table; - - using newaccount_action = action_wrapper<"newaccount"_n, &bios::newaccount>; - using updateauth_action = action_wrapper<"updateauth"_n, &bios::updateauth>; - using deleteauth_action = action_wrapper<"deleteauth"_n, &bios::deleteauth>; - using linkauth_action = action_wrapper<"linkauth"_n, &bios::linkauth>; - using unlinkauth_action = action_wrapper<"unlinkauth"_n, &bios::unlinkauth>; - using canceldelay_action = action_wrapper<"canceldelay"_n, &bios::canceldelay>; - using setcode_action = action_wrapper<"setcode"_n, &bios::setcode>; - using setabi_action = action_wrapper<"setabi"_n, &bios::setabi>; - using setpriv_action = action_wrapper<"setpriv"_n, &bios::setpriv>; - using setalimits_action = action_wrapper<"setalimits"_n, &bios::setalimits>; - using setprods_action = action_wrapper<"setprods"_n, &bios::setprods>; - using setparams_action = action_wrapper<"setparams"_n, &bios::setparams>; - using reqauth_action = action_wrapper<"reqauth"_n, &bios::reqauth>; - using activate_action = action_wrapper<"activate"_n, &bios::activate>; - using reqactivated_action = action_wrapper<"reqactivated"_n, &bios::reqactivated>; - }; -} diff --git a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in b/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in deleted file mode 100644 index a08b66e4..00000000 --- a/contracts/eosio.bios/ricardian/eosio.bios.contracts.md.in +++ /dev/null @@ -1,189 +0,0 @@ -

activate

- ---- -spec_version: "0.2.0" -title: Activate Protocol Feature -summary: 'Activate protocol feature {{nowrap feature_digest}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} activates the protocol feature with a digest of {{feature_digest}}. - -

canceldelay

- ---- -spec_version: "0.2.0" -title: Cancel Delayed Transaction -summary: '{{nowrap canceling_auth.actor}} cancels a delayed transaction' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{canceling_auth.actor}} cancels the delayed transaction with id {{trx_id}}. - -

deleteauth

- ---- -spec_version: "0.2.0" -title: Delete Account Permission -summary: 'Delete the {{nowrap permission}} permission of {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Delete the {{permission}} permission of {{account}}. - -

linkauth

- ---- -spec_version: "0.2.0" -title: Link Action to Permission -summary: '{{nowrap account}} sets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract to {{nowrap requirement}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{account}} sets the minimum required permission for the {{#if type}}{{type}} action of the{{/if}} {{code}} contract to {{requirement}}. - -{{#if type}}{{else}}Any links explicitly associated to specific actions of {{code}} will take precedence.{{/if}} - -

newaccount

- ---- -spec_version: "0.2.0" -title: Create New Account -summary: '{{nowrap creator}} creates a new account with the name {{nowrap name}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{creator}} creates a new account with the name {{name}} and the following permissions: - -owner permission with authority: -{{to_json owner}} - -active permission with authority: -{{to_json active}} - -

reqactivated

- ---- -spec_version: "0.2.0" -title: Assert Protocol Feature Activation -summary: 'Assert that protocol feature {{nowrap feature_digest}} has been activated' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -Assert that the protocol feature with a digest of {{feature_digest}} has been activated. - -

reqauth

- ---- -spec_version: "0.2.0" -title: Assert Authorization -summary: 'Assert that authorization by {{nowrap from}} is provided' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Assert that authorization by {{from}} is provided. - -

setabi

- ---- -spec_version: "0.2.0" -title: Deploy Contract ABI -summary: 'Deploy contract ABI on account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Deploy the ABI file associated with the contract on account {{account}}. - -

setalimits

- ---- -spec_version: "0.2.0" -title: Adjust Resource Limits of Account -summary: 'Adjust resource limits of account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} updates {{account}}’s resource limits to have a RAM quota of {{ram_bytes}} bytes, a NET bandwidth quota of {{net_weight}} and a CPU bandwidth quota of {{cpu_weight}}. - -

setcode

- ---- -spec_version: "0.2.0" -title: Deploy Contract Code -summary: 'Deploy contract code on account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Deploy compiled contract code to the account {{account}}. - -

setparams

- ---- -spec_version: "0.2.0" -title: Set System Parameters -summary: 'Set system parameters' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} sets system parameters to: -{{to_json params}} - -

setpriv

- ---- -spec_version: "0.2.0" -title: Make an Account Privileged or Unprivileged -summary: '{{#if is_priv}}Make {{nowrap account}} privileged{{else}}Remove privileged status of {{nowrap account}}{{/if}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{#if is_priv}} -{{$action.account}} makes {{account}} privileged. -{{else}} -{{$action.account}} removes privileged status of {{account}}. -{{/if}} - -

setprods

- ---- -spec_version: "0.2.0" -title: Set Block Producers -summary: 'Set block producer schedule' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} proposes a block producer schedule of: -{{#each schedule}} - 1. {{this.producer_name}} -{{/each}} - -The block signing authorities of each of the producers in the above schedule are listed below: -{{#each schedule}} -### {{this.producer_name}} -{{to_json this.authority}} -{{/each}} - -

unlinkauth

- ---- -spec_version: "0.2.0" -title: Unlink Action from Permission -summary: '{{nowrap account}} unsets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{account}} removes the association between the {{#if type}}{{type}} action of the{{/if}} {{code}} contract and its minimum required permission. - -{{#if type}}{{else}}This will not remove any links explicitly associated to specific actions of {{code}}.{{/if}} - -

updateauth

- ---- -spec_version: "0.2.0" -title: Modify Account Permission -summary: 'Add or update the {{nowrap permission}} permission of {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Modify, and create if necessary, the {{permission}} permission of {{account}} to have a parent permission of {{parent}} and the following authority: -{{to_json auth}} diff --git a/contracts/eosio.bios/src/eosio.bios.cpp b/contracts/eosio.bios/src/eosio.bios.cpp deleted file mode 100644 index 69d6758f..00000000 --- a/contracts/eosio.bios/src/eosio.bios.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include - -namespace eosiobios { - -void bios::setabi( name account, const std::vector& abi ) { - abi_hash_table table(get_self(), get_self().value); - auto itr = table.find( account.value ); - if( itr == table.end() ) { - table.emplace( account, [&]( auto& row ) { - row.owner = account; - row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); - }); - } else { - table.modify( itr, eosio::same_payer, [&]( auto& row ) { - row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); - }); - } -} - -void bios::onerror( ignore, ignore> ) { - check( false, "the onerror action cannot be called directly" ); -} - -void bios::setpriv( name account, uint8_t is_priv ) { - require_auth( get_self() ); - set_privileged( account, is_priv ); -} - -void bios::setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ) { - require_auth( get_self() ); - set_resource_limits( account, ram_bytes, net_weight, cpu_weight ); -} - -void bios::setprods( const std::vector& schedule ) { - require_auth( get_self() ); - set_proposed_producers( schedule ); -} - -void bios::setparams( const eosio::blockchain_parameters& params ) { - require_auth( get_self() ); - set_blockchain_parameters( params ); -} - -void bios::reqauth( name from ) { - require_auth( from ); -} - -void bios::activate( const eosio::checksum256& feature_digest ) { - require_auth( get_self() ); - preactivate_feature( feature_digest ); -} - -void bios::reqactivated( const eosio::checksum256& feature_digest ) { - check( is_feature_activated( feature_digest ), "protocol feature is not activated" ); -} - -} diff --git a/contracts/eosio.msig/CMakeLists.txt b/contracts/eosio.msig/CMakeLists.txt deleted file mode 100644 index 0947ea9d..00000000 --- a/contracts/eosio.msig/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_contract(eosio.msig eosio.msig ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.msig.cpp) - -target_include_directories(eosio.msig - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) - -set_target_properties(eosio.msig - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.msig.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.msig.contracts.md @ONLY ) - -target_compile_options( eosio.msig PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp b/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp deleted file mode 100644 index 19f2600c..00000000 --- a/contracts/eosio.msig/include/eosio.msig/eosio.msig.hpp +++ /dev/null @@ -1,162 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -namespace eosio { - - /** - * The `eosio.msig` system contract allows for creation of proposed transactions which require authorization from a list of accounts, approval of the proposed transactions by those accounts required to approve it, and finally, it also allows the execution of the approved transactions on the blockchain. - * - * In short, the workflow to propose, review, approve and then executed a transaction it can be described by the following: - * - first you create a transaction json file, - * - then you submit this proposal to the `eosio.msig` contract, and you also insert the account permissions required to approve this proposal into the command that submits the proposal to the blockchain, - * - the proposal then gets stored on the blockchain by the `eosio.msig` contract, and is accessible for review and approval to those accounts required to approve it, - * - after each of the appointed accounts required to approve the proposed transactions reviews and approves it, you can execute the proposed transaction. The `eosio.msig` contract will execute it automatically, but not before validating that the transaction has not expired, it is not cancelled, and it has been signed by all the permissions in the initial proposal's required permission list. - */ - class [[eosio::contract("eosio.msig")]] multisig : public contract { - public: - using contract::contract; - - /** - * Propose action, creates a proposal containing one transaction. - * Allows an account `proposer` to make a proposal `proposal_name` which has `requested` - * permission levels expected to approve the proposal, and if approved by all expected - * permission levels then `trx` transaction can we executed by this proposal. - * The `proposer` account is authorized and the `trx` transaction is verified if it was - * authorized by the provided keys and permissions, and if the proposal name doesn’t - * already exist; if all validations pass the `proposal_name` and `trx` trasanction are - * saved in the proposals table and the `requested` permission levels to the - * approvals table (for the `proposer` context). Storage changes are billed to `proposer`. - * - * @param proposer - The account proposing a transaction - * @param proposal_name - The name of the proposal (should be unique for proposer) - * @param requested - Permission levels expected to approve the proposal - * @param trx - Proposed transaction - */ - [[eosio::action]] - void propose(ignore proposer, ignore proposal_name, - ignore> requested, ignore trx); - /** - * Approve action approves an existing proposal. Allows an account, the owner of `level` permission, to approve a proposal `proposal_name` - * proposed by `proposer`. If the proposal's requested approval list contains the `level` - * permission then the `level` permission is moved from internal `requested_approvals` list to - * internal `provided_approvals` list of the proposal, thus persisting the approval for - * the `proposal_name` proposal. Storage changes are billed to `proposer`. - * - * @param proposer - The account proposing a transaction - * @param proposal_name - The name of the proposal (should be unique for proposer) - * @param level - Permission level approving the transaction - * @param proposal_hash - Transaction's checksum - */ - [[eosio::action]] - void approve( name proposer, name proposal_name, permission_level level, - const eosio::binary_extension& proposal_hash ); - /** - * Unapprove action revokes an existing proposal. This action is the reverse of the `approve` action: if all validations pass - * the `level` permission is erased from internal `provided_approvals` and added to the internal - * `requested_approvals` list, and thus un-approve or revoke the proposal. - * - * @param proposer - The account proposing a transaction - * @param proposal_name - The name of the proposal (should be an existing proposal) - * @param level - Permission level revoking approval for proposal - */ - [[eosio::action]] - void unapprove( name proposer, name proposal_name, permission_level level ); - /** - * Cancel action cancels an existing proposal. - * - * @param proposer - The account proposing a transaction - * @param proposal_name - The name of the proposal (should be an existing proposal) - * @param canceler - The account cancelling the proposal (only the proposer can cancel an unexpired transaction, and the canceler has to be different than the proposer) - * - * Allows the `canceler` account to cancel the `proposal_name` proposal, created by a `proposer`, - * only after time has expired on the proposed transaction. It removes corresponding entries from - * internal proptable and from approval (or old approvals) tables as well. - */ - [[eosio::action]] - void cancel( name proposer, name proposal_name, name canceler ); - /** - * Exec action allows an `executer` account to execute a proposal. - * - * Preconditions: - * - `executer` has authorization, - * - `proposal_name` is found in the proposals table, - * - all requested approvals are received, - * - proposed transaction is not expired, - * - and approval accounts are not found in invalidations table. - * - * If all preconditions are met the transaction is executed as a deferred transaction, - * and the proposal is erased from the proposals table. - * - * @param proposer - The account proposing a transaction - * @param proposal_name - The name of the proposal (should be an existing proposal) - * @param executer - The account executing the transaction - */ - [[eosio::action]] - void exec( name proposer, name proposal_name, name executer ); - /** - * Invalidate action allows an `account` to invalidate itself, that is, its name is added to - * the invalidations table and this table will be cross referenced when exec is performed. - * - * @param account - The account invalidating the transaction - */ - [[eosio::action]] - void invalidate( name account ); - - using propose_action = eosio::action_wrapper<"propose"_n, &multisig::propose>; - using approve_action = eosio::action_wrapper<"approve"_n, &multisig::approve>; - using unapprove_action = eosio::action_wrapper<"unapprove"_n, &multisig::unapprove>; - using cancel_action = eosio::action_wrapper<"cancel"_n, &multisig::cancel>; - using exec_action = eosio::action_wrapper<"exec"_n, &multisig::exec>; - using invalidate_action = eosio::action_wrapper<"invalidate"_n, &multisig::invalidate>; - - private: - struct [[eosio::table]] proposal { - name proposal_name; - std::vector packed_transaction; - - uint64_t primary_key()const { return proposal_name.value; } - }; - - typedef eosio::multi_index< "proposal"_n, proposal > proposals; - - struct [[eosio::table]] old_approvals_info { - name proposal_name; - std::vector requested_approvals; - std::vector provided_approvals; - - uint64_t primary_key()const { return proposal_name.value; } - }; - typedef eosio::multi_index< "approvals"_n, old_approvals_info > old_approvals; - - struct approval { - permission_level level; - time_point time; - }; - - struct [[eosio::table]] approvals_info { - uint8_t version = 1; - name proposal_name; - //requested approval doesn't need to cointain time, but we want requested approval - //to be of exact the same size ad provided approval, in this case approve/unapprove - //doesn't change serialized data size. So, we use the same type. - std::vector requested_approvals; - std::vector provided_approvals; - - uint64_t primary_key()const { return proposal_name.value; } - }; - typedef eosio::multi_index< "approvals2"_n, approvals_info > approvals; - - struct [[eosio::table]] invalidation { - name account; - time_point last_invalidation_time; - - uint64_t primary_key() const { return account.value; } - }; - - typedef eosio::multi_index< "invals"_n, invalidation > invalidations; - }; -} /// namespace eosio diff --git a/contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in b/contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in deleted file mode 100644 index b9f3f35f..00000000 --- a/contracts/eosio.msig/ricardian/eosio.msig.contracts.md.in +++ /dev/null @@ -1,73 +0,0 @@ -

approve

- ---- -spec_version: "0.2.0" -title: Approve Proposed Transaction -summary: '{{nowrap level.actor}} approves the {{nowrap proposal_name}} proposal' -icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ ---- - -{{level.actor}} approves the {{proposal_name}} proposal proposed by {{proposer}} with the {{level.permission}} permission of {{level.actor}}. - -

cancel

- ---- -spec_version: "0.2.0" -title: Cancel Proposed Transaction -summary: '{{nowrap canceler}} cancels the {{nowrap proposal_name}} proposal' -icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ ---- - -{{canceler}} cancels the {{proposal_name}} proposal submitted by {{proposer}}. - -

exec

- ---- -spec_version: "0.2.0" -title: Execute Proposed Transaction -summary: '{{nowrap executer}} executes the {{nowrap proposal_name}} proposal' -icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ ---- - -{{executer}} executes the {{proposal_name}} proposal submitted by {{proposer}} if the minimum required approvals for the proposal have been secured. - -

invalidate

- ---- -spec_version: "0.2.0" -title: Invalidate All Approvals -summary: '{{nowrap account}} invalidates approvals on outstanding proposals' -icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ ---- - -{{account}} invalidates all approvals on proposals which have not yet executed. - -

propose

- ---- -spec_version: "0.2.0" -title: Propose Transaction -summary: '{{nowrap proposer}} creates the {{nowrap proposal_name}}' -icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ ---- - -{{proposer}} creates the {{proposal_name}} proposal for the following transaction: -{{to_json trx}} - -The proposal requests approvals from the following accounts at the specified permission levels: -{{#each requested}} - + {{this.permission}} permission of {{this.actor}} -{{/each}} - -If the proposed transaction is not executed prior to {{trx.expiration}}, the proposal will automatically expire. - -

unapprove

- ---- -spec_version: "0.2.0" -title: Unapprove Proposed Transaction -summary: '{{nowrap level.actor}} revokes the approval previously provided to {{nowrap proposal_name}} proposal' -icon: @ICON_BASE_URL@/@MULTISIG_ICON_URI@ ---- - -{{level.actor}} revokes the approval previously provided at their {{level.permission}} permission level from the {{proposal_name}} proposal proposed by {{proposer}}. diff --git a/contracts/eosio.msig/src/eosio.msig.cpp b/contracts/eosio.msig/src/eosio.msig.cpp deleted file mode 100644 index 17692192..00000000 --- a/contracts/eosio.msig/src/eosio.msig.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include -#include -#include - -#include - -namespace eosio { - -void multisig::propose( ignore proposer, - ignore proposal_name, - ignore> requested, - ignore trx ) -{ - name _proposer; - name _proposal_name; - std::vector _requested; - transaction_header _trx_header; - - _ds >> _proposer >> _proposal_name >> _requested; - - const char* trx_pos = _ds.pos(); - size_t size = _ds.remaining(); - _ds >> _trx_header; - - require_auth( _proposer ); - check( _trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); - //check( trx_header.actions.size() > 0, "transaction must have at least one action" ); - - proposals proptable( get_self(), _proposer.value ); - check( proptable.find( _proposal_name.value ) == proptable.end(), "proposal with the same name exists" ); - - auto packed_requested = pack(_requested); - auto res = check_transaction_authorization( - trx_pos, size, - (const char*)0, 0, - packed_requested.data(), packed_requested.size() - ); - - check( res > 0, "transaction authorization failed" ); - - std::vector pkd_trans; - pkd_trans.resize(size); - memcpy((char*)pkd_trans.data(), trx_pos, size); - proptable.emplace( _proposer, [&]( auto& prop ) { - prop.proposal_name = _proposal_name; - prop.packed_transaction = pkd_trans; - }); - - approvals apptable( get_self(), _proposer.value ); - apptable.emplace( _proposer, [&]( auto& a ) { - a.proposal_name = _proposal_name; - a.requested_approvals.reserve( _requested.size() ); - for ( auto& level : _requested ) { - a.requested_approvals.push_back( approval{ level, time_point{ microseconds{0} } } ); - } - }); -} - -void multisig::approve( name proposer, name proposal_name, permission_level level, - const eosio::binary_extension& proposal_hash ) -{ - require_auth( level ); - - if( proposal_hash ) { - proposals proptable( get_self(), proposer.value ); - auto& prop = proptable.get( proposal_name.value, "proposal not found" ); - assert_sha256( prop.packed_transaction.data(), prop.packed_transaction.size(), *proposal_hash ); - } - - approvals apptable( get_self(), proposer.value ); - auto apps_it = apptable.find( proposal_name.value ); - if ( apps_it != apptable.end() ) { - auto itr = std::find_if( apps_it->requested_approvals.begin(), apps_it->requested_approvals.end(), [&](const approval& a) { return a.level == level; } ); - check( itr != apps_it->requested_approvals.end(), "approval is not on the list of requested approvals" ); - - apptable.modify( apps_it, proposer, [&]( auto& a ) { - a.provided_approvals.push_back( approval{ level, current_time_point() } ); - a.requested_approvals.erase( itr ); - }); - } else { - old_approvals old_apptable( get_self(), proposer.value ); - auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); - - auto itr = std::find( apps.requested_approvals.begin(), apps.requested_approvals.end(), level ); - check( itr != apps.requested_approvals.end(), "approval is not on the list of requested approvals" ); - - old_apptable.modify( apps, proposer, [&]( auto& a ) { - a.provided_approvals.push_back( level ); - a.requested_approvals.erase( itr ); - }); - } -} - -void multisig::unapprove( name proposer, name proposal_name, permission_level level ) { - require_auth( level ); - - approvals apptable( get_self(), proposer.value ); - auto apps_it = apptable.find( proposal_name.value ); - if ( apps_it != apptable.end() ) { - auto itr = std::find_if( apps_it->provided_approvals.begin(), apps_it->provided_approvals.end(), [&](const approval& a) { return a.level == level; } ); - check( itr != apps_it->provided_approvals.end(), "no approval previously granted" ); - apptable.modify( apps_it, proposer, [&]( auto& a ) { - a.requested_approvals.push_back( approval{ level, current_time_point() } ); - a.provided_approvals.erase( itr ); - }); - } else { - old_approvals old_apptable( get_self(), proposer.value ); - auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); - auto itr = std::find( apps.provided_approvals.begin(), apps.provided_approvals.end(), level ); - check( itr != apps.provided_approvals.end(), "no approval previously granted" ); - old_apptable.modify( apps, proposer, [&]( auto& a ) { - a.requested_approvals.push_back( level ); - a.provided_approvals.erase( itr ); - }); - } -} - -void multisig::cancel( name proposer, name proposal_name, name canceler ) { - require_auth( canceler ); - - proposals proptable( get_self(), proposer.value ); - auto& prop = proptable.get( proposal_name.value, "proposal not found" ); - - if( canceler != proposer ) { - check( unpack( prop.packed_transaction ).expiration < eosio::time_point_sec(current_time_point()), "cannot cancel until expiration" ); - } - proptable.erase(prop); - - //remove from new table - approvals apptable( get_self(), proposer.value ); - auto apps_it = apptable.find( proposal_name.value ); - if ( apps_it != apptable.end() ) { - apptable.erase(apps_it); - } else { - old_approvals old_apptable( get_self(), proposer.value ); - auto apps_it = old_apptable.find( proposal_name.value ); - check( apps_it != old_apptable.end(), "proposal not found" ); - old_apptable.erase(apps_it); - } -} - -void multisig::exec( name proposer, name proposal_name, name executer ) { - require_auth( executer ); - - proposals proptable( get_self(), proposer.value ); - auto& prop = proptable.get( proposal_name.value, "proposal not found" ); - transaction_header trx_header; - datastream ds( prop.packed_transaction.data(), prop.packed_transaction.size() ); - ds >> trx_header; - check( trx_header.expiration >= eosio::time_point_sec(current_time_point()), "transaction expired" ); - - approvals apptable( get_self(), proposer.value ); - auto apps_it = apptable.find( proposal_name.value ); - std::vector approvals; - invalidations inv_table( get_self(), get_self().value ); - if ( apps_it != apptable.end() ) { - approvals.reserve( apps_it->provided_approvals.size() ); - for ( auto& p : apps_it->provided_approvals ) { - auto it = inv_table.find( p.level.actor.value ); - if ( it == inv_table.end() || it->last_invalidation_time < p.time ) { - approvals.push_back(p.level); - } - } - apptable.erase(apps_it); - } else { - old_approvals old_apptable( get_self(), proposer.value ); - auto& apps = old_apptable.get( proposal_name.value, "proposal not found" ); - for ( auto& level : apps.provided_approvals ) { - auto it = inv_table.find( level.actor.value ); - if ( it == inv_table.end() ) { - approvals.push_back( level ); - } - } - old_apptable.erase(apps); - } - auto packed_provided_approvals = pack(approvals); - auto res = check_transaction_authorization( - prop.packed_transaction.data(), prop.packed_transaction.size(), - (const char*)0, 0, - packed_provided_approvals.data(), packed_provided_approvals.size() - ); - - check( res > 0, "transaction authorization failed" ); - - send_deferred( (uint128_t(proposer.value) << 64) | proposal_name.value, executer, - prop.packed_transaction.data(), prop.packed_transaction.size() ); - - proptable.erase(prop); -} - -void multisig::invalidate( name account ) { - require_auth( account ); - invalidations inv_table( get_self(), get_self().value ); - auto it = inv_table.find( account.value ); - if ( it == inv_table.end() ) { - inv_table.emplace( account, [&](auto& i) { - i.account = account; - i.last_invalidation_time = current_time_point(); - }); - } else { - inv_table.modify( it, account, [&](auto& i) { - i.last_invalidation_time = current_time_point(); - }); - } -} - -} /// namespace eosio diff --git a/contracts/eosio.system/CMakeLists.txt b/contracts/eosio.system/CMakeLists.txt deleted file mode 100644 index 6b47d156..00000000 --- a/contracts/eosio.system/CMakeLists.txt +++ /dev/null @@ -1,43 +0,0 @@ -add_contract(eosio.system eosio.system - ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/delegate_bandwidth.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/exchange_state.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/name_bidding.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/powerup.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp - ${CMAKE_CURRENT_SOURCE_DIR}/src/voting.cpp -) - -target_include_directories(eosio.system - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include - ${CMAKE_CURRENT_SOURCE_DIR}/../eosio.token/include) - -set_target_properties(eosio.system - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -add_contract(rex.results rex.results ${CMAKE_CURRENT_SOURCE_DIR}/src/rex.results.cpp) -add_contract(powup.results powup.results ${CMAKE_CURRENT_SOURCE_DIR}/src/powerup.results.cpp) - -target_include_directories(rex.results - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) - -target_include_directories(powup.results - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) - -set_target_properties(rex.results - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.rex") - -set_target_properties(powup.results - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/.powerup") - -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.system.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.system.contracts.md @ONLY ) - -target_compile_options( eosio.system PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.system/include/eosio.system/eosio.system.hpp b/contracts/eosio.system/include/eosio.system/eosio.system.hpp deleted file mode 100644 index d49834cd..00000000 --- a/contracts/eosio.system/include/eosio.system/eosio.system.hpp +++ /dev/null @@ -1,1489 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#ifdef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX -#undef CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX -#endif -// CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX macro determines whether ramfee and namebid proceeds are -// channeled to REX pool. In order to stop these proceeds from being channeled, the macro must -// be set to 0. -#define CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX 1 - -namespace eosiosystem { - - using eosio::asset; - using eosio::block_timestamp; - using eosio::check; - using eosio::const_mem_fun; - using eosio::datastream; - using eosio::indexed_by; - using eosio::name; - using eosio::same_payer; - using eosio::symbol; - using eosio::symbol_code; - using eosio::time_point; - using eosio::time_point_sec; - using eosio::unsigned_int; - - inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 - - template - static inline auto has_field( F flags, E field ) - -> std::enable_if_t< std::is_integral_v && std::is_unsigned_v && - std::is_enum_v && std::is_same_v< F, std::underlying_type_t >, bool> - { - return ( (flags & static_cast(field)) != 0 ); - } - - template - static inline auto set_field( F flags, E field, bool value = true ) - -> std::enable_if_t< std::is_integral_v && std::is_unsigned_v && - std::is_enum_v && std::is_same_v< F, std::underlying_type_t >, F > - { - if( value ) - return ( flags | static_cast(field) ); - else - return ( flags & ~static_cast(field) ); - } - - static constexpr uint32_t seconds_per_year = 52 * 7 * 24 * 3600; - static constexpr uint32_t seconds_per_day = 24 * 3600; - static constexpr uint32_t seconds_per_hour = 3600; - static constexpr int64_t useconds_per_year = int64_t(seconds_per_year) * 1000'000ll; - static constexpr int64_t useconds_per_day = int64_t(seconds_per_day) * 1000'000ll; - static constexpr int64_t useconds_per_hour = int64_t(seconds_per_hour) * 1000'000ll; - static constexpr uint32_t blocks_per_day = 2 * seconds_per_day; // half seconds per day - - static constexpr int64_t min_activated_stake = 150'000'000'0000; - static constexpr int64_t ram_gift_bytes = 1400; - static constexpr int64_t min_pervote_daily_pay = 100'0000; - static constexpr uint32_t refund_delay_sec = 3 * seconds_per_day; - - static constexpr int64_t inflation_precision = 100; // 2 decimals - static constexpr int64_t default_annual_rate = 500; // 5% annual rate - static constexpr int64_t pay_factor_precision = 10000; - static constexpr int64_t default_inflation_pay_factor = 50000; // producers pay share = 10000 / 50000 = 20% of the inflation - static constexpr int64_t default_votepay_factor = 40000; // per-block pay share = 10000 / 40000 = 25% of the producer pay - - /** - * The `eosio.system` smart contract is provided by `block.one` as a sample system contract, and it defines the structures and actions needed for blockchain's core functionality. - * - * Just like in the `eosio.bios` sample contract implementation, there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the `eosio.system` contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - * - * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or - * delegate their vote to a proxy. - * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. - * - Users can buy and sell RAM at a market-determined price. - * - Users can bid on premium names. - * - A resource exchange system (REX) allows token holders to lend their tokens, - * and users to rent CPU and Network resources in return for a market-determined fee. - */ - - // A name bid, which consists of: - // - a `newname` name that the bid is for - // - a `high_bidder` account name that is the one with the highest bid so far - // - the `high_bid` which is amount of highest bid - // - and `last_bid_time` which is the time of the highest bid - struct [[eosio::table, eosio::contract("eosio.system")]] name_bid { - name newname; - name high_bidder; - int64_t high_bid = 0; ///< negative high_bid == closed auction waiting to be claimed - time_point last_bid_time; - - uint64_t primary_key()const { return newname.value; } - uint64_t by_high_bid()const { return static_cast(-high_bid); } - }; - - // A bid refund, which is defined by: - // - the `bidder` account name owning the refund - // - the `amount` to be refunded - struct [[eosio::table, eosio::contract("eosio.system")]] bid_refund { - name bidder; - asset amount; - - uint64_t primary_key()const { return bidder.value; } - }; - typedef eosio::multi_index< "namebids"_n, name_bid, - indexed_by<"highbid"_n, const_mem_fun > - > name_bid_table; - - typedef eosio::multi_index< "bidrefunds"_n, bid_refund > bid_refund_table; - - // Defines new global state parameters. - struct [[eosio::table("global"), eosio::contract("eosio.system")]] eosio_global_state : eosio::blockchain_parameters { - uint64_t free_ram()const { return max_ram_size - total_ram_bytes_reserved; } - - uint64_t max_ram_size = 64ll*1024 * 1024 * 1024; - uint64_t total_ram_bytes_reserved = 0; - int64_t total_ram_stake = 0; - - block_timestamp last_producer_schedule_update; - time_point last_pervote_bucket_fill; - int64_t pervote_bucket = 0; - int64_t perblock_bucket = 0; - uint32_t total_unpaid_blocks = 0; /// all blocks which have been produced but not paid - int64_t total_activated_stake = 0; - time_point thresh_activated_stake_time; - uint16_t last_producer_schedule_size = 0; - double total_producer_vote_weight = 0; /// the sum of all producer votes - block_timestamp last_name_close; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE_DERIVED( eosio_global_state, eosio::blockchain_parameters, - (max_ram_size)(total_ram_bytes_reserved)(total_ram_stake) - (last_producer_schedule_update)(last_pervote_bucket_fill) - (pervote_bucket)(perblock_bucket)(total_unpaid_blocks)(total_activated_stake)(thresh_activated_stake_time) - (last_producer_schedule_size)(total_producer_vote_weight)(last_name_close) ) - }; - - // Defines new global state parameters added after version 1.0 - struct [[eosio::table("global2"), eosio::contract("eosio.system")]] eosio_global_state2 { - eosio_global_state2(){} - - uint16_t new_ram_per_block = 0; - block_timestamp last_ram_increase; - block_timestamp last_block_num; /* deprecated */ - double total_producer_votepay_share = 0; - uint8_t revision = 0; ///< used to track version updates in the future. - - EOSLIB_SERIALIZE( eosio_global_state2, (new_ram_per_block)(last_ram_increase)(last_block_num) - (total_producer_votepay_share)(revision) ) - }; - - // Defines new global state parameters added after version 1.3.0 - struct [[eosio::table("global3"), eosio::contract("eosio.system")]] eosio_global_state3 { - eosio_global_state3() { } - time_point last_vpay_state_update; - double total_vpay_share_change_rate = 0; - - EOSLIB_SERIALIZE( eosio_global_state3, (last_vpay_state_update)(total_vpay_share_change_rate) ) - }; - - // Defines new global state parameters to store inflation rate and distribution - struct [[eosio::table("global4"), eosio::contract("eosio.system")]] eosio_global_state4 { - eosio_global_state4() { } - double continuous_rate; - int64_t inflation_pay_factor; - int64_t votepay_factor; - - EOSLIB_SERIALIZE( eosio_global_state4, (continuous_rate)(inflation_pay_factor)(votepay_factor) ) - }; - - inline eosio::block_signing_authority convert_to_block_signing_authority( const eosio::public_key& producer_key ) { - return eosio::block_signing_authority_v0{ .threshold = 1, .keys = {{producer_key, 1}} }; - } - - // Defines `producer_info` structure to be stored in `producer_info` table, added after version 1.0 - struct [[eosio::table, eosio::contract("eosio.system")]] producer_info { - name owner; - double total_votes = 0; - eosio::public_key producer_key; /// a packed public key object - bool is_active = true; - std::string url; - uint32_t unpaid_blocks = 0; - time_point last_claim_time; - uint16_t location = 0; - eosio::binary_extension producer_authority; // added in version 1.9.0 - - uint64_t primary_key()const { return owner.value; } - double by_votes()const { return is_active ? -total_votes : total_votes; } - bool active()const { return is_active; } - void deactivate() { producer_key = public_key(); producer_authority.reset(); is_active = false; } - - eosio::block_signing_authority get_producer_authority()const { - if( producer_authority.has_value() ) { - bool zero_threshold = std::visit( [](auto&& auth ) -> bool { - return (auth.threshold == 0); - }, *producer_authority ); - // zero_threshold could be true despite the validation done in regproducer2 because the v1.9.0 eosio.system - // contract has a bug which may have modified the producer table such that the producer_authority field - // contains a default constructed eosio::block_signing_authority (which has a 0 threshold and so is invalid). - if( !zero_threshold ) return *producer_authority; - } - return convert_to_block_signing_authority( producer_key ); - } - - // The unregprod and claimrewards actions modify unrelated fields of the producers table and under the default - // serialization behavior they would increase the size of the serialized table if the producer_authority field - // was not already present. This is acceptable (though not necessarily desired) because those two actions require - // the authority of the producer who pays for the table rows. - // However, the rmvproducer action and the onblock transaction would also modify the producer table in a similar - // way and increasing its serialized size is not acceptable in that context. - // So, a custom serialization is defined to handle the binary_extension producer_authority - // field in the desired way. (Note: v1.9.0 did not have this custom serialization behavior.) - - template - friend DataStream& operator << ( DataStream& ds, const producer_info& t ) { - ds << t.owner - << t.total_votes - << t.producer_key - << t.is_active - << t.url - << t.unpaid_blocks - << t.last_claim_time - << t.location; - - if( !t.producer_authority.has_value() ) return ds; - - return ds << t.producer_authority; - } - - template - friend DataStream& operator >> ( DataStream& ds, producer_info& t ) { - return ds >> t.owner - >> t.total_votes - >> t.producer_key - >> t.is_active - >> t.url - >> t.unpaid_blocks - >> t.last_claim_time - >> t.location - >> t.producer_authority; - } - }; - - // Defines new producer info structure to be stored in new producer info table, added after version 1.3.0 - struct [[eosio::table, eosio::contract("eosio.system")]] producer_info2 { - name owner; - double votepay_share = 0; - time_point last_votepay_share_update; - - uint64_t primary_key()const { return owner.value; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) ) - }; - - // Voter info. Voter info stores information about the voter: - // - `owner` the voter - // - `proxy` the proxy set by the voter, if any - // - `producers` the producers approved by this voter if no proxy set - // - `staked` the amount staked - struct [[eosio::table, eosio::contract("eosio.system")]] voter_info { - name owner; /// the voter - name proxy; /// the proxy set by the voter, if any - std::vector producers; /// the producers approved by this voter if no proxy set - int64_t staked = 0; - - // Every time a vote is cast we must first "undo" the last vote weight, before casting the - // new vote weight. Vote weight is calculated as: - // stated.amount * 2 ^ ( weeks_since_launch/weeks_per_year) - double last_vote_weight = 0; /// the vote weight cast the last time the vote was updated - - // Total vote weight delegated to this voter. - double proxied_vote_weight= 0; /// the total vote weight delegated to this voter as a proxy - bool is_proxy = 0; /// whether the voter is a proxy for others - - - uint32_t flags1 = 0; - uint32_t reserved2 = 0; - eosio::asset reserved3; - - uint64_t primary_key()const { return owner.value; } - - enum class flags1_fields : uint32_t { - ram_managed = 1, - net_managed = 2, - cpu_managed = 4 - }; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(flags1)(reserved2)(reserved3) ) - }; - - - typedef eosio::multi_index< "voters"_n, voter_info > voters_table; - - - typedef eosio::multi_index< "producers"_n, producer_info, - indexed_by<"prototalvote"_n, const_mem_fun > - > producers_table; - - typedef eosio::multi_index< "producers2"_n, producer_info2 > producers_table2; - - - typedef eosio::singleton< "global"_n, eosio_global_state > global_state_singleton; - - typedef eosio::singleton< "global2"_n, eosio_global_state2 > global_state2_singleton; - - typedef eosio::singleton< "global3"_n, eosio_global_state3 > global_state3_singleton; - - typedef eosio::singleton< "global4"_n, eosio_global_state4 > global_state4_singleton; - - struct [[eosio::table, eosio::contract("eosio.system")]] user_resources { - name owner; - asset net_weight; - asset cpu_weight; - int64_t ram_bytes = 0; - - bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0 && ram_bytes == 0; } - uint64_t primary_key()const { return owner.value; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( user_resources, (owner)(net_weight)(cpu_weight)(ram_bytes) ) - }; - - // Every user 'from' has a scope/table that uses every receipient 'to' as the primary key. - struct [[eosio::table, eosio::contract("eosio.system")]] delegated_bandwidth { - name from; - name to; - asset net_weight; - asset cpu_weight; - - bool is_empty()const { return net_weight.amount == 0 && cpu_weight.amount == 0; } - uint64_t primary_key()const { return to.value; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( delegated_bandwidth, (from)(to)(net_weight)(cpu_weight) ) - - }; - - struct [[eosio::table, eosio::contract("eosio.system")]] refund_request { - name owner; - time_point_sec request_time; - eosio::asset net_amount; - eosio::asset cpu_amount; - - bool is_empty()const { return net_amount.amount == 0 && cpu_amount.amount == 0; } - uint64_t primary_key()const { return owner.value; } - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( refund_request, (owner)(request_time)(net_amount)(cpu_amount) ) - }; - - - typedef eosio::multi_index< "userres"_n, user_resources > user_resources_table; - typedef eosio::multi_index< "delband"_n, delegated_bandwidth > del_bandwidth_table; - typedef eosio::multi_index< "refunds"_n, refund_request > refunds_table; - - // `rex_pool` structure underlying the rex pool table. A rex pool table entry is defined by: - // - `version` defaulted to zero, - // - `total_lent` total amount of CORE_SYMBOL in open rex_loans - // - `total_unlent` total amount of CORE_SYMBOL available to be lent (connector), - // - `total_rent` fees received in exchange for lent (connector), - // - `total_lendable` total amount of CORE_SYMBOL that have been lent (total_unlent + total_lent), - // - `total_rex` total number of REX shares allocated to contributors to total_lendable, - // - `namebid_proceeds` the amount of CORE_SYMBOL to be transferred from namebids to REX pool, - // - `loan_num` increments with each new loan - struct [[eosio::table,eosio::contract("eosio.system")]] rex_pool { - uint8_t version = 0; - asset total_lent; - asset total_unlent; - asset total_rent; - asset total_lendable; - asset total_rex; - asset namebid_proceeds; - uint64_t loan_num = 0; - - uint64_t primary_key()const { return 0; } - }; - - typedef eosio::multi_index< "rexpool"_n, rex_pool > rex_pool_table; - - // `rex_return_pool` structure underlying the rex return pool table. A rex return pool table entry is defined by: - // - `version` defaulted to zero, - // - `last_dist_time` the last time proceeds from renting, ram fees, and name bids were added to the rex pool, - // - `pending_bucket_time` timestamp of the pending 12-hour return bucket, - // - `oldest_bucket_time` cached timestamp of the oldest 12-hour return bucket, - // - `pending_bucket_proceeds` proceeds in the pending 12-hour return bucket, - // - `current_rate_of_increase` the current rate per dist_interval at which proceeds are added to the rex pool, - // - `proceeds` the maximum amount of proceeds that can be added to the rex pool at any given time - struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_pool { - uint8_t version = 0; - time_point_sec last_dist_time; - time_point_sec pending_bucket_time = time_point_sec::maximum(); - time_point_sec oldest_bucket_time = time_point_sec::min(); - int64_t pending_bucket_proceeds = 0; - int64_t current_rate_of_increase = 0; - int64_t proceeds = 0; - - static constexpr uint32_t total_intervals = 30 * 144; // 30 days - static constexpr uint32_t dist_interval = 10 * 60; // 10 minutes - static constexpr uint8_t hours_per_bucket = 12; - static_assert( total_intervals * dist_interval == 30 * seconds_per_day ); - - uint64_t primary_key()const { return 0; } - }; - - typedef eosio::multi_index< "rexretpool"_n, rex_return_pool > rex_return_pool_table; - - // `rex_return_buckets` structure underlying the rex return buckets table. A rex return buckets table is defined by: - // - `version` defaulted to zero, - // - `return_buckets` buckets of proceeds accumulated in 12-hour intervals - struct [[eosio::table,eosio::contract("eosio.system")]] rex_return_buckets { - uint8_t version = 0; - std::map return_buckets; - - uint64_t primary_key()const { return 0; } - }; - - typedef eosio::multi_index< "retbuckets"_n, rex_return_buckets > rex_return_buckets_table; - - // `rex_fund` structure underlying the rex fund table. A rex fund table entry is defined by: - // - `version` defaulted to zero, - // - `owner` the owner of the rex fund, - // - `balance` the balance of the fund. - struct [[eosio::table,eosio::contract("eosio.system")]] rex_fund { - uint8_t version = 0; - name owner; - asset balance; - - uint64_t primary_key()const { return owner.value; } - }; - - typedef eosio::multi_index< "rexfund"_n, rex_fund > rex_fund_table; - - // `rex_balance` structure underlying the rex balance table. A rex balance table entry is defined by: - // - `version` defaulted to zero, - // - `owner` the owner of the rex fund, - // - `vote_stake` the amount of CORE_SYMBOL currently included in owner's vote, - // - `rex_balance` the amount of REX owned by owner, - // - `matured_rex` matured REX available for selling - struct [[eosio::table,eosio::contract("eosio.system")]] rex_balance { - uint8_t version = 0; - name owner; - asset vote_stake; - asset rex_balance; - int64_t matured_rex = 0; - std::deque> rex_maturities; /// REX daily maturity buckets - - uint64_t primary_key()const { return owner.value; } - }; - - typedef eosio::multi_index< "rexbal"_n, rex_balance > rex_balance_table; - - // `rex_loan` structure underlying the `rex_cpu_loan_table` and `rex_net_loan_table`. A rex net/cpu loan table entry is defined by: - // - `version` defaulted to zero, - // - `from` account creating and paying for loan, - // - `receiver` account receiving rented resources, - // - `payment` SYS tokens paid for the loan, - // - `balance` is the amount of SYS tokens available to be used for loan auto-renewal, - // - `total_staked` total amount staked, - // - `loan_num` loan number/id, - // - `expiration` the expiration time when loan will be either closed or renewed - // If payment <= balance, the loan is renewed, and closed otherwise. - struct [[eosio::table,eosio::contract("eosio.system")]] rex_loan { - uint8_t version = 0; - name from; - name receiver; - asset payment; - asset balance; - asset total_staked; - uint64_t loan_num; - eosio::time_point expiration; - - uint64_t primary_key()const { return loan_num; } - uint64_t by_expr()const { return expiration.elapsed.count(); } - uint64_t by_owner()const { return from.value; } - }; - - typedef eosio::multi_index< "cpuloan"_n, rex_loan, - indexed_by<"byexpr"_n, const_mem_fun>, - indexed_by<"byowner"_n, const_mem_fun> - > rex_cpu_loan_table; - - typedef eosio::multi_index< "netloan"_n, rex_loan, - indexed_by<"byexpr"_n, const_mem_fun>, - indexed_by<"byowner"_n, const_mem_fun> - > rex_net_loan_table; - - struct [[eosio::table,eosio::contract("eosio.system")]] rex_order { - uint8_t version = 0; - name owner; - asset rex_requested; - asset proceeds; - asset stake_change; - eosio::time_point order_time; - bool is_open = true; - - void close() { is_open = false; } - uint64_t primary_key()const { return owner.value; } - uint64_t by_time()const { return is_open ? order_time.elapsed.count() : std::numeric_limits::max(); } - }; - - typedef eosio::multi_index< "rexqueue"_n, rex_order, - indexed_by<"bytime"_n, const_mem_fun>> rex_order_table; - - struct rex_order_outcome { - bool success; - asset proceeds; - asset stake_change; - }; - - struct powerup_config_resource { - std::optional current_weight_ratio; // Immediately set weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. - // Do not specify to preserve the existing setting or use the default; - // this avoids sudden price jumps. For new chains which don't need - // to gradually phase out staking and REX, 0.01x (10^13) is a good - // value for both current_weight_ratio and target_weight_ratio. - std::optional target_weight_ratio; // Linearly shrink weight_ratio to this amount. 1x = 10^15. 0.01x = 10^13. - // Do not specify to preserve the existing setting or use the default. - std::optional assumed_stake_weight; // Assumed stake weight for ratio calculations. Use the sum of total - // staked and total rented by REX at the time the power market - // is first activated. Do not specify to preserve the existing - // setting (no default exists); this avoids sudden price jumps. - // For new chains which don't need to phase out staking and REX, - // 10^12 is probably a good value. - std::optional target_timestamp; // Stop automatic weight_ratio shrinkage at this time. Once this - // time hits, weight_ratio will be target_weight_ratio. Ignored - // if current_weight_ratio == target_weight_ratio. Do not specify - // this to preserve the existing setting (no default exists). - std::optional exponent; // Exponent of resource price curve. Must be >= 1. Do not specify - // to preserve the existing setting or use the default. - std::optional decay_secs; // Number of seconds for the gap between adjusted resource - // utilization and instantaneous resource utilization to shrink - // by 63%. Do not specify to preserve the existing setting or - // use the default. - std::optional min_price; // Fee needed to reserve the entire resource market weight at the - // minimum price. For example, this could be set to 0.005% of - // total token supply. Do not specify to preserve the existing - // setting or use the default. - std::optional max_price; // Fee needed to reserve the entire resource market weight at the - // maximum price. For example, this could be set to 10% of total - // token supply. Do not specify to preserve the existing - // setting (no default exists). - - EOSLIB_SERIALIZE( powerup_config_resource, (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight) - (target_timestamp)(exponent)(decay_secs)(min_price)(max_price) ) - }; - - struct powerup_config { - powerup_config_resource net; // NET market configuration - powerup_config_resource cpu; // CPU market configuration - std::optional powerup_days; // `powerup` `days` argument must match this. Do not specify to preserve the - // existing setting or use the default. - std::optional min_powerup_fee; // Fees below this amount are rejected. Do not specify to preserve the - // existing setting (no default exists). - - EOSLIB_SERIALIZE( powerup_config, (net)(cpu)(powerup_days)(min_powerup_fee) ) - }; - - struct powerup_state_resource { - static constexpr double default_exponent = 2.0; // Exponent of 2.0 means that the price to reserve a - // tiny amount of resources increases linearly - // with utilization. - static constexpr uint32_t default_decay_secs = 1 * seconds_per_day; // 1 day; if 100% of bandwidth resources are in a - // single loan, then, assuming no further powerup usage, - // 1 day after it expires the adjusted utilization - // will be at approximately 37% and after 3 days - // the adjusted utilization will be less than 5%. - - uint8_t version = 0; - int64_t weight = 0; // resource market weight. calculated; varies over time. - // 1 represents the same amount of resources as 1 - // satoshi of SYS staked. - int64_t weight_ratio = 0; // resource market weight ratio: - // assumed_stake_weight / (assumed_stake_weight + weight). - // calculated; varies over time. 1x = 10^15. 0.01x = 10^13. - int64_t assumed_stake_weight = 0; // Assumed stake weight for ratio calculations. - int64_t initial_weight_ratio = powerup_frac; // Initial weight_ratio used for linear shrinkage. - int64_t target_weight_ratio = powerup_frac / 100; // Linearly shrink the weight_ratio to this amount. - time_point_sec initial_timestamp = {}; // When weight_ratio shrinkage started - time_point_sec target_timestamp = {}; // Stop automatic weight_ratio shrinkage at this time. Once this - // time hits, weight_ratio will be target_weight_ratio. - double exponent = default_exponent; // Exponent of resource price curve. - uint32_t decay_secs = default_decay_secs; // Number of seconds for the gap between adjusted resource - // utilization and instantaneous utilization to shrink by 63%. - asset min_price = {}; // Fee needed to reserve the entire resource market weight at - // the minimum price (defaults to 0). - asset max_price = {}; // Fee needed to reserve the entire resource market weight at - // the maximum price. - int64_t utilization = 0; // Instantaneous resource utilization. This is the current - // amount sold. utilization <= weight. - int64_t adjusted_utilization = 0; // Adjusted resource utilization. This is >= utilization and - // <= weight. It grows instantly but decays exponentially. - time_point_sec utilization_timestamp = {}; // When adjusted_utilization was last updated - }; - - struct [[eosio::table("powup.state"),eosio::contract("eosio.system")]] powerup_state { - static constexpr uint32_t default_powerup_days = 30; // 30 day resource powerups - - uint8_t version = 0; - powerup_state_resource net = {}; // NET market state - powerup_state_resource cpu = {}; // CPU market state - uint32_t powerup_days = default_powerup_days; // `powerup` `days` argument must match this. - asset min_powerup_fee = {}; // fees below this amount are rejected - - uint64_t primary_key()const { return 0; } - }; - - typedef eosio::singleton<"powup.state"_n, powerup_state> powerup_state_singleton; - - struct [[eosio::table("powup.order"),eosio::contract("eosio.system")]] powerup_order { - uint8_t version = 0; - uint64_t id; - name owner; - int64_t net_weight; - int64_t cpu_weight; - time_point_sec expires; - - uint64_t primary_key()const { return id; } - uint64_t by_owner()const { return owner.value; } - uint64_t by_expires()const { return expires.utc_seconds; } - }; - - typedef eosio::multi_index< "powup.order"_n, powerup_order, - indexed_by<"byowner"_n, const_mem_fun>, - indexed_by<"byexpires"_n, const_mem_fun> - > powerup_order_table; - - /** - * The `eosio.system` smart contract is provided by `block.one` as a sample system contract, and it defines the structures and actions needed for blockchain's core functionality. - * - * Just like in the `eosio.bios` sample contract implementation, there are a few actions which are not implemented at the contract level (`newaccount`, `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, `canceldelay`, `onerror`, `setabi`, `setcode`), they are just declared in the contract so they will show in the contract's ABI and users will be able to push those actions to the chain via the account holding the `eosio.system` contract, but the implementation is at the EOSIO core level. They are referred to as EOSIO native actions. - * - * - Users can stake tokens for CPU and Network bandwidth, and then vote for producers or - * delegate their vote to a proxy. - * - Producers register in order to be voted for, and can claim per-block and per-vote rewards. - * - Users can buy and sell RAM at a market-determined price. - * - Users can bid on premium names. - * - A resource exchange system (REX) allows token holders to lend their tokens, - * and users to rent CPU and Network resources in return for a market-determined fee. - * - A resource market separate from REX: `power`. - */ - class [[eosio::contract("eosio.system")]] system_contract : public native { - - private: - voters_table _voters; - producers_table _producers; - producers_table2 _producers2; - global_state_singleton _global; - global_state2_singleton _global2; - global_state3_singleton _global3; - global_state4_singleton _global4; - eosio_global_state _gstate; - eosio_global_state2 _gstate2; - eosio_global_state3 _gstate3; - eosio_global_state4 _gstate4; - rammarket _rammarket; - rex_pool_table _rexpool; - rex_return_pool_table _rexretpool; - rex_return_buckets_table _rexretbuckets; - rex_fund_table _rexfunds; - rex_balance_table _rexbalance; - rex_order_table _rexorders; - - public: - static constexpr eosio::name active_permission{"active"_n}; - static constexpr eosio::name token_account{"eosio.token"_n}; - static constexpr eosio::name ram_account{"eosio.ram"_n}; - static constexpr eosio::name ramfee_account{"eosio.ramfee"_n}; - static constexpr eosio::name stake_account{"eosio.stake"_n}; - static constexpr eosio::name bpay_account{"eosio.bpay"_n}; - static constexpr eosio::name vpay_account{"eosio.vpay"_n}; - static constexpr eosio::name names_account{"eosio.names"_n}; - static constexpr eosio::name saving_account{"eosio.saving"_n}; - static constexpr eosio::name rex_account{"eosio.rex"_n}; - static constexpr eosio::name reserv_account{"eosio.reserv"_n}; - static constexpr eosio::name null_account{"eosio.null"_n}; - static constexpr symbol ramcore_symbol = symbol(symbol_code("RAMCORE"), 4); - static constexpr symbol ram_symbol = symbol(symbol_code("RAM"), 0); - static constexpr symbol rex_symbol = symbol(symbol_code("REX"), 4); - - system_contract( name s, name code, datastream ds ); - ~system_contract(); - - // Returns the core symbol by system account name - // @param system_account - the system account to get the core symbol for. - static symbol get_core_symbol( name system_account = "eosio"_n ) { - rammarket rm(system_account, system_account.value); - const static auto sym = get_core_symbol( rm ); - return sym; - } - - // Actions: - /** - * The Init action initializes the system contract for a version and a symbol. - * Only succeeds when: - * - version is 0 and - * - symbol is found and - * - system token supply is greater than 0, - * - and system contract wasn’t already been initialized. - * - * @param version - the version, has to be 0, - * @param core - the system symbol. - */ - [[eosio::action]] - void init( unsigned_int version, const symbol& core ); - - /** - * On block action. This special action is triggered when a block is applied by the given producer - * and cannot be generated from any other source. It is used to pay producers and calculate - * missed blocks of other producers. Producer pay is deposited into the producer's stake - * balance and can be withdrawn over time. If blocknum is the start of a new round this may - * update the active producer config from the producer votes. - * - * @param header - the block header produced. - */ - [[eosio::action]] - void onblock( ignore header ); - - /** - * Set account limits action sets the resource limits of an account - * - * @param account - name of the account whose resource limit to be set, - * @param ram_bytes - ram limit in absolute bytes, - * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts), - * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). - */ - [[eosio::action]] - void setalimits( const name& account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight ); - - /** - * Set account RAM limits action, which sets the RAM limits of an account - * - * @param account - name of the account whose resource limit to be set, - * @param ram_bytes - ram limit in absolute bytes. - */ - [[eosio::action]] - void setacctram( const name& account, const std::optional& ram_bytes ); - - /** - * Set account NET limits action, which sets the NET limits of an account - * - * @param account - name of the account whose resource limit to be set, - * @param net_weight - fractionally proportionate net limit of available resources based on (weight / total_weight_of_all_accounts). - */ - [[eosio::action]] - void setacctnet( const name& account, const std::optional& net_weight ); - - /** - * Set account CPU limits action, which sets the CPU limits of an account - * - * @param account - name of the account whose resource limit to be set, - * @param cpu_weight - fractionally proportionate cpu limit of available resources based on (weight / total_weight_of_all_accounts). - */ - [[eosio::action]] - void setacctcpu( const name& account, const std::optional& cpu_weight ); - - - /** - * The activate action, activates a protocol feature - * - * @param feature_digest - hash of the protocol feature to activate. - */ - [[eosio::action]] - void activate( const eosio::checksum256& feature_digest ); - - // functions defined in delegate_bandwidth.cpp - - /** - * Delegate bandwidth and/or cpu action. Stakes SYS from the balance of `from` for the benefit of `receiver`. - * - * @param from - the account to delegate bandwidth from, that is, the account holding - * tokens to be staked, - * @param receiver - the account to delegate bandwith to, that is, the account to - * whose resources staked tokens are added - * @param stake_net_quantity - tokens staked for NET bandwidth, - * @param stake_cpu_quantity - tokens staked for CPU bandwidth, - * @param transfer - if true, ownership of staked tokens is transfered to `receiver`. - * - * @post All producers `from` account has voted for will have their votes updated immediately. - */ - [[eosio::action]] - void delegatebw( const name& from, const name& receiver, - const asset& stake_net_quantity, const asset& stake_cpu_quantity, bool transfer ); - - /** - * Setrex action, sets total_rent balance of REX pool to the passed value. - * @param balance - amount to set the REX pool balance. - */ - [[eosio::action]] - void setrex( const asset& balance ); - - /** - * Deposit to REX fund action. Deposits core tokens to user REX fund. - * All proceeds and expenses related to REX are added to or taken out of this fund. - * An inline transfer from 'owner' liquid balance is executed. - * All REX-related costs and proceeds are deducted from and added to 'owner' REX fund, - * with one exception being buying REX using staked tokens. - * Storage change is billed to 'owner'. - * - * @param owner - REX fund owner account, - * @param amount - amount of tokens to be deposited. - */ - [[eosio::action]] - void deposit( const name& owner, const asset& amount ); - - /** - * Withdraw from REX fund action, withdraws core tokens from user REX fund. - * An inline token transfer to user balance is executed. - * - * @param owner - REX fund owner account, - * @param amount - amount of tokens to be withdrawn. - */ - [[eosio::action]] - void withdraw( const name& owner, const asset& amount ); - - /** - * Buyrex action, buys REX in exchange for tokens taken out of user's REX fund by transfering - * core tokens from user REX fund and converts them to REX stake. By buying REX, user is - * lending tokens in order to be rented as CPU or NET resourses. - * Storage change is billed to 'from' account. - * - * @param from - owner account name, - * @param amount - amount of tokens taken out of 'from' REX fund. - * - * @pre A voting requirement must be satisfied before action can be executed. - * @pre User must vote for at least 21 producers or delegate vote to proxy before buying REX. - * - * @post User votes are updated following this action. - * @post Tokens used in purchase are added to user's voting power. - * @post Bought REX cannot be sold before 4 days counting from end of day of purchase. - */ - [[eosio::action]] - void buyrex( const name& from, const asset& amount ); - - /** - * Unstaketorex action, uses staked core tokens to buy REX. - * Storage change is billed to 'owner' account. - * - * @param owner - owner of staked tokens, - * @param receiver - account name that tokens have previously been staked to, - * @param from_net - amount of tokens to be unstaked from NET bandwidth and used for REX purchase, - * @param from_cpu - amount of tokens to be unstaked from CPU bandwidth and used for REX purchase. - * - * @pre A voting requirement must be satisfied before action can be executed. - * @pre User must vote for at least 21 producers or delegate vote to proxy before buying REX. - * - * @post User votes are updated following this action. - * @post Tokens used in purchase are added to user's voting power. - * @post Bought REX cannot be sold before 4 days counting from end of day of purchase. - */ - [[eosio::action]] - void unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ); - - /** - * Sellrex action, sells REX in exchange for core tokens by converting REX stake back into core tokens - * at current exchange rate. If order cannot be processed, it gets queued until there is enough - * in REX pool to fill order, and will be processed within 30 days at most. If successful, user - * votes are updated, that is, proceeds are deducted from user's voting power. In case sell order - * is queued, storage change is billed to 'from' account. - * - * @param from - owner account of REX, - * @param rex - amount of REX to be sold. - */ - [[eosio::action]] - void sellrex( const name& from, const asset& rex ); - - /** - * Cnclrexorder action, cancels unfilled REX sell order by owner if one exists. - * - * @param owner - owner account name. - * - * @pre Order cannot be cancelled once it's been filled. - */ - [[eosio::action]] - void cnclrexorder( const name& owner ); - - /** - * Rentcpu action, uses payment to rent as many SYS tokens as possible as determined by market price and - * stake them for CPU for the benefit of receiver, after 30 days the rented core delegation of CPU - * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` - * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user - * is refunded any remaining balance. - * Owner can fund or refund a loan at any time before its expiration. - * All loan expenses and refunds come out of or are added to owner's REX fund. - * - * @param from - account creating and paying for CPU loan, 'from' account can add tokens to loan - * balance using action `fundcpuloan` and withdraw from loan balance using `defcpuloan` - * @param receiver - account receiving rented CPU resources, - * @param loan_payment - tokens paid for the loan, it has to be greater than zero, - * amount of rented resources is calculated from `loan_payment`, - * @param loan_fund - additional tokens can be zero, and is added to loan balance. - * Loan balance represents a reserve that is used at expiration for automatic loan renewal. - */ - [[eosio::action]] - void rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); - - /** - * Rentnet action, uses payment to rent as many SYS tokens as possible as determined by market price and - * stake them for NET for the benefit of receiver, after 30 days the rented core delegation of NET - * will expire. At expiration, if balance is greater than or equal to `loan_payment`, `loan_payment` - * is taken out of loan balance and used to renew the loan. Otherwise, the loan is closed and user - * is refunded any remaining balance. - * Owner can fund or refund a loan at any time before its expiration. - * All loan expenses and refunds come out of or are added to owner's REX fund. - * - * @param from - account creating and paying for NET loan, 'from' account can add tokens to loan - * balance using action `fundnetloan` and withdraw from loan balance using `defnetloan`, - * @param receiver - account receiving rented NET resources, - * @param loan_payment - tokens paid for the loan, it has to be greater than zero, - * amount of rented resources is calculated from `loan_payment`, - * @param loan_fund - additional tokens can be zero, and is added to loan balance. - * Loan balance represents a reserve that is used at expiration for automatic loan renewal. - */ - [[eosio::action]] - void rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); - - /** - * Fundcpuloan action, transfers tokens from REX fund to the fund of a specific CPU loan in order to - * be used for loan renewal at expiry. - * - * @param from - loan creator account, - * @param loan_num - loan id, - * @param payment - tokens transfered from REX fund to loan fund. - */ - [[eosio::action]] - void fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ); - - /** - * Fundnetloan action, transfers tokens from REX fund to the fund of a specific NET loan in order to - * be used for loan renewal at expiry. - * - * @param from - loan creator account, - * @param loan_num - loan id, - * @param payment - tokens transfered from REX fund to loan fund. - */ - [[eosio::action]] - void fundnetloan( const name& from, uint64_t loan_num, const asset& payment ); - - /** - * Defcpuloan action, withdraws tokens from the fund of a specific CPU loan and adds them to REX fund. - * - * @param from - loan creator account, - * @param loan_num - loan id, - * @param amount - tokens transfered from CPU loan fund to REX fund. - */ - [[eosio::action]] - void defcpuloan( const name& from, uint64_t loan_num, const asset& amount ); - - /** - * Defnetloan action, withdraws tokens from the fund of a specific NET loan and adds them to REX fund. - * - * @param from - loan creator account, - * @param loan_num - loan id, - * @param amount - tokens transfered from NET loan fund to REX fund. - */ - [[eosio::action]] - void defnetloan( const name& from, uint64_t loan_num, const asset& amount ); - - /** - * Updaterex action, updates REX owner vote weight to current value of held REX tokens. - * - * @param owner - REX owner account. - */ - [[eosio::action]] - void updaterex( const name& owner ); - - /** - * Rexexec action, processes max CPU loans, max NET loans, and max queued sellrex orders. - * Action does not execute anything related to a specific user. - * - * @param user - any account can execute this action, - * @param max - number of each of CPU loans, NET loans, and sell orders to be processed. - */ - [[eosio::action]] - void rexexec( const name& user, uint16_t max ); - - /** - * Consolidate action, consolidates REX maturity buckets into one bucket that can be sold after 4 days - * starting from the end of the day. - * - * @param owner - REX owner account name. - */ - [[eosio::action]] - void consolidate( const name& owner ); - - /** - * Mvtosavings action, moves a specified amount of REX into savings bucket. REX savings bucket - * never matures. In order for it to be sold, it has to be moved explicitly - * out of that bucket. Then the moved amount will have the regular maturity - * period of 4 days starting from the end of the day. - * - * @param owner - REX owner account name. - * @param rex - amount of REX to be moved. - */ - [[eosio::action]] - void mvtosavings( const name& owner, const asset& rex ); - - /** - * Mvfrsavings action, moves a specified amount of REX out of savings bucket. The moved amount - * will have the regular REX maturity period of 4 days. - * - * @param owner - REX owner account name. - * @param rex - amount of REX to be moved. - */ - [[eosio::action]] - void mvfrsavings( const name& owner, const asset& rex ); - - /** - * Closerex action, deletes owner records from REX tables and frees used RAM. Owner must not have - * an outstanding REX balance. - * - * @param owner - user account name. - * - * @pre If owner has a non-zero REX balance, the action fails; otherwise, - * owner REX balance entry is deleted. - * @pre If owner has no outstanding loans and a zero REX fund balance, - * REX fund entry is deleted. - */ - [[eosio::action]] - void closerex( const name& owner ); - - /** - * Undelegate bandwitdh action, decreases the total tokens delegated by `from` to `receiver` and/or - * frees the memory associated with the delegation if there is nothing - * left to delegate. - * This will cause an immediate reduction in net/cpu bandwidth of the - * receiver. - * A transaction is scheduled to send the tokens back to `from` after - * the staking period has passed. If existing transaction is scheduled, it - * will be canceled and a new transaction issued that has the combined - * undelegated amount. - * The `from` account loses voting power as a result of this call and - * all producer tallies are updated. - * - * @param from - the account to undelegate bandwidth from, that is, - * the account whose tokens will be unstaked, - * @param receiver - the account to undelegate bandwith to, that is, - * the account to whose benefit tokens have been staked, - * @param unstake_net_quantity - tokens to be unstaked from NET bandwidth, - * @param unstake_cpu_quantity - tokens to be unstaked from CPU bandwidth, - * - * @post Unstaked tokens are transferred to `from` liquid balance via a - * deferred transaction with a delay of 3 days. - * @post If called during the delay period of a previous `undelegatebw` - * action, pending action is canceled and timer is reset. - * @post All producers `from` account has voted for will have their votes updated immediately. - * @post Bandwidth and storage for the deferred transaction are billed to `from`. - */ - [[eosio::action]] - void undelegatebw( const name& from, const name& receiver, - const asset& unstake_net_quantity, const asset& unstake_cpu_quantity ); - - /** - * Buy ram action, increases receiver's ram quota based upon current price and quantity of - * tokens provided. An inline transfer from receiver to system contract of - * tokens will be executed. - * - * @param payer - the ram buyer, - * @param receiver - the ram receiver, - * @param quant - the quntity of tokens to buy ram with. - */ - [[eosio::action]] - void buyram( const name& payer, const name& receiver, const asset& quant ); - - /** - * Buy a specific amount of ram bytes action. Increases receiver's ram in quantity of bytes provided. - * An inline transfer from receiver to system contract of tokens will be executed. - * - * @param payer - the ram buyer, - * @param receiver - the ram receiver, - * @param bytes - the quntity of ram to buy specified in bytes. - */ - [[eosio::action]] - void buyrambytes( const name& payer, const name& receiver, uint32_t bytes ); - - /** - * Sell ram action, reduces quota by bytes and then performs an inline transfer of tokens - * to receiver based upon the average purchase price of the original quota. - * - * @param account - the ram seller account, - * @param bytes - the amount of ram to sell in bytes. - */ - [[eosio::action]] - void sellram( const name& account, int64_t bytes ); - - /** - * Refund action, this action is called after the delegation-period to claim all pending - * unstaked tokens belonging to owner. - * - * @param owner - the owner of the tokens claimed. - */ - [[eosio::action]] - void refund( const name& owner ); - - // functions defined in voting.cpp - - /** - * Register producer action, indicates that a particular account wishes to become a producer, - * this action will create a `producer_config` and a `producer_info` object for `producer` scope - * in producers tables. - * - * @param producer - account registering to be a producer candidate, - * @param producer_key - the public key of the block producer, this is the key used by block producer to sign blocks, - * @param url - the url of the block producer, normally the url of the block producer presentation website, - * @param location - is the country code as defined in the ISO 3166, https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes - * - * @pre Producer to register is an account - * @pre Authority of producer to register - */ - [[eosio::action]] - void regproducer( const name& producer, const public_key& producer_key, const std::string& url, uint16_t location ); - - /** - * Register producer action, indicates that a particular account wishes to become a producer, - * this action will create a `producer_config` and a `producer_info` object for `producer` scope - * in producers tables. - * - * @param producer - account registering to be a producer candidate, - * @param producer_authority - the weighted threshold multisig block signing authority of the block producer used to sign blocks, - * @param url - the url of the block producer, normally the url of the block producer presentation website, - * @param location - is the country code as defined in the ISO 3166, https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes - * - * @pre Producer to register is an account - * @pre Authority of producer to register - */ - [[eosio::action]] - void regproducer2( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ); - - /** - * Unregister producer action, deactivates the block producer with account name `producer`. - * - * Deactivate the block producer with account name `producer`. - * @param producer - the block producer account to unregister. - */ - [[eosio::action]] - void unregprod( const name& producer ); - - /** - * Set ram action sets the ram supply. - * @param max_ram_size - the amount of ram supply to set. - */ - [[eosio::action]] - void setram( uint64_t max_ram_size ); - - /** - * Set ram rate action, sets the rate of increase of RAM in bytes per block. It is capped by the uint16_t to - * a maximum rate of 3 TB per year. If update_ram_supply hasn't been called for the most recent block, - * then new ram will be allocated at the old rate up to the present block before switching the rate. - * - * @param bytes_per_block - the amount of bytes per block increase to set. - */ - [[eosio::action]] - void setramrate( uint16_t bytes_per_block ); - - /** - * Vote producer action, votes for a set of producers. This action updates the list of `producers` voted for, - * for `voter` account. If voting for a `proxy`, the producer votes will not change until the - * proxy updates their own vote. Voter can vote for a proxy __or__ a list of at most 30 producers. - * Storage change is billed to `voter`. - * - * @param voter - the account to change the voted producers for, - * @param proxy - the proxy to change the voted producers for, - * @param producers - the list of producers to vote for, a maximum of 30 producers is allowed. - * - * @pre Producers must be sorted from lowest to highest and must be registered and active - * @pre If proxy is set then no producers can be voted for - * @pre If proxy is set then proxy account must exist and be registered as a proxy - * @pre Every listed producer or proxy must have been previously registered - * @pre Voter must authorize this action - * @pre Voter must have previously staked some EOS for voting - * @pre Voter->staked must be up to date - * - * @post Every producer previously voted for will have vote reduced by previous vote weight - * @post Every producer newly voted for will have vote increased by new vote amount - * @post Prior proxy will proxied_vote_weight decremented by previous vote weight - * @post New proxy will proxied_vote_weight incremented by new vote weight - */ - [[eosio::action]] - void voteproducer( const name& voter, const name& proxy, const std::vector& producers ); - - /** - * Register proxy action, sets `proxy` account as proxy. - * An account marked as a proxy can vote with the weight of other accounts which - * have selected it as a proxy. Other accounts must refresh their voteproducer to - * update the proxy's weight. - * Storage change is billed to `proxy`. - * - * @param rpoxy - the account registering as voter proxy (or unregistering), - * @param isproxy - if true, proxy is registered; if false, proxy is unregistered. - * - * @pre Proxy must have something staked (existing row in voters table) - * @pre New state must be different than current state - */ - [[eosio::action]] - void regproxy( const name& proxy, bool isproxy ); - - /** - * Set the blockchain parameters. By tunning these parameters a degree of - * customization can be achieved. - * @param params - New blockchain parameters to set. - */ - [[eosio::action]] - void setparams( const eosio::blockchain_parameters& params ); - - /** - * Claim rewards action, claims block producing and vote rewards. - * @param owner - producer account claiming per-block and per-vote rewards. - */ - [[eosio::action]] - void claimrewards( const name& owner ); - - /** - * Set privilege status for an account. Allows to set privilege status for an account (turn it on/off). - * @param account - the account to set the privileged status for. - * @param is_priv - 0 for false, > 0 for true. - */ - [[eosio::action]] - void setpriv( const name& account, uint8_t is_priv ); - - /** - * Remove producer action, deactivates a producer by name, if not found asserts. - * @param producer - the producer account to deactivate. - */ - [[eosio::action]] - void rmvproducer( const name& producer ); - - /** - * Update revision action, updates the current revision. - * @param revision - it has to be incremented by 1 compared with current revision. - * - * @pre Current revision can not be higher than 254, and has to be smaller - * than or equal 1 (“set upper bound to greatest revision supported in the code”). - */ - [[eosio::action]] - void updtrevision( uint8_t revision ); - - /** - * Bid name action, allows an account `bidder` to place a bid for a name `newname`. - * @param bidder - the account placing the bid, - * @param newname - the name the bid is placed for, - * @param bid - the amount of system tokens payed for the bid. - * - * @pre Bids can be placed only on top-level suffix, - * @pre Non empty name, - * @pre Names longer than 12 chars are not allowed, - * @pre Names equal with 12 chars can be created without placing a bid, - * @pre Bid has to be bigger than zero, - * @pre Bid's symbol must be system token, - * @pre Bidder account has to be different than current highest bidder, - * @pre Bid must increase current bid by 10%, - * @pre Auction must still be opened. - */ - [[eosio::action]] - void bidname( const name& bidder, const name& newname, const asset& bid ); - - /** - * Bid refund action, allows the account `bidder` to get back the amount it bid so far on a `newname` name. - * - * @param bidder - the account that gets refunded, - * @param newname - the name for which the bid was placed and now it gets refunded for. - */ - [[eosio::action]] - void bidrefund( const name& bidder, const name& newname ); - - /** - * Change the annual inflation rate of the core token supply and specify how - * the new issued tokens will be distributed based on the following structure. - * - * @param annual_rate - Annual inflation rate of the core token supply. - * (eg. For 5% Annual inflation => annual_rate=500 - * For 1.5% Annual inflation => annual_rate=150 - * @param inflation_pay_factor - Inverse of the fraction of the inflation used to reward block producers. - * The remaining inflation will be sent to the `eosio.saving` account. - * (eg. For 20% of inflation going to block producer rewards => inflation_pay_factor = 50000 - * For 100% of inflation going to block producer rewards => inflation_pay_factor = 10000). - * @param votepay_factor - Inverse of the fraction of the block producer rewards to be distributed proportional to blocks produced. - * The remaining rewards will be distributed proportional to votes received. - * (eg. For 25% of block producer rewards going towards block pay => votepay_factor = 40000 - * For 75% of block producer rewards going towards block pay => votepay_factor = 13333). - */ - [[eosio::action]] - void setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ); - - /** - * Configure the `power` market. The market becomes available the first time this - * action is invoked. - */ - [[eosio::action]] - void cfgpowerup( powerup_config& args ); - - /** - * Process power queue and update state. Action does not execute anything related to a specific user. - * - * @param user - any account can execute this action - * @param max - number of queue items to process - */ - [[eosio::action]] - void powerupexec( const name& user, uint16_t max ); - - /** - * Powerup NET and CPU resources by percentage - * - * @param payer - the resource buyer - * @param receiver - the resource receiver - * @param days - number of days of resource availability. Must match market configuration. - * @param net_frac - fraction of net (100% = 10^15) managed by this market - * @param cpu_frac - fraction of cpu (100% = 10^15) managed by this market - * @param max_payment - the maximum amount `payer` is willing to pay. Tokens are withdrawn from - * `payer`'s token balance. - */ - [[eosio::action]] - void powerup( const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, const asset& max_payment ); - - using init_action = eosio::action_wrapper<"init"_n, &system_contract::init>; - using setacctram_action = eosio::action_wrapper<"setacctram"_n, &system_contract::setacctram>; - using setacctnet_action = eosio::action_wrapper<"setacctnet"_n, &system_contract::setacctnet>; - using setacctcpu_action = eosio::action_wrapper<"setacctcpu"_n, &system_contract::setacctcpu>; - using activate_action = eosio::action_wrapper<"activate"_n, &system_contract::activate>; - using delegatebw_action = eosio::action_wrapper<"delegatebw"_n, &system_contract::delegatebw>; - using deposit_action = eosio::action_wrapper<"deposit"_n, &system_contract::deposit>; - using withdraw_action = eosio::action_wrapper<"withdraw"_n, &system_contract::withdraw>; - using buyrex_action = eosio::action_wrapper<"buyrex"_n, &system_contract::buyrex>; - using unstaketorex_action = eosio::action_wrapper<"unstaketorex"_n, &system_contract::unstaketorex>; - using sellrex_action = eosio::action_wrapper<"sellrex"_n, &system_contract::sellrex>; - using cnclrexorder_action = eosio::action_wrapper<"cnclrexorder"_n, &system_contract::cnclrexorder>; - using rentcpu_action = eosio::action_wrapper<"rentcpu"_n, &system_contract::rentcpu>; - using rentnet_action = eosio::action_wrapper<"rentnet"_n, &system_contract::rentnet>; - using fundcpuloan_action = eosio::action_wrapper<"fundcpuloan"_n, &system_contract::fundcpuloan>; - using fundnetloan_action = eosio::action_wrapper<"fundnetloan"_n, &system_contract::fundnetloan>; - using defcpuloan_action = eosio::action_wrapper<"defcpuloan"_n, &system_contract::defcpuloan>; - using defnetloan_action = eosio::action_wrapper<"defnetloan"_n, &system_contract::defnetloan>; - using updaterex_action = eosio::action_wrapper<"updaterex"_n, &system_contract::updaterex>; - using rexexec_action = eosio::action_wrapper<"rexexec"_n, &system_contract::rexexec>; - using setrex_action = eosio::action_wrapper<"setrex"_n, &system_contract::setrex>; - using mvtosavings_action = eosio::action_wrapper<"mvtosavings"_n, &system_contract::mvtosavings>; - using mvfrsavings_action = eosio::action_wrapper<"mvfrsavings"_n, &system_contract::mvfrsavings>; - using consolidate_action = eosio::action_wrapper<"consolidate"_n, &system_contract::consolidate>; - using closerex_action = eosio::action_wrapper<"closerex"_n, &system_contract::closerex>; - using undelegatebw_action = eosio::action_wrapper<"undelegatebw"_n, &system_contract::undelegatebw>; - using buyram_action = eosio::action_wrapper<"buyram"_n, &system_contract::buyram>; - using buyrambytes_action = eosio::action_wrapper<"buyrambytes"_n, &system_contract::buyrambytes>; - using sellram_action = eosio::action_wrapper<"sellram"_n, &system_contract::sellram>; - using refund_action = eosio::action_wrapper<"refund"_n, &system_contract::refund>; - using regproducer_action = eosio::action_wrapper<"regproducer"_n, &system_contract::regproducer>; - using regproducer2_action = eosio::action_wrapper<"regproducer2"_n, &system_contract::regproducer2>; - using unregprod_action = eosio::action_wrapper<"unregprod"_n, &system_contract::unregprod>; - using setram_action = eosio::action_wrapper<"setram"_n, &system_contract::setram>; - using setramrate_action = eosio::action_wrapper<"setramrate"_n, &system_contract::setramrate>; - using voteproducer_action = eosio::action_wrapper<"voteproducer"_n, &system_contract::voteproducer>; - using regproxy_action = eosio::action_wrapper<"regproxy"_n, &system_contract::regproxy>; - using claimrewards_action = eosio::action_wrapper<"claimrewards"_n, &system_contract::claimrewards>; - using rmvproducer_action = eosio::action_wrapper<"rmvproducer"_n, &system_contract::rmvproducer>; - using updtrevision_action = eosio::action_wrapper<"updtrevision"_n, &system_contract::updtrevision>; - using bidname_action = eosio::action_wrapper<"bidname"_n, &system_contract::bidname>; - using bidrefund_action = eosio::action_wrapper<"bidrefund"_n, &system_contract::bidrefund>; - using setpriv_action = eosio::action_wrapper<"setpriv"_n, &system_contract::setpriv>; - using setalimits_action = eosio::action_wrapper<"setalimits"_n, &system_contract::setalimits>; - using setparams_action = eosio::action_wrapper<"setparams"_n, &system_contract::setparams>; - using setinflation_action = eosio::action_wrapper<"setinflation"_n, &system_contract::setinflation>; - using cfgpowerup_action = eosio::action_wrapper<"cfgpowerup"_n, &system_contract::cfgpowerup>; - using powerupexec_action = eosio::action_wrapper<"powerupexec"_n, &system_contract::powerupexec>; - using powerup_action = eosio::action_wrapper<"powerup"_n, &system_contract::powerup>; - - private: - // Implementation details: - - static symbol get_core_symbol( const rammarket& rm ) { - auto itr = rm.find(ramcore_symbol.raw()); - check(itr != rm.end(), "system contract must first be initialized"); - return itr->quote.balance.symbol; - } - - //defined in eosio.system.cpp - static eosio_global_state get_default_parameters(); - static eosio_global_state4 get_default_inflation_parameters(); - symbol core_symbol()const; - void update_ram_supply(); - - // defined in rex.cpp - void runrex( uint16_t max ); - void update_rex_pool(); - void update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ); - void check_voting_requirement( const name& owner, - const char* error_msg = "must vote for at least 21 producers or for a proxy before buying REX" )const; - rex_order_outcome fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ); - asset update_rex_account( const name& owner, const asset& proceeds, const asset& unstake_quant, bool force_vote_update = false ); - void channel_to_rex( const name& from, const asset& amount, bool required = false ); - void channel_namebid_to_rex( const int64_t highest_bid ); - template - int64_t rent_rex( T& table, const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ); - template - void fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ); - template - void defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ); - void transfer_from_fund( const name& owner, const asset& amount ); - void transfer_to_fund( const name& owner, const asset& amount ); - bool rex_loans_available()const; - bool rex_system_initialized()const { return _rexpool.begin() != _rexpool.end(); } - bool rex_available()const { return rex_system_initialized() && _rexpool.begin()->total_rex.amount > 0; } - static time_point_sec get_rex_maturity(); - asset add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ); - asset add_to_rex_pool( const asset& payment ); - void add_to_rex_return_pool( const asset& fee ); - void process_rex_maturities( const rex_balance_table::const_iterator& bitr ); - void consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, - const asset& rex_in_sell_order ); - int64_t read_rex_savings( const rex_balance_table::const_iterator& bitr ); - void put_rex_savings( const rex_balance_table::const_iterator& bitr, int64_t rex ); - void update_rex_stake( const name& voter ); - - void add_loan_to_rex_pool( const asset& payment, int64_t rented_tokens, bool new_loan ); - void remove_loan_from_rex_pool( const rex_loan& loan ); - template - int64_t update_renewed_loan( Index& idx, const Iterator& itr, int64_t rented_tokens ); - - // defined in delegate_bandwidth.cpp - void changebw( name from, const name& receiver, - const asset& stake_net_quantity, const asset& stake_cpu_quantity, bool transfer ); - void update_voting_power( const name& voter, const asset& total_update ); - - // defined in voting.cpp - void register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ); - void update_elected_producers( const block_timestamp& timestamp ); - void update_votes( const name& voter, const name& proxy, const std::vector& producers, bool voting ); - void propagate_weight_change( const voter_info& voter ); - double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, - const time_point& ct, - double shares_rate, bool reset_to_zero = false ); - double update_total_votepay_share( const time_point& ct, - double additional_shares_delta = 0.0, double shares_rate_delta = 0.0 ); - - template - class registration { - public: - template - struct for_each { - template - static constexpr void call( system_contract* this_contract, Args&&... args ) - { - std::invoke( P, this_contract, args... ); - for_each::call( this_contract, std::forward(args)... ); - } - }; - template - struct for_each

{ - template - static constexpr void call( system_contract* this_contract, Args&&... args ) - { - std::invoke( P, this_contract, std::forward(args)... ); - } - }; - - template - constexpr void operator() ( Args&&... args ) - { - for_each::call( this_contract, std::forward(args)... ); - } - - system_contract* this_contract; - }; - - registration<&system_contract::update_rex_stake> vote_stake_updater{ this }; - - // defined in power.cpp - void adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, int64_t cpu_delta, bool must_not_be_managed = false); - void process_powerup_queue( - time_point_sec now, symbol core_symbol, powerup_state& state, - powerup_order_table& orders, uint32_t max_items, int64_t& net_delta_available, - int64_t& cpu_delta_available); - }; - -} diff --git a/contracts/eosio.system/include/eosio.system/exchange_state.hpp b/contracts/eosio.system/include/eosio.system/exchange_state.hpp deleted file mode 100644 index c339b970..00000000 --- a/contracts/eosio.system/include/eosio.system/exchange_state.hpp +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include - -namespace eosiosystem { - - using eosio::asset; - using eosio::symbol; - - /** - * Uses Bancor math to create a 50/50 relay between two asset types. - * - * The state of the bancor exchange is entirely contained within this struct. - * There are no external side effects associated with using this API. - */ - struct [[eosio::table, eosio::contract("eosio.system")]] exchange_state { - asset supply; - - struct connector { - asset balance; - double weight = .5; - - EOSLIB_SERIALIZE( connector, (balance)(weight) ) - }; - - connector base; - connector quote; - - uint64_t primary_key()const { return supply.symbol.raw(); } - - asset convert_to_exchange( connector& reserve, const asset& payment ); - asset convert_from_exchange( connector& reserve, const asset& tokens ); - asset convert( const asset& from, const symbol& to ); - asset direct_convert( const asset& from, const symbol& to ); - - static int64_t get_bancor_output( int64_t inp_reserve, - int64_t out_reserve, - int64_t inp ); - static int64_t get_bancor_input( int64_t out_reserve, - int64_t inp_reserve, - int64_t out ); - - EOSLIB_SERIALIZE( exchange_state, (supply)(base)(quote) ) - }; - - typedef eosio::multi_index< "rammarket"_n, exchange_state > rammarket; -} /// namespace eosiosystem diff --git a/contracts/eosio.system/include/eosio.system/native.hpp b/contracts/eosio.system/include/eosio.system/native.hpp deleted file mode 100644 index a0931cde..00000000 --- a/contracts/eosio.system/include/eosio.system/native.hpp +++ /dev/null @@ -1,260 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -namespace eosiosystem { - - using eosio::checksum256; - using eosio::ignore; - using eosio::name; - using eosio::permission_level; - using eosio::public_key; - - /** - * A weighted permission. - * - * Defines a weighted permission, that is a permission which has a weight associated. - * A permission is defined by an account name plus a permission name. - */ - struct permission_level_weight { - permission_level permission; - uint16_t weight; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( permission_level_weight, (permission)(weight) ) - }; - - /** - * Weighted key. - * - * A weighted key is defined by a public key and an associated weight. - */ - struct key_weight { - eosio::public_key key; - uint16_t weight; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( key_weight, (key)(weight) ) - }; - - /** - * Wait weight. - * - * A wait weight is defined by a number of seconds to wait for and a weight. - */ - struct wait_weight { - uint32_t wait_sec; - uint16_t weight; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( wait_weight, (wait_sec)(weight) ) - }; - - /** - * Blockchain authority. - * - * An authority is defined by: - * - a vector of key_weights (a key_weight is a public key plus a wieght), - * - a vector of permission_level_weights, (a permission_level is an account name plus a permission name) - * - a vector of wait_weights (a wait_weight is defined by a number of seconds to wait and a weight) - * - a threshold value - */ - struct authority { - uint32_t threshold = 0; - std::vector keys; - std::vector accounts; - std::vector waits; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE( authority, (threshold)(keys)(accounts)(waits) ) - }; - - /** - * Blockchain block header. - * - * A block header is defined by: - * - a timestamp, - * - the producer that created it, - * - a confirmed flag default as zero, - * - a link to previous block, - * - a link to the transaction merkel root, - * - a link to action root, - * - a schedule version, - * - and a producers' schedule. - */ - struct block_header { - uint32_t timestamp; - name producer; - uint16_t confirmed = 0; - checksum256 previous; - checksum256 transaction_mroot; - checksum256 action_mroot; - uint32_t schedule_version = 0; - std::optional new_producers; - - // explicit serialization macro is not necessary, used here only to improve compilation time - EOSLIB_SERIALIZE(block_header, (timestamp)(producer)(confirmed)(previous)(transaction_mroot)(action_mroot) - (schedule_version)(new_producers)) - }; - - /** - * abi_hash is the structure underlying the abihash table and consists of: - * - `owner`: the account owner of the contract's abi - * - `hash`: is the sha256 hash of the abi/binary - */ - struct [[eosio::table("abihash"), eosio::contract("eosio.system")]] abi_hash { - name owner; - checksum256 hash; - uint64_t primary_key()const { return owner.value; } - - EOSLIB_SERIALIZE( abi_hash, (owner)(hash) ) - }; - - // Method parameters commented out to prevent generation of code that parses input data. - /** - * The EOSIO core `native` contract that governs authorization and contracts' abi. - */ - class [[eosio::contract("eosio.system")]] native : public eosio::contract { - public: - - using eosio::contract::contract; - - /** - * These actions map one-on-one with the ones defined in core layer of EOSIO, that's where their implementation - * actually is done. - * They are present here only so they can show up in the abi file and thus user can send them - * to this contract, but they have no specific implementation at this contract level, - * they will execute the implementation at the core layer and nothing else. - */ - /** - * New account action is called after a new account is created. This code enforces resource-limits rules - * for new accounts as well as new account naming conventions. - * - * 1. accounts cannot contain '.' symbols which forces all acccounts to be 12 - * characters long without '.' until a future account auction process is implemented - * which prevents name squatting. - * - * 2. new accounts must stake a minimal number of tokens (as set in system parameters) - * therefore, this method will execute an inline buyram from receiver for newacnt in - * an amount equal to the current new account creation fee. - */ - [[eosio::action]] - void newaccount( const name& creator, - const name& name, - ignore owner, - ignore active); - - /** - * Update authorization action updates pemission for an account. - * - * @param account - the account for which the permission is updated - * @param pemission - the permission name which is updated - * @param parem - the parent of the permission which is updated - * @param aut - the json describing the permission authorization - */ - [[eosio::action]] - void updateauth( ignore account, - ignore permission, - ignore parent, - ignore auth ) {} - - /** - * Delete authorization action deletes the authorization for an account's permission. - * - * @param account - the account for which the permission authorization is deleted, - * @param permission - the permission name been deleted. - */ - [[eosio::action]] - void deleteauth( ignore account, - ignore permission ) {} - - /** - * Link authorization action assigns a specific action from a contract to a permission you have created. Five system - * actions can not be linked `updateauth`, `deleteauth`, `linkauth`, `unlinkauth`, and `canceldelay`. - * This is useful because when doing authorization checks, the EOSIO based blockchain starts with the - * action needed to be authorized (and the contract belonging to), and looks up which permission - * is needed to pass authorization validation. If a link is set, that permission is used for authoraization - * validation otherwise then active is the default, with the exception of `eosio.any`. - * `eosio.any` is an implicit permission which exists on every account; you can link actions to `eosio.any` - * and that will make it so linked actions are accessible to any permissions defined for the account. - * - * @param account - the permission's owner to be linked and the payer of the RAM needed to store this link, - * @param code - the owner of the action to be linked, - * @param type - the action to be linked, - * @param requirement - the permission to be linked. - */ - [[eosio::action]] - void linkauth( ignore account, - ignore code, - ignore type, - ignore requirement ) {} - - /** - * Unlink authorization action it's doing the reverse of linkauth action, by unlinking the given action. - * - * @param account - the owner of the permission to be unlinked and the receiver of the freed RAM, - * @param code - the owner of the action to be unlinked, - * @param type - the action to be unlinked. - */ - [[eosio::action]] - void unlinkauth( ignore account, - ignore code, - ignore type ) {} - - /** - * Cancel delay action cancels a deferred transaction. - * - * @param canceling_auth - the permission that authorizes this action, - * @param trx_id - the deferred transaction id to be cancelled. - */ - [[eosio::action]] - void canceldelay( ignore canceling_auth, ignore trx_id ) {} - - /** - * On error action, notification of this action is delivered to the sender of a deferred transaction - * when an objective error occurs while executing the deferred transaction. - * This action is not meant to be called directly. - * - * @param sender_id - the id for the deferred transaction chosen by the sender, - * @param sent_trx - the deferred transaction that failed. - */ - [[eosio::action]] - void onerror( ignore sender_id, ignore> sent_trx ); - - /** - * Set abi action sets the contract abi for an account. - * - * @param account - the account for which to set the contract abi. - * @param abi - the abi content to be set, in the form of a blob binary. - */ - [[eosio::action]] - void setabi( const name& account, const std::vector& abi ); - - /** - * Set code action sets the contract code for an account. - * - * @param account - the account for which to set the contract code. - * @param vmtype - reserved, set it to zero. - * @param vmversion - reserved, set it to zero. - * @param code - the code content to be set, in the form of a blob binary.. - */ - [[eosio::action]] - void setcode( const name& account, uint8_t vmtype, uint8_t vmversion, const std::vector& code ) {} - - using newaccount_action = eosio::action_wrapper<"newaccount"_n, &native::newaccount>; - using updateauth_action = eosio::action_wrapper<"updateauth"_n, &native::updateauth>; - using deleteauth_action = eosio::action_wrapper<"deleteauth"_n, &native::deleteauth>; - using linkauth_action = eosio::action_wrapper<"linkauth"_n, &native::linkauth>; - using unlinkauth_action = eosio::action_wrapper<"unlinkauth"_n, &native::unlinkauth>; - using canceldelay_action = eosio::action_wrapper<"canceldelay"_n, &native::canceldelay>; - using setcode_action = eosio::action_wrapper<"setcode"_n, &native::setcode>; - using setabi_action = eosio::action_wrapper<"setabi"_n, &native::setabi>; - }; -} diff --git a/contracts/eosio.system/include/eosio.system/powerup.results.hpp b/contracts/eosio.system/include/eosio.system/powerup.results.hpp deleted file mode 100644 index 716be93a..00000000 --- a/contracts/eosio.system/include/eosio.system/powerup.results.hpp +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once - -#include -#include -#include - -using eosio::action_wrapper; -using eosio::asset; -using eosio::name; - -/** - * The action `powerresult` of `power.results` is a no-op. - * It is added as an inline convenience action to `powerup` reservation. - * This inline convenience action does not have any effect, however, - * its data includes the result of the parent action and appears in its trace. - */ -class [[eosio::contract("powup.results")]] powup_results : eosio::contract { - public: - - using eosio::contract::contract; - - /** - * powupresult action. - * - * @param fee - powerup fee amount - * @param powup_net - amount of powup NET tokens - * @param powup_cpu - amount of powup CPU tokens - */ - [[eosio::action]] - void powupresult( const asset& fee, const int64_t powup_net, const int64_t powup_cpu ); - - using powupresult_action = action_wrapper<"powupresult"_n, &powup_results::powupresult>; -}; diff --git a/contracts/eosio.system/include/eosio.system/rex.results.hpp b/contracts/eosio.system/include/eosio.system/rex.results.hpp deleted file mode 100644 index 378d6add..00000000 --- a/contracts/eosio.system/include/eosio.system/rex.results.hpp +++ /dev/null @@ -1,59 +0,0 @@ -#pragma once - -#include -#include -#include - -using eosio::action_wrapper; -using eosio::asset; -using eosio::name; - -/** - * The actions `buyresult`, `sellresult`, `rentresult`, and `orderresult` of `rex.results` are all no-ops. - * They are added as inline convenience actions to `rentnet`, `rentcpu`, `buyrex`, `unstaketorex`, and `sellrex`. - * An inline convenience action does not have any effect, however, - * its data includes the result of the parent action and appears in its trace. - */ -class [[eosio::contract("rex.results")]] rex_results : eosio::contract { - public: - - using eosio::contract::contract; - - /** - * Buyresult action. - * - * @param rex_received - amount of tokens used in buy order - */ - [[eosio::action]] - void buyresult( const asset& rex_received ); - - /** - * Sellresult action. - * - * @param proceeds - amount of tokens used in sell order - */ - [[eosio::action]] - void sellresult( const asset& proceeds ); - - /** - * Orderresult action. - * - * @param owner - the owner of the order - * @param proceeds - amount of tokens used in order - */ - [[eosio::action]] - void orderresult( const name& owner, const asset& proceeds ); - - /** - * Rentresult action. - * - * @param rented_tokens - amount of rented tokens - */ - [[eosio::action]] - void rentresult( const asset& rented_tokens ); - - using buyresult_action = action_wrapper<"buyresult"_n, &rex_results::buyresult>; - using sellresult_action = action_wrapper<"sellresult"_n, &rex_results::sellresult>; - using orderresult_action = action_wrapper<"orderresult"_n, &rex_results::orderresult>; - using rentresult_action = action_wrapper<"rentresult"_n, &rex_results::rentresult>; -}; diff --git a/contracts/eosio.system/ricardian/eosio.system.clauses.md b/contracts/eosio.system/ricardian/eosio.system.clauses.md deleted file mode 100644 index ef5bfc98..00000000 --- a/contracts/eosio.system/ricardian/eosio.system.clauses.md +++ /dev/null @@ -1,63 +0,0 @@ -

UserAgreement

- -User agreement for the chain can go here. - -

BlockProducerAgreement

- -I, {{producer}}, hereby nominate myself for consideration as an elected block producer. - -If {{producer}} is selected to produce blocks by the system contract, I will sign blocks with my registered block signing keys and I hereby attest that I will keep these keys secret and secure. - -If {{producer}} is unable to perform obligations under this contract I will resign my position using the unregprod action. - -I acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules. - -{{producer}} hereby agrees to only use my registered block signing keys to sign messages under the following scenarios: - -* proposing an objectively valid block at the time appointed by the block scheduling algorithm; -* pre-confirming a block produced by another producer in the schedule when I find said block objectively valid; -* and, confirming a block for which {{producer}} has received pre-confirmation messages from more than two-thirds of the active block producers. - -I hereby accept liability for any and all provable damages that result from my: - -* signing two different block proposals with the same timestamp; -* signing two different block proposals with the same block number; -* signing any block proposal which builds off of an objectively invalid block; -* signing a pre-confirmation for an objectively invalid block; -* or, signing a confirmation for a block for which I do not possess pre-confirmation messages from more than two-thirds of the active block producers. - -I hereby agree that double-signing for a timestamp or block number in concert with two or more other block producers shall automatically be deemed malicious and cause {{producer}} to be subject to: - -* a fine equal to the past year of compensation received, -* immediate disqualification from being a producer, -* and/or other damages. - -An exception may be made if {{producer}} can demonstrate that the double-signing occurred due to a bug in the reference software; the burden of proof is on {{producer}}. - -I hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract. - -I hereby acknowledge that more than two-thirds of the active block producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among block producers. - -If {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least one validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among block producers, said method and reports to be made public. - -The community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers. - -I agree to process transactions on a FIFO (first in, first out) best-effort basis and to honestly bill transactions for measured execution time. - -I {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: the order in which transactions are included, or the hash of the block that is produced. - -I, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my business entity who own more than 10% and all direct shareholders. - -I, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain. - -I, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract. - -I, {{producer}}, agree to set the location value of {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer. - -I, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among block producers. - -I, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior block producer. - -I, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either NET or CPU bandwidth metrics. - -I, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by more than two-thirds of active block producers, as shown in the system parameters. diff --git a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in b/contracts/eosio.system/ricardian/eosio.system.contracts.md.in deleted file mode 100644 index 9ab33cd8..00000000 --- a/contracts/eosio.system/ricardian/eosio.system.contracts.md.in +++ /dev/null @@ -1,703 +0,0 @@ -

activate

- ---- -spec_version: "0.2.0" -title: Activate Protocol Feature -summary: 'Activate protocol feature {{nowrap feature_digest}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} activates the protocol feature with a digest of {{feature_digest}}. - -

bidname

- ---- -spec_version: "0.2.0" -title: Bid On a Premium Account Name -summary: '{{nowrap bidder}} bids on the premium account name {{nowrap newname}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{bidder}} bids {{bid}} on an auction to own the premium account name {{newname}}. - -{{bidder}} transfers {{bid}} to the system to cover the cost of the bid, which will be returned to {{bidder}} only if {{bidder}} is later outbid in the auction for {{newname}} by another account. - -If the auction for {{newname}} closes with {{bidder}} remaining as the highest bidder, {{bidder}} will be authorized to create the account with name {{newname}}. - -## Bid refund behavior - -If {{bidder}}’s bid on {{newname}} is later outbid by another account, {{bidder}} will be able to claim back the transferred amount of {{bid}}. The system will attempt to automatically do this on behalf of {{bidder}}, but the automatic refund may occasionally fail which will then require {{bidder}} to manually claim the refund with the bidrefund action. - -## Auction close criteria - -The system should automatically close the auction for {{newname}} if it satisfies the condition that over a period of two minutes the following two properties continuously hold: - -- no one has bid on {{newname}} within the last 24 hours; -- and, the value of the latest bid on {{newname}} is greater than the value of the bids on each of the other open auctions. - -Be aware that the condition to close the auction described above are sufficient but not necessary. The auction for {{newname}} cannot close unless both of the properties are simultaneously satisfied, but it may be closed without requiring the properties to hold for a period of 2 minutes. - -

bidrefund

- ---- -spec_version: "0.2.0" -title: Claim Refund on Name Bid -summary: 'Claim refund on {{nowrap newname}} bid' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{bidder}} claims refund on {{newname}} bid after being outbid by someone else. - -

buyram

- ---- -spec_version: "0.2.0" -title: Buy RAM -summary: '{{nowrap payer}} buys RAM on behalf of {{nowrap receiver}} by paying {{nowrap quant}}' -icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ ---- - -{{payer}} buys RAM on behalf of {{receiver}} by paying {{quant}}. This transaction will incur a 0.5% fee out of {{quant}} and the amount of RAM delivered will depend on market rates. - -

buyrambytes

- ---- -spec_version: "0.2.0" -title: Buy RAM -summary: '{{nowrap payer}} buys {{nowrap bytes}} bytes of RAM on behalf of {{nowrap receiver}}' -icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ ---- - -{{payer}} buys approximately {{bytes}} bytes of RAM on behalf of {{receiver}} by paying market rates for RAM. This transaction will incur a 0.5% fee and the cost will depend on market rates. - -

buyrex

- ---- -spec_version: "0.2.0" -title: Buy REX Tokens -summary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{amount}} is taken out of {{from}}’s REX fund and used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{from}} must have voted for a proxy or at least 21 block producers. {{amount}} is added to {{from}}’s vote stake. - -A sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately. - -

canceldelay

- ---- -spec_version: "0.2.0" -title: Cancel Delayed Transaction -summary: '{{nowrap canceling_auth.actor}} cancels a delayed transaction' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{canceling_auth.actor}} cancels the delayed transaction with id {{trx_id}}. - -

claimrewards

- ---- -spec_version: "0.2.0" -title: Claim Block Producer Rewards -summary: '{{nowrap owner}} claims block and vote rewards' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{owner}} claims block and vote rewards from the system. - -

closerex

- ---- -spec_version: "0.2.0" -title: Cleanup Unused REX Data -summary: 'Delete REX related DB entries and free associated RAM' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -Delete REX related DB entries and free associated RAM for {{owner}}. - -To fully delete all REX related DB entries, {{owner}} must ensure that their REX balance and REX fund amounts are both zero and they have no outstanding loans. - -

cnclrexorder

- ---- -spec_version: "0.2.0" -title: Cancel Scheduled REX Sell Order -summary: '{{nowrap owner}} cancels a scheduled sell order if not yet filled' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{owner}} cancels their open sell order. - -

consolidate

- ---- -spec_version: "0.2.0" -title: Consolidate REX Maturity Buckets Into One -summary: 'Consolidate REX maturity buckets into one' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -Consolidate REX maturity buckets into one bucket that {{owner}} will not be able to sell until 4 to 5 days later. - -

defcpuloan

- ---- -spec_version: "0.2.0" -title: Withdraw from the Fund of a Specific CPU Loan -summary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of CPU loan number {{nowrap loan_num}} back to REX fund' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from}} transfers {{amount}} from the fund of CPU loan number {{loan_num}} back to REX fund. - -

defnetloan

- ---- -spec_version: "0.2.0" -title: Withdraw from the Fund of a Specific NET Loan -summary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of NET loan number {{nowrap loan_num}} back to REX fund' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from}} transfers {{amount}} from the fund of NET loan number {{loan_num}} back to REX fund. - -

delegatebw

- ---- -spec_version: "0.2.0" -title: Stake Tokens for NET and/or CPU -summary: 'Stake tokens for NET and/or CPU and optionally transfer ownership' -icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ ---- - -{{#if transfer}} {{from}} stakes on behalf of {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth. - -Staked tokens will also be transferred to {{receiver}}. The sum of these two quantities will be deducted from {{from}}’s liquid balance and add to the vote weight of {{receiver}}. -{{else}} -{{from}} stakes to self and delegates to {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth. - -The sum of these two quantities add to the vote weight of {{from}}. -{{/if}} - -

deleteauth

- ---- -spec_version: "0.2.0" -title: Delete Account Permission -summary: 'Delete the {{nowrap permission}} permission of {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Delete the {{permission}} permission of {{account}}. - -

deposit

- ---- -spec_version: "0.2.0" -title: Deposit Into REX Fund -summary: 'Add to {{nowrap owner}}’s REX fund by transferring {{nowrap amount}} from {{nowrap owner}}’s liquid balance' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -Transfer {{amount}} from {{owner}}’s liquid balance to {{owner}}’s REX fund. All proceeds and expenses related to REX are added to or taken out of this fund. - -

fundcpuloan

- ---- -spec_version: "0.2.0" -title: Deposit into the Fund of a Specific CPU Loan -summary: '{{nowrap from}} funds a CPU loan' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from}} transfers {{payment}} from REX fund to the fund of CPU loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time. - -

fundnetloan

- ---- -spec_version: "0.2.0" -title: Deposit into the Fund of a Specific NET Loan -summary: '{{nowrap from}} funds a NET loan' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from}} transfers {{payment}} from REX fund to the fund of NET loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time. - -

init

- ---- -spec_version: "0.2.0" -title: Initialize System Contract -summary: 'Initialize system contract' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -Initialize system contract. The core token symbol will be set to {{core}}. - -

linkauth

- ---- -spec_version: "0.2.0" -title: Link Action to Permission -summary: '{{nowrap account}} sets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract to {{nowrap requirement}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{account}} sets the minimum required permission for the {{#if type}}{{type}} action of the{{/if}} {{code}} contract to {{requirement}}. - -{{#if type}}{{else}}Any links explicitly associated to specific actions of {{code}} will take precedence.{{/if}} - -

newaccount

- ---- -spec_version: "0.2.0" -title: Create New Account -summary: '{{nowrap creator}} creates a new account with the name {{nowrap name}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{creator}} creates a new account with the name {{name}} and the following permissions: - -owner permission with authority: -{{to_json owner}} - -active permission with authority: -{{to_json active}} - -

mvfrsavings

- ---- -spec_version: "0.2.0" -title: Unlock REX Tokens -summary: '{{nowrap owner}} unlocks REX Tokens' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{owner}} unlocks {{rex}} by moving it out of the REX savings bucket. The unlocked REX tokens cannot be sold until 4 to 5 days later. - -

mvtosavings

- ---- -spec_version: "0.2.0" -title: Lock REX Tokens -summary: '{{nowrap owner}} locks REX Tokens' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{owner}} locks {{rex}} by moving it into the REX savings bucket. The locked REX tokens cannot be sold directly and will have to be unlocked explicitly before selling. - -

refund

- ---- -spec_version: "0.2.0" -title: Claim Unstaked Tokens -summary: 'Return previously unstaked tokens to {{nowrap owner}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Return previously unstaked tokens to {{owner}} after the unstaking period has elapsed. - -

regproducer

- ---- -spec_version: "0.2.0" -title: Register as a Block Producer Candidate -summary: 'Register {{nowrap producer}} account as a block producer candidate' -icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ ---- - -Register {{producer}} account as a block producer candidate. - -URL: {{url}} -Location code: {{location}} -Block signing key: {{producer_key}} - -## Block Producer Agreement -{{$clauses.BlockProducerAgreement}} - -

regproducer2

- ---- -spec_version: "0.2.0" -title: Register as a Block Producer Candidate -summary: 'Register {{nowrap producer}} account as a block producer candidate' -icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ ---- - -Register {{producer}} account as a block producer candidate. - -URL: {{url}} -Location code: {{location}} -Block signing authority: -{{to_json producer_authority}} - -## Block Producer Agreement -{{$clauses.BlockProducerAgreement}} - -

regproxy

- ---- -spec_version: "0.2.0" -title: Register/unregister as a Proxy -summary: 'Register/unregister {{nowrap proxy}} as a proxy account' -icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ ---- - -{{#if isproxy}} -{{proxy}} registers as a proxy that can vote on behalf of accounts that appoint it as their proxy. -{{else}} -{{proxy}} unregisters as a proxy that can vote on behalf of accounts that appoint it as their proxy. -{{/if}} - -

rentcpu

- ---- -spec_version: "0.2.0" -title: Rent CPU Bandwidth for 30 Days -summary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent CPU bandwidth for {{nowrap receiver}}' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from}} pays {{loan_payment}} to rent CPU bandwidth on behalf of {{receiver}} for a period of 30 days. - -{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s CPU resources. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan. - -At expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s CPU bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s CPU bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund. - -

rentnet

- ---- -spec_version: "0.2.0" -title: Rent NET Bandwidth for 30 Days -summary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent NET bandwidth for {{nowrap receiver}}' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from}} pays {{loan_payment}} to rent NET bandwidth on behalf of {{receiver}} for a period of 30 days. - -{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s NET resources for 30 days. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan. - -At expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s NET bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s NET bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund. - -

rexexec

- ---- -spec_version: "0.2.0" -title: Perform REX Maintenance -summary: 'Process sell orders and expired loans' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -Performs REX maintenance by processing a maximum of {{max}} REX sell orders and expired loans. Any account can execute this action. - -

rmvproducer

- ---- -spec_version: "0.2.0" -title: Forcibly Unregister a Block Producer Candidate -summary: '{{nowrap producer}} is unregistered as a block producer candidate' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} unregisters {{producer}} as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered. - -

sellram

- ---- -spec_version: "0.2.0" -title: Sell RAM From Account -summary: 'Sell unused RAM from {{nowrap account}}' -icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ ---- - -Sell {{bytes}} bytes of unused RAM from account {{account}} at market price. This transaction will incur a 0.5% fee on the proceeds which depend on market rates. - -

sellrex

- ---- -spec_version: "0.2.0" -title: Sell REX Tokens in Exchange for EOS -summary: '{{nowrap from}} sells {{nowrap rex}} tokens' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from}} initiates a sell order to sell {{rex}} tokens at the market exchange rate during the time at which the order is ultimately executed. If {{from}} already has an open sell order in the sell queue, {{rex}} will be added to the amount of the sell order without change the position of the sell order within the queue. Once the sell order is executed, proceeds are added to {{from}}’s REX fund, the value of sold REX tokens is deducted from {{from}}’s vote stake, and votes are updated accordingly. - -Depending on the market conditions, it may not be possible to fill the entire sell order immediately. In such a case, the sell order is added to the back of a sell queue. A sell order at the front of the sell queue will automatically be executed when the market conditions allow for the entire order to be filled. Regardless of the market conditions, the system is designed to execute this sell order within 30 days. {{from}} can cancel the order at any time before it is filled using the cnclrexorder action. - -

setabi

- ---- -spec_version: "0.2.0" -title: Deploy Contract ABI -summary: 'Deploy contract ABI on account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Deploy the ABI file associated with the contract on account {{account}}. - -

setacctcpu

- ---- -spec_version: "0.2.0" -title: Explicitly Manage the CPU Quota of Account -summary: 'Explicitly manage the CPU bandwidth quota of account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{#if_has_value cpu_weight}} -Explicitly manage the CPU bandwidth quota of account {{account}} by pinning it to a weight of {{cpu_weight}}. - -{{account}} can stake and unstake, however, it will not change their CPU bandwidth quota as long as it remains pinned. -{{else}} -Unpin the CPU bandwidth quota of account {{account}}. The CPU bandwidth quota of {{account}} will be driven by the current tokens staked for CPU bandwidth by {{account}}. -{{/if_has_value}} - -

setacctnet

- ---- -spec_version: "0.2.0" -title: Explicitly Manage the NET Quota of Account -summary: 'Explicitly manage the NET bandwidth quota of account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{#if_has_value net_weight}} -Explicitly manage the network bandwidth quota of account {{account}} by pinning it to a weight of {{net_weight}}. - -{{account}} can stake and unstake, however, it will not change their NET bandwidth quota as long as it remains pinned. -{{else}} -Unpin the NET bandwidth quota of account {{account}}. The NET bandwidth quota of {{account}} will be driven by the current tokens staked for NET bandwidth by {{account}}. -{{/if_has_value}} - -

setacctram

- ---- -spec_version: "0.2.0" -title: Explicitly Manage the RAM Quota of Account -summary: 'Explicitly manage the RAM quota of account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{#if_has_value ram_bytes}} -Explicitly manage the RAM quota of account {{account}} by pinning it to {{ram_bytes}} bytes. - -{{account}} can buy and sell RAM, however, it will not change their RAM quota as long as it remains pinned. -{{else}} -Unpin the RAM quota of account {{account}}. The RAM quota of {{account}} will be driven by the current RAM holdings of {{account}}. -{{/if_has_value}} - -

setalimits

- ---- -spec_version: "0.2.0" -title: Adjust Resource Limits of Account -summary: 'Adjust resource limits of account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} updates {{account}}’s resource limits to have a RAM quota of {{ram_bytes}} bytes, a NET bandwidth quota of {{net_weight}} and a CPU bandwidth quota of {{cpu_weight}}. - -

setcode

- ---- -spec_version: "0.2.0" -title: Deploy Contract Code -summary: 'Deploy contract code on account {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Deploy compiled contract code to the account {{account}}. - -

setparams

- ---- -spec_version: "0.2.0" -title: Set System Parameters -summary: 'Set System Parameters' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} sets system parameters to: -{{to_json params}} - -

setpriv

- ---- -spec_version: "0.2.0" -title: Make an Account Privileged or Unprivileged -summary: '{{#if is_priv}}Make {{nowrap account}} privileged{{else}}Remove privileged status of {{nowrap account}}{{/if}}' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{#if is_priv}} -{{$action.account}} makes {{account}} privileged. -{{else}} -{{$action.account}} removes privileged status of {{account}}. -{{/if}} - -

setram

- ---- -spec_version: "0.2.0" -title: Configure the Available RAM -summary: 'Configure the available RAM' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} configures the available RAM to {{max_ram_size}} bytes. - -

setramrate

- ---- -spec_version: "0.2.0" -title: Set the Rate of Increase of RAM -summary: 'Set the rate of increase of RAM per block' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} sets the rate of increase of RAM to {{bytes_per_block}} bytes/block. - -

setrex

- ---- -spec_version: "0.2.0" -title: Adjust REX Pool Virtual Balance -summary: 'Adjust REX Pool Virtual Balance' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} adjusts REX loan rate by setting REX pool virtual balance to {{balance}}. No token transfer or issue is executed in this action. - -

setinflation

- ---- -spec_version: "0.2.0" -title: Set Inflation Parameters -summary: 'Set inflation parameters' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} sets the inflation parameters as follows: - -* Annual inflation rate (in units of a hundredth of a percent): {{annual_rate}} -* Fraction of inflation used to reward block producers: 10000/{{inflation_pay_factor}} -* Fraction of block producer rewards to be distributed proportional to blocks produced: 10000/{{votepay_factor}} - -

undelegatebw

- ---- -spec_version: "0.2.0" -title: Unstake Tokens for NET and/or CPU -summary: 'Unstake tokens for NET and/or CPU from {{nowrap receiver}}' -icon: @ICON_BASE_URL@/@RESOURCE_ICON_URI@ ---- - -{{from}} unstakes from {{receiver}} {{unstake_net_quantity}} for NET bandwidth and {{unstake_cpu_quantity}} for CPU bandwidth. - -The sum of these two quantities will be removed from the vote weight of {{receiver}} and will be made available to {{from}} after an uninterrupted 3 day period without further unstaking by {{from}}. After the uninterrupted 3 day period passes, the system will attempt to automatically return the funds to {{from}}’s regular token balance. However, this automatic refund may occasionally fail which will then require {{from}} to manually claim the funds with the refund action. - -

unlinkauth

- ---- -spec_version: "0.2.0" -title: Unlink Action from Permission -summary: '{{nowrap account}} unsets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -{{account}} removes the association between the {{#if type}}{{type}} action of the{{/if}} {{code}} contract and its minimum required permission. - -{{#if type}}{{else}}This will not remove any links explicitly associated to specific actions of {{code}}.{{/if}} - -

unregprod

- ---- -spec_version: "0.2.0" -title: Unregister as a Block Producer Candidate -summary: '{{nowrap producer}} unregisters as a block producer candidate' -icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ ---- - -{{producer}} unregisters as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered. - -

unstaketorex

- ---- -spec_version: "0.2.0" -title: Buy REX Tokens Using Staked Tokens -summary: '{{nowrap owner}} buys REX tokens in exchange for tokens currently staked to NET and/or CPU' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -{{from_net}} and {{from_cpu}} are withdrawn from {{receiver}}’s NET and CPU bandwidths respectively. These funds are used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{owner}} must have voted for a proxy or at least 21 block producers. - -A sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately. - -

updateauth

- ---- -spec_version: "0.2.0" -title: Modify Account Permission -summary: 'Add or update the {{nowrap permission}} permission of {{nowrap account}}' -icon: @ICON_BASE_URL@/@ACCOUNT_ICON_URI@ ---- - -Modify, and create if necessary, the {{permission}} permission of {{account}} to have a parent permission of {{parent}} and the following authority: -{{to_json auth}} - -

updaterex

- ---- -spec_version: "0.2.0" -title: Update REX Owner Vote Weight -summary: 'Update vote weight to current value of held REX tokens' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -Update vote weight of {{owner}} account to current value of held REX tokens. - -

updtrevision

- ---- -spec_version: "0.2.0" -title: Update System Contract Revision Number -summary: 'Update system contract revision number' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{$action.account}} advances the system contract revision number to {{revision}}. - -

voteproducer

- ---- -spec_version: "0.2.0" -title: Vote for Block Producers -summary: '{{nowrap voter}} votes for {{#if proxy}}the proxy {{nowrap proxy}}{{else}}up to 30 block producer candidates{{/if}}' -icon: @ICON_BASE_URL@/@VOTING_ICON_URI@ ---- - -{{#if proxy}} -{{voter}} votes for the proxy {{proxy}}. -At the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the producers voted by {{proxy}}. -{{else}} -{{voter}} votes for the following block producer candidates: - -{{#each producers}} - + {{this}} -{{/each}} - -At the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the above producers. -{{/if}} - -

withdraw

- ---- -spec_version: "0.2.0" -title: Withdraw from REX Fund -summary: 'Withdraw {{nowrap amount}} from {{nowrap owner}}’s REX fund by transferring to {{owner}}’s liquid balance' -icon: @ICON_BASE_URL@/@REX_ICON_URI@ ---- - -Withdraws {{amount}} from {{owner}}’s REX fund and transfer them to {{owner}}’s liquid balance. diff --git a/contracts/eosio.system/src/delegate_bandwidth.cpp b/contracts/eosio.system/src/delegate_bandwidth.cpp deleted file mode 100644 index a64506c0..00000000 --- a/contracts/eosio.system/src/delegate_bandwidth.cpp +++ /dev/null @@ -1,413 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include -#include - -namespace eosiosystem { - - using eosio::asset; - using eosio::const_mem_fun; - using eosio::current_time_point; - using eosio::indexed_by; - using eosio::permission_level; - using eosio::seconds; - using eosio::time_point_sec; - using eosio::token; - - /** - * This action will buy an exact amount of ram and bill the payer the current market price. - */ - void system_contract::buyrambytes( const name& payer, const name& receiver, uint32_t bytes ) { - auto itr = _rammarket.find(ramcore_symbol.raw()); - const int64_t ram_reserve = itr->base.balance.amount; - const int64_t eos_reserve = itr->quote.balance.amount; - const int64_t cost = exchange_state::get_bancor_input( ram_reserve, eos_reserve, bytes ); - const int64_t cost_plus_fee = cost / double(0.995); - buyram( payer, receiver, asset{ cost_plus_fee, core_symbol() } ); - } - - - /** - * When buying ram the payer irreversiblly transfers quant to system contract and only - * the receiver may reclaim the tokens via the sellram action. The receiver pays for the - * storage of all database records associated with this action. - * - * RAM is a scarce resource whose supply is defined by global properties max_ram_size. RAM is - * priced using the bancor algorithm such that price-per-byte with a constant reserve ratio of 100:1. - */ - void system_contract::buyram( const name& payer, const name& receiver, const asset& quant ) - { - require_auth( payer ); - update_ram_supply(); - - check( quant.symbol == core_symbol(), "must buy ram with core token" ); - check( quant.amount > 0, "must purchase a positive amount" ); - - auto fee = quant; - fee.amount = ( fee.amount + 199 ) / 200; /// .5% fee (round up) - // fee.amount cannot be 0 since that is only possible if quant.amount is 0 which is not allowed by the assert above. - // If quant.amount == 1, then fee.amount == 1, - // otherwise if quant.amount > 1, then 0 < fee.amount < quant.amount. - auto quant_after_fee = quant; - quant_after_fee.amount -= fee.amount; - // quant_after_fee.amount should be > 0 if quant.amount > 1. - // If quant.amount == 1, then quant_after_fee.amount == 0 and the next inline transfer will fail causing the buyram action to fail. - { - token::transfer_action transfer_act{ token_account, { {payer, active_permission}, {ram_account, active_permission} } }; - transfer_act.send( payer, ram_account, quant_after_fee, "buy ram" ); - } - if ( fee.amount > 0 ) { - token::transfer_action transfer_act{ token_account, { {payer, active_permission} } }; - transfer_act.send( payer, ramfee_account, fee, "ram fee" ); - channel_to_rex( ramfee_account, fee ); - } - - int64_t bytes_out; - - const auto& market = _rammarket.get(ramcore_symbol.raw(), "ram market does not exist"); - _rammarket.modify( market, same_payer, [&]( auto& es ) { - bytes_out = es.direct_convert( quant_after_fee, ram_symbol ).amount; - }); - - check( bytes_out > 0, "must reserve a positive amount" ); - - _gstate.total_ram_bytes_reserved += uint64_t(bytes_out); - _gstate.total_ram_stake += quant_after_fee.amount; - - user_resources_table userres( get_self(), receiver.value ); - auto res_itr = userres.find( receiver.value ); - if( res_itr == userres.end() ) { - res_itr = userres.emplace( receiver, [&]( auto& res ) { - res.owner = receiver; - res.net_weight = asset( 0, core_symbol() ); - res.cpu_weight = asset( 0, core_symbol() ); - res.ram_bytes = bytes_out; - }); - } else { - userres.modify( res_itr, receiver, [&]( auto& res ) { - res.ram_bytes += bytes_out; - }); - } - - auto voter_itr = _voters.find( res_itr->owner.value ); - if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { - int64_t ram_bytes, net, cpu; - get_resource_limits( res_itr->owner, ram_bytes, net, cpu ); - set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); - } - } - - /** - * The system contract now buys and sells RAM allocations at prevailing market prices. - * This may result in traders buying RAM today in anticipation of potential shortages - * tomorrow. Overall this will result in the market balancing the supply and demand - * for RAM over time. - */ - void system_contract::sellram( const name& account, int64_t bytes ) { - require_auth( account ); - update_ram_supply(); - - check( bytes > 0, "cannot sell negative byte" ); - - user_resources_table userres( get_self(), account.value ); - auto res_itr = userres.find( account.value ); - check( res_itr != userres.end(), "no resource row" ); - check( res_itr->ram_bytes >= bytes, "insufficient quota" ); - - asset tokens_out; - auto itr = _rammarket.find(ramcore_symbol.raw()); - _rammarket.modify( itr, same_payer, [&]( auto& es ) { - /// the cast to int64_t of bytes is safe because we certify bytes is <= quota which is limited by prior purchases - tokens_out = es.direct_convert( asset(bytes, ram_symbol), core_symbol()); - }); - - check( tokens_out.amount > 1, "token amount received from selling ram is too low" ); - - _gstate.total_ram_bytes_reserved -= static_cast(bytes); // bytes > 0 is asserted above - _gstate.total_ram_stake -= tokens_out.amount; - - //// this shouldn't happen, but just in case it does we should prevent it - check( _gstate.total_ram_stake >= 0, "error, attempt to unstake more tokens than previously staked" ); - - userres.modify( res_itr, account, [&]( auto& res ) { - res.ram_bytes -= bytes; - }); - - auto voter_itr = _voters.find( res_itr->owner.value ); - if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) { - int64_t ram_bytes, net, cpu; - get_resource_limits( res_itr->owner, ram_bytes, net, cpu ); - set_resource_limits( res_itr->owner, res_itr->ram_bytes + ram_gift_bytes, net, cpu ); - } - - { - token::transfer_action transfer_act{ token_account, { {ram_account, active_permission}, {account, active_permission} } }; - transfer_act.send( ram_account, account, asset(tokens_out), "sell ram" ); - } - auto fee = ( tokens_out.amount + 199 ) / 200; /// .5% fee (round up) - // since tokens_out.amount was asserted to be at least 2 earlier, fee.amount < tokens_out.amount - if ( fee > 0 ) { - token::transfer_action transfer_act{ token_account, { {account, active_permission} } }; - transfer_act.send( account, ramfee_account, asset(fee, core_symbol()), "sell ram fee" ); - channel_to_rex( ramfee_account, asset(fee, core_symbol() )); - } - } - - void validate_b1_vesting( int64_t stake ) { - const int64_t base_time = 1527811200; /// 2018-06-01 - const int64_t max_claimable = 100'000'000'0000ll; - const int64_t claimable = int64_t(max_claimable * double(current_time_point().sec_since_epoch() - base_time) / (10*seconds_per_year) ); - - check( max_claimable - claimable <= stake, "b1 can only claim their tokens over 10 years" ); - } - - void system_contract::changebw( name from, const name& receiver, - const asset& stake_net_delta, const asset& stake_cpu_delta, bool transfer ) - { - require_auth( from ); - check( stake_net_delta.amount != 0 || stake_cpu_delta.amount != 0, "should stake non-zero amount" ); - check( std::abs( (stake_net_delta + stake_cpu_delta).amount ) - >= std::max( std::abs( stake_net_delta.amount ), std::abs( stake_cpu_delta.amount ) ), - "net and cpu deltas cannot be opposite signs" ); - - name source_stake_from = from; - if ( transfer ) { - from = receiver; - } - - // update stake delegated from "from" to "receiver" - { - del_bandwidth_table del_tbl( get_self(), from.value ); - auto itr = del_tbl.find( receiver.value ); - if( itr == del_tbl.end() ) { - itr = del_tbl.emplace( from, [&]( auto& dbo ){ - dbo.from = from; - dbo.to = receiver; - dbo.net_weight = stake_net_delta; - dbo.cpu_weight = stake_cpu_delta; - }); - } - else { - del_tbl.modify( itr, same_payer, [&]( auto& dbo ){ - dbo.net_weight += stake_net_delta; - dbo.cpu_weight += stake_cpu_delta; - }); - } - check( 0 <= itr->net_weight.amount, "insufficient staked net bandwidth" ); - check( 0 <= itr->cpu_weight.amount, "insufficient staked cpu bandwidth" ); - if ( itr->is_empty() ) { - del_tbl.erase( itr ); - } - } // itr can be invalid, should go out of scope - - // update totals of "receiver" - { - user_resources_table totals_tbl( get_self(), receiver.value ); - auto tot_itr = totals_tbl.find( receiver.value ); - if( tot_itr == totals_tbl.end() ) { - tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { - tot.owner = receiver; - tot.net_weight = stake_net_delta; - tot.cpu_weight = stake_cpu_delta; - }); - } else { - totals_tbl.modify( tot_itr, from == receiver ? from : same_payer, [&]( auto& tot ) { - tot.net_weight += stake_net_delta; - tot.cpu_weight += stake_cpu_delta; - }); - } - check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); - check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); - - { - bool ram_managed = false; - bool net_managed = false; - bool cpu_managed = false; - - auto voter_itr = _voters.find( receiver.value ); - if( voter_itr != _voters.end() ) { - ram_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ); - net_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::net_managed ); - cpu_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::cpu_managed ); - } - - if( !(net_managed && cpu_managed) ) { - int64_t ram_bytes, net, cpu; - get_resource_limits( receiver, ram_bytes, net, cpu ); - - set_resource_limits( receiver, - ram_managed ? ram_bytes : std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), - net_managed ? net : tot_itr->net_weight.amount, - cpu_managed ? cpu : tot_itr->cpu_weight.amount ); - } - } - - if ( tot_itr->is_empty() ) { - totals_tbl.erase( tot_itr ); - } - } // tot_itr can be invalid, should go out of scope - - // create refund or update from existing refund - if ( stake_account != source_stake_from ) { //for eosio both transfer and refund make no sense - refunds_table refunds_tbl( get_self(), from.value ); - auto req = refunds_tbl.find( from.value ); - - //create/update/delete refund - auto net_balance = stake_net_delta; - auto cpu_balance = stake_cpu_delta; - bool need_deferred_trx = false; - - - // net and cpu are same sign by assertions in delegatebw and undelegatebw - // redundant assertion also at start of changebw to protect against misuse of changebw - bool is_undelegating = (net_balance.amount + cpu_balance.amount ) < 0; - bool is_delegating_to_self = (!transfer && from == receiver); - - if( is_delegating_to_self || is_undelegating ) { - if ( req != refunds_tbl.end() ) { //need to update refund - refunds_tbl.modify( req, same_payer, [&]( refund_request& r ) { - if ( net_balance.amount < 0 || cpu_balance.amount < 0 ) { - r.request_time = current_time_point(); - } - r.net_amount -= net_balance; - if ( r.net_amount.amount < 0 ) { - net_balance = -r.net_amount; - r.net_amount.amount = 0; - } else { - net_balance.amount = 0; - } - r.cpu_amount -= cpu_balance; - if ( r.cpu_amount.amount < 0 ){ - cpu_balance = -r.cpu_amount; - r.cpu_amount.amount = 0; - } else { - cpu_balance.amount = 0; - } - }); - - check( 0 <= req->net_amount.amount, "negative net refund amount" ); //should never happen - check( 0 <= req->cpu_amount.amount, "negative cpu refund amount" ); //should never happen - - if ( req->is_empty() ) { - refunds_tbl.erase( req ); - need_deferred_trx = false; - } else { - need_deferred_trx = true; - } - } else if ( net_balance.amount < 0 || cpu_balance.amount < 0 ) { //need to create refund - refunds_tbl.emplace( from, [&]( refund_request& r ) { - r.owner = from; - if ( net_balance.amount < 0 ) { - r.net_amount = -net_balance; - net_balance.amount = 0; - } else { - r.net_amount = asset( 0, core_symbol() ); - } - if ( cpu_balance.amount < 0 ) { - r.cpu_amount = -cpu_balance; - cpu_balance.amount = 0; - } else { - r.cpu_amount = asset( 0, core_symbol() ); - } - r.request_time = current_time_point(); - }); - need_deferred_trx = true; - } // else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl - } /// end if is_delegating_to_self || is_undelegating - - if ( need_deferred_trx ) { - eosio::transaction out; - out.actions.emplace_back( permission_level{from, active_permission}, - get_self(), "refund"_n, - from - ); - out.delay_sec = refund_delay_sec; - eosio::cancel_deferred( from.value ); // TODO: Remove this line when replacing deferred trxs is fixed - out.send( from.value, from, true ); - } else { - eosio::cancel_deferred( from.value ); - } - - auto transfer_amount = net_balance + cpu_balance; - if ( 0 < transfer_amount.amount ) { - token::transfer_action transfer_act{ token_account, { {source_stake_from, active_permission} } }; - transfer_act.send( source_stake_from, stake_account, asset(transfer_amount), "stake bandwidth" ); - } - } - - vote_stake_updater( from ); - update_voting_power( from, stake_net_delta + stake_cpu_delta ); - } - - void system_contract::update_voting_power( const name& voter, const asset& total_update ) - { - auto voter_itr = _voters.find( voter.value ); - if( voter_itr == _voters.end() ) { - voter_itr = _voters.emplace( voter, [&]( auto& v ) { - v.owner = voter; - v.staked = total_update.amount; - }); - } else { - _voters.modify( voter_itr, same_payer, [&]( auto& v ) { - v.staked += total_update.amount; - }); - } - - check( 0 <= voter_itr->staked, "stake for voting cannot be negative" ); - - if( voter == "b1"_n ) { - validate_b1_vesting( voter_itr->staked ); - } - - if( voter_itr->producers.size() || voter_itr->proxy ) { - update_votes( voter, voter_itr->proxy, voter_itr->producers, false ); - } - } - - void system_contract::delegatebw( const name& from, const name& receiver, - const asset& stake_net_quantity, - const asset& stake_cpu_quantity, bool transfer ) - { - asset zero_asset( 0, core_symbol() ); - check( stake_cpu_quantity >= zero_asset, "must stake a positive amount" ); - check( stake_net_quantity >= zero_asset, "must stake a positive amount" ); - check( stake_net_quantity.amount + stake_cpu_quantity.amount > 0, "must stake a positive amount" ); - check( !transfer || from != receiver, "cannot use transfer flag if delegating to self" ); - - changebw( from, receiver, stake_net_quantity, stake_cpu_quantity, transfer); - } // delegatebw - - void system_contract::undelegatebw( const name& from, const name& receiver, - const asset& unstake_net_quantity, const asset& unstake_cpu_quantity ) - { - asset zero_asset( 0, core_symbol() ); - check( unstake_cpu_quantity >= zero_asset, "must unstake a positive amount" ); - check( unstake_net_quantity >= zero_asset, "must unstake a positive amount" ); - check( unstake_cpu_quantity.amount + unstake_net_quantity.amount > 0, "must unstake a positive amount" ); - check( _gstate.thresh_activated_stake_time != time_point(), - "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ); - - changebw( from, receiver, -unstake_net_quantity, -unstake_cpu_quantity, false); - } // undelegatebw - - - void system_contract::refund( const name& owner ) { - require_auth( owner ); - - refunds_table refunds_tbl( get_self(), owner.value ); - auto req = refunds_tbl.find( owner.value ); - check( req != refunds_tbl.end(), "refund request not found" ); - check( req->request_time + seconds(refund_delay_sec) <= current_time_point(), - "refund is not available yet" ); - token::transfer_action transfer_act{ token_account, { {stake_account, active_permission}, {req->owner, active_permission} } }; - transfer_act.send( stake_account, req->owner, req->net_amount + req->cpu_amount, "unstake" ); - refunds_tbl.erase( req ); - } - - -} //namespace eosiosystem diff --git a/contracts/eosio.system/src/eosio.system.cpp b/contracts/eosio.system/src/eosio.system.cpp deleted file mode 100644 index 202210c7..00000000 --- a/contracts/eosio.system/src/eosio.system.cpp +++ /dev/null @@ -1,400 +0,0 @@ -#include -#include - -#include -#include - -#include - -namespace eosiosystem { - - using eosio::current_time_point; - using eosio::token; - - double get_continuous_rate(int64_t annual_rate) { - return std::log1p(double(annual_rate)/double(100*inflation_precision)); - } - - system_contract::system_contract( name s, name code, datastream ds ) - :native(s,code,ds), - _voters(get_self(), get_self().value), - _producers(get_self(), get_self().value), - _producers2(get_self(), get_self().value), - _global(get_self(), get_self().value), - _global2(get_self(), get_self().value), - _global3(get_self(), get_self().value), - _global4(get_self(), get_self().value), - _rammarket(get_self(), get_self().value), - _rexpool(get_self(), get_self().value), - _rexretpool(get_self(), get_self().value), - _rexretbuckets(get_self(), get_self().value), - _rexfunds(get_self(), get_self().value), - _rexbalance(get_self(), get_self().value), - _rexorders(get_self(), get_self().value) - { - _gstate = _global.exists() ? _global.get() : get_default_parameters(); - _gstate2 = _global2.exists() ? _global2.get() : eosio_global_state2{}; - _gstate3 = _global3.exists() ? _global3.get() : eosio_global_state3{}; - _gstate4 = _global4.exists() ? _global4.get() : get_default_inflation_parameters(); - } - - eosio_global_state system_contract::get_default_parameters() { - eosio_global_state dp; - get_blockchain_parameters(dp); - return dp; - } - - eosio_global_state4 system_contract::get_default_inflation_parameters() { - eosio_global_state4 gs4; - gs4.continuous_rate = get_continuous_rate(default_annual_rate); - gs4.inflation_pay_factor = default_inflation_pay_factor; - gs4.votepay_factor = default_votepay_factor; - return gs4; - } - - symbol system_contract::core_symbol()const { - const static auto sym = get_core_symbol( _rammarket ); - return sym; - } - - system_contract::~system_contract() { - _global.set( _gstate, get_self() ); - _global2.set( _gstate2, get_self() ); - _global3.set( _gstate3, get_self() ); - _global4.set( _gstate4, get_self() ); - } - - void system_contract::setram( uint64_t max_ram_size ) { - require_auth( get_self() ); - - check( _gstate.max_ram_size < max_ram_size, "ram may only be increased" ); /// decreasing ram might result market maker issues - check( max_ram_size < 1024ll*1024*1024*1024*1024, "ram size is unrealistic" ); - check( max_ram_size > _gstate.total_ram_bytes_reserved, "attempt to set max below reserved" ); - - auto delta = int64_t(max_ram_size) - int64_t(_gstate.max_ram_size); - auto itr = _rammarket.find(ramcore_symbol.raw()); - - /** - * Increase the amount of ram for sale based upon the change in max ram size. - */ - _rammarket.modify( itr, same_payer, [&]( auto& m ) { - m.base.balance.amount += delta; - }); - - _gstate.max_ram_size = max_ram_size; - } - - void system_contract::update_ram_supply() { - auto cbt = eosio::current_block_time(); - - if( cbt <= _gstate2.last_ram_increase ) return; - - auto itr = _rammarket.find(ramcore_symbol.raw()); - auto new_ram = (cbt.slot - _gstate2.last_ram_increase.slot)*_gstate2.new_ram_per_block; - _gstate.max_ram_size += new_ram; - - /** - * Increase the amount of ram for sale based upon the change in max ram size. - */ - _rammarket.modify( itr, same_payer, [&]( auto& m ) { - m.base.balance.amount += new_ram; - }); - _gstate2.last_ram_increase = cbt; - } - - void system_contract::setramrate( uint16_t bytes_per_block ) { - require_auth( get_self() ); - - update_ram_supply(); - _gstate2.new_ram_per_block = bytes_per_block; - } - - void system_contract::setparams( const eosio::blockchain_parameters& params ) { - require_auth( get_self() ); - (eosio::blockchain_parameters&)(_gstate) = params; - check( 3 <= _gstate.max_authority_depth, "max_authority_depth should be at least 3" ); - set_blockchain_parameters( params ); - } - - void system_contract::setpriv( const name& account, uint8_t ispriv ) { - require_auth( get_self() ); - set_privileged( account, ispriv ); - } - - void system_contract::setalimits( const name& account, int64_t ram, int64_t net, int64_t cpu ) { - require_auth( get_self() ); - - user_resources_table userres( get_self(), account.value ); - auto ritr = userres.find( account.value ); - check( ritr == userres.end(), "only supports unlimited accounts" ); - - auto vitr = _voters.find( account.value ); - if( vitr != _voters.end() ) { - bool ram_managed = has_field( vitr->flags1, voter_info::flags1_fields::ram_managed ); - bool net_managed = has_field( vitr->flags1, voter_info::flags1_fields::net_managed ); - bool cpu_managed = has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed ); - check( !(ram_managed || net_managed || cpu_managed), "cannot use setalimits on an account with managed resources" ); - } - - set_resource_limits( account, ram, net, cpu ); - } - - void system_contract::setacctram( const name& account, const std::optional& ram_bytes ) { - require_auth( get_self() ); - - int64_t current_ram, current_net, current_cpu; - get_resource_limits( account, current_ram, current_net, current_cpu ); - - int64_t ram = 0; - - if( !ram_bytes ) { - auto vitr = _voters.find( account.value ); - check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::ram_managed ), - "RAM of account is already unmanaged" ); - - user_resources_table userres( get_self(), account.value ); - auto ritr = userres.find( account.value ); - - ram = ram_gift_bytes; - if( ritr != userres.end() ) { - ram += ritr->ram_bytes; - } - - _voters.modify( vitr, same_payer, [&]( auto& v ) { - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, false ); - }); - } else { - check( *ram_bytes >= 0, "not allowed to set RAM limit to unlimited" ); - - auto vitr = _voters.find( account.value ); - if ( vitr != _voters.end() ) { - _voters.modify( vitr, same_payer, [&]( auto& v ) { - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, true ); - }); - } else { - _voters.emplace( account, [&]( auto& v ) { - v.owner = account; - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, true ); - }); - } - - ram = *ram_bytes; - } - - set_resource_limits( account, ram, current_net, current_cpu ); - } - - void system_contract::setacctnet( const name& account, const std::optional& net_weight ) { - require_auth( get_self() ); - - int64_t current_ram, current_net, current_cpu; - get_resource_limits( account, current_ram, current_net, current_cpu ); - - int64_t net = 0; - - if( !net_weight ) { - auto vitr = _voters.find( account.value ); - check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::net_managed ), - "Network bandwidth of account is already unmanaged" ); - - user_resources_table userres( get_self(), account.value ); - auto ritr = userres.find( account.value ); - - if( ritr != userres.end() ) { - net = ritr->net_weight.amount; - } - - _voters.modify( vitr, same_payer, [&]( auto& v ) { - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, false ); - }); - } else { - check( *net_weight >= -1, "invalid value for net_weight" ); - - auto vitr = _voters.find( account.value ); - if ( vitr != _voters.end() ) { - _voters.modify( vitr, same_payer, [&]( auto& v ) { - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, true ); - }); - } else { - _voters.emplace( account, [&]( auto& v ) { - v.owner = account; - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, true ); - }); - } - - net = *net_weight; - } - - set_resource_limits( account, current_ram, net, current_cpu ); - } - - void system_contract::setacctcpu( const name& account, const std::optional& cpu_weight ) { - require_auth( get_self() ); - - int64_t current_ram, current_net, current_cpu; - get_resource_limits( account, current_ram, current_net, current_cpu ); - - int64_t cpu = 0; - - if( !cpu_weight ) { - auto vitr = _voters.find( account.value ); - check( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed ), - "CPU bandwidth of account is already unmanaged" ); - - user_resources_table userres( get_self(), account.value ); - auto ritr = userres.find( account.value ); - - if( ritr != userres.end() ) { - cpu = ritr->cpu_weight.amount; - } - - _voters.modify( vitr, same_payer, [&]( auto& v ) { - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, false ); - }); - } else { - check( *cpu_weight >= -1, "invalid value for cpu_weight" ); - - auto vitr = _voters.find( account.value ); - if ( vitr != _voters.end() ) { - _voters.modify( vitr, same_payer, [&]( auto& v ) { - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, true ); - }); - } else { - _voters.emplace( account, [&]( auto& v ) { - v.owner = account; - v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, true ); - }); - } - - cpu = *cpu_weight; - } - - set_resource_limits( account, current_ram, current_net, cpu ); - } - - void system_contract::activate( const eosio::checksum256& feature_digest ) { - require_auth( get_self() ); - preactivate_feature( feature_digest ); - } - - void system_contract::rmvproducer( const name& producer ) { - require_auth( get_self() ); - auto prod = _producers.find( producer.value ); - check( prod != _producers.end(), "producer not found" ); - _producers.modify( prod, same_payer, [&](auto& p) { - p.deactivate(); - }); - } - - void system_contract::updtrevision( uint8_t revision ) { - require_auth( get_self() ); - check( _gstate2.revision < 255, "can not increment revision" ); // prevent wrap around - check( revision == _gstate2.revision + 1, "can only increment revision by one" ); - check( revision <= 1, // set upper bound to greatest revision supported in the code - "specified revision is not yet supported by the code" ); - _gstate2.revision = revision; - } - - void system_contract::setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { - require_auth(get_self()); - check(annual_rate >= 0, "annual_rate can't be negative"); - if ( inflation_pay_factor < pay_factor_precision ) { - check( false, "inflation_pay_factor must not be less than " + std::to_string(pay_factor_precision) ); - } - if ( votepay_factor < pay_factor_precision ) { - check( false, "votepay_factor must not be less than " + std::to_string(pay_factor_precision) ); - } - _gstate4.continuous_rate = get_continuous_rate(annual_rate); - _gstate4.inflation_pay_factor = inflation_pay_factor; - _gstate4.votepay_factor = votepay_factor; - _global4.set( _gstate4, get_self() ); - } - - /** - * Called after a new account is created. This code enforces resource-limits rules - * for new accounts as well as new account naming conventions. - * - * Account names containing '.' symbols must have a suffix equal to the name of the creator. - * This allows users who buy a premium name (shorter than 12 characters with no dots) to be the only ones - * who can create accounts with the creator's name as a suffix. - * - */ - void native::newaccount( const name& creator, - const name& newact, - ignore owner, - ignore active ) { - - if( creator != get_self() ) { - uint64_t tmp = newact.value >> 4; - bool has_dot = false; - - for( uint32_t i = 0; i < 12; ++i ) { - has_dot |= !(tmp & 0x1f); - tmp >>= 5; - } - if( has_dot ) { // or is less than 12 characters - auto suffix = newact.suffix(); - if( suffix == newact ) { - name_bid_table bids(get_self(), get_self().value); - auto current = bids.find( newact.value ); - check( current != bids.end(), "no active bid for name" ); - check( current->high_bidder == creator, "only highest bidder can claim" ); - check( current->high_bid < 0, "auction for name is not closed yet" ); - bids.erase( current ); - } else { - check( creator == suffix, "only suffix may create this account" ); - } - } - } - - user_resources_table userres( get_self(), newact.value ); - - userres.emplace( newact, [&]( auto& res ) { - res.owner = newact; - res.net_weight = asset( 0, system_contract::get_core_symbol() ); - res.cpu_weight = asset( 0, system_contract::get_core_symbol() ); - }); - - set_resource_limits( newact, 0, 0, 0 ); - } - - void native::setabi( const name& acnt, const std::vector& abi ) { - eosio::multi_index< "abihash"_n, abi_hash > table(get_self(), get_self().value); - auto itr = table.find( acnt.value ); - if( itr == table.end() ) { - table.emplace( acnt, [&]( auto& row ) { - row.owner = acnt; - row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); - }); - } else { - table.modify( itr, same_payer, [&]( auto& row ) { - row.hash = eosio::sha256(const_cast(abi.data()), abi.size()); - }); - } - } - - void system_contract::init( unsigned_int version, const symbol& core ) { - require_auth( get_self() ); - check( version.value == 0, "unsupported version for init action" ); - - auto itr = _rammarket.find(ramcore_symbol.raw()); - check( itr == _rammarket.end(), "system contract has already been initialized" ); - - auto system_token_supply = eosio::token::get_supply(token_account, core.code() ); - check( system_token_supply.symbol == core, "specified core symbol does not exist (precision mismatch)" ); - - check( system_token_supply.amount > 0, "system token supply must be greater than 0" ); - _rammarket.emplace( get_self(), [&]( auto& m ) { - m.supply.amount = 100000000000000ll; - m.supply.symbol = ramcore_symbol; - m.base.balance.amount = int64_t(_gstate.free_ram()); - m.base.balance.symbol = ram_symbol; - m.quote.balance.amount = system_token_supply.amount / 1000; - m.quote.balance.symbol = core; - }); - - token::open_action open_act{ token_account, { {get_self(), active_permission} } }; - open_act.send( rex_account, core, get_self() ); - } - -} /// eosio.system diff --git a/contracts/eosio.system/src/exchange_state.cpp b/contracts/eosio.system/src/exchange_state.cpp deleted file mode 100644 index 8f9734bc..00000000 --- a/contracts/eosio.system/src/exchange_state.cpp +++ /dev/null @@ -1,110 +0,0 @@ -#include - -#include - -#include - -namespace eosiosystem { - - using eosio::check; - - asset exchange_state::convert_to_exchange( connector& reserve, const asset& payment ) - { - const double S0 = supply.amount; - const double R0 = reserve.balance.amount; - const double dR = payment.amount; - const double F = reserve.weight; - - double dS = S0 * ( std::pow(1. + dR / R0, F) - 1. ); - if ( dS < 0 ) dS = 0; // rounding errors - reserve.balance += payment; - supply.amount += int64_t(dS); - return asset( int64_t(dS), supply.symbol ); - } - - asset exchange_state::convert_from_exchange( connector& reserve, const asset& tokens ) - { - const double R0 = reserve.balance.amount; - const double S0 = supply.amount; - const double dS = -tokens.amount; // dS < 0, tokens are subtracted from supply - const double Fi = double(1) / reserve.weight; - - double dR = R0 * ( std::pow(1. + dS / S0, Fi) - 1. ); // dR < 0 since dS < 0 - if ( dR > 0 ) dR = 0; // rounding errors - reserve.balance.amount -= int64_t(-dR); - supply -= tokens; - return asset( int64_t(-dR), reserve.balance.symbol ); - } - - asset exchange_state::convert( const asset& from, const symbol& to ) - { - const auto& sell_symbol = from.symbol; - const auto& base_symbol = base.balance.symbol; - const auto& quote_symbol = quote.balance.symbol; - check( sell_symbol != to, "cannot convert to the same symbol" ); - - asset out( 0, to ); - if ( sell_symbol == base_symbol && to == quote_symbol ) { - const asset tmp = convert_to_exchange( base, from ); - out = convert_from_exchange( quote, tmp ); - } else if ( sell_symbol == quote_symbol && to == base_symbol ) { - const asset tmp = convert_to_exchange( quote, from ); - out = convert_from_exchange( base, tmp ); - } else { - check( false, "invalid conversion" ); - } - return out; - } - - asset exchange_state::direct_convert( const asset& from, const symbol& to ) - { - const auto& sell_symbol = from.symbol; - const auto& base_symbol = base.balance.symbol; - const auto& quote_symbol = quote.balance.symbol; - check( sell_symbol != to, "cannot convert to the same symbol" ); - - asset out( 0, to ); - if ( sell_symbol == base_symbol && to == quote_symbol ) { - out.amount = get_bancor_output( base.balance.amount, quote.balance.amount, from.amount ); - base.balance += from; - quote.balance -= out; - } else if ( sell_symbol == quote_symbol && to == base_symbol ) { - out.amount = get_bancor_output( quote.balance.amount, base.balance.amount, from.amount ); - quote.balance += from; - base.balance -= out; - } else { - check( false, "invalid conversion" ); - } - return out; - } - - int64_t exchange_state::get_bancor_output( int64_t inp_reserve, - int64_t out_reserve, - int64_t inp ) - { - const double ib = inp_reserve; - const double ob = out_reserve; - const double in = inp; - - int64_t out = int64_t( (in * ob) / (ib + in) ); - - if ( out < 0 ) out = 0; - - return out; - } - - int64_t exchange_state::get_bancor_input( int64_t out_reserve, - int64_t inp_reserve, - int64_t out ) - { - const double ob = out_reserve; - const double ib = inp_reserve; - - int64_t inp = (ib * out) / (ob - out); - - if ( inp < 0 ) inp = 0; - - return inp; - } - -} /// namespace eosiosystem diff --git a/contracts/eosio.system/src/name_bidding.cpp b/contracts/eosio.system/src/name_bidding.cpp deleted file mode 100644 index 4c01f353..00000000 --- a/contracts/eosio.system/src/name_bidding.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include -#include - -#include - -namespace eosiosystem { - - using eosio::current_time_point; - using eosio::token; - - void system_contract::bidname( const name& bidder, const name& newname, const asset& bid ) { - require_auth( bidder ); - check( newname.suffix() == newname, "you can only bid on top-level suffix" ); - - check( (bool)newname, "the empty name is not a valid account name to bid on" ); - check( (newname.value & 0xFull) == 0, "13 character names are not valid account names to bid on" ); - check( (newname.value & 0x1F0ull) == 0, "accounts with 12 character names and no dots can be created without bidding required" ); - check( !is_account( newname ), "account already exists" ); - check( bid.symbol == core_symbol(), "asset must be system token" ); - check( bid.amount > 0, "insufficient bid" ); - token::transfer_action transfer_act{ token_account, { {bidder, active_permission} } }; - transfer_act.send( bidder, names_account, bid, std::string("bid name ")+ newname.to_string() ); - name_bid_table bids(get_self(), get_self().value); - print( name{bidder}, " bid ", bid, " on ", name{newname}, "\n" ); - auto current = bids.find( newname.value ); - if( current == bids.end() ) { - bids.emplace( bidder, [&]( auto& b ) { - b.newname = newname; - b.high_bidder = bidder; - b.high_bid = bid.amount; - b.last_bid_time = current_time_point(); - }); - } else { - check( current->high_bid > 0, "this auction has already closed" ); - check( bid.amount - current->high_bid > (current->high_bid / 10), "must increase bid by 10%" ); - check( current->high_bidder != bidder, "account is already highest bidder" ); - - bid_refund_table refunds_table(get_self(), newname.value); - - auto it = refunds_table.find( current->high_bidder.value ); - if ( it != refunds_table.end() ) { - refunds_table.modify( it, same_payer, [&](auto& r) { - r.amount += asset( current->high_bid, core_symbol() ); - }); - } else { - refunds_table.emplace( bidder, [&](auto& r) { - r.bidder = current->high_bidder; - r.amount = asset( current->high_bid, core_symbol() ); - }); - } - - eosio::transaction t; - t.actions.emplace_back( permission_level{current->high_bidder, active_permission}, - get_self(), "bidrefund"_n, - std::make_tuple( current->high_bidder, newname ) - ); - t.delay_sec = 0; - uint128_t deferred_id = (uint128_t(newname.value) << 64) | current->high_bidder.value; - eosio::cancel_deferred( deferred_id ); - t.send( deferred_id, bidder ); - - bids.modify( current, bidder, [&]( auto& b ) { - b.high_bidder = bidder; - b.high_bid = bid.amount; - b.last_bid_time = current_time_point(); - }); - } - } - - void system_contract::bidrefund( const name& bidder, const name& newname ) { - bid_refund_table refunds_table(get_self(), newname.value); - auto it = refunds_table.find( bidder.value ); - check( it != refunds_table.end(), "refund not found" ); - - token::transfer_action transfer_act{ token_account, { {names_account, active_permission}, {bidder, active_permission} } }; - transfer_act.send( names_account, bidder, asset(it->amount), std::string("refund bid on name ")+(name{newname}).to_string() ); - refunds_table.erase( it ); - } - -} diff --git a/contracts/eosio.system/src/native.cpp b/contracts/eosio.system/src/native.cpp deleted file mode 100644 index df98daab..00000000 --- a/contracts/eosio.system/src/native.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -#include - -namespace eosiosystem { - - void native::onerror( ignore, ignore> ) { - eosio::check( false, "the onerror action cannot be called directly" ); - } - -} diff --git a/contracts/eosio.system/src/powerup.cpp b/contracts/eosio.system/src/powerup.cpp deleted file mode 100644 index 335d9bb2..00000000 --- a/contracts/eosio.system/src/powerup.cpp +++ /dev/null @@ -1,398 +0,0 @@ -#include -#include -#include -#include -#include - -namespace eosiosystem { - -void update_weight(time_point_sec now, powerup_state_resource& res, int64_t& delta_available); - -/** - * @pre now >= res.utilization_timestamp - * @post res.utilization <= new res.adjusted_utilization - * @post if res.utilization < old res.adjusted_utilization, then new res.adjusted_utilization <= old res.adjusted_utilization - * @post if res.utilization >= old res.adjusted_utilization, then new res.adjusted_utilization == res.utilization - */ -void update_utilization(time_point_sec now, powerup_state_resource& res); - -void system_contract::adjust_resources(name payer, name account, symbol core_symbol, int64_t net_delta, - int64_t cpu_delta, bool must_not_be_managed) { - if (!net_delta && !cpu_delta) - return; - - user_resources_table totals_tbl(get_self(), account.value); - auto tot_itr = totals_tbl.find(account.value); - if (tot_itr == totals_tbl.end()) { - tot_itr = totals_tbl.emplace(payer, [&](auto& tot) { - tot.owner = account; - tot.net_weight = asset{ net_delta, core_symbol }; - tot.cpu_weight = asset{ cpu_delta, core_symbol }; - }); - } else { - totals_tbl.modify(tot_itr, same_payer, [&](auto& tot) { - tot.net_weight.amount += net_delta; - tot.cpu_weight.amount += cpu_delta; - }); - } - check(0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth"); - check(0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth"); - - { - bool ram_managed = false; - bool net_managed = false; - bool cpu_managed = false; - - auto voter_itr = _voters.find(account.value); - if (voter_itr != _voters.end()) { - ram_managed = has_field(voter_itr->flags1, voter_info::flags1_fields::ram_managed); - net_managed = has_field(voter_itr->flags1, voter_info::flags1_fields::net_managed); - cpu_managed = has_field(voter_itr->flags1, voter_info::flags1_fields::cpu_managed); - } - - if (must_not_be_managed) - eosio::check(!net_managed && !cpu_managed, "something is managed which shouldn't be"); - - if (!(net_managed && cpu_managed)) { - int64_t ram_bytes, net, cpu; - get_resource_limits(account, ram_bytes, net, cpu); - set_resource_limits( - account, ram_managed ? ram_bytes : std::max(tot_itr->ram_bytes + ram_gift_bytes, ram_bytes), - net_managed ? net : tot_itr->net_weight.amount, cpu_managed ? cpu : tot_itr->cpu_weight.amount); - } - } - - if (tot_itr->is_empty()) { - totals_tbl.erase(tot_itr); - } -} // system_contract::adjust_resources - -void system_contract::process_powerup_queue(time_point_sec now, symbol core_symbol, powerup_state& state, - powerup_order_table& orders, uint32_t max_items, int64_t& net_delta_available, - int64_t& cpu_delta_available) { - update_utilization(now, state.net); - update_utilization(now, state.cpu); - auto idx = orders.get_index<"byexpires"_n>(); - while (max_items--) { - auto it = idx.begin(); - if (it == idx.end() || it->expires > now) - break; - net_delta_available += it->net_weight; - cpu_delta_available += it->cpu_weight; - adjust_resources(get_self(), it->owner, core_symbol, -it->net_weight, -it->cpu_weight); - idx.erase(it); - } - state.net.utilization -= net_delta_available; - state.cpu.utilization -= cpu_delta_available; - update_weight(now, state.net, net_delta_available); - update_weight(now, state.cpu, cpu_delta_available); -} - -void update_weight(time_point_sec now, powerup_state_resource& res, int64_t& delta_available) { - if (now >= res.target_timestamp) { - res.weight_ratio = res.target_weight_ratio; - } else { - res.weight_ratio = res.initial_weight_ratio + // - int128_t(res.target_weight_ratio - res.initial_weight_ratio) * - (now.utc_seconds - res.initial_timestamp.utc_seconds) / - (res.target_timestamp.utc_seconds - res.initial_timestamp.utc_seconds); - } - int64_t new_weight = res.assumed_stake_weight * int128_t(powerup_frac) / res.weight_ratio - res.assumed_stake_weight; - delta_available += new_weight - res.weight; - res.weight = new_weight; -} - -void update_utilization(time_point_sec now, powerup_state_resource& res) { - if (now <= res.utilization_timestamp) return; - - if (res.utilization >= res.adjusted_utilization) { - res.adjusted_utilization = res.utilization; - } else { - int64_t diff = res.adjusted_utilization - res.utilization; - int64_t delta = diff * std::exp(-double(now.utc_seconds - res.utilization_timestamp.utc_seconds) / double(res.decay_secs)); - delta = std::clamp( delta, 0ll, diff); - res.adjusted_utilization = res.utilization + delta; - } - res.utilization_timestamp = now; -} - -void system_contract::cfgpowerup(powerup_config& args) { - require_auth(get_self()); - time_point_sec now = eosio::current_time_point(); - auto core_symbol = get_core_symbol(); - powerup_state_singleton state_sing{ get_self(), 0 }; - auto state = state_sing.get_or_default(); - - eosio::check(eosio::is_account(reserv_account), "eosio.reserv account must first be created"); - - int64_t net_delta_available = 0; - int64_t cpu_delta_available = 0; - if (state_sing.exists()) { - update_utilization(now, state.net); - update_utilization(now, state.cpu); - update_weight(now, state.net, net_delta_available); - update_weight(now, state.cpu, cpu_delta_available); - } else { - state.net.utilization_timestamp = now; - state.cpu.utilization_timestamp = now; - } - - auto is_default_asset = []( const eosio::asset& a ) -> bool { - return a.amount == 0 && a.symbol == symbol{}; - }; - - auto update = [&](auto& state, auto& args) { - if (!args.current_weight_ratio) { - if (state.weight_ratio) { - *args.current_weight_ratio = state.weight_ratio; - } else { - *args.current_weight_ratio = state.initial_weight_ratio; - } - } - - if (!args.target_weight_ratio) { - *args.target_weight_ratio = state.target_weight_ratio; - } - - if (!args.assumed_stake_weight) { - eosio::check(state.assumed_stake_weight != 0, "assumed_stake_weight does not have a default value"); - *args.assumed_stake_weight = state.assumed_stake_weight; - } - - if (*args.current_weight_ratio == *args.target_weight_ratio) { - *args.target_timestamp = now; - } else { - if (!args.target_timestamp) { - eosio::check(state.target_timestamp.utc_seconds != 0, "target_timestamp does not have a default value"); - *args.target_timestamp = state.target_timestamp; - } - eosio::check(*args.target_timestamp > now, "target_timestamp must be in the future"); - } - - if (!args.exponent) { - *args.exponent = state.exponent; - } - - if (!args.decay_secs) { - *args.decay_secs = state.decay_secs; - } - - if (!args.max_price) { - eosio::check(!is_default_asset(state.max_price), "max_price does not have a default value"); - *args.max_price = state.max_price; - } - - if (!args.min_price) { - if (is_default_asset(state.min_price)) { - *args.min_price = *args.max_price; // just to copy symbol of max_price - args.min_price->amount = 0; // min_price has a default of zero. - } else { - *args.min_price = state.min_price; - } - } - - eosio::check(*args.current_weight_ratio > 0, "current_weight_ratio is too small"); - eosio::check(*args.current_weight_ratio <= powerup_frac, "current_weight_ratio is too large"); - eosio::check(*args.target_weight_ratio > 0, "target_weight_ratio is too small"); - eosio::check(*args.target_weight_ratio <= *args.current_weight_ratio, "weight can't grow over time"); - eosio::check(*args.assumed_stake_weight >= 1, - "assumed_stake_weight must be at least 1; a much larger value is recommended"); - eosio::check(*args.assumed_stake_weight * int128_t(powerup_frac) / *args.target_weight_ratio <= - std::numeric_limits::max(), - "assumed_stake_weight/target_weight_ratio is too large"); - eosio::check(*args.exponent >= 1.0, "exponent must be >= 1"); - eosio::check(*args.decay_secs >= 1, "decay_secs must be >= 1"); - eosio::check(args.max_price->symbol == core_symbol, "max_price doesn't match core symbol"); - eosio::check(args.max_price->amount > 0, "max_price must be positive"); - eosio::check(args.min_price->symbol == core_symbol, "min_price doesn't match core symbol"); - eosio::check(args.min_price->amount >= 0, "min_price must be non-negative"); - eosio::check(args.min_price->amount <= args.max_price->amount, "min_price cannot exceed max_price"); - if (*args.exponent == 1.0) { - eosio::check(args.min_price->amount == args.max_price->amount, "min_price and max_price must be the same if the exponent is 1"); - } - - state.assumed_stake_weight = *args.assumed_stake_weight; - state.initial_weight_ratio = *args.current_weight_ratio; - state.target_weight_ratio = *args.target_weight_ratio; - state.initial_timestamp = now; - state.target_timestamp = *args.target_timestamp; - state.exponent = *args.exponent; - state.decay_secs = *args.decay_secs; - state.min_price = *args.min_price; - state.max_price = *args.max_price; - }; - - if (!args.powerup_days) { - *args.powerup_days = state.powerup_days; - } - - if (!args.min_powerup_fee) { - eosio::check(!is_default_asset(state.min_powerup_fee), "min_powerup_fee does not have a default value"); - *args.min_powerup_fee = state.min_powerup_fee; - } - - eosio::check(*args.powerup_days > 0, "powerup_days must be > 0"); - eosio::check(args.min_powerup_fee->symbol == core_symbol, "min_powerup_fee doesn't match core symbol"); - eosio::check(args.min_powerup_fee->amount > 0, "min_powerup_fee must be positive"); - - state.powerup_days = *args.powerup_days; - state.min_powerup_fee = *args.min_powerup_fee; - - update(state.net, args.net); - update(state.cpu, args.cpu); - - update_weight(now, state.net, net_delta_available); - update_weight(now, state.cpu, cpu_delta_available); - eosio::check(state.net.weight >= state.net.utilization, "weight can't shrink below utilization"); - eosio::check(state.cpu.weight >= state.cpu.utilization, "weight can't shrink below utilization"); - state.net.adjusted_utilization = std::min(state.net.adjusted_utilization, state.net.weight); - state.cpu.adjusted_utilization = std::min(state.cpu.adjusted_utilization, state.cpu.weight); - - adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); - state_sing.set(state, get_self()); -} // system_contract::configpower - -/** - * @pre 0 <= state.min_price.amount <= state.max_price.amount - * @pre 0 < state.max_price.amount - * @pre 1.0 <= state.exponent - * @pre 0 <= state.utilization <= state.adjusted_utilization <= state.weight - * @pre 0 <= utilization_increase <= (state.weight - state.utilization) - */ -int64_t calc_powerup_fee(const powerup_state_resource& state, int64_t utilization_increase) { - if( utilization_increase <= 0 ) return 0; - - // Let p(u) = price as a function of the utilization fraction u which is defined for u in [0.0, 1.0]. - // Let f(u) = integral of the price function p(x) from x = 0.0 to x = u, again defined for u in [0.0, 1.0]. - - // In particular we choose f(u) = min_price * u + ((max_price - min_price) / exponent) * (u ^ exponent). - // And so p(u) = min_price + (max_price - min_price) * (u ^ (exponent - 1.0)). - - // Returns f(double(end_utilization)/state.weight) - f(double(start_utilization)/state.weight) which is equivalent to - // the integral of p(x) from x = double(start_utilization)/state.weight to x = double(end_utilization)/state.weight. - // @pre 0 <= start_utilization <= end_utilization <= state.weight - auto price_integral_delta = [&state](int64_t start_utilization, int64_t end_utilization) -> double { - double coefficient = (state.max_price.amount - state.min_price.amount) / state.exponent; - double start_u = double(start_utilization) / state.weight; - double end_u = double(end_utilization) / state.weight; - return state.min_price.amount * end_u - state.min_price.amount * start_u + - coefficient * std::pow(end_u, state.exponent) - coefficient * std::pow(start_u, state.exponent); - }; - - // Returns p(double(utilization)/state.weight). - // @pre 0 <= utilization <= state.weight - auto price_function = [&state](int64_t utilization) -> double { - double price = state.min_price.amount; - // state.exponent >= 1.0, therefore the exponent passed into std::pow is >= 0.0. - // Since the exponent passed into std::pow could be 0.0 and simultaneously so could double(utilization)/state.weight, - // the safest thing to do is handle that as a special case explicitly rather than relying on std::pow to return 1.0 - // instead of triggering a domain error. - double new_exponent = state.exponent - 1.0; - if (new_exponent <= 0.0) { - return state.max_price.amount; - } else { - price += (state.max_price.amount - state.min_price.amount) * std::pow(double(utilization) / state.weight, new_exponent); - } - - return price; - }; - - double fee = 0.0; - int64_t start_utilization = state.utilization; - int64_t end_utilization = start_utilization + utilization_increase; - - if (start_utilization < state.adjusted_utilization) { - fee += price_function(state.adjusted_utilization) * - std::min(utilization_increase, state.adjusted_utilization - start_utilization) / state.weight; - start_utilization = state.adjusted_utilization; - } - - if (start_utilization < end_utilization) { - fee += price_integral_delta(start_utilization, end_utilization); - } - - return std::ceil(fee); -} - -void system_contract::powerupexec(const name& user, uint16_t max) { - require_auth(user); - powerup_state_singleton state_sing{ get_self(), 0 }; - powerup_order_table orders{ get_self(), 0 }; - eosio::check(state_sing.exists(), "powerup hasn't been initialized"); - auto state = state_sing.get(); - time_point_sec now = eosio::current_time_point(); - auto core_symbol = get_core_symbol(); - - int64_t net_delta_available = 0; - int64_t cpu_delta_available = 0; - process_powerup_queue(now, core_symbol, state, orders, max, net_delta_available, cpu_delta_available); - - adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); - state_sing.set(state, get_self()); -} - -void system_contract::powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, - const asset& max_payment) { - require_auth(payer); - powerup_state_singleton state_sing{ get_self(), 0 }; - powerup_order_table orders{ get_self(), 0 }; - eosio::check(state_sing.exists(), "powerup hasn't been initialized"); - auto state = state_sing.get(); - time_point_sec now = eosio::current_time_point(); - auto core_symbol = get_core_symbol(); - eosio::check(max_payment.symbol == core_symbol, "max_payment doesn't match core symbol"); - eosio::check(days == state.powerup_days, "days doesn't match configuration"); - eosio::check(net_frac >= 0, "net_frac can't be negative"); - eosio::check(cpu_frac >= 0, "cpu_frac can't be negative"); - eosio::check(net_frac <= powerup_frac, "net can't be more than 100%"); - eosio::check(cpu_frac <= powerup_frac, "cpu can't be more than 100%"); - - int64_t net_delta_available = 0; - int64_t cpu_delta_available = 0; - process_powerup_queue(now, core_symbol, state, orders, 2, net_delta_available, cpu_delta_available); - - eosio::asset fee{ 0, core_symbol }; - auto process = [&](int64_t frac, int64_t& amount, powerup_state_resource& state) { - if (!frac) - return; - amount = int128_t(frac) * state.weight / powerup_frac; - eosio::check(state.weight, "market doesn't have resources available"); - eosio::check(state.utilization + amount <= state.weight, "market doesn't have enough resources available"); - int64_t f = calc_powerup_fee(state, amount); - eosio::check(f > 0, "calculated fee is below minimum; try powering up with more resources"); - fee.amount += f; - state.utilization += amount; - }; - - int64_t net_amount = 0; - int64_t cpu_amount = 0; - process(net_frac, net_amount, state.net); - process(cpu_frac, cpu_amount, state.cpu); - if (fee > max_payment) { - std::string error_msg = "max_payment is less than calculated fee: "; - error_msg += fee.to_string(); - eosio::check(false, error_msg); - } - eosio::check(fee >= state.min_powerup_fee, "calculated fee is below minimum; try powering up with more resources"); - - orders.emplace(payer, [&](auto& order) { - order.id = orders.available_primary_key(); - order.owner = receiver; - order.net_weight = net_amount; - order.cpu_weight = cpu_amount; - order.expires = now + eosio::days(days); - }); - net_delta_available -= net_amount; - cpu_delta_available -= cpu_amount; - - adjust_resources(payer, receiver, core_symbol, net_amount, cpu_amount, true); - adjust_resources(get_self(), reserv_account, core_symbol, net_delta_available, cpu_delta_available, true); - channel_to_rex(payer, fee, true); - state_sing.set(state, get_self()); - - // inline noop action - powup_results::powupresult_action powupresult_act{ reserv_account, std::vector{ } }; - powupresult_act.send( fee, net_amount, cpu_amount ); -} - -} // namespace eosiosystem diff --git a/contracts/eosio.system/src/powerup.results.cpp b/contracts/eosio.system/src/powerup.results.cpp deleted file mode 100644 index 2be2e981..00000000 --- a/contracts/eosio.system/src/powerup.results.cpp +++ /dev/null @@ -1,5 +0,0 @@ -#include - -void powup_results::powupresult( const asset& fee, const int64_t powup_net_weight, const int64_t powup_cpu_weight ) { } - -extern "C" void apply( uint64_t, uint64_t, uint64_t ) { } diff --git a/contracts/eosio.system/src/producer_pay.cpp b/contracts/eosio.system/src/producer_pay.cpp deleted file mode 100644 index 4db2f774..00000000 --- a/contracts/eosio.system/src/producer_pay.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include - -namespace eosiosystem { - - using eosio::current_time_point; - using eosio::microseconds; - using eosio::token; - - void system_contract::onblock( ignore ) { - using namespace eosio; - - require_auth(get_self()); - - block_timestamp timestamp; - name producer; - _ds >> timestamp >> producer; - - // _gstate2.last_block_num is not used anywhere in the system contract code anymore. - // Although this field is deprecated, we will continue updating it for now until the last_block_num field - // is eventually completely removed, at which point this line can be removed. - _gstate2.last_block_num = timestamp; - - /** until activation, no new rewards are paid */ - if( _gstate.thresh_activated_stake_time == time_point() ) - return; - - if( _gstate.last_pervote_bucket_fill == time_point() ) /// start the presses - _gstate.last_pervote_bucket_fill = current_time_point(); - - - /** - * At startup the initial producer may not be one that is registered / elected - * and therefore there may be no producer object for them. - */ - auto prod = _producers.find( producer.value ); - if ( prod != _producers.end() ) { - _gstate.total_unpaid_blocks++; - _producers.modify( prod, same_payer, [&](auto& p ) { - p.unpaid_blocks++; - }); - } - - /// only update block producers once every minute, block_timestamp is in half seconds - if( timestamp.slot - _gstate.last_producer_schedule_update.slot > 120 ) { - update_elected_producers( timestamp ); - - if( (timestamp.slot - _gstate.last_name_close.slot) > blocks_per_day ) { - name_bid_table bids(get_self(), get_self().value); - auto idx = bids.get_index<"highbid"_n>(); - auto highest = idx.lower_bound( std::numeric_limits::max()/2 ); - if( highest != idx.end() && - highest->high_bid > 0 && - (current_time_point() - highest->last_bid_time) > microseconds(useconds_per_day) && - _gstate.thresh_activated_stake_time > time_point() && - (current_time_point() - _gstate.thresh_activated_stake_time) > microseconds(14 * useconds_per_day) - ) { - _gstate.last_name_close = timestamp; - channel_namebid_to_rex( highest->high_bid ); - idx.modify( highest, same_payer, [&]( auto& b ){ - b.high_bid = -b.high_bid; - }); - } - } - } - } - - void system_contract::claimrewards( const name& owner ) { - require_auth( owner ); - - const auto& prod = _producers.get( owner.value ); - check( prod.active(), "producer does not have an active key" ); - - check( _gstate.thresh_activated_stake_time != time_point(), - "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)" ); - - const auto ct = current_time_point(); - - check( ct - prod.last_claim_time > microseconds(useconds_per_day), "already claimed rewards within past day" ); - - const asset token_supply = token::get_supply(token_account, core_symbol().code() ); - const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count(); - - if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) { - double additional_inflation = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year); - check( additional_inflation <= double(std::numeric_limits::max() - ((1ll << 10) - 1)), - "overflow in calculating new tokens to be issued; inflation rate is too high" ); - int64_t new_tokens = (additional_inflation < 0.0) ? 0 : static_cast(additional_inflation); - - int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor; - int64_t to_savings = new_tokens - to_producers; - int64_t to_per_block_pay = (to_producers * uint128_t(pay_factor_precision)) / _gstate4.votepay_factor; - int64_t to_per_vote_pay = to_producers - to_per_block_pay; - - if( new_tokens > 0 ) { - { - token::issue_action issue_act{ token_account, { {get_self(), active_permission} } }; - issue_act.send( get_self(), asset(new_tokens, core_symbol()), "issue tokens for producer pay and savings" ); - } - { - token::transfer_action transfer_act{ token_account, { {get_self(), active_permission} } }; - if( to_savings > 0 ) { - transfer_act.send( get_self(), saving_account, asset(to_savings, core_symbol()), "unallocated inflation" ); - } - if( to_per_block_pay > 0 ) { - transfer_act.send( get_self(), bpay_account, asset(to_per_block_pay, core_symbol()), "fund per-block bucket" ); - } - if( to_per_vote_pay > 0 ) { - transfer_act.send( get_self(), vpay_account, asset(to_per_vote_pay, core_symbol()), "fund per-vote bucket" ); - } - } - } - - _gstate.pervote_bucket += to_per_vote_pay; - _gstate.perblock_bucket += to_per_block_pay; - _gstate.last_pervote_bucket_fill = ct; - } - - auto prod2 = _producers2.find( owner.value ); - - /// New metric to be used in pervote pay calculation. Instead of vote weight ratio, we combine vote weight and - /// time duration the vote weight has been held into one metric. - const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); - - bool crossed_threshold = (last_claim_plus_3days <= ct); - bool updated_after_threshold = true; - if ( prod2 != _producers2.end() ) { - updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); - } else { - prod2 = _producers2.emplace( owner, [&]( producer_info2& info ) { - info.owner = owner; - info.last_votepay_share_update = ct; - }); - } - - // Note: updated_after_threshold implies cross_threshold (except if claiming rewards when the producers2 table row did not exist). - // The exception leads to updated_after_threshold to be treated as true regardless of whether the threshold was crossed. - // This is okay because in this case the producer will not get paid anything either way. - // In fact it is desired behavior because the producers votes need to be counted in the global total_producer_votepay_share for the first time. - - int64_t producer_per_block_pay = 0; - if( _gstate.total_unpaid_blocks > 0 ) { - producer_per_block_pay = (_gstate.perblock_bucket * prod.unpaid_blocks) / _gstate.total_unpaid_blocks; - } - - double new_votepay_share = update_producer_votepay_share( prod2, - ct, - updated_after_threshold ? 0.0 : prod.total_votes, - true // reset votepay_share to zero after updating - ); - - int64_t producer_per_vote_pay = 0; - if( _gstate2.revision > 0 ) { - double total_votepay_share = update_total_votepay_share( ct ); - if( total_votepay_share > 0 && !crossed_threshold ) { - producer_per_vote_pay = int64_t((new_votepay_share * _gstate.pervote_bucket) / total_votepay_share); - if( producer_per_vote_pay > _gstate.pervote_bucket ) - producer_per_vote_pay = _gstate.pervote_bucket; - } - } else { - if( _gstate.total_producer_vote_weight > 0 ) { - producer_per_vote_pay = int64_t((_gstate.pervote_bucket * prod.total_votes) / _gstate.total_producer_vote_weight); - } - } - - if( producer_per_vote_pay < min_pervote_daily_pay ) { - producer_per_vote_pay = 0; - } - - _gstate.pervote_bucket -= producer_per_vote_pay; - _gstate.perblock_bucket -= producer_per_block_pay; - _gstate.total_unpaid_blocks -= prod.unpaid_blocks; - - update_total_votepay_share( ct, -new_votepay_share, (updated_after_threshold ? prod.total_votes : 0.0) ); - - _producers.modify( prod, same_payer, [&](auto& p) { - p.last_claim_time = ct; - p.unpaid_blocks = 0; - }); - - if ( producer_per_block_pay > 0 ) { - token::transfer_action transfer_act{ token_account, { {bpay_account, active_permission}, {owner, active_permission} } }; - transfer_act.send( bpay_account, owner, asset(producer_per_block_pay, core_symbol()), "producer block pay" ); - } - if ( producer_per_vote_pay > 0 ) { - token::transfer_action transfer_act{ token_account, { {vpay_account, active_permission}, {owner, active_permission} } }; - transfer_act.send( vpay_account, owner, asset(producer_per_vote_pay, core_symbol()), "producer vote pay" ); - } - } - -} //namespace eosiosystem diff --git a/contracts/eosio.system/src/rex.cpp b/contracts/eosio.system/src/rex.cpp deleted file mode 100644 index dee9c0ab..00000000 --- a/contracts/eosio.system/src/rex.cpp +++ /dev/null @@ -1,1221 +0,0 @@ -#include -#include -#include - -namespace eosiosystem { - - using eosio::current_time_point; - using eosio::token; - using eosio::seconds; - - void system_contract::deposit( const name& owner, const asset& amount ) - { - require_auth( owner ); - - check( amount.symbol == core_symbol(), "must deposit core token" ); - check( 0 < amount.amount, "must deposit a positive amount" ); - // inline transfer from owner's token balance - { - token::transfer_action transfer_act{ token_account, { owner, active_permission } }; - transfer_act.send( owner, rex_account, amount, "deposit to REX fund" ); - } - transfer_to_fund( owner, amount ); - } - - void system_contract::withdraw( const name& owner, const asset& amount ) - { - require_auth( owner ); - - check( amount.symbol == core_symbol(), "must withdraw core token" ); - check( 0 < amount.amount, "must withdraw a positive amount" ); - update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - transfer_from_fund( owner, amount ); - // inline transfer to owner's token balance - { - token::transfer_action transfer_act{ token_account, { rex_account, active_permission } }; - transfer_act.send( rex_account, owner, amount, "withdraw from REX fund" ); - } - } - - void system_contract::buyrex( const name& from, const asset& amount ) - { - require_auth( from ); - - check( amount.symbol == core_symbol(), "asset must be core token" ); - check( 0 < amount.amount, "must use positive amount" ); - check_voting_requirement( from ); - transfer_from_fund( from, amount ); - const asset rex_received = add_to_rex_pool( amount ); - const asset delta_rex_stake = add_to_rex_balance( from, amount, rex_received ); - runrex(2); - update_rex_account( from, asset( 0, core_symbol() ), delta_rex_stake ); - // dummy action added so that amount of REX tokens purchased shows up in action trace - rex_results::buyresult_action buyrex_act( rex_account, std::vector{ } ); - buyrex_act.send( rex_received ); - } - - void system_contract::unstaketorex( const name& owner, const name& receiver, const asset& from_net, const asset& from_cpu ) - { - require_auth( owner ); - - check( from_net.symbol == core_symbol() && from_cpu.symbol == core_symbol(), "asset must be core token" ); - check( (0 <= from_net.amount) && (0 <= from_cpu.amount) && (0 < from_net.amount || 0 < from_cpu.amount), - "must unstake a positive amount to buy rex" ); - check_voting_requirement( owner ); - - { - del_bandwidth_table dbw_table( get_self(), owner.value ); - auto del_itr = dbw_table.require_find( receiver.value, "delegated bandwidth record does not exist" ); - check( from_net.amount <= del_itr->net_weight.amount, "amount exceeds tokens staked for net"); - check( from_cpu.amount <= del_itr->cpu_weight.amount, "amount exceeds tokens staked for cpu"); - dbw_table.modify( del_itr, same_payer, [&]( delegated_bandwidth& dbw ) { - dbw.net_weight.amount -= from_net.amount; - dbw.cpu_weight.amount -= from_cpu.amount; - }); - if ( del_itr->is_empty() ) { - dbw_table.erase( del_itr ); - } - } - - update_resource_limits( name(0), receiver, -from_net.amount, -from_cpu.amount ); - - const asset payment = from_net + from_cpu; - // inline transfer from stake_account to rex_account - { - token::transfer_action transfer_act{ token_account, { stake_account, active_permission } }; - transfer_act.send( stake_account, rex_account, payment, "buy REX with staked tokens" ); - } - const asset rex_received = add_to_rex_pool( payment ); - add_to_rex_balance( owner, payment, rex_received ); - runrex(2); - update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ), true ); - // dummy action added so that amount of REX tokens purchased shows up in action trace - rex_results::buyresult_action buyrex_act( rex_account, std::vector{ } ); - buyrex_act.send( rex_received ); - } - - void system_contract::sellrex( const name& from, const asset& rex ) - { - require_auth( from ); - - runrex(2); - - auto bitr = _rexbalance.require_find( from.value, "user must first buyrex" ); - check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, - "asset must be a positive amount of (REX, 4)" ); - process_rex_maturities( bitr ); - check( rex.amount <= bitr->matured_rex, "insufficient available rex" ); - - const auto current_order = fill_rex_order( bitr, rex ); - if ( current_order.success && current_order.proceeds.amount == 0 ) { - check( false, "proceeds are negligible" ); - } - asset pending_sell_order = update_rex_account( from, current_order.proceeds, current_order.stake_change ); - if ( !current_order.success ) { - if ( from == "b1"_n ) { - check( false, "b1 sellrex orders should not be queued" ); - } - /** - * REX order couldn't be filled and is added to queue. - * If account already has an open order, requested rex is added to existing order. - */ - auto oitr = _rexorders.find( from.value ); - if ( oitr == _rexorders.end() ) { - oitr = _rexorders.emplace( from, [&]( auto& order ) { - order.owner = from; - order.rex_requested = rex; - order.is_open = true; - order.proceeds = asset( 0, core_symbol() ); - order.stake_change = asset( 0, core_symbol() ); - order.order_time = current_time_point(); - }); - } else { - _rexorders.modify( oitr, same_payer, [&]( auto& order ) { - order.rex_requested.amount += rex.amount; - }); - } - pending_sell_order.amount = oitr->rex_requested.amount; - } - check( pending_sell_order.amount <= bitr->matured_rex, "insufficient funds for current and scheduled orders" ); - // dummy action added so that sell order proceeds show up in action trace - if ( current_order.success ) { - rex_results::sellresult_action sellrex_act( rex_account, std::vector{ } ); - sellrex_act.send( current_order.proceeds ); - } - } - - void system_contract::cnclrexorder( const name& owner ) - { - require_auth( owner ); - - auto itr = _rexorders.require_find( owner.value, "no sellrex order is scheduled" ); - check( itr->is_open, "sellrex order has been filled and cannot be canceled" ); - _rexorders.erase( itr ); - } - - void system_contract::rentcpu( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) - { - require_auth( from ); - - rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); - int64_t rented_tokens = rent_rex( cpu_loans, from, receiver, loan_payment, loan_fund ); - update_resource_limits( from, receiver, 0, rented_tokens ); - } - - void system_contract::rentnet( const name& from, const name& receiver, const asset& loan_payment, const asset& loan_fund ) - { - require_auth( from ); - - rex_net_loan_table net_loans( get_self(), get_self().value ); - int64_t rented_tokens = rent_rex( net_loans, from, receiver, loan_payment, loan_fund ); - update_resource_limits( from, receiver, rented_tokens, 0 ); - } - - void system_contract::fundcpuloan( const name& from, uint64_t loan_num, const asset& payment ) - { - require_auth( from ); - - rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); - fund_rex_loan( cpu_loans, from, loan_num, payment ); - } - - void system_contract::fundnetloan( const name& from, uint64_t loan_num, const asset& payment ) - { - require_auth( from ); - - rex_net_loan_table net_loans( get_self(), get_self().value ); - fund_rex_loan( net_loans, from, loan_num, payment ); - } - - void system_contract::defcpuloan( const name& from, uint64_t loan_num, const asset& amount ) - { - require_auth( from ); - - rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); - defund_rex_loan( cpu_loans, from, loan_num, amount ); - } - - void system_contract::defnetloan( const name& from, uint64_t loan_num, const asset& amount ) - { - require_auth( from ); - - rex_net_loan_table net_loans( get_self(), get_self().value ); - defund_rex_loan( net_loans, from, loan_num, amount ); - } - - void system_contract::updaterex( const name& owner ) - { - require_auth( owner ); - - runrex(2); - - auto itr = _rexbalance.require_find( owner.value, "account has no REX balance" ); - const asset init_stake = itr->vote_stake; - - auto rexp_itr = _rexpool.begin(); - const int64_t total_rex = rexp_itr->total_rex.amount; - const int64_t total_lendable = rexp_itr->total_lendable.amount; - const int64_t rex_balance = itr->rex_balance.amount; - - asset current_stake( 0, core_symbol() ); - if ( total_rex > 0 ) { - current_stake.amount = ( uint128_t(rex_balance) * total_lendable ) / total_rex; - } - _rexbalance.modify( itr, same_payer, [&]( auto& rb ) { - rb.vote_stake = current_stake; - }); - - update_rex_account( owner, asset( 0, core_symbol() ), current_stake - init_stake, true ); - process_rex_maturities( itr ); - } - - void system_contract::setrex( const asset& balance ) - { - require_auth( "eosio"_n ); - - check( balance.amount > 0, "balance must be set to have a positive amount" ); - check( balance.symbol == core_symbol(), "balance symbol must be core symbol" ); - check( rex_system_initialized(), "rex system is not initialized" ); - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { - pool.total_rent = balance; - }); - } - - void system_contract::rexexec( const name& user, uint16_t max ) - { - require_auth( user ); - - runrex( max ); - } - - void system_contract::consolidate( const name& owner ) - { - require_auth( owner ); - - runrex(2); - - auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); - asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - consolidate_rex_balance( bitr, rex_in_sell_order ); - } - - void system_contract::mvtosavings( const name& owner, const asset& rex ) - { - require_auth( owner ); - - runrex(2); - - auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); - check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); - const asset rex_in_sell_order = update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - const int64_t rex_in_savings = read_rex_savings( bitr ); - check( rex.amount + rex_in_sell_order.amount + rex_in_savings <= bitr->rex_balance.amount, - "insufficient REX balance" ); - process_rex_maturities( bitr ); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - int64_t moved_rex = 0; - while ( !rb.rex_maturities.empty() && moved_rex < rex.amount) { - const int64_t drex = std::min( rex.amount - moved_rex, rb.rex_maturities.back().second ); - rb.rex_maturities.back().second -= drex; - moved_rex += drex; - if ( rb.rex_maturities.back().second == 0 ) { - rb.rex_maturities.pop_back(); - } - } - if ( moved_rex < rex.amount ) { - const int64_t drex = rex.amount - moved_rex; - rb.matured_rex -= drex; - moved_rex += drex; - check( rex_in_sell_order.amount <= rb.matured_rex, "logic error in mvtosavings" ); - } - check( moved_rex == rex.amount, "programmer error in mvtosavings" ); - }); - put_rex_savings( bitr, rex_in_savings + rex.amount ); - } - - void system_contract::mvfrsavings( const name& owner, const asset& rex ) - { - require_auth( owner ); - - runrex(2); - - auto bitr = _rexbalance.require_find( owner.value, "account has no REX balance" ); - check( rex.amount > 0 && rex.symbol == bitr->rex_balance.symbol, "asset must be a positive amount of (REX, 4)" ); - const int64_t rex_in_savings = read_rex_savings( bitr ); - check( rex.amount <= rex_in_savings, "insufficient REX in savings" ); - process_rex_maturities( bitr ); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - const time_point_sec maturity = get_rex_maturity(); - if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { - rb.rex_maturities.back().second += rex.amount; - } else { - rb.rex_maturities.emplace_back( maturity, rex.amount ); - } - }); - put_rex_savings( bitr, rex_in_savings - rex.amount ); - update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - } - - void system_contract::closerex( const name& owner ) - { - require_auth( owner ); - - if ( rex_system_initialized() ) - runrex(2); - - update_rex_account( owner, asset( 0, core_symbol() ), asset( 0, core_symbol() ) ); - - /// check for any outstanding loans or rex fund - { - rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); - auto cpu_idx = cpu_loans.get_index<"byowner"_n>(); - bool no_outstanding_cpu_loans = ( cpu_idx.find( owner.value ) == cpu_idx.end() ); - - rex_net_loan_table net_loans( get_self(), get_self().value ); - auto net_idx = net_loans.get_index<"byowner"_n>(); - bool no_outstanding_net_loans = ( net_idx.find( owner.value ) == net_idx.end() ); - - auto fund_itr = _rexfunds.find( owner.value ); - bool no_outstanding_rex_fund = ( fund_itr != _rexfunds.end() ) && ( fund_itr->balance.amount == 0 ); - - if ( no_outstanding_cpu_loans && no_outstanding_net_loans && no_outstanding_rex_fund ) { - _rexfunds.erase( fund_itr ); - } - } - - /// check for remaining rex balance - { - auto rex_itr = _rexbalance.find( owner.value ); - if ( rex_itr != _rexbalance.end() ) { - check( rex_itr->rex_balance.amount == 0, "account has remaining REX balance, must sell first"); - _rexbalance.erase( rex_itr ); - } - } - } - - /** - * @brief Updates account NET and CPU resource limits - * - * @param from - account charged for RAM if there is a need - * @param receiver - account whose resource limits are updated - * @param delta_net - change in NET bandwidth limit - * @param delta_cpu - change in CPU bandwidth limit - */ - void system_contract::update_resource_limits( const name& from, const name& receiver, int64_t delta_net, int64_t delta_cpu ) - { - if ( delta_cpu == 0 && delta_net == 0 ) { // nothing to update - return; - } - - user_resources_table totals_tbl( get_self(), receiver.value ); - auto tot_itr = totals_tbl.find( receiver.value ); - if ( tot_itr == totals_tbl.end() ) { - check( 0 <= delta_net && 0 <= delta_cpu, "logic error, should not occur"); - tot_itr = totals_tbl.emplace( from, [&]( auto& tot ) { - tot.owner = receiver; - tot.net_weight = asset( delta_net, core_symbol() ); - tot.cpu_weight = asset( delta_cpu, core_symbol() ); - }); - } else { - totals_tbl.modify( tot_itr, same_payer, [&]( auto& tot ) { - tot.net_weight.amount += delta_net; - tot.cpu_weight.amount += delta_cpu; - }); - } - check( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" ); - check( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" ); - - { - bool net_managed = false; - bool cpu_managed = false; - - auto voter_itr = _voters.find( receiver.value ); - if( voter_itr != _voters.end() ) { - net_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::net_managed ); - cpu_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::cpu_managed ); - } - - if( !(net_managed && cpu_managed) ) { - int64_t ram_bytes = 0, net = 0, cpu = 0; - get_resource_limits( receiver, ram_bytes, net, cpu ); - - set_resource_limits( receiver, - ram_bytes, - net_managed ? net : tot_itr->net_weight.amount, - cpu_managed ? cpu : tot_itr->cpu_weight.amount ); - } - } - - if ( tot_itr->is_empty() ) { - totals_tbl.erase( tot_itr ); - } - } - - /** - * @brief Checks if account satisfies voting requirement (voting for a proxy or 21 producers) - * for buying REX - * - * @param owner - account buying or already holding REX tokens - * @err_msg - error message - */ - void system_contract::check_voting_requirement( const name& owner, const char* error_msg )const - { - auto vitr = _voters.find( owner.value ); - check( vitr != _voters.end() && ( vitr->proxy || 21 <= vitr->producers.size() ), error_msg ); - } - - /** - * @brief Checks if CPU and Network loans are available - * - * Loans are available if 1) REX pool lendable balance is nonempty, and 2) there are no - * unfilled sellrex orders. - */ - bool system_contract::rex_loans_available()const - { - if ( !rex_available() ) { - return false; - } else { - if ( _rexorders.begin() == _rexorders.end() ) { - return true; // no outstanding sellrex orders - } else { - auto idx = _rexorders.get_index<"bytime"_n>(); - return !idx.begin()->is_open; // no outstanding unfilled sellrex orders - } - } - } - - /** - * @brief Updates rex_pool balances upon creating a new loan or renewing an existing one - * - * @param payment - loan fee paid - * @param rented_tokens - amount of tokens to be staked to loan receiver - * @param new_loan - flag indicating whether the loan is new or being renewed - */ - void system_contract::add_loan_to_rex_pool( const asset& payment, int64_t rented_tokens, bool new_loan ) - { - add_to_rex_return_pool( payment ); - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rt ) { - // add payment to total_rent - rt.total_rent.amount += payment.amount; - // move rented_tokens from total_unlent to total_lent - rt.total_unlent.amount -= rented_tokens; - rt.total_lent.amount += rented_tokens; - // increment loan_num if a new loan is being created - if ( new_loan ) { - rt.loan_num++; - } - }); - } - - /** - * @brief Updates rex_pool balances upon closing an expired loan - * - * @param loan - loan to be closed - */ - void system_contract::remove_loan_from_rex_pool( const rex_loan& loan ) - { - const auto& pool = _rexpool.begin(); - const int64_t delta_total_rent = exchange_state::get_bancor_output( pool->total_unlent.amount, - pool->total_rent.amount, - loan.total_staked.amount ); - _rexpool.modify( pool, same_payer, [&]( auto& rt ) { - // deduct calculated delta_total_rent from total_rent - rt.total_rent.amount -= delta_total_rent; - // move rented tokens from total_lent to total_unlent - rt.total_unlent.amount += loan.total_staked.amount; - rt.total_lent.amount -= loan.total_staked.amount; - rt.total_lendable.amount = rt.total_unlent.amount + rt.total_lent.amount; - }); - } - - /** - * @brief Updates the fields of an existing loan that is being renewed - */ - template - int64_t system_contract::update_renewed_loan( Index& idx, const Iterator& itr, int64_t rented_tokens ) - { - int64_t delta_stake = rented_tokens - itr->total_staked.amount; - idx.modify ( itr, same_payer, [&]( auto& loan ) { - loan.total_staked.amount = rented_tokens; - loan.expiration += eosio::days(30); - loan.balance.amount -= loan.payment.amount; - }); - return delta_stake; - } - - /** - * @brief Performs maintenance operations on expired NET and CPU loans and sellrex orders - * - * @param max - maximum number of each of the three categories to be processed - */ - void system_contract::runrex( uint16_t max ) - { - check( rex_system_initialized(), "rex system not initialized yet" ); - - update_rex_pool(); - - const auto& pool = _rexpool.begin(); - - auto process_expired_loan = [&]( auto& idx, const auto& itr ) -> std::pair { - /// update rex_pool in order to delete existing loan - remove_loan_from_rex_pool( *itr ); - bool delete_loan = false; - int64_t delta_stake = 0; - /// calculate rented tokens at current price - int64_t rented_tokens = exchange_state::get_bancor_output( pool->total_rent.amount, - pool->total_unlent.amount, - itr->payment.amount ); - /// conditions for loan renewal - bool renew_loan = itr->payment <= itr->balance /// loan has sufficient balance - && itr->payment.amount < rented_tokens /// loan has favorable return - && rex_loans_available(); /// no pending sell orders - if ( renew_loan ) { - /// update rex_pool in order to account for renewed loan - add_loan_to_rex_pool( itr->payment, rented_tokens, false ); - /// update renewed loan fields - delta_stake = update_renewed_loan( idx, itr, rented_tokens ); - } else { - delete_loan = true; - delta_stake = -( itr->total_staked.amount ); - /// refund "from" account if the closed loan balance is positive - if ( itr->balance.amount > 0 ) { - transfer_to_fund( itr->from, itr->balance ); - } - } - - return { delete_loan, delta_stake }; - }; - - /// transfer from eosio.names to eosio.rex - if ( pool->namebid_proceeds.amount > 0 ) { - channel_to_rex( names_account, pool->namebid_proceeds ); - _rexpool.modify( pool, same_payer, [&]( auto& rt ) { - rt.namebid_proceeds.amount = 0; - }); - } - - /// process cpu loans - { - rex_cpu_loan_table cpu_loans( get_self(), get_self().value ); - auto cpu_idx = cpu_loans.get_index<"byexpr"_n>(); - for ( uint16_t i = 0; i < max; ++i ) { - auto itr = cpu_idx.begin(); - if ( itr == cpu_idx.end() || itr->expiration > current_time_point() ) break; - - auto result = process_expired_loan( cpu_idx, itr ); - if ( result.second != 0 ) - update_resource_limits( itr->from, itr->receiver, 0, result.second ); - - if ( result.first ) - cpu_idx.erase( itr ); - } - } - - /// process net loans - { - rex_net_loan_table net_loans( get_self(), get_self().value ); - auto net_idx = net_loans.get_index<"byexpr"_n>(); - for ( uint16_t i = 0; i < max; ++i ) { - auto itr = net_idx.begin(); - if ( itr == net_idx.end() || itr->expiration > current_time_point() ) break; - - auto result = process_expired_loan( net_idx, itr ); - if ( result.second != 0 ) - update_resource_limits( itr->from, itr->receiver, result.second, 0 ); - - if ( result.first ) - net_idx.erase( itr ); - } - } - - /// process sellrex orders - if ( _rexorders.begin() != _rexorders.end() ) { - auto idx = _rexorders.get_index<"bytime"_n>(); - auto oitr = idx.begin(); - for ( uint16_t i = 0; i < max; ++i ) { - if ( oitr == idx.end() || !oitr->is_open ) break; - auto next = oitr; - ++next; - auto bitr = _rexbalance.find( oitr->owner.value ); - if ( bitr != _rexbalance.end() ) { // should always be true - auto result = fill_rex_order( bitr, oitr->rex_requested ); - if ( result.success ) { - const name order_owner = oitr->owner; - idx.modify( oitr, same_payer, [&]( auto& order ) { - order.proceeds.amount = result.proceeds.amount; - order.stake_change.amount = result.stake_change.amount; - order.close(); - }); - /// send dummy action to show owner and proceeds of filled sellrex order - rex_results::orderresult_action order_act( rex_account, std::vector{ } ); - order_act.send( order_owner, result.proceeds ); - } - } - oitr = next; - } - } - - } - - /** - * @brief Adds returns from the REX return pool to the REX pool - */ - void system_contract::update_rex_pool() - { - auto get_elapsed_intervals = [&]( const time_point_sec& t1, const time_point_sec& t0 ) -> uint32_t { - return ( t1.sec_since_epoch() - t0.sec_since_epoch() ) / rex_return_pool::dist_interval; - }; - - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); - const time_point_sec effective_time{cts - cts % rex_return_pool::dist_interval}; - - const auto ret_pool_elem = _rexretpool.begin(); - const auto ret_buckets_elem = _rexretbuckets.begin(); - - if ( ret_pool_elem == _rexretpool.end() || effective_time <= ret_pool_elem->last_dist_time ) { - return; - } - - const int64_t current_rate = ret_pool_elem->current_rate_of_increase; - const uint32_t elapsed_intervals = get_elapsed_intervals( effective_time, ret_pool_elem->last_dist_time ); - int64_t change_estimate = current_rate * elapsed_intervals; - - { - const bool new_return_bucket = ret_pool_elem->pending_bucket_time <= effective_time; - int64_t new_bucket_rate = 0; - time_point_sec new_bucket_time = time_point_sec::min(); - _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - if ( new_return_bucket ) { - int64_t remainder = rp.pending_bucket_proceeds % rex_return_pool::total_intervals; - new_bucket_rate = ( rp.pending_bucket_proceeds - remainder ) / rex_return_pool::total_intervals; - new_bucket_time = rp.pending_bucket_time; - rp.current_rate_of_increase += new_bucket_rate; - change_estimate += remainder + new_bucket_rate * get_elapsed_intervals( effective_time, rp.pending_bucket_time ); - rp.pending_bucket_proceeds = 0; - rp.pending_bucket_time = time_point_sec::maximum(); - if ( new_bucket_time < rp.oldest_bucket_time ) { - rp.oldest_bucket_time = new_bucket_time; - } - } - rp.proceeds -= change_estimate; - rp.last_dist_time = effective_time; - }); - - if ( new_return_bucket ) { - _rexretbuckets.modify( ret_buckets_elem, same_payer, [&]( auto& rb ) { - rb.return_buckets[new_bucket_time] = new_bucket_rate; - }); - } - } - - const time_point_sec time_threshold = effective_time - seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval); - if ( ret_pool_elem->oldest_bucket_time <= time_threshold ) { - int64_t expired_rate = 0; - int64_t surplus = 0; - _rexretbuckets.modify( ret_buckets_elem, same_payer, [&]( auto& rb ) { - auto& return_buckets = rb.return_buckets; - auto iter = return_buckets.begin(); - while ( iter != return_buckets.end() && iter->first <= time_threshold ) { - auto next = iter; - ++next; - const uint32_t overtime = get_elapsed_intervals( effective_time, - iter->first + seconds(rex_return_pool::total_intervals * rex_return_pool::dist_interval) ); - surplus += iter->second * overtime; - expired_rate += iter->second; - return_buckets.erase(iter); - iter = next; - } - }); - - _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - if ( !ret_buckets_elem->return_buckets.empty() ) { - rp.oldest_bucket_time = ret_buckets_elem->return_buckets.begin()->first; - } else { - rp.oldest_bucket_time = time_point_sec::min(); - } - if ( expired_rate > 0) { - rp.current_rate_of_increase -= expired_rate; - } - if ( surplus > 0 ) { - change_estimate -= surplus; - rp.proceeds += surplus; - } - }); - } - - if ( change_estimate > 0 && ret_pool_elem->proceeds < 0 ) { - _rexretpool.modify( ret_pool_elem, same_payer, [&]( auto& rp ) { - change_estimate += rp.proceeds; - rp.proceeds = 0; - }); - } - - if ( change_estimate > 0 ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& pool ) { - pool.total_unlent.amount += change_estimate; - pool.total_lendable = pool.total_unlent + pool.total_lent; - }); - } - } - - template - int64_t system_contract::rent_rex( T& table, const name& from, const name& receiver, const asset& payment, const asset& fund ) - { - runrex(2); - - check( rex_loans_available(), "rex loans are currently not available" ); - check( payment.symbol == core_symbol() && fund.symbol == core_symbol(), "must use core token" ); - check( 0 < payment.amount && 0 <= fund.amount, "must use positive asset amount" ); - - transfer_from_fund( from, payment + fund ); - - const auto& pool = _rexpool.begin(); /// already checked that _rexpool.begin() != _rexpool.end() in rex_loans_available() - - int64_t rented_tokens = exchange_state::get_bancor_output( pool->total_rent.amount, - pool->total_unlent.amount, - payment.amount ); - check( payment.amount < rented_tokens, "loan price does not favor renting" ); - add_loan_to_rex_pool( payment, rented_tokens, true ); - - table.emplace( from, [&]( auto& c ) { - c.from = from; - c.receiver = receiver; - c.payment = payment; - c.balance = fund; - c.total_staked = asset( rented_tokens, core_symbol() ); - c.expiration = current_time_point() + eosio::days(30); - c.loan_num = pool->loan_num; - }); - - rex_results::rentresult_action rentresult_act{ rex_account, std::vector{ } }; - rentresult_act.send( asset{ rented_tokens, core_symbol() } ); - return rented_tokens; - } - - /** - * @brief Processes a sellrex order and returns object containing the results - * - * Processes an incoming or already scheduled sellrex order. If REX pool has enough core - * tokens not frozen in loans, order is filled. In this case, REX pool totals, user rex_balance - * and user vote_stake are updated. However, this function does not update user voting power. The - * function returns success flag, order proceeds, and vote stake delta. These are used later in a - * different function to complete order processing, i.e. transfer proceeds to user REX fund and - * update user vote weight. - * - * @param bitr - iterator pointing to rex_balance database record - * @param rex - amount of rex to be sold - * - * @return rex_order_outcome - a struct containing success flag, order proceeds, and resultant - * vote stake change - */ - rex_order_outcome system_contract::fill_rex_order( const rex_balance_table::const_iterator& bitr, const asset& rex ) - { - auto rexitr = _rexpool.begin(); - const int64_t S0 = rexitr->total_lendable.amount; - const int64_t R0 = rexitr->total_rex.amount; - const int64_t p = (uint128_t(rex.amount) * S0) / R0; - const int64_t R1 = R0 - rex.amount; - const int64_t S1 = S0 - p; - asset proceeds( p, core_symbol() ); - asset stake_change( 0, core_symbol() ); - bool success = false; - - const int64_t unlent_lower_bound = rexitr->total_lent.amount / 10; - const int64_t available_unlent = rexitr->total_unlent.amount - unlent_lower_bound; // available_unlent <= 0 is possible - if ( proceeds.amount <= available_unlent ) { - const int64_t init_vote_stake_amount = bitr->vote_stake.amount; - const int64_t current_stake_value = ( uint128_t(bitr->rex_balance.amount) * S0 ) / R0; - _rexpool.modify( rexitr, same_payer, [&]( auto& rt ) { - rt.total_rex.amount = R1; - rt.total_lendable.amount = S1; - rt.total_unlent.amount = rt.total_lendable.amount - rt.total_lent.amount; - }); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount = current_stake_value - proceeds.amount; - rb.rex_balance.amount -= rex.amount; - rb.matured_rex -= rex.amount; - }); - stake_change.amount = bitr->vote_stake.amount - init_vote_stake_amount; - success = true; - } else { - proceeds.amount = 0; - } - - return { success, proceeds, stake_change }; - } - - template - void system_contract::fund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& payment ) - { - check( payment.symbol == core_symbol(), "must use core token" ); - transfer_from_fund( from, payment ); - auto itr = table.require_find( loan_num, "loan not found" ); - check( itr->from == from, "user must be loan creator" ); - check( itr->expiration > current_time_point(), "loan has already expired" ); - table.modify( itr, same_payer, [&]( auto& loan ) { - loan.balance.amount += payment.amount; - }); - } - - template - void system_contract::defund_rex_loan( T& table, const name& from, uint64_t loan_num, const asset& amount ) - { - check( amount.symbol == core_symbol(), "must use core token" ); - auto itr = table.require_find( loan_num, "loan not found" ); - check( itr->from == from, "user must be loan creator" ); - check( itr->expiration > current_time_point(), "loan has already expired" ); - check( itr->balance >= amount, "insufficent loan balance" ); - table.modify( itr, same_payer, [&]( auto& loan ) { - loan.balance.amount -= amount.amount; - }); - transfer_to_fund( from, amount ); - } - - /** - * @brief Transfers tokens from owner REX fund - * - * @pre - owner REX fund has sufficient balance - * - * @param owner - owner account name - * @param amount - tokens to be transfered out of REX fund - */ - void system_contract::transfer_from_fund( const name& owner, const asset& amount ) - { - check( 0 < amount.amount && amount.symbol == core_symbol(), "must transfer positive amount from REX fund" ); - auto itr = _rexfunds.require_find( owner.value, "must deposit to REX fund first" ); - check( amount <= itr->balance, "insufficient funds" ); - _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { - fund.balance.amount -= amount.amount; - }); - } - - /** - * @brief Transfers tokens to owner REX fund - * - * @param owner - owner account name - * @param amount - tokens to be transfered to REX fund - */ - void system_contract::transfer_to_fund( const name& owner, const asset& amount ) - { - check( 0 < amount.amount && amount.symbol == core_symbol(), "must transfer positive amount to REX fund" ); - auto itr = _rexfunds.find( owner.value ); - if ( itr == _rexfunds.end() ) { - _rexfunds.emplace( owner, [&]( auto& fund ) { - fund.owner = owner; - fund.balance = amount; - }); - } else { - _rexfunds.modify( itr, same_payer, [&]( auto& fund ) { - fund.balance.amount += amount.amount; - }); - } - } - - /** - * @brief Processes owner filled sellrex order and updates vote weight - * - * Checks if user has a scheduled sellrex order that has been filled, completes its processing, - * and deletes it. Processing entails transfering proceeds to user REX fund and updating user - * vote weight. Additional proceeds and stake change can be passed as arguments. This function - * is called only by actions pushed by owner. - * - * @param owner - owner account name - * @param proceeds - additional proceeds to be transfered to owner REX fund - * @param delta_stake - additional stake to be added to owner vote weight - * @param force_vote_update - if true, vote weight is updated even if vote stake didn't change - * - * @return asset - REX amount of owner unfilled sell order if one exists - */ - asset system_contract::update_rex_account( const name& owner, const asset& proceeds, const asset& delta_stake, bool force_vote_update ) - { - asset to_fund( proceeds ); - asset to_stake( delta_stake ); - asset rex_in_sell_order( 0, rex_symbol ); - auto itr = _rexorders.find( owner.value ); - if ( itr != _rexorders.end() ) { - if ( itr->is_open ) { - rex_in_sell_order.amount = itr->rex_requested.amount; - } else { - to_fund.amount += itr->proceeds.amount; - to_stake.amount += itr->stake_change.amount; - _rexorders.erase( itr ); - } - } - - if ( to_fund.amount > 0 ) - transfer_to_fund( owner, to_fund ); - if ( force_vote_update || to_stake.amount != 0 ) - update_voting_power( owner, to_stake ); - - return rex_in_sell_order; - } - - /** - * @brief Channels system fees to REX pool - * - * @param from - account from which asset is transfered to REX pool - * @param amount - amount of tokens to be transfered - * @param required - if true, asserts when the system is not configured to channel fees into REX - */ - void system_contract::channel_to_rex( const name& from, const asset& amount, bool required ) - { -#if CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX - if ( rex_available() ) { - add_to_rex_return_pool( amount ); - // inline transfer to rex_account - token::transfer_action transfer_act{ token_account, { from, active_permission } }; - transfer_act.send( from, rex_account, amount, - std::string("transfer from ") + from.to_string() + " to eosio.rex" ); - return; - } -#endif - eosio::check( !required, "can't channel fees to rex" ); - } - - /** - * @brief Updates namebid proceeds to be transfered to REX pool - * - * @param highest_bid - highest bidding amount of closed namebid - */ - void system_contract::channel_namebid_to_rex( const int64_t highest_bid ) - { -#if CHANNEL_RAM_AND_NAMEBID_FEES_TO_REX - if ( rex_available() ) { - _rexpool.modify( _rexpool.begin(), same_payer, [&]( auto& rp ) { - rp.namebid_proceeds.amount += highest_bid; - }); - } -#endif - } - - /** - * @brief Calculates maturity time of purchased REX tokens which is 4 days from end - * of the day UTC - * - * @return time_point_sec - */ - time_point_sec system_contract::get_rex_maturity() - { - const uint32_t num_of_maturity_buckets = 5; - static const uint32_t now = current_time_point().sec_since_epoch(); - static const uint32_t r = now % seconds_per_day; - static const time_point_sec rms{ now - r + num_of_maturity_buckets * seconds_per_day }; - return rms; - } - - /** - * @brief Updates REX owner maturity buckets - * - * @param bitr - iterator pointing to rex_balance object - */ - void system_contract::process_rex_maturities( const rex_balance_table::const_iterator& bitr ) - { - const time_point_sec now = current_time_point(); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - while ( !rb.rex_maturities.empty() && rb.rex_maturities.front().first <= now ) { - rb.matured_rex += rb.rex_maturities.front().second; - rb.rex_maturities.pop_front(); - } - }); - } - - /** - * @brief Consolidates REX maturity buckets into one - * - * @param bitr - iterator pointing to rex_balance object - * @param rex_in_sell_order - REX tokens in owner unfilled sell order, if one exists - */ - void system_contract::consolidate_rex_balance( const rex_balance_table::const_iterator& bitr, - const asset& rex_in_sell_order ) - { - const int64_t rex_in_savings = read_rex_savings( bitr ); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - int64_t total = rb.matured_rex - rex_in_sell_order.amount; - rb.matured_rex = rex_in_sell_order.amount; - while ( !rb.rex_maturities.empty() ) { - total += rb.rex_maturities.front().second; - rb.rex_maturities.pop_front(); - } - if ( total > 0 ) { - rb.rex_maturities.emplace_back( get_rex_maturity(), total ); - } - }); - put_rex_savings( bitr, rex_in_savings ); - } - - /** - * @brief Updates REX pool balances upon REX purchase - * - * @param payment - amount of core tokens paid - * - * @return asset - calculated amount of REX tokens purchased - */ - asset system_contract::add_to_rex_pool( const asset& payment ) - { - /** - * If CORE_SYMBOL is (EOS,4), maximum supply is 10^10 tokens (10 billion tokens), i.e., maximum amount - * of indivisible units is 10^14. rex_ratio = 10^4 sets the upper bound on (REX,4) indivisible units to - * 10^18 and that is within the maximum allowable amount field of asset type which is set to 2^62 - * (approximately 4.6 * 10^18). For a different CORE_SYMBOL, and in order for maximum (REX,4) amount not - * to exceed that limit, maximum amount of indivisible units cannot be set to a value larger than 4 * 10^14. - * If precision of CORE_SYMBOL is 4, that corresponds to a maximum supply of 40 billion tokens. - */ - const int64_t rex_ratio = 10000; - const asset init_total_rent( 20'000'0000, core_symbol() ); /// base balance prevents renting profitably until at least a minimum number of core_symbol() is made available - asset rex_received( 0, rex_symbol ); - auto itr = _rexpool.begin(); - if ( !rex_system_initialized() ) { - /// initialize REX pool - _rexpool.emplace( get_self(), [&]( auto& rp ) { - rex_received.amount = payment.amount * rex_ratio; - rp.total_lendable = payment; - rp.total_lent = asset( 0, core_symbol() ); - rp.total_unlent = rp.total_lendable - rp.total_lent; - rp.total_rent = init_total_rent; - rp.total_rex = rex_received; - rp.namebid_proceeds = asset( 0, core_symbol() ); - }); - } else if ( !rex_available() ) { /// should be a rare corner case, REX pool is initialized but empty - _rexpool.modify( itr, same_payer, [&]( auto& rp ) { - rex_received.amount = payment.amount * rex_ratio; - rp.total_lendable.amount = payment.amount; - rp.total_lent.amount = 0; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - rp.total_rent.amount = init_total_rent.amount; - rp.total_rex.amount = rex_received.amount; - }); - } else { - /// total_lendable > 0 if total_rex > 0 except in a rare case and due to rounding errors - check( itr->total_lendable.amount > 0, "lendable REX pool is empty" ); - const int64_t S0 = itr->total_lendable.amount; - const int64_t S1 = S0 + payment.amount; - const int64_t R0 = itr->total_rex.amount; - const int64_t R1 = (uint128_t(S1) * R0) / S0; - rex_received.amount = R1 - R0; - _rexpool.modify( itr, same_payer, [&]( auto& rp ) { - rp.total_lendable.amount = S1; - rp.total_rex.amount = R1; - rp.total_unlent.amount = rp.total_lendable.amount - rp.total_lent.amount; - check( rp.total_unlent.amount >= 0, "programmer error, this should never go negative" ); - }); - } - - return rex_received; - } - - /** - * @brief Adds an amount of core tokens to the REX return pool - * - * @param fee - amount to be added - */ - void system_contract::add_to_rex_return_pool( const asset& fee ) - { - update_rex_pool(); - if ( fee.amount <= 0 ) { - return; - } - - const time_point_sec ct = current_time_point(); - const uint32_t cts = ct.sec_since_epoch(); - const uint32_t bucket_interval = rex_return_pool::hours_per_bucket * seconds_per_hour; - const time_point_sec effective_time{cts - cts % bucket_interval + bucket_interval}; - const auto return_pool_elem = _rexretpool.begin(); - if ( return_pool_elem == _rexretpool.end() ) { - _rexretpool.emplace( get_self(), [&]( auto& rp ) { - rp.last_dist_time = effective_time; - rp.pending_bucket_proceeds = fee.amount; - rp.pending_bucket_time = effective_time; - rp.proceeds = fee.amount; - }); - _rexretbuckets.emplace( get_self(), [&]( auto& rb ) { } ); - } else { - _rexretpool.modify( return_pool_elem, same_payer, [&]( auto& rp ) { - rp.pending_bucket_proceeds += fee.amount; - rp.proceeds += fee.amount; - if ( rp.pending_bucket_time == time_point_sec::maximum() ) { - rp.pending_bucket_time = effective_time; - } - }); - } - } - - /** - * @brief Updates owner REX balance upon buying REX tokens - * - * @param owner - account name of REX owner - * @param payment - amount core tokens paid to buy REX - * @param rex_received - amount of purchased REX tokens - * - * @return asset - change in owner REX vote stake - */ - asset system_contract::add_to_rex_balance( const name& owner, const asset& payment, const asset& rex_received ) - { - asset init_rex_stake( 0, core_symbol() ); - asset current_rex_stake( 0, core_symbol() ); - auto bitr = _rexbalance.find( owner.value ); - if ( bitr == _rexbalance.end() ) { - bitr = _rexbalance.emplace( owner, [&]( auto& rb ) { - rb.owner = owner; - rb.vote_stake = payment; - rb.rex_balance = rex_received; - }); - current_rex_stake.amount = payment.amount; - } else { - init_rex_stake.amount = bitr->vote_stake.amount; - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.rex_balance.amount += rex_received.amount; - rb.vote_stake.amount = ( uint128_t(rb.rex_balance.amount) * _rexpool.begin()->total_lendable.amount ) - / _rexpool.begin()->total_rex.amount; - }); - current_rex_stake.amount = bitr->vote_stake.amount; - } - - const int64_t rex_in_savings = read_rex_savings( bitr ); - process_rex_maturities( bitr ); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - const time_point_sec maturity = get_rex_maturity(); - if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == maturity ) { - rb.rex_maturities.back().second += rex_received.amount; - } else { - rb.rex_maturities.emplace_back( maturity, rex_received.amount ); - } - }); - put_rex_savings( bitr, rex_in_savings ); - return current_rex_stake - init_rex_stake; - } - - /** - * @brief Reads amount of REX in savings bucket and removes the bucket from maturities - * - * Reads and (temporarily) removes REX savings bucket from REX maturities in order to - * allow uniform processing of remaining buckets as savings is a special case. This - * function is used in conjunction with put_rex_savings. - * - * @param bitr - iterator pointing to rex_balance object - * - * @return int64_t - amount of REX in savings bucket - */ - int64_t system_contract::read_rex_savings( const rex_balance_table::const_iterator& bitr ) - { - int64_t rex_in_savings = 0; - static const time_point_sec end_of_days = time_point_sec::maximum(); - if ( !bitr->rex_maturities.empty() && bitr->rex_maturities.back().first == end_of_days ) { - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rex_in_savings = rb.rex_maturities.back().second; - rb.rex_maturities.pop_back(); - }); - } - return rex_in_savings; - } - - /** - * @brief Adds a specified REX amount to savings bucket - * - * @param bitr - iterator pointing to rex_balance object - * @param rex - amount of REX to be added - */ - void system_contract::put_rex_savings( const rex_balance_table::const_iterator& bitr, int64_t rex ) - { - if ( rex == 0 ) return; - static const time_point_sec end_of_days = time_point_sec::maximum(); - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - if ( !rb.rex_maturities.empty() && rb.rex_maturities.back().first == end_of_days ) { - rb.rex_maturities.back().second += rex; - } else { - rb.rex_maturities.emplace_back( end_of_days, rex ); - } - }); - } - - /** - * @brief Updates voter REX vote stake to the current value of REX tokens held - * - * @param voter - account name of voter - */ - void system_contract::update_rex_stake( const name& voter ) - { - int64_t delta_stake = 0; - auto bitr = _rexbalance.find( voter.value ); - if ( bitr != _rexbalance.end() && rex_available() ) { - asset init_vote_stake = bitr->vote_stake; - asset current_vote_stake( 0, core_symbol() ); - current_vote_stake.amount = ( uint128_t(bitr->rex_balance.amount) * _rexpool.begin()->total_lendable.amount ) - / _rexpool.begin()->total_rex.amount; - _rexbalance.modify( bitr, same_payer, [&]( auto& rb ) { - rb.vote_stake.amount = current_vote_stake.amount; - }); - delta_stake = current_vote_stake.amount - init_vote_stake.amount; - } - - if ( delta_stake != 0 ) { - auto vitr = _voters.find( voter.value ); - if ( vitr != _voters.end() ) { - _voters.modify( vitr, same_payer, [&]( auto& vinfo ) { - vinfo.staked += delta_stake; - }); - } - } - } - -}; /// namespace eosiosystem diff --git a/contracts/eosio.system/src/rex.results.cpp b/contracts/eosio.system/src/rex.results.cpp deleted file mode 100644 index 1aabca02..00000000 --- a/contracts/eosio.system/src/rex.results.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -void rex_results::buyresult( const asset& rex_received ) { } - -void rex_results::sellresult( const asset& proceeds ) { } - -void rex_results::orderresult( const name& owner, const asset& proceeds ) { } - -void rex_results::rentresult( const asset& rented_tokens ) { } - -extern "C" void apply( uint64_t, uint64_t, uint64_t ) { } diff --git a/contracts/eosio.system/src/voting.cpp b/contracts/eosio.system/src/voting.cpp deleted file mode 100644 index 53bb2987..00000000 --- a/contracts/eosio.system/src/voting.cpp +++ /dev/null @@ -1,415 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -namespace eosiosystem { - - using eosio::const_mem_fun; - using eosio::current_time_point; - using eosio::indexed_by; - using eosio::microseconds; - using eosio::singleton; - - void system_contract::register_producer( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { - auto prod = _producers.find( producer.value ); - const auto ct = current_time_point(); - - eosio::public_key producer_key{}; - - std::visit( [&](auto&& auth ) { - if( auth.keys.size() == 1 ) { - // if the producer_authority consists of a single key, use that key in the legacy producer_key field - producer_key = auth.keys[0].key; - } - }, producer_authority ); - - if ( prod != _producers.end() ) { - _producers.modify( prod, producer, [&]( producer_info& info ){ - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; - info.producer_authority.emplace( producer_authority ); - if ( info.last_claim_time == time_point() ) - info.last_claim_time = ct; - }); - - auto prod2 = _producers2.find( producer.value ); - if ( prod2 == _producers2.end() ) { - _producers2.emplace( producer, [&]( producer_info2& info ){ - info.owner = producer; - info.last_votepay_share_update = ct; - }); - update_total_votepay_share( ct, 0.0, prod->total_votes ); - // When introducing the producer2 table row for the first time, the producer's votes must also be accounted for in the global total_producer_votepay_share at the same time. - } - } else { - _producers.emplace( producer, [&]( producer_info& info ){ - info.owner = producer; - info.total_votes = 0; - info.producer_key = producer_key; - info.is_active = true; - info.url = url; - info.location = location; - info.last_claim_time = ct; - info.producer_authority.emplace( producer_authority ); - }); - _producers2.emplace( producer, [&]( producer_info2& info ){ - info.owner = producer; - info.last_votepay_share_update = ct; - }); - } - - } - - void system_contract::regproducer( const name& producer, const eosio::public_key& producer_key, const std::string& url, uint16_t location ) { - require_auth( producer ); - check( url.size() < 512, "url too long" ); - - register_producer( producer, convert_to_block_signing_authority( producer_key ), url, location ); - } - - void system_contract::regproducer2( const name& producer, const eosio::block_signing_authority& producer_authority, const std::string& url, uint16_t location ) { - require_auth( producer ); - check( url.size() < 512, "url too long" ); - - std::visit( [&](auto&& auth ) { - check( auth.is_valid(), "invalid producer authority" ); - }, producer_authority ); - - register_producer( producer, producer_authority, url, location ); - } - - void system_contract::unregprod( const name& producer ) { - require_auth( producer ); - - const auto& prod = _producers.get( producer.value, "producer not found" ); - _producers.modify( prod, same_payer, [&]( producer_info& info ){ - info.deactivate(); - }); - } - - void system_contract::update_elected_producers( const block_timestamp& block_time ) { - _gstate.last_producer_schedule_update = block_time; - - auto idx = _producers.get_index<"prototalvote"_n>(); - - using value_type = std::pair; - std::vector< value_type > top_producers; - top_producers.reserve(21); - - for( auto it = idx.cbegin(); it != idx.cend() && top_producers.size() < 21 && 0 < it->total_votes && it->active(); ++it ) { - top_producers.emplace_back( - eosio::producer_authority{ - .producer_name = it->owner, - .authority = it->get_producer_authority() - }, - it->location - ); - } - - if( top_producers.size() == 0 || top_producers.size() < _gstate.last_producer_schedule_size ) { - return; - } - - std::sort( top_producers.begin(), top_producers.end(), []( const value_type& lhs, const value_type& rhs ) { - return lhs.first.producer_name < rhs.first.producer_name; // sort by producer name - // return lhs.second < rhs.second; // sort by location - } ); - - std::vector producers; - - producers.reserve(top_producers.size()); - for( auto& item : top_producers ) - producers.push_back( std::move(item.first) ); - - if( set_proposed_producers( producers ) >= 0 ) { - _gstate.last_producer_schedule_size = static_cast( top_producers.size() ); - } - } - - double stake2vote( int64_t staked ) { - /// TODO subtract 2080 brings the large numbers closer to this decade - double weight = int64_t( (current_time_point().sec_since_epoch() - (block_timestamp::block_timestamp_epoch / 1000)) / (seconds_per_day * 7) ) / double( 52 ); - return double(staked) * std::pow( 2, weight ); - } - - double system_contract::update_total_votepay_share( const time_point& ct, - double additional_shares_delta, - double shares_rate_delta ) - { - double delta_total_votepay_share = 0.0; - if( ct > _gstate3.last_vpay_state_update ) { - delta_total_votepay_share = _gstate3.total_vpay_share_change_rate - * double( (ct - _gstate3.last_vpay_state_update).count() / 1E6 ); - } - - delta_total_votepay_share += additional_shares_delta; - if( delta_total_votepay_share < 0 && _gstate2.total_producer_votepay_share < -delta_total_votepay_share ) { - _gstate2.total_producer_votepay_share = 0.0; - } else { - _gstate2.total_producer_votepay_share += delta_total_votepay_share; - } - - if( shares_rate_delta < 0 && _gstate3.total_vpay_share_change_rate < -shares_rate_delta ) { - _gstate3.total_vpay_share_change_rate = 0.0; - } else { - _gstate3.total_vpay_share_change_rate += shares_rate_delta; - } - - _gstate3.last_vpay_state_update = ct; - - return _gstate2.total_producer_votepay_share; - } - - double system_contract::update_producer_votepay_share( const producers_table2::const_iterator& prod_itr, - const time_point& ct, - double shares_rate, - bool reset_to_zero ) - { - double delta_votepay_share = 0.0; - if( shares_rate > 0.0 && ct > prod_itr->last_votepay_share_update ) { - delta_votepay_share = shares_rate * double( (ct - prod_itr->last_votepay_share_update).count() / 1E6 ); // cannot be negative - } - - double new_votepay_share = prod_itr->votepay_share + delta_votepay_share; - _producers2.modify( prod_itr, same_payer, [&](auto& p) { - if( reset_to_zero ) - p.votepay_share = 0.0; - else - p.votepay_share = new_votepay_share; - - p.last_votepay_share_update = ct; - } ); - - return new_votepay_share; - } - - void system_contract::voteproducer( const name& voter_name, const name& proxy, const std::vector& producers ) { - require_auth( voter_name ); - vote_stake_updater( voter_name ); - update_votes( voter_name, proxy, producers, true ); - auto rex_itr = _rexbalance.find( voter_name.value ); - if( rex_itr != _rexbalance.end() && rex_itr->rex_balance.amount > 0 ) { - check_voting_requirement( voter_name, "voter holding REX tokens must vote for at least 21 producers or for a proxy" ); - } - } - - void system_contract::update_votes( const name& voter_name, const name& proxy, const std::vector& producers, bool voting ) { - //validate input - if ( proxy ) { - check( producers.size() == 0, "cannot vote for producers and proxy at same time" ); - check( voter_name != proxy, "cannot proxy to self" ); - } else { - check( producers.size() <= 30, "attempt to vote for too many producers" ); - for( size_t i = 1; i < producers.size(); ++i ) { - check( producers[i-1] < producers[i], "producer votes must be unique and sorted" ); - } - } - - auto voter = _voters.find( voter_name.value ); - check( voter != _voters.end(), "user must stake before they can vote" ); /// staking creates voter object - check( !proxy || !voter->is_proxy, "account registered as a proxy is not allowed to use a proxy" ); - - /** - * The first time someone votes we calculate and set last_vote_weight. Since they cannot unstake until - * after the chain has been activated, we can use last_vote_weight to determine that this is - * their first vote and should consider their stake activated. - */ - if( _gstate.thresh_activated_stake_time == time_point() && voter->last_vote_weight <= 0.0 ) { - _gstate.total_activated_stake += voter->staked; - if( _gstate.total_activated_stake >= min_activated_stake ) { - _gstate.thresh_activated_stake_time = current_time_point(); - } - } - - auto new_vote_weight = stake2vote( voter->staked ); - if( voter->is_proxy ) { - new_vote_weight += voter->proxied_vote_weight; - } - - std::map > producer_deltas; - if ( voter->last_vote_weight > 0 ) { - if( voter->proxy ) { - auto old_proxy = _voters.find( voter->proxy.value ); - check( old_proxy != _voters.end(), "old proxy not found" ); //data corruption - _voters.modify( old_proxy, same_payer, [&]( auto& vp ) { - vp.proxied_vote_weight -= voter->last_vote_weight; - }); - propagate_weight_change( *old_proxy ); - } else { - for( const auto& p : voter->producers ) { - auto& d = producer_deltas[p]; - d.first -= voter->last_vote_weight; - d.second = false; - } - } - } - - if( proxy ) { - auto new_proxy = _voters.find( proxy.value ); - check( new_proxy != _voters.end(), "invalid proxy specified" ); //if ( !voting ) { data corruption } else { wrong vote } - check( !voting || new_proxy->is_proxy, "proxy not found" ); - if ( new_vote_weight >= 0 ) { - _voters.modify( new_proxy, same_payer, [&]( auto& vp ) { - vp.proxied_vote_weight += new_vote_weight; - }); - propagate_weight_change( *new_proxy ); - } - } else { - if( new_vote_weight >= 0 ) { - for( const auto& p : producers ) { - auto& d = producer_deltas[p]; - d.first += new_vote_weight; - d.second = true; - } - } - } - - const auto ct = current_time_point(); - double delta_change_rate = 0.0; - double total_inactive_vpay_share = 0.0; - for( const auto& pd : producer_deltas ) { - auto pitr = _producers.find( pd.first.value ); - if( pitr != _producers.end() ) { - if( voting && !pitr->active() && pd.second.second /* from new set */ ) { - check( false, ( "producer " + pitr->owner.to_string() + " is not currently registered" ).data() ); - } - double init_total_votes = pitr->total_votes; - _producers.modify( pitr, same_payer, [&]( auto& p ) { - p.total_votes += pd.second.first; - if ( p.total_votes < 0 ) { // floating point arithmetics can give small negative numbers - p.total_votes = 0; - } - _gstate.total_producer_vote_weight += pd.second.first; - //check( p.total_votes >= 0, "something bad happened" ); - }); - auto prod2 = _producers2.find( pd.first.value ); - if( prod2 != _producers2.end() ) { - const auto last_claim_plus_3days = pitr->last_claim_time + microseconds(3 * useconds_per_day); - bool crossed_threshold = (last_claim_plus_3days <= ct); - bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); - // Note: updated_after_threshold implies cross_threshold - - double new_votepay_share = update_producer_votepay_share( prod2, - ct, - updated_after_threshold ? 0.0 : init_total_votes, - crossed_threshold && !updated_after_threshold // only reset votepay_share once after threshold - ); - - if( !crossed_threshold ) { - delta_change_rate += pd.second.first; - } else if( !updated_after_threshold ) { - total_inactive_vpay_share += new_votepay_share; - delta_change_rate -= init_total_votes; - } - } - } else { - if( pd.second.second ) { - check( false, ( "producer " + pd.first.to_string() + " is not registered" ).data() ); - } - } - } - - update_total_votepay_share( ct, -total_inactive_vpay_share, delta_change_rate ); - - _voters.modify( voter, same_payer, [&]( auto& av ) { - av.last_vote_weight = new_vote_weight; - av.producers = producers; - av.proxy = proxy; - }); - } - - void system_contract::regproxy( const name& proxy, bool isproxy ) { - require_auth( proxy ); - - auto pitr = _voters.find( proxy.value ); - if ( pitr != _voters.end() ) { - check( isproxy != pitr->is_proxy, "action has no effect" ); - check( !isproxy || !pitr->proxy, "account that uses a proxy is not allowed to become a proxy" ); - _voters.modify( pitr, same_payer, [&]( auto& p ) { - p.is_proxy = isproxy; - }); - propagate_weight_change( *pitr ); - } else { - _voters.emplace( proxy, [&]( auto& p ) { - p.owner = proxy; - p.is_proxy = isproxy; - }); - } - } - - void system_contract::propagate_weight_change( const voter_info& voter ) { - check( !voter.proxy || !voter.is_proxy, "account registered as a proxy is not allowed to use a proxy" ); - double new_weight = stake2vote( voter.staked ); - if ( voter.is_proxy ) { - new_weight += voter.proxied_vote_weight; - } - - /// don't propagate small changes (1 ~= epsilon) - if ( fabs( new_weight - voter.last_vote_weight ) > 1 ) { - if ( voter.proxy ) { - auto& proxy = _voters.get( voter.proxy.value, "proxy not found" ); //data corruption - _voters.modify( proxy, same_payer, [&]( auto& p ) { - p.proxied_vote_weight += new_weight - voter.last_vote_weight; - } - ); - propagate_weight_change( proxy ); - } else { - auto delta = new_weight - voter.last_vote_weight; - const auto ct = current_time_point(); - double delta_change_rate = 0; - double total_inactive_vpay_share = 0; - for ( auto acnt : voter.producers ) { - auto& prod = _producers.get( acnt.value, "producer not found" ); //data corruption - const double init_total_votes = prod.total_votes; - _producers.modify( prod, same_payer, [&]( auto& p ) { - p.total_votes += delta; - _gstate.total_producer_vote_weight += delta; - }); - auto prod2 = _producers2.find( acnt.value ); - if ( prod2 != _producers2.end() ) { - const auto last_claim_plus_3days = prod.last_claim_time + microseconds(3 * useconds_per_day); - bool crossed_threshold = (last_claim_plus_3days <= ct); - bool updated_after_threshold = (last_claim_plus_3days <= prod2->last_votepay_share_update); - // Note: updated_after_threshold implies cross_threshold - - double new_votepay_share = update_producer_votepay_share( prod2, - ct, - updated_after_threshold ? 0.0 : init_total_votes, - crossed_threshold && !updated_after_threshold // only reset votepay_share once after threshold - ); - - if( !crossed_threshold ) { - delta_change_rate += delta; - } else if( !updated_after_threshold ) { - total_inactive_vpay_share += new_votepay_share; - delta_change_rate -= init_total_votes; - } - } - } - - update_total_votepay_share( ct, -total_inactive_vpay_share, delta_change_rate ); - } - } - _voters.modify( voter, same_payer, [&]( auto& v ) { - v.last_vote_weight = new_weight; - } - ); - } - -} /// namespace eosiosystem diff --git a/contracts/eosio.wrap/CMakeLists.txt b/contracts/eosio.wrap/CMakeLists.txt deleted file mode 100644 index 27d42919..00000000 --- a/contracts/eosio.wrap/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -add_contract(eosio.wrap eosio.wrap ${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.wrap.cpp) - -target_include_directories(eosio.wrap - PUBLIC - ${CMAKE_CURRENT_SOURCE_DIR}/include) - -set_target_properties(eosio.wrap - PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") - -configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/ricardian/eosio.wrap.contracts.md.in ${CMAKE_CURRENT_BINARY_DIR}/ricardian/eosio.wrap.contracts.md @ONLY ) - -target_compile_options( eosio.wrap PUBLIC -R${CMAKE_CURRENT_SOURCE_DIR}/ricardian -R${CMAKE_CURRENT_BINARY_DIR}/ricardian ) diff --git a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp b/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp deleted file mode 100644 index c272c8e2..00000000 --- a/contracts/eosio.wrap/include/eosio.wrap/eosio.wrap.hpp +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once - -#include -#include -#include - -namespace eosio { - /** - * The `eosio.wrap` system contract allows block producers to bypass authorization checks or run privileged actions with 15/21 producer approval and thus simplifies block producers superuser actions. It also makes these actions easier to audit. - * - * It does not give block producers any additional powers or privileges that do not already exist within the EOSIO based blockchains. As it is implemented, in an EOSIO based blockchain, 15/21 block producers can change an account's permissions or modify an account's contract code if they decided it is beneficial for the blockchain and community. However, the current method is opaque and leaves undesirable side effects on specific system accounts, and thus the `eosio.wrap `contract solves this matter by providing an easier method of executing important governance actions. - * - * The only action implemented by the `eosio.wrap` system contract is the `exec` action. This action allows for execution of a transaction, which is passed to the `exec` method in the form of a packed transaction in json format via the 'trx' parameter and the `executer` account that executes the transaction. The same `executer` account will also be used to pay the RAM and CPU fees needed to execute the transaction. - */ - class [[eosio::contract("eosio.wrap")]] wrap : public contract { - public: - using contract::contract; - - /** - * Execute action. - * - * Execute a transaction while bypassing regular authorization checks. - * - * Preconditions: - * - Requires authorization of eosio.wrap which needs to be a privileged account. - * - * Postconditions: - * - Deferred transaction RAM usage is billed to 'executer' * - * - * @param executer - account executing the transaction, - * @param trx - the transaction to be executed. - */ - [[eosio::action]] - void exec( ignore executer, ignore trx ); - - using exec_action = eosio::action_wrapper<"exec"_n, &wrap::exec>; - }; -} /// namespace eosio diff --git a/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in b/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in deleted file mode 100644 index 8077a347..00000000 --- a/contracts/eosio.wrap/ricardian/eosio.wrap.contracts.md.in +++ /dev/null @@ -1,13 +0,0 @@ -

exec

- ---- -spec_version: "0.2.0" -title: Privileged Execute -summary: '{{nowrap executer}} executes a transaction while bypassing authority checks' -icon: @ICON_BASE_URL@/@ADMIN_ICON_URI@ ---- - -{{executer}} executes the following transaction while bypassing authority checks: -{{to_json trx}} - -{{$action.account}} must also authorize this action. diff --git a/contracts/eosio.wrap/src/eosio.wrap.cpp b/contracts/eosio.wrap/src/eosio.wrap.cpp deleted file mode 100644 index 12056bf1..00000000 --- a/contracts/eosio.wrap/src/eosio.wrap.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include - -namespace eosio { - -void wrap::exec( ignore, ignore ) { - require_auth( get_self() ); - - name executer; - _ds >> executer; - - require_auth( executer ); - - send_deferred( (uint128_t(executer.value) << 64) | (uint64_t)current_time_point().time_since_epoch().count(), executer, _ds.pos(), _ds.remaining() ); -} - -} /// namespace eosio diff --git a/contracts/icons/account.png b/contracts/icons/account.png deleted file mode 100644 index 7686587824ac663ffb79f3ee30d06821a26e6c26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3795 zcmV;^4lMDBP)FWRNVR=Q&5~o{vsUi=0WccP1Vhp^+L0T^e&dJn!l764_-HuYO5T=qXAcLELol_v$~S}Q8pmFg=} zws|p=(DG>jWQadlt#Wp-$_blc5U@+c7i(!~KQ8ld2?PiLMt&lErRA0vJYAS zSVZjD(&q@j#MEGxcK{&Q*omd%&06G~)u05`04RDYyz^C_)B>vnwE)n&-}b-5i$O5C zD*e`8ivX~_!qOsh2-*ha0LXzlnCzDiDh3m#KLAd2 zh(~cz_}m)+L%_c5Hw`Kj;j$|L8XJbS2Zx~&3}Z(C?1Pp+sszII0zh(%=fRH9CkxdF zfYAJlZGXTRLw8_$01(PQxcwPpZa{$5<80;rlo8rOg9adU|J(kc5gtwq7Jxv0q4r0O z&>I*e0Kxu$%=S+h0)qn}lwa=88>R{YRwKXNA31_cDgy%GL*yqcm4g6apKSiq2xLUX ztXO`tKX~}NRmf%l%qPhoB5-Q1&j3)LC4Y#(+6KTVK1}`)0o?+C|FI8{KeU8P0|2(0 z{~H%=`R`1afpd*a4)+j9yMiPDTOaw|M&wte6bA zC4c1-0LTd*|I2MU&jm%CvrM+_N&s*?V2bv;|JciJk4H9}J9(B1qPt3b5Cq2y+@Tx* zF9K+GfTk>qxcR=#+rYXQ01kBkV{zq7^Mixu3S1!oTc!qeS$@o$gUJ$sTrMsle=5(Psyk>x;AqU}OaKnE zn6UDnWfKt)Xxt_kvj8~Wf+?u|&qya(Ca5pqCw7nkV1Sw7wJN1I$Uzq^R>++!CrbxV zqQwK~+W6jo?Vez>7%~8uP}=9}A5>i7)o%W&$eaRTV3$Bs!%p_CM@uZaByBoNPFuk? zKxsaKhd|R-#F6-_EsI5@^UA&V(oivl>50vwN~ zO>4p!Zb9kRDg`YL6=qnfEl)KD+)>M*A{YTGI9sB zS*`)KW`RDnxl~d@M(u#cX=4+s6l_DylpkQp|JrPA07ccf&yj1)sE})U$dUyL)#y_u zLPkbJK?0|*YBGd7F<4S?W}VL#GdW@3>=3*k~T zS}|ajWM#2IQH?Su-q*GbJaEx7`b`*q|cxs>}<7G3BAKXXX)Jy6p$*%rgx0j@C0+ zW`}@O)%t-tg9n?w?`qLp)uDFV`y%Ube)WREhHnlGKeg$&-x)mG4o+9~$=(`Yyna}l z;Wq#p8oP(?yHteX5WS9U|oh0 z@Z=x%J^(BM08oM+Fl& zUI>6sXq3^0gW#Is`{x2cvGH3~BtD+N^-=&R1lSPa%ObnA;t6c81%O20MIhmA1-V#~ zLZSnK@5KN_5P0ovt2gyE7Oi=VVyp*&@znrCTaxAQNp+ac^#DZLGG&ZD1ise;P|2h; z_2F+%M}qU-XH;y1Ufny0v%t_V=%`kLsT+O2y6Qe4_~8OVxt^V?ZUZ160-<}d_or`! z#NKtNHADHgzRe5t@t&#It#I_HzYS?h)$Xl3^flMwNem)eVVbXKTSdGJba)v$jg7YX z5dQL2FBi4#AYO*l^#J^_3BSg*4NHi(LDfAJe9|CZhpz|)A2X=@0DOkXg9n)*g3b|o z@*s1B?6rRI)D%1E^@Ge4T)JOEJkkmLpD8;295+Dc3h(U4xB)s_99%E(DK_w} zUSR$)RxnaAVt$MjjMNN4tHwSh4t%c~gVqf`dBo}lp_QYbVge48qub9g0`b~m_cJ1a zc=b4vKj6V5&L40v0?W4rAi*H9^?sBNw&UwIaC`L_(XW5H#PX&%M1U+ZC#R7wsX2Ks zK5(m-u0W(%WT3TvG1(W*&tHiLySWQ?fX^cYWRjwVH+Cv`9Ol~f-2ow!lsSfLoC+2oM*u5X&J>!tra6_`O%Cwzi9M#;a!a0VEY#?0o7 zQ4+@~`rFYrFMeKnZOu7=T(K%Fy7qqxO0y34*A4VphEfM2JASKGmJo5AbDqa1E=2)q0;odvpyga~Ek6UQ-E z1_oK|@_@4cWOvy?XC;HUZB6KqFwH(N+F#%ZQ;jFw1Sqgg1f4NvNQK|&lU1l2k3`sf(RLpI0tfAGQurGCXpP~9r zQ%camOZ#a~(LvQ*s{rXvQ?NGM{-NjFhAyrxE$=&A)Op%8`R5uXm^D z&E>bsA0nX6{z}A{v#i}Soc+GIKDp4J!I<_@F?Y_g>}OzQ%I*o^yGRgiwA~?r#IPCWZ5UlzgZQ>mgx6Z8;|r{mi!Q%6&yP(wKZ<8uW;0E z^lWtUh{lTT>~j72FaJc&i+vO;y6-jq1`zjGS6Kf*=533UWEWO;@-)XM^g9h8y+}g( zi*|BFbyg;*{0q+~834)*tOF~WA}iZt-s8_RN-K0KDMPjbuqP6}o>F5OPo_A()@OS? z0*|S)c2W7yZ8R&jGA$`2mv4d$AC*%p9YNqprA2gVT8@v(Di$XZcvN+rs+B(vfRH5n zaRsKl_VGNEE+BjYeprpQt4$urSfMXIP8+A*~7C&v0_^diWQlJmC&qfG>o@hWLN zOa8dUYI57UaWpb$s_2`;=%DKXLb>Kv1gF%c~X5zp2MTTpq+@2MAE8^J7(bjk3v2fV4#I%(nhlf zT@Y%csl=rjdP*-W`Z1;hm%6jP)L<|jI*@ibwwM(!J&IH95&+WCdyVvSuXo6f?F6I& z?S*0M_zK&(pMukkl!B8reP5m~Xegm_xMb-YWnA002ov JPDHLkV1nnf{$~IH diff --git a/contracts/icons/account.svg b/contracts/icons/account.svg deleted file mode 100644 index 511f0649..00000000 --- a/contracts/icons/account.svg +++ /dev/null @@ -1 +0,0 @@ -Account \ No newline at end of file diff --git a/contracts/icons/admin.png b/contracts/icons/admin.png deleted file mode 100644 index ae95364725ed2e9f6143044631d2ff136201fa2b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2937 zcmY+Gc{J308^*uCnK5JROC%nd5XrvR5MwL*I+mnJ#=d5db$-^eMT#t0k|j&gVoe!K zLfMxmyLe>DPNFQY=bZPv=e+kn*XKItzW=+83-VPX|f)cuCe+pQxp!VnOzV z^K(i~bZ>5LZ9CihkB?2o-%ac78LF#pT$o?7v2gp?+(`+JfBZ1-MQPR1(UBlEr|$Ti zm27Hgc5MG|z}XiW_5jc|>S(GF?~E>IUyFQlo&l~axp!ypsBwoJU{r%d%^5y<@c6@9 zvn@4sZFStIyUd&54tUFDD$};`%j(qF-0npX%GSz*FtUU#^!?^1UyFi561RcPsCXVz$sE`I$V0q}Q*Zm~d zs?`J3ZdPpYt>xgjN5VtE{eyY@Vu1f-G(iP^Iv9|o!A!yNP>HK$ytb~55Ipkxd)+yM z*we5F@IBa_kP${G!B5NgyW^}MAngk00%)BFLEGjg-=|><>}!zTtygkya*!-3_|d{m z+OJAkG?o*dPTf}^?MrFVQ{Td8jlAk3Ttt|uHh`3^(84024OPbdAc}RR0g*RA_pT)Q z&DmrI>Q_Yd%#_wO4^#(8tDlT>ont9RB+J|2DwGP=p>)@GWu+!|I1W(J0Q6hw@gOGk zrSFXg@&Os{z$|jMvsV+N{Q*5VT5v;g6gmaJiVlnW?V82_oBKr^-mlVfIL8P)W{SGR zr5@U_Q-7=&mqxSV>V)!&vVJdlK11a3ki3e}nQ16k9$(VM7=h3M!)Uz$3;7r<@ZhW{ z^>RxA>lV^ug@+VP8DYmVI(T>r;|mRnujefBWIdWn?Q-Sf3Im(a`f+BI!D+z9FfCBi zloSwk+H!Z6S%Z)AmnR3y11lu|C3Smlb}-@0lg?dmonUMOG96YDJ|o*r zZ~ZA2zG92q86pGUpz(9by^M0;T6okewV_dr@#FS|-{v8&4W8mAW$LP8(aO;&C7`XS z@HK)Dv}l@JA#Rn$n~^%_K2y#d-VSVG;5^ctSRN%l6_t(ddK<_~GoO0uhrs92rk_lY zi_YK3%Ho-P@&zj=mYSK9pjdaoWx`8r=jrg!2&*LcvAIob0mSYG2ZXWw%N`@edKKGe z;mzb?G#!Vvb7gQ4AbJbQZPuYu0Q8n?0yMo|$}mtGTbrEhjMecAoOT`rwN`E`zA zZP95wkSRJ@Xz{&?Vt zRa)jscvsOAG~k4$OUqdn_Lv(HJMu_;Hm*o{82BRXeY@aTkJ z@qb;=d!}_cI{StMoEt&ld43&{>2Aa`O5) zI9wzCwWaHuRO7@gH&xFj&Stxj!9L%?P;VcH`5w9#!M2M@oL={JtJPQevi(mmCn*Gx z&2_rC#?BRv<*HT@F=-ph@BaKZCCo5}ik$vmX#TYaF<%nI9~mTuMqesg!&DCp2(VU} z*z<+mP_#IJ+C%dT+G#QCDG3un2;(ieM4 zAPQ`70!@z%4TvD5{Wpe%2;PR&HM8sSs-1146O$=noGwKrc3G)RC~IUIrR zz5`K`4cH`k$a!sP-fWBQBn_p*f*B6@y;qR5(_)s^Kt$p$4K(f~PnJPCcor0Vrp!Zj zYWB-OH~@$Qve;Ii$8sD0v2_D>tRY4l28`*6{tCAOLGsTv(GL^O-kts7qCmFbPk!0{ zj$T3_o{-=3m)kG4njzOWX@$snF#fD3KRDjY6-L01kWzl{dpVy&8A%UQxb^~%7Viq# z{L^|_Cu$!Vhp;4!|HX^@w&{h5gT!`^v1vZ>)ZP7F^85n8jvwva(>z47DQIA{t$O_k z0*x_g!7)r!u)ITvr1GmS?>a63TIvV-B<--Iu^J&BQMO9RE@f(VcdcWkro9Sk6>MBv zC{B6Df&}HQO6T|9V{*@!W7^HBiO*7|g0~HZq1!$P&)OsUI@_Ye=RLCW0ug$S29d$>J(>W9R zW%xNk%ZV+2NXnXk?3cPP1Q(j=3H-}s0yp>`XC(9po%cE2l%3lDkw$qxaUow0r-NbO zk*Zm73H^??pd%=m--v|lM2v&4cQQXuiSYiR{M{1N$1^W0Vb^C&?#x+dHm##v8fk!a zc(aRkUiY^@&yA>NgjpKEZbcU~V_e*lJ0+ZlT}ehooi~ZA<2N1{Gf&?DlYUT$cvDk= zLxs=R!zyW%On7!bq1^DU`SbQI+oE`Y*G@7-mVO#Pf3$D}Q1_MB_Z-ZxTC`5w+w1dr zQsTzZqHe>O9)!3c`_;Ufb7mFFmi?BWuE(;i*BYxMer3(1{VeS@z1CMJXm!KmYEj|C zQ5WVxAdYK90;i%JwZ_adm11mp}EP7n0kVd7>fM7ENVa`?T6_VTQFJBT`ub{FaE zq~#?r+tpd+-e$jwCnPIH%xaZ8Mm|G{-I-w7lAO{`hkVd`?!L5XfZG!7cJX#J|C*)dP?Fc0jd zxFzQwW4-60eSHCnYnO)#toYY0xy9PC=Yy@H{hjQkD!{Ja0M{h z=GXSVAGW!>FC7BhQZbKO-=u5PIf9pH!bOUm#=Z}>+1@4nxV?bKVdUoDY^X(G5314H zwsQ;xCv7Fvl9_O5I~VHrp1ojKYy=rd!++DL+7@&=Nu52NkGunMT{QGh-NHc8WsF|(J!vw*0AF}7kIC_DT|8(xa0K0Q)T}Khr=xSUz~e%S z{Inn?;QRS979f75mWPYDJ|BQJ^gZni*_;k|U*9r?1W7U^ONk~%s5h_c2%jD{N1sna zm59hGM&cDWW^VwZ#e3yxHg`qjboniA%OkrQit( zu8o1cT0Z!(QzBbM|BuFaIOlS-)2LIF{!D`jer56JyG)b%*Bi?6J0r8R(7rGggme6i V=0Y3_AOE>PN6S$2rMg|je*nyqJZk^| diff --git a/contracts/icons/admin.svg b/contracts/icons/admin.svg deleted file mode 100644 index fbc05717..00000000 --- a/contracts/icons/admin.svg +++ /dev/null @@ -1 +0,0 @@ -Admin \ No newline at end of file diff --git a/contracts/icons/multisig.png b/contracts/icons/multisig.png deleted file mode 100644 index 00fa7564c88ea2785f53d641f150b32ec68a7b47..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1411 zcmZ`%doqG{65Om;k{$VjOf%}jL|q`{EKZ_{CyDS4zk z(jazeJThn}$`&WHgx7r|KPRBU)0;w2-ok=^j-Q{e~v!@bbksTMV)7UQT}8uv~^<) zI$fbW_lQS}W+oVL*;zwR1mJXycr06F{D&lRfmxK^r3bp`3GuFvkN6LW)?nAOQ93fq z{NKv|vE^}24I13&Wh`o#ToS$=*UB6&S+wz!O>_dYbMCipI)V7ntxsjw*ty)zAVSf@ z&_Dim2n9$=tBf-Io~;tQ+n($H@(}~A^u%D4Pc8_u^V;B0OaS5lReOLObZmOx;;G}#;8*|+;c2be4I3`gN zhA*dU-77eHcf@h4FR%G z^aZ0lMorCFr^CEtC{Ygw9Xv9H7uht5$`Kn7A&0(ix?>tq_wz@c;Czv+$H0B<@fC5_ z9^O&Zp-ZogJ!__ydf~*kd1zwdI~!h10hy_Vp5G`5#au9wFm3rbh33#LfS1xF(Rp3d zJI;SCx#J!;ZMoY>*CG>nzF~t|Qfl^Un0IA!!>OAI5=x`k}(g&Oz9Nt*cBh=0VG`vkBgj_>ji16&N=NetoxA@plV?sUDV0z&_Nds zzHBn;p*55~yBEcF0$Ep$~xv06jiA|H79p$LBE)8|Qx+v=u(O)N^t zRtH#rkk{syuG>An9-Go<{SB_$5xc_H^jz1y*RJg1-A7NY4@lW*x7xn&+;8m~?QvN>T-E3}C(Y{}`$>K-Ikm~!K&AM#mwr|S`X<*0X7g}z{(qH(X( z31&CWc{@Zxd}+R_Q0^=S3M|f29sr(*nyMR5^)AyiJZyIQWmk5p1~sg^zjorepylGp zgj$P1Xqrvaelf)=g)FDMUFW5j)@VI^UT~$UKB*WO%k%fCyfRP-|G?X8V*)#&nfEj6 YBtQ`z6CivXCH{CNh3rMDa-pC88^Gy0WB>pF diff --git a/contracts/icons/multisig.svg b/contracts/icons/multisig.svg deleted file mode 100644 index d9167fb2..00000000 --- a/contracts/icons/multisig.svg +++ /dev/null @@ -1 +0,0 @@ -Multi Sig \ No newline at end of file diff --git a/contracts/icons/resource.png b/contracts/icons/resource.png deleted file mode 100644 index 8e1bd127de7b7adb74c5d5765db70a036fd0aa8f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1913 zcmZ`)X;72r7Jk3v3rUbAhzdcFutg}ftU*A)ghh$S9s{zJkjPRZ5D~&=hYv_)5n2{6 z?uyE-vKAEx2$cwEr6L6t1QZDr1=%H(2(sKvXYSnktNTnXHn@iK#cQN17U1Bia1wiuy-wzn?2E zO-ntqxw)ymt=dhtt`hI#;VVnOFkn!9fenCME8UsKNE(_M9=v~(qySh)w|l>qrVZJg zWJY=qo{cPeD#^dHs%8Ln%;nhGqDbIxAel~zjS$&rI~(y%4F0VbW!k&0TgYU^kI^7QI zo*6`4>LJIf#+h74bp(8*sJsY1!NVw#taO-eetMQ@tT+L-otSu);kn-hVIP10>p&D- z3f(ul5tG}Q_^k1w;Sgj_HPvB`hA@^T9_6g|-^@hd`i`iKiI3SI`ntBxSRW99d3O=q zP5Y*IHc25^-aZHs&RbzU_E+!a%=;B!6cz$hjRN~GWCf%jDS&qU;SLoZ8BL{^S$aMJ zvG_a2q=_yQ)9i6ctQ@I7HuI;9O=%r|ui>TGwPKO6hz4YLz4g#>Mbg>nB%;Krc;k zR%ztmV@_fbb&zA*#|GXLy9WX(st#$xl9iKl-;X;oRU=Wg!l=im;~e%!TV7u)2*HSA zQSEcc+%3+V}|AVxANkq;~ra21-~uijQef``8a|4 z&-&>(->x)nJ4`Nvz8<3-<7@ax=_uSgo-XnV9yzzx$BAQd2|&#x=RFpP%){dFU4g z11agtk9rcj@~uLuaHTHZXKVOT%3c;JGhib60d6~$g|)86Bbc56s5^jyR-C4nn8R{BxO?@e^c|@teZ#tpFnYf3RS&Rs##B z%BcGvOhC!--W#CfiktR-Pu<@K&lU2b6nVw2ED@3mPG;xqYtw{874!0{fhjgw&M^!U zj%EKc(i?r){I2GM-J;jr%Y{%&>tmvt=)AdZyc2S#U6Ez`1{~7EinU@8T0d-9ZGU%D zSUt-X8aJs$H=l|QrIbPobD(7Q7nS=&`YmVoJcrNkYaiBSJ4N+EnJG78OmCF zZzz@pBbvzmLMdv80n$wSGfzd7Z0|j}&X8gk__t4`IjLr_pJ*%1xf7|&sZRZ1eAKgfsSDGj%m`;!J#Cf65piZ5<5Rj8_2@Y8)GI^_-~#s_AB12g`?0(nO|i|= z6Ud<^(@2>m-riQ(?mte8aom~M;W`cD5rF##;vmb`SZ9cY|AMnmyAqUY7IRlA zQBl*e^=#?A5N5W3!wvOd3raS|O&oszyqWP%t4 lQzThj4saQu7QLp*0xy<3x9!Ue2$20bKzH$Qu5n~#{0CM4EzSS{ diff --git a/contracts/icons/resource.svg b/contracts/icons/resource.svg deleted file mode 100644 index 4a475592..00000000 --- a/contracts/icons/resource.svg +++ /dev/null @@ -1 +0,0 @@ -Resource \ No newline at end of file diff --git a/contracts/icons/rex.png b/contracts/icons/rex.png deleted file mode 100644 index b43ee27fcf6180649c35b0739a74e37bc34d08ea..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2770 zcmY*bX*|>m7e4=)F=lKr_9X^c5*pdU7$aMjkmMapLP;fYBfI=YtgOC*`shx_F{&xhwczu!5}^YNUEuFiJC0&)TXAZ)+i+6@5NY7rn{ zwmIs4FD$=YE#O`*&*On;0F1VU3a0Dw-F=0SD53$%h6o-`sH_D_A8ch#^tdT zKEty!sZf3nV(yfa!Zl!?dcIxo9`HcP)R{&)1Oy3fc6fSMIq&(1B_Vl z9vCd8kKoYcgTC3-#_8;0wER>bww2lBt6Kk@pln`Lf;ip7hNvjC92ss&3D|ulEl(Ze z=g~-GEf8mo?R=us&+#H~=#UTi(}%w8D!4AJ ziwjEP(Pl5qv6_d10a(|$$}Ibz0V&?0Dbv;zpRDelVo>O7@S%%vtzdIHP>oE$Ugqb} z8r-$X4)G7v>8pF1?9eNBhmS5U8bD5?C_m@>#u;ek_7@^WcAp6kN%nwnkUx+;Duhd<#r}b%ahfm5zo7o0+b>f#0>Z5LazX`u=S0hD7o&S7-kO=pZADN zUe)>}CQ8f}=U+c&Q7QdNh0ZT^oxl*EqE7473X)gnQbjR&Bet^$rR300Jpv^|@x2*n zwmnh642bL3(vnO;o4^fnAId2vK_bqlCZkh&lV5Qjj>w7Y zwb;BOWr`#g?HeI3-T{_*Ouag2@2+#o0_sJ!5l|TTeyDJYoKZ(KyQNR#06U&!3)-{v zK6SwCO!5F%&Awg%RJKFT2n!vnMp!?1>ZcE}`XE_( zbnX@&&a?)fxrB~mDF%;hjD%M{xizi7a8n}-aTV*O!zj^IGQ!O;MFjws@uJX4X zr5Q`<_vTjLz@g^1Hx~~LaGht@s#2Sw^FWOdhW@R*z50d#YIu)Vpw%3CIgIPE2WGC% z1|ClT7ApTK4=)l$Q*0CP{u{LhR&te-6qK3V%Zu`|Leg2~nHq}sYNWaSRwa)S#^xidGr9HoJ_54o9nUqrYWAF>1iALlq5QiS(w=tDnx!q^*+Sh%T0Rl{>> zo?H(+DC9T(lL4R3riAZWPWU}2G_AT+^n6;b%3tHL{@$KYad?!7yV}>gf;3%y5~zcO znGdyGJWD{!2}4HS)mVt;gciPq3Ug*=+6xb{$Z4o@0R=r`)>Oct-VU7K!;Ve6?zjU@ zp^e#WfVFFn=8=!XvBuOs@XMPf3?2_|kha-{jKnI=B;u~<%UyU~Sl4``;5KB`dZ~}j zZ(Myiq_O)(ATF935kjJ={-feT?acRJBoVmk?Vp|1^kN&cJMS}Mo6OXayUZn$N{qeE zgqx1YE!?IN5wG=h?eP7C9}utJsNG9w{YNm|1B*&C5ehLkj<%+h?a#)dKUdr<`hSW4 zXXZ3SJ25}w5`@N!xSFqS%6={}aAz;8lnZfQ??4GOt+0g+ws>RdNuXsd?3$M-Yb+eg z^lGaL7BV2tYx?VH$9}`fD#YvMnLvhpbi%MIMe5YvGO0i3~7QGl!x1&d z8+sbY5?ZX-znKhYICdHvIDStr^4L;%p7E3lp6pQb%r3ZSV%f1XZACv2G(HMntU|!djWZ zrYBR>M%8>ac(6jLGT8;o5Zt908(ZW2eqnY4P3{%8-ItYX!4JI6v>;_4YU0+N!3E5& zj8AqEIo=A*&5GuUXJN?v{OG%|UmGSELUt-)vP*)VW6-=eu@xeVlskURE0uSaj+R{Oz;6Ynl5@#v(UT4GXnYzEt1K?OwB*S$u)gE=y-K3yRe#M-CMh;r7~5cvHbo`3{)`ugOT+V%Sm3yzJ<+A zmDyfca^F%h{_4s#{DoK7JC{c(7Tu;U7ymFXGPoSixjN%y^vl7jP~@vOWUi28qT-lg zQR7XnC2W2?Urk>q5d#bLw{OWUc9~@~ zzjHsH->t&J$xE_wm=WEmtXgGo#`!$MarDBCn%1TZVB>tP&P$bE2{dNTWPtDv2Y-bN zr9d4cO}J|XH#qEh#>ctc%u8|1^nCKvFwo_86)?8B z4a|{_|3|m0HK-CN`(2PaLz>`H{I?CMg&@)I)!Lp0+M0hMP4w$8=Qw7D_P$^E!x3O= z|N8Ge;=0JTrCR^cj)_k^I2XRUJ*&wJd>x t8r&`rkbbJN6JuapUk~*lca%q@K$2uhugGzw16vOy*xNW;v-kNi{|A}y)Mfwx diff --git a/contracts/icons/rex.svg b/contracts/icons/rex.svg deleted file mode 100644 index 99f77f37..00000000 --- a/contracts/icons/rex.svg +++ /dev/null @@ -1 +0,0 @@ -Rex \ No newline at end of file diff --git a/contracts/icons/voting.png b/contracts/icons/voting.png deleted file mode 100644 index 0356bddaf2b0f61f82f8dbd7cfad977e0757b187..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3238 zcmY*cc|4T+7yiEQyk?9gV~J#&uBEhCZuV_PSteN~+)!e;L|UXo$jsY@QYgaB9!6ZE zm0PZP(}KvZBBF$`@6l*xe(s;Y^Uryn=bZETJm;_TIoIgU_L5?o#Q*@3`)D?<06^;y z0;0I}biCZteLX3L+j@q(g&qx$^g9y>tOG**1IhbN`UM5L2Kog=g*63QtT*kZJG$H2 zS{+@-&Ti}U{{m=M{N)dT_|!fdYxnbgQ#q5-{o5qsUXFD+)(HO|U^f{(vnCUX zuOj%5U3L%8suarZF`CikvMOs2;NZ&)q0l7O5A3_dY!*z=q$Pg!_gVh!28gwE$ zKO>PSeILT+ABu=!S4Ay03}wdTBR+9xse7zG%s#kWENX#Z&a-K}JxI&$3CV@dt&Hsl zeXpRUUa>@21e&VUsi@8qZ@9wF_oGS-o`Rr2P%ZdZt0eq^t8W8Q^u@H9%p}j>fxp-i)VcFv57T>AAuwv zhjkOT!HM6xqFl`9apEKrqIW86IsKx09;%G)I~1!3`va@*JqlaMA`E=0a@H}=G~y;( zeuiA-LD+8cXU2g_7mWLfbMle@hd(k<1npQ`zIwRNkSGeOB85V~oa1pQKo9@=sOBuF zm)#WFah?)_Gda~EnCZWa+~+Mq{qh(iCng1Wv8>RiH<-%MbHNGlOt(mFFIqrR!bTu& zs@HhfdidS@uNB+rE*-I)hrTCqb(+Fo;_H~vi# zNB{-38bauqxBWc9{dIP@p1}O_J-cps+>3wVzZ%up^y7m(siFQAbIjPZc{1-tKGO)b z)ETxP-&rBlEX$K*B+0|A4nbc0$K^~NbiekLdL1pun$HAJM#jhB^KX=UkBskRv*ud{ zm#$u^$P;HIropl5mg3{Sdxw{;*07wc;n^CHRiumaFHdeVoN* zPITi;uLR!$n0t$>=r=%$yawl%8F8=*V)Jh^mAEezZI&K`PpU6W)e9+~(49{un;<=F zE4nSKMi?D2V+!cnj(ddy>0k7JoHpT65&H1Pl8k=EukF@d%rF-?^OcnzJ$tM3HI`G* zi)Sdo$-K#lW(FAM+iFa$qg}Ajs(~1O?Q>dhGcldvvw;cC|$ceMeu$NmJD#Z@rRT$sFK`qEw;^$>IWsAdr|K4O2kz}lfah^&J)T)|4Gg?x)<8={tvlJEFh_N1(jkD3 z>=(32!nZHf8vje~)f_u0|uy6Py)^g!i|5zj&EE7p8dAIsZD;W2o0!^iCF{ey`U$#4Iq zU4AMf6DWtO^k%;ZnA|#GzB`5iG9SKgI>Ki5bv18O{W&R$!+v}kJ@HOmPxiJ?>(wVk zn}F_xvu1TCc8|nVbsT4sprm!Q6by5_02cQ36rlt35Sv!1-X#w)1s zVeZ1k*s4`&fYH-%O!+_{|Kz~t><2$v6Ju_5%;Tf|3k!vV9G~<+-W{o(>e}zpbL~Y< z|I(2pyHIw&_cR=xzp~S9Gu2(#&G)_p@D)+sf?JO@(A8O15>F!!Ts=i2YtSH?h42vg z{T1cXRvMsHuq=Th5opUN;AnjmTd?N<3Sx1bz~R} z3wt2ZBAiif1`6o&$yR9ghIZ~Z7YKX9(gbtn)WSpx1QdnWai46QpsLk1D?LFrtK7HfDpcm0_c^~P+*CHe*~qHXn@#>==rUneUifib8N<*odOeJ$A5uBqd;pxF;sPTsK9OV++jI>Osr7RCn?qh*q(g8<WduSs%km^pMATc38N)wR`d0$@L=r`)*MSFzbz0`19v3``tNR<2Aj_DP%2Bp8 zjG;qU@I4*iwdmY(d~)k=eX+ry{_;cuV8DvJf~4W^M13(3T=&fe0n&{fZMip-2qZOk zd-H`&8Yv}%`X%@8K^pj;1A~U6vW*{RJU0=L~FO5=TEVVGwsJ3X(VUpfmcInBgbsrGW{`zwK{rTiTCEyx*GXF!j5(46) zp16iI1B{yI>KLj7zD;*MsdhFd0LL`b`1_v`l1g!B*yya$f5KmjTqT6$nARJr5iCt5 zn~ic(?>T{L8`H5rkP6sD^IeoI_p``c&bG0-%lUqQQ+?~v;GPZx)c1qln(Ssm3X89f Z0VhTSOesfxtUm={pRKdagFTE({{svY!SDb8 diff --git a/contracts/icons/voting.svg b/contracts/icons/voting.svg deleted file mode 100644 index fac87089..00000000 --- a/contracts/icons/voting.svg +++ /dev/null @@ -1 +0,0 @@ -Voting_1 \ No newline at end of file diff --git a/docs.json b/docs.json index 2d4e43af..625bedcf 100644 --- a/docs.json +++ b/docs.json @@ -1,5 +1,5 @@ { - "name": "eosio.contracts", + "name": "eosio.token", "generators": [ { "name": "collate_markdown", @@ -11,11 +11,7 @@ "name": "mdjavadoc", "options": { "source_dirs": [ - "contracts/eosio.token/include/eosio.token/", - "contracts/eosio.wrap/include/eosio.wrap/", - "contracts/eosio.bios/include/eosio.bios/", - "contracts/eosio.system/include/eosio.system/", - "contracts/eosio.msig/include/eosio.msig/" + "contracts/eosio.token/include/eosio.token/" ], "output_dir": "action-reference" } diff --git a/docs/03_build-and-deploy.md b/docs/03_build-and-deploy.md index b2db104f..c612d47c 100644 --- a/docs/03_build-and-deploy.md +++ b/docs/03_build-and-deploy.md @@ -1,6 +1,6 @@ --- -content_title: How to build eosio.contracts -link_text: How to build eosio.contracts +content_title: How to build eosio.token +link_text: How to build eosio.token --- ## Preconditions @@ -10,22 +10,13 @@ Ensure an appropriate version of `eosio.cdt` is installed. Installing `eosio.cdt eosio-cpp -v ``` -### Build contracts using the build script - -#### To build contracts alone -Run the `build.sh` script in the top directory to build all the contracts. - -#### To build the contracts and unit tests -1. Ensure an appropriate version of `eosio` has been built from source and installed. Installing `eosio` from binaries `is not` sufficient. You can find instructions on how to do it [here](https://developers.eos.io/manuals/eos/latest/install/build-from-source) in section `Building from Sources`. -2. Run the `build.sh` script in the top directory with the `-t` flag to build all the contracts and the unit tests for these contracts. - ### Build contracts manually -To build the `eosio.contracts` execute the following commands. +To build the `eosio.token` execute the following commands. On all platforms except macOS: ```sh -cd you_local_path_to/eosio.contracts/ +cd you_local_path_to/eosio.token/ rm -fr build mkdir build cd build @@ -36,7 +27,7 @@ cd .. For macOS: ```sh -cd you_local_path_to/eosio.contracts/ +cd you_local_path_to/eosio.token/ rm -fr build mkdir build cd build @@ -50,34 +41,10 @@ cd .. * The contracts (both `.wasm` and `.abi` files) are built into their corresponding _build/contracts/\_ folder. * Finally, simply use __cleos__ to _set contract_ by pointing to the previously mentioned directory for the specific contract. -# How to deploy the eosio.contracts - -## To deploy eosio.bios contract execute the following command: -Let's assume your account name to which you want to deploy the contract is `testerbios` -``` -cleos set contract testerbios you_local_path_to/eosio.contracts/build/contracts/eosio.bios/ -p testerbios -``` - -## To deploy eosio.msig contract execute the following command: -Let's assume your account name to which you want to deploy the contract is `testermsig` -``` -cleos set contract testermsig you_local_path_to/eosio.contracts/build/contracts/eosio.msig/ -p testermsig -``` - -## To deploy eosio.system contract execute the following command: -Let's assume your account name to which you want to deploy the contract is `testersystem` -``` -cleos set contract testersystem you_local_path_to/eosio.contracts/build/contracts/eosio.system/ -p testersystem -``` +# How to deploy the eosio.token ## To deploy eosio.token contract execute the following command: Let's assume your account name to which you want to deploy the contract is `testertoken` ``` -cleos set contract testertoken you_local_path_to/eosio.contracts/build/contracts/eosio.token/ -p testertoken -``` - -## To deploy eosio.wrap contract execute the following command: -Let's assume your account name to which you want to deploy the contract is `testerwrap` +cleos set contract testertoken you_local_path_to/eosio.token/build/contracts/eosio.token/ -p testertoken ``` -cleos set contract testerwrap you_local_path_to/eosio.contracts/build/contracts/eosio.wrap/ -p testerwrap -``` \ No newline at end of file diff --git a/pipeline.jsonc b/pipeline.jsonc index b9d36799..9cbda157 100644 --- a/pipeline.jsonc +++ b/pipeline.jsonc @@ -4,8 +4,8 @@ "pipeline-branch": "master", "dependencies": // dependencies to pull for a build of contracts, by branch, tag, or commit hash { - "eosio": "release/2.0.x", - "eosio.cdt": "release/1.7.x" + "eosio": "v2.1.0-rc3", + "eosio.cdt": "v1.8.0-rc1" } } } From 9c0e309815f7ef642f779a85034d39c032c87433 Mon Sep 17 00:00:00 2001 From: deck Date: Wed, 3 Mar 2021 09:17:50 -0500 Subject: [PATCH 1047/1048] cleanup cmake and tests --- contracts/CMakeLists.txt | 10 - tests/eosio.msig_tests.cpp | 1002 --- tests/eosio.powerup_tests.cpp | 858 --- tests/eosio.system_tester.hpp | 1126 ---- tests/eosio.system_tests.cpp | 5712 ----------------- tests/eosio.token_tests.cpp | 142 +- tests/eosio.wrap_tests.cpp | 368 -- tests/main.cpp | 4 +- tests/test_contracts/exchange.wasm | Bin 72187 -> 0 bytes .../old_versions/v1.2.1/eosio.msig/Readme.txt | 3 - .../v1.2.1/eosio.msig/eosio.msig.abi | 152 - .../v1.2.1/eosio.msig/eosio.msig.wasm | Bin 16573 -> 0 bytes .../v1.2.1/eosio.system/README.txt | 3 - .../v1.2.1/eosio.system/Readme.txt | 3 - .../v1.2.1/eosio.system/eosio.system.abi | 626 -- .../v1.2.1/eosio.system/eosio.system.wasm | Bin 132041 -> 0 bytes .../v1.8.3/eosio.system/README.txt | 3 - .../v1.8.3/eosio.system/eosio.system.abi | 2097 ------ .../v1.8.3/eosio.system/eosio.system.wasm | Bin 263877 -> 0 bytes tests/test_contracts/reject_all.wasm | Bin 1013 -> 0 bytes 20 files changed, 72 insertions(+), 12037 deletions(-) delete mode 100644 tests/eosio.msig_tests.cpp delete mode 100644 tests/eosio.powerup_tests.cpp delete mode 100644 tests/eosio.system_tester.hpp delete mode 100644 tests/eosio.system_tests.cpp delete mode 100644 tests/eosio.wrap_tests.cpp delete mode 100644 tests/test_contracts/exchange.wasm delete mode 100644 tests/test_contracts/old_versions/v1.2.1/eosio.msig/Readme.txt delete mode 100644 tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.abi delete mode 100755 tests/test_contracts/old_versions/v1.2.1/eosio.msig/eosio.msig.wasm delete mode 100644 tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt delete mode 100644 tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt delete mode 100644 tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi delete mode 100755 tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm delete mode 100644 tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt delete mode 100644 tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi delete mode 100755 tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm delete mode 100755 tests/test_contracts/reject_all.wasm diff --git a/contracts/CMakeLists.txt b/contracts/CMakeLists.txt index 69d438e1..7f02640f 100644 --- a/contracts/CMakeLists.txt +++ b/contracts/CMakeLists.txt @@ -7,17 +7,7 @@ find_package(eosio.cdt) set(ICON_BASE_URL "http://127.0.0.1/ricardian_assets/eosio.contracts/icons") -set(ACCOUNT_ICON_URI "account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f") -set(ADMIN_ICON_URI "admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e") -set(MULTISIG_ICON_URI "multisig.png#4fb41d3cf02d0dd2d35a29308e93c2d826ec770d6bb520db668f530764be7153") -set(RESOURCE_ICON_URI "resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19") -set(REX_ICON_URI "rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8") set(TOKEN_ICON_URI "token.png#207ff68b0406eaa56618b08bda81d6a0954543f36adc328ab3065f31a5c5d654") set(TRANSFER_ICON_URI "transfer.png#5dfad0df72772ee1ccc155e670c1d124f5c5122f1d5027565df38b418042d1dd") -set(VOTING_ICON_URI "voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84") -add_subdirectory(eosio.bios) -add_subdirectory(eosio.msig) -add_subdirectory(eosio.system) add_subdirectory(eosio.token) -add_subdirectory(eosio.wrap) diff --git a/tests/eosio.msig_tests.cpp b/tests/eosio.msig_tests.cpp deleted file mode 100644 index 89f7dbc9..00000000 --- a/tests/eosio.msig_tests.cpp +++ /dev/null @@ -1,1002 +0,0 @@ -#include -#include -#include -#include - -#include - -#include -#include "contracts.hpp" -#include "test_symbol.hpp" - -using namespace eosio::testing; -using namespace eosio; -using namespace eosio::chain; -using namespace eosio::testing; -using namespace fc; - -using mvo = fc::mutable_variant_object; - -class eosio_msig_tester : public tester { -public: - eosio_msig_tester() { - create_accounts( { N(eosio.msig), N(eosio.stake), N(eosio.ram), N(eosio.ramfee), N(alice), N(bob), N(carol) } ); - produce_block(); - - auto trace = base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.msig") - ("is_priv", 1) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - - produce_blocks(); - const auto& accnt = control->db().get( N(eosio.msig) ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, - asset net = core_sym::from_string("10.0000"), asset cpu = core_sym::from_string("10.0000") ) { - signed_transaction trx; - set_transaction_headers(trx); - - authority owner_auth; - if (multisig) { - // multisig between account's owner key and creators active permission - owner_auth = authority(2, {key_weight{get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}}); - } else { - owner_auth = authority( get_public_key( a, "owner" ) ); - } - - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( N(eosio), N(buyram), vector{{creator,config::active_name}}, - mvo() - ("payer", creator) - ("receiver", a) - ("quant", ramfunds) ) - ); - - trx.actions.emplace_back( get_action( N(eosio), N(delegatebw), vector{{creator,config::active_name}}, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", net ) - ("stake_cpu_quantity", cpu ) - ("transfer", 0 ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - void create_currency( name contract, name manager, asset maxsupply ) { - auto act = mutable_variant_object() - ("issuer", manager ) - ("maximum_supply", maxsupply ); - - base_tester::push_action(contract, N(create), contract, act ); - } - void issue( name to, const asset& amount, name manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() - ("to", to ) - ("quantity", amount ) - ("memo", "") - ); - } - void transfer( name from, name to, const string& amount, name manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() - ("from", from) - ("to", to ) - ("quantity", asset::from_string(amount) ) - ("memo", "") - ); - } - asset get_balance( const account_name& act ) { - //return get_currency_balance( config::system_account_name, symbol(CORE_SYMBOL), act ); - //temporary code. current get_currency_balancy uses table name N(accounts) from currency.h - //generic_currency table name is N(account). - const auto& db = control->db(); - const auto* tbl = db.find(boost::make_tuple(N(eosio.token), act, N(accounts))); - share_type result = 0; - - // the balance is implied to be 0 if either the table or row does not exist - if (tbl) { - const auto *obj = db.find(boost::make_tuple(tbl->id, symbol(CORE_SYM).to_symbol_code())); - if (obj) { - // balance is the first field in the serialization - fc::datastream ds(obj->value.data(), obj->value.size()); - fc::raw::unpack(ds, result); - } - } - return asset( result, symbol(CORE_SYM) ); - } - - transaction_trace_ptr push_action( const account_name& signer, const action_name& name, const variant_object& data, bool auth = true ) { - vector accounts; - if( auth ) - accounts.push_back( signer ); - auto trace = base_tester::push_action( N(eosio.msig), name, accounts, data ); - produce_block(); - BOOST_REQUIRE_EQUAL( true, chain_has_transaction(trace->id) ); - return trace; - - /* - string action_type_name = abi_ser.get_action_type(name); - - action act; - act.account = N(eosio.msig); - act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - //std::cout << "test:\n" << fc::to_hex(act.data.data(), act.data.size()) << " size = " << act.data.size() << std::endl; - - return base_tester::push_action( std::move(act), auth ? uint64_t(signer) : 0 ); - */ - } - - transaction reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ); - - abi_serializer abi_ser; -}; - -transaction eosio_msig_tester::reqauth( account_name from, const vector& auths, const fc::microseconds& max_serialization_time ) { - fc::variants v; - for ( auto& level : auths ) { - v.push_back(fc::mutable_variant_object() - ("actor", level.actor) - ("permission", level.permission) - ); - } - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "reqauth") - ("authorization", v) - ("data", fc::mutable_variant_object() ("from", from) ) - }) - ); - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(max_serialization_time)); - return trx; -} - -BOOST_AUTO_TEST_SUITE(eosio_msig_tests) - -BOOST_FIXTURE_TEST_CASE( propose_approve_execute, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to execute before approval - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve and execute - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( propose_approve_unapprove, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - push_action( N(alice), N(unapprove), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( propose_approve_by_two, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - //fail because approval by bob is missing - - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve by bob and execute - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( propose_with_wrong_requested_auth, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); - //try with not enough requested auth - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "third") - ("trx", trx) - ("requested", vector{ { N(alice), config::active_name } } ) - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( big_transaction, eosio_msig_tester ) try { - vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name } }; - auto wasm = contracts::util::exchange_wasm(); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", perm) - ("data", fc::mutable_variant_object() - ("account", "alice") - ("vmtype", 0) - ("vmversion", 0) - ("code", bytes( wasm.begin(), wasm.end() )) - ) - }) - ); - - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", perm) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - //approve by bob and execute - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - - - -BOOST_FIXTURE_TEST_CASE( update_system_contract_all_approve, eosio_msig_tester ) try { - - // required to set up the link between (eosio active) and (eosio.prods active) - // - // eosio active - // | - // eosio.prods active (2/3 threshold) - // / | \ <--- implicitly updated in onblock action - // alice active bob active carol active - - set_authority( - config::system_account_name, - config::active_name, - authority( 1, - vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}} - ), - config::owner_name, - {{config::system_account_name, config::active_name}}, - {get_private_key(config::system_account_name, "active")} - ); - - set_producers( {N(alice),N(bob),N(carol)} ); - produce_blocks(50); - - create_accounts( { N(eosio.token), N(eosio.rex) } ); - set_code( N(eosio.token), contracts::token_wasm() ); - set_abi( N(eosio.token), contracts::token_abi().data() ); - - create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); - issue(config::system_account_name, core_sym::from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); - - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - base_tester::push_action( config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("version", 0) - ("core", CORE_SYM_STR) - ); - produce_blocks(); - create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); - - vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, - {N(carol), config::active_name} }; - - vector action_perm = {{N(eosio), config::active_name}}; - - auto wasm = contracts::util::reject_all_wasm(); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", action_perm) - ("data", fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("vmtype", 0) - ("vmversion", 0) - ("code", bytes( wasm.begin(), wasm.end() )) - ) - }) - ); - - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - - // propose action - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", perm) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - //approve by bob - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - //approve by carol - push_action( N(carol), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(carol), config::active_name }) - ); - // execute by alice to replace the eosio system contract - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - // can't create account because system contract was replaced by the reject_all contract - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), - eosio_assert_message_exception, eosio_assert_message_is("rejecting all actions") - - ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( update_system_contract_major_approve, eosio_msig_tester ) try { - - // set up the link between (eosio active) and (eosio.prods active) - set_authority( - config::system_account_name, - config::active_name, - authority( 1, - vector{{get_private_key(config::system_account_name, "active").get_public_key(), 1}}, - vector{{{N(eosio.prods), config::active_name}, 1}} - ), - config::owner_name, - {{config::system_account_name, config::active_name}}, - {get_private_key(config::system_account_name, "active")} - ); - - create_accounts( { N(apple) } ); - set_producers( {N(alice),N(bob),N(carol), N(apple)} ); - produce_blocks(50); - - create_accounts( { N(eosio.token), N(eosio.rex) } ); - set_code( N(eosio.token), contracts::token_wasm() ); - set_abi( N(eosio.token), contracts::token_abi().data() ); - - create_currency( N(eosio.token), config::system_account_name, core_sym::from_string("10000000000.0000") ); - issue(config::system_account_name, core_sym::from_string("1000000000.0000")); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance( config::system_account_name ) ); - - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - base_tester::push_action( config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("version", 0) - ("core", CORE_SYM_STR) - ); - produce_blocks(); - - create_account_with_resources( N(alice1111111), N(eosio), core_sym::from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), N(eosio), core_sym::from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), N(eosio), core_sym::from_string("1.0000"), false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), - get_balance(config::system_account_name) + get_balance(N(eosio.ramfee)) + get_balance(N(eosio.stake)) + get_balance(N(eosio.ram)) ); - - vector perm = { { N(alice), config::active_name }, { N(bob), config::active_name }, - {N(carol), config::active_name}, {N(apple), config::active_name}}; - - vector action_perm = {{N(eosio), config::active_name}}; - - auto wasm = contracts::util::reject_all_wasm(); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("max_net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", action_perm) - ("data", fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("vmtype", 0) - ("vmversion", 0) - ("code", bytes( wasm.begin(), wasm.end() )) - ) - }) - ); - - transaction trx; - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - - // propose action - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", perm) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - //approve by bob - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - // not enough approvers - BOOST_REQUIRE_EXCEPTION( - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, eosio_assert_message_is("transaction authorization failed") - ); - - //approve by apple - push_action( N(apple), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(apple), config::active_name }) - ); - // execute by alice to replace the eosio system contract - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - // execute by another producer different from proposer - push_action( N(apple), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "apple") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - // can't create account because system contract was replaced by the reject_all contract - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(alice1111112), N(eosio), core_sym::from_string("1.0000"), false ), - eosio_assert_message_exception, eosio_assert_message_is("rejecting all actions") - - ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( propose_approve_invalidate, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to execute before approval - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - //invalidate - push_action( N(alice), N(invalidate), mvo() - ("account", "alice") - ); - - //fail to execute after invalidation - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( propose_invalidate_approve, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to execute before approval - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //invalidate - push_action( N(alice), N(invalidate), mvo() - ("account", "alice") - ); - - //approve - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - //successfully execute - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(bob), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "bob") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( approve_execute_old, eosio_msig_tester ) try { - set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); - set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); - produce_blocks(); - - //propose with old version of eosio.msig - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - produce_blocks(); - - //approve and execute with new version - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( approve_unapprove_old, eosio_msig_tester ) try { - set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); - set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); - produce_blocks(); - - //propose with old version of eosio.msig - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //approve with old version - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - produce_blocks(); - - //unapprove with old version - push_action( N(alice), N(unapprove), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( approve_by_two_old, eosio_msig_tester ) try { - set_code( N(eosio.msig), contracts::util::msig_wasm_old() ); - set_abi( N(eosio.msig), contracts::util::msig_abi_old().data() ); - produce_blocks(); - - auto trx = reqauth( N(alice), vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }, abi_serializer_max_time ); - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{ { N(alice), config::active_name }, { N(bob), config::active_name } }) - ); - - //approve by alice - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - produce_blocks(); - - //fail because approval by bob is missing - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ), - eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - //approve and execute with new version - push_action( N(bob), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(bob), config::active_name }) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( approve_with_hash, eosio_msig_tester ) try { - auto trx = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - auto trx_hash = fc::sha256::hash( trx ); - auto not_trx_hash = fc::sha256::hash( trx_hash ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - //fail to approve with incorrect hash - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ("proposal_hash", not_trx_hash) - ), - eosio::chain::crypto_api_exception, - fc_exception_message_is("hash mismatch") - ); - - //approve and execute - push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ("proposal_hash", trx_hash) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - push_action( N(alice), N(exec), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("executer", "alice") - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( switch_proposal_and_fail_approve_with_hash, eosio_msig_tester ) try { - auto trx1 = reqauth( N(alice), {permission_level{N(alice), config::active_name}}, abi_serializer_max_time ); - auto trx1_hash = fc::sha256::hash( trx1 ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx1) - ("requested", vector{{ N(alice), config::active_name }}) - ); - - auto trx2 = reqauth( N(alice), - { permission_level{N(alice), config::active_name}, - permission_level{N(alice), config::owner_name} }, - abi_serializer_max_time ); - - push_action( N(alice), N(cancel), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("canceler", "alice") - ); - - push_action( N(alice), N(propose), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("trx", trx2) - ("requested", vector{ { N(alice), config::active_name }, - { N(alice), config::owner_name } }) - ); - - //fail to approve with hash meant for old proposal - BOOST_REQUIRE_EXCEPTION( push_action( N(alice), N(approve), mvo() - ("proposer", "alice") - ("proposal_name", "first") - ("level", permission_level{ N(alice), config::active_name }) - ("proposal_hash", trx1_hash) - ), - eosio::chain::crypto_api_exception, - fc_exception_message_is("hash mismatch") - ); -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.powerup_tests.cpp b/tests/eosio.powerup_tests.cpp deleted file mode 100644 index 3c8f43e0..00000000 --- a/tests/eosio.powerup_tests.cpp +++ /dev/null @@ -1,858 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "eosio.system_tester.hpp" - -inline constexpr int64_t powerup_frac = 1'000'000'000'000'000ll; // 1.0 = 10^15 -inline constexpr int64_t stake_weight = 100'000'000'0000ll; // 10^12 - -struct powerup_config_resource { - fc::optional current_weight_ratio = {}; - fc::optional target_weight_ratio = {}; - fc::optional assumed_stake_weight = {}; - fc::optional target_timestamp = {}; - fc::optional exponent = {}; - fc::optional decay_secs = {}; - fc::optional min_price = {}; - fc::optional max_price = {}; -}; -FC_REFLECT(powerup_config_resource, // - (current_weight_ratio)(target_weight_ratio)(assumed_stake_weight)(target_timestamp) // - (exponent)(decay_secs)(min_price)(max_price)) - -struct powerup_config { - powerup_config_resource net = {}; - powerup_config_resource cpu = {}; - fc::optional powerup_days = {}; - fc::optional min_powerup_fee = {}; -}; -FC_REFLECT(powerup_config, (net)(cpu)(powerup_days)(min_powerup_fee)) - -struct powerup_state_resource { - uint8_t version; - int64_t weight; - int64_t weight_ratio; - int64_t assumed_stake_weight; - int64_t initial_weight_ratio; - int64_t target_weight_ratio; - time_point_sec initial_timestamp; - time_point_sec target_timestamp; - double exponent; - uint32_t decay_secs; - asset min_price; - asset max_price; - int64_t utilization; - int64_t adjusted_utilization; - time_point_sec utilization_timestamp; -}; -FC_REFLECT(powerup_state_resource, // - (version)(weight)(weight_ratio)(assumed_stake_weight)(initial_weight_ratio)(target_weight_ratio) // - (initial_timestamp)(target_timestamp)(exponent)(decay_secs)(min_price)(max_price)(utilization) // - (adjusted_utilization)(utilization_timestamp)) - -struct powerup_state { - uint8_t version; - powerup_state_resource net; - powerup_state_resource cpu; - uint32_t powerup_days; - asset min_powerup_fee; -}; -FC_REFLECT(powerup_state, (version)(net)(cpu)(powerup_days)(min_powerup_fee)) - -using namespace eosio_system; - -struct powerup_tester : eosio_system_tester { - - powerup_tester() { create_accounts_with_resources({ N(eosio.reserv) }); } - - void start_rex() { - create_account_with_resources(N(rexholder111), config::system_account_name, core_sym::from_string("1.0000"), - false); - transfer(config::system_account_name, N(rexholder111), core_sym::from_string("1001.0000")); - BOOST_REQUIRE_EQUAL("", stake(N(rexholder111), N(rexholder111), core_sym::from_string("500.0000"), - core_sym::from_string("500.0000"))); - create_account_with_resources(N(proxyaccount), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - BOOST_REQUIRE_EQUAL("", - push_action(N(proxyaccount), N(regproxy), mvo()("proxy", "proxyaccount")("isproxy", true))); - BOOST_REQUIRE_EQUAL("", vote(N(rexholder111), {}, N(proxyaccount))); - BOOST_REQUIRE_EQUAL("", push_action(N(rexholder111), N(deposit), - mvo()("owner", "rexholder111")("amount", asset::from_string("1.0000 TST")))); - BOOST_REQUIRE_EQUAL("", push_action(N(rexholder111), N(buyrex), - mvo()("from", "rexholder111")("amount", asset::from_string("1.0000 TST")))); - } - - template - powerup_config make_config(F f) { - powerup_config config; - - config.net.current_weight_ratio = powerup_frac; - config.net.target_weight_ratio = powerup_frac / 100; - config.net.assumed_stake_weight = stake_weight; - config.net.target_timestamp = control->head_block_time() + fc::days(100); - config.net.exponent = 2; - config.net.decay_secs = fc::days(1).to_seconds(); - config.net.min_price = asset::from_string("0.0000 TST"); - config.net.max_price = asset::from_string("1000000.0000 TST"); - - config.cpu.current_weight_ratio = powerup_frac; - config.cpu.target_weight_ratio = powerup_frac / 100; - config.cpu.assumed_stake_weight = stake_weight; - config.cpu.target_timestamp = control->head_block_time() + fc::days(100); - config.cpu.exponent = 2; - config.cpu.decay_secs = fc::days(1).to_seconds(); - config.cpu.min_price = asset::from_string("0.0000 TST"); - config.cpu.max_price = asset::from_string("1000000.0000 TST"); - - config.powerup_days = 30; - config.min_powerup_fee = asset::from_string("1.0000 TST"); - - f(config); - return config; - } - - powerup_config make_config() { - return make_config([](auto&) {}); - } - - template - powerup_config make_default_config(F f) { - powerup_config config; - f(config); - return config; - } - - action_result configbw(const powerup_config& config) { - // Verbose solution needed to work around bug in abi_serializer that fails if optional values aren't explicitly - // specified with a null value. - - auto optional_to_variant = []( const auto& v ) -> fc::variant { - return (!v ? fc::variant() : fc::variant(*v)); - }; - - auto resource_conf_vo = [&optional_to_variant](const powerup_config_resource& c ) { - return mvo("current_weight_ratio", optional_to_variant(c.current_weight_ratio)) - ("target_weight_ratio", optional_to_variant(c.target_weight_ratio)) - ("assumed_stake_weight", optional_to_variant(c.assumed_stake_weight)) - ("target_timestamp", optional_to_variant(c.target_timestamp)) - ("exponent", optional_to_variant(c.exponent)) - ("decay_secs", optional_to_variant(c.decay_secs)) - ("min_price", optional_to_variant(c.min_price)) - ("max_price", optional_to_variant(c.max_price)) - ; - }; - - auto conf = mvo("net", resource_conf_vo(config.net)) - ("cpu", resource_conf_vo(config.cpu)) - ("powerup_days", optional_to_variant(config.powerup_days)) - ("min_powerup_fee", optional_to_variant(config.min_powerup_fee)) - ; - - //idump((fc::json::to_pretty_string(conf))); - return push_action(config::system_account_name, N(cfgpowerup), mvo()("args", std::move(conf))); - - // If abi_serializer worked correctly, the following is all that would be needed: - //return push_action(config::system_account_name, N(cfgpowerup), mvo()("args", config)); - } - - action_result powerupexec(name user, uint16_t max) { - return push_action(user, N(powerupexec), mvo()("user", user)("max", max)); - } - - action_result powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, - const asset& max_payment) { - return push_action(payer, N(powerup), - mvo()("payer", payer)("receiver", receiver)("days", days)("net_frac", net_frac)( - "cpu_frac", cpu_frac)("max_payment", max_payment)); - } - - powerup_state get_state() { - vector data = get_row_by_account(config::system_account_name, {}, N(powup.state), N(powup.state)); - return fc::raw::unpack(data); - } - - struct account_info { - int64_t ram = 0; - int64_t net = 0; - int64_t cpu = 0; - asset liquid; - }; - - account_info get_account_info(account_name acc) { - account_info info; - control->get_resource_limits_manager().get_account_limits(acc, info.ram, info.net, info.cpu); - info.liquid = get_balance(acc); - return info; - }; - - void check_powerup(const name& payer, const name& receiver, uint32_t days, int64_t net_frac, int64_t cpu_frac, - const asset& expected_fee, int64_t expected_net, int64_t expected_cpu) { - auto before_payer = get_account_info(payer); - auto before_receiver = get_account_info(receiver); - auto before_reserve = get_account_info(N(eosio.reserv)); - auto before_state = get_state(); - BOOST_REQUIRE_EQUAL("", powerup(payer, receiver, days, net_frac, cpu_frac, expected_fee)); - auto after_payer = get_account_info(payer); - auto after_receiver = get_account_info(receiver); - auto after_reserve = get_account_info(N(eosio.reserv)); - auto after_state = get_state(); - - if (false) { - ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); - ilog("before_state.net.weight_ratio: ${x}", - ("x", before_state.net.weight_ratio / double(powerup_frac))); - ilog("before_state.net.assumed_stake_weight: ${x}", ("x", before_state.net.assumed_stake_weight)); - ilog("before_state.net.weight: ${x}", ("x", before_state.net.weight)); - - ilog("before_receiver.net: ${x}", ("x", before_receiver.net)); - ilog("after_receiver.net: ${x}", ("x", after_receiver.net)); - ilog("after_receiver.net - before_receiver.net: ${x}", ("x", after_receiver.net - before_receiver.net)); - ilog("expected_net: ${x}", ("x", expected_net)); - ilog("before_payer.liquid - after_payer.liquid: ${x}", ("x", before_payer.liquid - after_payer.liquid)); - ilog("expected_fee: ${x}", ("x", expected_fee)); - - ilog("before_reserve.net: ${x}", ("x", before_reserve.net)); - ilog("after_reserve.net: ${x}", ("x", after_reserve.net)); - ilog("before_reserve.cpu: ${x}", ("x", before_reserve.cpu)); - ilog("after_reserve.cpu: ${x}", ("x", after_reserve.cpu)); - } - - if (payer != receiver) { - BOOST_REQUIRE_EQUAL(before_payer.ram, after_payer.ram); - BOOST_REQUIRE_EQUAL(before_payer.net, after_payer.net); - BOOST_REQUIRE_EQUAL(before_payer.cpu, after_payer.cpu); - BOOST_REQUIRE_EQUAL(before_receiver.liquid, after_receiver.liquid); - } - BOOST_REQUIRE_EQUAL(before_receiver.ram, after_receiver.ram); - BOOST_REQUIRE_EQUAL(after_receiver.net - before_receiver.net, expected_net); - BOOST_REQUIRE_EQUAL(after_receiver.cpu - before_receiver.cpu, expected_cpu); - BOOST_REQUIRE_EQUAL(before_payer.liquid - after_payer.liquid, expected_fee); - - BOOST_REQUIRE_EQUAL(before_reserve.net - after_reserve.net, expected_net); - BOOST_REQUIRE_EQUAL(before_reserve.cpu - after_reserve.cpu, expected_cpu); - BOOST_REQUIRE_EQUAL(after_state.net.utilization - before_state.net.utilization, expected_net); - BOOST_REQUIRE_EQUAL(after_state.cpu.utilization - before_state.cpu.utilization, expected_cpu); - } -}; - -template -bool near(A a, B b, D delta) { - if (abs(a - b) <= delta) - return true; - elog("near: ${a} ${b}", ("a", a)("b", b)); - return false; -} - -BOOST_AUTO_TEST_SUITE(eosio_system_powerup_tests) - -BOOST_FIXTURE_TEST_CASE(config_tests, powerup_tester) try { - BOOST_REQUIRE_EQUAL("missing authority of eosio", - push_action(N(alice1111111), N(cfgpowerup), mvo()("args", make_config()))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("powerup hasn't been initialized"), powerupexec(N(alice1111111), 10)); - - BOOST_REQUIRE_EQUAL(wasm_assert_msg("powerup_days must be > 0"), - configbw(make_config([&](auto& c) { c.powerup_days = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.min_powerup_fee = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee does not have a default value"), - configbw(make_config([&](auto& c) { c.min_powerup_fee = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee must be positive"), - configbw(make_config([&](auto& c) { c.min_powerup_fee = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_powerup_fee must be positive"), - configbw(make_config([&](auto& c) { c.min_powerup_fee = asset::from_string("-1.0000 TST"); }))); - - // net assertions - BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), - configbw(make_config([](auto& c) { c.net.current_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), - configbw(make_config([](auto& c) { - c.net.assumed_stake_weight = 100000; - c.net.target_weight_ratio = 10; - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), - configbw(make_config([](auto& c) { c.net.target_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), - configbw(make_config([](auto& c) { c.net.assumed_stake_weight = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), - configbw(make_config([](auto& c) { c.net.assumed_stake_weight = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp does not have a default value"), - configbw(make_config([&](auto& c) { c.net.target_timestamp = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), - configbw(make_config([&](auto& c) { c.net.target_timestamp = control->head_block_time(); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { - c.net.target_timestamp = control->head_block_time() - fc::seconds(1); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), - configbw(make_config([&](auto& c) { c.net.exponent = .999; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - configbw(make_config([&](auto& c) { c.net.decay_secs = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price does not have a default value"), - configbw(make_config([&](auto& c) { c.net.max_price = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.net.max_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.net.max_price = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.net.max_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.net.min_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price must be non-negative"), - configbw(make_config([&](auto& c) { c.net.min_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price cannot exceed max_price"), - configbw(make_config([&](auto& c) { - c.net.min_price = asset::from_string("3.0000 TST"); - c.net.max_price = asset::from_string("2.0000 TST"); - }))); - - // cpu assertions - BOOST_REQUIRE_EQUAL(wasm_assert_msg("current_weight_ratio is too large"), - configbw(make_config([](auto& c) { c.cpu.current_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight/target_weight_ratio is too large"), - configbw(make_config([](auto& c) { - c.cpu.assumed_stake_weight = 100000; - c.cpu.target_weight_ratio = 10; - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("weight can't grow over time"), - configbw(make_config([](auto& c) { c.cpu.target_weight_ratio = powerup_frac + 1; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight does not have a default value"), - configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("assumed_stake_weight must be at least 1; a much larger value is recommended"), - configbw(make_config([](auto& c) { c.cpu.assumed_stake_weight = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp does not have a default value"), - configbw(make_config([&](auto& c) { c.cpu.target_timestamp = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), - configbw(make_config([&](auto& c) { c.cpu.target_timestamp = control->head_block_time(); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("target_timestamp must be in the future"), configbw(make_config([&](auto& c) { - c.cpu.target_timestamp = control->head_block_time() - fc::seconds(1); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("exponent must be >= 1"), - configbw(make_config([&](auto& c) { c.cpu.exponent = .999; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("decay_secs must be >= 1"), - configbw(make_config([&](auto& c) { c.cpu.decay_secs = 0; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price does not have a default value"), - configbw(make_config([&](auto& c) { c.cpu.max_price = {}; }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.cpu.max_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.cpu.max_price = asset::from_string("0.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("max_price must be positive"), - configbw(make_config([&](auto& c) { c.cpu.max_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price doesn't match core symbol"), configbw(make_config([&](auto& c) { - c.cpu.min_price = asset::from_string("1000000.000 TST"); - }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price must be non-negative"), - configbw(make_config([&](auto& c) { c.cpu.min_price = asset::from_string("-1.0000 TST"); }))); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("min_price cannot exceed max_price"), - configbw(make_config([&](auto& c) { - c.cpu.min_price = asset::from_string("3.0000 TST"); - c.cpu.max_price = asset::from_string("2.0000 TST"); - }))); -} // config_tests -FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(weight_tests, powerup_tester) try { - produce_block(); - - auto net_start = (powerup_frac * 11) / 100; - auto net_target = (powerup_frac * 1) / 100; - auto cpu_start = (powerup_frac * 11) / 1000; - auto cpu_target = (powerup_frac * 1) / 1000; - - BOOST_REQUIRE_EQUAL("", configbw(make_config([&](powerup_config& config) { - config.net.current_weight_ratio = net_start; - config.net.target_weight_ratio = net_target; - config.net.assumed_stake_weight = stake_weight; - config.net.target_timestamp = control->head_block_time() + fc::days(10); - - config.cpu.current_weight_ratio = cpu_start; - config.cpu.target_weight_ratio = cpu_target; - config.cpu.assumed_stake_weight = stake_weight; - config.cpu.target_timestamp = control->head_block_time() + fc::days(20); - }))); - - int64_t net; - int64_t cpu; - - auto check_weight = [&] { - auto state = get_state(); - BOOST_REQUIRE(near( // - state.net.weight_ratio, // - int64_t(state.net.assumed_stake_weight * eosio::chain::int128_t(powerup_frac) / - (state.net.weight + state.net.assumed_stake_weight)), - 10)); - }; - - for (int i = 0; i <= 6; ++i) { - if (i == 2) { - // Leaves config as-is, but may introduce slight rounding - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw({})); - } else if (i) { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - } - net = net_start + i * (net_target - net_start) / 10; - cpu = cpu_start + i * (cpu_target - cpu_start) / 20; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - // Extend transition time - { - int i = 7; - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { - config.net.target_timestamp = control->head_block_time() + fc::days(30); - config.cpu.target_timestamp = control->head_block_time() + fc::days(40); - }))); - net_start = net = net_start + i * (net_target - net_start) / 10; - cpu_start = cpu = cpu_start + i * (cpu_target - cpu_start) / 20; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - for (int i = 0; i <= 5; ++i) { - if (i) { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - } - net = net_start + i * (net_target - net_start) / 30; - cpu = cpu_start + i * (cpu_target - cpu_start) / 40; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - // Change target, keep existing transition time - { - int i = 6; - produce_block(fc::days(1) - fc::milliseconds(500)); - auto new_net_target = net_target / 10; - auto new_cpu_target = cpu_target / 20; - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { - config.net.target_weight_ratio = new_net_target; - config.cpu.target_weight_ratio = new_cpu_target; - }))); - net_start = net = net_start + i * (net_target - net_start) / 30; - cpu_start = cpu = cpu_start + i * (cpu_target - cpu_start) / 40; - net_target = new_net_target; - cpu_target = new_cpu_target; - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - for (int i = 0; i <= 10; ++i) { - if (i) { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - } - net = net_start + i * (net_target - net_start) / (30 - 6); - cpu = cpu_start + i * (cpu_target - cpu_start) / (40 - 6); - BOOST_REQUIRE(near(get_state().net.weight_ratio, net, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu, 1)); - check_weight(); - } - - // Move transition time to immediate future - { - produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", configbw(make_default_config([&](powerup_config& config) { - config.net.target_timestamp = control->head_block_time() + fc::milliseconds(1000); - config.cpu.target_timestamp = control->head_block_time() + fc::milliseconds(1000); - }))); - produce_blocks(2); - } - - // Verify targets hold as time advances - for (int i = 0; i <= 10; ++i) { - BOOST_REQUIRE_EQUAL("", powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(get_state().net.weight_ratio, net_target, 1)); - BOOST_REQUIRE(near(get_state().cpu.weight_ratio, cpu_target, 1)); - check_weight(); - produce_block(fc::days(1)); - } -} // weight_tests -FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_CASE(rent_tests) try { - { - powerup_tester t; - t.produce_block(); - - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("powerup hasn't been initialized"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 4, powerup_frac / 8, - asset::from_string("1.000 TST"))); - - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac; - config.net.target_weight_ratio = powerup_frac; - config.net.assumed_stake_weight = stake_weight; - config.net.exponent = 1; - config.net.min_price = asset::from_string("1000000.0000 TST"); - config.net.max_price = asset::from_string("1000000.0000 TST"); - - config.cpu.current_weight_ratio = powerup_frac; - config.cpu.target_weight_ratio = powerup_frac; - config.cpu.assumed_stake_weight = stake_weight; - config.cpu.exponent = 1; - config.cpu.min_price = asset::from_string("1000000.0000 TST"); - config.cpu.max_price = asset::from_string("1000000.0000 TST"); - - config.powerup_days = 30; - config.min_powerup_fee = asset::from_string("1.0000 TST"); - }))); - - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("max_payment doesn't match core symbol"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, asset::from_string("1.000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("market doesn't have resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, 0, powerup_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("market doesn't have resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, 0, asset::from_string("1.0000 TST"))); - - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { - // weight = stake_weight - config.net.current_weight_ratio = powerup_frac/2; - config.net.target_weight_ratio = powerup_frac/2; - - // weight = stake_weight - config.cpu.current_weight_ratio = powerup_frac/2; - config.cpu.target_weight_ratio = powerup_frac/2; - }))); - - auto net_weight = stake_weight; - auto cpu_weight = stake_weight; - - t.start_rex(); - t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - - // 10%, 20% - // (.1) * 1000000.0000 = 100000.0000 - // (.2) * 1000000.0000 = 200000.0000 - // total = 300000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("300000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, powerup_frac * .1, powerup_frac * .2, - asset::from_string("300000.0000 TST"), net_weight * .1, cpu_weight * .2); - - // Start decay - t.produce_block(fc::days(30) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .1 * net_weight, 0)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .2 * cpu_weight, 0)); - - // 2 days of decay from (10%, 20%) to (1.35%, 2.71%) - t.produce_block(fc::days(2) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2)), - int64_t(.1 * net_weight * exp(-2)) / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-2)), - int64_t(.2 * cpu_weight * exp(-2)) / 1000)); - - // 2%, 2% - // (0.0135 + 0.02 - 0.0135) * 1000000.0000 = 20000.0000 - // (.02) * 1000000.0000 = 20000.0000 - // total = 40000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("40000.0001")); - t.check_powerup(N(aaaaaaaaaaaa), N(aaaaaaaaaaaa), 30, powerup_frac * .02, powerup_frac * .02, - asset::from_string("40000.0001 TST"), net_weight * .02, cpu_weight * .02); - } - - auto init = [](auto& t, bool rex) { - t.produce_block(); - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_config([&](auto& config) { - // weight = stake_weight * 3 - config.net.current_weight_ratio = powerup_frac / 4; - config.net.target_weight_ratio = powerup_frac / 4; - config.net.assumed_stake_weight = stake_weight; - config.net.exponent = 2; - config.net.max_price = asset::from_string("2000000.0000 TST"); - - // weight = stake_weight * 4 / 2 - config.cpu.current_weight_ratio = powerup_frac / 5; - config.cpu.target_weight_ratio = powerup_frac / 5; - config.cpu.assumed_stake_weight = stake_weight / 2; - config.cpu.exponent = 3; - config.cpu.max_price = asset::from_string("6000000.0000 TST"); - - config.powerup_days = 30; - config.min_powerup_fee = asset::from_string("1.0000 TST"); - }))); - - if (rex) - t.start_rex(); - - t.create_account_with_resources(N(aaaaaaaaaaaa), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - t.create_account_with_resources(N(bbbbbbbbbbbb), config::system_account_name, core_sym::from_string("1.0000"), - false, core_sym::from_string("500.0000"), core_sym::from_string("500.0000")); - }; - auto net_weight = stake_weight * 3; - auto cpu_weight = stake_weight * 4 / 2; - - { - powerup_tester t; - init(t, false); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("days doesn't match configuration"), // - t.powerup(N(bob111111111), N(alice1111111), 20, powerup_frac, powerup_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("net_frac can't be negative"), // - t.powerup(N(bob111111111), N(alice1111111), 30, -powerup_frac, powerup_frac, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("cpu_frac can't be negative"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, -powerup_frac, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("net can't be more than 100%"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac + 1, powerup_frac, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("cpu can't be more than 100%"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac + 1, - asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("max_payment is less than calculated fee: 3000000.0000 TST"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, asset::from_string("1.0000 TST"))); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("can't channel fees to rex"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac, powerup_frac, - asset::from_string("3000000.0000 TST"))); - } - - // net:100%, cpu:100% - { - powerup_tester t; - init(t, true); - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); - BOOST_REQUIRE_EQUAL( - t.wasm_assert_msg("calculated fee is below minimum; try powering up with more resources"), - t.powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, 10, 10, asset::from_string("3000000.0000 TST"))); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); - - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("weight can't shrink below utilization"), - t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac / 4 + 1; - config.net.target_weight_ratio = powerup_frac / 4 + 1; - config.cpu.current_weight_ratio = powerup_frac / 5; - config.cpu.target_weight_ratio = powerup_frac / 5; - }))); - BOOST_REQUIRE_EQUAL( // - t.wasm_assert_msg("weight can't shrink below utilization"), - t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac / 4; - config.net.target_weight_ratio = powerup_frac / 4; - config.cpu.current_weight_ratio = powerup_frac / 5 + 1; - config.cpu.target_weight_ratio = powerup_frac / 5 + 1; - }))); - BOOST_REQUIRE_EQUAL( // - "", // - t.configbw(t.make_default_config([&](auto& config) { - config.net.current_weight_ratio = powerup_frac / 4; - config.net.target_weight_ratio = powerup_frac / 4; - config.cpu.current_weight_ratio = powerup_frac / 5; - config.cpu.target_weight_ratio = powerup_frac / 5; - }))); - } - - // net:30%, cpu:40%, then net:5%, cpu:10% - { - powerup_tester t; - init(t, true); - // (.3 ^ 2) * 2000000.0000 / 2 = 90000.0000 - // (.4 ^ 3) * 6000000.0000 / 3 = 128000.0000 - // total = 218000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("218000.0001")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .3, powerup_frac * .4, - asset::from_string("218000.0001 TST"), net_weight * .3, cpu_weight * .4); - - // (.35 ^ 2) * 2000000.0000 / 2 - 90000.0000 = 32500.0000 - // (.5 ^ 3) * 6000000.0000 / 3 - 128000.0000 = 122000.0000 - // total = 154500.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("154500.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .05, powerup_frac * .10, - asset::from_string("154500.0000 TST"), net_weight * .05, cpu_weight * .10); - } - - // net:50%, cpu:50% (but with non-zero min_price and also an exponent of 2 to simplify the math) - { - powerup_tester t; - init(t, true); - BOOST_REQUIRE_EQUAL("", t.configbw(t.make_default_config([&](auto& config) { - config.cpu.exponent = 2; - config.net.min_price = asset::from_string("1200000.0000 TST"); - config.net.max_price = asset::from_string("2000000.0000 TST"); - - config.cpu.exponent = 2; - config.cpu.min_price = asset::from_string("4000000.0000 TST"); - config.cpu.max_price = asset::from_string("6000000.0000 TST"); - }))); - - // At 0% utilization for both NET and CPU, the cost (in TST) for renting an infinitesimal amount of resources (dr) is - // 1200000.0000 * dr for NET and 4000000.0000 * dr for CPU. - // At 50% utilization for both NET and CPU, the cost (in TST for renting an infinitesimal amount of resources (dr) is - // 1600000.0000 * dr for NET and 5000000.0000 * dr for CPU. - - // The fee for renting 50% of NET (starting from 0% utilization) is expected to be somewhere between - // 1200000.0000 * 0.5 (= 600000.0000) and 1600000.0000 * 0.5 (= 800000.0000). - // In fact, the cost ends up being 700000.0000. - - // The fee for renting 50% of CPU (starting from 0% utilization) is expected to be somewhere between - // 4000000.0000 * 0.5 (= 2000000.0000) and 5000000.0000 * 0.5 (= 2500000.0000). - // In fact, the cost ends up being 2250000.0000. - - - // 1200000.0000 * .5 + (800000.0000 / 2) * (.5 ^ 2) = 700000.0000 - // 4000000.0000 * .5 + (2000000.0000 / 2) * (.5 ^ 2) = 2250000.0000 - // total = 2950000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("2950000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .5, powerup_frac * .5, - asset::from_string("2950000.0000 TST"), net_weight * .5, cpu_weight * .5); - } - - { - // net:100%, cpu:100% - powerup_tester t; - init(t, true); - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3000000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("3000000.0000 TST"), net_weight, cpu_weight); - - // No more available for 30 days - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(29)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(1) - fc::milliseconds(1500)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::milliseconds(500)); - - // immediate renewal: adjusted_utilization doesn't have time to fall - // - // (1.0 ^ 1) * 2000000.0000 = 2000000.0000 - // (1.0 ^ 2) * 6000000.0000 = 6000000.0000 - // total = 8000000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("8000000.0000")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("8000000.0000 TST"), 0, 0); - - // No more available for 30 days - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(29)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - t.produce_block(fc::days(1) - fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("market doesn't have enough resources available"), // - t.powerup(N(bob111111111), N(alice1111111), 30, powerup_frac / 1000, powerup_frac / 1000, - asset::from_string("1.0000 TST"))); - - // Start decay - t.produce_block(fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, net_weight, net_weight / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, cpu_weight, cpu_weight / 1000)); - - // 1 day of decay - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-1)), - int64_t(net_weight * exp(-1)) / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-1)), - int64_t(cpu_weight * exp(-1)) / 1000)); - - // 1 day of decay - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, int64_t(net_weight * exp(-2)), - int64_t(net_weight * exp(-2)) / 1000)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, int64_t(cpu_weight * exp(-2)), - int64_t(cpu_weight * exp(-2)) / 1000)); - - // 100% after 2 days of decay - // - // [ ((e^-2) ^ 1)*(e^-2 - 0.0) + ((1.0) ^ 2)/2 - ((e^-2) ^ 2)/2 ] * 2000000.0000 = 1018315.6389 - // [ ((e^-2) ^ 2)*(e^-2 - 0.0) + ((1.0) ^ 3)/3 - ((e^-2) ^ 3)/3 ] * 6000000.0000 = 2009915.0087 - // total = 3028230.6476 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("3028229.8795")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac, powerup_frac, - asset::from_string("3028229.8795 TST"), net_weight, cpu_weight); - } - - { - powerup_tester t; - init(t, true); - - // 10%, 20% - // (.1 ^ 2) * 2000000.0000 / 2 = 10000.0000 - // (.2 ^ 3) * 6000000.0000 / 3 = 16000.0000 - // total = 26000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("26000.0002")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .1, powerup_frac * .2, - asset::from_string("26000.0002 TST"), net_weight * .1, cpu_weight * .2); - - t.produce_block(fc::days(15) - fc::milliseconds(500)); - - // 20%, 20% - // (.3 ^ 2) * 2000000.0000 / 2 - 10000.0000 = 80000.0000 - // (.4 ^ 3) * 6000000.0000 / 3 - 16000.0000 = 112000.0000 - // total = 192000.0000 - t.transfer(config::system_account_name, N(aaaaaaaaaaaa), core_sym::from_string("192000.0001")); - t.check_powerup(N(aaaaaaaaaaaa), N(bbbbbbbbbbbb), 30, powerup_frac * .2, powerup_frac * .2, - asset::from_string("192000.0001 TST"), net_weight * .2, cpu_weight * .2); - - // Start decay - t.produce_block(fc::days(15) - fc::milliseconds(1000)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE(near(t.get_state().net.adjusted_utilization, .3 * net_weight, 0)); - BOOST_REQUIRE(near(t.get_state().cpu.adjusted_utilization, .4 * cpu_weight, 0)); - - // 1 day of decay from (30%, 40%) to (20%, 20%) - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE( - near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-1) + .2 * net_weight), 0)); - BOOST_REQUIRE( - near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-1) + .2 * cpu_weight), 0)); - - // 2 days of decay from (30%, 40%) to (20%, 20%) - t.produce_block(fc::days(1) - fc::milliseconds(500)); - BOOST_REQUIRE_EQUAL("", t.powerupexec(config::system_account_name, 10)); - BOOST_REQUIRE( - near(t.get_state().net.adjusted_utilization, int64_t(.1 * net_weight * exp(-2) + .2 * net_weight), 0)); - BOOST_REQUIRE( - near(t.get_state().cpu.adjusted_utilization, int64_t(.2 * cpu_weight * exp(-2) + .2 * cpu_weight), 0)); - } - -} // rent_tests -FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.system_tester.hpp b/tests/eosio.system_tester.hpp deleted file mode 100644 index 3d9c76eb..00000000 --- a/tests/eosio.system_tester.hpp +++ /dev/null @@ -1,1126 +0,0 @@ -#pragma once - -#include -#include -#include -#include "contracts.hpp" -#include "test_symbol.hpp" - -#include -#include - -using namespace eosio::chain; -using namespace eosio::testing; -using namespace fc; - -using mvo = fc::mutable_variant_object; - -#ifndef TESTER -#ifdef NON_VALIDATING_TEST -#define TESTER tester -#else -#define TESTER validating_tester -#endif -#endif - -namespace eosio_system { - - -class eosio_system_tester : public TESTER { -public: - - void basic_setup() { - 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), N(eosio.rex) }); - - - produce_blocks( 100 ); - set_code( N(eosio.token), contracts::token_wasm()); - set_abi( N(eosio.token), contracts::token_abi().data() ); - { - const auto& accnt = control->db().get( N(eosio.token) ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - token_abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - } - - void create_core_token( symbol core_symbol = symbol{CORE_SYM} ) { - FC_ASSERT( core_symbol.decimals() == 4, "create_core_token assumes core token has 4 digits of precision" ); - create_currency( N(eosio.token), config::system_account_name, asset(100000000000000, core_symbol) ); - issue( asset(10000000000000, core_symbol) ); - BOOST_REQUIRE_EQUAL( asset(10000000000000, core_symbol), get_balance( "eosio", core_symbol ) ); - } - - void deploy_contract( bool call_init = true ) { - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - if( call_init ) { - base_tester::push_action(config::system_account_name, N(init), - config::system_account_name, mutable_variant_object() - ("version", 0) - ("core", CORE_SYM_STR) - ); - } - - { - const auto& accnt = control->db().get( config::system_account_name ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - } - - void remaining_setup() { - produce_blocks(); - - // Assumes previous setup steps were done with core token symbol set to CORE_SYM - create_account_with_resources( N(alice1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); - create_account_with_resources( N(bob111111111), config::system_account_name, core_sym::from_string("0.4500"), false ); - create_account_with_resources( N(carol1111111), config::system_account_name, core_sym::from_string("1.0000"), false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000000000.0000"), get_balance("eosio") + get_balance("eosio.ramfee") + get_balance("eosio.stake") + get_balance("eosio.ram") ); - } - - enum class setup_level { - none, - minimal, - core_token, - deploy_contract, - full - }; - - eosio_system_tester( setup_level l = setup_level::full ) { - if( l == setup_level::none ) return; - - basic_setup(); - if( l == setup_level::minimal ) return; - - create_core_token(); - if( l == setup_level::core_token ) return; - - deploy_contract(); - if( l == setup_level::deploy_contract ) return; - - remaining_setup(); - } - - template - eosio_system_tester(Lambda setup) { - setup(*this); - - basic_setup(); - create_core_token(); - deploy_contract(); - remaining_setup(); - } - - - void create_accounts_with_resources( vector accounts, account_name creator = config::system_account_name ) { - for( auto a : accounts ) { - create_account_with_resources( a, creator ); - } - } - - transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, uint32_t ram_bytes = 8000 ) { - signed_transaction trx; - set_transaction_headers(trx); - - authority owner_auth; - owner_auth = authority( get_public_key( a, "owner" ) ); - - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( config::system_account_name, N(buyrambytes), vector{{creator,config::active_name}}, - mvo() - ("payer", creator) - ("receiver", a) - ("bytes", ram_bytes) ) - ); - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", core_sym::from_string("10.0000") ) - ("stake_cpu_quantity", core_sym::from_string("10.0000") ) - ("transfer", 0 ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - - transaction_trace_ptr create_account_with_resources( account_name a, account_name creator, asset ramfunds, bool multisig, - asset net = core_sym::from_string("10.0000"), asset cpu = core_sym::from_string("10.0000") ) { - signed_transaction trx; - set_transaction_headers(trx); - - authority owner_auth; - if (multisig) { - // multisig between account's owner key and creators active permission - owner_auth = authority(2, {key_weight{get_public_key( a, "owner" ), 1}}, {permission_level_weight{{creator, config::active_name}, 1}}); - } else { - owner_auth = authority( get_public_key( a, "owner" ) ); - } - - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{{creator,config::active_name}}, - mvo() - ("payer", creator) - ("receiver", a) - ("quant", ramfunds) ) - ); - - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{{creator,config::active_name}}, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", net ) - ("stake_cpu_quantity", cpu ) - ("transfer", 0 ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - - transaction_trace_ptr setup_producer_accounts( const std::vector& accounts, - asset ram = core_sym::from_string("1.0000"), - asset cpu = core_sym::from_string("80.0000"), - asset net = core_sym::from_string("80.0000") - ) - { - account_name creator(config::system_account_name); - signed_transaction trx; - set_transaction_headers(trx); - - for (const auto& a: accounts) { - authority owner_auth( get_public_key( a, "owner" ) ); - trx.actions.emplace_back( vector{{creator,config::active_name}}, - newaccount{ - .creator = creator, - .name = a, - .owner = owner_auth, - .active = authority( get_public_key( a, "active" ) ) - }); - - trx.actions.emplace_back( get_action( config::system_account_name, N(buyram), vector{ {creator, config::active_name} }, - mvo() - ("payer", creator) - ("receiver", a) - ("quant", ram) ) - ); - - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), vector{ {creator, config::active_name} }, - mvo() - ("from", creator) - ("receiver", a) - ("stake_net_quantity", net) - ("stake_cpu_quantity", cpu ) - ("transfer", 0 ) - ) - ); - } - - set_transaction_headers(trx); - trx.sign( get_private_key( creator, "active" ), control->get_chain_id() ); - return push_transaction( trx ); - } - - action_result buyram( const account_name& payer, account_name receiver, const asset& eosin ) { - return push_action( payer, N(buyram), mvo()( "payer",payer)("receiver",receiver)("quant",eosin) ); - } - action_result buyram( std::string_view payer, std::string_view receiver, const asset& eosin ) { - return buyram( account_name(payer), account_name(receiver), eosin ); - } - - action_result buyrambytes( const account_name& payer, account_name receiver, uint32_t numbytes ) { - return push_action( payer, N(buyrambytes), mvo()( "payer",payer)("receiver",receiver)("bytes",numbytes) ); - } - action_result buyrambytes( std::string_view payer, std::string_view receiver, uint32_t numbytes ) { - return buyrambytes( account_name(payer), account_name(receiver), numbytes ); - } - - action_result sellram( const account_name& account, uint64_t numbytes ) { - return push_action( account, N(sellram), mvo()( "account", account)("bytes",numbytes) ); - } - action_result sellram( std::string_view account, uint64_t numbytes ) { - return sellram( account_name(account), numbytes ); - } - - action_result push_action( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) { - string action_type_name = abi_ser.get_action_type(name); - - action act; - act.account = config::system_account_name; - act.name = name; - act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - - return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); - } - - action_result stake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { - return push_action( name(from), N(delegatebw), mvo() - ("from", from) - ("receiver", to) - ("stake_net_quantity", net) - ("stake_cpu_quantity", cpu) - ("transfer", 0 ) - ); - } - action_result stake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { - return stake( account_name(from), account_name(to), net, cpu ); - } - - action_result stake( const account_name& acnt, const asset& net, const asset& cpu ) { - return stake( acnt, acnt, net, cpu ); - } - action_result stake( std::string_view acnt, const asset& net, const asset& cpu ) { - return stake( account_name(acnt), net, cpu ); - } - - action_result stake_with_transfer( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { - return push_action( name(from), N(delegatebw), mvo() - ("from", from) - ("receiver", to) - ("stake_net_quantity", net) - ("stake_cpu_quantity", cpu) - ("transfer", true ) - ); - } - action_result stake_with_transfer( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { - return stake_with_transfer( account_name(from), account_name(to), net, cpu ); - } - - action_result stake_with_transfer( const account_name& acnt, const asset& net, const asset& cpu ) { - return stake_with_transfer( acnt, acnt, net, cpu ); - } - action_result stake_with_transfer( std::string_view acnt, const asset& net, const asset& cpu ) { - return stake_with_transfer( account_name(acnt), net, cpu ); - } - - action_result unstake( const account_name& from, const account_name& to, const asset& net, const asset& cpu ) { - return push_action( name(from), N(undelegatebw), mvo() - ("from", from) - ("receiver", to) - ("unstake_net_quantity", net) - ("unstake_cpu_quantity", cpu) - ); - } - action_result unstake( std::string_view from, std::string_view to, const asset& net, const asset& cpu ) { - return unstake( account_name(from), account_name(to), net, cpu ); - } - - action_result unstake( const account_name& acnt, const asset& net, const asset& cpu ) { - return unstake( acnt, acnt, net, cpu ); - } - action_result unstake( std::string_view acnt, const asset& net, const asset& cpu ) { - return unstake( account_name(acnt), net, cpu ); - } - - int64_t bancor_convert( int64_t S, int64_t R, int64_t T ) { return double(R) * T / ( double(S) + T ); }; - - int64_t get_net_limit( account_name a ) { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return net; - }; - - int64_t get_cpu_limit( account_name a ) { - int64_t ram_bytes = 0, net = 0, cpu = 0; - control->get_resource_limits_manager().get_account_limits( a, ram_bytes, net, cpu ); - return cpu; - }; - - action_result deposit( const account_name& owner, const asset& amount ) { - return push_action( name(owner), N(deposit), mvo() - ("owner", owner) - ("amount", amount) - ); - } - - action_result withdraw( const account_name& owner, const asset& amount ) { - return push_action( name(owner), N(withdraw), mvo() - ("owner", owner) - ("amount", amount) - ); - } - - action_result buyrex( const account_name& from, const asset& amount ) { - return push_action( name(from), N(buyrex), mvo() - ("from", from) - ("amount", amount) - ); - } - - asset get_buyrex_result( const account_name& from, const asset& amount ) { - auto trace = base_tester::push_action( config::system_account_name, N(buyrex), from, mvo()("from", from)("amount", amount) ); - asset rex_received; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(buyresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - rex_received ); - return rex_received; - } - } - return rex_received; - } - - action_result unstaketorex( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { - return push_action( name(owner), N(unstaketorex), mvo() - ("owner", owner) - ("receiver", receiver) - ("from_net", from_net) - ("from_cpu", from_cpu) - ); - } - - asset get_unstaketorex_result( const account_name& owner, const account_name& receiver, const asset& from_net, const asset& from_cpu ) { - auto trace = base_tester::push_action( config::system_account_name, N(unstaketorex), owner, mvo() - ("owner", owner) - ("receiver", receiver) - ("from_net", from_net) - ("from_cpu", from_cpu) - ); - asset rex_received; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(buyresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - rex_received ); - return rex_received; - } - } - return rex_received; - } - - action_result sellrex( const account_name& from, const asset& rex ) { - return push_action( name(from), N(sellrex), mvo() - ("from", from) - ("rex", rex) - ); - } - - asset get_sellrex_result( const account_name& from, const asset& rex ) { - auto trace = base_tester::push_action( config::system_account_name, N(sellrex), from, mvo()("from", from)("rex", rex) ); - asset proceeds; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(sellresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - proceeds ); - return proceeds; - } - } - return proceeds; - } - - auto get_rexorder_result( const transaction_trace_ptr& trace ) { - std::vector> output; - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(orderresult) ) { - fc::datastream ds( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size() ); - account_name owner; fc::raw::unpack( ds, owner ); - asset proceeds; fc::raw::unpack( ds, proceeds ); - output.emplace_back( owner, proceeds ); - } - } - return output; - } - - action_result cancelrexorder( const account_name& owner ) { - return push_action( name(owner), N(cnclrexorder), mvo()("owner", owner) ); - } - - action_result rentcpu( const account_name& from, const account_name& receiver, const asset& payment, const asset& fund = core_sym::from_string("0.0000") ) { - return push_action( name(from), N(rentcpu), mvo() - ("from", from) - ("receiver", receiver) - ("loan_payment", payment) - ("loan_fund", fund) - ); - } - - action_result rentnet( const account_name& from, const account_name& receiver, const asset& payment, const asset& fund = core_sym::from_string("0.0000") ) { - return push_action( name(from), N(rentnet), mvo() - ("from", from) - ("receiver", receiver) - ("loan_payment", payment) - ("loan_fund", fund) - ); - } - - asset _get_rentrex_result( const account_name& from, const account_name& receiver, const asset& payment, bool cpu ) { - const name act = cpu ? N(rentcpu) : N(rentnet); - auto trace = base_tester::push_action( config::system_account_name, act, from, mvo() - ("from", from) - ("receiver", receiver) - ("loan_payment", payment) - ("loan_fund", core_sym::from_string("0.0000") ) - ); - - asset rented_tokens = core_sym::from_string("0.0000"); - for ( size_t i = 0; i < trace->action_traces.size(); ++i ) { - if ( trace->action_traces[i].act.name == N(rentresult) ) { - fc::raw::unpack( trace->action_traces[i].act.data.data(), - trace->action_traces[i].act.data.size(), - rented_tokens ); - return rented_tokens; - } - } - return rented_tokens; - } - - asset get_rentcpu_result( const account_name& from, const account_name& receiver, const asset& payment ) { - return _get_rentrex_result( from, receiver, payment, true ); - } - - asset get_rentnet_result( const account_name& from, const account_name& receiver, const asset& payment ) { - return _get_rentrex_result( from, receiver, payment, false ); - } - - action_result fundcpuloan( const account_name& from, const uint64_t loan_num, const asset& payment ) { - return push_action( name(from), N(fundcpuloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("payment", payment) - ); - } - - action_result fundnetloan( const account_name& from, const uint64_t loan_num, const asset& payment ) { - return push_action( name(from), N(fundnetloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("payment", payment) - ); - } - - - action_result defundcpuloan( const account_name& from, const uint64_t loan_num, const asset& amount ) { - return push_action( name(from), N(defcpuloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("amount", amount) - ); - } - - action_result defundnetloan( const account_name& from, const uint64_t loan_num, const asset& amount ) { - return push_action( name(from), N(defnetloan), mvo() - ("from", from) - ("loan_num", loan_num) - ("amount", amount) - ); - } - - action_result updaterex( const account_name& owner ) { - return push_action( name(owner), N(updaterex), mvo()("owner", owner) ); - } - - action_result rexexec( const account_name& user, uint16_t max ) { - return push_action( name(user), N(rexexec), mvo()("user", user)("max", max) ); - } - - action_result consolidate( const account_name& owner ) { - return push_action( name(owner), N(consolidate), mvo()("owner", owner) ); - } - - action_result mvtosavings( const account_name& owner, const asset& rex ) { - return push_action( name(owner), N(mvtosavings), mvo()("owner", owner)("rex", rex) ); - } - - action_result mvfrsavings( const account_name& owner, const asset& rex ) { - return push_action( name(owner), N(mvfrsavings), mvo()("owner", owner)("rex", rex) ); - } - - action_result closerex( const account_name& owner ) { - return push_action( name(owner), N(closerex), mvo()("owner", owner) ); - } - - fc::variant get_last_loan(bool cpu) { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - auto table = cpu ? N(cpuloan) : N(netloan); - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, table ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.upper_bound( boost::make_tuple( t_id->id, std::numeric_limits::max() )); - if ( itr == idx.begin() ) { - return fc::variant(); - } - --itr; - if ( itr->t_id != t_id->id ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_last_cpu_loan() { - return get_last_loan( true ); - } - - fc::variant get_last_net_loan() { - return get_last_loan( false ); - } - - fc::variant get_loan_info( const uint64_t& loan_num, bool cpu ) const { - name table_name = cpu ? N(cpuloan) : N(netloan); - vector data = get_row_by_account( config::system_account_name, config::system_account_name, table_name, account_name(loan_num) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_loan", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_cpu_loan( const uint64_t loan_num ) const { - return get_loan_info( loan_num, true ); - } - - fc::variant get_net_loan( const uint64_t loan_num ) const { - return get_loan_info( loan_num, false ); - } - - fc::variant get_dbw_obj( const account_name& from, const account_name& receiver ) const { - vector data = get_row_by_account( config::system_account_name, from, N(delband), receiver ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant("delegated_bandwidth", data, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - asset get_rex_balance( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? asset(0, symbol(SY(4, REX))) : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time))["rex_balance"].as(); - } - - fc::variant get_rex_balance_obj( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - asset get_rex_fund( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); - return data.empty() ? asset(0, symbol{CORE_SYM}) : abi_ser.binary_to_variant("rex_fund", data, abi_serializer::create_yield_function(abi_serializer_max_time))["balance"].as(); - } - - fc::variant get_rex_fund_obj( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexfund), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_fund", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - asset get_rex_vote_stake( const account_name& act ) const { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexbal), act ); - return data.empty() ? core_sym::from_string("0.0000") : abi_ser.binary_to_variant("rex_balance", data, abi_serializer::create_yield_function(abi_serializer_max_time))["vote_stake"].as(); - } - - fc::variant get_rex_order( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); - return abi_ser.binary_to_variant( "rex_order", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_order_obj( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(rexqueue), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_order", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_pool() const { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(rexpool) ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); - if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_pool", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_return_pool() const { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(rexretpool) ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); - if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_pool", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_rex_return_buckets() const { - vector data; - const auto& db = control->db(); - namespace chain = eosio::chain; - const auto* t_id = db.find( boost::make_tuple( config::system_account_name, config::system_account_name, N(retbuckets) ) ); - if ( !t_id ) { - return fc::variant(); - } - - const auto& idx = db.get_index(); - - auto itr = idx.lower_bound( boost::make_tuple( t_id->id, 0 ) ); - if ( itr == idx.end() || itr->t_id != t_id->id || 0 != itr->primary_key ) { - return fc::variant(); - } - - data.resize( itr->value.size() ); - memcpy( data.data(), itr->value.data(), data.size() ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "rex_return_buckets", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - void setup_rex_accounts( const std::vector& accounts, - const asset& init_balance, - const asset& net = core_sym::from_string("80.0000"), - const asset& cpu = core_sym::from_string("80.0000"), - bool deposit_into_rex_fund = true ) { - const asset nstake = core_sym::from_string("10.0000"); - const asset cstake = core_sym::from_string("10.0000"); - create_account_with_resources( N(proxyaccount), config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(proxyaccount), N(regproxy), mvo()("proxy", "proxyaccount")("isproxy", true) ) ); - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, init_balance + nstake + cstake, config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( a, a, nstake, cstake) ); - BOOST_REQUIRE_EQUAL( success(), vote( a, { }, N(proxyaccount) ) ); - BOOST_REQUIRE_EQUAL( init_balance, get_balance(a) ); - BOOST_REQUIRE_EQUAL( asset::from_string("0.0000 REX"), get_rex_balance(a) ); - if (deposit_into_rex_fund) { - BOOST_REQUIRE_EQUAL( success(), deposit( a, init_balance ) ); - BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( a ) ); - BOOST_REQUIRE_EQUAL( 0, get_balance( a ).get_amount() ); - } - } - } - - action_result bidname( const account_name& bidder, const account_name& newname, const asset& bid ) { - return push_action( name(bidder), N(bidname), mvo() - ("bidder", bidder) - ("newname", newname) - ("bid", bid) - ); - } - action_result bidname( std::string_view bidder, std::string_view newname, const asset& bid ) { - return bidname( account_name(bidder), account_name(newname), bid ); - } - - static fc::variant_object producer_parameters_example( int n ) { - return mutable_variant_object() - ("max_block_net_usage", 10000000 + n ) - ("target_block_net_usage_pct", 10 + n ) - ("max_transaction_net_usage", 1000000 + n ) - ("base_per_transaction_net_usage", 100 + n) - ("net_usage_leeway", 500 + n ) - ("context_free_discount_net_usage_num", 1 + n ) - ("context_free_discount_net_usage_den", 100 + n ) - ("max_block_cpu_usage", 10000000 + n ) - ("target_block_cpu_usage_pct", 10 + n ) - ("max_transaction_cpu_usage", 1000000 + n ) - ("min_transaction_cpu_usage", 100 + n ) - ("max_transaction_lifetime", 3600 + n) - ("deferred_trx_expiration_window", 600 + n) - ("max_transaction_delay", 10*86400+n) - ("max_inline_action_size", 4096 + n) - ("max_inline_action_depth", 4 + n) - ("max_authority_depth", 6 + n) - ("max_ram_size", (n % 10 + 1) * 1024 * 1024) - ("ram_reserve_ratio", 100 + n); - } - - action_result regproducer( const account_name& acnt, int params_fixture = 1 ) { - action_result r = push_action( acnt, N(regproducer), mvo() - ("producer", acnt ) - ("producer_key", get_public_key( acnt, "active" ) ) - ("url", "" ) - ("location", 0 ) - ); - BOOST_REQUIRE_EQUAL( success(), r); - return r; - } - - action_result vote( const account_name& voter, const std::vector& producers, const account_name& proxy = name(0) ) { - return push_action(voter, N(voteproducer), mvo() - ("voter", voter) - ("proxy", proxy) - ("producers", producers)); - } - action_result vote( const account_name& voter, const std::vector& producers, std::string_view proxy ) { - return vote( voter, producers, account_name(proxy) ); - } - - uint32_t last_block_time() const { - return time_point_sec( control->head_block_time() ).sec_since_epoch(); - } - - asset get_balance( const account_name& act, symbol balance_symbol = symbol{CORE_SYM} ) { - vector data = get_row_by_account( N(eosio.token), act, N(accounts), account_name(balance_symbol.to_symbol_code().value) ); - return data.empty() ? asset(0, balance_symbol) : token_abi_ser.binary_to_variant("account", data, abi_serializer::create_yield_function(abi_serializer_max_time))["balance"].as(); - } - - asset get_balance( std::string_view act, symbol balance_symbol = symbol{CORE_SYM} ) { - return get_balance( account_name(act), balance_symbol ); - } - - fc::variant get_total_stake( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, act, N(userres), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "user_resources", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_total_stake( std::string_view act ) { - return get_total_stake( account_name(act) ); - } - - fc::variant get_voter_info( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(voters), act ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "voter_info", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_voter_info( std::string_view act ) { - return get_voter_info( account_name(act) ); - } - - fc::variant get_producer_info( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers), act ); - return abi_ser.binary_to_variant( "producer_info", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_producer_info( std::string_view act ) { - return get_producer_info( account_name(act) ); - } - - fc::variant get_producer_info2( const account_name& act ) { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(producers2), act ); - return abi_ser.binary_to_variant( "producer_info2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - fc::variant get_producer_info2( std::string_view act ) { - return get_producer_info2( account_name(act) ); - } - - void create_currency( name contract, name manager, asset maxsupply ) { - auto act = mutable_variant_object() - ("issuer", manager ) - ("maximum_supply", maxsupply ); - - base_tester::push_action(contract, N(create), contract, act ); - } - - void issue( const asset& amount, const name& manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(issue), manager, mutable_variant_object() - ("to", manager ) - ("quantity", amount ) - ("memo", "") - ); - } - - void transfer( const name& from, const name& to, const asset& amount, const name& manager = config::system_account_name ) { - base_tester::push_action( N(eosio.token), N(transfer), manager, mutable_variant_object() - ("from", from) - ("to", to ) - ("quantity", amount) - ("memo", "") - ); - } - - void transfer( const name& from, std::string_view to, const asset& amount, const name& manager = config::system_account_name ) { - transfer( from, name(to), amount, manager ); - } - - void transfer( std::string_view from, std::string_view to, const asset& amount, std::string_view manager ) { - transfer( name(from), name(to), amount, name(manager) ); - } - - void transfer( std::string_view from, std::string_view to, const asset& amount ) { - transfer( name(from), name(to), amount ); - } - - void issue_and_transfer( const name& to, const asset& amount, const name& manager = config::system_account_name ) { - signed_transaction trx; - trx.actions.emplace_back( get_action( N(eosio.token), N(issue), - vector{{manager, config::active_name}}, - mutable_variant_object() - ("to", manager ) - ("quantity", amount ) - ("memo", "") - ) - ); - if ( to != manager ) { - trx.actions.emplace_back( get_action( N(eosio.token), N(transfer), - vector{{manager, config::active_name}}, - mutable_variant_object() - ("from", manager) - ("to", to ) - ("quantity", amount ) - ("memo", "") - ) - ); - } - set_transaction_headers( trx ); - trx.sign( get_private_key( manager, "active" ), control->get_chain_id() ); - push_transaction( trx ); - } - - void issue_and_transfer( std::string_view to, const asset& amount, std::string_view manager ) { - issue_and_transfer( name(to), amount, name(manager) ); - } - - void issue_and_transfer( std::string_view to, const asset& amount, const name& manager ) { - issue_and_transfer( name(to), amount, manager); - } - - void issue_and_transfer( std::string_view to, const asset& amount ) { - issue_and_transfer( name(to), amount ); - } - - double stake2votes( asset stake ) { - auto now = control->pending_block_time().time_since_epoch().count() / 1000000; - return stake.get_amount() * pow(2, int64_t((now - (config::block_timestamp_epoch / 1000)) / (86400 * 7))/ double(52) ); // 52 week periods (i.e. ~years) - } - - double stake2votes( const string& s ) { - return stake2votes( core_sym::from_string(s) ); - } - - fc::variant get_stats( const string& symbolname ) { - auto symb = eosio::chain::symbol::from_string(symbolname); - auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); - return data.empty() ? fc::variant() : token_abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - asset get_token_supply() { - return get_stats("4," CORE_SYM_NAME)["supply"].as(); - } - - uint64_t microseconds_since_epoch_of_iso_string( const fc::variant& v ) { - return static_cast( time_point::from_iso_string( v.as_string() ).time_since_epoch().count() ); - } - - fc::variant get_global_state() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global), N(global) ); - if (data.empty()) std::cout << "\nData is empty\n" << std::endl; - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_global_state2() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global2), N(global2) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state2", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_global_state3() { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, N(global3), N(global3) ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "eosio_global_state3", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - fc::variant get_refund_request( name account ) { - vector data = get_row_by_account( config::system_account_name, account, N(refunds), account ); - return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "refund_request", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - } - - abi_serializer initialize_multisig() { - abi_serializer msig_abi_ser; - { - create_account_with_resources( N(eosio.msig), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( N(eosio), N(eosio.msig), core_sym::from_string("5000.0000") ) ); - produce_block(); - - auto trace = base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.msig") - ("is_priv", 1) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - - produce_blocks(); - const auto& accnt = control->db().get( N(eosio.msig) ); - abi_def msig_abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, msig_abi), true); - msig_abi_ser.set_abi(msig_abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - } - return msig_abi_ser; - } - - vector active_and_vote_producers() { - //stake more than 15% of total EOS supply to activate chain - transfer( N(eosio), N(alice1111111), core_sym::from_string("650000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), N(alice1111111), core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c < 'a'+21; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - } - } - produce_blocks( 250); - - auto trace_auth = TESTER::push_action(config::system_account_name, updateauth::get_name(), config::system_account_name, mvo() - ("account", name(config::system_account_name).to_string()) - ("permission", name(config::active_name).to_string()) - ("parent", name(config::owner_name).to_string()) - ("auth", authority(1, {key_weight{get_public_key( config::system_account_name, "active" ), 1}}, { - permission_level_weight{{config::system_account_name, config::eosio_code_name}, 1}, - permission_level_weight{{config::producers_account_name, config::active_name}, 1} - } - )) - ); - BOOST_REQUIRE_EQUAL(transaction_receipt::executed, trace_auth->receipt->status); - - //vote for producers - { - transfer( config::system_account_name, N(alice1111111), core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake( N(alice1111111), core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), buyram( N(alice1111111), N(alice1111111), core_sym::from_string("30000000.0000") ) ); - BOOST_REQUIRE_EQUAL(success(), push_action(N(alice1111111), N(voteproducer), mvo() - ("voter", "alice1111111") - ("proxy", name(0).to_string()) - ("producers", vector(producer_names.begin(), producer_names.begin()+21)) - ) - ); - } - produce_blocks( 250 ); - - auto producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 21, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducera"), producer_keys[0].producer_name ); - - return producer_names; - } - - void cross_15_percent_threshold() { - setup_producer_accounts({N(producer1111)}); - regproducer(N(producer1111)); - { - signed_transaction trx; - set_transaction_headers(trx); - - trx.actions.emplace_back( get_action( config::system_account_name, N(delegatebw), - vector{{config::system_account_name, config::active_name}}, - mvo() - ("from", name{config::system_account_name}) - ("receiver", "producer1111") - ("stake_net_quantity", core_sym::from_string("150000000.0000") ) - ("stake_cpu_quantity", core_sym::from_string("0.0000") ) - ("transfer", 1 ) - ) - ); - trx.actions.emplace_back( get_action( config::system_account_name, N(voteproducer), - vector{{N(producer1111), config::active_name}}, - mvo() - ("voter", "producer1111") - ("proxy", name(0).to_string()) - ("producers", vector(1, N(producer1111))) - ) - ); - trx.actions.emplace_back( get_action( config::system_account_name, N(undelegatebw), - vector{{N(producer1111), config::active_name}}, - mvo() - ("from", "producer1111") - ("receiver", "producer1111") - ("unstake_net_quantity", core_sym::from_string("150000000.0000") ) - ("unstake_cpu_quantity", core_sym::from_string("0.0000") ) - ) - ); - - set_transaction_headers(trx); - trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); - trx.sign( get_private_key( N(producer1111), "active" ), control->get_chain_id() ); - push_transaction( trx ); - produce_block(); - } - } - - action_result setinflation( int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor ) { - return push_action( N(eosio), N(setinflation), mvo() - ("annual_rate", annual_rate) - ("inflation_pay_factor", inflation_pay_factor) - ("votepay_factor", votepay_factor) - ); - } - - abi_serializer abi_ser; - abi_serializer token_abi_ser; -}; - -inline fc::mutable_variant_object voter( account_name acct ) { - return mutable_variant_object() - ("owner", acct) - ("proxy", name(0).to_string()) - ("producers", variants() ) - ("staked", int64_t(0)) - //("last_vote_weight", double(0)) - ("proxied_vote_weight", double(0)) - ("is_proxy", 0) - ; -} -inline fc::mutable_variant_object voter( std::string_view acct ) { - return voter( account_name(acct) ); -} - -inline fc::mutable_variant_object voter( account_name acct, const asset& vote_stake ) { - return voter( acct )( "staked", vote_stake.get_amount() ); -} -inline fc::mutable_variant_object voter( std::string_view acct, const asset& vote_stake ) { - return voter( account_name(acct), vote_stake ); -} - -inline fc::mutable_variant_object voter( account_name acct, int64_t vote_stake ) { - return voter( acct )( "staked", vote_stake ); -} -inline fc::mutable_variant_object voter( std::string_view acct, int64_t vote_stake ) { - return voter( account_name(acct), vote_stake ); -} - -inline fc::mutable_variant_object proxy( account_name acct ) { - return voter( acct )( "is_proxy", 1 ); -} - -inline uint64_t M( const string& eos_str ) { - return core_sym::from_string( eos_str ).get_amount(); -} - -} diff --git a/tests/eosio.system_tests.cpp b/tests/eosio.system_tests.cpp deleted file mode 100644 index dbbf46d4..00000000 --- a/tests/eosio.system_tests.cpp +++ /dev/null @@ -1,5712 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "eosio.system_tester.hpp" -struct _abi_hash { - name owner; - fc::sha256 hash; -}; -FC_REFLECT( _abi_hash, (owner)(hash) ); - -struct connector { - asset balance; - double weight = .5; -}; -FC_REFLECT( connector, (balance)(weight) ); - -using namespace eosio_system; - -BOOST_AUTO_TEST_SUITE(eosio_system_tests) - -bool within_error(int64_t a, int64_t b, int64_t err) { return std::abs(a - b) <= err; }; -bool within_one(int64_t a, int64_t b) { return within_error(a, b, 1); } - -BOOST_FIXTURE_TEST_CASE( buysell, eosio_system_tester ) try { - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - auto init_bytes = total["ram_bytes"].as_uint64(); - - const asset initial_ram_balance = get_balance(N(eosio.ram)); - const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("800.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( initial_ram_balance + core_sym::from_string("199.0000"), get_balance(N(eosio.ram)) ); - BOOST_REQUIRE_EQUAL( initial_ramfee_balance + core_sym::from_string("1.0000"), get_balance(N(eosio.ramfee)) ); - - total = get_total_stake( "alice1111111" ); - auto bytes = total["ram_bytes"].as_uint64(); - auto bought_bytes = bytes - init_bytes; - wdump((init_bytes)(bought_bytes)(bytes) ); - - BOOST_REQUIRE_EQUAL( true, 0 < bought_bytes ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("998.0049"), get_balance( "alice1111111" ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - - transfer( "eosio", "alice1111111", core_sym::from_string("100000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100000998.0049"), get_balance( "alice1111111" ) ); - // alice buys ram for 10000000.0000, 0.5% = 50000.0000 go to ramfee - // after fee 9950000.0000 go to bought bytes - // when selling back bought bytes, pay 0.5% fee and get back 99.5% of 9950000.0000 = 9900250.0000 - // expected account after that is 90000998.0049 + 9900250.0000 = 99901248.0049 with a difference - // of order 0.0001 due to rounding errors - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("90000998.0049"), get_balance( "alice1111111" ) ); - - total = get_total_stake( "alice1111111" ); - bytes = total["ram_bytes"].as_uint64(); - bought_bytes = bytes - init_bytes; - wdump((init_bytes)(bought_bytes)(bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - total = get_total_stake( "alice1111111" ); - - bytes = total["ram_bytes"].as_uint64(); - bought_bytes = bytes - init_bytes; - wdump((init_bytes)(bought_bytes)(bytes) ); - - BOOST_REQUIRE_EQUAL( true, total["ram_bytes"].as_uint64() == init_bytes ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("99901248.0048"), get_balance( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("30.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("99900688.0048"), get_balance( "alice1111111" ) ); - - auto newtotal = get_total_stake( "alice1111111" ); - - auto newbytes = newtotal["ram_bytes"].as_uint64(); - bought_bytes = newbytes - bytes; - wdump((newbytes)(bytes)(bought_bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("99901242.4187"), get_balance( "alice1111111" ) ); - - newtotal = get_total_stake( "alice1111111" ); - auto startbytes = newtotal["ram_bytes"].as_uint64(); - - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("10000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("300000.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("49301242.4187"), get_balance( "alice1111111" ) ); - - auto finaltotal = get_total_stake( "alice1111111" ); - auto endbytes = finaltotal["ram_bytes"].as_uint64(); - - bought_bytes = endbytes - startbytes; - wdump((startbytes)(endbytes)(bought_bytes) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", bought_bytes ) ); - - BOOST_REQUIRE_EQUAL( false, get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ).empty() ); - - auto get_ram_market = [this]() -> fc::variant { - vector data = get_row_by_account( config::system_account_name, config::system_account_name, - N(rammarket), account_name(symbol{SY(4,RAMCORE)}.value()) ); - BOOST_REQUIRE( !data.empty() ); - return abi_ser.binary_to_variant("exchange_state", data, abi_serializer::create_yield_function(abi_serializer_max_time)); - }; - - { - transfer( config::system_account_name, N(alice1111111), core_sym::from_string("10000000.0000"), config::system_account_name ); - uint64_t bytes0 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); - - auto market = get_ram_market(); - const asset r0 = market["base"].as().balance; - const asset e0 = market["quote"].as().balance; - BOOST_REQUIRE_EQUAL( asset::from_string("0 RAM").get_symbol(), r0.get_symbol() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000").get_symbol(), e0.get_symbol() ); - - const asset payment = core_sym::from_string("10000000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", payment ) ); - uint64_t bytes1 = get_total_stake( "alice1111111" )["ram_bytes"].as_uint64(); - - const int64_t fee = (payment.get_amount() + 199) / 200; - const double net_payment = payment.get_amount() - fee; - const int64_t expected_delta = net_payment * r0.get_amount() / ( net_payment + e0.get_amount() ); - - BOOST_REQUIRE_EQUAL( expected_delta, bytes1 - bytes0 ); - } - - { - transfer( config::system_account_name, N(bob111111111), core_sym::from_string("100000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must reserve a positive amount"), - buyrambytes( "bob111111111", "bob111111111", 1 ) ); - - uint64_t bytes0 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "bob111111111", "bob111111111", 1024 ) ); - uint64_t bytes1 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); - BOOST_REQUIRE( within_one( 1024, bytes1 - bytes0 ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "bob111111111", "bob111111111", 1024 * 1024) ); - uint64_t bytes2 = get_total_stake( "bob111111111" )["ram_bytes"].as_uint64(); - BOOST_REQUIRE( within_one( 1024 * 1024, bytes2 - bytes1 ) ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_unstake, eosio_system_tester ) try { - cross_15_percent_threshold(); - - produce_blocks( 10 ); - produce_block( fc::hours(3*24) ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - const auto init_eosio_stake_balance = get_balance( N(eosio.stake) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_sym::from_string("300.0000"), get_balance( N(eosio.stake) ) ); - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance + core_sym::from_string("300.0000"), get_balance( N(eosio.stake) ) ); - //after 3 days funds should be released - produce_block( fc::hours(1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( init_eosio_stake_balance, get_balance( N(eosio.stake) ) ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - total = get_total_stake("bob111111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000").get_amount(), total["net_weight"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000").get_amount(), total["cpu_weight"].as().get_amount() ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - - auto bytes = total["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( true, 0 < bytes ); - - //unstake from bob111111111 - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - total = get_total_stake("bob111111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //after 3 days funds should be released - produce_block( fc::hours(1) ); - produce_blocks(1); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000") ), get_voter_info( "alice1111111" ) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_unstake_with_transfer, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //eosio stakes for alice with transfer flag - - transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - //check that alice has both bandwidth and voting power - auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //alice stakes for herself - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - //now alice's stake should be equal to transfered from eosio + own stake - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("600.0000")), get_voter_info( "alice1111111" ) ); - - //alice can unstake everything (including what was transfered) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("400.0000"), core_sym::from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //after 3 days funds should be released - - produce_block( fc::hours(1) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1300.0000"), get_balance( "alice1111111" ) ); - - //stake should be equal to what was staked in constructor, voting power should be 0 - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); - - // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_to_self_with_transfer, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot use transfer flag if delegating to self"), - stake_with_transfer( N(alice1111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_while_pending_refund, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //eosio stakes for alice with transfer flag - transfer( "eosio", "bob111111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(bob111111111), N(alice1111111), core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - //check that alice has both bandwidth and voting power - auto total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000")), get_voter_info( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - - //alice stakes for herself - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - //now alice's stake should be equal to transfered from eosio + own stake - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("410.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("600.0000")), get_voter_info( "alice1111111" ) ); - - //alice can unstake everything (including what was transfered) - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("400.0000"), core_sym::from_string("200.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - produce_block( fc::hours(3*24-1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //after 3 days funds should be released - - produce_block( fc::hours(1) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("1300.0000"), get_balance( "alice1111111" ) ); - - //stake should be equal to what was staked in constructor, voting power should be 0 - total = get_total_stake("alice1111111"); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("0.0000")), get_voter_info( "alice1111111" ) ); - - // Now alice stakes to bob with transfer flag - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( fail_without_auth, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("2000.0000"), core_sym::from_string("1000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("10.0000") ) ); - - BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), - push_action( N(alice1111111), N(delegatebw), mvo() - ("from", "alice1111111") - ("receiver", "bob111111111") - ("stake_net_quantity", core_sym::from_string("10.0000")) - ("stake_cpu_quantity", core_sym::from_string("10.0000")) - ("transfer", 0 ) - ,false - ) - ); - - BOOST_REQUIRE_EQUAL( error("missing authority of alice1111111"), - push_action(N(alice1111111), N(undelegatebw), mvo() - ("from", "alice1111111") - ("receiver", "bob111111111") - ("unstake_net_quantity", core_sym::from_string("200.0000")) - ("unstake_cpu_quantity", core_sym::from_string("100.0000")) - ("transfer", 0 ) - ,false - ) - ); - //REQUIRE_MATCHING_OBJECT( , get_voter_info( "alice1111111" ) ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( stake_negative, eosio_system_tester ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("-0.0001"), core_sym::from_string("0.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("-0.0001") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("00.0000"), core_sym::from_string("00.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must stake a positive amount"), - stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("00.0000") ) - - ); - - BOOST_REQUIRE_EQUAL( true, get_voter_info( "alice1111111" ).is_null() ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unstake_negative, eosio_system_tester ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0001"), core_sym::from_string("100.0001") ) ); - - auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0001"), total["net_weight"].as()); - auto vinfo = get_voter_info("alice1111111" ); - wdump((vinfo)); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0002") ), get_voter_info( "alice1111111" ) ); - - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("-1.0000"), core_sym::from_string("0.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("-1.0000") ) - ); - - //unstake all zeros - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("0.0000") ) - - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unstake_more_than_at_stake, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - //trying to unstake more net bandwith than at stake - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111", core_sym::from_string("200.0001"), core_sym::from_string("0.0000") ) - ); - - //trying to unstake more cpu bandwith than at stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("100.0001") ) - - ); - - //check that nothing has changed - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( delegate_to_another_user, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - BOOST_REQUIRE_EQUAL( success(), stake ( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //all voting power goes to alice1111111 - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - //but not to bob111111111 - BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); - - //bob111111111 should not be able to unstake what was staked by alice1111111 - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "bob111111111", core_sym::from_string("0.0000"), core_sym::from_string("10.0000") ) - - ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "bob111111111", core_sym::from_string("10.0000"), core_sym::from_string("0.0000") ) - ); - - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", "bob111111111", core_sym::from_string("20.0000"), core_sym::from_string("10.0000") ) ); - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_balance( "carol1111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("30.0000") ), get_voter_info( "carol1111111" ) ); - - //alice1111111 should not be able to unstake money staked by carol1111111 - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked net bandwidth"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("2001.0000"), core_sym::from_string("1.0000") ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient staked cpu bandwidth"), - unstake( "alice1111111", "bob111111111", core_sym::from_string("1.0000"), core_sym::from_string("101.0000") ) - - ); - - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["cpu_weight"].as()); - //balance should not change after unsuccessfull attempts to unstake - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - //voting power too - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("30.0000") ), get_voter_info( "carol1111111" ) ); - BOOST_REQUIRE_EQUAL( true, get_voter_info( "bob111111111" ).is_null() ); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( stake_unstake_separate, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance( "alice1111111" ) ); - - //everything at once - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("10.0000"), core_sym::from_string("20.0000") ) ); - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); - - //cpu - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("0.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); - - //net - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("200.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("120.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["cpu_weight"].as()); - - //unstake cpu - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("0.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("230.0000"), total["cpu_weight"].as()); - - //unstake net - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("0.0000"), core_sym::from_string("200.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("20.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), total["cpu_weight"].as()); -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( adding_stake_partial_unstake, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); - - auto total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("450.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("550.0000"), get_balance( "alice1111111" ) ); - - //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("150.0000"), core_sym::from_string("75.0000") ) ); - - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("225.0000") ), get_voter_info( "alice1111111" ) ); - - //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("150.0000") ), get_voter_info( "alice1111111" ) ); - - //combined amount should be available only in 3 days - produce_block( fc::days(2) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("550.0000"), get_balance( "alice1111111" ) ); - produce_block( fc::days(1) ); - produce_blocks(1); - BOOST_REQUIRE_EQUAL( core_sym::from_string("850.0000"), get_balance( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_from_refund, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("400.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); - - //unstake a share - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("250.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("600.0000"), get_balance( "alice1111111" ) ); - auto refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); - //XXX auto request_time = refund["request_time"].as_int64(); - - //alice delegates to bob, should pull from liquid balance not refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("60.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("350.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "50.0000"), refund["cpu_amount"].as() ); - - //stake less than pending refund, entire amount should be taken from refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("160.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("85.0000"), total["cpu_weight"].as()); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("50.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("25.0000"), refund["cpu_amount"].as() ); - //request time should stay the same - //BOOST_REQUIRE_EQUAL( request_time, refund["request_time"].as_int64() ); - //balance should stay the same - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - - //stake exactly pending refund amount - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("50.0000"), core_sym::from_string("25.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - //pending refund should be removed - refund = get_refund_request( N(alice1111111) ); - BOOST_TEST_REQUIRE( refund.is_null() ); - //balance should stay the same - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - - //create pending refund again - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("10.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("500.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); - - //stake more than pending refund - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300.0000"), core_sym::from_string("200.0000") ) ); - total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("310.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["cpu_weight"].as()); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("700.0000") ), get_voter_info( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_TEST_REQUIRE( refund.is_null() ); - //200 core tokens should be taken from alice's account - BOOST_REQUIRE_EQUAL( core_sym::from_string("300.0000"), get_balance( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( stake_to_another_user_not_from_refund, eosio_system_tester ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - auto total = get_total_stake( "alice1111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - REQUIRE_MATCHING_OBJECT( voter( "alice1111111", core_sym::from_string("300.0000") ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance( "alice1111111" ) ); - - //unstake - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - auto refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); - //auto orig_request_time = refund["request_time"].as_int64(); - - //stake to another user - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "bob111111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - total = get_total_stake( "bob111111111" ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("210.0000"), total["net_weight"].as()); - BOOST_REQUIRE_EQUAL( core_sym::from_string("110.0000"), total["cpu_weight"].as()); - //stake should be taken from alices' balance, and refund request should stay the same - BOOST_REQUIRE_EQUAL( core_sym::from_string("400.0000"), get_balance( "alice1111111" ) ); - refund = get_refund_request( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("200.0000"), refund["net_amount"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("100.0000"), refund["cpu_amount"].as() ); - //BOOST_REQUIRE_EQUAL( orig_request_time, refund["request_time"].as_int64() ); - -} FC_LOG_AND_RETHROW() - -// Tests for voting -BOOST_FIXTURE_TEST_CASE( producer_register_unregister, eosio_system_tester ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - - //fc::variant params = producer_parameters_example(1); - auto key = fc::crypto::public_key( std::string("EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV") ); - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", key ) - ("url", "http://block.one") - ("location", 1) - ) - ); - - auto info = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( 0, info["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "http://block.one", info["url"].as_string() ); - - //change parameters one by one to check for things like #3783 - //fc::variant params2 = producer_parameters_example(2); - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", key ) - ("url", "http://block.two") - ("location", 1) - ) - ); - info = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( key, fc::crypto::public_key(info["producer_key"].as_string()) ); - BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); - BOOST_REQUIRE_EQUAL( 1, info["location"].as_int64() ); - - auto key2 = fc::crypto::public_key( std::string("EOS5jnmSKrzdBHE9n8hw58y7yxFWBC8SNiG7m8S1crJH3KvAnf9o6") ); - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", key2 ) - ("url", "http://block.two") - ("location", 2) - ) - ); - info = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( key2, fc::crypto::public_key(info["producer_key"].as_string()) ); - BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); - BOOST_REQUIRE_EQUAL( 2, info["location"].as_int64() ); - - //unregister producer - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(unregprod), mvo() - ("producer", "alice1111111") - ) - ); - info = get_producer_info( "alice1111111" ); - //key should be empty - BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(info["producer_key"].as_string()) ); - //everything else should stay the same - BOOST_REQUIRE_EQUAL( "alice1111111", info["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( 0, info["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "http://block.two", info["url"].as_string() ); - - //unregister bob111111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer not found" ), - push_action( N(bob111111111), N(unregprod), mvo() - ("producer", "bob111111111") - ) - ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( producer_wtmsig, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( control->active_producers().version, 0u ); - - issue_and_transfer( N(alice1111111), core_sym::from_string("200000000.0000"), config::system_account_name ); - block_signing_authority_v0 alice_signing_authority; - alice_signing_authority.threshold = 1; - alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs1"), .weight = 1} ); - alice_signing_authority.keys.push_back( {.key = get_public_key( N(alice1111111), "bs2"), .weight = 1} ); - producer_authority alice_producer_authority = {.producer_name = N(alice1111111), .authority = alice_signing_authority}; - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); - - block_signing_private_keys.emplace(get_public_key(N(alice1111111), "bs1"), get_private_key(N(alice1111111), "bs1")); - - auto alice_prod_info = get_producer_info( N(alice1111111) ); - wdump((alice_prod_info)); - BOOST_REQUIRE_EQUAL( alice_prod_info["is_active"], true ); - - produce_block(); - produce_block( fc::minutes(2) ); - produce_blocks(2); - BOOST_REQUIRE_EQUAL( control->active_producers().version, 1u ); - produce_block(); - BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); - produce_block(); - - alice_signing_authority.threshold = 0; - alice_producer_authority.authority = alice_signing_authority; - - // Ensure an authority with a threshold of 0 is rejected. - BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - // Ensure an authority that is not satisfiable is rejected. - alice_signing_authority.threshold = 3; - alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - // Ensure an authority with duplicate keys is rejected. - alice_signing_authority.threshold = 1; - alice_signing_authority.keys[1] = alice_signing_authority.keys[0]; - alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( error("assertion failure with message: invalid producer authority"), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - // However, an authority with an invalid key is okay. - alice_signing_authority.keys[1] = {}; - alice_producer_authority.authority = alice_signing_authority; - BOOST_REQUIRE_EQUAL( success(), - push_action( N(alice1111111), N(regproducer2), mvo() - ("producer", "alice1111111") - ("producer_authority", alice_producer_authority.get_abi_variant()["authority"]) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - - produce_block(); - produce_block( fc::minutes(2) ); - produce_blocks(2); - BOOST_REQUIRE_EQUAL( control->active_producers().version, 2u ); - produce_block(); - BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); - produce_block(); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( producer_wtmsig_transition, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( control->active_producers().version, 0u ); - - set_code( config::system_account_name, contracts::util::system_wasm_v1_8() ); - set_abi( config::system_account_name, contracts::util::system_abi_v1_8().data() ); - - issue_and_transfer( N(alice1111111), core_sym::from_string("200000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - BOOST_REQUIRE_EQUAL( success(), stake( N(alice1111111), core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(alice1111111) } ) ); - - //auto alice_prod_info1 = get_producer_info( N(alice1111111) ); - //wdump((alice_prod_info1)); - - produce_block(); - produce_block( fc::minutes(2) ); - produce_blocks(2); - BOOST_REQUIRE_EQUAL( control->active_producers().version, 1u ); - - const auto schedule_update1 = get_global_state()["last_producer_schedule_update"]; - - const auto& rlm = control->get_resource_limits_manager(); - - auto alice_initial_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - - set_code( config::system_account_name, contracts::system_wasm() ); - set_abi( config::system_account_name, contracts::system_abi().data() ); - produce_block(); - BOOST_REQUIRE_EQUAL( control->pending_block_producer(), N(alice1111111) ); - - auto alice_prod_info2 = get_producer_info( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( alice_prod_info2["is_active"], true ); - - produce_block( fc::minutes(2) ); - const auto schedule_update2 = get_global_state()["last_producer_schedule_update"]; - BOOST_REQUIRE( schedule_update1 < schedule_update2 ); // Ensure last_producer_schedule_update is increasing. - - // Producing the above block would trigger the bug in v1.9.0 that sets the default block_signing_authority - // in the producer object of the currently active producer alice1111111. - // However, starting in v1.9.1, the producer object does not have a default block_signing_authority added to the - // serialization of the producer object if it was not already present in the binary extension field - // producer_authority to begin with. This is verified below by ensuring the RAM usage of alice (who pays for the - // producer object) does not increase. - - auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - BOOST_CHECK_EQUAL( alice_initial_ram_usage, alice_ram_usage ); - - auto alice_prod_info3 = get_producer_info( N(alice1111111) ); - if( alice_prod_info3.get_object().contains("producer_authority") ) { - BOOST_CHECK_EQUAL( alice_prod_info3["producer_authority"][1]["threshold"], 0 ); - } - - produce_block( fc::minutes(2) ); - const auto schedule_update3 = get_global_state()["last_producer_schedule_update"]; - - // The bug in v1.9.0 would cause alice to have an invalid producer authority (the default block_signing_authority). - // The v1.9.0 system contract would have attempted to set a proposed producer schedule including this invalid - // authority which would be rejected by the EOSIO native system and cause the onblock transaction to continue to fail. - // This could be observed by noticing that last_producer_schedule_update was not being updated even though it should. - // However, starting in v1.9.1, update_elected_producers is smarter about the producer schedule it constructs to - // propose to the system. It will recognize the default constructed authority (which shouldn't be created by the - // v1.9.1 system contract but may still exist in the tables if it was constructed by the buggy v1.9.0 system contract) - // and instead resort to constructing the block signing authority from the single producer key in the table. - // So newer system contracts should see onblock continue to function, which is verified by the check below. - - BOOST_CHECK( schedule_update2 < schedule_update3 ); // Ensure last_producer_schedule_update is increasing. - - // But even if the buggy v1.9.0 system contract was running, it should always still be possible to recover - // by having the producer with the invalid authority simply call regproducer or regproducer2 to correct their - // block signing authority. - - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - - produce_block(); - produce_block( fc::minutes(2) ); - - auto alice_prod_info4 = get_producer_info( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( alice_prod_info4["is_active"], true ); - const auto schedule_update4 = get_global_state()["last_producer_schedule_update"]; - BOOST_REQUIRE( schedule_update2 < schedule_update4 ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( vote_for_producer, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - cross_15_percent_threshold(); - - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "http://block.one") - ("location", 0 ) - ) - ); - auto prod = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( "alice1111111", prod["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( 0, prod["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); - - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - issue_and_transfer( "carol1111111", core_sym::from_string("3000.0000"), config::system_account_name ); - - //bob111111111 makes stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("11.0000"), core_sym::from_string("0.1111") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1988.8889"), get_balance( "bob111111111" ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("11.1111") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(alice1111111) } ) ); - - //check that producer parameters stay the same after voting - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("11.1111")) == prod["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( "alice1111111", prod["owner"].as_string() ); - BOOST_REQUIRE_EQUAL( "http://block.one", prod["url"].as_string() ); - - //carol1111111 makes stake - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("22.2222") ), get_voter_info( "carol1111111" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("2977.7778"), get_balance( "carol1111111" ) ); - //carol1111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); - - //new stake votes be added to alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("33.3333")) == prod["total_votes"].as_double() ); - - //bob111111111 increases his stake - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("33.0000"), core_sym::from_string("0.3333") ) ); - //alice1111111 stake with transfer to bob111111111 - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( N(alice1111111), N(bob111111111), core_sym::from_string("22.0000"), core_sym::from_string("0.2222") ) ); - //should increase alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("88.8888")) == prod["total_votes"].as_double() ); - - //carol1111111 unstakes part of the stake - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_sym::from_string("2.0000"), core_sym::from_string("0.0002")/*"2.0000 EOS", "0.0002 EOS"*/ ) ); - - //should decrease alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - wdump((prod)); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("86.8886")) == prod["total_votes"].as_double() ); - - //bob111111111 revokes his vote - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector() ) ); - - //should decrease alice1111111's total_votes - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.2220")) == prod["total_votes"].as_double() ); - //but eos should still be at stake - BOOST_REQUIRE_EQUAL( core_sym::from_string("1955.5556"), get_balance( "bob111111111" ) ); - - //carol1111111 unstakes rest of eos - BOOST_REQUIRE_EQUAL( success(), unstake( "carol1111111", core_sym::from_string("20.0000"), core_sym::from_string("0.2220") ) ); - //should decrease alice1111111's total_votes to zero - prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( 0.0 == prod["total_votes"].as_double() ); - - //carol1111111 should receive funds in 3 days - produce_block( fc::days(3) ); - produce_block(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("3000.0000"), get_balance( "carol1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unregistered_producer_voting, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer alice1111111 is not registered" ), - vote( N(bob111111111), { N(alice1111111) } ) ); - - //alice1111111 registers as a producer - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - //and then unregisters - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(unregprod), mvo() - ("producer", "alice1111111") - ) - ); - //key should be empty - auto prod = get_producer_info( "alice1111111" ); - BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(prod["producer_key"].as_string()) ); - - //bob111111111 should not be able to vote for alice1111111 who is an unregistered producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer alice1111111 is not currently registered" ), - vote( N(bob111111111), { N(alice1111111) } ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( more_than_30_producer_voting, eosio_system_tester ) try { - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "attempt to vote for too many producers" ), - vote( N(bob111111111), vector(31, N(alice1111111)) ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( vote_same_producer_30_times, eosio_system_tester ) try { - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("100.0000") ), get_voter_info( "bob111111111" ) ); - - //alice1111111 becomes a producer - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key(N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - - //bob111111111 should not be able to vote for alice1111111 who is not a producer - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "producer votes must be unique and sorted" ), - vote( N(bob111111111), vector(30, N(alice1111111)) ) ); - - auto prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( 0 == prod["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( producer_keep_votes, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - fc::variant params = producer_parameters_example(1); - vector key = fc::raw::pack( get_public_key( N(alice1111111), "active" ) ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - - //bob111111111 makes stake - issue_and_transfer( "bob111111111", core_sym::from_string("2000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("13.0000"), core_sym::from_string("0.5791") ) ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("13.5791") ), get_voter_info( "bob111111111" ) ); - - //bob111111111 votes for alice1111111 - BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), { N(alice1111111) } ) ); - - auto prod = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")) == prod["total_votes"].as_double() ); - - //unregister producer - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(unregprod), mvo() - ("producer", "alice1111111") - ) - ); - prod = get_producer_info( "alice1111111" ); - //key should be empty - BOOST_REQUIRE_EQUAL( fc::crypto::public_key(), fc::crypto::public_key(prod["producer_key"].as_string()) ); - //check parameters just in case - //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); - - //regtister the same producer again - params = producer_parameters_example(2); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url", "") - ("location", 0) - ) - ); - prod = get_producer_info( "alice1111111" ); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); - - //change parameters - params = producer_parameters_example(3); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - prod = get_producer_info( "alice1111111" ); - //votes should stay the same - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("13.5791")), prod["total_votes"].as_double() ); - //check parameters just in case - //REQUIRE_MATCHING_OBJECT( params, prod["prefs"]); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( vote_for_two_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - //alice1111111 becomes a producer - fc::variant params = producer_parameters_example(1); - auto key = get_public_key( N(alice1111111), "active" ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproducer), mvo() - ("producer", "alice1111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - //bob111111111 becomes a producer - params = producer_parameters_example(2); - key = get_public_key( N(bob111111111), "active" ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproducer), mvo() - ("producer", "bob111111111") - ("producer_key", get_public_key( N(alice1111111), "active") ) - ("url","") - ("location", 0) - ) - ); - - //carol1111111 votes for alice1111111 and bob111111111 - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("15.0005"), core_sym::from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111), N(bob111111111) } ) ); - - auto alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == alice_info["total_votes"].as_double() ); - auto bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == bob_info["total_votes"].as_double() ); - - //carol1111111 votes for alice1111111 (but revokes vote for bob111111111) - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), { N(alice1111111) } ) ); - - alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("20.0005")) == alice_info["total_votes"].as_double() ); - bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( 0 == bob_info["total_votes"].as_double() ); - - //alice1111111 votes for herself and bob111111111 - issue_and_transfer( "alice1111111", core_sym::from_string("2.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("1.0000"), core_sym::from_string("1.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(alice1111111), N(bob111111111) } ) ); - - alice_info = get_producer_info( "alice1111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("22.0005")) == alice_info["total_votes"].as_double() ); - - bob_info = get_producer_info( "bob111111111" ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("2.0000")) == bob_info["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_register_unregister_keeps_stake, eosio_system_tester ) try { - //register proxy by first action for this user ever - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true ) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //unregister proxy - BOOST_REQUIRE_EQUAL( success(), push_action(N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" ), get_voter_info( "alice1111111" ) ); - - //stake and then register as a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("200.0002"), core_sym::from_string("100.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() - ("proxy", "bob111111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(bob111111111) )( "staked", 3000003 ), get_voter_info( "bob111111111" ) ); - //unrgister and check that stake is still in place - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() - ("proxy", "bob111111111") - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "bob111111111", core_sym::from_string("300.0003") ), get_voter_info( "bob111111111" ) ); - - //register as a proxy and then stake - BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() - ("proxy", "carol1111111") - ("isproxy", true) - ) - ); - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("246.0002"), core_sym::from_string("531.0001") ) ); - //check that both proxy flag and stake a correct - REQUIRE_MATCHING_OBJECT( proxy( N(carol1111111) )( "staked", 7770003 ), get_voter_info( "carol1111111" ) ); - - //unregister - BOOST_REQUIRE_EQUAL( success(), push_action( N(carol1111111), N(regproxy), mvo() - ("proxy", "carol1111111") - ("isproxy", false) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "carol1111111", core_sym::from_string("777.0003") ), get_voter_info( "carol1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_stake_unstake_keeps_proxy_flag, eosio_system_tester ) try { - cross_15_percent_threshold(); - - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //stake - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("100.0000"), core_sym::from_string("50.0000") ) ); - //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 1500000 ), get_voter_info( "alice1111111" ) ); - - //stake more - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0000"), core_sym::from_string("20.0000") ) ); - //check that account is still a proxy - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 2000000 ), get_voter_info( "alice1111111" ) ); - - //unstake more - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )("staked", 1000000 ), get_voter_info( "alice1111111" ) ); - - //unstake the rest - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("65.0000"), core_sym::from_string("35.0000") ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 0 ), get_voter_info( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_actions_affect_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+5) ) try { - cross_15_percent_threshold(); - - create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); - - //register as a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - - //accumulate proxied votes - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(bob111111111), vector(), N(alice1111111) ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); - - //vote for producers - BOOST_REQUIRE_EQUAL( success(), vote(N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //vote for another producers - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer3) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //unregister proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", false) - ) - ); - //REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) ), get_voter_info( "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //register proxy again - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //stake increase by proxy itself affects producers - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( stake2votes(core_sym::from_string("200.0005")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( stake2votes(core_sym::from_string("200.0005")), get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //stake decrease by proxy itself affects producers - BOOST_REQUIRE_EQUAL( success(), unstake( "alice1111111", core_sym::from_string("10.0001"), core_sym::from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("180.0003")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("180.0003")) == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const double continuous_rate = std::log1p(double(0.05)); - const double usecs_per_year = 52 * 7 * 24 * 3600 * 1000000ll; - const double secs_per_year = 52 * 7 * 24 * 3600; - - - const asset large_asset = core_sym::from_string("80.0000"); - create_account_with_resources( N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); - produce_block(fc::hours(24)); - auto prod = get_producer_info( N(defproducera) ); - BOOST_REQUIRE_EQUAL("defproducera", prod["owner"].as_string()); - BOOST_REQUIRE_EQUAL(0, prod["total_votes"].as_double()); - - transfer( config::system_account_name, "producvotera", core_sym::from_string("400000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera) })); - // defproducera is the only active producer - // produce enough blocks so new schedule kicks in and defproducera produces some blocks - { - produce_blocks(50); - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - - prod = get_producer_info("defproducera"); - const uint32_t unpaid_blocks = prod["unpaid_blocks"].as(); - BOOST_REQUIRE(1 < unpaid_blocks); - - BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); - - const asset initial_supply = get_token_supply(); - const asset initial_balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - - prod = get_producer_info("defproducera"); - BOOST_REQUIRE_EQUAL(1, prod["unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(1, tot_unpaid_blocks); - const asset supply = get_token_supply(); - const asset balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(claim_time, microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); - - auto usecs_between_fills = claim_time - initial_claim_time; - int32_t secs_between_fills = usecs_between_fills/1000000; - - BOOST_REQUIRE_EQUAL(0, initial_savings); - BOOST_REQUIRE_EQUAL(0, initial_perblock_bucket); - BOOST_REQUIRE_EQUAL(0, initial_pervote_bucket); - - BOOST_REQUIRE_EQUAL(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * continuous_rate ) / secs_per_year ), - supply.get_amount() - initial_supply.get_amount()); - BOOST_REQUIRE(within_one(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (4. * continuous_rate/ 5.) / secs_per_year ) ), - savings - initial_savings)); - BOOST_REQUIRE(within_one(int64_t( ( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ), - balance.get_amount() - initial_balance.get_amount())); - - int64_t from_perblock_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.25 * continuous_rate/ 5.) / secs_per_year ) ; - int64_t from_pervote_bucket = int64_t( initial_supply.get_amount() * double(secs_between_fills) * (0.75 * continuous_rate/ 5.) / secs_per_year ) ; - - - if (from_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE_EQUAL(from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(0, pervote_bucket); - } else { - BOOST_REQUIRE_EQUAL(from_perblock_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(from_pervote_bucket, pervote_bucket); - } - } - - { - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - - // defproducera waits for 23 hours and 55 minutes, can't claim rewards yet - { - produce_block(fc::seconds(23 * 3600 + 55 * 60)); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - - // wait 5 more minutes, defproducera can now claim rewards again - { - produce_block(fc::seconds(5 * 60)); - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const double initial_tot_vote_weight = initial_global_state["total_producer_vote_weight"].as(); - - prod = get_producer_info("defproducera"); - const uint32_t unpaid_blocks = prod["unpaid_blocks"].as(); - BOOST_REQUIRE(1 < unpaid_blocks); - BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); - BOOST_REQUIRE(0 < prod["total_votes"].as()); - BOOST_TEST(initial_tot_vote_weight, prod["total_votes"].as()); - BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); - - BOOST_REQUIRE_EQUAL(initial_tot_unpaid_blocks, unpaid_blocks); - - const asset initial_supply = get_token_supply(); - const asset initial_balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - - prod = get_producer_info("defproducera"); - BOOST_REQUIRE_EQUAL(1, prod["unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(1, tot_unpaid_blocks); - const asset supply = get_token_supply(); - const asset balance = get_balance(N(defproducera)); - - BOOST_REQUIRE_EQUAL(claim_time, microseconds_since_epoch_of_iso_string( prod["last_claim_time"] )); - auto usecs_between_fills = claim_time - initial_claim_time; - - BOOST_REQUIRE_EQUAL( int64_t( initial_supply.get_amount() * double(usecs_between_fills) * continuous_rate / usecs_per_year ), - supply.get_amount() - initial_supply.get_amount() ); - BOOST_REQUIRE_EQUAL( (supply.get_amount() - initial_supply.get_amount()) - (supply.get_amount() - initial_supply.get_amount()) / 5, - savings - initial_savings ); - - int64_t to_producer = int64_t( initial_supply.get_amount() * double(usecs_between_fills) * continuous_rate / usecs_per_year ) / 5; - int64_t to_perblock_bucket = to_producer / 4; - int64_t to_pervote_bucket = to_producer - to_perblock_bucket; - - if (to_pervote_bucket + initial_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE_EQUAL(to_perblock_bucket + to_pervote_bucket + initial_pervote_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(0, pervote_bucket); - } else { - BOOST_REQUIRE_EQUAL(to_perblock_bucket, balance.get_amount() - initial_balance.get_amount()); - BOOST_REQUIRE_EQUAL(to_pervote_bucket + initial_pervote_bucket, pervote_bucket); - } - } - - // defproducerb tries to claim rewards but he's not on the list - { - BOOST_REQUIRE_EQUAL(wasm_assert_msg("unable to find key"), - push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); - } - - // test stability over a year - { - regproducer(N(defproducerb)); - regproducer(N(defproducerc)); - produce_block(fc::hours(24)); - const asset initial_supply = get_token_supply(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - for (uint32_t i = 0; i < 7 * 52; ++i) { - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerc), N(claimrewards), mvo()("owner", "defproducerc"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - const asset supply = get_token_supply(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - // Amount issued per year is very close to the 5% inflation target. Small difference (500 tokens out of 50'000'000 issued) - // is due to compounding every 8 hours in this test as opposed to theoretical continuous compounding - BOOST_REQUIRE(500 * 10000 > int64_t(double(initial_supply.get_amount()) * double(0.05)) - (supply.get_amount() - initial_supply.get_amount())); - BOOST_REQUIRE(500 * 10000 > int64_t(double(initial_supply.get_amount()) * double(0.04)) - (savings - initial_savings)); - } -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try { - - { - BOOST_REQUIRE_EQUAL( success(), - setinflation(0, 10000, 10000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("annual_rate can't be negative"), - setinflation(-1, 10000, 10000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("inflation_pay_factor must not be less than 10000"), - setinflation(1, 9999, 10000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("votepay_factor must not be less than 10000"), - setinflation(1, 10000, 9999) ); - } - - { - const asset large_asset = core_sym::from_string("80.0000"); - create_account_with_resources( N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(defproducerc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducera))); - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducerb))); - BOOST_REQUIRE_EQUAL(success(), regproducer(N(defproducerc))); - - produce_block(fc::hours(24)); - - transfer( config::system_account_name, "producvotera", core_sym::from_string("400000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), { N(defproducera),N(defproducerb),N(defproducerc) })); - - auto run_for_1year = [this](int64_t annual_rate, int64_t inflation_pay_factor, int64_t votepay_factor) { - - double inflation = double(annual_rate)/double(10000); - - BOOST_REQUIRE_EQUAL(success(), setinflation( - annual_rate, - inflation_pay_factor, - votepay_factor - )); - - produce_block(fc::hours(24)); - const asset initial_supply = get_token_supply(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - for (uint32_t i = 0; i < 7 * 52; ++i) { - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerc), N(claimrewards), mvo()("owner", "defproducerc"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducerb), N(claimrewards), mvo()("owner", "defproducerb"))); - produce_block(fc::seconds(8 * 3600)); - BOOST_REQUIRE_EQUAL(success(), push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - } - const asset final_supply = get_token_supply(); - const int64_t final_savings = get_balance(N(eosio.saving)).get_amount(); - - double computed_new_tokens = double(final_supply.get_amount() - initial_supply.get_amount()); - double theoretical_new_tokens = double(initial_supply.get_amount())*inflation; - double diff_new_tokens = std::abs(theoretical_new_tokens-computed_new_tokens); - - if( annual_rate > 0 ) { - //Error should be less than 0.3% - BOOST_REQUIRE( diff_new_tokens/theoretical_new_tokens < double(0.003) ); - } else { - BOOST_REQUIRE_EQUAL( computed_new_tokens, 0 ); - BOOST_REQUIRE_EQUAL( theoretical_new_tokens, 0 ); - } - - double savings_inflation = inflation - inflation * 10000 / inflation_pay_factor; - - double computed_savings_tokens = double(final_savings-initial_savings); - double theoretical_savings_tokens = double(initial_supply.get_amount())*savings_inflation; - double diff_savings_tokens = std::abs(theoretical_savings_tokens-computed_savings_tokens); - - if( annual_rate > 0 ) { - //Error should be less than 0.3% - BOOST_REQUIRE( diff_savings_tokens/theoretical_savings_tokens < double(0.003) ); - } else { - BOOST_REQUIRE_EQUAL( computed_savings_tokens, 0 ); - BOOST_REQUIRE_EQUAL( theoretical_savings_tokens, 0 ); - } - }; - - // 1% inflation for 1 year. 50% savings / 50% bp reward. 10000 / 50000 = 0.2 => 20% blockpay, 80% votepay - run_for_1year(100, 20000, 50000); - - // 3% inflation for 1 year. 66.6% savings / 33.33% bp reward. 10000/13333 = 0.75 => 75% blockpay, 25% votepay - run_for_1year(300, 30000, 13333); - - // 0% inflation for 1 year - run_for_1year(0, 30000, 50000); - } - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_CASE(extreme_inflation) try { - eosio_system_tester t(eosio_system_tester::setup_level::minimal); - symbol core_symbol{CORE_SYM}; - t.create_currency( N(eosio.token), config::system_account_name, asset((1ll << 62) - 1, core_symbol) ); - t.issue( asset(10000000000000, core_symbol) ); - t.deploy_contract(); - t.produce_block(); - t.create_account_with_resources(N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false); - BOOST_REQUIRE_EQUAL(t.success(), t.regproducer(N(defproducera))); - t.transfer( config::system_account_name, "defproducera", core_sym::from_string("200000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(t.success(), t.stake("defproducera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000"))); - BOOST_REQUIRE_EQUAL(t.success(), t.vote( N(defproducera), { N(defproducera) })); - t.produce_blocks(4); - t.produce_block(fc::hours(24)); - - BOOST_REQUIRE_EQUAL(t.success(), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - t.produce_block(); - asset current_supply; - { - vector data = t.get_row_by_account( N(eosio.token), name(core_symbol.to_symbol_code().value), N(stat), account_name(core_symbol.to_symbol_code().value) ); - current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, abi_serializer::create_yield_function(eosio_system_tester::abi_serializer_max_time))["supply"].template as(); - } - t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply ); - BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(std::numeric_limits::max(), 50000, 40000)); - t.produce_block(); - - t.produce_block(fc::hours(10*24)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - t.produce_block(fc::hours(11*24)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("magnitude of asset amount must be less than 2^62"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - - t.produce_block(fc::hours(24)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("overflow in calculating new tokens to be issued; inflation rate is too high"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); - BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(500, 50000, 40000)); - BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera"))); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const int64_t secs_per_year = 52 * 7 * 24 * 3600; - const double usecs_per_year = secs_per_year * 1000000; - const double cont_rate = std::log1p(double(0.05)); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - { - const std::string root("abcproducer"); - for ( char c = 'a'; c <= 'n'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - produce_blocks(1); - ilog( "------ get pro----------" ); - wdump((p)); - BOOST_TEST(0 == get_producer_info(p)["total_votes"].as()); - } - } - - produce_block( fc::hours(24) ); - - // producvotera votes for defproducera ... defproducerj - // producvoterb votes for defproducera ... defproduceru - // producvoterc votes for defproducera ... defproducerz - // producvoterd votes for abcproducera ... abcproducern - { - BOOST_REQUIRE_EQUAL(success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.begin()+26))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end()))); - } - - { - auto proda = get_producer_info( N(defproducera) ); - auto prodj = get_producer_info( N(defproducerj) ); - auto prodk = get_producer_info( N(defproducerk) ); - auto produ = get_producer_info( N(defproduceru) ); - auto prodv = get_producer_info( N(defproducerv) ); - auto prodz = get_producer_info( N(defproducerz) ); - - BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); - - // check vote ratios - BOOST_REQUIRE ( 0 < proda["total_votes"].as() && 0 < prodz["total_votes"].as() ); - BOOST_TEST( proda["total_votes"].as() == prodj["total_votes"].as() ); - BOOST_TEST( prodk["total_votes"].as() == produ["total_votes"].as() ); - BOOST_TEST( prodv["total_votes"].as() == prodz["total_votes"].as() ); - BOOST_TEST( 2 * proda["total_votes"].as() == 3 * produ["total_votes"].as() ); - BOOST_TEST( proda["total_votes"].as() == 3 * prodz["total_votes"].as() ); - } - - // give a chance for everyone to produce blocks - { - produce_blocks(23 * 12 + 20); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced = false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE(all_21_produced && rest_didnt_produce); - } - - std::vector vote_shares(producer_names.size()); - { - double total_votes = 0; - for (uint32_t i = 0; i < producer_names.size(); ++i) { - vote_shares[i] = get_producer_info(producer_names[i])["total_votes"].as(); - total_votes += vote_shares[i]; - } - BOOST_TEST(total_votes == get_global_state()["total_producer_vote_weight"].as()); - std::for_each(vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; }); - - BOOST_TEST(double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0))); - BOOST_TEST(double(3./71.) == vote_shares.front()); - BOOST_TEST(double(1./71.) == vote_shares.back()); - } - - { - const uint32_t prod_index = 2; - const auto prod_name = producer_names[prod_index]; - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const asset initial_supply = get_token_supply(); - const asset initial_bpay_balance = get_balance(N(eosio.bpay)); - const asset initial_vpay_balance = get_balance(N(eosio.vpay)); - const asset initial_balance = get_balance(prod_name); - const uint32_t initial_unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - const asset supply = get_token_supply(); - const asset bpay_balance = get_balance(N(eosio.bpay)); - const asset vpay_balance = get_balance(N(eosio.vpay)); - const asset balance = get_balance(prod_name); - const uint32_t unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - const uint64_t usecs_between_fills = claim_time - initial_claim_time; - const int32_t secs_between_fills = static_cast(usecs_between_fills / 1000000); - - const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); - - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth) - int64_t(expected_supply_growth)/5, savings - initial_savings ); - - const int64_t expected_perblock_bucket = initial_supply.get_amount() * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year; - const int64_t expected_pervote_bucket = initial_supply.get_amount() * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year; - - const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; - const int64_t from_pervote_bucket = vote_shares[prod_index] * expected_pervote_bucket; - - BOOST_REQUIRE( 1 >= abs(int32_t(initial_tot_unpaid_blocks - tot_unpaid_blocks) - int32_t(initial_unpaid_blocks - unpaid_blocks)) ); - - if (from_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE( within_one( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ) ); - } else { - BOOST_REQUIRE( within_one( from_perblock_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket, pervote_bucket ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket, vpay_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( perblock_bucket, bpay_balance.get_amount() ) ); - } - - produce_blocks(5); - - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - { - const uint32_t prod_index = 23; - const auto prod_name = producer_names[prod_index]; - BOOST_REQUIRE_EQUAL(success(), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - BOOST_REQUIRE_EQUAL(0, get_balance(prod_name).get_amount()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - // Wait for 23 hours. By now, pervote_bucket has grown enough - // that a producer's share is more than 100 tokens. - produce_block(fc::seconds(23 * 3600)); - - { - const uint32_t prod_index = 15; - const auto prod_name = producer_names[prod_index]; - - const auto initial_global_state = get_global_state(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const int64_t initial_savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const asset initial_supply = get_token_supply(); - const asset initial_bpay_balance = get_balance(N(eosio.bpay)); - const asset initial_vpay_balance = get_balance(N(eosio.vpay)); - const asset initial_balance = get_balance(prod_name); - const uint32_t initial_unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - BOOST_REQUIRE_EQUAL(success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - - const auto global_state = get_global_state(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const int64_t savings = get_balance(N(eosio.saving)).get_amount(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - const asset supply = get_token_supply(); - const asset bpay_balance = get_balance(N(eosio.bpay)); - const asset vpay_balance = get_balance(N(eosio.vpay)); - const asset balance = get_balance(prod_name); - const uint32_t unpaid_blocks = get_producer_info(prod_name)["unpaid_blocks"].as(); - - const uint64_t usecs_between_fills = claim_time - initial_claim_time; - - const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth) - int64_t(expected_supply_growth)/5, savings - initial_savings ); - - const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) - + initial_perblock_bucket; - const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) - + initial_pervote_bucket; - const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks ; - const int64_t from_pervote_bucket = int64_t( vote_shares[prod_index] * expected_pervote_bucket); - - BOOST_REQUIRE( 1 >= abs(int32_t(initial_tot_unpaid_blocks - tot_unpaid_blocks) - int32_t(initial_unpaid_blocks - unpaid_blocks)) ); - if (from_pervote_bucket >= 100 * 10000) { - BOOST_REQUIRE( within_one( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket - from_pervote_bucket, vpay_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_perblock_bucket - from_perblock_bucket, perblock_bucket ) ); - BOOST_REQUIRE( within_one( expected_perblock_bucket - from_perblock_bucket, bpay_balance.get_amount() ) ); - } else { - BOOST_REQUIRE( within_one( from_perblock_bucket, balance.get_amount() - initial_balance.get_amount() ) ); - BOOST_REQUIRE( within_one( expected_pervote_bucket, pervote_bucket ) ); - } - - produce_blocks(5); - - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - { - const uint32_t prod_index = 24; - const auto prod_name = producer_names[prod_index]; - BOOST_REQUIRE_EQUAL(success(), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - BOOST_REQUIRE(100 * 10000 <= get_balance(prod_name).get_amount()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name))); - } - - { - const uint32_t rmv_index = 5; - account_name prod_name = producer_names[rmv_index]; - - auto info = get_producer_info(prod_name); - BOOST_REQUIRE( info["is_active"].as() ); - BOOST_REQUIRE( fc::crypto::public_key() != fc::crypto::public_key(info["producer_key"].as_string()) ); - - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(prod_name, N(rmvproducer), mvo()("producer", prod_name))); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(producer_names[rmv_index + 2], N(rmvproducer), mvo()("producer", prod_name) ) ); - BOOST_REQUIRE_EQUAL( success(), - push_action(config::system_account_name, N(rmvproducer), mvo()("producer", prod_name) ) ); - { - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE(rest_didnt_produce); - } - - produce_blocks(3 * 21 * 12); - info = get_producer_info(prod_name); - const uint32_t init_unpaid_blocks = info["unpaid_blocks"].as(); - BOOST_REQUIRE( !info["is_active"].as() ); - BOOST_REQUIRE( fc::crypto::public_key() == fc::crypto::public_key(info["producer_key"].as_string()) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("producer does not have an active key"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); - produce_blocks(3 * 21 * 12); - BOOST_REQUIRE_EQUAL( init_unpaid_blocks, get_producer_info(prod_name)["unpaid_blocks"].as() ); - { - bool prod_was_replaced = false; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - prod_was_replaced = true; - } - } - BOOST_REQUIRE(prod_was_replaced); - } - } - - { - BOOST_REQUIRE_EQUAL( wasm_assert_msg("producer not found"), - push_action( config::system_account_name, N(rmvproducer), mvo()("producer", "nonexistingp") ) ); - } - - produce_block(fc::hours(24)); - - // switch to new producer pay metric - { - BOOST_REQUIRE_EQUAL( 0, get_global_state2()["revision"].as() ); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(producer_names[1], N(updtrevision), mvo()("revision", 1) ) ); - BOOST_REQUIRE_EQUAL( success(), - push_action(config::system_account_name, N(updtrevision), mvo()("revision", 1) ) ); - BOOST_REQUIRE_EQUAL( 1, get_global_state2()["revision"].as() ); - - const uint32_t prod_index = 2; - const auto prod_name = producer_names[prod_index]; - - const auto initial_prod_info = get_producer_info(prod_name); - const auto initial_prod_info2 = get_producer_info2(prod_name); - const auto initial_global_state = get_global_state(); - const double initial_tot_votepay_share = get_global_state2()["total_producer_votepay_share"].as_double(); - const double initial_tot_vpay_rate = get_global_state3()["total_vpay_share_change_rate"].as_double(); - const uint64_t initial_vpay_state_update = microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ); - const uint64_t initial_bucket_fill_time = microseconds_since_epoch_of_iso_string( initial_global_state["last_pervote_bucket_fill"] ); - const int64_t initial_pervote_bucket = initial_global_state["pervote_bucket"].as(); - const int64_t initial_perblock_bucket = initial_global_state["perblock_bucket"].as(); - const uint32_t initial_tot_unpaid_blocks = initial_global_state["total_unpaid_blocks"].as(); - const asset initial_supply = get_token_supply(); - const asset initial_balance = get_balance(prod_name); - const uint32_t initial_unpaid_blocks = initial_prod_info["unpaid_blocks"].as(); - const uint64_t initial_claim_time = microseconds_since_epoch_of_iso_string( initial_prod_info["last_claim_time"] ); - const uint64_t initial_prod_update_time = microseconds_since_epoch_of_iso_string( initial_prod_info2["last_votepay_share_update"] ); - - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); - - const auto prod_info = get_producer_info(prod_name); - const auto prod_info2 = get_producer_info2(prod_name); - const auto global_state = get_global_state(); - const uint64_t vpay_state_update = microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ); - const uint64_t bucket_fill_time = microseconds_since_epoch_of_iso_string( global_state["last_pervote_bucket_fill"] ); - const int64_t pervote_bucket = global_state["pervote_bucket"].as(); - const int64_t perblock_bucket = global_state["perblock_bucket"].as(); - const uint32_t tot_unpaid_blocks = global_state["total_unpaid_blocks"].as(); - const asset supply = get_token_supply(); - const asset balance = get_balance(prod_name); - const uint32_t unpaid_blocks = prod_info["unpaid_blocks"].as(); - const uint64_t claim_time = microseconds_since_epoch_of_iso_string( prod_info["last_claim_time"] ); - const uint64_t prod_update_time = microseconds_since_epoch_of_iso_string( prod_info2["last_votepay_share_update"] ); - - const uint64_t usecs_between_fills = bucket_fill_time - initial_bucket_fill_time; - const double secs_between_global_updates = (vpay_state_update - initial_vpay_state_update) / 1E6; - const double secs_between_prod_updates = (prod_update_time - initial_prod_update_time) / 1E6; - const double votepay_share = initial_prod_info2["votepay_share"].as_double() + secs_between_prod_updates * prod_info["total_votes"].as_double(); - const double tot_votepay_share = initial_tot_votepay_share + initial_tot_vpay_rate * secs_between_global_updates; - - const int64_t expected_perblock_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.25 * cont_rate/ 5.) / usecs_per_year ) - + initial_perblock_bucket; - const int64_t expected_pervote_bucket = int64_t( double(initial_supply.get_amount()) * double(usecs_between_fills) * (0.75 * cont_rate/ 5.) / usecs_per_year ) - + initial_pervote_bucket; - const int64_t from_perblock_bucket = initial_unpaid_blocks * expected_perblock_bucket / initial_tot_unpaid_blocks; - const int64_t from_pervote_bucket = int64_t( ( votepay_share * expected_pervote_bucket ) / tot_votepay_share ); - - const double expected_supply_growth = initial_supply.get_amount() * double(usecs_between_fills) * cont_rate / usecs_per_year; - BOOST_REQUIRE_EQUAL( int64_t(expected_supply_growth), supply.get_amount() - initial_supply.get_amount() ); - BOOST_REQUIRE_EQUAL( claim_time, vpay_state_update ); - BOOST_REQUIRE( 100 * 10000 < from_pervote_bucket ); - BOOST_CHECK_EQUAL( expected_pervote_bucket - from_pervote_bucket, pervote_bucket ); - BOOST_CHECK_EQUAL( from_perblock_bucket + from_pervote_bucket, balance.get_amount() - initial_balance.get_amount() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - - produce_block(fc::hours(2)); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("already claimed rewards within past day"), - push_action(prod_name, N(claimrewards), mvo()("owner", prod_name) ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE(multiple_producer_votepay_share, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz, abcproducera, ..., defproducern} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - { - const std::string root("abcproducer"); - for ( char c = 'a'; c <= 'n'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - produce_blocks(1); - ilog( "------ get pro----------" ); - wdump((p)); - BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); - BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( get_producer_info2(p)["last_votepay_share_update"] )); - } - } - - produce_block( fc::hours(24) ); - - // producvotera votes for defproducera ... defproducerj - // producvoterb votes for defproducera ... defproduceru - // producvoterc votes for defproducera ... defproducerz - // producvoterd votes for abcproducera ... abcproducern - { - BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+10)) ); - produce_block( fc::hours(10) ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - const auto& init_info = get_producer_info(producer_names[0]); - const auto& init_info2 = get_producer_info2(producer_names[0]); - uint64_t init_update = microseconds_since_epoch_of_iso_string( init_info2["last_votepay_share_update"] ); - double init_votes = init_info["total_votes"].as_double(); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21)) ); - const auto& info = get_producer_info(producer_names[0]); - const auto& info2 = get_producer_info2(producer_names[0]); - BOOST_TEST_REQUIRE( ((microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) - init_update)/double(1E6)) * init_votes == info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( info2["votepay_share"].as_double() * 10 == get_global_state2()["total_producer_votepay_share"].as_double() ); - - BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[11])["votepay_share"].as_double() ); - produce_block( fc::hours(13) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.begin()+26)) ); - BOOST_REQUIRE( 0 < get_producer_info2(producer_names[11])["votepay_share"].as_double() ); - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterd), vector(producer_names.begin()+26, producer_names.end())) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(producer_names[26])["votepay_share"].as_double() ); - } - - { - auto proda = get_producer_info( N(defproducera) ); - auto prodj = get_producer_info( N(defproducerj) ); - auto prodk = get_producer_info( N(defproducerk) ); - auto produ = get_producer_info( N(defproduceru) ); - auto prodv = get_producer_info( N(defproducerv) ); - auto prodz = get_producer_info( N(defproducerz) ); - - BOOST_REQUIRE (0 == proda["unpaid_blocks"].as() && 0 == prodz["unpaid_blocks"].as()); - - // check vote ratios - BOOST_REQUIRE ( 0 < proda["total_votes"].as_double() && 0 < prodz["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( proda["total_votes"].as_double() == prodj["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( prodk["total_votes"].as_double() == produ["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( prodv["total_votes"].as_double() == prodz["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 2 * proda["total_votes"].as_double() == 3 * produ["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( proda["total_votes"].as_double() == 3 * prodz["total_votes"].as_double() ); - } - - std::vector vote_shares(producer_names.size()); - { - double total_votes = 0; - for (uint32_t i = 0; i < producer_names.size(); ++i) { - vote_shares[i] = get_producer_info(producer_names[i])["total_votes"].as_double(); - total_votes += vote_shares[i]; - } - BOOST_TEST_REQUIRE( total_votes == get_global_state()["total_producer_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( microseconds_since_epoch_of_iso_string( get_producer_info2(producer_names.back())["last_votepay_share_update"] ), - microseconds_since_epoch_of_iso_string( get_global_state3()["last_vpay_state_update"] ) ); - - std::for_each( vote_shares.begin(), vote_shares.end(), [total_votes](double& x) { x /= total_votes; } ); - BOOST_TEST_REQUIRE( double(1) == std::accumulate(vote_shares.begin(), vote_shares.end(), double(0)) ); - BOOST_TEST_REQUIRE( double(3./71.) == vote_shares.front() ); - BOOST_TEST_REQUIRE( double(1./71.) == vote_shares.back() ); - } - - std::vector votepay_shares(producer_names.size()); - { - const auto& gs3 = get_global_state3(); - double total_votepay_shares = 0; - double expected_total_votepay_shares = 0; - for (uint32_t i = 0; i < producer_names.size() ; ++i) { - const auto& info = get_producer_info(producer_names[i]); - const auto& info2 = get_producer_info2(producer_names[i]); - votepay_shares[i] = info2["votepay_share"].as_double(); - total_votepay_shares += votepay_shares[i]; - expected_total_votepay_shares += votepay_shares[i]; - expected_total_votepay_shares += info["total_votes"].as_double() - * double( ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) - - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) - ) / 1E6 ); - } - BOOST_TEST( expected_total_votepay_shares > total_votepay_shares ); - BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); - } - - { - const uint32_t prod_index = 15; - const account_name prod_name = producer_names[prod_index]; - const auto& init_info = get_producer_info(prod_name); - const auto& init_info2 = get_producer_info2(prod_name); - BOOST_REQUIRE( 0 < init_info2["votepay_share"].as_double() ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( init_info2["last_votepay_share_update"] ) ); - - BOOST_REQUIRE_EQUAL( success(), push_action(prod_name, N(claimrewards), mvo()("owner", prod_name)) ); - - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prod_name)["votepay_share"].as_double() ); - BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_string(), - get_producer_info2(prod_name)["last_votepay_share_update"].as_string() ); - BOOST_REQUIRE_EQUAL( get_producer_info(prod_name)["last_claim_time"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - const auto& gs3 = get_global_state3(); - double expected_total_votepay_shares = 0; - for (uint32_t i = 0; i < producer_names.size(); ++i) { - const auto& info = get_producer_info(producer_names[i]); - const auto& info2 = get_producer_info2(producer_names[i]); - expected_total_votepay_shares += info2["votepay_share"].as_double(); - expected_total_votepay_shares += info["total_votes"].as_double() - * double( ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) - - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) - ) / 1E6 ); - } - BOOST_TEST_REQUIRE( expected_total_votepay_shares == get_global_state2()["total_producer_votepay_share"].as_double() ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_share_invariant, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - cross_15_percent_threshold(); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); - } - const auto vota = accounts[0]; - const auto votb = accounts[1]; - const auto proda = accounts[2]; - const auto prodb = accounts[3]; - - BOOST_REQUIRE_EQUAL( success(), stake( vota, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( votb, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), regproducer( proda ) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( prodb ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - - produce_block( fc::hours(25) ); - - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - - produce_block( fc::hours(1) ); - - BOOST_REQUIRE_EQUAL( success(), push_action(proda, N(claimrewards), mvo()("owner", proda)) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(proda)["votepay_share"].as_double() ); - - produce_block( fc::hours(24) ); - - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - - produce_block( fc::hours(24) ); - - BOOST_REQUIRE_EQUAL( success(), push_action(prodb, N(claimrewards), mvo()("owner", prodb)) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(prodb)["votepay_share"].as_double() ); - - produce_block( fc::hours(10) ); - - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - - produce_block( fc::hours(16) ); - - BOOST_REQUIRE_EQUAL( success(), vote( votb, { prodb } ) ); - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), vote( vota, { proda } ) ); - - const auto& info = get_producer_info(prodb); - const auto& info2 = get_producer_info2(prodb); - const auto& gs2 = get_global_state2(); - const auto& gs3 = get_global_state3(); - - double expected_total_vpay_share = info2["votepay_share"].as_double() - + info["total_votes"].as_double() - * ( microseconds_since_epoch_of_iso_string( gs3["last_vpay_state_update"] ) - - microseconds_since_epoch_of_iso_string( info2["last_votepay_share_update"] ) ) / 1E6; - - BOOST_TEST_REQUIRE( expected_total_vpay_share == gs2["total_producer_votepay_share"].as_double() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_share_proxy, eosio_system_tester, * boost::unit_test::tolerance(1e-5)) try { - - cross_15_percent_threshold(); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); - } - const auto alice = accounts[0]; - const auto bob = accounts[1]; - const auto carol = accounts[2]; - const auto emily = accounts[3]; - - // alice becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( alice, N(regproxy), mvo()("proxy", alice)("isproxy", true) ) ); - REQUIRE_MATCHING_OBJECT( proxy( alice ), get_voter_info( alice ) ); - - // carol and emily become producers - BOOST_REQUIRE_EQUAL( success(), regproducer( carol, 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( emily, 1) ); - - // bob chooses alice as proxy - BOOST_REQUIRE_EQUAL( success(), stake( bob, core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, core_sym::from_string("150.0000"), core_sym::from_string("150.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_voter_info(alice)["proxied_vote_weight"].as_double() ); - - // alice (proxy) votes for carol - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); - double total_votes = get_producer_info(carol)["total_votes"].as_double(); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("450.0003")) == total_votes ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - uint64_t last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); - - produce_block( fc::hours(15) ); - - // alice (proxy) votes again for carol - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol } ) ); - auto cur_info2 = get_producer_info2(carol); - double expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("450.0003")) == get_producer_info(carol)["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - last_update_time = microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ); - total_votes = get_producer_info(carol)["total_votes"].as_double(); - - produce_block( fc::hours(40) ); - - // bob unstakes - BOOST_REQUIRE_EQUAL( success(), unstake( bob, core_sym::from_string("10.0002"), core_sym::from_string("10.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); - - cur_info2 = get_producer_info2(carol); - expected_votepay_share += double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - last_update_time = microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ); - total_votes = get_producer_info(carol)["total_votes"].as_double(); - - // carol claims rewards - BOOST_REQUIRE_EQUAL( success(), push_action(carol, N(claimrewards), mvo()("owner", carol)) ); - - produce_block( fc::hours(20) ); - - // bob votes for carol - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("430.0000")), get_producer_info(carol)["total_votes"].as_double() ); - cur_info2 = get_producer_info2(carol); - expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - - produce_block( fc::hours(54) ); - - // bob votes for carol again - // carol hasn't claimed rewards in over 3 days - total_votes = get_producer_info(carol)["total_votes"].as_double(); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_REQUIRE_EQUAL( get_producer_info2(carol)["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - produce_block( fc::hours(20) ); - - // bob votes for carol again - // carol still hasn't claimed rewards - BOOST_REQUIRE_EQUAL( success(), vote( bob, { carol } ) ); - BOOST_REQUIRE_EQUAL(get_producer_info2(carol)["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - produce_block( fc::hours(24) ); - - // carol finally claims rewards - BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info2(carol)["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( total_votes == get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - produce_block( fc::hours(5) ); - - // alice votes for carol and emily - // emily hasn't claimed rewards in over 3 days - last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); - cur_info2 = get_producer_info2(carol); - auto cur_info2_emily = get_producer_info2(emily); - - expected_votepay_share = double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == - get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - - produce_block( fc::hours(10) ); - - // bob chooses alice as proxy - // emily still hasn't claimed rewards - last_update_time = microseconds_since_epoch_of_iso_string( get_producer_info2(carol)["last_votepay_share_update"] ); - BOOST_REQUIRE_EQUAL( success(), vote( bob, { }, alice ) ); - cur_info2 = get_producer_info2(carol); - cur_info2_emily = get_producer_info2(emily); - - expected_votepay_share += double( (microseconds_since_epoch_of_iso_string( cur_info2["last_votepay_share_update"] ) - last_update_time) / 1E6 ) * total_votes; - BOOST_TEST_REQUIRE( expected_votepay_share == cur_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == cur_info2_emily["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( expected_votepay_share == get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( get_producer_info(carol)["total_votes"].as_double() == - get_global_state3()["total_vpay_share_change_rate"].as_double() ); - BOOST_REQUIRE_EQUAL( cur_info2["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - BOOST_REQUIRE_EQUAL( cur_info2_emily["last_votepay_share_update"].as_string(), - get_global_state3()["last_vpay_state_update"].as_string() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_share_update_order, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - cross_15_percent_threshold(); - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources( a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, a, core_sym::from_string("1000.0000"), config::system_account_name ); - } - const auto alice = accounts[0]; - const auto bob = accounts[1]; - const auto carol = accounts[2]; - const auto emily = accounts[3]; - - BOOST_REQUIRE_EQUAL( success(), regproducer( carol ) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( emily ) ); - - produce_block( fc::hours(24) ); - - BOOST_REQUIRE_EQUAL( success(), stake( alice, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), stake( bob, core_sym::from_string("100.0000"), core_sym::from_string("100.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( alice, { carol, emily } ) ); - - - BOOST_REQUIRE_EQUAL( success(), push_action( carol, N(claimrewards), mvo()("owner", carol) ) ); - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), push_action( emily, N(claimrewards), mvo()("owner", emily) ) ); - - produce_block( fc::hours(3 * 24 + 1) ); - - { - signed_transaction trx; - set_transaction_headers(trx); - - trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {carol, config::active_name} }, - mvo()("owner", carol) ) ); - - std::vector prods = { carol, emily }; - trx.actions.emplace_back( get_action( config::system_account_name, N(voteproducer), { {alice, config::active_name} }, - mvo()("voter", alice)("proxy", name(0))("producers", prods) ) ); - - trx.actions.emplace_back( get_action( config::system_account_name, N(claimrewards), { {emily, config::active_name} }, - mvo()("owner", emily) ) ); - - trx.sign( get_private_key( carol, "active" ), control->get_chain_id() ); - trx.sign( get_private_key( alice, "active" ), control->get_chain_id() ); - trx.sign( get_private_key( emily, "active" ), control->get_chain_id() ); - - push_transaction( trx ); - } - - const auto& carol_info = get_producer_info(carol); - const auto& carol_info2 = get_producer_info2(carol); - const auto& emily_info = get_producer_info(emily); - const auto& emily_info2 = get_producer_info2(emily); - const auto& gs3 = get_global_state3(); - BOOST_REQUIRE_EQUAL( carol_info2["last_votepay_share_update"].as_string(), gs3["last_vpay_state_update"].as_string() ); - BOOST_REQUIRE_EQUAL( emily_info2["last_votepay_share_update"].as_string(), gs3["last_vpay_state_update"].as_string() ); - BOOST_TEST_REQUIRE( 0 == carol_info2["votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( 0 == emily_info2["votepay_share"].as_double() ); - BOOST_REQUIRE( 0 < carol_info["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( carol_info["total_votes"].as_double() == emily_info["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( gs3["total_vpay_share_change_rate"].as_double() == 2 * carol_info["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(votepay_transition, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try { - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources( v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - transfer( config::system_account_name, v, core_sym::from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'd'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE(0 == get_producer_info(p)["total_votes"].as_double()); - BOOST_TEST_REQUIRE(0 == get_producer_info2(p)["votepay_share"].as_double()); - BOOST_REQUIRE(0 < microseconds_since_epoch_of_iso_string( get_producer_info2(p)["last_votepay_share_update"] )); - } - } - - BOOST_REQUIRE_EQUAL( success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); - auto* tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( tbl ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info2("defproducera")["last_votepay_share_update"] ) ); - - // const_cast hack for now - const_cast(control->db()).remove( *tbl ); - tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( !tbl ); - - BOOST_REQUIRE_EQUAL( success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); - tbl = control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( !tbl ); - BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducera)) ); - BOOST_REQUIRE( microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducera))["last_claim_time"] ) < microseconds_since_epoch_of_iso_string( get_producer_info2(N(defproducera))["last_votepay_share_update"] ) ); - - create_account_with_resources( N(defproducer1), config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu ); - BOOST_REQUIRE_EQUAL( success(), regproducer(N(defproducer1)) ); - BOOST_REQUIRE( 0 < microseconds_since_epoch_of_iso_string( get_producer_info(N(defproducer1))["last_claim_time"] ) ); - BOOST_REQUIRE_EQUAL( get_producer_info(N(defproducer1))["last_claim_time"].as_string(), - get_producer_info2(N(defproducer1))["last_votepay_share_update"].as_string() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_AUTO_TEST_CASE(votepay_transition2, * boost::unit_test::tolerance(1e-10)) try { - eosio_system_tester t(eosio_system_tester::setup_level::minimal); - - std::string old_contract_core_symbol_name = "SYS"; // Set to core symbol used in contracts::util::system_wasm_old() - symbol old_contract_core_symbol{::eosio::chain::string_to_symbol_c( 4, old_contract_core_symbol_name.c_str() )}; - - auto old_core_from_string = [&]( const std::string& s ) { - return eosio::chain::asset::from_string(s + " " + old_contract_core_symbol_name); - }; - - t.create_core_token( old_contract_core_symbol ); - t.set_code( config::system_account_name, contracts::util::system_wasm_old() ); - t.set_abi( config::system_account_name, contracts::util::system_abi_old().data() ); - { - const auto& accnt = t.control->db().get( config::system_account_name ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - t.abi_ser.set_abi(abi, abi_serializer::create_yield_function(eosio_system_tester::abi_serializer_max_time)); - } - const asset net = old_core_from_string("80.0000"); - const asset cpu = old_core_from_string("80.0000"); - const std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - t.create_account_with_resources( v, config::system_account_name, old_core_from_string("1.0000"), false, net, cpu ); - t.transfer( config::system_account_name, v, old_core_from_string("100000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(t.success(), t.stake(v, old_core_from_string("30000000.0000"), old_core_from_string("30000000.0000")) ); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - { - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'd'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - } - t.setup_producer_accounts( producer_names, old_core_from_string("1.0000"), - old_core_from_string("80.0000"), old_core_from_string("80.0000") ); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(p) ); - BOOST_TEST_REQUIRE(0 == t.get_producer_info(p)["total_votes"].as_double()); - } - } - - BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvotera), vector(producer_names.begin(), producer_names.end())) ); - t.produce_block( fc::hours(20) ); - BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvoterb), vector(producer_names.begin(), producer_names.end())) ); - t.produce_block( fc::hours(30) ); - BOOST_REQUIRE_EQUAL( t.success(), t.vote(N(producvoterc), vector(producer_names.begin(), producer_names.end())) ); - BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); - BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[1], N(claimrewards), mvo()("owner", producer_names[1])) ); - auto* tbl = t.control->db().find( - boost::make_tuple( config::system_account_name, - config::system_account_name, - N(producers2) ) ); - BOOST_REQUIRE( !tbl ); - - t.produce_block( fc::hours(2*24) ); - - t.deploy_contract( false ); - - t.produce_blocks(2); - t.produce_block( fc::hours(24 + 1) ); - - BOOST_REQUIRE_EQUAL( t.success(), t.push_action(producer_names[0], N(claimrewards), mvo()("owner", producer_names[0])) ); - BOOST_TEST_REQUIRE( 0 == t.get_global_state2()["total_producer_votepay_share"].as_double() ); - BOOST_TEST_REQUIRE( t.get_producer_info(producer_names[0])["total_votes"].as_double() == t.get_global_state3()["total_vpay_share_change_rate"].as_double() ); - - t.produce_block( fc::hours(5) ); - - BOOST_REQUIRE_EQUAL( t.success(), t.regproducer(producer_names[1]) ); - BOOST_TEST_REQUIRE( t.get_producer_info(producer_names[0])["total_votes"].as_double() + t.get_producer_info(producer_names[1])["total_votes"].as_double() == - t.get_global_state3()["total_vpay_share_change_rate"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE(producers_upgrade_system_contract, eosio_system_tester) try { - //install multisig contract - abi_serializer msig_abi_ser = initialize_multisig(); - auto producer_names = active_and_vote_producers(); - - //helper function - auto push_action_msig = [&]( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) -> action_result { - string action_type_name = msig_abi_ser.get_action_type(name); - - action act; - act.account = N(eosio.msig); - act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - - return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); - }; - // test begins - vector prod_perms; - for ( auto& x : producer_names ) { - prod_perms.push_back( { name(x), config::active_name } ); - } - - transaction trx; - { - //prepare system contract with different hash (contract differs in one byte) - auto code = contracts::system_wasm(); - string msg = "producer votes must be unique and sorted"; - auto it = std::search( code.begin(), code.end(), msg.begin(), msg.end() ); - BOOST_REQUIRE( it != code.end() ); - msg[0] = 'P'; - std::copy( msg.begin(), msg.end(), it ); - - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setcode") - ("authorization", vector{ { config::system_account_name, config::active_name } }) - ("data", fc::mutable_variant_object() ("account", name(config::system_account_name)) - ("vmtype", 0) - ("vmversion", "0") - ("code", bytes( code.begin(), code.end() )) - ) - }) - ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("trx", trx) - ("requested", prod_perms) - ) - ); - - // get 15 approvals - for ( size_t i = 0; i < 14; ++i ) { - BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[i]), N(approve), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("level", permission_level{ name(producer_names[i]), config::active_name }) - ) - ); - } - - //should fail - BOOST_REQUIRE_EQUAL(wasm_assert_msg("transaction authorization failed"), - push_action_msig( N(alice1111111), N(exec), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("executer", "alice1111111") - ) - ); - - // one more approval - BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[14]), N(approve), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("level", permission_level{ name(producer_names[14]), config::active_name }) - ) - ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() - ("proposer", "alice1111111") - ("proposal_name", "upgrade1") - ("executer", "alice1111111") - ) - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - produce_blocks( 250 ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE(producer_onblock_check, eosio_system_tester) try { - - const asset large_asset = core_sym::from_string("80.0000"); - create_account_with_resources( N(producvotera), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterb), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - create_account_with_resources( N(producvoterc), config::system_account_name, core_sym::from_string("1.0000"), false, large_asset, large_asset ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - setup_producer_accounts(producer_names); - - for (auto a:producer_names) - regproducer(a); - - produce_block(fc::hours(24)); - - BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.front() )["total_votes"].as()); - BOOST_REQUIRE_EQUAL(0, get_producer_info( producer_names.back() )["total_votes"].as()); - - - transfer(config::system_account_name, "producvotera", core_sym::from_string("200000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvotera", core_sym::from_string("70000000.0000"), core_sym::from_string("70000000.0000") )); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvotera), vector(producer_names.begin(), producer_names.begin()+10))); - BOOST_CHECK_EQUAL( wasm_assert_msg( "cannot undelegate bandwidth until the chain is activated (at least 15% of all tokens participate in voting)" ), - unstake( "producvotera", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - - // give a chance for everyone to produce blocks - { - produce_blocks(21 * 12); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced= false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE_EQUAL(false, all_21_produced); - BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); - } - - { - const char* claimrewards_activation_error_message = "cannot claim rewards until the chain is activated (at least 15% of all tokens participate in voting)"; - BOOST_CHECK_EQUAL(0, get_global_state()["total_unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg( claimrewards_activation_error_message ), - push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); - BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.front()).get_amount()); - BOOST_REQUIRE_EQUAL(wasm_assert_msg( claimrewards_activation_error_message ), - push_action(producer_names.back(), N(claimrewards), mvo()("owner", producer_names.back()))); - BOOST_REQUIRE_EQUAL(0, get_balance(producer_names.back()).get_amount()); - } - - // stake across 15% boundary - transfer(config::system_account_name, "producvoterb", core_sym::from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterb", core_sym::from_string("4000000.0000"), core_sym::from_string("4000000.0000"))); - transfer(config::system_account_name, "producvoterc", core_sym::from_string("100000000.0000"), config::system_account_name); - BOOST_REQUIRE_EQUAL(success(), stake("producvoterc", core_sym::from_string("2000000.0000"), core_sym::from_string("2000000.0000"))); - - BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote( N(producvoterc), vector(producer_names.begin(), producer_names.end()))); - - // give a chance for everyone to produce blocks - { - produce_blocks(21 * 12); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced= false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE_EQUAL(true, all_21_produced); - BOOST_REQUIRE_EQUAL(true, rest_didnt_produce); - BOOST_REQUIRE_EQUAL(success(), - push_action(producer_names.front(), N(claimrewards), mvo()("owner", producer_names.front()))); - BOOST_REQUIRE(0 < get_balance(producer_names.front()).get_amount()); - } - - BOOST_CHECK_EQUAL( success(), unstake( "producvotera", core_sym::from_string("50.0000"), core_sym::from_string("50.0000") ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( voters_actions_affect_proxy_and_producers, eosio_system_tester, * boost::unit_test::tolerance(1e+6) ) try { - cross_15_percent_threshold(); - - create_accounts_with_resources( { N(donald111111), N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); - - //alice1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //alice1111111 makes stake and votes - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1), N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - BOOST_REQUIRE_EQUAL( success(), push_action( N(donald111111), N(regproxy), mvo() - ("proxy", "donald111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(donald111111) ), get_voter_info( "donald111111" ) ); - - //bob111111111 chooses alice1111111 as a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("150.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //carol1111111 chooses alice1111111 as a proxy - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("30.0001"), core_sym::from_string("20.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("200.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("250.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("250.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //proxied voter carol1111111 increases stake - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("50.0000"), core_sym::from_string("70.0000") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("320.0005")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("370.0007")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("370.0007")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //proxied voter bob111111111 decreases stake - BOOST_REQUIRE_EQUAL( success(), unstake( "bob111111111", core_sym::from_string("50.0001"), core_sym::from_string("50.0001") ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("220.0003")) == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("270.0005")) == get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("270.0005")) == get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //proxied voter carol1111111 chooses another proxy - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "donald111111" ) ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0001")), get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("170.0002")), get_voter_info( "donald111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( 0, get_producer_info( "defproducer3" )["total_votes"].as_double() ); - - //bob111111111 switches to direct voting and votes for one of the same producers, but not for another one - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); - BOOST_TEST_REQUIRE( 0.0 == get_voter_info( "alice1111111" )["proxied_vote_weight"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("50.0002")), get_producer_info( "defproducer1" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( stake2votes(core_sym::from_string("100.0003")), get_producer_info( "defproducer2" )["total_votes"].as_double() ); - BOOST_TEST_REQUIRE( 0.0 == get_producer_info( "defproducer3" )["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( vote_both_proxy_and_producers, eosio_system_tester ) try { - //alice1111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", true) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) ), get_voter_info( "alice1111111" ) ); - - //carol1111111 becomes a producer - BOOST_REQUIRE_EQUAL( success(), regproducer( N(carol1111111), 1) ); - - //bob111111111 chooses alice1111111 as a proxy - - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("cannot vote for producers and proxy at same time"), - vote( N(bob111111111), { N(carol1111111) }, "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( select_invalid_proxy, eosio_system_tester ) try { - //accumulate proxied votes - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - - //selecting account not registered as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), - vote( N(bob111111111), vector(), "alice1111111" ) ); - - //selecting not existing account as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "invalid proxy specified" ), - vote( N(bob111111111), vector(), "notexist" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( double_register_unregister_proxy_keeps_votes, eosio_system_tester ) try { - //alice1111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 1) - ) - ); - issue_and_transfer( "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", core_sym::from_string("5.0000"), core_sym::from_string("5.0000") ) ); - edump((get_voter_info("alice1111111"))); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //bob111111111 stakes and selects alice1111111 as a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), vector(), "alice1111111" ) ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes( core_sym::from_string("150.0003") ))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //double regestering should fail without affecting total votes and stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), - push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 1) - ) - ); - REQUIRE_MATCHING_OBJECT( proxy( N(alice1111111) )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //uregister - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 0) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")) )( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - - //double unregistering should not affect proxied_votes and stake - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "action has no effect" ), - push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 0) - ) - ); - REQUIRE_MATCHING_OBJECT( voter( "alice1111111" )( "proxied_vote_weight", stake2votes(core_sym::from_string("150.0003")))( "staked", 100000 ), get_voter_info( "alice1111111" ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( proxy_cannot_use_another_proxy, eosio_system_tester ) try { - //alice1111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(alice1111111), N(regproxy), mvo() - ("proxy", "alice1111111") - ("isproxy", 1) - ) - ); - - //bob111111111 becomes a proxy - BOOST_REQUIRE_EQUAL( success(), push_action( N(bob111111111), N(regproxy), mvo() - ("proxy", "bob111111111") - ("isproxy", 1) - ) - ); - - //proxy should not be able to use a proxy - issue_and_transfer( "bob111111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account registered as a proxy is not allowed to use a proxy" ), - vote( N(bob111111111), vector(), "alice1111111" ) ); - - //voter that uses a proxy should not be allowed to become a proxy - issue_and_transfer( "carol1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), stake( "carol1111111", core_sym::from_string("100.0002"), core_sym::from_string("50.0001") ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carol1111111), vector(), "alice1111111" ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "account that uses a proxy is not allowed to become a proxy" ), - push_action( N(carol1111111), N(regproxy), mvo() - ("proxy", "carol1111111") - ("isproxy", 1) - ) - ); - - //proxy should not be able to use itself as a proxy - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "cannot proxy to self" ), - vote( N(bob111111111), vector(), "bob111111111" ) ); - -} FC_LOG_AND_RETHROW() - -fc::mutable_variant_object config_to_variant( const eosio::chain::chain_config& config ) { - return mutable_variant_object() - ( "max_block_net_usage", config.max_block_net_usage ) - ( "target_block_net_usage_pct", config.target_block_net_usage_pct ) - ( "max_transaction_net_usage", config.max_transaction_net_usage ) - ( "base_per_transaction_net_usage", config.base_per_transaction_net_usage ) - ( "context_free_discount_net_usage_num", config.context_free_discount_net_usage_num ) - ( "context_free_discount_net_usage_den", config.context_free_discount_net_usage_den ) - ( "max_block_cpu_usage", config.max_block_cpu_usage ) - ( "target_block_cpu_usage_pct", config.target_block_cpu_usage_pct ) - ( "max_transaction_cpu_usage", config.max_transaction_cpu_usage ) - ( "min_transaction_cpu_usage", config.min_transaction_cpu_usage ) - ( "max_transaction_lifetime", config.max_transaction_lifetime ) - ( "deferred_trx_expiration_window", config.deferred_trx_expiration_window ) - ( "max_transaction_delay", config.max_transaction_delay ) - ( "max_inline_action_size", config.max_inline_action_size ) - ( "max_inline_action_depth", config.max_inline_action_depth ) - ( "max_authority_depth", config.max_authority_depth ); -} - -BOOST_FIXTURE_TEST_CASE( elect_producers /*_and_parameters*/, eosio_system_tester ) try { - create_accounts_with_resources( { N(defproducer1), N(defproducer2), N(defproducer3) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer1), 1) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer2), 2) ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(defproducer3), 3) ); - - //stake more than 15% of total EOS supply to activate chain - transfer( "eosio", "alice1111111", core_sym::from_string("600000000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "alice1111111", "alice1111111", core_sym::from_string("300000000.0000"), core_sym::from_string("300000000.0000") ) ); - //vote for producers - BOOST_REQUIRE_EQUAL( success(), vote( N(alice1111111), { N(defproducer1) } ) ); - produce_blocks(250); - auto producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 1, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - - //auto config = config_to_variant( control->get_global_properties().configuration ); - //auto prod1_config = testing::filter_fields( config, producer_parameters_example( 1 ) ); - //REQUIRE_EQUAL_OBJECTS(prod1_config, config); - - // elect 2 producers - issue_and_transfer( "bob111111111", core_sym::from_string("80000.0000"), config::system_account_name ); - ilog("stake"); - BOOST_REQUIRE_EQUAL( success(), stake( "bob111111111", core_sym::from_string("40000.0000"), core_sym::from_string("40000.0000") ) ); - ilog("start vote"); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2) } ) ); - ilog("."); - produce_blocks(250); - producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 2, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer2"), producer_keys[1].producer_name ); - //config = config_to_variant( control->get_global_properties().configuration ); - //auto prod2_config = testing::filter_fields( config, producer_parameters_example( 2 ) ); - //REQUIRE_EQUAL_OBJECTS(prod2_config, config); - - // elect 3 producers - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer2), N(defproducer3) } ) ); - produce_blocks(250); - producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 3, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer2"), producer_keys[1].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer3"), producer_keys[2].producer_name ); - //config = config_to_variant( control->get_global_properties().configuration ); - //REQUIRE_EQUAL_OBJECTS(prod2_config, config); - - // try to go back to 2 producers and fail - BOOST_REQUIRE_EQUAL( success(), vote( N(bob111111111), { N(defproducer3) } ) ); - produce_blocks(250); - producer_keys = control->head_block_state()->active_schedule.producers; - BOOST_REQUIRE_EQUAL( 3, producer_keys.size() ); - - // The test below is invalid now, producer schedule is not updated if there are - // fewer producers in the new schedule - /* - BOOST_REQUIRE_EQUAL( 2, producer_keys.size() ); - BOOST_REQUIRE_EQUAL( name("defproducer1"), producer_keys[0].producer_name ); - BOOST_REQUIRE_EQUAL( name("defproducer3"), producer_keys[1].producer_name ); - //config = config_to_variant( control->get_global_properties().configuration ); - //auto prod3_config = testing::filter_fields( config, producer_parameters_example( 3 ) ); - //REQUIRE_EQUAL_OBJECTS(prod3_config, config); - */ - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buyname, eosio_system_tester ) try { - create_accounts_with_resources( { N(dan), N(sam) } ); - transfer( config::system_account_name, "dan", core_sym::from_string( "10000.0000" ) ); - transfer( config::system_account_name, "sam", core_sym::from_string( "10000.0000" ) ); - stake_with_transfer( config::system_account_name, N(sam), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); - stake_with_transfer( config::system_account_name, N(dan), core_sym::from_string( "80000000.0000" ), core_sym::from_string( "80000000.0000" ) ); - - regproducer( config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), vote( N(sam), { config::system_account_name } ) ); - // wait 14 days after min required amount has been staked - produce_block( fc::days(7) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(dan), { config::system_account_name } ) ); - produce_block( fc::days(7) ); - produce_block(); - - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(fail) }, N(dan) ), // dan shouldn't be able to create fail - eosio_assert_message_exception, eosio_assert_message_is( "no active bid for name" ) ); - bidname( "dan", "nofail", core_sym::from_string( "1.0000" ) ); - BOOST_REQUIRE_EQUAL( "assertion failure with message: must increase bid by 10%", bidname( "sam", "nofail", core_sym::from_string( "1.0000" ) )); // didn't increase bid by 10% - BOOST_REQUIRE_EQUAL( success(), bidname( "sam", "nofail", core_sym::from_string( "2.0000" ) )); // didn't increase bid by 10% - produce_block( fc::days(1) ); - produce_block(); - - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(nofail) }, N(dan) ), // dan shoudn't be able to do this, sam won - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - //wlog( "verify sam can create nofail" ); - create_accounts_with_resources( { N(nofail) }, N(sam) ); // sam should be able to do this, he won the bid - //wlog( "verify nofail can create test.nofail" ); - transfer( "eosio", "nofail", core_sym::from_string( "1000.0000" ) ); - create_accounts_with_resources( { N(test.nofail) }, N(nofail) ); // only nofail can create test.nofail - //wlog( "verify dan cannot create test.fail" ); - BOOST_REQUIRE_EXCEPTION( create_accounts_with_resources( { N(test.fail) }, N(dan) ), // dan shouldn't be able to do this - eosio_assert_message_exception, eosio_assert_message_is( "only suffix may create this account" ) ); - - create_accounts_with_resources( { N(goodgoodgood) }, N(dan) ); /// 12 char names should succeed -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( bid_invalid_names, eosio_system_tester ) try { - create_accounts_with_resources( { N(dan) } ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "you can only bid on top-level suffix" ), - bidname( "dan", "abcdefg.12345", core_sym::from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "the empty name is not a valid account name to bid on" ), - bidname( "dan", "", core_sym::from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "13 character names are not valid account names to bid on" ), - bidname( "dan", "abcdefgh12345", core_sym::from_string( "1.0000" ) ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "accounts with 12 character names and no dots can be created without bidding required" ), - bidname( "dan", "abcdefg12345", core_sym::from_string( "1.0000" ) ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( multiple_namebids, eosio_system_tester ) try { - - const std::string not_closed_message("auction for name is not closed yet"); - - std::vector accounts = { N(alice), N(bob), N(carl), N(david), N(eve) }; - create_accounts_with_resources( accounts ); - for ( const auto& a: accounts ) { - transfer( config::system_account_name, a, core_sym::from_string( "10000.0000" ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance(a) ); - } - create_accounts_with_resources( { N(producer) } ); - BOOST_REQUIRE_EQUAL( success(), regproducer( N(producer) ) ); - - produce_block(); - // stake but but not enough to go live - stake_with_transfer( config::system_account_name, N(bob), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); - stake_with_transfer( config::system_account_name, N(carl), core_sym::from_string( "35000000.0000" ), core_sym::from_string( "35000000.0000" ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(bob), { N(producer) } ) ); - BOOST_REQUIRE_EQUAL( success(), vote( N(carl), { N(producer) } ) ); - - // start bids - bidname( "bob", "prefa", core_sym::from_string("1.0003") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.9997" ), get_balance("bob") ); - bidname( "bob", "prefb", core_sym::from_string("1.0000") ); - bidname( "bob", "prefc", core_sym::from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9996.9997" ), get_balance("bob") ); - - bidname( "carl", "prefd", core_sym::from_string("1.0000") ); - bidname( "carl", "prefe", core_sym::from_string("1.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0000" ), get_balance("carl") ); - - BOOST_REQUIRE_EQUAL( error("assertion failure with message: account is already highest bidder"), - bidname( "bob", "prefb", core_sym::from_string("1.1001") ) ); - BOOST_REQUIRE_EQUAL( error("assertion failure with message: must increase bid by 10%"), - bidname( "alice", "prefb", core_sym::from_string("1.0999") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9996.9997" ), get_balance("bob") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance("alice") ); - - // alice outbids bob on prefb - { - const asset initial_names_balance = get_balance(N(eosio.names)); - BOOST_REQUIRE_EQUAL( success(), - bidname( "alice", "prefb", core_sym::from_string("1.1001") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9997.9997" ), get_balance("bob") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.8999" ), get_balance("alice") ); - BOOST_REQUIRE_EQUAL( initial_names_balance + core_sym::from_string("0.1001"), get_balance(N(eosio.names)) ); - } - - // david outbids carl on prefd - { - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0000" ), get_balance("carl") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "10000.0000" ), get_balance("david") ); - BOOST_REQUIRE_EQUAL( success(), - bidname( "david", "prefd", core_sym::from_string("1.9900") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9999.0000" ), get_balance("carl") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string( "9998.0100" ), get_balance("david") ); - } - - // eve outbids carl on prefe - { - BOOST_REQUIRE_EQUAL( success(), - bidname( "eve", "prefe", core_sym::from_string("1.7200") ) ); - } - - produce_block( fc::days(14) ); - produce_block(); - - // highest bid is from david for prefd but no bids can be closed yet - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefd), N(david) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - - // stake enough to go above the 15% threshold - stake_with_transfer( config::system_account_name, N(alice), core_sym::from_string( "10000000.0000" ), core_sym::from_string( "10000000.0000" ) ); - BOOST_REQUIRE_EQUAL(0, get_producer_info("producer")["unpaid_blocks"].as()); - BOOST_REQUIRE_EQUAL( success(), vote( N(alice), { N(producer) } ) ); - - // need to wait for 14 days after going live - produce_blocks(10); - produce_block( fc::days(2) ); - produce_blocks( 10 ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefd), N(david) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - // it's been 14 days, auction for prefd has been closed - produce_block( fc::days(12) ); - create_account_with_resources( N(prefd), N(david) ); - produce_blocks(2); - produce_block( fc::hours(23) ); - // auctions for prefa, prefb, prefc, prefe haven't been closed - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefa), N(bob) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(alice) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefc), N(bob) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefe), N(eve) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - // attemp to create account with no bid - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefg), N(alice) ), - fc::exception, fc_assert_exception_message_is( "no active bid for name" ) ); - // changing highest bid pushes auction closing time by 24 hours - BOOST_REQUIRE_EQUAL( success(), - bidname( "eve", "prefb", core_sym::from_string("2.1880") ) ); - - produce_block( fc::hours(22) ); - produce_blocks(2); - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(eve) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - // but changing a bid that is not the highest does not push closing time - BOOST_REQUIRE_EQUAL( success(), - bidname( "carl", "prefe", core_sym::from_string("2.0980") ) ); - produce_block( fc::hours(2) ); - produce_blocks(2); - // bid for prefb has closed, only highest bidder can claim - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(alice) ), - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefb), N(carl) ), - eosio_assert_message_exception, eosio_assert_message_is( "only highest bidder can claim" ) ); - create_account_with_resources( N(prefb), N(eve) ); - - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefe), N(carl) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - produce_block(); - produce_block( fc::hours(24) ); - // by now bid for prefe has closed - create_account_with_resources( N(prefe), N(carl) ); - // prefe can now create *.prefe - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(xyz.prefe), N(carl) ), - fc::exception, fc_assert_exception_message_is("only suffix may create this account") ); - transfer( config::system_account_name, N(prefe), core_sym::from_string("10000.0000") ); - create_account_with_resources( N(xyz.prefe), N(prefe) ); - - // other auctions haven't closed - BOOST_REQUIRE_EXCEPTION( create_account_with_resources( N(prefa), N(bob) ), - fc::exception, fc_assert_exception_message_is( not_closed_message ) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( namebid_pending_winner, eosio_system_tester ) try { - cross_15_percent_threshold(); - produce_block( fc::hours(14*24) ); //wait 14 day for name auction activation - transfer( config::system_account_name, N(alice1111111), core_sym::from_string("10000.0000") ); - transfer( config::system_account_name, N(bob111111111), core_sym::from_string("10000.0000") ); - - BOOST_REQUIRE_EQUAL( success(), bidname( "alice1111111", "prefa", core_sym::from_string( "50.0000" ) )); - BOOST_REQUIRE_EQUAL( success(), bidname( "bob111111111", "prefb", core_sym::from_string( "30.0000" ) )); - produce_block( fc::hours(100) ); //should close "perfa" - produce_block( fc::hours(100) ); //should close "perfb" - - //despite "perfa" account hasn't been created, we should be able to create "perfb" account - create_account_with_resources( N(prefb), N(bob111111111) ); -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( vote_producers_in_and_out, eosio_system_tester ) try { - - const asset net = core_sym::from_string("80.0000"); - const asset cpu = core_sym::from_string("80.0000"); - std::vector voters = { N(producvotera), N(producvoterb), N(producvoterc), N(producvoterd) }; - for (const auto& v: voters) { - create_account_with_resources(v, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu); - } - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - setup_producer_accounts(producer_names); - for (const auto& p: producer_names) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - produce_blocks(1); - ilog( "------ get pro----------" ); - wdump((p)); - BOOST_TEST(0 == get_producer_info(p)["total_votes"].as()); - } - } - - for (const auto& v: voters) { - transfer( config::system_account_name, v, core_sym::from_string("200000000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL(success(), stake(v, core_sym::from_string("30000000.0000"), core_sym::from_string("30000000.0000")) ); - } - - { - BOOST_REQUIRE_EQUAL(success(), vote(N(producvotera), vector(producer_names.begin(), producer_names.begin()+20))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterb), vector(producer_names.begin(), producer_names.begin()+21))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterc), vector(producer_names.begin(), producer_names.end()))); - } - - // give a chance for everyone to produce blocks - { - produce_blocks(23 * 12 + 20); - bool all_21_produced = true; - for (uint32_t i = 0; i < 21; ++i) { - if (0 == get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - all_21_produced = false; - } - } - bool rest_didnt_produce = true; - for (uint32_t i = 21; i < producer_names.size(); ++i) { - if (0 < get_producer_info(producer_names[i])["unpaid_blocks"].as()) { - rest_didnt_produce = false; - } - } - BOOST_REQUIRE(all_21_produced && rest_didnt_produce); - } - - { - produce_block(fc::hours(7)); - const uint32_t voted_out_index = 20; - const uint32_t new_prod_index = 23; - BOOST_REQUIRE_EQUAL(success(), stake("producvoterd", core_sym::from_string("40000000.0000"), core_sym::from_string("40000000.0000"))); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), { producer_names[new_prod_index] })); - BOOST_REQUIRE_EQUAL(0, get_producer_info(producer_names[new_prod_index])["unpaid_blocks"].as()); - produce_blocks(4 * 12 * 21); - BOOST_REQUIRE(0 < get_producer_info(producer_names[new_prod_index])["unpaid_blocks"].as()); - const uint32_t initial_unpaid_blocks = get_producer_info(producer_names[voted_out_index])["unpaid_blocks"].as(); - produce_blocks(2 * 12 * 21); - BOOST_REQUIRE_EQUAL(initial_unpaid_blocks, get_producer_info(producer_names[voted_out_index])["unpaid_blocks"].as()); - produce_block(fc::hours(24)); - BOOST_REQUIRE_EQUAL(success(), vote(N(producvoterd), { producer_names[voted_out_index] })); - produce_blocks(2 * 12 * 21); - BOOST_REQUIRE(fc::crypto::public_key() != fc::crypto::public_key(get_producer_info(producer_names[voted_out_index])["producer_key"].as_string())); - BOOST_REQUIRE_EQUAL(success(), push_action(producer_names[voted_out_index], N(claimrewards), mvo()("owner", producer_names[voted_out_index]))); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( setparams, eosio_system_tester ) try { - //install multisig contract - abi_serializer msig_abi_ser = initialize_multisig(); - auto producer_names = active_and_vote_producers(); - - //helper function - auto push_action_msig = [&]( const account_name& signer, const action_name &name, const variant_object &data, bool auth = true ) -> action_result { - string action_type_name = msig_abi_ser.get_action_type(name); - - action act; - act.account = N(eosio.msig); - act.name = name; - act.data = msig_abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); - - return base_tester::push_action( std::move(act), (auth ? signer : signer == N(bob111111111) ? N(alice1111111) : N(bob111111111)).to_uint64_t() ); - }; - - // test begins - vector prod_perms; - for ( auto& x : producer_names ) { - prod_perms.push_back( { name(x), config::active_name } ); - } - - eosio::chain::chain_config params; - params = control->get_global_properties().configuration; - //change some values - params.max_block_net_usage += 10; - params.max_transaction_lifetime += 1; - - transaction trx; - { - variant pretty_trx = fc::mutable_variant_object() - ("expiration", "2020-01-01T00:30") - ("ref_block_num", 2) - ("ref_block_prefix", 3) - ("net_usage_words", 0) - ("max_cpu_usage_ms", 0) - ("delay_sec", 0) - ("actions", fc::variants({ - fc::mutable_variant_object() - ("account", name(config::system_account_name)) - ("name", "setparams") - ("authorization", vector{ { config::system_account_name, config::active_name } }) - ("data", fc::mutable_variant_object() - ("params", params) - ) - }) - ); - abi_serializer::from_variant(pretty_trx, trx, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - } - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(propose), mvo() - ("proposer", "alice1111111") - ("proposal_name", "setparams1") - ("trx", trx) - ("requested", prod_perms) - ) - ); - - // get 16 approvals - for ( size_t i = 0; i < 15; ++i ) { - BOOST_REQUIRE_EQUAL(success(), push_action_msig( name(producer_names[i]), N(approve), mvo() - ("proposer", "alice1111111") - ("proposal_name", "setparams1") - ("level", permission_level{ name(producer_names[i]), config::active_name }) - ) - ); - } - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - BOOST_REQUIRE_EQUAL(success(), push_action_msig( N(alice1111111), N(exec), mvo() - ("proposer", "alice1111111") - ("proposal_name", "setparams1") - ("executer", "alice1111111") - ) - ); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - - produce_blocks( 250 ); - - // make sure that changed parameters were applied - auto active_params = control->get_global_properties().configuration; - BOOST_REQUIRE_EQUAL( params.max_block_net_usage, active_params.max_block_net_usage ); - BOOST_REQUIRE_EQUAL( params.max_transaction_lifetime, active_params.max_transaction_lifetime ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( setram_effect, eosio_system_tester ) try { - - const asset net = core_sym::from_string("8.0000"); - const asset cpu = core_sym::from_string("8.0000"); - std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - for (const auto& a: accounts) { - create_account_with_resources(a, config::system_account_name, core_sym::from_string("1.0000"), false, net, cpu); - } - - { - const auto name_a = accounts[0]; - transfer( config::system_account_name, name_a, core_sym::from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance(name_a) ); - const uint64_t init_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64(); - BOOST_REQUIRE_EQUAL( success(), buyram( name_a, name_a, core_sym::from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance(name_a) ); - const uint64_t bought_bytes_a = get_total_stake(name_a)["ram_bytes"].as_uint64() - init_bytes_a; - - // after buying and selling balance should be 700 + 300 * 0.995 * 0.995 = 997.0075 (actually 997.0074 due to rounding fees up) - BOOST_REQUIRE_EQUAL( success(), sellram(name_a, bought_bytes_a ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("997.0074"), get_balance(name_a) ); - } - - { - const auto name_b = accounts[1]; - transfer( config::system_account_name, name_b, core_sym::from_string("1000.0000") ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("1000.0000"), get_balance(name_b) ); - const uint64_t init_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64(); - // name_b buys ram at current price - BOOST_REQUIRE_EQUAL( success(), buyram( name_b, name_b, core_sym::from_string("300.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("700.0000"), get_balance(name_b) ); - const uint64_t bought_bytes_b = get_total_stake(name_b)["ram_bytes"].as_uint64() - init_bytes_b; - - // increase max_ram_size, ram bought by name_b loses part of its value - BOOST_REQUIRE_EQUAL( wasm_assert_msg("ram may only be increased"), - push_action(config::system_account_name, N(setram), mvo()("max_ram_size", 64ll*1024 * 1024 * 1024)) ); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action(name_b, N(setram), mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); - BOOST_REQUIRE_EQUAL( success(), - push_action(config::system_account_name, N(setram), mvo()("max_ram_size", 80ll*1024 * 1024 * 1024)) ); - - BOOST_REQUIRE_EQUAL( success(), sellram(name_b, bought_bytes_b ) ); - BOOST_REQUIRE( core_sym::from_string("900.0000") < get_balance(name_b) ); - BOOST_REQUIRE( core_sym::from_string("950.0000") > get_balance(name_b) ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( ram_inflation, eosio_system_tester ) try { - - const uint64_t init_max_ram_size = 64ll*1024 * 1024 * 1024; - - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - produce_blocks(20); - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - transfer( config::system_account_name, "alice1111111", core_sym::from_string("1000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - produce_blocks(3); - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - uint16_t rate = 1000; - BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); - BOOST_REQUIRE_EQUAL( rate, get_global_state2()["new_ram_per_block"].as() ); - // last time update_ram_supply called is in buyram, num of blocks since then to - // the block that includes the setramrate action is 1 + 3 = 4. - // However, those 4 blocks were accumulating at a rate of 0, so the max_ram_size should not have changed. - BOOST_REQUIRE_EQUAL( init_max_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - // But with additional blocks, it should start accumulating at the new rate. - uint64_t cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(10); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("100.0000") ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * rate, get_global_state()["max_ram_size"].as_uint64() ); - cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(5); - BOOST_REQUIRE_EQUAL( cur_ram_size, get_global_state()["max_ram_size"].as_uint64() ); - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 100 ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 6 * rate, get_global_state()["max_ram_size"].as_uint64() ); - cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(); - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "alice1111111", "alice1111111", 100 ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 2 * rate, get_global_state()["max_ram_size"].as_uint64() ); - - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( N(alice1111111), N(setramrate), mvo()("bytes_per_block", rate) ) ); - - cur_ram_size = get_global_state()["max_ram_size"].as_uint64(); - produce_blocks(10); - uint16_t old_rate = rate; - rate = 5000; - BOOST_REQUIRE_EQUAL( success(), push_action( config::system_account_name, N(setramrate), mvo()("bytes_per_block", rate) ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate, get_global_state()["max_ram_size"].as_uint64() ); - produce_blocks(5); - BOOST_REQUIRE_EQUAL( success(), buyrambytes( "alice1111111", "alice1111111", 100 ) ); - BOOST_REQUIRE_EQUAL( cur_ram_size + 11 * old_rate + 6 * rate, get_global_state()["max_ram_size"].as_uint64() ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( eosioram_ramusage, eosio_system_tester ) try { - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_balance( "alice1111111" ) ); - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - - const asset initial_ram_balance = get_balance(N(eosio.ram)); - const asset initial_ramfee_balance = get_balance(N(eosio.ramfee)); - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); - - BOOST_REQUIRE_EQUAL( false, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); - - //remove row - base_tester::push_action( N(eosio.token), N(close), N(alice1111111), mvo() - ( "owner", "alice1111111" ) - ( "symbol", symbol{CORE_SYM} ) - ); - BOOST_REQUIRE_EQUAL( true, get_row_by_account( N(eosio.token), N(alice1111111), N(accounts), account_name(symbol{CORE_SYM}.to_symbol_code()) ).empty() ); - - auto rlm = control->get_resource_limits_manager(); - auto eosioram_ram_usage = rlm.get_account_ram_usage(N(eosio.ram)); - auto alice_ram_usage = rlm.get_account_ram_usage(N(alice1111111)); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 2048 ) ); - - //make sure that ram was billed to alice, not to eosio.ram - BOOST_REQUIRE_EQUAL( true, alice_ram_usage < rlm.get_account_ram_usage(N(alice1111111)) ); - BOOST_REQUIRE_EQUAL( eosioram_ram_usage, rlm.get_account_ram_usage(N(eosio.ram)) ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( ram_gift, eosio_system_tester ) try { - active_and_vote_producers(); - - auto rlm = control->get_resource_limits_manager(); - int64_t ram_bytes_orig, net_weight, cpu_weight; - rlm.get_account_limits( N(alice1111111), ram_bytes_orig, net_weight, cpu_weight ); - - /* - * It seems impossible to write this test, because buyrambytes action doesn't give you exact amount of bytes requested - * - //check that it's possible to create account bying required_bytes(2724) + userres table(112) + userres row(160) - ram_gift_bytes(1400) - create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 ); - - //check that one byte less is not enough - BOOST_REQUIRE_THROW( create_account_with_resources( N(abcdefghklmn), N(alice1111111), 2724 + 112 + 160 - 1400 - 1 ), - ram_usage_exceeded ); - */ - - //check that stake/unstake keeps the gift - transfer( "eosio", "alice1111111", core_sym::from_string("1000.0000"), "eosio" ); - BOOST_REQUIRE_EQUAL( success(), stake( "eosio", "alice1111111", core_sym::from_string("200.0000"), core_sym::from_string("100.0000") ) ); - int64_t ram_bytes_after_stake; - rlm.get_account_limits( N(alice1111111), ram_bytes_after_stake, net_weight, cpu_weight ); - BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_stake ); - - BOOST_REQUIRE_EQUAL( success(), unstake( "eosio", "alice1111111", core_sym::from_string("20.0000"), core_sym::from_string("10.0000") ) ); - int64_t ram_bytes_after_unstake; - rlm.get_account_limits( N(alice1111111), ram_bytes_after_unstake, net_weight, cpu_weight ); - BOOST_REQUIRE_EQUAL( ram_bytes_orig, ram_bytes_after_unstake ); - - uint64_t ram_gift = 1400; - - int64_t ram_bytes; - BOOST_REQUIRE_EQUAL( success(), buyram( "alice1111111", "alice1111111", core_sym::from_string("1000.0000") ) ); - rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); - auto userres = get_total_stake( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); - - BOOST_REQUIRE_EQUAL( success(), sellram( "alice1111111", 1024 ) ); - rlm.get_account_limits( N(alice1111111), ram_bytes, net_weight, cpu_weight ); - userres = get_total_stake( N(alice1111111) ); - BOOST_REQUIRE_EQUAL( userres["ram_bytes"].as_uint64() + ram_gift, ram_bytes ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_auth, eosio_system_tester ) try { - - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - const account_name alice = accounts[0], bob = accounts[1]; - const asset init_balance = core_sym::from_string("1000.0000"); - const asset one_eos = core_sym::from_string("1.0000"); - const asset one_rex = asset::from_string("1.0000 REX"); - setup_rex_accounts( accounts, init_balance ); - - const std::string error_msg("missing authority of aliceaccount"); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(deposit), mvo()("owner", alice)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(withdraw), mvo()("owner", alice)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(buyrex), mvo()("from", alice)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), - push_action( bob, N(unstaketorex), mvo()("owner", alice)("receiver", alice)("from_net", one_eos)("from_cpu", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(sellrex), mvo()("from", alice)("rex", one_rex) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(cnclrexorder), mvo()("owner", alice) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), - push_action( bob, N(rentcpu), mvo()("from", alice)("receiver", alice)("loan_payment", one_eos)("loan_fund", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), - push_action( bob, N(rentnet), mvo()("from", alice)("receiver", alice)("loan_payment", one_eos)("loan_fund", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(fundcpuloan), mvo()("from", alice)("loan_num", 1)("payment", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(fundnetloan), mvo()("from", alice)("loan_num", 1)("payment", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(defcpuloan), mvo()("from", alice)("loan_num", 1)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(defnetloan), mvo()("from", alice)("loan_num", 1)("amount", one_eos) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(updaterex), mvo()("owner", alice) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(rexexec), mvo()("user", alice)("max", 1) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(consolidate), mvo()("owner", alice) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(mvtosavings), mvo()("owner", alice)("rex", one_rex) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(mvfrsavings), mvo()("owner", alice)("rex", one_rex) ) ); - BOOST_REQUIRE_EQUAL( error(error_msg), push_action( bob, N(closerex), mvo()("owner", alice) ) ); - - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), push_action( alice, N(setrex), mvo()("balance", one_eos) ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_rent = core_sym::from_string("20000.0000"); - const asset init_balance = core_sym::from_string("1000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - const asset one_unit = core_sym::from_string("0.0001"); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), buyrex( alice, init_balance + one_unit ) ); - BOOST_REQUIRE_EQUAL( asset::from_string("25000.0000 REX"), get_buyrex_result( alice, core_sym::from_string("2.5000") ) ); - produce_blocks(2); - produce_block(fc::days(5)); - BOOST_REQUIRE_EQUAL( core_sym::from_string("2.5000"), get_sellrex_result( alice, asset::from_string("25000.0000 REX") ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("13.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("13.0000"), get_rex_vote_stake( alice ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("17.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), get_rex_vote_stake( alice ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("970.0000"), get_rex_fund(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice).get_amount(), ratio * asset::from_string("30.0000 REX").get_amount() ); - auto rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("30.0000"), rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice), rex_pool["total_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("75.0000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("925.0000"), get_rex_fund(bob) ); - BOOST_REQUIRE_EQUAL( ratio * asset::from_string("75.0000 REX").get_amount(), get_rex_balance(bob).get_amount() ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("105.0000"), rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("105.0000"), rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); - - produce_block( fc::days(6) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("user must first buyrex"), sellrex( carol, asset::from_string("5.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - sellrex( bob, core_sym::from_string("55.0000") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - sellrex( bob, asset::from_string("-75.0030 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), sellrex( bob, asset::from_string("750000.0030 REX") ) ); - - auto init_total_rex = rex_pool["total_rex"].as().get_amount(); - auto init_total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset::from_string("550001.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( asset::from_string("199999.0000 REX"), get_rex_balance(bob) ); - rex_pool = get_rex_pool(); - auto total_rex = rex_pool["total_rex"].as().get_amount(); - auto total_lendable = rex_pool["total_lendable"].as().get_amount(); - BOOST_REQUIRE_EQUAL( init_total_rex / init_total_lendable, total_rex / total_lendable ); - BOOST_REQUIRE_EQUAL( total_lendable, rex_pool["total_unlent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rent, rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_balance(alice) + get_rex_balance(bob), rex_pool["total_rex"].as() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_small_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("50000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; - setup_rex_accounts( accounts, init_balance ); - - const asset payment = core_sym::from_string("40000.0000"); - BOOST_REQUIRE_EQUAL( ratio * payment.get_amount(), get_buyrex_result( alice, payment ).get_amount() ); - - produce_blocks(2); - produce_block( fc::days(5) ); - produce_blocks(2); - - asset init_rex_stake = get_rex_vote_stake( alice ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.0001 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.9999 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0001"), get_sellrex_result( alice, asset::from_string("1.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0001"), get_sellrex_result( alice, asset::from_string("1.9999 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0002"), get_sellrex_result( alice, asset::from_string("2.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0002"), get_sellrex_result( alice, asset::from_string("2.9999 REX") ) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake( alice ), init_rex_stake - core_sym::from_string("0.0006") ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, bob, core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("proceeds are negligible"), sellrex( alice, asset::from_string("0.4000 REX") ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( unstake_buy_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { - - const int64_t ratio = 10000; - const asset zero_asset = core_sym::from_string("0.0000"); - const asset neg_asset = core_sym::from_string("-0.0001"); - const asset one_token = core_sym::from_string("1.0000"); - const asset init_balance = core_sym::from_string("10000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - - setup_producer_accounts(producer_names); - for ( const auto& p: producer_names ) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); - } - } - - const int64_t init_cpu_limit = get_cpu_limit( alice ); - const int64_t init_net_limit = get_net_limit( alice ); - - { - const asset net_stake = core_sym::from_string("25.5000"); - const asset cpu_stake = core_sym::from_string("12.4000"); - const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( init_balance, get_balance( alice ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit + cpu_stake.get_amount() ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit + net_stake.get_amount() ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), - unstaketorex( alice, alice, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - const asset init_eosio_stake_balance = get_balance( N(eosio.stake) ); - const auto init_voter_info = get_voter_info( alice ); - const auto init_prod_info = get_producer_info( producer_names[0] ); - BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() == - stake2votes( asset( init_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); - produce_block( fc::days(4) ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_unstaketorex_result( alice, alice, net_stake, cpu_stake ).get_amount() ); - BOOST_REQUIRE_EQUAL( get_cpu_limit( alice ), init_cpu_limit ); - BOOST_REQUIRE_EQUAL( get_net_limit( alice ), init_net_limit ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( tot_stake, get_rex_balance_obj( alice )["vote_stake"].as() ); - BOOST_REQUIRE_EQUAL( tot_stake, get_balance( N(eosio.rex) ) ); - BOOST_REQUIRE_EQUAL( tot_stake, init_eosio_stake_balance - get_balance( N(eosio.stake) ) ); - auto current_voter_info = get_voter_info( alice ); - auto current_prod_info = get_producer_info( producer_names[0] ); - BOOST_REQUIRE_EQUAL( init_voter_info["staked"].as(), current_voter_info["staked"].as() ); - BOOST_TEST_REQUIRE( current_prod_info["total_votes"].as_double() == - stake2votes( asset( current_voter_info["staked"].as(), symbol{CORE_SYM} ) ) ); - BOOST_TEST_REQUIRE( init_prod_info["total_votes"].as_double() < current_prod_info["total_votes"].as_double() ); - } - - { - const asset net_stake = core_sym::from_string("200.5000"); - const asset cpu_stake = core_sym::from_string("120.0000"); - const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( success(), stake( bob, carol, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("amount exceeds tokens staked for net"), - unstaketorex( bob, carol, net_stake + one_token, zero_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("amount exceeds tokens staked for cpu"), - unstaketorex( bob, carol, zero_asset, cpu_stake + one_token ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), - unstaketorex( bob, emily, zero_asset, one_token ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), - unstaketorex( bob, carol, zero_asset, zero_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), - unstaketorex( bob, carol, neg_asset, one_token ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must unstake a positive amount to buy rex"), - unstaketorex( bob, carol, one_token, neg_asset ) ); - BOOST_REQUIRE_EQUAL( init_net_limit + net_stake.get_amount(), get_net_limit( carol ) ); - BOOST_REQUIRE_EQUAL( init_cpu_limit + cpu_stake.get_amount(), get_cpu_limit( carol ) ); - BOOST_REQUIRE_EQUAL( false, get_dbw_obj( bob, carol ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, net_stake, zero_asset ) ); - BOOST_REQUIRE_EQUAL( false, get_dbw_obj( bob, carol ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( bob, carol, zero_asset, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( true, get_dbw_obj( bob, carol ).is_null() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( carol ).get_amount() ); - BOOST_REQUIRE_EQUAL( ratio * tot_stake.get_amount(), get_rex_balance( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( bob ) ); - BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( bob ) ); - BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); - BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); - } - - { - const asset net_stake = core_sym::from_string("130.5000"); - const asset cpu_stake = core_sym::from_string("220.0800"); - const asset tot_stake = net_stake + cpu_stake; - BOOST_REQUIRE_EQUAL( success(), stake_with_transfer( emily, frank, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("delegated bandwidth record does not exist"), - unstaketorex( emily, frank, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( frank, frank, net_stake, cpu_stake ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( frank, asset::from_string("1.0000 REX") ) ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( frank, asset::from_string("1.0000 REX") ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_rent_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("60000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu ); - - const int64_t init_cpu_limit = get_cpu_limit( alice ); - const int64_t init_net_limit = get_net_limit( alice ); - - // bob tries to rent rex - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system not initialized yet"), rentcpu( bob, carol, core_sym::from_string("5.0000") ) ); - // alice lends rex - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("50265.0000") ) ); - BOOST_REQUIRE_EQUAL( init_balance - core_sym::from_string("50265.0000"), get_rex_fund(alice) ); - auto rex_pool = get_rex_pool(); - const asset init_tot_unlent = rex_pool["total_unlent"].as(); - const asset init_tot_lendable = rex_pool["total_lendable"].as(); - const asset init_tot_rent = rex_pool["total_rent"].as(); - const int64_t init_stake = get_voter_info(alice)["staked"].as(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); - - BOOST_REQUIRE( get_rex_return_pool().is_null() ); - - { - // bob rents cpu for carol - const asset fee = core_sym::from_string("17.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); - BOOST_REQUIRE_EQUAL( init_balance - fee, get_rex_fund(bob) ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); // 65 - BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); // 100 + 17 - int64_t expected_total_lent = bancor_convert( init_tot_rent.get_amount(), init_tot_unlent.get_amount(), fee.get_amount() ); - BOOST_REQUIRE_EQUAL( expected_total_lent, - rex_pool["total_lent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_lent"].as() + rex_pool["total_unlent"].as(), - rex_pool["total_lendable"].as() ); - - auto rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE( !rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - - // test that carol's resource limits have been updated properly - BOOST_REQUIRE_EQUAL( expected_total_lent, get_cpu_limit( carol ) - init_cpu_limit ); - BOOST_REQUIRE_EQUAL( 0, get_net_limit( carol ) - init_net_limit ); - - // alice tries to sellrex, order gets scheduled then she cancels order - BOOST_REQUIRE_EQUAL( cancelrexorder( alice ), wasm_assert_msg("no sellrex order is scheduled") ); - produce_block( fc::days(6) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) ); - - produce_block( fc::days(20) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE( !rex_return_pool.is_null() ); - int64_t rate = fee.get_amount() / (30 * 144); - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - - produce_block( fc::days(10) ); - // alice is finally able to sellrex, she gains the fee paid by bob - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - auto expected_rex_fund = (init_balance + fee).get_amount(); - auto actual_rex_fund = get_rex_fund(alice).get_amount(); - BOOST_REQUIRE_EQUAL( expected_rex_fund, actual_rex_fund ); - // test that carol's resource limits have been updated properly when loan expires - BOOST_REQUIRE_EQUAL( init_cpu_limit, get_cpu_limit( carol ) ); - BOOST_REQUIRE_EQUAL( init_net_limit, get_net_limit( carol ) ); - - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_unlent"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); - } - - { - const int64_t init_net_limit = get_net_limit( emily ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("20050.0000") ) ); - rex_pool = get_rex_pool(); - const asset fee = core_sym::from_string("0.4560"); - int64_t expected_net = bancor_convert( rex_pool["total_rent"].as().get_amount(), - rex_pool["total_unlent"].as().get_amount(), - fee.get_amount() ); - BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, fee ) ); - BOOST_REQUIRE_EQUAL( expected_net, get_net_limit( emily ) - init_net_limit ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_sell_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("40000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu ); - - const int64_t init_cpu_limit = get_cpu_limit( alice ); - const int64_t init_net_limit = get_net_limit( alice ); - - // alice lends rex - const asset payment = core_sym::from_string("30250.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, core_sym::from_string("0.0005") ) ); - BOOST_REQUIRE_EQUAL( init_balance - payment, get_rex_fund(alice) ); - auto rex_pool = get_rex_pool(); - const asset init_tot_unlent = rex_pool["total_unlent"].as(); - const asset init_tot_lendable = rex_pool["total_lendable"].as(); - const asset init_tot_rent = rex_pool["total_rent"].as(); - const int64_t init_stake = get_voter_info(alice)["staked"].as(); - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( ratio * init_tot_lendable.get_amount(), rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_rex"].as(), get_rex_balance(alice) + get_rex_balance(bob) ); - - // bob rents cpu for carol - const asset fee = core_sym::from_string("7.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, carol, fee ) ); - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_tot_lendable, rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( init_tot_rent + fee, rex_pool["total_rent"].as() ); - - produce_block( fc::days(5) ); - produce_blocks(2); - const asset rex_tok = asset::from_string("1.0000 REX"); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) - rex_tok ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_order_obj( alice ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_tok ) ); - BOOST_REQUIRE_EQUAL( sellrex( alice, rex_tok ), wasm_assert_msg("insufficient funds for current and scheduled orders") ); - BOOST_REQUIRE_EQUAL( ratio * payment.get_amount() - rex_tok.get_amount(), get_rex_order( alice )["rex_requested"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), consolidate( alice ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["rex_maturities"].get_array().size() ); - - produce_block( fc::days(26) ); - produce_blocks(2); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 2 ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["matured_rex"].as() ); - const asset init_fund = get_rex_fund( alice ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance_obj( alice )["matured_rex"].as() ); - BOOST_REQUIRE ( init_fund < get_rex_fund( alice ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( buy_sell_claim_rex, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("3000000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - const auto purchase1 = core_sym::from_string("50000.0000"); - const auto purchase2 = core_sym::from_string("105500.0000"); - const auto purchase3 = core_sym::from_string("104500.0000"); - const auto init_stake = get_voter_info(alice)["staked"].as(); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase1) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, purchase2) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, purchase3) ); - - BOOST_REQUIRE_EQUAL( init_balance - purchase1, get_rex_fund(alice) ); - BOOST_REQUIRE_EQUAL( purchase1.get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); - - BOOST_REQUIRE_EQUAL( init_balance - purchase2, get_rex_fund(bob) ); - BOOST_REQUIRE_EQUAL( init_balance - purchase3, get_rex_fund(carol) ); - - auto init_alice_rex = get_rex_balance(alice); - auto init_bob_rex = get_rex_balance(bob); - auto init_carol_rex = get_rex_balance(carol); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("20000.0000"), get_rex_pool()["total_rent"].as() ); - - for (uint8_t i = 0; i < 4; ++i) { - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, emily, core_sym::from_string("12000.0000") ) ); - } - - produce_block( fc::days(25) ); - - const asset rent_payment = core_sym::from_string("46000.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, rent_payment, rent_payment ) ); - - produce_block( fc::days(4) ); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - - const auto init_rex_pool = get_rex_pool(); - const int64_t total_lendable = init_rex_pool["total_lendable"].as().get_amount(); - const int64_t total_rex = init_rex_pool["total_rex"].as().get_amount(); - const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_alice_rex.get_amount()) * total_lendable ) / total_rex; - - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 3 * get_rex_balance(alice).get_amount() / 4, symbol{SY(4,REX)} ) ) ); - - BOOST_TEST_REQUIRE( within_one( init_alice_rex.get_amount() / 4, get_rex_balance(alice).get_amount() ) ); - - init_alice_rex = get_rex_balance(alice); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance(bob) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance(carol) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance(alice) ) ); - - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_balance(bob) ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_balance(carol) ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_balance(alice) ); - - // now bob's, carol's and alice's sellrex orders have been queued - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(bob)["proceeds"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); - - // wait for a total of 30 days minus 1 hour - produce_block( fc::hours(23) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - - // wait for 2 more hours, by now frank's loan has expired and there is enough balance in - // total_unlent to close some sellrex orders. only two are processed, bob's and carol's. - // alices's order is still open. - // an action is needed to trigger queue processing - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( frank, frank, core_sym::from_string("0.0001") ) ); - { - auto trace = base_tester::push_action( config::system_account_name, N(rexexec), frank, - mvo()("user", frank)("max", 2) ); - auto output = get_rexorder_result( trace ); - BOOST_REQUIRE_EQUAL( output.size(), 1 ); - BOOST_REQUIRE_EQUAL( output[0].first, bob ); - BOOST_REQUIRE_EQUAL( output[0].second, get_rex_order(bob)["proceeds"].as() ); - } - - { - BOOST_REQUIRE_EQUAL( false, get_rex_order(bob)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_bob_rex, get_rex_order(bob)["rex_requested"].as() ); - BOOST_TEST_REQUIRE ( 0 < get_rex_order(bob)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_order(alice)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_alice_rex, get_rex_order(alice)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(alice)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_order(carol)["is_open"].as() ); - BOOST_REQUIRE_EQUAL( init_carol_rex, get_rex_order(carol)["rex_requested"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_order(carol)["proceeds"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); - } - - produce_blocks(2); - produce_block( fc::hours(13) ); - produce_blocks(2); - produce_block( fc::days(30) ); - produce_blocks(2); - - { - auto trace1 = base_tester::push_action( config::system_account_name, N(updaterex), bob, mvo()("owner", bob) ); - auto trace2 = base_tester::push_action( config::system_account_name, N(updaterex), carol, mvo()("owner", carol) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( bob )["staked"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_vote_stake( carol ).get_amount() ); - BOOST_REQUIRE_EQUAL( init_stake, get_voter_info( carol )["staked"].as() ); - auto output1 = get_rexorder_result( trace1 ); - auto output2 = get_rexorder_result( trace2 ); - BOOST_REQUIRE_EQUAL( 2, output1.size() + output2.size() ); - - BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(bob).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_order_obj(carol).is_null() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); - - const auto& rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_pool["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( emily, core_sym::from_string("22000.0000") ) ); - BOOST_REQUIRE_EQUAL( false, get_rex_order_obj(alice).is_null() ); - BOOST_REQUIRE_EQUAL( false, get_rex_order(alice)["is_open"].as() ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( frank, frank, core_sym::from_string("1.0000") ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_loans, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("40000.0000"); - const asset one_unit = core_sym::from_string("0.0001"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("25000.0000") ) ); - - auto rex_pool = get_rex_pool(); - const asset payment = core_sym::from_string("30.0000"); - const asset zero_asset = core_sym::from_string("0.0000"); - const asset neg_asset = core_sym::from_string("-1.0000"); - BOOST_TEST_REQUIRE( 0 > neg_asset.get_amount() ); - asset cur_frank_balance = get_rex_fund( frank ); - int64_t expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount(), - rex_pool["total_unlent"].as().get_amount(), - payment.get_amount() ); - const int64_t init_stake = get_cpu_limit( frank ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use core token"), - rentcpu( frank, bob, asset::from_string("10.0000 RND") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use core token"), - rentcpu( frank, bob, payment, asset::from_string("10.0000 RND") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), - rentcpu( frank, bob, zero_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), - rentcpu( frank, bob, payment, neg_asset ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must use positive asset amount"), - rentcpu( frank, bob, neg_asset, payment ) ); - // create 2 cpu and 3 net loans - const asset rented_tokens{ expected_stake, symbol{CORE_SYM} }; - BOOST_REQUIRE_EQUAL( rented_tokens, get_rentcpu_result( frank, bob, payment ) ); // loan_num = 1 - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, emily, payment ) ); // loan_num = 2 - BOOST_REQUIRE_EQUAL( 2, get_last_cpu_loan()["loan_num"].as_uint64() ); - - asset expected_rented_net; - { - const auto& pool = get_rex_pool(); - const int64_t r = bancor_convert( pool["total_rent"].as().get_amount(), - pool["total_unlent"].as().get_amount(), - payment.get_amount() ); - expected_rented_net = asset{ r, symbol{CORE_SYM} }; - } - BOOST_REQUIRE_EQUAL( expected_rented_net, get_rentnet_result( alice, emily, payment ) ); // loan_num = 3 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, alice, payment ) ); // loan_num = 4 - BOOST_REQUIRE_EQUAL( success(), rentnet( alice, frank, payment ) ); // loan_num = 5 - BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); - - auto loan_info = get_cpu_loan(1); - auto old_frank_balance = cur_frank_balance; - cur_frank_balance = get_rex_fund( frank ); - BOOST_REQUIRE_EQUAL( old_frank_balance, payment + cur_frank_balance ); - BOOST_REQUIRE_EQUAL( 1, loan_info["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); - BOOST_REQUIRE_EQUAL( 0, loan_info["balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); - - // frank funds his loan enough to be renewed once - const asset fund = core_sym::from_string("35.0000"); - BOOST_REQUIRE_EQUAL( fundcpuloan( frank, 1, cur_frank_balance + one_unit), wasm_assert_msg("insufficient funds") ); - BOOST_REQUIRE_EQUAL( fundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); - BOOST_REQUIRE_EQUAL( fundcpuloan( alice, 1, fund ), wasm_assert_msg("user must be loan creator") ); - BOOST_REQUIRE_EQUAL( success(), fundcpuloan( frank, 1, fund ) ); - old_frank_balance = cur_frank_balance; - cur_frank_balance = get_rex_fund( frank ); - loan_info = get_cpu_loan(1); - BOOST_REQUIRE_EQUAL( old_frank_balance, fund + cur_frank_balance ); - BOOST_REQUIRE_EQUAL( fund, loan_info["balance"].as() ); - BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); - - // in the meantime, defund then fund the same amount and test the balances - { - const asset amount = core_sym::from_string("7.5000"); - BOOST_REQUIRE_EQUAL( defundnetloan( frank, 1, fund ), wasm_assert_msg("loan not found") ); - BOOST_REQUIRE_EQUAL( defundcpuloan( alice, 1, fund ), wasm_assert_msg("user must be loan creator") ); - BOOST_REQUIRE_EQUAL( defundcpuloan( frank, 1, core_sym::from_string("75.0000") ), wasm_assert_msg("insufficent loan balance") ); - old_frank_balance = cur_frank_balance; - asset old_loan_balance = get_cpu_loan(1)["balance"].as(); - BOOST_REQUIRE_EQUAL( defundcpuloan( frank, 1, amount ), success() ); - BOOST_REQUIRE_EQUAL( old_loan_balance, get_cpu_loan(1)["balance"].as() + amount ); - cur_frank_balance = get_rex_fund( frank ); - old_loan_balance = get_cpu_loan(1)["balance"].as(); - BOOST_REQUIRE_EQUAL( old_frank_balance + amount, cur_frank_balance ); - old_frank_balance = cur_frank_balance; - BOOST_REQUIRE_EQUAL( fundcpuloan( frank, 1, amount ), success() ); - BOOST_REQUIRE_EQUAL( old_loan_balance + amount, get_cpu_loan(1)["balance"].as() ); - cur_frank_balance = get_rex_fund( frank ); - BOOST_REQUIRE_EQUAL( old_frank_balance - amount, cur_frank_balance ); - } - - // wait for 30 days, frank's loan will be renewed at the current price - produce_block( fc::minutes(30*24*60 - 1) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - rex_pool = get_rex_pool(); - { - int64_t unlent_tokens = bancor_convert( rex_pool["total_unlent"].as().get_amount(), - rex_pool["total_rent"].as().get_amount(), - expected_stake ); - - expected_stake = bancor_convert( rex_pool["total_rent"].as().get_amount() - unlent_tokens, - rex_pool["total_unlent"].as().get_amount() + expected_stake, - payment.get_amount() ); - } - - produce_block( fc::minutes(2) ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1.0000 REX") ) ); - - loan_info = get_cpu_loan(1); - BOOST_REQUIRE_EQUAL( payment, loan_info["payment"].as() ); - BOOST_REQUIRE_EQUAL( fund - payment, loan_info["balance"].as() ); - BOOST_REQUIRE_EQUAL( expected_stake, loan_info["total_staked"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( expected_stake + init_stake, get_cpu_limit( bob ) ); - - // check that loans have been processed in order - BOOST_REQUIRE_EQUAL( false, get_cpu_loan(1).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_cpu_loan(2).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_net_loan(3).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_net_loan(4).is_null() ); - BOOST_REQUIRE_EQUAL( false, get_net_loan(5).is_null() ); - BOOST_REQUIRE_EQUAL( 1, get_last_cpu_loan()["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( 5, get_last_net_loan()["loan_num"].as_uint64() ); - - // wait for another month, frank's loan doesn't have enough funds and will be closed - produce_block( fc::hours(30*24) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("10.0000") ) ); - BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); - BOOST_REQUIRE_EQUAL( init_stake, get_cpu_limit( bob ) ); - old_frank_balance = cur_frank_balance; - cur_frank_balance = get_rex_fund( frank ); - BOOST_REQUIRE_EQUAL( fund - payment, cur_frank_balance - old_frank_balance ); - BOOST_REQUIRE ( old_frank_balance < cur_frank_balance ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_loan_checks, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("40000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const asset payment1 = core_sym::from_string("20000.0000"); - const asset payment2 = core_sym::from_string("4.0000"); - const asset fee = core_sym::from_string("1.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("loan price does not favor renting"), - rentcpu( bob, bob, fee ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment2 ) ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee, fee + fee + fee ) ); - BOOST_REQUIRE_EQUAL( true, !get_cpu_loan(1).is_null() ); - BOOST_REQUIRE_EQUAL( 3 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); - - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 3) ); - BOOST_REQUIRE_EQUAL( 2 * fee.get_amount(), get_last_cpu_loan()["balance"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("1000000.0000 REX") ) ); - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 3) ); - BOOST_REQUIRE_EQUAL( true, get_cpu_loan(1).is_null() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( ramfee_namebid_to_rex, eosio_system_tester ) try { - - const int64_t ratio = 10000; - const asset init_balance = core_sym::from_string("10000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance, core_sym::from_string("80.0000"), core_sym::from_string("80.0000"), false ); - - asset cur_ramfee_balance = get_balance( N(eosio.ramfee) ); - BOOST_REQUIRE_EQUAL( success(), buyram( alice, alice, core_sym::from_string("20.0000") ) ); - BOOST_REQUIRE_EQUAL( get_balance( N(eosio.ramfee) ), core_sym::from_string("0.1000") + cur_ramfee_balance ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit to REX fund first"), - buyrex( alice, core_sym::from_string("350.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, core_sym::from_string("350.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("350.0000") ) ); - cur_ramfee_balance = get_balance( N(eosio.ramfee) ); - asset cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("350.0000"), cur_rex_balance ); - BOOST_REQUIRE_EQUAL( success(), buyram( bob, carol, core_sym::from_string("70.0000") ) ); - BOOST_REQUIRE_EQUAL( cur_ramfee_balance, get_balance( N(eosio.ramfee) ) ); - BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("0.3500") ); - - cur_rex_balance = get_balance( N(eosio.rex) ); - - produce_blocks( 1 ); - produce_block( fc::hours(30*24 + 12) ); - produce_blocks( 1 ); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - auto cur_rex_pool = get_rex_pool(); - - BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_unlent"].as().get_amount() ) ); - BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["total_lent"].as().get_amount() ); - BOOST_TEST_REQUIRE( within_one( cur_rex_balance.get_amount(), cur_rex_pool["total_lendable"].as().get_amount() ) ); - BOOST_TEST_REQUIRE( cur_rex_balance >= cur_rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( 0, cur_rex_pool["namebid_proceeds"].as().get_amount() ); - - // required for closing namebids - cross_15_percent_threshold(); - produce_block( fc::days(14) ); - - cur_rex_balance = get_balance( N(eosio.rex) ); - BOOST_REQUIRE_EQUAL( success(), bidname( carol, N(rndmbid), core_sym::from_string("23.7000") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("23.7000"), get_balance( N(eosio.names) ) ); - BOOST_REQUIRE_EQUAL( success(), bidname( alice, N(rndmbid), core_sym::from_string("29.3500") ) ); - BOOST_REQUIRE_EQUAL( core_sym::from_string("29.3500"), get_balance( N(eosio.names) )); - - produce_block( fc::hours(24) ); - produce_blocks( 2 ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("29.3500"), get_rex_pool()["namebid_proceeds"].as() ); - BOOST_REQUIRE_EQUAL( success(), deposit( frank, core_sym::from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( frank, core_sym::from_string("5.0000") ) ); - BOOST_REQUIRE_EQUAL( get_balance( N(eosio.rex) ), cur_rex_balance + core_sym::from_string("34.3500") ); - BOOST_REQUIRE_EQUAL( 0, get_balance( N(eosio.names) ).get_amount() ); - - cur_rex_balance = get_balance( N(eosio.rex) ); - produce_block( fc::hours(30*24 + 13) ); - produce_blocks( 1 ); - - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - BOOST_REQUIRE_EQUAL( cur_rex_balance, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( get_rex_pool()["total_lendable"].as(), - get_rex_pool()["total_unlent"].as() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_maturity, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("1000000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t rex_ratio = 10000; - const symbol rex_sym( SY(4, REX) ); - - { - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("11.5000") ) ); - produce_block( fc::hours(3) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("18.5000") ) ); - produce_block( fc::hours(25) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, core_sym::from_string("25.0000") ) ); - - auto rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 550000 * rex_ratio, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string("115000.0000 REX") ) ); - produce_block( fc::hours( 3*24 + 20) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("300000.0000 REX") ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 250000 * rex_ratio, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::hours(23) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string("250000.0000 REX") ) ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("130000.0000 REX") ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 1200000000, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string("130000.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string("120000.0000 REX") ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); - } - - { - const asset payment1 = core_sym::from_string("14.8000"); - const asset payment2 = core_sym::from_string("15.2000"); - const asset payment = payment1 + payment2; - const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); - for ( uint8_t i = 0; i < 8; ++i ) { - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment1 ) ); - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); - produce_block( fc::hours(24) ); - } - - auto rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - produce_block( fc::hours(2) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 3 * rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, asset( 2 * rex_bucket.get_amount(), rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - - produce_block( fc::hours(23) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - - produce_block( fc::days(3) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); - produce_block( fc::hours(24 + 20) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 4 * rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - } - - { - const asset payment1 = core_sym::from_string("250000.0000"); - const asset payment2 = core_sym::from_string("10000.0000"); - const asset rex_bucket1( rex_ratio * payment1.get_amount(), rex_sym ); - const asset rex_bucket2( rex_ratio * payment2.get_amount(), rex_sym ); - const asset tot_rex = rex_bucket1 + rex_bucket2; - - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment1 ) ); - produce_block( fc::days(3) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment2 ) ); - produce_block( fc::days(2) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( bob ) ); - - auto rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( alice, alice, core_sym::from_string("8000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket1.get_amount() - 20, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), get_rex_order( bob )["rex_requested"].as().get_amount() + 20 ); - BOOST_REQUIRE_EQUAL( tot_rex, rex_balance["rex_balance"].as() ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( rex_bucket1.get_amount(), rex_balance["matured_rex"].as() + 20 ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( bob ) ); - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_savings, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("100000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount), N(frankaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3], frank = accounts[4]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t rex_ratio = 10000; - const symbol rex_sym( SY(4, REX) ); - - { - const asset payment1 = core_sym::from_string("14.8000"); - const asset payment2 = core_sym::from_string("15.2000"); - const asset payment = payment1 + payment2; - const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); - for ( uint8_t i = 0; i < 8; ++i ) { - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment1 ) ); - produce_block( fc::hours(12) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment2 ) ); - produce_block( fc::hours(14) ); - } - - auto rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 8 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( 8 * rex_bucket.get_amount(), rex_sym ) ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - produce_block( fc::days(1000) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "1.0000 REX" ) ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, asset::from_string( "10.0000 REX" ) ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::days(3) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "1.0000 REX" ) ) ); - produce_blocks( 2 ); - produce_block( fc::days(2) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "10.0001 REX" ) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset::from_string( "10.0000 REX" ) ) ); - rex_balance = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::days(100) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( alice, asset::from_string( "0.0001 REX" ) ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, get_rex_balance( alice ) ) ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); - } - - { - const asset payment = core_sym::from_string("20.0000"); - const asset rex_bucket( rex_ratio * payment.get_amount(), rex_sym ); - for ( uint8_t i = 0; i < 5; ++i ) { - produce_block( fc::hours(24) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, payment ) ); - } - - auto rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 5 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 6, rex_balance["rex_maturities"].get_array().size() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 5, rex_balance["rex_maturities"].get_array().size() ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 4, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 4 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( bob, asset( 3 * rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 3 * rex_bucket.get_amount(), rex_balance["rex_balance"].as().get_amount() ); - - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( 5 * rex_bucket.get_amount(), 2 * rex_balance["rex_balance"].as().get_amount() ); - - produce_block( fc::days(20) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX in savings"), - mvfrsavings( bob, asset( 3 * rex_bucket.get_amount(), rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( 2, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX balance"), - mvtosavings( bob, asset( 3 * rex_bucket.get_amount() / 2, rex_sym ) ) ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( 3, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - produce_block( fc::days(4) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, rex_bucket ) ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, rex_bucket ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount() / 2, rex_balance["rex_balance"].as().get_amount() ); - - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 4, rex_sym ) ) ); - produce_block( fc::days(2) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, asset( rex_bucket.get_amount() / 8, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( 3, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( success(), consolidate( bob ) ); - BOOST_REQUIRE_EQUAL( 2, get_rex_balance_obj( bob )["rex_maturities"].get_array().size() ); - - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient available rex"), - sellrex( bob, asset( rex_bucket.get_amount() / 2, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, asset( 3 * rex_bucket.get_amount() / 8, rex_sym ) ) ); - rex_balance = get_rex_balance_obj( bob ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - BOOST_REQUIRE_EQUAL( rex_bucket.get_amount() / 8, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( bob, get_rex_balance( bob ) ) ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - } - - { - const asset payment = core_sym::from_string("40000.0000"); - const int64_t rex_bucket_amount = rex_ratio * payment.get_amount(); - const asset rex_bucket( rex_bucket_amount, rex_sym ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_pool()["total_rex"].as() ); - - produce_block( fc::days(5) ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("3000.0000") ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( 9 * rex_bucket_amount / 10, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( alice ) ); - BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX balance"), - mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - BOOST_REQUIRE_EQUAL( success(), mvtosavings( alice, asset( rex_bucket_amount / 10, rex_sym ) ) ); - auto rb = get_rex_balance_obj( alice ); - BOOST_REQUIRE_EQUAL( rb["matured_rex"].as(), 8 * rex_bucket_amount / 10 ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( alice, asset( 2 * rex_bucket_amount / 10, rex_sym ) ) ); - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); - } - - { - const asset payment = core_sym::from_string("250.0000"); - const asset half_payment = core_sym::from_string("125.0000"); - const int64_t rex_bucket_amount = rex_ratio * payment.get_amount(); - const int64_t half_rex_bucket_amount = rex_bucket_amount / 2; - const asset rex_bucket( rex_bucket_amount, rex_sym ); - const asset half_rex_bucket( half_rex_bucket_amount, rex_sym ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, payment ) ); - BOOST_REQUIRE_EQUAL( rex_bucket, get_rex_balance( carol ) ); - auto rex_balance = get_rex_balance_obj( carol ); - - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, payment ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 2, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, rex_balance["matured_rex"].as() ); - - BOOST_REQUIRE_EQUAL( success(), mvtosavings( carol, half_rex_bucket ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - - BOOST_REQUIRE_EQUAL( success(), buyrex( carol, half_payment ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 3, rex_balance["rex_maturities"].get_array().size() ); - - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - mvfrsavings( carol, asset::from_string("0.0000 REX") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("asset must be a positive amount of (REX, 4)"), - mvfrsavings( carol, asset::from_string("1.0000 RND") ) ); - BOOST_REQUIRE_EQUAL( success(), mvfrsavings( carol, half_rex_bucket ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient REX in savings"), - mvfrsavings( carol, asset::from_string("0.0001 REX") ) ); - rex_balance = get_rex_balance_obj( carol ); - BOOST_REQUIRE_EQUAL( 1, rex_balance["rex_maturities"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 5 * half_rex_bucket_amount, rex_balance["rex_balance"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 2 * rex_bucket_amount, rex_balance["matured_rex"].as() ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( carol, get_rex_balance( carol) ) ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( update_rex, eosio_system_tester, * boost::unit_test::tolerance(1e-10) ) try { - - const asset init_balance = core_sym::from_string("30000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t init_stake = get_voter_info( alice )["staked"].as(); - - // alice buys rex - const asset payment = core_sym::from_string("25000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake ); - - // emily rents cpu - const asset fee = core_sym::from_string("50.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, fee ) ); - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_REQUIRE_EQUAL( payment, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info( alice )["staked"].as() - init_stake ); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - - setup_producer_accounts(producer_names); - for ( const auto& p: producer_names ) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); - } - } - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("voter holding REX tokens must vote for at least 21 producers or for a proxy"), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 20) ) ); - BOOST_REQUIRE_EQUAL( success(), - vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[0])["total_votes"].as() ); - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[20])["total_votes"].as() ); - - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - produce_block( fc::days(10) ); - BOOST_TEST_REQUIRE( get_producer_info(producer_names[20])["total_votes"].as() - < stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) ); - - BOOST_REQUIRE_EQUAL( success(), updaterex( alice ) ); - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[20])["total_votes"].as() ); - - produce_block( fc::hours(19 * 24 + 23) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - const asset init_rex = get_rex_balance( alice ); - const auto current_rex_pool = get_rex_pool(); - const int64_t total_lendable = current_rex_pool["total_lendable"].as().get_amount(); - const int64_t total_rex = current_rex_pool["total_rex"].as().get_amount(); - const int64_t init_alice_rex_stake = ( eosio::chain::uint128_t(init_rex.get_amount()) * total_lendable ) / total_rex; - const asset rex_sell_amount( get_rex_balance(alice).get_amount() / 4, symbol( SY(4,REX) ) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, rex_sell_amount ) ); - BOOST_REQUIRE_EQUAL( init_rex, get_rex_balance(alice) + rex_sell_amount ); - BOOST_REQUIRE_EQUAL( 3 * init_alice_rex_stake, 4 * get_rex_vote_stake(alice).get_amount() ); - BOOST_REQUIRE_EQUAL( get_voter_info( alice )["staked"].as(), init_stake + get_rex_vote_stake(alice).get_amount() ); - BOOST_TEST_REQUIRE( stake2votes( asset( get_voter_info( alice )["staked"].as(), symbol{CORE_SYM} ) ) - == get_producer_info(producer_names[0])["total_votes"].as() ); - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, get_rex_balance( alice ) ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_balance( alice ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), vote( alice, { producer_names[0], producer_names[4] } ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must vote for at least 21 producers or for a proxy before buying REX"), - buyrex( alice, core_sym::from_string("1.0000") ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( update_rex_vote, eosio_system_tester, * boost::unit_test::tolerance(1e-8) ) try { - - cross_15_percent_threshold(); - - // create accounts {defproducera, defproducerb, ..., defproducerz} and register as producers - std::vector producer_names; - { - producer_names.reserve('z' - 'a' + 1); - const std::string root("defproducer"); - for ( char c = 'a'; c <= 'z'; ++c ) { - producer_names.emplace_back(root + std::string(1, c)); - } - - setup_producer_accounts(producer_names); - for ( const auto& p: producer_names ) { - BOOST_REQUIRE_EQUAL( success(), regproducer(p) ); - BOOST_TEST_REQUIRE( 0 == get_producer_info(p)["total_votes"].as() ); - } - } - - const asset init_balance = core_sym::from_string("30000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; - setup_rex_accounts( accounts, init_balance ); - - const int64_t init_stake_amount = get_voter_info( alice )["staked"].as(); - const asset init_stake( init_stake_amount, symbol{CORE_SYM} ); - - const asset purchase = core_sym::from_string("25000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, purchase ) ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( get_rex_vote_stake(alice).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_pool()["total_lendable"].as() ); - - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - BOOST_REQUIRE_EQUAL( purchase, get_rex_vote_stake(alice) ); - BOOST_REQUIRE_EQUAL( purchase.get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ); - - const auto init_rex_pool = get_rex_pool(); - const asset rent = core_sym::from_string("25.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - - produce_block( fc::days(31) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - const auto curr_rex_pool = get_rex_pool(); - BOOST_TEST_REQUIRE( within_one( curr_rex_pool["total_lendable"].as().get_amount(), - init_rex_pool["total_lendable"].as().get_amount() + rent.get_amount() ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( alice, std::vector(producer_names.begin(), producer_names.begin() + 21) ) ); - BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_voter_info(alice)["staked"].as() - init_stake_amount ) ); - BOOST_TEST_REQUIRE( within_one( (purchase + rent).get_amount(), get_rex_vote_stake(alice).get_amount() ) ); - BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == - get_producer_info(producer_names[0])["total_votes"].as_double() ); - BOOST_TEST_REQUIRE ( stake2votes(purchase + rent + init_stake) == - get_producer_info(producer_names[20])["total_votes"].as_double() ); - - const asset to_net_stake = core_sym::from_string("60.0000"); - const asset to_cpu_stake = core_sym::from_string("40.0000"); - transfer( config::system_account_name, alice, to_net_stake + to_cpu_stake, config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - BOOST_REQUIRE_EQUAL( success(), stake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent, get_rex_vote_stake(alice) ); - BOOST_TEST_REQUIRE ( stake2votes(init_stake + purchase + rent + rent + to_net_stake + to_cpu_stake) == - get_producer_info(producer_names[0])["total_votes"].as_double() ); - BOOST_REQUIRE_EQUAL( success(), rentcpu( emily, bob, rent ) ); - produce_block( fc::hours(30 * 24 + 13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( alice, 1 ) ); - BOOST_REQUIRE_EQUAL( success(), unstake( alice, alice, to_net_stake, to_cpu_stake ) ); - BOOST_REQUIRE_EQUAL( purchase + rent + rent + rent, get_rex_vote_stake(alice) ); - BOOST_TEST_REQUIRE ( stake2votes(init_stake + get_rex_vote_stake(alice) ) == - get_producer_info(producer_names[0])["total_votes"].as_double() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( deposit_rex_fund, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("1000.0000"); - const asset init_net = core_sym::from_string("70.0000"); - const asset init_cpu = core_sym::from_string("90.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance, init_net, init_cpu, false ); - - BOOST_REQUIRE_EQUAL( core_sym::from_string("0.0000"), get_rex_fund( alice ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit to REX fund first"), withdraw( alice, core_sym::from_string("0.0001") ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), deposit( alice, init_balance + init_balance ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("must deposit core token"), deposit( alice, asset::from_string("1.0000 RNDM") ) ); - - asset deposit_quant( init_balance.get_amount() / 5, init_balance.get_symbol() ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, deposit_quant ) ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant + deposit_quant ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant - deposit_quant ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), withdraw( alice, get_rex_fund( alice ) + core_sym::from_string("0.0001")) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( alice, deposit_quant ) ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ), deposit_quant ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance - deposit_quant ); - BOOST_REQUIRE_EQUAL( success(), withdraw( alice, get_rex_fund( alice ) ) ); - BOOST_REQUIRE_EQUAL( get_rex_fund( alice ).get_amount(), 0 ); - BOOST_REQUIRE_EQUAL( get_balance( alice ), init_balance ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_lower_bound, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - const symbol rex_sym( SY(4, REX) ); - - const asset payment = core_sym::from_string("25000.0000"); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - const asset fee = core_sym::from_string("25.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - - const auto rex_pool = get_rex_pool(); - const int64_t tot_rex = rex_pool["total_rex"].as().get_amount(); - const int64_t tot_unlent = rex_pool["total_unlent"].as().get_amount(); - const int64_t tot_lent = rex_pool["total_lent"].as().get_amount(); - const int64_t tot_lendable = rex_pool["total_lendable"].as().get_amount(); - double rex_per_eos = double(tot_rex) / double(tot_lendable); - int64_t sell_amount = rex_per_eos * ( tot_unlent - 0.09 * tot_lent ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( success(), cancelrexorder( alice ) ); - sell_amount = rex_per_eos * ( tot_unlent - 0.1 * tot_lent ); - BOOST_REQUIRE_EQUAL( success(), sellrex( alice, asset( sell_amount, rex_sym ) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("no sellrex order is scheduled"), - cancelrexorder( alice ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( close_rex, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount), N(carolaccount), N(emilyaccount) }; - account_name alice = accounts[0], bob = accounts[1], carol = accounts[2], emily = accounts[3]; - setup_rex_accounts( accounts, init_balance ); - - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( alice ).is_null() ); - BOOST_REQUIRE_EQUAL( init_balance, get_rex_fund( alice ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( alice, init_balance ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( alice ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( alice ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), deposit( alice, init_balance ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( alice ).is_null() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_fund( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); - - BOOST_REQUIRE_EQUAL( success(), deposit( bob, init_balance ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( bob, init_balance ) ); - - const asset fee = core_sym::from_string("1.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( carol, emily, fee ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("insufficient funds"), - withdraw( carol, init_balance ) ); - BOOST_REQUIRE_EQUAL( success(), withdraw( carol, init_balance - fee ) ); - - produce_block( fc::days(20) ); - - BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( carol ).is_null() ); - - produce_block( fc::days(10) ); - - BOOST_REQUIRE_EQUAL( success(), closerex( carol ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( carol ).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( carol ).is_null() ); - - BOOST_REQUIRE_EQUAL( success(), rentnet( emily, emily, fee ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( emily ).is_null() ); - BOOST_REQUIRE_EQUAL( success(), closerex( emily ) ); - BOOST_REQUIRE_EQUAL( true, !get_rex_fund_obj( emily ).is_null() ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( bob, get_rex_balance( bob ) ) ); - BOOST_REQUIRE_EQUAL( closerex( bob ), wasm_assert_msg("account has remaining REX balance, must sell first") ); - - produce_block( fc::days(30) ); - - BOOST_REQUIRE_EQUAL( closerex( bob ), success() ); - BOOST_REQUIRE ( 0 < get_rex_fund( bob ).get_amount() ); - BOOST_REQUIRE_EQUAL( success(), withdraw( bob, get_rex_fund( bob ) ) ); - BOOST_REQUIRE_EQUAL( success(), closerex( bob ) ); - BOOST_REQUIRE_EQUAL( true, get_rex_balance_obj( bob ).is_null() ); - BOOST_REQUIRE_EQUAL( true, get_rex_fund_obj( bob ).is_null() ); - - BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_rex"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_pool()["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex loans are currently not available"), - rentcpu( emily, emily, core_sym::from_string("1.0000") ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( set_rex, eosio_system_tester ) try { - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const name act_name{ N(setrex) }; - const asset init_total_rent = core_sym::from_string("20000.0000"); - const asset set_total_rent = core_sym::from_string("10000.0000"); - const asset negative_balance = core_sym::from_string("-10000.0000"); - const asset different_symbol = asset::from_string("10000.0000 RND"); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( alice, act_name, mvo()("balance", set_total_rent) ) ); - BOOST_REQUIRE_EQUAL( error("missing authority of eosio"), - push_action( bob, act_name, mvo()("balance", set_total_rent) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("rex system is not initialized"), - push_action( config::system_account_name, act_name, mvo()("balance", set_total_rent) ) ); - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, init_balance ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("balance must be set to have a positive amount"), - push_action( config::system_account_name, act_name, mvo()("balance", negative_balance) ) ); - BOOST_REQUIRE_EQUAL( wasm_assert_msg("balance symbol must be core symbol"), - push_action( config::system_account_name, act_name, mvo()("balance", different_symbol) ) ); - const asset fee = core_sym::from_string("100.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - const auto& init_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_total_rent + fee, init_rex_pool["total_rent"].as() ); - BOOST_TEST_REQUIRE( set_total_rent != init_rex_pool["total_rent"].as() ); - BOOST_REQUIRE_EQUAL( success(), - push_action( config::system_account_name, act_name, mvo()("balance", set_total_rent) ) ); - const auto& curr_rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( init_rex_pool["total_lendable"].as(), curr_rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["total_lent"].as(), curr_rex_pool["total_lent"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["total_unlent"].as(), curr_rex_pool["total_unlent"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["namebid_proceeds"].as(), curr_rex_pool["namebid_proceeds"].as() ); - BOOST_REQUIRE_EQUAL( init_rex_pool["loan_num"].as_uint64(), curr_rex_pool["loan_num"].as_uint64() ); - BOOST_REQUIRE_EQUAL( set_total_rent, curr_rex_pool["total_rent"].as() ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( b1_vesting, eosio_system_tester ) try { - - cross_15_percent_threshold(); - - produce_block( fc::days(14) ); - - const asset init_balance = core_sym::from_string("25000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const name b1{ N(b1) }; - - issue_and_transfer( alice, core_sym::from_string("20000.0000"), config::system_account_name ); - issue_and_transfer( bob, core_sym::from_string("20000.0000"), config::system_account_name ); - BOOST_REQUIRE_EQUAL( success(), bidname( bob, b1, core_sym::from_string( "0.5000" ) ) ); - BOOST_REQUIRE_EQUAL( success(), bidname( alice, b1, core_sym::from_string( "1.0000" ) ) ); - - produce_block( fc::days(1) ); - - create_accounts_with_resources( { b1 }, alice ); - - const asset stake_amount = core_sym::from_string("50000000.0000"); - const asset half_stake = core_sym::from_string("25000000.0000"); - const asset small_amount = core_sym::from_string("1000.0000"); - issue_and_transfer( b1, stake_amount + stake_amount + stake_amount, config::system_account_name ); - - stake( b1, b1, stake_amount, stake_amount ); - - BOOST_REQUIRE_EQUAL( 2 * stake_amount.get_amount(), get_voter_info( b1 )["staked"].as() ); - - BOOST_REQUIRE_EQUAL( success(), unstake( b1, b1, small_amount, small_amount ) ); - - produce_block( fc::days(4) ); - - BOOST_REQUIRE_EQUAL( success(), push_action( b1, N(refund), mvo()("owner", b1) ) ); - - BOOST_REQUIRE_EQUAL( 2 * ( stake_amount.get_amount() - small_amount.get_amount() ), - get_voter_info( b1 )["staked"].as() ); - - produce_block( fc::days( 3 * 364 ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), - unstake( b1, b1, half_stake, half_stake ) ); - - BOOST_REQUIRE_EQUAL( success(), vote( b1, { }, N(proxyaccount) ) ); - BOOST_REQUIRE_EQUAL( success(), unstaketorex( b1, b1, half_stake, half_stake ) ); - - produce_block( fc::days(5) ); - produce_blocks(1); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), - sellrex( b1, get_rex_balance( b1 ) ) ); - - produce_block( fc::days( 2 * 364 ) ); - - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, core_sym::from_string("10000.0000") ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 sellrex orders should not be queued"), - sellrex( b1, get_rex_balance( b1 ) ) ); - - produce_block( fc::days( 30 ) ); - - BOOST_REQUIRE_EQUAL( success(), sellrex( b1, get_rex_balance( b1 ) ) ); - - produce_block( fc::days( 3 * 364 ) ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg("b1 can only claim their tokens over 10 years"), - unstake( b1, b1, half_stake - small_amount, half_stake - small_amount ) ); - - produce_block( fc::days( 1 * 364 ) ); - - BOOST_REQUIRE_EQUAL( success(), - unstake( b1, b1, half_stake - small_amount, half_stake - small_amount ) ); - - produce_block( fc::days(4) ); - BOOST_REQUIRE_EQUAL( success(), push_action( b1, N(refund), mvo()("owner", b1) ) ); - -} FC_LOG_AND_RETHROW() - - -BOOST_FIXTURE_TEST_CASE( rex_return, eosio_system_tester ) try { - - constexpr uint32_t total_intervals = 30 * 144; - constexpr uint32_t dist_interval = 10 * 60; - BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); - - const asset init_balance = core_sym::from_string("100000.0000"); - const std::vector accounts = { N(aliceaccount), N(bobbyaccount) }; - account_name alice = accounts[0], bob = accounts[1]; - setup_rex_accounts( accounts, init_balance ); - - const asset payment = core_sym::from_string("100000.0000"); - { - BOOST_REQUIRE_EQUAL( success(), buyrex( alice, payment ) ); - auto rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( payment, rex_pool["total_lendable"].as() ); - BOOST_REQUIRE_EQUAL( payment, rex_pool["total_unlent"].as() ); - - BOOST_REQUIRE_EQUAL( true, get_rex_return_pool().is_null() ); - } - - { - const asset fee = core_sym::from_string("30.0000"); - const uint32_t bucket_interval_sec = fc::hours(12).to_seconds(); - const uint32_t current_time_sec = control->pending_block_time().sec_since_epoch(); - const time_point_sec expected_pending_bucket_time{current_time_sec - current_time_sec % bucket_interval_sec + bucket_interval_sec}; - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - auto rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( false, rex_return_pool.is_null() ); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( expected_pending_bucket_time.sec_since_epoch(), - rex_return_pool["pending_bucket_time"].as().sec_since_epoch() ); - int32_t t0 = rex_return_pool["pending_bucket_time"].as().sec_since_epoch(); - - produce_block( fc::hours(13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - int64_t rate = fee.get_amount() / total_intervals; - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - - int32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - int64_t change = rate * ((t1-t0) / dist_interval) + fee.get_amount() % total_intervals; - int64_t expected = payment.get_amount() + change; - - auto rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); - - produce_blocks( 1 ); - produce_block( fc::days(25) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); - int64_t t2 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - change = rate * ((t2-t0) / dist_interval) + fee.get_amount() % total_intervals; - expected = payment.get_amount() + change; - - rex_pool = get_rex_pool(); - BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); - - produce_blocks( 1 ); - produce_block( fc::days(5) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - - rex_pool = get_rex_pool(); - expected = payment.get_amount() + fee.get_amount(); - BOOST_REQUIRE_EQUAL( expected, rex_pool["total_lendable"].as().get_amount() ); - BOOST_REQUIRE_EQUAL( rex_pool["total_lendable"].as(), - rex_pool["total_unlent"].as() ); - } - - produce_block( fc::hours(1) ); - - { - const asset init_lendable = get_rex_pool()["total_lendable"].as(); - const asset fee = core_sym::from_string("15.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - auto rex_return_pool = get_rex_return_pool(); - uint32_t t0 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - produce_block( fc::hours(1) ); - BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - uint32_t t1 = rex_return_pool["last_dist_time"].as().sec_since_epoch(); - BOOST_REQUIRE_EQUAL( t1, t0 + 6 * dist_interval ); - - produce_block( fc::hours(12) ); - BOOST_REQUIRE_EQUAL( success(), rentnet( bob, bob, fee ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 1, get_rex_return_buckets()["return_buckets"].get_array().size() ); - int64_t rate = 2 * fee.get_amount() / total_intervals; - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - produce_block( fc::hours(8) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rate, rex_return_pool["current_rate_of_increase"].as() ); - - produce_block( fc::days(30) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( fee.get_amount() / total_intervals, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_TEST_REQUIRE( (init_lendable + fee + fee).get_amount() < get_rex_pool()["total_lendable"].as().get_amount() ); - - produce_block( fc::days(1) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - rex_return_pool = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( 0, rex_return_pool["current_rate_of_increase"].as() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( init_lendable.get_amount() + 3 * fee.get_amount(), - get_rex_pool()["total_lendable"].as().get_amount() ); - } - - { - const asset fee = core_sym::from_string("25.0000"); - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - produce_block( fc::hours(13) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - auto rex_pool_0 = get_rex_pool(); - auto rex_return_pool_0 = get_rex_return_pool(); - produce_block( fc::minutes(2) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - auto rex_pool_1 = get_rex_pool(); - auto rex_return_pool_1 = get_rex_return_pool(); - BOOST_REQUIRE_EQUAL( rex_return_pool_0["last_dist_time"].as().sec_since_epoch(), - rex_return_pool_1["last_dist_time"].as().sec_since_epoch() ); - BOOST_REQUIRE_EQUAL( rex_pool_0["total_lendable"].as(), - rex_pool_1["total_lendable"].as() ); - produce_block( fc::minutes(9) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - auto rex_pool_2 = get_rex_pool(); - auto rex_return_pool_2 = get_rex_return_pool(); - BOOST_TEST_REQUIRE( rex_return_pool_1["last_dist_time"].as().sec_since_epoch() < - rex_return_pool_2["last_dist_time"].as().sec_since_epoch() ); - BOOST_TEST_REQUIRE( rex_pool_1["total_lendable"].as().get_amount() < - rex_pool_2["total_lendable"].as().get_amount() ); - produce_block( fc::days(31) ); - produce_blocks( 1 ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_pool()["current_rate_of_increase"].as() ); - } - - { - const asset fee = core_sym::from_string("30.0000"); - for ( uint8_t i = 0; i < 5; ++i ) { - BOOST_REQUIRE_EQUAL( success(), rentcpu( bob, bob, fee ) ); - produce_block( fc::days(1) ); - } - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - BOOST_REQUIRE_EQUAL( 5, get_rex_return_buckets()["return_buckets"].get_array().size() ); - produce_block( fc::days(30) ); - BOOST_REQUIRE_EQUAL( success(), rexexec( bob, 1 ) ); - BOOST_REQUIRE_EQUAL( 0, get_rex_return_buckets()["return_buckets"].get_array().size() ); - } - -} FC_LOG_AND_RETHROW() - - -BOOST_AUTO_TEST_CASE( setabi_bios ) try { - fc::temp_directory tempdir; - validating_tester t( tempdir, true ); - t.execute_setup_policy( setup_policy::full ); - - abi_serializer abi_ser(fc::json::from_string( (const char*)contracts::bios_abi().data()).template as(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); - t.set_code( config::system_account_name, contracts::bios_wasm() ); - t.set_abi( config::system_account_name, contracts::bios_abi().data() ); - t.create_account(N(eosio.token)); - t.set_abi( N(eosio.token), contracts::token_abi().data() ); - { - auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(base_tester::abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } - - t.set_abi( N(eosio.token), contracts::system_abi().data() ); - { - auto res = t.get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(base_tester::abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, t.get_resolver(), abi_serializer::create_yield_function(base_tester::abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( setabi, eosio_system_tester ) try { - set_abi( N(eosio.token), contracts::token_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::token_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } - - set_abi( N(eosio.token), contracts::system_abi().data() ); - { - auto res = get_row_by_account( config::system_account_name, config::system_account_name, N(abihash), N(eosio.token) ); - _abi_hash abi_hash; - auto abi_hash_var = abi_ser.binary_to_variant( "abi_hash", res, abi_serializer::create_yield_function(abi_serializer_max_time) ); - abi_serializer::from_variant( abi_hash_var, abi_hash, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time)); - auto abi = fc::raw::pack(fc::json::from_string( (const char*)contracts::system_abi().data()).template as()); - auto result = fc::sha256::hash( (const char*)abi.data(), abi.size() ); - - BOOST_REQUIRE( abi_hash.hash == result ); - } - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( change_limited_account_back_to_unlimited, eosio_system_tester ) try { - BOOST_REQUIRE( get_total_stake( "eosio" ).is_null() ); - - transfer( N(eosio), N(alice1111111), core_sym::from_string("1.0000") ); - - auto error_msg = stake( N(alice1111111), N(eosio), core_sym::from_string("0.0000"), core_sym::from_string("1.0000") ); - auto semicolon_pos = error_msg.find(';'); - - BOOST_REQUIRE_EQUAL( error("account eosio has insufficient ram"), - error_msg.substr(0, semicolon_pos) ); - - int64_t ram_bytes_needed = 0; - { - std::istringstream s( error_msg ); - s.seekg( semicolon_pos + 7, std::ios_base::beg ); - s >> ram_bytes_needed; - ram_bytes_needed += 256; // enough room to cover total_resources_table - } - - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ); - - stake( N(alice1111111), N(eosio), core_sym::from_string("0.0000"), core_sym::from_string("1.0000") ); - - REQUIRE_MATCHING_OBJECT( get_total_stake( "eosio" ), mvo() - ("owner", "eosio") - ("net_weight", core_sym::from_string("0.0000")) - ("cpu_weight", core_sym::from_string("1.0000")) - ("ram_bytes", 0) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "only supports unlimited accounts" ), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( error( "transaction net usage is too high: 128 > 0" ), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio.saving") - ("ram_bytes", -1) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setacctnet), mvo() - ("account", "eosio") - ("net_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setacctcpu), mvo() - ("account", "eosio") - ("cpu_weight", -1) - - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio.saving") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( buy_pin_sell_ram, eosio_system_tester ) try { - BOOST_REQUIRE( get_total_stake( "eosio" ).is_null() ); - - transfer( N(eosio), N(alice1111111), core_sym::from_string("1020.0000") ); - - auto error_msg = stake( N(alice1111111), N(eosio), core_sym::from_string("10.0000"), core_sym::from_string("10.0000") ); - auto semicolon_pos = error_msg.find(';'); - - BOOST_REQUIRE_EQUAL( error("account eosio has insufficient ram"), - error_msg.substr(0, semicolon_pos) ); - - int64_t ram_bytes_needed = 0; - { - std::istringstream s( error_msg ); - s.seekg( semicolon_pos + 7, std::ios_base::beg ); - s >> ram_bytes_needed; - ram_bytes_needed += ram_bytes_needed/10; // enough buffer to make up for buyrambytes estimation errors - } - - auto alice_original_balance = get_balance( N(alice1111111) ); - - BOOST_REQUIRE_EQUAL( success(), buyrambytes( N(alice1111111), N(eosio), static_cast(ram_bytes_needed) ) ); - - auto tokens_paid_for_ram = alice_original_balance - get_balance( N(alice1111111) ); - - auto total_res = get_total_stake( "eosio" ); - - REQUIRE_MATCHING_OBJECT( total_res, mvo() - ("owner", "eosio") - ("net_weight", core_sym::from_string("0.0000")) - ("cpu_weight", core_sym::from_string("0.0000")) - ("ram_bytes", total_res["ram_bytes"].as_int64() ) - ); - - BOOST_REQUIRE_EQUAL( wasm_assert_msg( "only supports unlimited accounts" ), - push_action( N(eosio), N(setalimits), mvo() - ("account", "eosio") - ("ram_bytes", ram_bytes_needed) - ("net_weight", -1) - ("cpu_weight", -1) - ) - ); - - BOOST_REQUIRE_EQUAL( success(), - push_action( N(eosio), N(setacctram), mvo() - ("account", "eosio") - ("ram_bytes", total_res["ram_bytes"].as_int64() ) - ) - ); - - auto eosio_original_balance = get_balance( N(eosio) ); - - BOOST_REQUIRE_EQUAL( success(), sellram( N(eosio), total_res["ram_bytes"].as_int64() ) ); - - auto tokens_received_by_selling_ram = get_balance( N(eosio) ) - eosio_original_balance; - - BOOST_REQUIRE( double(tokens_paid_for_ram.get_amount() - tokens_received_by_selling_ram.get_amount()) / tokens_paid_for_ram.get_amount() < 0.01 ); - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/eosio.token_tests.cpp b/tests/eosio.token_tests.cpp index 23de001a..e6e86135 100644 --- a/tests/eosio.token_tests.cpp +++ b/tests/eosio.token_tests.cpp @@ -1,10 +1,10 @@ #include #include #include -#include "eosio.system_tester.hpp" +// #include "eosio.system_tester.hpp" +#include "contracts.hpp" #include "Runtime/Runtime.h" - #include using namespace eosio::testing; @@ -22,15 +22,15 @@ class eosio_token_tester : public tester { eosio_token_tester() { produce_blocks( 2 ); - create_accounts( { N(alice), N(bob), N(carol), N(eosio.token) } ); + create_accounts( { "alice"_n, "bob"_n, "carol"_n, "eosio.token"_n } ); produce_blocks( 2 ); - set_code( N(eosio.token), contracts::token_wasm() ); - set_abi( N(eosio.token), contracts::token_abi().data() ); + set_code( "eosio.token"_n, contracts::token_wasm() ); + set_abi( "eosio.token"_n, contracts::token_abi().data() ); produce_blocks(); - const auto& accnt = control->db().get( N(eosio.token) ); + const auto& accnt = control->db().get( "eosio.token"_n ); abi_def abi; BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); @@ -40,7 +40,7 @@ class eosio_token_tester : public tester { string action_type_name = abi_ser.get_action_type(name); action act; - act.account = N(eosio.token); + act.account = "eosio.token"_n; act.name = name; act.data = abi_ser.variant_to_binary( action_type_name, data, abi_serializer::create_yield_function(abi_serializer_max_time) ); @@ -51,7 +51,7 @@ class eosio_token_tester : public tester { { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), name(symbol_code), N(stat), account_name(symbol_code) ); + vector data = get_row_by_account( "eosio.token"_n, name(symbol_code), "stat"_n, account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "currency_stats", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } @@ -59,21 +59,21 @@ class eosio_token_tester : public tester { { auto symb = eosio::chain::symbol::from_string(symbolname); auto symbol_code = symb.to_symbol_code().value; - vector data = get_row_by_account( N(eosio.token), acc, N(accounts), account_name(symbol_code) ); + vector data = get_row_by_account( "eosio.token"_n, acc, "accounts"_n, account_name(symbol_code) ); return data.empty() ? fc::variant() : abi_ser.binary_to_variant( "account", data, abi_serializer::create_yield_function(abi_serializer_max_time) ); } action_result create( account_name issuer, asset maximum_supply ) { - return push_action( N(eosio.token), N(create), mvo() + return push_action( "eosio.token"_n, "create"_n, mvo() ( "issuer", issuer) ( "maximum_supply", maximum_supply) ); } action_result issue( account_name issuer, asset quantity, string memo ) { - return push_action( issuer, N(issue), mvo() + return push_action( issuer, "issue"_n, mvo() ( "to", issuer) ( "quantity", quantity) ( "memo", memo) @@ -81,7 +81,7 @@ class eosio_token_tester : public tester { } action_result retire( account_name issuer, asset quantity, string memo ) { - return push_action( issuer, N(retire), mvo() + return push_action( issuer, "retire"_n, mvo() ( "quantity", quantity) ( "memo", memo) ); @@ -92,7 +92,7 @@ class eosio_token_tester : public tester { account_name to, asset quantity, string memo ) { - return push_action( from, N(transfer), mvo() + return push_action( from, "transfer"_n, mvo() ( "from", from) ( "to", to) ( "quantity", quantity) @@ -103,7 +103,7 @@ class eosio_token_tester : public tester { action_result open( account_name owner, const string& symbolname, account_name ram_payer ) { - return push_action( ram_payer, N(open), mvo() + return push_action( ram_payer, "open"_n, mvo() ( "owner", owner ) ( "symbol", symbolname ) ( "ram_payer", ram_payer ) @@ -112,7 +112,7 @@ class eosio_token_tester : public tester { action_result close( account_name owner, const string& symbolname ) { - return push_action( owner, N(close), mvo() + return push_action( owner, "close"_n, mvo() ( "owner", owner ) ( "symbol", "0,CERO" ) ); @@ -125,7 +125,7 @@ BOOST_AUTO_TEST_SUITE(eosio_token_tests) BOOST_FIXTURE_TEST_CASE( create_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000.000 TKN")); + auto token = create( "alice"_n, asset::from_string("1000.000 TKN")); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0.000 TKN") @@ -139,14 +139,14 @@ BOOST_FIXTURE_TEST_CASE( create_tests, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( create_negative_max_supply, eosio_token_tester ) try { BOOST_REQUIRE_EQUAL( wasm_assert_msg( "max-supply must be positive" ), - create( N(alice), asset::from_string("-1000.000 TKN")) + create( "alice"_n, asset::from_string("-1000.000 TKN")) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( symbol_already_exists, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("100 TKN")); + auto token = create( "alice"_n, asset::from_string("100 TKN")); auto stats = get_stats("0,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0 TKN") @@ -156,14 +156,14 @@ BOOST_FIXTURE_TEST_CASE( symbol_already_exists, eosio_token_tester ) try { produce_blocks(1); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "token with symbol already exists" ), - create( N(alice), asset::from_string("100 TKN")) + create( "alice"_n, asset::from_string("100 TKN")) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("4611686018427387903 TKN")); + auto token = create( "alice"_n, asset::from_string("4611686018427387903 TKN")); auto stats = get_stats("0,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0 TKN") @@ -178,7 +178,7 @@ BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try { static_assert(std::is_trivially_copyable::value, "asset is not trivially copyable"); memcpy(&max, &amount, sizeof(share_type)); // hack in an invalid amount - BOOST_CHECK_EXCEPTION( create( N(alice), max) , asset_type_exception, [](const asset_type_exception& e) { + BOOST_CHECK_EXCEPTION( create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) { return expect_assert_message(e, "magnitude of asset amount must be less than 2^62"); }); @@ -187,7 +187,7 @@ BOOST_FIXTURE_TEST_CASE( create_max_supply, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1.000000000000000000 TKN")); + auto token = create( "alice"_n, asset::from_string("1.000000000000000000 TKN")); auto stats = get_stats("18,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0.000000000000000000 TKN") @@ -203,7 +203,7 @@ BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try { static_assert(std::is_trivially_copyable::value, "asset is not trivially copyable"); memcpy(&max, &amount, sizeof(share_type)); // hack in an invalid amount - BOOST_CHECK_EXCEPTION( create( N(alice), max) , asset_type_exception, [](const asset_type_exception& e) { + BOOST_CHECK_EXCEPTION( create( "alice"_n, max) , asset_type_exception, [](const asset_type_exception& e) { return expect_assert_message(e, "magnitude of asset amount must be less than 2^62"); }); @@ -211,10 +211,10 @@ BOOST_FIXTURE_TEST_CASE( create_max_decimals, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000.000 TKN")); + auto token = create( "alice"_n, asset::from_string("1000.000 TKN")); produce_blocks(1); - issue( N(alice), asset::from_string("500.000 TKN"), "hola" ); + issue( "alice"_n, asset::from_string("500.000 TKN"), "hola" ); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -223,21 +223,21 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { ("issuer", "alice") ); - auto alice_balance = get_account(N(alice), "3,TKN"); + auto alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "500.000 TKN") ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "quantity exceeds available supply" ), - issue( N(alice), asset::from_string("500.001 TKN"), "hola" ) + issue( "alice"_n, asset::from_string("500.001 TKN"), "hola" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must issue positive quantity" ), - issue( N(alice), asset::from_string("-1.000 TKN"), "hola" ) + issue( "alice"_n, asset::from_string("-1.000 TKN"), "hola" ) ); BOOST_REQUIRE_EQUAL( success(), - issue( N(alice), asset::from_string("1.000 TKN"), "hola" ) + issue( "alice"_n, asset::from_string("1.000 TKN"), "hola" ) ); @@ -245,10 +245,10 @@ BOOST_FIXTURE_TEST_CASE( issue_tests, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( retire_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000.000 TKN")); + auto token = create( "alice"_n, asset::from_string("1000.000 TKN")); produce_blocks(1); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("500.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( "alice"_n, asset::from_string("500.000 TKN"), "hola" ) ); auto stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -257,55 +257,55 @@ BOOST_FIXTURE_TEST_CASE( retire_tests, eosio_token_tester ) try { ("issuer", "alice") ); - auto alice_balance = get_account(N(alice), "3,TKN"); + auto alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "500.000 TKN") ); - BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("200.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), retire( "alice"_n, asset::from_string("200.000 TKN"), "hola" ) ); stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "300.000 TKN") ("max_supply", "1000.000 TKN") ("issuer", "alice") ); - alice_balance = get_account(N(alice), "3,TKN"); + alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "300.000 TKN") ); //should fail to retire more than current supply - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("500.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( "alice"_n, asset::from_string("500.000 TKN"), "hola" ) ); - BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("200.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "alice"_n, "bob"_n, asset::from_string("200.000 TKN"), "hola" ) ); //should fail to retire since tokens are not on the issuer's balance - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( "alice"_n, asset::from_string("300.000 TKN"), "hola" ) ); //transfer tokens back - BOOST_REQUIRE_EQUAL( success(), transfer( N(bob), N(alice), asset::from_string("200.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "bob"_n, "alice"_n, asset::from_string("200.000 TKN"), "hola" ) ); - BOOST_REQUIRE_EQUAL( success(), retire( N(alice), asset::from_string("300.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), retire( "alice"_n, asset::from_string("300.000 TKN"), "hola" ) ); stats = get_stats("3,TKN"); REQUIRE_MATCHING_OBJECT( stats, mvo() ("supply", "0.000 TKN") ("max_supply", "1000.000 TKN") ("issuer", "alice") ); - alice_balance = get_account(N(alice), "3,TKN"); + alice_balance = get_account("alice"_n, "3,TKN"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "0.000 TKN") ); //trying to retire tokens with zero supply - BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( N(alice), asset::from_string("1.000 TKN"), "hola" ) ); + BOOST_REQUIRE_EQUAL( wasm_assert_msg("overdrawn balance"), retire( "alice"_n, asset::from_string("1.000 TKN"), "hola" ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000 CERO")); + auto token = create( "alice"_n, asset::from_string("1000 CERO")); produce_blocks(1); - issue( N(alice), asset::from_string("1000 CERO"), "hola" ); + issue( "alice"_n, asset::from_string("1000 CERO"), "hola" ); auto stats = get_stats("0,CERO"); REQUIRE_MATCHING_OBJECT( stats, mvo() @@ -314,21 +314,21 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { ("issuer", "alice") ); - auto alice_balance = get_account(N(alice), "0,CERO"); + auto alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "1000 CERO") ); - transfer( N(alice), N(bob), asset::from_string("300 CERO"), "hola" ); + transfer( "alice"_n, "bob"_n, asset::from_string("300 CERO"), "hola" ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "700 CERO") ("frozen", 0) ("whitelist", 1) ); - auto bob_balance = get_account(N(bob), "0,CERO"); + auto bob_balance = get_account("bob"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( bob_balance, mvo() ("balance", "300 CERO") ("frozen", 0) @@ -336,11 +336,11 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "overdrawn balance" ), - transfer( N(alice), N(bob), asset::from_string("701 CERO"), "hola" ) + transfer( "alice"_n, "bob"_n, asset::from_string("701 CERO"), "hola" ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "must transfer positive quantity" ), - transfer( N(alice), N(bob), asset::from_string("-1000 CERO"), "hola" ) + transfer( "alice"_n, "bob"_n, asset::from_string("-1000 CERO"), "hola" ) ); @@ -348,75 +348,75 @@ BOOST_FIXTURE_TEST_CASE( transfer_tests, eosio_token_tester ) try { BOOST_FIXTURE_TEST_CASE( open_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000 CERO")); + auto token = create( "alice"_n, asset::from_string("1000 CERO")); - auto alice_balance = get_account(N(alice), "0,CERO"); + auto alice_balance = get_account("alice"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("tokens can only be issued to issuer account"), - push_action( N(alice), N(issue), mvo() + push_action( "alice"_n, "issue"_n, mvo() ( "to", "bob") ( "quantity", asset::from_string("1000 CERO") ) ( "memo", "") ) ); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("1000 CERO"), "issue" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( "alice"_n, asset::from_string("1000 CERO"), "issue" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "1000 CERO") ); - auto bob_balance = get_account(N(bob), "0,CERO"); + auto bob_balance = get_account("bob"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, bob_balance.is_null() ); BOOST_REQUIRE_EQUAL( wasm_assert_msg("owner account does not exist"), - open( N(nonexistent), "0,CERO", N(alice) ) ); + open( "nonexistent"_n, "0,CERO", "alice"_n ) ); BOOST_REQUIRE_EQUAL( success(), - open( N(bob), "0,CERO", N(alice) ) ); + open( "bob"_n, "0,CERO", "alice"_n ) ); - bob_balance = get_account(N(bob), "0,CERO"); + bob_balance = get_account("bob"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( bob_balance, mvo() ("balance", "0 CERO") ); - BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("200 CERO"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "alice"_n, "bob"_n, asset::from_string("200 CERO"), "hola" ) ); - bob_balance = get_account(N(bob), "0,CERO"); + bob_balance = get_account("bob"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( bob_balance, mvo() ("balance", "200 CERO") ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "symbol does not exist" ), - open( N(carol), "0,INVALID", N(alice) ) ); + open( "carol"_n, "0,INVALID", "alice"_n ) ); BOOST_REQUIRE_EQUAL( wasm_assert_msg( "symbol precision mismatch" ), - open( N(carol), "1,CERO", N(alice) ) ); + open( "carol"_n, "1,CERO", "alice"_n ) ); } FC_LOG_AND_RETHROW() BOOST_FIXTURE_TEST_CASE( close_tests, eosio_token_tester ) try { - auto token = create( N(alice), asset::from_string("1000 CERO")); + auto token = create( "alice"_n, asset::from_string("1000 CERO")); - auto alice_balance = get_account(N(alice), "0,CERO"); + auto alice_balance = get_account("alice"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); - BOOST_REQUIRE_EQUAL( success(), issue( N(alice), asset::from_string("1000 CERO"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), issue( "alice"_n, asset::from_string("1000 CERO"), "hola" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "1000 CERO") ); - BOOST_REQUIRE_EQUAL( success(), transfer( N(alice), N(bob), asset::from_string("1000 CERO"), "hola" ) ); + BOOST_REQUIRE_EQUAL( success(), transfer( "alice"_n, "bob"_n, asset::from_string("1000 CERO"), "hola" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + alice_balance = get_account("alice"_n, "0,CERO"); REQUIRE_MATCHING_OBJECT( alice_balance, mvo() ("balance", "0 CERO") ); - BOOST_REQUIRE_EQUAL( success(), close( N(alice), "0,CERO" ) ); - alice_balance = get_account(N(alice), "0,CERO"); + BOOST_REQUIRE_EQUAL( success(), close( "alice"_n, "0,CERO" ) ); + alice_balance = get_account("alice"_n, "0,CERO"); BOOST_REQUIRE_EQUAL(true, alice_balance.is_null() ); } FC_LOG_AND_RETHROW() -BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() \ No newline at end of file diff --git a/tests/eosio.wrap_tests.cpp b/tests/eosio.wrap_tests.cpp deleted file mode 100644 index 1f462bb8..00000000 --- a/tests/eosio.wrap_tests.cpp +++ /dev/null @@ -1,368 +0,0 @@ -#include -#include -#include - -#include - -#include - -#include "contracts.hpp" - -using namespace eosio::testing; -using namespace eosio; -using namespace eosio::chain; -using namespace eosio::testing; -using namespace fc; - -using mvo = fc::mutable_variant_object; - -class eosio_wrap_tester : public tester { -public: - - eosio_wrap_tester() { - create_accounts( { N(eosio.msig), N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(alice), N(bob), N(carol) } ); - produce_block(); - - - base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.msig") - ("is_priv", 1) - ); - - set_code( N(eosio.msig), contracts::msig_wasm() ); - set_abi( N(eosio.msig), contracts::msig_abi().data() ); - - produce_blocks(); - - signed_transaction trx; - set_transaction_headers(trx); - authority auth( 1, {}, {{{config::system_account_name, config::active_name}, 1}} ); - trx.actions.emplace_back( vector{{config::system_account_name, config::active_name}}, - newaccount{ - .creator = config::system_account_name, - .name = N(eosio.wrap), - .owner = auth, - .active = auth, - }); - - set_transaction_headers(trx); - trx.sign( get_private_key( config::system_account_name, "active" ), control->get_chain_id() ); - push_transaction( trx ); - - base_tester::push_action(config::system_account_name, N(setpriv), - config::system_account_name, mutable_variant_object() - ("account", "eosio.wrap") - ("is_priv", 1) - ); - - auto system_private_key = get_private_key( config::system_account_name, "active" ); - set_code( N(eosio.wrap), contracts::wrap_wasm(), &system_private_key ); - set_abi( N(eosio.wrap), contracts::wrap_abi().data(), &system_private_key ); - - produce_blocks(); - - set_authority( config::system_account_name, config::active_name, - authority( 1, {{get_public_key( config::system_account_name, "active" ), 1}}, - {{{config::producers_account_name, config::active_name}, 1}} ), - config::owner_name, - { { config::system_account_name, config::owner_name } }, - { get_private_key( config::system_account_name, "active" ) } - ); - - set_producers( {N(prod1), N(prod2), N(prod3), N(prod4), N(prod5)} ); - - produce_blocks(); - - const auto& accnt = control->db().get( N(eosio.wrap) ); - abi_def abi; - BOOST_REQUIRE_EQUAL(abi_serializer::to_abi(accnt.abi, abi), true); - abi_ser.set_abi(abi, abi_serializer::create_yield_function(abi_serializer_max_time)); - - while( control->pending_block_producer().to_string() == "eosio" ) { - produce_block(); - } - } - - void propose( name proposer, name proposal_name, vector requested_permissions, const transaction& trx ) { - push_action( N(eosio.msig), N(propose), proposer, mvo() - ("proposer", proposer) - ("proposal_name", proposal_name) - ("requested", requested_permissions) - ("trx", trx) - ); - } - - void approve( name proposer, name proposal_name, name approver ) { - push_action( N(eosio.msig), N(approve), approver, mvo() - ("proposer", proposer) - ("proposal_name", proposal_name) - ("level", permission_level{approver, config::active_name} ) - ); - } - - void unapprove( name proposer, name proposal_name, name unapprover ) { - push_action( N(eosio.msig), N(unapprove), unapprover, mvo() - ("proposer", proposer) - ("proposal_name", proposal_name) - ("level", permission_level{unapprover, config::active_name}) - ); - } - - transaction wrap_exec( account_name executer, const transaction& trx, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); - - transaction reqauth( account_name from, const vector& auths, uint32_t expiration = base_tester::DEFAULT_EXPIRATION_DELTA ); - - abi_serializer abi_ser; -}; - -transaction eosio_wrap_tester::wrap_exec( account_name executer, const transaction& trx, uint32_t expiration ) { - fc::variants v; - v.push_back( fc::mutable_variant_object() - ("actor", executer) - ("permission", name{config::active_name}) - ); - v.push_back( fc::mutable_variant_object() - ("actor", "eosio.wrap") - ("permission", name{config::active_name}) - ); - auto act_obj = fc::mutable_variant_object() - ("account", "eosio.wrap") - ("name", "exec") - ("authorization", v) - ("data", fc::mutable_variant_object()("executer", executer)("trx", trx) ); - transaction trx2; - set_transaction_headers(trx2, expiration); - action act; - abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time) ); - trx2.actions.push_back( std::move(act) ); - return trx2; -} - -transaction eosio_wrap_tester::reqauth( account_name from, const vector& auths, uint32_t expiration ) { - fc::variants v; - for ( auto& level : auths ) { - v.push_back(fc::mutable_variant_object() - ("actor", level.actor) - ("permission", level.permission) - ); - } - auto act_obj = fc::mutable_variant_object() - ("account", name{config::system_account_name}) - ("name", "reqauth") - ("authorization", v) - ("data", fc::mutable_variant_object() ("from", from) ); - transaction trx; - set_transaction_headers(trx, expiration); - action act; - abi_serializer::from_variant( act_obj, act, get_resolver(), abi_serializer::create_yield_function(abi_serializer_max_time) ); - trx.actions.push_back( std::move(act) ); - return trx; -} - -BOOST_AUTO_TEST_SUITE(eosio_wrap_tests) - -BOOST_FIXTURE_TEST_CASE( wrap_exec_direct, eosio_wrap_tester ) try { - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - - transaction_trace_ptr trace; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { trace = t; } - } ); - - { - signed_transaction wrap_trx( wrap_exec( N(alice), trx ), {}, {} ); - /* - set_transaction_headers( wrap_trx ); - wrap_trx.actions.emplace_back( get_action( N(eosio.wrap), N(exec), - {{N(alice), config::active_name}, {N(eosio.wrap), config::active_name}}, - mvo() - ("executer", "alice") - ("trx", trx) - ) ); - */ - wrap_trx.sign( get_private_key( N(alice), "active" ), control->get_chain_id() ); - for( const auto& actor : {N(prod1), N(prod2), N(prod3), N(prod4)} ) { - wrap_trx.sign( get_private_key( actor, "active" ), control->get_chain_id() ); - } - push_transaction( wrap_trx ); - } - - produce_block(); - - BOOST_REQUIRE( bool(trace) ); - BOOST_REQUIRE_EQUAL( 1, trace->action_traces.size() ); - BOOST_REQUIRE_EQUAL( config::system_account_name, name{trace->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(reqauth), name{trace->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, trace->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( wrap_with_msig, eosio_wrap_tester ) try { - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto wrap_trx = wrap_exec( N(alice), trx ); - - propose( N(carol), N(first), - { {N(alice), N(active)}, - {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - wrap_trx ); - - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action - - // More than 2/3 of block producers approve - approve( N(carol), N(first), N(prod1) ); - approve( N(carol), N(first), N(prod2) ); - approve( N(carol), N(first), N(prod3) ); - approve( N(carol), N(first), N(prod4) ); - - vector traces; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { - traces.push_back( t ); - } - } ); - - // Now the proposal should be ready to execute - push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ); - - produce_block(); - - BOOST_REQUIRE_EQUAL( 2, traces.size() ); - - BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); - - BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( wrap_with_msig_unapprove, eosio_wrap_tester ) try { - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto wrap_trx = wrap_exec( N(alice), trx ); - - propose( N(carol), N(first), - { {N(alice), N(active)}, - {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - wrap_trx ); - - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action - - // 3 of the 4 needed producers approve - approve( N(carol), N(first), N(prod1) ); - approve( N(carol), N(first), N(prod2) ); - approve( N(carol), N(first), N(prod3) ); - - // first producer takes back approval - unapprove( N(carol), N(first), N(prod1) ); - - // fourth producer approves but the total number of approving producers is still 3 which is less than two-thirds of producers - approve( N(carol), N(first), N(prod4) ); - - produce_block(); - - // The proposal should not have sufficient approvals to pass the authorization checks of eosio.wrap::exec. - BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ), eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - -} FC_LOG_AND_RETHROW() - -BOOST_FIXTURE_TEST_CASE( wrap_with_msig_producers_change, eosio_wrap_tester ) try { - create_accounts( { N(newprod1) } ); - - auto trx = reqauth( N(bob), {permission_level{N(bob), config::active_name}} ); - auto wrap_trx = wrap_exec( N(alice), trx, 36000 ); - - propose( N(carol), N(first), - { {N(alice), N(active)}, - {N(prod1), N(active)}, {N(prod2), N(active)}, {N(prod3), N(active)}, {N(prod4), N(active)}, {N(prod5), N(active)} }, - wrap_trx ); - - approve( N(carol), N(first), N(alice) ); // alice must approve since she is the executer of the wrap::exec action - - // 2 of the 4 needed producers approve - approve( N(carol), N(first), N(prod1) ); - approve( N(carol), N(first), N(prod2) ); - - produce_block(); - - set_producers( {N(prod1), N(prod2), N(prod3), N(prod4), N(prod5), N(newprod1)} ); // With 6 producers, the 2/3+1 threshold becomes 5 - - while( control->active_producers().producers.size() != 6 ) { - produce_block(); - } - - // Now two more block producers approve which would have been sufficient under the old schedule but not the new one. - approve( N(carol), N(first), N(prod3) ); - approve( N(carol), N(first), N(prod4) ); - - produce_block(); - - // The proposal has four of the five requested approvals but they are not sufficient to satisfy the authorization checks of eosio.wrap::exec. - BOOST_REQUIRE_EXCEPTION( push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ), eosio_assert_message_exception, - eosio_assert_message_is("transaction authorization failed") - ); - - // Unfortunately the new producer cannot approve because they were not in the original requested approvals. - BOOST_REQUIRE_EXCEPTION( approve( N(carol), N(first), N(newprod1) ), - eosio_assert_message_exception, - eosio_assert_message_is("approval is not on the list of requested approvals") - ); - - // But prod5 still can provide the fifth approval necessary to satisfy the 2/3+1 threshold of the new producer set - approve( N(carol), N(first), N(prod5) ); - - vector traces; - control->applied_transaction.connect( - [&]( std::tuple p ) { - const auto& t = std::get<0>(p); - if( t->scheduled ) { - traces.push_back( t ); - } - } ); - - // Now the proposal should be ready to execute - push_action( N(eosio.msig), N(exec), N(alice), mvo() - ("proposer", "carol") - ("proposal_name", "first") - ("executer", "alice") - ); - - produce_block(); - - BOOST_REQUIRE_EQUAL( 2, traces.size() ); - - BOOST_REQUIRE_EQUAL( 1, traces[0]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( N(eosio.wrap), name{traces[0]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(exec), name{traces[0]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[0]->receipt->status ); - - BOOST_REQUIRE_EQUAL( 1, traces[1]->action_traces.size() ); - BOOST_REQUIRE_EQUAL( config::system_account_name, name{traces[1]->action_traces[0].act.account} ); - BOOST_REQUIRE_EQUAL( N(reqauth), name{traces[1]->action_traces[0].act.name} ); - BOOST_REQUIRE_EQUAL( transaction_receipt::executed, traces[1]->receipt->status ); - -} FC_LOG_AND_RETHROW() - -BOOST_AUTO_TEST_SUITE_END() diff --git a/tests/main.cpp b/tests/main.cpp index e3d61750..f1f23ace 100644 --- a/tests/main.cpp +++ b/tests/main.cpp @@ -10,9 +10,7 @@ #include #include -#include "eosio.system_tester.hpp" - -using namespace eosio_system; +// using namespace eosio_system; #define BOOST_TEST_STATIC_LINK void translate_fc_exception(const fc::exception &e) { diff --git a/tests/test_contracts/exchange.wasm b/tests/test_contracts/exchange.wasm deleted file mode 100644 index 8880a905c9e52813621b3745938a95c588d0d0c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 72187 zcmeFa3z%KkQRllK=hf$&?%uMVu?*Sg5TKRV(2`|IHX+vTNPgzwXJRr8k}S0&wPZUp1_bxzALicBzRU^^)GYLh1xxH56B?A4{I< zzNu>r+vlaTd2^&k$Bu=^=p}!mW5>f|(H~XPczpkn>W+sGOil$AJtsSMPVG6cf7`Ad zQ#-aD+Vg|s!7@wUd3bVieE-z8$?=`zdyb4x22~}u^W>>LkB+;f)~<)QJ+f#2u5EiZ ztPdK>)FkEI<5QL}poHZl?Adj6!+MwT;N+f1cT7GW4C>p`;@iFh?-`$b_`u=)yMkeT z87#i+A3r)33@L56NShpg^uUqvpsm!QBK6SJfywdUn*OYZ4>Gv%AXMrSvX%{%eby+{ zjHOspYTh+sY1UAiG;6|=TB=alTmzQYR9budz@a?{w(U4{XdE!tmDF@e<45;Qxjr{` z?>Mw=$Kk2n!BTy%Jv#pA&V!E!2Cq60+CR1Hkzk2^vbQ}!Qoii(eL3VSv}}jA?Q;#f zIu83{$>jKsUE6x5+JUn@IsVw;J(J_EBi6uRZ_>J;rbd_KX&}R%gL^;=*M95JxaNKT zzCHWLY4ue2W8u)y(6aXO<;#awG*=GQm#jze>7+TS;RI1^@uvV+aVG!1TYS|kE zw=iWnyA6<9ThWpoU3(|QX)@~TphYlb1kN1}FAG-1W z1MdmGZFJka-gcAC@!EAcv^2Y0@4NeL_itOf;o$h>qk9g475lgC8$U9>Z)@m!o~9=*zXzvJ#j>)q(9U9dyy>G0wg4OPl*QuXAm#b+Fnt_4vVYP5rjD z^Lx8B*m%n#)vR6H3%rGA;ns^iu;}YVe`#xd&Mfudp?zNa=;3`+d*B7T#*g0lmdDqQ zuD^NXP3t$@yza)EHr#mA`b`@)t~30&$#?4@98&Af*1OcVQ7Z=)Km0g_*Kb^R^M;#l zylLZ&H?6(-<{NKZzkYP<+irUJz=1~r(5^+<5X`bB`dejhZq^>Ihq^GNW{ z{fiV^yU8P$if=mvmW&^w76G7lSO&he8*bdR{-&Ep*Kb_EZX*ELu-?FTlVb4S3-DW>GS6Oo@_Bt+~@@ahx>~G^ZpyR1^0b$QFz|yk*BESe|CW0fBUxJ{%>6b zrt1&wI5G~6K2R>an{sZxao4y}$imD!c<0)p&Z5Ys_w1S4y=!vEdlo6P?c3&;SqJwL zU5#$L31+`*d~2}%J1&=N)8T`D?t;nJUoImnh-fd*eCSQ{GjH69KsPmh)Vh0F4B?f0nvn4tBIr2}Aj|U$Q2L{6+3tF{Lgi}Yi zJ^s$-zx|u|$HI1y25Fe3$+O|sR^Q7|`6UZ(Z#5B#$7WA_@AR`ReOVLRpGNX6t)Gs< z_{lU(!!>c^Q(I6~`FHWwG$u>8_Nla%Mm!z+)HB7WnKT-SRz2t5H-BjJGs!dI(`P<> zu3NP_j%|z^X_S}SNJC+^YJxgC6`m4%s?qDJJ_Tt_*{frh{J&d|6_1yK2eKqtlGer= zCp)z)=!DVcXmh+dtv#Eqn#xq*y%X7&E?xSA@a{prS;lT{>{9stvEaVJKshN|ro^-# zPISYpe#cP=}!qy?R*l}6e5fQEy#vN29tza7QllW3<;3MNTDntQX0%0p5k zAJ)CusgNYWt5b6TtbfX2lGdN-1z-U>2T1|21Mu>!4uGmAWdf=>;Gds4bFN!|LSW-t z0yz0;&{B}rdtg~F0Js<|>l&qpWqlD?)&)7LDq-255(6Y)8I`aMds93t!xpgVh2;;o zs#U@Ac=%*=JOiIcqDpo?+}j=65D7g_hlU>l=_&VE=W&xqnlKx+r>X-$TVv?|&p^^G z5DhFy+f-oqrx(NOc3Qn}FmzK_)6-Bk6Hb7dj3All4g&bDVW&%PD7`V!Z7Lm%Fz^SR zHpND*l+VixSuMj*+TIw?P_ceT$@pA2q4~{5CahHQ9qFJ;bp)YGn?9kTAzCZx(3<$U zkjHkTl~!D*+o|R;@YV8crd^^=Zp;ibqt@cp< zz+7U^>96i%cy@`|6w8$`wp)t#=}g5%*7R)fjQJl{Ovo5cxU6irlgxI@QX7 zX-SYgCrCzO-d9ovw4smU1dgsn1_cfo2N0zz#ZkH_Bv6A&b}t@{+A4)_NFmw6|O5n*qqP-EMU(ydPN9 zvzLMi;P6tIEV~v)a6XuL1M6Iz!k|G}F~-e2$FLHXDOlnrr6(-0ugof{%v_*GsiL|7 zyU^lZ6}zCSazW}(iRl}Z5|r$Mg|STW3lij3b2wE`qmA($3=E}-9ic}%*2tcBaH*ScQxu;DVqJ)gf zy(S*j{E=ZzJYr7*Gam(d^(n0<--*~lmNoG`bl4WgcMgU^{Xnx@&(24h-85*uE)0*8 zSFjWQj!YyYhSGr;WHQpx+T1!>k1MRjm0~Tv5bW)?RRPN;!cWQq-2i=q%*K|D?&~%u zI->FBR%&ZzqmOo)X{$59%nk4w9_d!eG|{cGHg@Zz)qrRkKG3bLX4R>uz<+f|gnfJ> zt?o^$ymp(C#;6ijcpH^gco34O;XBCcKisaqYjPTCTT`aqv9@c<#*Vv3K-F!I83nYn z7ojbiG}x+e(S|chfe|4wz;4sQIztyx!r&}~c$5gl}Mo|@us-;z-P}B0YN1_oR(iX9V zHrniU%8xkR0^#&j7g(zFqC@j(eQ&3xUh&1CbT1N26a2Mq4lo@6eInbf#sMT_?KCws z8(uXn>QcpYd0E=LExRDO6$Jw-u@b7c#mM*_o1T8|r~c)SJpIu>U_z2gcOVPyP=k!} z`o8iEA&oXfqgj|;h^S8eFd%=o#_fjZvb6bWQ~QR9$<#!Sw7S-uAO z*4xtvPn*znJ`$=IBAWrGn@X4#k&{}ZTQ`t-U_+GZhXHhHKs7PeRbAkIodKc+kn?G7 zffPXF?Etx{?lkxzV?u?rl4>NHt{M0wA0qPgZ?TO+%5M{^!6&{k5_HX%d{vI?|mgxei> z;Ff?|(t!sYa_CzYk_MvsvUH`9Rz#nb>~kOc-0N=}tnwu7OlldA@l;mb->D0?Lbz|3 zM#%=P*2nFe&-?h@t2=cVfH-!OuBs;gbLVOp32ArpoBcb|-!3tUkE8oQ1$c_9^CqeX zKmZ}$3sf|k4(y%;rfj&C(B~7CSnw6Mlio49w>!{jFbPbrSX#g&3dD7By;a=^VDK^8 zt3^)4C#tKtxlF^`7+bBQ#$gT>z{}ocPIZC|{Za*1l1e)@VNEENC#k|6Uwb4A4`rvS z$r8(4%bu#-N$y(mb77}KR`rUyhbOXwkL~SNgdvQ%LWb(KDe&G9z0Uol`hnoJaF5Vz zEt{^qRg;l?JY?n#v*~7IBzj$^0@jLpP^N|6HAg+HlWsAp?9J+TXXoe>K&)g9E%a0l z2eH@{AJ8?WVixFK4_SAc6jA~aUFL`ec3y)pI7fZ8?86*?O~6QQ9&h|pMS)e|N` z^)L<*nvkX-v_RrZ!~J0aY_JfC&=}7u7V5m9BeY6MXqBAMDq^xgQ$(P3t=9Uv3X~Q- zSqBp&`Un%!z1`u?5V?kxCDi;^x-rwnu(Y@c$5{nKzY4ChRS>voVxyFdm98NLS1aR-RBo~;s*GO#Y}D>Z5ze4yJ{Z48_NYME?{Wb1purN-)R z+ZcK%hF&+MVIdKQ4ccn?E~EgYOM~iAI;dU`X)#Qk0H~FBC_xn!+_Wy3Z3D@(B9y1M zW4E4sRw#L~!u0!rcAKB*3}%f^n{LzT3C1uuRzKMtH2aFyDlY{HAh!Nws}Al>+hjEU zKp}_LZK1W+KY^H3kJe2?>mhM(Nyb2iDbfO8zbm_-e!z|$8uHQ5utK(avK9fQQ(vjH;UbJbX$ENA@v2_<2!JQkSikeHMmwH%-A%vv3ODQctVm zXj?U3LIMa9=3v^33^T?jg5>EC(LrQmf+^GiZxC64Gid9MO0+D9h%jZ4(J0z#L_h;> zt0p>C*L63?U5BqGOfa9ux8N8O;Ul-qgs`$Swz{*UqV=P~4fj5!_o?#zpxzIb@32Rv zM5|01nb@P1LbV$+^~0(=h79Y-R~h$&I0i!tm>T#gC{6doaJ$IK0o4K)_ce56E-M6I zcrn5>DJrzTG;d-LHP!UFrqtF?RVwk5wSICR087>pAsND7(N%OYei z3=`DoLsyu@6!8O@m~JJ-@z zif4-K2O;~xg6t`jq?Kb`vLfK*R6i|h!#+xlNMLhVKpPeiF((XQ0(RFH3us@S1w>?Y zEFkhMAnIWOD8ctEQ0&_lwh2_ zZBUd28f!7=Hhh)`NQIrhYp{}51k99G7k<(*`AT?;z+nmCZ%p%;(y>%as1xl=piS!% z>IOvM`qm@VwG36Tz2Am}6oHSfLk|o_*h#+J%Gw%US(!&TB>e`R6NRKz34dC)Su2nZ z(>Pg&b&ihP&`_ETMuLLIRMv zqXMIcEUV8-zQaHQSymxS8Re&7nwNsdCT|IbZE?_Y6!=9I(MaMDYp|Jez(d!)t_fda zH=0<#XjD9xl~ioYPjAcWNmp!8)#q!rRgXPG(xb1NT(0g#vSKT_^4zklERdU}R0fCG z_&-2xIG|z(`K>st9e3Q?=}@9CX;E&`HXQCodtrb4G0JXEAd8Fg!49v;2vM9O6G@Dr zK3@H2=`Nr}69oWdjeNEKm$e?OOC!@>a&dv#v4tP~BNDKI3k*W$hLn`FA)q%T2s*x7 zSRM^o#Rd!H1;?dc7VpLsq^Hso(IuiDbXa`WO50OhUkp(}X(6QbMy=B+kz z)nU);t*zQqn+UEtuQL!el2T518me2col-4vRyqJ=L2LANK(nKFrvN!Baq8PlT&QnO zY@fwgCEZP86XlT-JgqdwBsUqMAb*HZA_%1+!&`7?HY*LsR`13Qfvx0V3*sEK1|t{U zz=JM@k9BKPpGd1GsHv9Kr9sD8{fHxv>a*QglN7^#p*~rG7zkOcv6zHSjyR=b!DVEq zfFG0u(-2KA&Y0rJ1Z%-SkKIU?blDf_2dKRe7&%NtXqt_$~}CMcW|q|axg0`^0zE?z z_bdQCzzaDg7pV$glOKZ2xX7-t03D|dEn@iyIs?KVncnICfOye>2AH>FJlQC*sZME* zvDygFgjObNk_4i;1}Q2nQ9lfoFCt&S>MXRTJ0cXctOKTswpjYpSmqO?dF!|>W!PJ> zv132iYAfWnRB&5a5FDh?Xk7r{p-ht`w=SXnV_8Te>wx;)|DPigx1512nm1?-y+nN+ zq>?mxyE(m(%J?!Q)xE;aeS49&BYx?SyaH?s9@PnGWDiYH@}Yc=8`&>WRcB~*gGs%gT2H{Fw>`e|!cqLDc&<$y%_5rJ#TKCk6 zQm!`!$fkEXFp-To8OFRdjDO0o0d5qiDq{fe1*%$3qchOcr1t!iPlbt|wIltE0PpiHsjDbq?yhXK#2R*KtT+qUNW}SDa z7kNSAVG6+=bgEx5bV|ZREODIB8tDvR3vmf@Eqfhn zx=7a`rq>>zIj<@QEmdb@S6RejBgh>0w4C)}rjcaM>pW}A#fXAOuonUK3ESalT5)?x zMJsOpZo3JR9E@oEVrfL~f>t=1>vD8%Td^%2hwu@oss$tIW&E9b`eVo1VtUJfVBWZT7=Lu)MsPe&A-iO?m-Dj$&d%89N#g-ASG)^@I};*;g$bLHc&>QQ^2 zR_Cnhe1STvW6=rc8yLvb!nqy<*^6bt&zFxE%EvGCRrivryGV7uV=tFAO~=L9PLz)) zi${&{l#D;8V|wGpH4_&dIa_4RK3+baD;_1bJg4HnN^$xC_@d-yo@TLKn5r1uo}HI| z%yuU8=-qvS)(0w)w#(9hNdOaNQtd`#CqDWoA66&W^OvWtte;F~CuHHkt`Tj9io<6Y zcGeBa*bRIAdHPdiJ4GkQmX$l}_NBn(AcPL296Ns=>(~e#1NT#YMqh3Hla`$QwTX@3 z5cOtu{Gv8jpV0N?3h=P!jU#6yq^j+BFIpQm8P83o0nJ?yl)C}xtS15rXH3Opsfo1 zX|M-4J$>=xzy1gR5ThIpDz)tRTclXB`E$$VYjMb8{6-@Azb?&7*jxYS@(##-1Kf73 zd;?nWPV)sYmW$zPgWxTJ3)g|~@jLuqB&BDIKM~DB?|zs6i{aOHoBxfrmd)Abr+0HV z^#5CktD6)i_!2W$TGm)XG?Qj7hLhVf@xLamHc`YxshhCA~y^CE9Q>9>xC9r zm%Ab}x9@jFRuo<&lO*5EkDU0vxAhD0H#exIFop=Oh*PhI4QjmP= zhrl^c%gtX>1hN1)flT52{v|(>bUKxJ(Mj&SBWv64<|s zZ|-oo&5o0#jhmhK-GJ10NU3!uinX2C=a|zJjWtDEa?|!BclxH^M+X>kr}T=!pZ%f~ z18u@#U8r|sxv#TL#&@~Lxgr&>%nZmCVpZ3?DhIIpbpQdb4Q2$@KCEi4N{xxk$i5p} zns)24ixz4ORf3&TWK@9^846-Tb$X2U5AcalJ^bnGVKu2FTlzAyb1yy7b{fQjoZM;} z5Z%(QzhLwq9gJ!PBVxPN_>gfWW^j5yKE}4dNFBO^jj-bw?UbPZ*~X;Kll1k*wvM$8 zmq=riortV5jopF4(10)XUjGTV1lk7YYEAKC?i-!hwP+1Q9=gceg07wM&}KphixRsQ zooY-aR4=H+f^HpKrfqVXwwP9P=mKd9qmp>YQfM>IKz4dTR!?=)j9_~4SPp{p4J}}b35sCUQ&%x=2gEyn@Rt>-c zwNsH(X|0A;Xv*5X1_}*^FB_SLZ#r@Vh---53UH8XcYc;b-YwZI)%$`T{MLw|>cGjC znIWt>#HeB#^0qfYSqi$jS<`iM?lFCe8sQ^#xE5I?P`d+3tnYM7Jj6PMgNy46pw3<8 z8_bAyZEeEx25c7k8(>PEsaQo*bF~0`TaqCgg`K^kX(8ubLQX-0KYep&NGS*=HS*~g z3U=FMpl7ODFO)jGTb4)jRk@2l%ZBKBO<2))n-_VL0l9AwH~$3`dB}n(Yw*)xzVN%Z zr|Wr2WEzvdf3j5yJ-I+Ntr4~4HZoyS>Gj=L4KRo;Z|3uPpb{+Gr9c=mHJ;V z$E2!OL`*?WfpP5I%Wbt<5WLiLOZS}cS&;dWnDYItkbIUvV7_-dy2g*$~rl~ zPI{igIj?>g zo}zk+<0(w)8_sfMGJcGa(*%J+G12Ns9o84@z8RSiawm&m0cW2 zR^fOMCU488n|fsRPgdHGKXfT8TvsdVrhGxI@-kbPmy%XKa;F08m9#tnt@E^Lur>&iYqRqp6wWl>n~EK!XS?`64U;R-Ss3Mv-I=l1 zkSiKXe1=6nue$ta*_T!QBBe(z|9SNCpEnhsdwVUA$OBgpc_PH~Ou~#E*5v`&ovswL zDhw=XRUo##ApVY`^d?cBs+D1GE;N%Rt^d%j)ou3(<93fS zFXoigmiTWQ+C!4%TGTE%;+XQL}4* zUpAxnr6$nZmQf9jL5>Vdv*&PvgNu++KTAC6y7UIFvZV8qAE;RB_o<$XXlc}W<#vYB zrMzKyafe3FM!XMgjL-2aE-LmSSxzM55*+h!3F%Ve>ES4NRNXV~tCVx*I=EDiXL;Ps zM?CwK#r{&O%g#;?Rl1$JhRZ~AWn;Ey!yv3U1IfRr;`3Dea+qq!HUu}umqOQjHVG*- zxA#hz+xwRhJ?|kixT$Z{e9;7I>-|eSZswyl8f&gbmsLGq6Q7E@Lw<_R+Z3&dXQFP~ zI_0B%{edvU>0GwEFTlQbR>E~rg`e1j|z-9LRQBoNjO(R;w+D=_{NH0kQh;& zwijnb&x0-6=44dtltw1(7YHm(SiM!23kpZ1JxIQ$MD-x)MUGtawcGaaA&lb{0!Nin zN8N3yK{sw+2AbNUuA&?a_EFol+QUeaH;X<+uF5QipE=FXS3eU2i;Z7)4-qE2i!~$?6Emhy zd{=hn7ulDsDxWk{E8y6~6N*0|wTa-BL!WvE*##YNMw%(@3m8K24beJC^n@sWu93q+a>`FQRbB0A`!jLlQ1Hc9ZXR%b{Nk$ApVP)+{?ErN~BecDo%0 z8x{|_eQ#AIQbB2^E$_d(pc$-3%%Ev!1{*}o=q-uzEvW>{9Nl?B!FqX5dDmL?1WdS% zr3u!-4lF<7sqo7|TBedM=`cK%qd-oA8A`SoPi^47uqZb*dmK9;*yFZvxJIT-8X5~8 z%r0utRI7S9MYC2(9rw44oU&8w8^ zmK~LnCNS4zk(#D zMJVmGXlW3Vn7dHyroDka`IBR4!;;jJrZ!P1<$tI});h(K8q83fL*>7&plTaZ*y@Nz5)8e4bXk-Ik;I1-6dYh}^?)*h>nB1&#gL6Cokjb4aa`NjS zkIl)w*#+T=nP%O(cdR?0bZ6%j&21?}17ODGBF&U~Lm*d}@|pmtMiSm8POYeIOj%rJ|rBL?ZlQ@%^^n>txLiaoy>Jd;>`H!P+0@hM|Pfv@qd9na~#mJ z>yC5Uti_%+dq~@YZFA?i&oPH{VF6hr;e76bBC(h|z>LBPtlycPXD*FJ>h!J{gO>WH zU+RTQ-S#6`o|_MI97GMiiQDdWg*xtn4NN^tm<$Qf`N3Ig)n! zxe$H7hxK!8SOEmJ^w?gO^XxK2X9YkDv4cQm0IZ8)vBedP{`UgExamj_e(+i?J6{Z$GiCO|TA-s|T`f5Z%f`9` z2Z6vftctu3HLUq={{522RV?2O<0^80RYjV(zte~`{hrn~Q3zav^Kf8}B;jC4+C41rpIQ75{0 ze7w?Q_nU?fC=d$*l8J#3Th2r-aa9BtX}EvEJ0L;hxg6y~9@3HK7=db$gM1Ag3TpHo zhYiR>eF+jqpTY`st;c$|j_nOnr6i9-It=+1kI_emGH47&_9Fw{YF>$>=pB6Al(wHR!{CpPjWLZph%Ob<( zv}NLt1b~4AP^YaMf`>9^VCMYyb~`-N(n_orG~anOmgeU+PZOTfHnkuMYjrB8akO^| zL)Nau!dopglcTQqLK7*e-X=1zi6o~ca+90L^$SlVwHa{S81k-aA$Q{{?;(+CE=DyQK3D zk>NT6pjRWiIMgB1iek|^)G~++jMar+b)i?SAH8as&`TjoDJA#c9KDF7Z|GI)MK4a< z*K+hi9BT=^;0_+WNFhYEh0GFq4KV2D3By^?tKrd0XWu24_Yk%v$x*DNYfCaV;i+3; za?lEhYMFu(3N7wveHDl6sW6osbtb%)^rkR|m^z#h!Lb3gt*#P`UQRd)dw_bMdR(#> zT9$*Xi(+RfG%Onrwa6)&A|T!auH@^AlC)~4;nVgF!3d`E@Q6nL*lHl03I?@L00FD+ zIsiJX6RWDl*zr9zJiHNdBI}nKu9qKUBImd94ask|bwqhd(Oi zK0M&!Y*`n*Lv{HP$8#%{{SFxM6=bp^>~0!5_X}Q$ zHO(eg$|6#c)47Y%M|4@bL43Ns2)J6!V#VFn@fqUo5^FN85Q~q1KN!(!qG|=jge?#p zE&%jwbhzXGs@|3-O)vg?c)$(@x@|@)A^%tWztjilWm`niQiz_%zJ-quZq;akV}|nL ztOM4P9kJJV&|m2#8#(H67Ro>&pRdRkem?7V29neT)=&MIA^_{5PXeP384kBvzY%_8 zn)z}mH=Rg+pfwxWB@}%T<8Y^u!U9#{-OQ@YoG8w&qWzd#rR@%Yn)r|>-53QYs~rA> z%>XMdk&m&xLPIR0j)s7uU3^esab|a{L&OhCUPlF0@Cs_wl*G&jFVG^v55V`lKEh1( z*9R8VjV^U77&vuN#z~gne)j z`$`RrTrk13k$gXHH-GfAf?X795cq*=z6tq$DsJVUxu~tUQYl z1m6?1DheKooHm7qnFkLQ3srxET;YIT92VD$2%A=GHYtQpr5d|65ugR$qX;_MiN zIx*Cy_T`jpb=Q5}3OE5B+JMU_h*sxfSv`2>E=_VbY*j4FCG;yW}aO5T6 zs8<5k;j>%<9+13@1nkgD3Kl7vb$GCxQQ7oR}Ss!74Bc?r0wxymQQD-cahcn~Zj;;%2@#(qRt3M@9mx*$gm6WrhH^o!V zidMQJn-#6dUa3u*3%t0Vj$E#%qtYY9%MF zCq#S!sn5yiAj(~dhr>j=at#&89fAb82Ar+|K~h4S$WdX#i+b-$!KFH+~Qf@uxA>Rv9Zo8~yJ@7js-@nre1MaJy2<>QORqp?)2w8Z7`LA<0~L@k=ZGiO<9iL#=@X7qC{neo|yo!#;(&c$xOMsm$D-z6RXmftje4kco`cIkflRZxJ_z*Rn zrMs@vRx8hx#F+?;h!t6rRMejqzxYd_#FLlz0e*#m#6)c##Nk%9-3%~HhNYcp*TmBCk9LKVMH2h|dwN-}`X zg(X`S2Fn-uwSWxdTHzwBt)vn$-x8#}_d%48D{}A(m~zERsE@}NZKHCftT(=YsxDn= za0J5kqOUyURS5EG&`R-;r>nkc>N^`L^fn8d1Mf?QM0PM1x=iGcoa}Ip$>JPc&3v*l zyPz*NtNB-|doJROoQcIK9XIM$?m<*%3g8LRJF|;0B|ytp<4fkywG#0{D*_ec#xfg< z4e9*RN{?md1w^(kJROVaOovXb&!(4X*@Rc6KBaBhpH^u>goPje=@$NFG^d4s zg%8*L7qRQt&bz*d|X52`7F<8OVAs{av_Te63DYtC9pmGfw5V!zk0wvwGgmJ1Y$qN z9>gZujcgvM<+C^9K|OL=NE`PMhp~ET15OK!gyxNV!Ccr=#g@xu4r9F!A8^gffT=biRVW#Ndw5Cl< zv?himAviJYaqchY$mu_luZ#`mQzc&@Pa6T)jr2H=EMiX%j?pv5h-m@&M@8cxZG0y->@pb zBnz9vsXUqVqE2%xlqE$z=#6gUo^F-tvwa6VNL&zuvF4MKk;jhX>@XHSh|27A=1xe{ zcR zU{P19QjU|Sp_XaIwM@a|$%^dUH9D68mwin(t4I36Nf5Lp+Hd`Zvu2ehhV$6roiPTS zbDQZ3{h)n86Lac{BDx860L(zW^f)rYle@m&T{8JtL z!!MQ<8ExnV?3Q*rI#-tRV@DIzdtJ1bF)pY=n zxDHg*0S%81pqb3;0FDaQfxI@mj4@>kNF6ZmV~dwzwNKA$kC3fjc6+Y2%eD7nGs*0BUbL0-JYxMa_ya**WL%eg7#c(i?oN0=s6$BbWS*sA_%FB{V68l z3PdS;n^Ux$N95vROhpCr0-25~NX!LYQm#XiGAwH8u^Qd-@`aDy24d?E@)otDsM#f*D!V%8TR?y2hbHX z?ustGN6c-s8#`fCh2)WSeo0;|zrtIs!60F}$-8|K-Sp@g;(BMuWlzgrN)d@2$y(N7 zHOtwN-9zElTSn>mp>5E)&8JwmO>v)w*rBma;A#w0aGg;^&>X77CvZU3W#=P?1i8bi z(9~V~3Rk1|)S&y7S7ml=yOM`?X0a6f1E7K)F!uYu^t(}qjw-;D*>s{sY&wx_I#I7p zr#}UYy=*!d&~vX422`ean~pY<0I>+^Qt|=r?;}seYWuX3a|Z zBE`I$^LuEuuj5X0!^c@Kfw{I50kF1wZIeyaf_W)#w$a9t$#eo`twDD0gce%YwwB3c zFH4iMg6?i@07p{or&u-7=G5I0rIpR5$i*i3-HKW1^SfsiLt>%R-EavFpf@~`uFJEH z2w6cHfEG1w1BIdJa`3J;cIMtfT*C#MVXCCCOjipt6gUUB5Lf4(?ymZ~8moP`5LYE% z_1{8VUHBGa?MNU3(3_q(!z{yyx$za?mAA1QUVZhf>;ev$=IrhZ;1x4o;#ETvTuCN$ zbsY$&@JP(B{gn8HRb5BV`|+!cm89LZ0>3cx3cuJt6qVskrP`P#6J_XGfnS8}67SHC z9)BEi;cmN%In7IHv$5)tDZkFR()!D=?{sI%#*r-sP6X7-^9t)hU=cZNHNco|r*Omr zwe^(mP8RP95K-<*^7)1!xg~gQ`CVF2_F8|npnYG`_kBt4cUBF_(beo4w`v&iiqDrz zM^r8yRiG*k_h%fkC^(!y%qm)8qZqA%{nI>xti8|ij+^7zmuF>iUn#ebO%P{8KC4+> zSjK5o2xiKMttXr~xc!zO(HC}Wi*myYmb1CiDl}}RIKBYa$+s)N8B@S*FMXrL6!_0! ztPnxvK0MTDq8X?ljUzN{;km0*B_@P9-OR6EZlN{OtBKCAVdbR7zW5}RVw>Z9>!&+y zc*Em!y0h=SbXUuuyYhSJ#H3Pc5~fNdwc{-;+$@LCq`y9!C9>yuM;ezDDK{oj!UVouw`eEdsC{o1^o}6TTAmlqVH8$w%`HKD zv2yLplzaUx!Qf)$1}{_Y4YveCi2cg*Rc zU))hhN$*tEBkmNsmpnA)iaUt#5_eQm6la&I=i(0de?&t2DIye`JYMr+O07@asm&L6 zY72`yH81Yu^|)&lX6+zYEjfUd5gAT<(_X4L=x+Z8zv=BSPisNxr$=f+MM7!os0dJO*8wX9_52#b#kQ|o>?)b1G%)Ab+suciM+b=Wx>yuk1v*w zpVwni-33+m64lv;BBLp5dbup~Kg!2x_Arq&d~Z$?AU`|BeY3tJrz=HAW{Qm2&y*cPXOG7k}A(bgK+_8MDx3X>arC}V=PGFuUyEY}Zr%jT**XJ%bYK_cJFy;s) z+Pp_%SayD?{64tJygX1>&)q%Y1-N_O;|t^V0ef(kcH6$h?ZeJt4bURfj=v{a6@Sy5 zTQ@`xh;f`>%25;@sH1F7OiYR7pM12;iz9E68IwycJU*J@7~2&s0YRLP2scgh_rR6% z9`Eka9El#XjY>F_Luc*THphg@Bf>!3VKx<@Akh$SV|<4nTJE1g3E+}lC}9!`NKE(Q zFd>#^KTHO+=N}3Z1x&D6mN3DHm&1gz1x)CJ!GuFjMyn1aq#8&_?S}~Q=Qsp!5K)H3 zAtH*!HNYs>xdy-!?cOr;HU%x5Yk*;hJ^oV77Sz&Qa-NeMioa?Q%)L&dSM{2DQH;x! z4uu6-CN8GlyTuEWqa%QMIrC+7yGKasOny(I$OIKO}=(9^0+AT!SWHN=WEgkPwW007Gk${G1#*B zxgw)meO*Uje0g!LT^piV)$kc=pc`;ftz1N_WMdw^w|C{TSGRJ#0_(QRj+jTse=YQ- ze{)g2)nm;W#17lOCuiHF_HcZLQoI$#Ua(@g+xT(?&sGj-$$reshAE28*7l_pl^R|& zy+%e+%@U)UL^3FG`78pCkn(cp8u%_O?O?9%5a$s-HnfNcIwY-ls8@Dl*5{s+WoeQ}o;Sk_c)^cCqN?spa%n zVOZ?!A3CE2W0Rd!XFdGCc}GShp?^)_x@eEjsh@0>16Mr>YJ~f%-KVES$K3SOz;FDb zK9kk%5L=?SZ|B+bS%DYR59##ays16Y;2A z{v2PYud!p}P4el)Gs~a?8FlHYiX!*BqV8QSpNsVoFId7EFgEBzV_v0rMHG~+k4~)N zgVxqz@eRd;vQLWRGOG7t6&^Mk(f<9gdH3}Md>YP9!8>{)K5^#7YB?Fw0&}~YAEx@C zd%MTIJ;V=l`GWE=w{+9qnG$=~l=zWaFqaqN{Cz|8nVx5cWrHUOA36X9hY=cP6G9C!b_0;r<3URm=gbd*Dn0`p zb2ORgro4b^JZgKNss!Rh(Vp}L1f({=uf?Mcr5F3J3BXLRgMb$yC#mJ{u5(7?30rk)=Rhy6dVdl_kDP3Ky8iwpA6?=mSdw3z9FdaIc zkmIy=riAFMWsWOAm=qSB2~-gKG|@ynwD>(G1OYc^LTYy~7P!QVOYqPJqjqL&dYePZ zL+HGq%?tvA4qT%jObTm2D)BoFM9QnZ2*XQ&^I4Q;!fNNxp}2?65||NfQnLn7@FYuS zI4-$hO*SxHg1Cuoe02v-w!}1qB{u|&#reoXKddCW6c^esW`>run+_FB?x4N+){gpN z<+_p)6qU`EfHA}VS5R}MQ0*E*^0J#Sk6rB7ad-08Je`SCe8@x(@_!u>6RVuZi$dv)aX^5}^aLhyGyAq+!=M2lkxLlCzOyV{l#$6)AU?eal}5OvQAEOS`iPQ-H4mO3&4v`)qz zFJdOoyylFjE8DP)M3oMDsCT^?7CL6ohZn2)k~ryF>(v5a+Uf}0@jG6Z8=b~7b*6HO>h;@ zc)g_tUmWKB83#F`Mo3w)ld^P^3EILTa7B?4so< zcZw>UOP`9qLMKSKiOVKE_85lo9_~1iyQCZqIeI6BqzeS)Wk}G1^$M@oHfWlcAp^G2 zVL{?aVhFcEi2@Ay3NOQ|^Wcpu@jdXSFNllArT7DAmmcSu_%^0Yys0ok{bmSp|)>s=3ehlKPh$ zf>pMw#x97G`%t>74w^B z0_0|UgPc^>N3xQV+uX+FJ%uf!@HoyrW7&;8U5(-%=bX~oWO{RhYILqrN0Ap(?EK`L zGWd74ZDV24aKn8tJGBau8-QYU;`b{vE`gBV0QB-)<5KiZ{;!2jEoom&6}WO6h6A~$Yl>;YV%ebHo7u*vQw zu;0SISQ82mpx{Io(wF)0%d{_2cVS7UprlM3pZ;%pV7n!izj<-4y55jfDYwdNZ$)SV7>ljyCRylh$Op&qB6@+#5npEh?gi zSk5kS@)-CHLCXG89%K!XfwnjW;v#{}gj+jyoWSa*b?!%Gy~JAOBR!^8341*lc2o&} z9$Q^jV(}VPiS1IKS0~#tQm0M?Qq(vm#dcf?JSVxUt%Zmu85%J35Qa`anmy9V&k^?5 zYsFUZHRhPriE{x$06Gow5cif9TLC+*1=|f_E0sMeTnyB4dMJ&=SXE0TPn1cCdfPFb z30t)5#IC<&6=>xivUB7RF93gtP#BYZEAT_ZM14>rmvLE8vpJ%GRS4l*D9sX4 z2AHQJ#UqMA*%m%6$y)oSuLa~S3AY?^Y~m!%k9MCW09rCCI3g9ZVCVZRnO7e>X+!iz zfT0LeI>uyDYlC8|>;yKudcGRonMKK>t~@yL#tqSR6jdlj`Rw5&XXOx;kMS^)-{<5j z;GGUMixZR_V6n=sFIwjq4q0p#T|eqn<5VXBSr}q*AxCV5x7O$qhd%9yCEeKGm27N8 z)5^ZU5lcZq5OLCUQ_7J>)Cq6W&8l}+@O#)|wo;3U$fSB_eF zT)sb#!V)WCN#@dA)7Wj)2>+4~P2E7Z5DunZ-Ow0JDe#*OLcS*~&a>^Aaa$0xYC{Q= zrSvgFtmpq?c(}w95CU?+)fu-<7a?}mvNNp~y-=UY_6B`+Dv5BU?_k%d)#f3f`Z(We zZK%ka?40`mt)1sd=c#buXKP;b52!fN`Xq&zytF*gT7xS&RW!;Ev_^uqmzSd)+C91p z^0n7pOd0Ue19gCl6+#W>2e_o%hztD6-_^0i@_fjJ#ZD&rGj(%LChpeB#AW%BMxD?q zP9}ckXHhVO0DV{!>(@8HS(N{~8utfXoguEHcCg1-rHD0ERkT&T)MFO8{6A>KqODdG zYbx%KH5FT|sTej$DTt?tHAU2SEOH=xZ>%Z#p60QpEwV9ZiuVGWrnP z(0GQOU=zBkSW{IOYs!cZcN2*Y1K?mX9fJRQf?xb#I*|K5gp%5fVZa^4F|@>_A;t1h z<-aM%{w`hm_rLp-|MCxaa%|qcUV8qMANx-aJUAHg>QuU)`TZX`e(xYw2=_kovw!;5 z`v$c^P9Oe3-iKs+n?YEGmp=86fAY_NGbpOKU=8>he&@%2^9pbzCi zufVAK%=(7yR0jriBuZgw!ell2JOfzRXWN}Bjge`r-WXoJ$VPN5VFpB<($`mhK*ivD8B0;f+$%mW?u~k6kEVme_?{H;#zXZvLLxsDL0Yt;P zR5klb9cfL_IZwdGMu+uQ7XbqT(sbTO>nn1#`%eI~b=aU50v4dAtGF4t`+-0U;He%c z+JGmic~-(3Z>Pg(Gr8Oe%LX^^+DBLea)(xY^3g>vNgz>d?y%y^wdoGqWkoW02)<%& zX5_<)VlmZ=oE_(Z+}o`M&bi=?v$C$`mB7idNNJicGMj^n)9*<*@f(v6UDKuvwvR4ue1mnqS z_V7$xM+IU%RVO8Umkh;JpH)r+N)a83)9RS@;?1;9ESE*Nic^t#xk`VE4vfQ9!jh{< z7wt)bXBs=S6ibO=a*aiDEZK;d@5ZQxUoMdVPBac^Lw=7Fn<3{ z22af^8=9bU4mw@FE!b=_+)~d99L?3DI*G-G3?b)N!2nRMZQcoG@Aq-c{ni22xo{SQ zY5E9$fcGp;OHHRrs3UHhtf-b&6tzL~r7s|yYtTC6c1tZ@zRx3swA_k~PedT?6e27u zDFhuM)+M1ZF^`82CZ3NAH$q|IDX_3EPkb4c`&lu#a2ZxycdXd`fOQ2c&e2fonATM` z_4u0n(_T*Oror8dOb{?!&`em8i0=|1e67W>XLye#k^OYd8FyI`EZ;DPy7$;C99gu*JYeer2DCtt~pIM2D-@@k7| zbYGaJyncOgrbOYhxQixB5|Ad_8yS&}wresauJFS`28+?)$UmjTCq zjkEXGLCM%iSCXzrQn#hY5;|0?E_0TrrG=bO+*bwEjq(V{QT=_9} z@*`4H&i=LOWpS5GeoX!mGNv|qH2?M^VH4&I#1+#ExisNN4qP(X@FaVU5+t#u_M{Le zud^orts{E+45e;}u18SRz9pHHe;m?HdQ5Vq^$VdHKZ+s5ml=W=fqRC~F9Ih&9(K^+ z)H95M`cdc+CuAl($$F(u$4JY1dYztJL=xxRI%1zRitEV?A5w&p>gzoSK}mDNq#s?fpzjDEU2)zigpksqA5C;SxlsDLcr74S?+0<`@MN) zR(dk)cCitWgi}qkQ!exWMmmU$6dHO5V=uilQN8lBuBfeM$(I2?rk=1-Eo4^0Zed~#x=ocw4AUZB7Wl6a@3~rVB-$(Qpt}CKqZBF=^pP*f> z?0FNTe1rpOze)G%jM1t5`YPG32I9@)KJGu}$F8qx$>J6ETf9QEc!|m>)g)&gT|M*` zudvtRg{&Lq7BB54&AYxzVD88ihQ$l@Wr6Ff{0%oYuwqQ@HSwrM2Y-Oa0wRrVAo;OS zm-jd}!_Y^f5gEsU6psh(<^m0n+<%QB-W)#=R-GZfCDX7rl{z7FFOg3GHUog_VA*V$ zY1pp6QMMKfU|Q`E;gTs8k+zf%j@6b%EnfWL{}mWkcuOE_(NhHa^6Y96gUko}_{xW( zxmV%j2j;aE`}I0o?^QSR>#=SubdH@5WuTxid(DLF@fBpfcEPNm3f?Xs3;O~?$^XYi zhLT6uD~E+@%nu6%%2vJC4o~vhv7b>=u@&?N0wmj&g>-_439;?^G99iiJs^tf%f#d{ zro&P4>&sx33twLrh`rSN*-PEni|gUtfl1<*zRb zR6?xFG%LGMtXMH+7ocT{k8=MKGa-eB-HXJ_J4oZ_6|OI1;76!N*O%4djliJZdwm%j z9Qx{D!~HmDO;~8*lrTLDXjsRD+H-vww~9&e72i{QJyt`7e+zVd8GX_9W&CXChkouR z?*;TJf$^%ZFJr{IzAWguzRdb#4e+Pr=MUIUAFUvAsC6J(e!L_9sO!thkC_1K)ScEZ z$6>A5yifDcivlenDaa#u&x7NkEoi2K-&Ko#96=7G?qF(e|;Wz0Rk}hHX z{DLY3HYSPRZ{3`I-=9ZqHrC6&9r!pVy;_PGYNy=+6~~)_vvzy$%w~xqWE9%1GC(x+ z+%s2rQ_+=Bbc!oFyY;D0q_q>&M1%&N6K8YcNKP0vB2{Z-70l-R;Cjd$zEv|%by4q~ zVsb1tMxm4DA{vY2NG7?L>XXD4N8xTuhdkWdrGdlt-=3XQcUcwW55bJ`O`&FRy0mA2 z0kXILNn|lueLx*D_w3kwy%m|L)I=DsDJhW*t1Rq(jddGYOqW+-3Y)4q+(@y=Kja2g z^Jvx5oPS7*su2D{kieBFud(;W z`a)0H0*_>^M8awPaOInLE|Vo|jPU%`M|;TveTuz`==qObUhnyj1+LIomd&Hte35Vj z>tf&dX91w~qY)O35AGW zl|}Y%`)`X2lv92p#f@^gWLA>4OlA=KA~B&C6E!fig%JkiSY#OH>FKJXSCQ+&QRvtju3;sVqS8&$|U;;Hadx6t*~0 zn!>;Com8JT(I@<$^Ululn49Xq-u<(~bFy)<*yCV?@Gl<=IUORplOCF!w@ZDEqT% z!7@&GvqAR>Z{Xg7-8Wfpes-{Sq3mL08wx34+!aBCI-m2rXbi*0k7( z_?Y9>Vw;cT7H(IwCm++zQBliG82Uy<)$B{*V;Igl+T6A!SbLC7Z38j@Y5C#Z^fGJR zX==P#S5!-dTC_LKPJ&fe$>g-3g=Ubzj>6!erA{O>g=&^n#iD_^Vt1=HcblTz;ayj) zJXSc_VN}q9Bl~Kon9A!5_ubChl9Br*)GfDk+CB!Gh_WLnwWb7fX6L1DKefV-L+g4GGLI1}8z7{R0^sSH>C=Gu5WDaf1x#Gm!44PG zK_^;eb+bE#5L>hhib6B8@X@ls`zuL9F{8Nq9G9Bq6I(OtxXz`KHY8UqoIBan-v3yGVa{D#F-O+ zxed3VyK;5=P!|dUpxZHfDP#RMkwc^W2EK&(`|UE(0h1YEALxou50@xAeiv99b(WHo z+W%RFT9v~Wj5Ys_Y}t|SK=#zpiEQ~DgJGsyi2eolgYNAvReJc?-VAenx^yb7-L|^3 z6hk8|qt019H7n4_e!>dWj&zs$0!!1{RNAltMR$DfWtp`>O&!1o>y7+uzUhOPfbsMsN$yc zsp;9D=20ELbm{p^@!f-!yt?E5ArKtti{XpH-EwXF-Rgq>zWL2(y30RpC|l3&CSZVB z%)jJni?@8_aB%XCU)cEMmhbzkm;aB~?*Caqm)bPww0VY!05@D?v3Z7B3}%Su#8m-wAv{bkrl+Gx8op*~f|qnc zEk55(&OA*Hf+(efPd|O;=`-E-8Hz4Hqbkp+R`=hQzkJ))yGEY;?OV@m8ULey^AmS{ z;CFAGIkP3qzUAk(PyJgxzV$mkbnk-?eol{lYq)lMVlj@7o0^wCL#h=g(|;(Ee$_PoLTHrT4vIoC=0z{II^=I!pI&lPrsjC&@RyxjyN%3>73)!V% z=y&fCT$QwOW9%zp{w*&E0UaO7jvso=5c=uPa^@G(mk8(Q4(BR>7@aFIOQ$s1& z^QX7`<<0;7OJho7o^RfFw!P!~Q!oi!G?v1sj3^kU5aImK{MzK6jgP$P%$EPO_y79M z?9;#UYoPn}fBfzL`@}nz2=jm9)4#T2->*ONJdbZOO!-Y=N>?=Hdlk&ih#dQ8eyf}{kkDJ<#+?n`y8Yy3wCS;5oLH;n;f0H5`*nqt1Y6NgP(_mPTNu z*egq2EG`;r&D=YI0}p$dN7(aQeQhY`H2(HYu{fI5lAG24xVXU!(X?g2}3Rg?|)tw zb|SZKcK;z=Pd5b8oF**3C)l2hG^y6bG`#hM^u0s7XWw zimKx=R6)@wJB9=yG||p4dqx4nIDUv>T>9I;dCvp{{M7qS95pIYnxVYqRwdNvD#6s- zYQl8C1u^quVe9{_gl$ua9Ri?U&1T&}s4(fUBxkd~j$@*N@d>zQC?&o;8b!1>4by0K zq4rSjGZ_ch2c;0{Y*Bk3D1vpQ6AG=An4RFYOPEhOLS=lE-a{i+yT;@kflQwwdS??O zE16CIMcYaT71C419pQ-4r~-9MteFoKaaESNEX$za6%K+RLGtq&Bfy;71=d8en~r0jL@4JZymH+p_b2tUE138yyLVa|}e~Fii6< z8XaWfEMze{j3}V~m_Y^J0@ec_APLwgGKdBX5bJLrWQA2_Fa|?@0O|@(*ig`pZ8GJv zkEKw`G6Ze>dRUafCru?<&8NxikEr*-n zw$%#psmi4GfQhIq@L!9%Y>hf7OV)1vP&I6zS_>UC$Y^s0b$oOi*d>e2*==UyxYay_ zGIrfQx{dbmqk+e7;42)?Il8MP>6c(JS#qQs-5PWo8V`Jb@8*ERn_5n84d9KwTDgPE z&sh5N*=-aRY*Wn@bEmZi@Q9~74I@S;&YpTXzO!3fjW}d2v2@i|?@jBl^SsxC0X>Zo zQSzRmzE8=hrJll>gx`LtLrr%}1fC)CWgvWoVD7r#p!*edU)#}iKPBOImQM$fnqUsL zfV}h^ZyITDzUN?_$i@&$`%-`bMfJA92=K_;TPW$m7$^W6wJ>d%MabyUAv=amg;l|( z2)T(bno6Ii2PuN=GY|pCCY8nbj`E3n3HcrM3b>@%z%eSw?F>XPwb=Eo=yvRSCaUbB zr^`Pe0a$4WR%Fxvj~o~@Fg?PeVpMDhL7kOB5!i|yrN(=(!;o$-wqx8@_hqeW zVeXD2BW`_pwluwfmg&Ihe!d-fmMv2V|=^w8svK73$bx_`%` z<9xXY_2#Tid?6{*0;{f_fbLT$K zJ$Gyawn8Oif+t6Q#_ z-8;QnJXm{`Nq(YNlN~w6iDBq?G8~I* zH5Q|RLWZ>Kj^7t3xG~HD@6hfjL{9N}wbjhG9BqX7 z?erBxA+6A1;$Qm#9EKm)dU08y?}uT~52fe9VXg5sN)jc#o?|%**t7!I9#m( zXq)ZQK|CHR;W?2fV{5=>cj+4$$I2VVEE*+U14aY&krNLDYSmLAt2H3RspT%Ub5Vc{ zpte=mbAu7~CRJ*c_t<#0HLKER|Az}W9B~TMDt&be7JBneR802hyG*qa{6tVJ_UMOF z{GsyTZ&q0D>R62A9qlox(c{ddc2SPkf-_#n56pN@>r^u*^zy7umqNXFqF6)C2Od-u zzl#PE&)0%aE^xArXNu>ScrNP&huEqMu4Bf-#)Rn155yXYeK5c-TjrHk1b+Yw=L=v!?0UVq2eR{6d z_oU+*YO`GFctW~vsSO~x+^3f%AEliW@LeFEKBOk3bc`DapFgC=dZPsI^dWt|(S|*g zH4^f7xF%hU3Y6YN26rY0bfs}%h)0Zq#05A)r{71iB*TM~Y#|N~^MH+;w$g>*2oI==K?0!QWpzL`w6Y(eckwzoq^DUDIbP;KPUOe1njcav-^Z!NVQG|M z%w)5VZ5`5ORIIG0p#g>VU~)v~xz8R#36-T7#Abd%$Lxq++}_9;82QQ_glu|5J3?c2 zc|=tqetM%{R!2;bd4KgBovg_*RieOUDxDrvEwjt7^J8k3#nFync2<8(FOeP*`0f}* zFlpm@jRxRo;i8FnU|SZCe#Y^nK`%1JOy@U=gQhalEG)WXP*s%Z+|L_y{}s+G@Z_#b z8`R1ZlOf$!ZY;62YS3A}RU+|xd)lNr+E9UzEpC}vv$zHTFYMU7S!ggM-owCIlTF&B znz5-kAreM{gul3zdy|>IIpsV7M z!t9SnL1`FTNr<6{dCOU!wW-RUY2ux?X-}KcZ;LjONxx(3g|rPQ*BJ=QHnq(b=!%E` z*zmOmScgvYWUW1kgKOn$dmU=}Y6S7jM-4WpTy&_lu~9_7?9fxKKxoFxZj`qSPfzJW z$FE0^%xJ#cxARkatR=GXv`r>GrOToWhOqRtv7n^YDP4U~VIXosQ5g0ERq1*V9 zSxC>$=nKP42;1aA#}OnL(K(~xh=&P|JfvrIl{fy!;#o@AKqfuGzm?Dt&L7c5MhzT7FAP2aEoBB+KB8wlkaG1H3Yd*s1gGa4s`%<%W*``wL&7i% zntH4+?ub(>XK--n=iGy(+n`M1L4eyS_u%TBs`@yO{mBK@bC>vidO>^Urq6G)3%b-v z(ehg}l3ws%xA|-J);#}t3s|pL@7>!?|NQ0ee}8=g%cWJw{`}yNzaWd>#L#aZm)v@X ye0cb#P7K$A#%-nVJ*+ZCiYqO%+k$q^Mz*b>-I7KL|IFTlk?JlW1Lu_#WK}oC$8WT%G(poHO2!uuxveiYK2nh;Bq7nBGV~XJqW6)Hi;OG0i z=iGZ|e?Sq8sO)C$`SJdG-si{ndEV!JPtfVFg+UO6zaGBkXtI6&{Q1Bx+riP0zaTi; z*tUP+_R;3~^SV9HZNOi&y=`~rbr&3sDdIU)2Xv!aQPrD@(`_}TJC#|@M4hSKd9~x| zyq+l4(BXFU7x7JTcm2$*ODDTaD~p4z&U(MIG+5qPU+kP7oZQ%2eqTpVL84l(^R+g+ zTWibx{?(OIRm!XO$2)`0Vt@I4-JoHwx4NC*9VJ(<+X0mvRB;= z`d;kx``xWUFrinCweH%|=DA?f%D1|wPA_kDjlv+)tL*r(#S_cx#}}99?+m8&Ca?S5 z>MnJc&vdtZ-_zr5-x5r#YLm{_HqLZ?@6&X3dK2Qi*4YiJp?6zd)vAJe-k(IKYZ1zn-k%ygI7&V1T%Wsys3Fp zbkj`{|B^J^3>%F!4ui1qns_@bcP<9mc2Hip5Z0IG11)vEv2`vAvc<)d-OlFXu};4m zhm(toCS^DgM`>qsbM;(sdt>pv$5)S>3GPZ4-@E=uFF2rUrxzSlL5G67C$cao!z_K% zkGJPuJ9)W3N57wm!p3&AQ2%$qT+}KeU6LYRap42gfs6GR6v;}Fy0BL?%I$YeN9DKp z*K9YV1s6GrqVk)(h~G*5hKtH@KrfMN+<$Y?e8+T@xn_Q#9ZkiV3(BO|4&ntDm%-gZ z;P_APB^}4}QQ*RIyH|wM!BmoEWzcT&7fppU%ik7c^w{jRn@|+?7_^=6BJCAvJ0A5H z(^Z=aRX=LOfQd_Oy}Gi*mpfF}1rcjQ7B=Z(Eq+}4;b5=jl0=n|Bzo@*M7 z@1S;=-?b;pK668g^uPoCy*?=akzT`nlonAQX+|%E;w?kGKe=DL%U~Cz`k3JbZ)el$38$5gM23Ea%IiR=liLjT?)}5)7vn%t_fC689f#M&b__p}DFmL(^ z&WZYJG7rc+jJTJAo@S0@4s9QZ-@^qy9fiu^wip#X5Z@zCR0h2?`3q^7$c=vRWMGO8vN*EqS3!2EC#__$=lCVh` z(d2{F34t<%6ZM}n_;HJuHQisn?PS+ zz?Cv!6kZ-I&@1}nRnDuQD?j+WF<6{4vx>?~AI)rgS}?1Z3#bfw;wm25?P->4|<3 z35YQZUB;bO8%o4(UnK^?B$cSVY}yPCc)ECj=KiQSd3BQzu{-EP&x99oIfasGfHc1= zV@mu)<$lmh(qmXDwBrIp=9p%!&=T)Zp*`cVruk?}@4aNi6|@~0B)bLBqFyBc$>IwB z@4uS=5(E6#W!A)?W)M|L;dKlIw=Tn(tHiKR0P(p>4AFv#;!Tw#m~$n9z>5G`3`Ib1 zaL3Ca7|Gyrh!L3psDK2*DZEHj&WZPMonL82RDKQ#+$srN-qm1Q@|uh0#C!?Q%VMSo zyewvW&R`@!48EvU7a^u$k;F9YMx9VMD#xaUHOC9MhLgQQZVZwG!zcC0NWSZtA{>rt zvc`7|N3Dt&by(z;1BZ1l*ui*nQeY1ZxH^2P*CVNr=rL>7045wvdiegRsa{3(&@N(^ zda`4YjfMtosi!7QcVdt(Qe2}gkm8PL6UV?Yu*+z}BEAE0PlSb7;i>y5vQ!5Vp0c+u z$i5uK5xz6t)__Sn!tBsK5J=v(4GR=4G+;4~o^kFk|HHhLym%4a9uOe-aHCh4t4@H{ zZw05A&9}l+MLc-sF}jLNf`*uqo$%BUj2&2?$o8zK70??*Or9*79w>-0R&rOB0u6~~ zS)>3qY6yGi?&pOl6hIo_KfsV-ATtwp6+BR6IApY1Oaj9Scv8E*`O+B2O7gOH8drYWy;}#*!{0wwdeg?{C+dz^p2JXzu$P4k#eo!2FZk+rT zb!Fot&O-=D(kc=mT`0t~HA5n-1MP=3vyViv77K|M3pu)=wF1UvNFx+_MlM89sM!bt zWh+lgsc_3gl%V6g2{xMphvo&Rw(bu07&3~rgmM35@Hn(3R1q1QzBinVYpB0XLqZR5 zihVr5S#+w_hPh@*f?bna-MJxC(~GX^6l}BUUbk-Vn$?>EEe7|XB?yBXLH4yIZo(p4 zPt`0ko|vyf3#4H1NNxh5B)Y>K3k;YNEE%65fws79Ra%0T%tcewM89;~(yiilb4{_9 zv>~m)u9&EZNEE`PDh=1t1x=;^)M#i0nBW0wfm?eMxP>r^7lby2sT8s`JFt+Rw{qTi z4)thFsyjxtQD7=}1pavV*2**O3CSLb@nS-@!QVj{5K6IWLgpcy`%fEQD^rd0i1w=M1k>DS*&&FYD=?~K{Q!4Tt#xpd^ zkG=Txi&{IBPwPhM4ndB5q_38gUwZn*H~Opx&S8K$!xEqM03e#>>?(XLCzbnY2t*8aVH}pgbTLqJf*uACRu;{bV!}WlE41W+0t{enQszEcn>$^# zB-9Dg2A0f{7-nQ^(gNQdT$?E-R*KAbhuE*()r9XV8+K*WPbxG?hz?pFO_Dk~Xc?M# zgo-skTs6NVctJsHN8Uo%;G>*&P7VSf(*=dDO#IhA|M{aAu#NW@$Cr23SF?-MDK zYh~k;YGyW$QMa&h|KcHeUfC};J}DcYtZh85ZQS2vmw#y8So05@bX6 z^3g0wG1kIoI9hGkK-cncAn3j2^Ym%6G^Al9rJ<($h=3k9ED>HW8s?(?+F)R!dMfYi z6%!s0(EYOBcKP4%@-ytysT^Q z{g}jr_ZwC#fyqj7JQaosF@`{ImK;O9*pnx;#a<#3%^LuBVB&*BqNze#Tg}^&55*Av z6L~uqRHkGf71k=zjpvc#1mNsG4K?Zo*Hw3uW}iqBB@L>T zDxr6RDoRUmF4p9mmfF=Q$}|4{B}s{3+M*abYe;(S#g`m2z&xX+NeroUtu97)CC(5VRMQD@6-4ZBH=gmYjBsZ)oM&UK|7WxKy(^ z1f>}A!SZiKDIQkFNB{sO>Ix&1nCZ+r%_;N+6H~Z7CI36+{jZVJW+5T}qluXBBw8l& zto<*`1oilxy1G^$rn%$Md_yci{I&mW$p0c`si%-3Hvb!s{I9^m!h1@Yp8Rj>CggZi zm?Hnn`WzskXo}VDZRBGc_*nnKe5@=KAKR3VZPq?E<>fxG4874!_UZo@nGL1N zugGjDrX#bV%Pforyqr0ZQFag8spF!n6CCV@#Xj3HV_RdE?bs)y|3S!h+$ysk&x~9v z+c8sTJMaU;YzHcCR`nedA-_9v-9AjOmM`QyanhD(BirPibYQ#9z>FD-z?t+cS&%VL zo#K1&)FdQa%JQp0DhF$*+GD8=@2L?~wQ}*pkyY2mTN^NKr@Q^K#HX|_jw15n9yzH@j=L zLSR|7d;r$I2Y3CASK_YUz~ufnxa&`Sznq|!k#Y)hg1O>^@74**NqQ$(`BNF?E+>e} zc_)avdned1Cy05x0w-8ygMR1-;obM_2cJvGBoSC&t^@0w^*ug=`jJQ@4tyZ)+=-12i6lu+&G?;0keDtF6NkRTf9_Fo!=#3Tc2Dg$!dyKZx}d zi$3HpN4Nkm@1gD&NP#Atw(uRHmUXlH%imD)SoyPEG_yJv&5VPuiI>titIvGRW)p7?G z@&llR=EEW%n!~0lG&f{xTRhp&`hujUp)SzssaqJQ?h@HxBabNClQ-JamCsOahi2Nz z*F|xoktgwt(O_HqjcVi8768KhYZ3v+F5CLx_r9O&12&sp>H45P4Rgf;VXqblqi%LB z5T1%-Ee_aK#K&8m-~O!D0QHLCPyLe?I&5;mD4eXeXAHEoYbD+xc9?<+`Sedii$k`x zE$f6o(jtODoIJ8NztZvu2{x}QF{=^DNKMtsmPU-DoO*O``L7yW0Rn?yB2+9QK`zbc zk4do`P$`=4&+?C!Yah8@wUu!FszSo``F}0@Y~xy6b2K+Vmp-LrOZgeDWrzf{{P9|- zxhh3k?eE!^5+%0Dq|NtsGlR6zHax4TYiXJhW12Q1#x#vxYD%=rNnVnwHPV;7xJzDEHpK4N!!9EX}8^{r118{=2Zp$z>1UPXQnxcpgN z?hfwrPw%2hbId&*Y;##2lWDov`$y&OK%|1Jqrw$ld z-SKMtT%H9F>Ll`hmt~^xjb%O;$SH&T2I$dg%7%Qf31!R=+X*xy=oTohJ>W?*9s|sz z{5l@ca%bc+ya#N^K`T=N!&o0(=>e;=RHo7@GzX07nM%u#!))+#SY!js4Ob5OC4X|r zvs8S8|AweT`aTqn6ZkkAaz-Ftz!Nx%AaMINfj;E$%4JlD&0|zF1mz}PB^}ETg_gp* zCKVKO)Q%*_pU06l?W^!E-WTLI9b&f&eM(4JWLn zD=Jx)or{0);TQ3L50;;>kjq36x`2T18vS0;D;h`^k;AWEZQ*!yNQbe%sI8S>g6)wt z_>vx#OZ1NypZdrbpJxCL4SEuGo_P8%Ih?9Q6C%2k3#sG%bWJXJzarAO{0iz6V}|*g z_bQ+58$NDlXzPwH{?*t1`pbX+(7UH;=dC_2S>4J5)6at9#k!x_UjCDNwOwl!-^GQr z>V3ZAeRiy)8ZfttB#Ese=h;eD$p?MKgUU(QJvyUI{Ls)3alzt__=-ogaava-TfBcS z%lurO`Kaq-QPkLuB~mv$k)x<4A@j-wosTS(h!!}O5p2FU`o8nV4QcaciDTQaU`#hd)5>}=Qk}`-WS33=!cA#_h0~y7#cOSc`@)fGpy5L; zkUMc63b7}WkvH-T&_TrCgrPr1s6%voIo{svK?eo9 z+ml7ZA3nvKtq@j>GL_ZwEUyKqs)UPA9-ctu$caBTig01OWEriXPV^f+P@RF)GK3SU z@J0wRJOJq;q!e)KYBDIF`x9>RJG0Lx;goi)sskBF@M2j+9D>Phr}N_T*hfw)?SIHl z=(lWg+;#;$j&Ih&PyZ$POC{;kNV5_iO|ACyAqSu&&C|>BF&+z@-V+k3P{gomwB7-J zGO4lpf=&7^i49dTOk1;D>6*qm03BGS_bdm0x72~i!sJ!ejw`6kQ7x;&HZN7Cm5$Bd zst=C%-00u+NfQ}e;+>#;fmxDu2}(^@AtWEnlts(VNYS4rQ-tLO=+`JlyN^!}m!H0< zMR918qp%{9q1PhGYc0Bg*&Hli3<9t1uix!tH z;+HlNA8^>vJ{eG)gf*a#8b$ix_bSrG$PhXgJ$8YQ2(^tB-AMRg#Sm$y z`x|gKKakxZtF|>xK&+G5+q<$f(6JKGIs3!rjEN+h8T-K4bqHDV_mmIP2O})@G-5kPgbq!(#G26Dj(QV$-3ezUyaWYiENINgWFhxr`aQ%FWUyLG9vu5P(3bywZ#^}+J0XQKZ^JJ2F7 zTi96Vi{yQilFKTWneeB-=`C@Ll_ue-I=tApi5 zKF{u+r6r#NWUuuks@vuDhh5!_Qa;+t?x-h9`2gB&l)j^iFHX1)j5vvCmp0as z+ma~aOi1?Tt0-FAIKF)1+;xfJ=*V!ms_H8oj-wpe+x&;(kWoqIWM}>1E)rZ`>ujBK zE8TPMk&|5*U_@x9o%L!u5KJO8yZtJHVPL;|U3y7uXK$%S^EF=~xg@2tw{`{ydUGH{ U@t?C-#GnqHffk5heC$jo-@Bjb+ diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt deleted file mode 100644 index a9aa16fb..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.system/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Compiled with -eosio.contracts: bf28f8bbf9ee753966c95c586906e82d72f9dfac (v1.2.1) -eosio.wasmsdk: 2c106a018f2e69d34325ef2376cf085426068e93, CORE_SYMBOL_NAME = "SYS" diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt b/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt deleted file mode 100644 index a9aa16fb..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.system/Readme.txt +++ /dev/null @@ -1,3 +0,0 @@ -Compiled with -eosio.contracts: bf28f8bbf9ee753966c95c586906e82d72f9dfac (v1.2.1) -eosio.wasmsdk: 2c106a018f2e69d34325ef2376cf085426068e93, CORE_SYMBOL_NAME = "SYS" diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi b/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi deleted file mode 100644 index 5445473a..00000000 --- a/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.abi +++ /dev/null @@ -1,626 +0,0 @@ -{ - "version": "eosio::abi/1.0", - "types": [{ - "new_type_name": "account_name", - "type": "name" - },{ - "new_type_name": "permission_name", - "type": "name" - },{ - "new_type_name": "action_name", - "type": "name" - },{ - "new_type_name": "transaction_id_type", - "type": "checksum256" - },{ - "new_type_name": "weight_type", - "type": "uint16" - }], - "____comment": "eosio.bios structs: set_account_limits, setpriv, set_global_limits, producer_key, set_producers, require_auth are provided so abi available for deserialization in future.", - "structs": [{ - "name": "permission_level", - "base": "", - "fields": [ - {"name":"actor", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "key_weight", - "base": "", - "fields": [ - {"name":"key", "type":"public_key"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "bidname", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"newname", "type":"account_name"}, - {"name":"bid", "type":"asset"} - ] - },{ - "name": "bidrefund", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"newname", "type":"account_name"} - ] - },{ - "name": "permission_level_weight", - "base": "", - "fields": [ - {"name":"permission", "type":"permission_level"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "wait_weight", - "base": "", - "fields": [ - {"name":"wait_sec", "type":"uint32"}, - {"name":"weight", "type":"weight_type"} - ] - },{ - "name": "authority", - "base": "", - "fields": [ - {"name":"threshold", "type":"uint32"}, - {"name":"keys", "type":"key_weight[]"}, - {"name":"accounts", "type":"permission_level_weight[]"}, - {"name":"waits", "type":"wait_weight[]"} - ] - },{ - "name": "newaccount", - "base": "", - "fields": [ - {"name":"creator", "type":"account_name"}, - {"name":"name", "type":"account_name"}, - {"name":"owner", "type":"authority"}, - {"name":"active", "type":"authority"} - ] - },{ - "name": "setcode", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"vmtype", "type":"uint8"}, - {"name":"vmversion", "type":"uint8"}, - {"name":"code", "type":"bytes"} - ] - },{ - "name": "setabi", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"abi", "type":"bytes"} - ] - },{ - "name": "updateauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"}, - {"name":"parent", "type":"permission_name"}, - {"name":"auth", "type":"authority"} - ] - },{ - "name": "deleteauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"permission", "type":"permission_name"} - ] - },{ - "name": "linkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"}, - {"name":"requirement", "type":"permission_name"} - ] - },{ - "name": "unlinkauth", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"code", "type":"account_name"}, - {"name":"type", "type":"action_name"} - ] - },{ - "name": "canceldelay", - "base": "", - "fields": [ - {"name":"canceling_auth", "type":"permission_level"}, - {"name":"trx_id", "type":"transaction_id_type"} - ] - },{ - "name": "onerror", - "base": "", - "fields": [ - {"name":"sender_id", "type":"uint128"}, - {"name":"sent_trx", "type":"bytes"} - ] - },{ - "name": "buyrambytes", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"bytes", "type":"uint32"} - ] - },{ - "name": "sellram", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"bytes", "type":"uint64"} - ] - },{ - "name": "buyram", - "base": "", - "fields": [ - {"name":"payer", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"quant", "type":"asset"} - ] - },{ - "name": "delegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"stake_net_quantity", "type":"asset"}, - {"name":"stake_cpu_quantity", "type":"asset"}, - {"name":"transfer", "type":"bool"} - ] - },{ - "name": "undelegatebw", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"receiver", "type":"account_name"}, - {"name":"unstake_net_quantity", "type":"asset"}, - {"name":"unstake_cpu_quantity", "type":"asset"} - ] - },{ - "name": "refund", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "delegated_bandwidth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"}, - {"name":"to", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"} - ] - },{ - "name": "user_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "total_resources", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"net_weight", "type":"asset"}, - {"name":"cpu_weight", "type":"asset"}, - {"name":"ram_bytes", "type":"uint64"} - ] - },{ - "name": "refund_request", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"request_time", "type":"time_point_sec"}, - {"name":"net_amount", "type":"asset"}, - {"name":"cpu_amount", "type":"asset"} - ] - },{ - "name": "blockchain_parameters", - "base": "", - "fields": [ - - {"name":"max_block_net_usage", "type":"uint64"}, - {"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":"uint32"}, - {"name":"max_inline_action_depth", "type":"uint16"}, - {"name":"max_authority_depth", "type":"uint16"} - ] - },{ - "name": "eosio_global_state2", - "fields": [ - {"name":"new_ram_per_block", "type":"uint16"}, - {"name":"last_ram_increase", "type":"block_timestamp_type"}, - {"name":"last_block_num", "type":"block_timestamp_type"}, - {"name":"reserved", "type":"float64"}, - {"name":"revision", "type":"uint8"} - ] - },{ - "name": "eosio_global_state", - "base": "blockchain_parameters", - "fields": [ - {"name":"max_ram_size", "type":"uint64"}, - {"name":"total_ram_bytes_reserved", "type":"uint64"}, - {"name":"total_ram_stake", "type":"int64"}, - {"name":"last_producer_schedule_update", "type":"block_timestamp_type"}, - {"name":"last_pervote_bucket_fill", "type":"uint64"}, - {"name":"pervote_bucket", "type":"int64"}, - {"name":"perblock_bucket", "type":"int64"}, - {"name":"total_unpaid_blocks", "type":"uint32"}, - {"name":"total_activated_stake", "type":"int64"}, - {"name":"thresh_activated_stake_time", "type":"uint64"}, - {"name":"last_producer_schedule_size", "type":"uint16"}, - {"name":"total_producer_vote_weight", "type":"float64"}, - {"name":"last_name_close", "type":"block_timestamp_type"} - ] - },{ - "name": "producer_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"total_votes", "type":"float64"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"is_active", "type":"bool"}, - {"name":"url", "type":"string"}, - {"name":"unpaid_blocks", "type":"uint32"}, - {"name":"last_claim_time", "type":"uint64"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "regproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"}, - {"name":"producer_key", "type":"public_key"}, - {"name":"url", "type":"string"}, - {"name":"location", "type":"uint16"} - ] - },{ - "name": "unregprod", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "setram", - "base": "", - "fields": [ - {"name":"max_ram_size", "type":"uint64"} - ] - },{ - "name": "setramrate", - "base": "", - "fields": [ - {"name":"bytes_per_block", "type":"uint16"} - ] - },{ - "name": "regproxy", - "base": "", - "fields": [ - {"name":"proxy", "type":"account_name"}, - {"name":"isproxy", "type":"bool"} - ] - },{ - "name": "voteproducer", - "base": "", - "fields": [ - {"name":"voter", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"} - ] - },{ - "name": "voter_info", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"}, - {"name":"proxy", "type":"account_name"}, - {"name":"producers", "type":"account_name[]"}, - {"name":"staked", "type":"int64"}, - {"name":"last_vote_weight", "type":"float64"}, - {"name":"proxied_vote_weight", "type":"float64"}, - {"name":"is_proxy", "type":"bool"} - ] - },{ - "name": "claimrewards", - "base": "", - "fields": [ - {"name":"owner", "type":"account_name"} - ] - },{ - "name": "setpriv", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"is_priv", "type":"int8"} - ] - },{ - "name": "rmvproducer", - "base": "", - "fields": [ - {"name":"producer", "type":"account_name"} - ] - },{ - "name": "set_account_limits", - "base": "", - "fields": [ - {"name":"account", "type":"account_name"}, - {"name":"ram_bytes", "type":"int64"}, - {"name":"net_weight", "type":"int64"}, - {"name":"cpu_weight", "type":"int64"} - ] - },{ - "name": "set_global_limits", - "base": "", - "fields": [ - {"name":"cpu_usec_per_period", "type":"int64"} - ] - },{ - "name": "producer_key", - "base": "", - "fields": [ - {"name":"producer_name", "type":"account_name"}, - {"name":"block_signing_key", "type":"public_key"} - ] - },{ - "name": "set_producers", - "base": "", - "fields": [ - {"name":"schedule", "type":"producer_key[]"} - ] - },{ - "name": "require_auth", - "base": "", - "fields": [ - {"name":"from", "type":"account_name"} - ] - },{ - "name": "setparams", - "base": "", - "fields": [ - {"name":"params", "type":"blockchain_parameters"} - ] - },{ - "name": "connector", - "base": "", - "fields": [ - {"name":"balance", "type":"asset"}, - {"name":"weight", "type":"float64"} - ] - },{ - "name": "exchange_state", - "base": "", - "fields": [ - {"name":"supply", "type":"asset"}, - {"name":"base", "type":"connector"}, - {"name":"quote", "type":"connector"} - ] - }, { - "name": "name_bid", - "base": "", - "fields": [ - {"name":"newname", "type":"account_name"}, - {"name":"high_bidder", "type":"account_name"}, - {"name":"high_bid", "type":"int64"}, - {"name":"last_bid_time", "type":"uint64"} - ] - }, { - "name": "bid_refund", - "base": "", - "fields": [ - {"name":"bidder", "type":"account_name"}, - {"name":"amount", "type":"asset"} - ] - } - ], - "actions": [{ - "name": "newaccount", - "type": "newaccount", - "ricardian_contract": "" - },{ - "name": "setcode", - "type": "setcode", - "ricardian_contract": "" - },{ - "name": "setabi", - "type": "setabi", - "ricardian_contract": "" - },{ - "name": "updateauth", - "type": "updateauth", - "ricardian_contract": "" - },{ - "name": "deleteauth", - "type": "deleteauth", - "ricardian_contract": "" - },{ - "name": "linkauth", - "type": "linkauth", - "ricardian_contract": "" - },{ - "name": "unlinkauth", - "type": "unlinkauth", - "ricardian_contract": "" - },{ - "name": "canceldelay", - "type": "canceldelay", - "ricardian_contract": "" - },{ - "name": "onerror", - "type": "onerror", - "ricardian_contract": "" - },{ - "name": "buyrambytes", - "type": "buyrambytes", - "ricardian_contract": "" - },{ - "name": "buyram", - "type": "buyram", - "ricardian_contract": "" - },{ - "name": "sellram", - "type": "sellram", - "ricardian_contract": "" - },{ - "name": "delegatebw", - "type": "delegatebw", - "ricardian_contract": "" - },{ - "name": "undelegatebw", - "type": "undelegatebw", - "ricardian_contract": "" - },{ - "name": "refund", - "type": "refund", - "ricardian_contract": "" - },{ - "name": "regproducer", - "type": "regproducer", - "ricardian_contract": "" - },{ - "name": "setram", - "type": "setram", - "ricardian_contract": "" - },{ - "name": "setramrate", - "type": "setramrate", - "ricardian_contract": "Sets the number of new bytes of ram to create per block and resyncs bancor base connector balance" - },{ - "name": "bidname", - "type": "bidname", - "ricardian_contract": "" - },{ - "name": "bidrefund", - "type": "bidrefund", - "ricardian_contract": "" - },{ - "name": "unregprod", - "type": "unregprod", - "ricardian_contract": "" - },{ - "name": "regproxy", - "type": "regproxy", - "ricardian_contract": "" - },{ - "name": "voteproducer", - "type": "voteproducer", - "ricardian_contract": "" - },{ - "name": "claimrewards", - "type": "claimrewards", - "ricardian_contract": "" - },{ - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "" - },{ - "name": "rmvproducer", - "type": "rmvproducer", - "ricardian_contract": "" - },{ - "name": "setalimits", - "type": "set_account_limits", - "ricardian_contract": "" - },{ - "name": "setglimits", - "type": "set_global_limits", - "ricardian_contract": "" - },{ - "name": "setprods", - "type": "set_producers", - "ricardian_contract": "" - },{ - "name": "reqauth", - "type": "require_auth", - "ricardian_contract": "" - },{ - "name": "setparams", - "type": "setparams", - "ricardian_contract": "" - }], - "tables": [{ - "name": "producers", - "type": "producer_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "global", - "type": "eosio_global_state", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "global2", - "type": "eosio_global_state2", - "index_type": "i64", - "key_names" : [], - "key_types" : [] - },{ - "name": "voters", - "type": "voter_info", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["account_name"] - },{ - "name": "userres", - "type": "user_resources", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "delband", - "type": "delegated_bandwidth", - "index_type": "i64", - "key_names" : ["to"], - "key_types" : ["uint64"] - },{ - "name": "rammarket", - "type": "exchange_state", - "index_type": "i64", - "key_names" : ["supply"], - "key_types" : ["uint64"] - },{ - "name": "refunds", - "type": "refund_request", - "index_type": "i64", - "key_names" : ["owner"], - "key_types" : ["uint64"] - },{ - "name": "namebids", - "type": "name_bid", - "index_type": "i64", - "key_names" : ["newname"], - "key_types" : ["account_name"] - },{ - "name": "bidrefunds", - "type": "bid_refund", - "index_type": "i64", - "key_names" : ["bidder"], - "key_types" : ["account_name"] - } - ], - "ricardian_clauses": [], - "abi_extensions": [] -} diff --git a/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm b/tests/test_contracts/old_versions/v1.2.1/eosio.system/eosio.system.wasm deleted file mode 100755 index 912604751ecfd98bb35740ae65c44fd3030a9b38..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 132041 zcmeFa54>GhRqwn0?7wI4owJfA?P-(JwKoAzDS;!DB>jVAo!h@4l0pj+@g|`OHYfd) zCTXqSwC5lZs!y>9ctfokpwQyA8u{S8Eg}X*Z$W%i{&?|S;6)#5L9VY?QBisHeSc%l zx%S%UoTNz$N=j2WYwfw_nrqH6$GeP)Qs>vKe)EM{E_{tj z4OOz=R^2+GcU)_+Rn!M!y{RT{Q&Hr9xQ6U2$?QJ8d@FzWz0dyMYTvTa=q|N|A6q_Jq58!xkM``n0nliKr>MD8^xfUt z_uO#P?yI+NzIMlTJNE90mg|Y2asBpN_FCN)R`*91se7uPj9UrZYq$RhEl;SGu^oFh zZ@v2J8*bwD(^b#_-q-KF-nHd^?1>^hS>hUIUToyi8CD(8)2;)3w)N`0J8rmsGxNE1 z^PU|)zCBv0I@#{+TetC*@|o+;80`rTf}qXZDdh*Qz2Qf*^G(;^uzTCy*FDeSeslBY?KhUcTAMdtchj|dU-$f|siE<6>o)2R zf9|>IwdGGm7V1~w{6GG)!tk?(wn`zZ@T{Ky|3Fw8@cM!U1l_lo9_Aw zdnoFwLM|M9?X@>tz4Pj8w(huo^RBJCw_dk>FZ9Xn)jPpT;~%;3;+WM|q+f{tXWU6v z#PNXtP8-DWiumbIU%h&;qPF50wP!|8U$J7vY0pdtW4iE=I`K2VCq9jvXSVqNU@#bK zHR>xS<7YPF+SB>j9>gooR_)W0WRic4IBqw2_N+Ksp|_qHr~G#gKUS=;Km3it4Q2F% z7UC6rM^*g4m~ZoMDG#2#<~d8h=b3{Q&*VQRC%E zIc>#hQLP^DidU_wr*RZFPEBXyV(xI%nT?7s{Yo4z%`01CeK+j>u_R)Wui3tJ*XGx5 z-LpN7!9gQJrZ`RNTX*fc_Q#@Mj~km`z3tkKH%H%$>ziMF{g2K>->{plGtvKN&$jaH z(YXEmI4a`K%HN3Zj4!|N1MzD%?)#PaK>We@_3>TthvMIfe=UAT{NuOBzZCy!{EFX? z|I-`dUyOfj>^DE%{GT!1__Jn;+`Fwl`}C-|Bi=bkS4Y$Jel6XQ*QVorgW7cO<-Mpg zJ*R(%KX~A?Q5NM<@klb0$7_=)*}#v($;{blG(C6di~scLb6(MNg$I+FL0!cW@8|U_ zUYAB4Do@Sy8_5R!$Bzf2naLy?G`anRyKP;f_xXCOxP}Jwv`s5{az!uB>-|>V%Q{g-h3d=lDyrEsgO7HVpObmy_=i+@Z0ac=WF-P=1GP2)J zEjH-c3kU7Vg4_Ee6Ft-@eIQ(;^GT;s^v!B&c3gc$J9BHsP8+Ae~vDv6Hy*# zFS7C@zWnunIHm_F-!CHC$kXZBb?GFRXk9u*d31hsVV>p@y&Tlmr4!t9$+@J(1Ygal z`e^vaI~yo(&G0AFpTp5iwgDiflSy|_zgRFnJI$tJ;IF%hES{b_{I0ir_||=|R`-er z{d{cfMH!Ifqqk1Ke(smveCN}zwC8l&X4E%WM3?#@0|ojtnPh|Ll49-`1qF3Et6fq2 zy8U86d7VxTT5427*_F366zfRTuK~S3cQswVi=5G2W8-8LYm;rm+bwo`M5VWITW7#) zll`%7*Cuniw$>)M+i!!>&v0AJ#RACJ0Z5@aTTOoqK1H6@fly8T&DqdG+C-Yb(*_mfBx5?UMwYz|EDrWL0i-)7^8?gvh zBmqFzrGid;eze|xB^SEOMef-~LGFThQw~(uLe?qR29f_+dk~^)M88kIN%r%X0_cEJ!scI)aF^xDfWbp;=ZG2I$>hiItu;}!@;n$*421fC+>>$q zf+XuV;6VK*NZX`^elu@OH*X&_jN1zzAZ)`V`aftD@y$RczHud>Y^rkWzJ6ozR}E>J z9%-5tq-l;Ijp0gHNU}C*=|a11KH!jX_OdfHwk;4J4~z+fCJoxa7wi~i3U#C%7*sNa zqd{Ymm;G!`RyhRU+cs!A<`5TOf`^DpmJA}u9*>TlLDTp{lP;$4maOZj8iIJ&Skj!W z-R8wHB;sU^W6tniXx~_1QXFWDFu=oo43o<(x=_k<5G)D8<3}Yr5{ZtaxE)rRnCzHl z9EoIyFwK<}Yi7hE^qAWHn!iP2*VV#gvTxAP<(8er`s<42FM&zK=cKKRBL8n2q_46y z(fW(ICg6N=CNxB+*36t8Me8Dch{6eYDTR{~%n}nZB|@>b!?ZD7vVI2|fnZ{2kB5V< zYTD}*4u3GLww~1Tj$JfPSHQRPrvGe>FBp@zMpShIV2wGUisVa*6*EO5gg>870)*#A zD=y#;Uh&*`(*<#4c$rAZ@Bv|VMH9FTsKIIA_$})uOi$egHX;b-q_I|S=c(ALp{B7q zUKZjFz$%TUCP`$t0G_7l2KRUseSnWjm@*_Wt#UFd$YvAak*b^okAdX`#9&_eKEM}i ztiWF+xXLrhL42uW^y&}1=aNb}6Hr8bI_-p)fwg4-Li`$t8as=r>+b8fA+T7CG|t;% zq;1DYHG7P$k!!$K zh=E+>F2GvTfKU*+8l1Ds&TuehDQ2zY@y@J0J^Ly^ZMdXDk1Jpb1Ow)&jQYl3)O?pd zpvJfdU`P32m3yH2x6m0X44>@_&zw>--pR(I&QByME3Dg6X*QXyS)5vJqQK1)!>Xwv z@L>Rvf-dt_H5f0{@-(*;04sU!mL~2cME`{3l~G8HQUg_B!P7? zuR&F6<*J?6q&YYJqD0i%gdgz=e@2wXMwVvpjt3*v#r$9*PK%_ewF&x~lL1-)NV|*U zWLBzN)MxV4A8;Q4OeVFRMf1hQeYRlHPiC+sa${k^F9vOmar<~*Y(3r=yT}*oD&0n_ z8ttlnYEINuu&V6p6PoQ(?z-6?d>dyws9VRF@z5L1_zN}RuPO0^3D<0Ila{~8Z2x5v zH)f3)2rvWm0Gn|!b9ijba z#qZ@S2QYL{6aIcJT)bb0oNK1wyHE5}R??nLxaCInCR^BmpX;xkfsF+|TayGt90WdT z_*>z-H8J@L-!+k3;k#bgmwZ=J#UL7%ZgG5a$;{Sb@t!oT9 zMQ+=G{VY^(-_e8^OW=>ucbIJrLhL2VIw(~hzUl^(9ou?_PDta19W4(C3RnX>(je6M zJdTtGj+BZcflQv!8Aqx?X)MBr97(ld1m09~+&BuOtKuj?cQ`6Q8b~E6rK5Jfd}gCL zo8ZrgZ|lyc(qCC~Vofr!b;qoxiMd1j7Z!_?y6a+p^EhW!Ead_0j*7Zety=M>^!s78 zb?zRCt_KAM(M-Q3$Q3{JTd8Ipiw!@H#P*Q>X_dyM$r9_!F&x?!dSj*r4mwx%+T9il zbn2+WR~A%wb+1VU+K-kr#>b;Zy=DvD%K$Y~Ip9@YdatHWG3(~OY*Ok1sK_6T2!pn@ zt99qS5GWITNv{VwWfCI&$PGNNnSG1qv|Lbg!ctW3C3*X~@l=0Ya-)~iT{Hs<2IG0e zg|(%xW@~?5mFm()WLWR|J@6?SDxYm=&pjBk2c-tumM*UG^v|#dr5f61THS+{_Mjw7 ztZ}XWDj6ICX~JRD{L;LqK4@(;SSHn4_cU@!eulem%?y_3GPyvUt8{6LV`#7_qF%)o zxSgFL)8bMv$_3RXodK|BVsb#LVHcPgEaBCDw}erej~92e<`kq9NPDctXkNDkWMq)ryBIC0KMQ!F=fC<_tXT!BXzT7^zw1UAQA z%9v_dWL-VxdI@D*#>+D196ODsJ`6yL7C0em-XL_n&FE<=bbg$lv=Ulg%1;^yjh@0! z-VNeZsv#Pg`|H`t%%SMZO%Qh8+PJ|EG^ghtw3 z(!*Ls5g$U3H2U3igN9hbr<4@37&e?*VuK(KSOqGO!QsFZ zI8YM~w6!=xggCgtRg#WpPbLj|UaG*pi&p=1h`VU_Pe*zjOUwn)m!H05EJSi4{A+y^;gq+?58>Mh*l3VV2d9P8#Jb};ITswIp$q1i=>rN|iC@}IUUy%p2 zUJU;xN^YcCbYg5gU&74Y0+o99(=~<;2AU#s$x6HePSFk6DA8x)MDv0|k&hV*lyakA zoqWhi#P*FDfL^e*OOT4Dr06xc$Qa|g%;TJNjmp~|%Opds0koW$+Uvm(agzqqXtRdw zDt6KNawdVXw1jIIUReg91;Q;%Xjuldmr}Ng2`$S2`6-lb914gf$WU4g6Or+g#zM=> z_(?mV(dGQ4iO^n&W?FuWk#%`K>4s~3&D#!#;<{uW%Su_BmGT%t>)Tn82Z1HW zIUzfo#+J!t1A7Xvon^w*M<#=&24dQdS2!^Z`}bh?M1DE^M%1!inw`NOP6a!F-4vT8m4b^etXTpELiL?$@EE14Rr$U&o4hPn^7rFKxv)^V8j!KZQOqe^)#{N zyP65gG_hq_OY~~A6zH{0XPMEV24FK9T3*Ui8VHRd+%==2J=taGT4<`&05sE@(PlY; zi}C!$GyrMUTAk7G6k|3LoYDfq6agbJI2Zh^Xx@k}T6;-PD`P-dGcPnZf)jeYx?sQ$ zYCCOBNfJwGuduu!SQ!XXM&lVF9*KZ zjhR~Rq%F_|tZgYnKsm|28hZ{1xMKUwDyU_Yk=M`G+P z#@N-oSkv2-r7MxzD`QMQf^(({$AA%9^RlPmfB?&i*_lD?bY|49CjU1dcI1p;@;b6$ zz}CcSa3|aYuwaRkM+A(@+*8;)1$wku%@eu zH-ALMNk%Bby7cR2h&nsncq>shU-;XPB(E&~UeBlTlTTlOQ{@+b4|L&ItGWQdzdZIz zkg~ZZBCM(SmD!o%(fG#Vba_(S#e1-kwUH^jHAcZEUuEwD0zP z)9c?jz5Y#o^zyOkv)+IMUQ{sthBvCDbjts$%JxB}*uC~EtVBUwbr;kHX%M9)*HpyB zw+Me>dI5{&x1$-k)qdIYu?H@CXzPbR6#eVHFM3yA|KPhWilVs-ufOv{)9)Vi z-oX$3JMtf{?nN%LP0?+${U!Qp?~qJIOQ!3yu$U#&%V!7Uw_;9V*?Vh$DRXo3%!$JWt_g{-?$I;RG%+Id|a<#FUw41rh2;t{*VKwaLS=uF@d* z@reCcn|w81Hi}Z zsnn-iw;Sfwr{}(zzF|7L0u&fifQry-fFu`JW(7)wpO`$4z`;=Y<#?^F1^Gc5ml;OF zv_Lkg8d}A+d3V@^DcJN$G*`U&9g2TTFfs?a5uJQ4F7ElgDEqkt!M+PEPrV1hn?*+= zOTdZuo*#V<&=jBJ#dxYT=c8?jJ>jzkg$V|{w}+C+8p_S)o#u7LIPAZA-1fe>0} z$mZLm1Cm%w#pmR!i~BaD26E@?-! z;6gneN642r^3Q2N96_Iam~hTRx~Gr#a}^Z819N-K%^m#mfq&Ge4q0RcTqFB_z>%zp z4j_yzn5hFVa1^Z$9|CY<1~$|W@HaeK1JL{%26O+`laLA*p%y>NvEomD&&iS{=?2Og zfD-9|97znx7RVCG3MWepX^tj65E)~o$Y_)zL)-#%YUE4yHDHvKP9?I&Xe z1LsRi+C9n1_;5Tz8V{9JEu23D@r)3|y%gk2*QNLC0SNyf*Wy7qMZ5T7h5XUs^j}H- zs^VFIriS_eJA{nzNuD_#&=sdOX_pkAP`MM#UE>H3GMOEH$8!MMa2&uh=#idMsmjy| zO_1zn&BqN^YibVB$DN`X+fzRiTSQV-RJGd8iFei54 zn)g0i=?r>$KToAnh=CjobqJm_#lu*}{h$5GPyW?QdE0s@hVfFzFb*!xFeWPeV%3mc zsK1ay$uR)#cO%DW6ki*142O({koD>I@oS%(p1AhuS;?4VC5^yJ8dX*@{$yb#cZ{-< zgCneDF3v|;i9$8U5vwYPzz%SgClXHbXoZuc$vjRXXQfjn7IG54xF{#NYd$AAV4Q^S zJW)=fV94X;B=r2aILR#~BXOaY#-{=!xqUt(QJrrKBcZ!hMgnZVI~mE_f4@{c94_iF z>c@8;BgvjDjO0i(qLUCI5LW2uBpdTlK0=IUo~=taQ4AZo1};L}16<_b?+=$FnC5KO z!g54aj><(8w6K^y@>P{r^^t3&j_{c$%0!5vIBq6F$B&DNTvjp>wLVW9*)&fXQI&5C z523eJ9s*=N55cx{P%9%DEu>sU#l5V_d~j&C&lRzD3Ps~8a>j7mnnp8D|B1B1ftsK8e6nJl+6DI?dsw~ ziwB~?CfSX*h#^UDlp&sGWt!AZEV%+p->R7f*3*pn3*kZ=biX#autbTI2Fm%9M@*Fp zu2?c=n%}C3oNt>2jE{JMbNm)C+4r%in{Byj2ouvS4Pl3)1%@zTJN(G7*ECQBZFLzd z2EKlw8En0?f|X0!p%LuZYuZJPU^1F5Y661>#%;52NdqT?$D!=(NuyUT%I2! zIBbyD?mP2G)#S%iT8M$=mWW+a3c`(tNhwfYwbP;zc3MOsDMh1*F2#LJ9KyIZ)YSDE z>F)d)-7P|P3O1W41OUaJZ9;tSHDm~Ixh)jB>)WY!e(glM+rn#>AFIcc$z=H%`hV=+ zGM8U^?YW3Z0imefG^iI^eGmvjtPVzV(ju5jSubjPnHMcCYT|$j!4o3{#EA<$u$Bf5g@#yg z1^d;R3xX@Cn4<@<6UcTEH2Zi$YQ?kN-XQKwp>@0a^+mT7uN4=DyPOqVPAiOI!hLnp zkH{{`xrB3AmW4cB6JfU2R(Srf6<)?}`RVTKN7Uh-h$Ve)6mlXd z-^YV<-OASDuIRnkn%gqUv&ry`>6!nm<)7KSyO-$5Ly=1q9s0#U{j|B;i$;@f+id!gv7I2hq<$47}ce-bim#6Fu!3I}`43>#t>m*ucX zs=C}7^*b?)jO5lZ)`TFCanF`2gz;AsZ8VF+P&6DNk?RmD7Dpho$UL#fNVJitGKn@6 zXtl_zW)w<%qK!m}Hc~~uDF1`c&cX=ALztz$6S8_=9r2o%^O)~prAP-i>Bc= zG^9iu3Rq-ppHA37?KY5GmW`urNoMLS3{P5tMb!ck7{1?HTk=yqwP~JL-S6Cnc8Ohs z*RxrhC^JRWSrdA#5>#ic41?;>0rXLs#`q-7UpNDg9aP>-LpYwj8H=I{ORnHwCCKoY z{e|S_b$GOXJgIwUlL-rDh`KY)(MYwq*5;#A@KX=WR$4@BLE~_HMqAkxO2ag4M+hRQ5c#V;bViy& z9+kn0wQF&tj7VE;yc{V5_u3%fNSQ2J@V1dM#Hn^#j+8-I^2LWTZw7;nPR{`n@@lOY z9o|P0F&Kploch#H{8rK*WArV78G;{MG;nH6fm0&Nu}a`nhZhwv)EZc90=Wyyz$qT7 zEniuIQ`Q2ZgbJME6%cdKCaSRM0;hkSU>>vLU5tu5f2iRf=&v`#IFHx~eIv81U7zBLo#o zoA8ORT1tGSHc;CyQv6~QWHB$dg@my{g~qhpW|u)zehX@|9-*hwc2PK0#->Y&X}btpkD#x_ zd=)ZQz3j>y8L3i-qSlPiatn9bG6xUSCr!+ou^UeKfW2?KZ1Tpw2j1=7GmpIJAP;i6 zY_gwr`9?8( z-QdQWSH?Q2vF494R?&Q3*C!W@m0%+cW8qlWKd!OD6~jM`Rk`pEDI=bPa$YxgnzS!X zr{b!QWoUBztx;j5jYS!0LyWWuRW&M%l(i#_v;!k0VoO|*osvERl}9krP+5%BT3|xO zNO?t!w96|U$4Iq>bJ#>+q{zKa8G#B)8r!p|DsAc|1>cuHNeDXA&F$yymc0(&jnI&Y zD=}PDjuv9{EP~X2f^wsu?ZEe%zKJBai))ktj8OlSqX@MK8)JutgwrEhE_A+jYCWE9 z!l9G}1I6-?@?RlgV(m4^u98{S_DU&D-c`l_g<%jp02BUuyl?u!cy`dd6%1fA6}g?* zLojB02-u0y_dAUpM+1Xx4*^R#vKx%i^=qXCn?;+^AJp|qA9s(5MZrDS> z-r%105DWuCDM^KbDP?{S!I(C*?FU;QE1=wyWC$onE5Hvdp66({*PKfN~-wy$YXNq;^Q@HnZc1Y zCY}h7N0)KI1!ij^JboN~hSD1OJro{K)x2vK1VQN{u}eN++oiN)B<1^xjh8|wvzm3o z0uaDwGds%mK=4?|6nH!AcU(>Jjxv8Jw~uxwrhXj4;4OTUS-yq~_U&C<2xpxW58yK! ziEPy^ow}E+KDaTrtjXTuT`LryXS#vKw$|1}bFmLp9p__1L&m{)U)+}avh|ve*;vE%q4qlyk=q!BDq-(p!W8rfZcZ7y_qxg39 zk;PE@ptgG$is`jU5KfdKOuZLPREj@Zmn2|x9O`Q$)CZ$_fcq5$5mPg=d zXwGi*_S5Bm^tWmb0HoQgNbzeW*pv}BI80xAs8OG^xu+i6?m(olh)Bm>$5gu&4ZotWr{C4 zun510_d;T0j%oIT2EKE(W;gInWiF)`O9t(XR}QT1e9*~gSyylFQf@Y8$p|2OwP?vEZ~l0C)wN#nhFNorqC5<3umfS5&|@m=4IsgD4c4+W`Yyws=6Bg! zRW)$mhLbM5&Q#HWOz{Irg@Fj$oIKh{M)oCPa90cZj0aq3gK>(Al}pF3z9%UTEI}2V zD3#5Hmr60jJt&?1kXXoQeM<<~b*pdTpyqe_>tp+LV+!g-wnV)gNoPLnGj<7VbF6nP zFWrbF<*lyh-!)Flw(Cc5N)N9LlqaM%6o@)cK+n-Jo^ljfc zt?jQUKCH!$Tfhehv&z;`>bF)G*u!OXatnziZ#0# z?uD$`UP!Q=Y>DXb%F@e9)ON1(NUfD7JuE-=sXWn2H0FXT#Aox^twfnj*FmhV+8l!nhehi*5pbq`)l0x zdSyeIZ%t+wEVS1M)?`#US(Ax$0BJ|8$u5rw%|C`U8IysSX^O|;3Pnr|+fg_y!K_NR zDFhUIXEe6)f2R_SJ)B&7-@vhSc1DLo7eW*MyafqD-X1bt3l`3Dy+^R5BpxP&;5A~p zp%bac;Ih24cG=*H@tGl|XkSuF6-`1Zd5*)!|t!NvKvSp>UW(lNeTH2xqnX zz7q;Qc#Oz{4aXgM5UlyEsz*W(u2AH`u$hs_gKs2pY^ib?rny@dIBiB9JPZ_+l7lDN zIrNO{RYo5?2;6YcUeSEpmh|I z(dq`5&M&5xQ#CkFPu627oMur+vmkG-nD zQ{SykMSaO>6;ed`G&yJq8iDz^S+LF!cG!=F1d2aI??y?cm!>1rqJ2WkT}5(P^L$cP z?u3MV2z2S5u{Dt^FV7JrKf+LM>ofMkdV@K5E<3pv z#ez3n4kxY~wOKegAxhb5<^X~4;C8NV@yjZ27jF=Az~?y!i+^s-CY>RuYBJiRu5FUu zAXd)Lkr+$jq`qeBadaYE*dB;~u-N|xT3Mul{I79e-cr&IE2L|TIFk+O2D*R-adaNg zR{ttIpxqY_z(heG;Q=V9jt9t#b2J`M6Av(yof(Yj6~_ZwIZk~wF{UPzBeGQzzrrz? z4nAHg&|+&o9D^jY%rCgs2)H&FTc|+S_$D0<3N$iG3iOyXu+E4AJ(hQ*_CBTp4K_=G zhDo77kF=whq*R-u*Crp(45wOduT99#FgDbeN%F!2)`{5@z*4rTXiVO9K^gU@4oF$KMbf}Ti0 zPf7({x;w1jB2jF)P5}!|8EckIv!uiO(lwtFmZE+y1p&f;G-5s_EO9ubM}0~SGp;tA zPl*IIrBA8hd`gX~Pl@2!M(`;qUygiA-O}nxi9(sc%5Lx}b;)GY+mFpnV;Lm=u))w- zxr)@;QCAVtPp+cl>#TPbJ(13;Yp_j{Mk*sp=sI@EVMY{OMNUQ!2LWd=yMXh8Y0hyT zOf6awtUv_d6|B4T{|&pOc^> zpA%q`eI5oHjAVQWf76)!O$3ODjpA<-G?C;OzXViNsfHSdS1A`0FY|5JmeylpE55_! zRKP9RJ(f%QbE*T6k=M|zTBRbci_elww+6v1Xp)|yhK8ItG?qI(n9j~{coGM z%JV47Y|FtgInzQOg?{N7s!WAPWufrRcF8v_WYzelXGLAdirT?j)vmCj67G#*Hh#luTXSW{9J{a6ZIWDokz`?qr2lE zXljbiCLA6w*Jo*eAwlaLI!~ayLU>>xUY{3_)t7PQD(i->MWsPU41^60J4ONrnc};= zXrv1X8|ku-3aT8EupC%o+Y%jI&YefF=n78ZnNP1MPZfHds*vlsj#@?CSxKuCRa%|o zY}LUS^li{hi=PogqCGg;m{a#{2b8Tqq;!fWF%5PmT*Hj@V}5aw7WmY8(=C(GOfkrb z6$!>JtnY|7>Zi`2FOF$_)m_;K4Xv9_?>5Tdk=m*( z-+k;?HT&RLzmk2h+C*5sSF#W42nF;!lZajrnEHu;k^YBCN+}Ze`^Z^sp<*$M8VK9R z#_e7d+Ip&sCtY*Zud~(S! zH_E^oxE5F_kF|h*Me%pa7U@VyNZ2D)DI@wAj7%O*((jVun+M4J`1%XXBXHQocw_Ep?#`e86KRCZi?mHGoGybbNBS+d>K2c)l##az@Ue&xH}V z7raNQQE0)c69wc^YA)hY5;Xg#$c~oH_uwzfwnAphXpuS+n9DS$bWrP?115BrNtb0J zGlL}3uv`&wFo-?L4KhY*_FKH=xW?49F}aVsW~&I{z{KGeez?5>f=!NpmCPS=TO6=m zF47zMG95n6#kD&C>oR`Q!bTyVrMKjv6*QFuZDZUc9!YeEiPjNRAa5 zPB7`72^(z%)6UQTcUcrq)?s;4H`$_LqVG0G zBSWIl1rTZ9CO@J}u`hp8AxkJ3;aEv=Q6tZ6oTnynIQJymEF*(So@Lq9GNeP|=;>v~ zb;mGxSqx)A#&u~iUQd^1pO2aT4ZkoafH4N%tYlnYR>`>TzDw8LQtT)K6t*M*3WIh6 z6sx!K%VDtDJo&k4q5O1woz!(FAV+0immD=z8IgW1$x&jyxR!FRDn}PnGbBfCjz(G{ ziVi%q#wL!^*hKk>p-?s%QEJr3DR!30_-jaj@`N-=u2^a4KyaCS8S(_flNs)DN>vk; zXqQ0&sfNfc!;!sEz=E1ysxkn{iAAL9gu&@?NmUKc55k0X1xwoEWzj%ml+r;oofoRd zIqFibS}XsaLiLB9%tF6LHhjZ$tZnFUBT0RIjo5=tZ!;qcoBo@gw}-9P??q> zsx6=^SZl$NsDtgi^@^1choQC};CMON)C{9~NN7ZOnLM^pouu;EiQbVls$YFs9t8&N zB=+MF&YLR2dE39OaGpl~;neFD?|o4A5vEn~#SNIm5wx7w!7@UU;Ev$X zKZ<6-0#=%Z2{J8}&@V)0CO01Wz*qk0gR|rSN`tcGl%!_1eW7|G4T{ANv{@Btcw)eH zMPJ)`NKa*#u`*Ut&XB=pH%j(G@B3t982;z14Xx?ft6XqxYdT^hj_Ylnu+z63wJ1o+ zmlOe5$l7GN-O?kLa;3`Sl|1TT3w_dhJ@GtB}segA_`%7xb-pNzwT=h-}s zF#5p#Ve=66f_1-arHj~Iz18%1?XI{2=G$G<6STXgc#9TxPlS1tF6wBSe`nJ${NtKY zV2h)OV`#rj%YVC%fXW}NDOprKk6E~+t!>cPM?jS4YNz-z5i(}m_ zY`Gp|VO#R*iv0W$7hPBR7$DlT0B9ShXURPcN0%9QB8Uf5`NcSwoTQ}Bajq^h75rs7vz^1aR!+3JFOQoURLJ3Hm-=9Z!xt4X)dym! z6T^nUn`<==f$5OWJL5{YS#xI*XUjBQuGqIw3LC>;}9^_ty-vU`L=) z!ZG&YC9y&Cr!++ji%QeMBFx}Bnz4DY&uC5H1FP|{AK7WAAu;iHvUa)%>MhW&lkXhu zI@wQD!YDx%_YYNRF#k|oJd9crj-(3#6aEYcxRHfFiS1dCAt4iR80RYp$3NJSbnqtm zJc)r)U3ne|Rxk$l0l3GQJ^~>q42t)$5-JP|Y(HciMI@-#CV45uFx~I>D3gcB{L%9m z0Shr5Xd%K}uk_q}kbB4c%rPuhilI?#pNNT^3v>+gWkj-zDXhw>E65N^^8rp`{gAj~ zB^qlY5@*dng^oUAJuS(b#FUP@*F-?l)ouvHRC5phElsfI>JRG{&$mkFSIZ8c54^^h z8=FH}!m#v`k9^C3ayv5_%c9k3gKTU!b8qn{<~cJv%>I?`mG?3NPbgDif>8 zc`RP=1SsfsizwH})LhdAK@Aow-ZClbA|U1mHMr&aU>S4ZlMSV4{T9@)EX0bZKAM4G z9)*oMRc$O2kUTwV&V^o9M1Eo^HiuAbn9|i=t7&pS8I+pRbvaaOAAoDoqK+K-vbv#QS`32opIgt zyL1ZF9an9)U+`+fK=V#B%+qdSeR~2_Dx&cOLVFPqzjL|T7 zkyQqz|$;`l3e!sP_djHg}Jj)Du^6bj{T9VdmSDpeprxa=XbHAhr1x3k8 zVfv8!r7WrJ;ug|DgyacTJn+C}UI0t3k$6H{i4e&zDrs4FxjkIUds82YNWBClua3U~ zsjHU;DSIKcHCnIgEz=?Sjy8ZLmll7kkBfElT_U3ONo_&Qc@1?(QOeekLLFRtQch8- zP(3KpOOlf=rAVEPl2ppnQ&)eNewUVik}8V1)Gb6poulb+7=$Hm<4G(lQ)=q*`2wJe%G({IN9UJYlGD{8)#jqhtY&Z!aCCMhb{sGXXG zk=nLZf!x3@k+kKaxuSUYFKcGm6RzNBB@VvTA+SH-+!<3p?JCWWkN&cXPdYsCNvs#5 zg0u+$pu-=)hm&qxZhB=(VbLmUlcmdYrG^t)c;Q0No7$m$(hX0uV}nzITyN=dM5}z) z!fAAUQS%5+=R=&%#Z3G^Om!trk4EaBtT^ogY^qK}V{fsuqnxxj?Gtu@w)4m zsqPt@e?Sa$rR3V*%C*T;TC(3M^;m0@r;IMPT3u|9^mnS!<-u0H?)T4@#~ZN>))7Z> zE)$zA*CAaoEPhL4W;IPlmy=H9V(6Z)G0XUkzWjse%eBCQDZ#5CwMxPkuLY3sYKFz$ z9Y9NT`z=obb-El?&@oJBVoW4gvE&j@x>>Yr5_V>Y%_0us`LmdxbYoVODWpemtk)EW zvshUYk-)W-s(1$_RqcWqtCXrZHJntHqA?N}3vFw?Z~CW z0GMB`QoVTpUwz_qrN9F}lmZW&%$t|5)cLC{)mz1+rNFCW_mnY(|Jwr2r@$j`4HcB< zRtG1E$A;i)thvr(t~{0lXB(xmWvVB+Y33d)w2bI2GshyWfV_e^SU?&6s=Wl738@OK zeYth5P6LxFsYfrR35!>dcX-vHn!DBZ+bfkRCT4Y0o1$2c>2v`s!#)KbQD2gW&a8|% zXJ=mnjj{5e>yqZR*uwX8*W%6(GATB}kN8vm#*$svc-7%u<#_d7p484x>=9(Fhq78b z`?Fn=LdV#Km-p$D?lHA_lKPiPH)G9HN*$TZ)dmxyixT~CQJ&sS_?FCqt?pwV44MA0 z+VhTIe(S6x=1Q+xrayDZTc$s9JwyNpTezkE&@H_Xfb2kCxiy>}yJZG$K|)AHE%N{j zED2yzT+5`Xb$6Us3l9^pFjF{nhX(S_opGEFk7ESzDIH=+Sl$CfY=9s{_UZTxn>aHb zSUw`eJ@X$%$g3J*yT;h?#o63MY_L~f?exu9 z-VVB>s^Q!ZzPY;kO{@qb->iJhWoFXHh}#fET&5M~#dXQei|-QiV)ypL#9J5Ok z)h^)z`nGq;^3)uqOC$jOBbQ`2WQ&ou`)_fuU%fc%W@QWfh;&Fpin>|5HPalaYB@sX zO!7ynavGFQCL=>@b|z;XXqr~LORh^^XQ4dFT?!u?Inj?Yk%Es$igVBdZkYY0OHu~D zD3g(Sek^=}dj;i4V^F6+5%be=%q857`!ew`TuxRuf(gZljWT`47hnf;YtypI5xd$fPxi^RS8}- z;N_D!wgfK>U>;rs3dk+n6ufG19tW?Q;Pu$FVI(0f*BDqJ34EupYJ-6#YOtaEeR*$WMHUP5JohXq!Q<*J=`6<-@t_5uY? zgj&UgFip~@!RCwF?tTw73Sj$0zVkzNT~6iM@24?hf(Y3?-X>A;IMGHb-oh{H_^asB z;w^s+pn+P0&ubdGoScogb$J5+s~+;8drmreQRM$^=P?z@CPsQ+3x?(`=VRD6u!wW= zK_B|!KYjWfxm2U#K~)1rZXa+XQx$#OMRyXQ5?bCcKgjc+KmMV8`=;mqVfCyw~jE=j&Y=xzibDs#e%9$r%)Mg&p!pyS>)6BDRPE($7+FjQ(`RtOOV!J*< zDyF4er?f|wy}5Rmk)DZZ!Ysyrq%?2L^x3%Dt0~eNo+<I|VP*B;Q8a~=v+YHpRY){Uov%NBUs4KdJa6__j2xy}h3=E-K3}oq0{kV-C~mdKI^FSX=_$+m&w1|D_n!NL zwd>D2f8Fz*KY04;XFThiv!A`@ncp*+FY7H?aq4Lkr=PKM)mcwFvr%VBXjvbz1Hcc5 z6Mu2<0)y)=1^-Q42df$f$@&WXZ-XW)x;L=jkVo;&*sUfo2DF&I!KvD@ZOC}#ptTZQ zJXJASD=pA_mQ!qZGN-MTgGLY1rj6@~P|ufN(mSt6_;npw<9K(#H@IBcJFk1bE9u9@ zc|70AHUp!h97NUT6L5GkI(x0|V8tNI+3>KL=SI;5R@CrCjhQu()knwC{*k&)tpwp@ z`T)Id(#Unhc~1&Yw@CTaj6&xXQLWE#Jis|9&f-1qJdc}kFdm{JB740d+YUhJP?G}C zu6vD?wnd0`ebM6Sk93MQm)8Nm1q6IvF~+0qz&z0Ly6##}f9s1iJi8jQ7$L*+WVkpk zGF(@5X<#cS3mfkqX{PA$Xp5)GcJapl(=+27S-P$`hliVa2#dpYu!LX#QE2hYs+HF{ zPpjl)uM;O*TZ~iXhXD%^RwlVAhU&I((1?Tj&ABJ)fOWm~-F3V{V}m85&Ap;{F3tUr ztu=H^n&hrTAc*sdVv0wv<~?I-ItFw%Zqbqa9R4vX zkLKeG(R{o(Q8X8b`%8+oeCp*M%{iM(XuiY{9l-^%3&*?p@=JR!DV{~mD-3>)KU~~< z7OR34-HjzokriD~erl$Fsu1Sc#nX8FGEu=N5H+0eCW=GkL~QixFE7sG=@0N}2kE7n z7pO`X#LNqeoX0O+j5=Oe^m+9C73w&@d!DC`3yVpfy;vCh`AF!IpX#?E<)p&eP@K)v z%Ox?;xlB@DSgfY#GR=E@WAW<_m9_FdSF8b?m7~G79i19*_D5j~Fu7*ly|nlI?(;hN zsf-|B&L0JHeE98m-}ANmW>H7|!4u~dPv;AlPz`!}p`_ny%1)IXfz3XHS{J*SfKi#w zqhW~wx!=X7t#`wZujxMfsK8xDYtu&q?&{(c9v6!NcXhFxM;j`@WllYCpI)5Fv+r9J zxV>j|S3edc2F0nof8pYgIE_aaFf%7U2WNCoKPH$?D<)_gP(u2vn0U+-Zh8Y(5`U8Q zWj#oM3L03HbR-1BEnLiXb8+t(#p$%P-XT28jp7V`id`wght}aH5?|mnl5;!7`8v&+Zh@rtlnB_^gicasz9+OQT~<8x2qF6Ae$C7!7Yd7c@L^Ni;lhFxE*AK28e~I=Weq z5I|0{Pkpx=k=~e^EiT??#`zpGk~`H=aA|2N62reei;@i+CZ>q}!d7Qyk|S_83BvpM zS5Z1?vwmJG^P&HO7E)Rh#9Bz%Gp$PP_vAaXp9}wJ%8JVG+i%DWO-{8&PP15?%7!0*1XX=S%E5@+Mt#Ib-il*_)AI6Ll6* zEXmaci+aTt3|(}3kaTZ%LX-6eNh+rtwnVs7&aMd!^BSs9NZvB#KpM2Jq?9$?t9uwt z@CXhttLWpX`Dka(K8hSgwTIwoUZ>46FtabTt{ik%VmTcv(C0flkr3UL1BE@)lD-Cg zGE>~|wB+*CQ>(JLo^Xr4NuY&t9)_h4sMGS?X~rs#_-V#hIi>)PTLv?^GI?@jNX#t% zFWq}cSo47bIDKtT@c^Eka}GI2e;5e9Rfb`RHM% za>i?-3$c91H=`KDH?D+8HvxgE`e1eoak1arxc{g6mASG4mPKc@DVgM_oRU zFbg)Z7C=#%SS-=vSD3)%Gcxxq7n@l5HoOmnH3KlCxbzvRQMY@!;xnqt&(ZLc3?KBf zJQ7|zGmW=ES z@zQ%_T;y0>5)y(~CS*&6Vp|K!93aD@G6zVQ=9A{^iFuId>bOXoSdsF}MVote7Y}Hr zS<9JW+f*)bhOQ!re6B|nHRVgex+YDCLphWyMqJb?$tk0}Avl3xT*DuBo*VSV`90Dc zmB7kf@*Hu2-k??}sb~L@TZ93${nbEScI>673yKe52mKm84Ao;{^XMDZq|b!CXQb22 zTNvqMM$o|WYQa8s@S{I~MvN*{u547(@sfH)SUAQ~xQ)hUjZ~Wm8`Xvf&^YuH$k-JZ z^6LwL9DL#rPkeYGbt$wKH;z%)cl5Zxf!3fG#$~$kl9PH|c`s+0+#w^lq4puCj1};w zfE#Y$}RGL8^Hgb3YJsUEA-6fu8%$t;#u*OY;`dp{MB;M{R14wTG3}HCdwAX8cw)fTbEu23QLhf5E}%2 z0$SPjqQYESiFpyCY`Z&D)_!`6qwGTF+WLD3D>MzIs+;j{#d}^_{EQsTT}vDn73@+-45#iJN03D}HLG~P2y@Eyw_-eUby=JRd2e7>z}K3{fP zwn9E%)Ph)tbk@ql=1ft5gTNibA)SmjZ|+A-rApzKmWOnv*4g(y81>cJ_IFNa+xx}K ztDSB1Q+Qyti0L&da486LrWp>7&s*3TlMZfSeHOg3^!n%%_g=(%;LW5vrjuVJ{WhEw zLd&ecl@=YE@^DgkYcW(#&(!;vm)Gk8<`1~v;EFC34xTgs7Thvurj8=dc)40~*+Co_ z507w%340dso?%hRdjOprZCY>}6(a45dm#_f*+tdUJR^6Sr+}x^Je_St2YTWc5AkX= z6b|&{xeN{@v(uf0yczged9>7i9$6+kUiMx-W=x05xjtxhkUiYQ!$cbx-)$MBtU36*p0OZ-}RG)Yj znG0-9DTvC~@f;Z@rGuJZ3oS6GR(2atm3`G<`g*#SN%6-=8{3aI-mJI9lIquK}cBehssbr@~r6mRvcO~Ku&XPw00)Zf>WZ4amR(&@ z%NNi8nNx}vTxva2iV`69czq9wk_uC8d@7unSnnU~WHHw?@b zE%mkR>WY^6BD=bxQ+$zKUD0x1WLH34V3a;{>HChshHez+!=hx*=U=0!X9PK9kf6Tv*$u9_9D4K#5d@a#4>WsOI zye-~CtIn8fdjiauD?U;+=HhvhG1o5g5~*D=BQrjf#$2fk@Mf(+LX*d9%v}VC4umr1 zYGW3E78-Nwk7>-6O~j13lF;T|vW8^LmB|I0$D3+t9cyB|4*{LC^wP>o$m6(uEWS1p zjBY9dl0?X(eaX19Mv+IoEs=$<%g$2%wt=8?d*os}u|N~&5#%al$ttV9MEQt89f%EM;87)rEFlJdi%qOUJlmGRZyZ+W=`#6? z;udcF^eNC->d7s_P(@6Z$jz){K)?~=*qwyGRNX2p5T&CAWdu=5kJ(ez*NLGiI07O( z_*4k}wnV}=;CPxdQmlpzbJZ1>}P!EZ#dWZ|4XMYevp<~MiTT4hs>72o5 zz1}s0d>e z_s5o~QER`DxQOm1%R5_hyW&{&MEgObk4r6IJN>96m8v}VATG|u3dIK{M^ZJR7@V-)1OhnS!vnD6k-@?*iDqf2q0abrEy5dpwrRMrX>=)vC~fUlSU7#_uW5}p~`(ek)L|83EK0$)ue=0`US&ZB?Ge4*bT zOX*^-8vQ5Ve!oA9U#|ps`qx1ccqwmvKo8U9gS60o<+*>-@A&*sBhijeFLgyM$cOWzaq)Cno}JVt6uu^86W2pE6D?qT z^ZSUj+0}S!!y?4=&?%ShfCmN4mIpjQO5&|#AQ+y}pb$Vj7iNhu0mIBVn{UZd;lA#G z2krkEc^Nw_aoBl6wqHdz7aVXzCvAftooH?B6Q$8C-tb9zn9NMZ(0Y{o@LAKf|ucz{)H&xl5t*~{=c5tCz zm`Mm#K^jBuE|cyu<@AU3uI7cV@G>s@-}{$$))$-v5ex7@51+!Kp5Hj6D8>I&Nm0t$ zhF6*_lwe0XKEYCyq8+yTF{~z3mgm=6Kv|dPS4XB`uf}tnH=O4ev$JbLDNLpI!KPeZ zZ!@rMGU%dJ{50!n+481z0eZ5y31o=J*9#U|R>D zh9S6Q7Y(zv=_rU$wetknk137ozuVc*iElU$aPxecWxx3JQyb2s&QH|h5dWstlh*iV zD%n{yUtHX0wtC7;Rx7WK)sU}!VD^2ho-R^Xs(ZD%oB>j)P{kjP<(@g(R}}g(^5(HW zWVWR0hmKu+YVp=#SjYnjurQ!#WbhUd8CSXmKN}f;I#ONMpQ2W&&R*?fR%c;y%=+`E z0$;!hK?$$Hy!x7tgxS!PcRswdMk+rd?=2Ybh!0#~y2L*1LM{CwBepKAO>~(<{LzGN zc@8^OOoQ(78Mow(Wa_gev>ZvH9)k@P8Aqt8F8ZpU(XH0Tk=zsEwTFkVJ%WEl>t^_P zRD6B-;vI3>^6fY;eZO#)hPt>k!$; z!`u6ZbqQMujj{1N+&-iV7sUD+OMp;%WcV5nAC`~#>%*sCwObqLTpGZlk=?Fk>K*BD zlxaEkgWP)H+^csa<)VUv8iP8PY{+AYYyKU6_^uCp$th0m7WW={22xqQlyen1{IhV& z!}$Axi!ds_W(G>sIV57_4p?wWfB0Rgsd)KB1Kq+!pPK{Pn_ST~;2&MXO|1&Jsdbr) z-Su{^dMbCd$~kAqt_QgahQVij$bQ>laY^=;gzur&2r_gXg@GF|C}@Vq7^@ql&Q+-N zUcx=PwD_ha{g$cVuvmZsT<3tLY^F)^Ar&PXhX3*OE<3($0K=1`-T=h19yOO+d1X;y z0wim_m=4!mzx4twyMBYfq2C`J&XKzfoBX66HL^D|JHsZ`y+t~py$6eQfDd03`G4Ae z&kkGd1;7~lIJ*@2E{%?p#oiE-cqAtj3aPE2=d zmpHQL9mO8I&@CV=@6kx;R%)SJ+QGtGJ*dBP1qbxl7OIW#2(bHQF3_uf`AXYa6+*Xq zoxG>etxg%bMG4LbxCv$d`skyNj_)HrrRR=fj};9SyU;DjBlqlw4LoAA7WI~Kfutw6 zeER)=3_~DD#_o!_!%_AUAk&Y5S0Y=Sl<7p!OHjaN7K4CnF__9k;Da25DaPffS2=ve zO_0_WE~l6IK^np*ixZHgO}Sg>v8CwHcYEb5l?ydI?mC*Umi?Tza*<_PkyEwGgsJ~E znA?}%@S9&eRfFUQ$U>~mgiIXM4>#vzG2j)q7Mr3JG_=4*ea>#kL=RZ#D#CGX^0`>| zYm?9T>qA_NhmdG#_Np`N^#vFN{4G#cHGyJJ%cG0vY0M`Mq=-v~Cx1+eGe&d7pJ0a} zE@*9{PXI-?kIe)pM$5IyCzuIZG4gQW7js3bFcVs0*?M38BU@r6ngv<{PNF-cgI{AY zmk-6@OQ-yCH(sn5b6 zfqIqExT1rS4WNzAn!c#A|mYbOrl@r=VEgw zj|ibcelEe%`(4eLZqRkP*qB$X_qpV{~C?G zIXrYCBxI#o27sLXMpoMOpp~1fwBLt(z5BT;cI>cLq^xr5*&}2KtINalQOzCf6MKI} zI}mO%(fA963<9l)(bE3NfoGN-TW^oNqlGu`l-b_=!dun=x9}F!7RmO8LYWrbne2Z{ zWS#JdE+0%!dQ_M)OmLc_CN2RfHP2=MIzPeyq}c;`+~oaTm^@)sW$v7+aAI>8-g%;P z_xF!$?tZFXbKbl}XYYA-$pS=!k7Ru_pNjcTI6)3_RJ@YW^fAm>Dfk*JQ`*3g@}jXK z)Ldkkyk6m?9Uj3SLgk7XE0GyX+>2!&TU7I!Gh>N)44ViW7?3Zua7rDRK1jkyA~%vU z6}at{m8I=u7>VX!(um#hrn$LCUgQ=|Q`I4svqXq#bh3<%wduS;J(ZGLmKqS=M5Sc8 zTs8dOCB;?q9wQ<9P`M1kKEte%+fo#A<02Xmvo2lbw<3lBr-IbA#UlmYqR3o6&9aZb zEOpJ#n*F@GGpApLmJ9N|W^av6f_c?nX+phBV+Alk^+0nTX4yqI&QUW$4uRkN}zKO8IPtcx57 z8ZsC=j22kTfWgW~PA(~*Kg%-33>cvmxuY}yab;)8Md8Jek-ZIgn(@y(R#cG+&+?2? zaz?y8JnbAl;W6ZoF@(iz8I>Wt*@iG|dr68&$zKmaMgM;1UOM6k}# zSAud37_1`P&$Y=1hPSLSY&a|`1QHe%A=1SSI8Q1739Y%+>PKThM)mn1v-8g8gG`F9 zzEx>Wnl82hze+(su}0C+tYYWGHOlC^rd+w2{eT8dgO=yeuUxe?#13?Eqtfu{wXIHI z`|1Uh?3e_kcPN$#OM=4AsJ8^@KJ7WPs@S7Xdvs)_>ao#q{piSO3wI}Q3A<9S%#|ep zYzrkqQiDK7K#P3c?-A@hMN3SFyQ|$Lr<*MO;_M%VxXvYSsC&vN<~nj6!Q8M$FwC{c z+d~0y*%o7?8bRFSSk8cJxkt5fyjptu!QcnyhaV}cpdlD!VKJ1{2=TDn52e`(cNkmb z!>!vmE7<4;;jz*Ga1A+RTwTS*ArMMjtO7w;z;_H4L;3NeVt8W|70u%AG9!@ciQ8cs=xZh1le4)hWup4D2HqW1CO&ki-l+8jOUs-(qEed0Et^!%_ zuPpx2N`l==b>95*s$=F&^dxAAhHljcR=yoHqpFEjnT(PRh+zvC6@O9W2Pf3rT{W?$ z*oLvIhVVMf29lOI`4Q1xNV*UZtZ#gfFD_#~QbpSu&cMFvt0O+u zU>X(HIcO~MDHiA$eM%o-U0%Oo_=VnGpJ4vHa*U3p zq?GEy;|VPd@rX%f?21*^TAP*^-Kyt(d5Y0}p-gtKK?e?7_3-sviWNjL)iQ%P{KxE@ z{qj@s)es0I%Ss>)G8l5K`0Dqc)pTL`O7G*dD;**wo2dp$hL9bEsa#R~ zi_vRBGNa;G-YOB2Opm`|WAPb(|47P@pM9G>$WA52O7R!=1M%W`Zb%h$QY16Mglh)P zD~f;CD5k|4B`B5b;%#qN$pr`!dG$ENsy~uEoGmYwkf9;3UVGH5*EX+S+j;fiR;5?3 z?GiGyt6n{&Rta7`C1;RVuU>lfDDm5g>cOk01ZAE5eVD6QeABadl3j^)R*M*o_5VF@ zC&w-Q@1_X<@ZZ00|GWE10#fZPx)T;5WA-R*7_)8(9W8#7iD2u0qq_CK;kN#>vaqfH zxA3|mPT2cTMjO9XT8pBv_a9fb-}_Hh`Jd;sI$~L}Pl<2&0@R}*0^X(*igIB|zAinY zg%h%!zen(by;DE=j?598+!H=2Bgsa(7vDH&uhgR})vKHH_R8#ybek<`QkobOYztoB zQWrH)R3z4qga9dPK&e)nE(8j$OCLh7mD2&?tEEQ6RM|O~c|z~96{hE0=}MrMkJ(Fl zonhIcSmK+X_;@F{kTeB-m`{@qjT%~~sphZgimvt$wR2p@XeIZ5_9s92S1;uYQc0xK zW-mnmGfEO5TjBtvMVE+G=_KDWhj7`P#a6l(Hu@K8G67azS`*z8o=h?oCa!D6gF^&B zC(%+?h;UdyXG%Vyj!ON}3Gg;Pu8bniPAh&J6u~=|y(=z0Vz&u}f2g~FMZ>GQd^iSl zY`k_MA<7D8s&89fNAsWwm~cZ(I7++T8y=hi#HI0$DY(M`yc^;C1Mz5jyp;kW+Ny`Or=ER5GDhxT>A#COL^4Sif6kc)pzIuAW2NBC96gNzzo zOa0e0Q95YeDq^1{e~&$L#q8^QdGY#RpfU;}PI(2z1o8v=x6>Oz{|>Gt)I~c`#T+5T zxl9K4-}w*k`NGF8@E>Y15Do&c;BKRmc6K+Yfklnhp_(eBfDcYcRCK4_II2=FK(_b9 z9OS?)ByzXDUV*D1IW)f58dfhE+;bKtbPhrhz1TKdfFKgEb3H@?M#U(Np8V}6EFe5t zn`nU67v%sDt+c4STz7Jrdg1}xYD^nZwH3=R`rr~-!MEp6FBn8OP;ULlwK-GkSQQ8( zphmr-D1i3DEtz^3?qPNg-9q=%HrJ8GCXi6Jib|Rn1L5h;vOupjBG&=O3>rSrpFuD} zQNTd>Kpt4v9W$Te|AiAmUfRh?O@^-7xJB$yxCRl};3Lt}Ervbzn7EL77d2c!v>B#? zCW9}Xo!(MToSr+ddRPmz#%F~Z_@`f5uOye)hw{UcDQWGDQp&K zhqQA>@*W3m8jc|2X@_}G1s6nAD-Ih6H<6{@7?87j=*j53F>RR2YXza2{5|5?KDP&x znM}-Ul2)tjTkMB1dX}3D6pux8kwt0+_2k{Z;M9}(>QzeyuH#d$Ho5UW5%o&S2$bek ztDtNV`|&TtQhhR3YER}71_SMj=3wAjx*Ku_2I%IM^gf%s`#4oto^NcmSD+uXuYQ#)C&BfA`gj=voj1Q@tyDqJE7n%5)(}(xJaPA&nbc}=M zR|m{{AE>0!QeB{gn+-w7aI>YvQI+VIG0xoMp2%V{`4X7DlW3o1P`06DMe)!xr$FvM9M>>*Ov>mBUvGeK%X#W7+pN?;894oM`$yr3Bq zEVo0Xcj=zHBGNtR#ZR`kc;15jZh-EpN zD$SM?B6LS0q*mM?FS4^=Lz9$YR0pwsP>pD6{?a@XA2RqV2ZS@lG+gEfgo4*y@P+WY z&^M?p)+;P64Jnh*20(NTW)c7(RdyW_xE>*K=Ti2_|KHyEz}Zz*_x_%9@64TD zqP3K&z)(@qisIj*qA&gPQBa?vwMx;F_x-KC_qpfZxiew(gDtH==bp3A-fQo@_S$Q$ zz4qE`L(C>WG7WKke1RWAqx8l{mAg8!c;V9AC@cnPl8W0poSDdusDTs(CoqM&K*nxW z)op~(V_KVMYs%IsI}uzw)0r}YK_BEw5OcgV_FbK|E&)aj(N`TRLJG%Nl)UF?PI&$p zO`12=vwf37MU}hbST|wDh`RLD6l;FLes^Vk5CTx(7~&80rIDfN-arLN7Vh8C{QC;G;%$fbpLDGrtI zNobOoLA;Jm_g_{ko=qP_hXH(#-7;^L%m8K$8m8oBuj)>0en;bKJ(D^xBknOQx% z2=iE(QP+ID&E$opY`#3uVeeu4tLc$Zm30R|1P)N z(<_T67OB$i^cbI{jZr0aH98%bCqNb1=1)GKeu;A48X zv|28WjTcLMdM*ufx}_bTOXEzVrJbBhGovhZJU^EfxzjeP`qV3L2pe1Afpx$M=E2O` zwy4!^372G-xqvp5@EX}N3U6PAB`L}mxyYpeHR35k)B6M~J(0;Po5nsZqqIRGrc3EU z_0kxI!4y_4fafzGaV6KR^#MuT(pcIkYq7`nC23kK!#m0qVhA=ahl54 zBSoelDupglP#B|H6zsq!7rLOQ8t!BGSE2-9=l2%$o=ebqFpyu28W5f5LJH`kYY(!L zPToK?PDI?p#a$z{2+|@PCrs2glt$>1ak-{B*hM0zbiRsxpl;AHSSZq4?Cc$^&T5rS zJ(v8S8?af+`asA!J|`9Vx~hH}M*TRoQ+!|b*z}FpYr#uh)#K7@?HNOP^#@E4`uZhZ z76IFMGCALBGO;(Kd4SxL>X5oEN@@RodqSIx3~xdnnM=$e)^;77?=BmD`lQ%4?jB`# zec>dn5rEL#E;7duA$iSITt?gICC;$U}xtMXbL&6$b zIu2YyK-e)6?KNV?E#gXRjp5>Cso~3arTvTl9#>u4DllSpXr!zErp1R1jAEWBDuawb zA{I{B9R1U}>6(R*3%n&=K;cy6hOt&t)Cd4_$!+Quor`*>W@EgsWV5lRy9{XY+N2Ov zQQObUwlOWPH3=mQhBRbZP5*`4mm)v3>;j7zcmKXg{YSD zi3`ed#?u(kk2jtrH=Z(hA9g%TZaj5x2>S+>@uutYK^*H_7$FF@3s#E$^euEp5;tjY=ar&OGew<+T zmP zZ8r=bTGz?d&?T7xT}kq)UC&KsE*_{%JXjG_yc-!|{0UxT$+F3nRis;bWS1+f7U}S7 zH#U<&Hp0|#e+g}`P{8^^3!EtF9pS!NnhP&S)b3#YcmY?7=&6GzUq_Uludt`*H{RKZ zDu%XC2!FP&k#@_M6?9I`&`}pY%2`XAr>P<8>~ya1#i}wZ%okxsg=JUgM>-98QyN#NUqz@+vBI{<(YfS+uSi&cj0W3jl>Ue_i&O8`Q&-^H3%Vuk=cdlbDg9KrebAKw@K35^z z=d$-^Po8pmvo_h-i0{g7b|3_pD8~HnoLS&8vJxF!#j9JFC6wefQ1XrhI>D^Q%4+~eh!(Gh|Io&o z*F#fdIXKM3$|td2HVx7l+0SM)vB#gWsa-}nfQeW1l@$Vde!N{jVmmxfxTH~$*^>sh;*TiHm~7D=vYui0MyFlR zM~k%SIg4fvTkYu`koqFGGzc5IrGW*UisGr!(|SuouUNe7WxaMwgO+-5kHjJGXk9f7 zd<;c$)SxgnAel;RD)XbJ7UiNL_*$81VUD_wg9dj1bm6gx$*O0azQCd7pwVLv8U;xT zY+H^UO4C%!)G^kVI9UKgWZ;mI;Q_MXHjh(Czek2?w+COe3uVaP1LwlQrN^U3MtNf@ zjyfR7Ik6eYj3p(eF>`XjsPT;AcDa3!)N9AhB>{>eB))Jp1kMiKB3197QIz)x4Vc3- zpG?t(DF%?(M2Hs5nE$=l+r+Z<_iO(|juK)0{Q>vJ+Pua( zj%sC8fTDe?&;UKT19#rkp(=Bx4(5rVNx&S9 zf}~otl&&U~@09UQjxVtTG!Ns^jufV-iB}9E9Q@@i-XsG*?MKGS`tP1**&Far+B)!$ zv)Wq-&$H}4WY5~5$X;d}5KR{3z}kBQw!LN*$jqXD5_@e`9X>79 zL3@o@8efq<6yBI^=5d?`uGfaVat}PGlAxUjXw#b zOHUemYx03mj~OYV@D;poH8vX~AQOn9&rV2MM%7oOH>p{A>yn||dt|$vwxZ-AUi}V% zwgGIIgHxLX0i8x0Fh)oy^A}-bN3yuH`Wu+su>rdLj|D3?pi^UwbWNnzk z3JSvVuOFq7!IK+DXOlaA2=_o1Q@*}pmFgAw;)&REitf93~fMovho@Nx6 zF!N~#I~In)c_o#VPm+nB3j)`|*M>Q1SXm!mAXBIN>^&KsK(me*%@m1QUHwgsU_Nid zC4-rSG}}}#Z+mjBHSVvr0hpGF6Y1!OW4ebMYPho>Y8SA@c2OB{23URJv*)>N?_zBE zP|iMG^>?j_ys>yL%5gD^s%?(r+M!Svht$ZB#%3J1tXYUEr!662Ww6UQF4QQF+lf+a zd%>_P#VZm?tEfsD$E6-Dw{WZUTRD!)DoO~kU_lfsLjAlOAlE;!Kj925!ETAsT*#d_ z?i9zBl0+86hd8db_cLWdu3|NZMPb_(QU1g!UxZ)dxU!55c8lZc$wUvma7#a`v=EjK z*{JL}j%&*im;GVCohz|T z(}Osaz`3iZZYnQOx8sebJiqJFuYCP&_%ed&O@!c97xHTgW3%QjBM$KiaR}qDNt6(| zsn7;)3sf8LTL?>2s9wc!J~z*n`!|VM4c&O_yB>Pr3!8ooLelH?&V}(j$j4p}eEVZJ z{@~nS(;exXzJ1d@pLp;~H(mSN=k+;%$2s@)6@5K?ot?e;^MCM$H{W>PIeoTYjJKk= z5j#S2{ECCjal@C^Shj_6OLSB(3|N&M`u6)D{rtz@x9`_{rGNeXx4rQ?HA$69{`}Ps zKL3SHq0-yj*HG!~AK&|p&wgRkIekw7F7)=#GGwqcKB&E1Dm@5WJ;N$xbyIyewLZma z{lVKm`{{S=|IA&5P|XiN^_~yj_^FQ-d_9kZ@4liN{{A06_s;jd{cbKbmdZ{|4~S91 zeDCL1HQf*6Ls?b-P(-Wmp{ljMgNJT5dN|K|#Na>pp8q%hncv?R`tWa`z47vEAGnTp zg{#jMwBY4nPb&#s=aaEyiSO1c#j&wzDa>MB$&0l}ht#5k6 zO%I*>iasnXZiH@o-*?VEr|$>{_bM8mvP*X*zv{x3j8I}dAa1Zm=m_7ShusKyI1l{Z zr>}YR^I!S^4aOp34Sw6deE3rg!Wst`H=bgO0y^ghVU9t#(zW+W+WS{PUgIFoIeKdV zntkYjublRZz7>Ld@TTv-R(72Gn;+8*vLz$MNQiMaGtZw2f?z@VFf9uOFv zfA81-?tL`4Uw~Z)Ah~n;Ry)Y}CP9`s!g|QFKxQ!_&^Q!T{~FM%1^VGI2RtMozy6_* zfArLI`c^qWcMA|4Xx;;w2hetd^B_&U4LGYp6K@q+H{j57(eX+L=X-*~a_?ae=V9QS zVsK8`QT-dhtaM<0qjBe3&im=)`^mY&=e%6CyeD52l@zEIgv=> zNe-I`e#>~3GOmRK_>5PQan8ZiI$DEn(f2_7_tbklsUP;ef0*9i=CZP$uii~oZ2=o= z6x5?&jUMX#Kt0>4XTebY5IIeN0rV}(xz2n5txszHDg{m5v z9_*A_g_--+kwqfV`c&(ylG{rz46?YcnxVXa?C(ftOD{vV>9Q%VGw7%ueH1p+H?+A+ zBynF^wV`4}GtTO&>x`u3OCw6$8k?4**RL!T5_EtxsywFil$=n$n!{siicTr#nZ@Ty>5-w1^LnO9{-X(J0JlfVLSZow9#+JV>n{#dredIWWA;vblofq5LT$AV`W6&ygMvtHN=uHEx$Cq-@j3-+lyV9AtY@ ze6*qW{U^u8yV7bNJq#e{X|&=p+R0(4l{m~!1~LspLKKJZmOvE73P`qNWl5+?9F=^i zR4g+wY#}tK7~Jh<{7=U6jt@2^9Oa!ATFdnC6mG9l_{EThRT`wyN-+vGmNzi1H%t-o zntYMtnispDJsIzu6&p46Q4v#l)HxutYw=gAf?|t;+h%Smvlqi6!$e~*z>HxGg@hD$ z^7*|Fe~N(t5(=AAW&9y^eU@q?B1vf^tV`o)0e_L%uZjo7e_y012-*{n!V5eFdGK9U z0*mKzQ$iIk*_0qk3kj;`Y$?!T3W1;$U}6&B2GVkS|-isso);Pjnv5mXnUTjOXsQN$chaiyLzODO~QyG zQ7zWSVg%1JePGNThL|N>YMNlZuK2e60%xHr}97?Gg z*+Gybnx({0sV^rkrOaOkr!516{L#%O=g;li+RisXD29b^^h{hS=S9 zZ0Mk@Y6$3${U=pB4vz7gUu0##+ifexg#Bs}f{O$NA=7tremZ387S5@-D_ zbTwq{!)^E^vUb+gjb{`u&>BCREsLVhHj@RosKa7B(4-pv20|svWB0|?tuNi~i}7t7 zvn(5hU9#Ffp~7>%4YQF7u-GmtFM`lz)S+po*pSk(vP*Sg|FQY^`{GizDtf~7WU&dh z3+1-fSQ@CKnSz{K8XRNE_%s-iN*6hXbB;AGd8_8eT*L}gDbPA{<8F#YMzO}H^HPG# zi;jRD?N1LyyMPNex`hp|3IBIpEWv@_8As+xHZPqGdxvhTMdjvb37SESlu0CuOjIdO zm82G%Sx$#8IB{i0k3vw`ywRiJ6*e4V8v6VKiIqf&G#zA-q}544Zcqwj<1S`eu!z(b zD8NyQJb)E}PlAj;(%P%{n&Big(;H4~xGg77$2&o2WvZW`f9~o`<4;)oP>Zw(ap5}} zLhHLvtSLdWB|}ku(zKm1jm4z95+-AeEgU_GHB*ekv8G;fdUR@fgt_50n$HwVTvcnw z%Y3ZRCyL3hcT662a3Pa-Jkyx`e1n|_-Y=d2!_RYhoQfu(DtN*f#_!Q>9S+uu%b!p< z-?SLdc^k~$bAKJdFs3U2aCl>_;=0E79}l;O&x+L*(*-y>YbW16PKo;%hGc9*kajxmzSL-uQldzLTA=4Cp$P=PIml%mXjTg zWjWc2Be0z8OqJziKYn@HnPJNUfA=!;qmV5NK2AJ`&!1_#kywGtZyImGKeteEF8`<7 z=Qo=K2T8jDnD zh4=$AXl|l8@+!@nC+#~km{wN4{3PmR4bhCJi}f(axU75aaZ>qKu_KtLOxZ!@Wyi-H zV_}-|k43?@ALs9!8JL=FN%*Tc2aV#!q}0}$RFXBxY;QSh5?(#2!jE*|AciRje@SOe zVmB`MZa1Ry7zCYuz?wu6S(9{6S=m{WbON^lBAi}h|FN9i0J1)392zxo=m%15Lxo*3mEe*ePv3kwVB)l_1H=VXK|(*sO|SE`xGU|Ytiakdr=qxsSr@o+ z;&WT0NDowElH978fTi~A>mn7G^7I6AVN~-m)?&;1qPrQONlaz3PC<{H;Bdwu|7r((+%*p-iL{ zXQN(z0s6pT#A%VEU~-u^*Ll1r<-N^?xI*4wk@l-UJOj3&_EL@{CmB7SSzq}vEmNRo zftdkSxh6KxZxbZm4HR;b1Oa8@PdeC5C$)xf7ogI#0jrT7Qo{L{tDBvvJjCcHy`&C& z8gK^YvOsk~>2{Jg zIdrg7*cp_%el~>KJy-r9jvT*cARL1XJdLlJ6;cmg1(+C;SjFxFjsutq-OG}7NN}hO zMpZ!pBKYtK3%b(GqJV&aN~F_nT}12F5p&zomC#UQI+6DZ@lzfFG@Jh;ivptJ^{@(m z?Vanlt_gByA*@r!{+H?0a}7CWy*NpoS^~kI1Z<@I1sfV9)9yfT8XJa7j}OCa9I!Gs zWjbKEP&wf4t;y?pC`-X;T0F}~;E|3c{ZlHK)3~H?qCJ}ZhZXBc8nx!7dAaNaO=!yA z3Yz_n7U;&lZGzZI${Wx)>AWTgm$#mSYFVB}C1Ei#`NG1AOy`Bw7qXUEBOyhm*NVo@ z8wt!di3ip*HqpSS-E5V#FRdMzY~L<2c%RjV{7Wy7i5E`2<@#5{MsJ}!0F#FU@tPI4_=$rNv3@s(pM%xBtV>lU!q?|g;x z?J`%YM!P!gJXMCRF4_e#O25WQEG$&)g6C}Uq{W9Fxe_uPk!;mpmKmZ550q>+1UjD8 zHm~0S%d%^{1O!XS{p;Lg$biKWGkGCp=)2sZ&knLKM4!#RX7s_1 z!JEc2W5=~}^LT1~xR6+uMxHEO0eP%upiO|(>=Gv7EIThOxQ)pq64t3=h{>iCXHt1% z<~wZ2&DO9WmrD3H;4JRx0xWzkT7rmR%*`mU1*NTpp8yKV&DDSgPf{bb&R+=}C+j#O zMpWZEZmvF>Ieu>J|4%r$jhSI_WSVD2pq$4uGZxL;Iy2lv(#+7b6pPQ%|EpaL)kRo* zwjCWA1-KdNSv)heiDx(RLa&QvXU#+in!G&);-Ua#+hkHu$fd! zW>P81q=Hf)lZuQj-nzsB^fW?D4p7$SjZ9J)Zc0pBn}C^h2_8XYQ_U9Rv3}-+x(Fx_ zw$kT0f#}-TuuO>s8eBU(-@>Fd^;qScQ0Pw!FL`0%6u44^-3iN7UYpPDB5FU#w0IM7 ze*1)p&G9h5LcuDO!>;ys+N=PY^Jg|M-8|;=FEDzAnNlR&ox8_f-Y{~5kSS+v50Xwl3PLZe=?5@=ufp) z#S_t*9Rb0?%8FMjE-Ss37Lr4K$tqW^At)^(jKl1LL7KtmSK(-F%U3;wZu~fFt6c3d z9Q;yWNv&=z?>i)=)xZ=Tf-J06DC$lM$1XrM!bSHexWErF8ncP|EB<3ll~z*i)&e6$s@EI?C0euiCzsvb;D&uJXQAwL(^+Oo!y|#huokhJh+pmvznZ#I zAc2T|4eoApf@dezDqoDuRGXLCQb8GHR4(|7LC&+7l2dd_QV-!i=d@LH&{8wqa8X%p zj7W-(tAhoQ5uIr%c>vY{GiS^H)NzQiDS8<@6M3Si9%n2j6IruvjPrdH`i)F$@In`% zdEL$GrTQ$xG?T@%xgu=taGkZjv9icIyQsEl*4Lobxp8f2N3FcBW+6&M@wk+PA?;vD zn`E^KD^@l1IVlsWN25w4IE`>oqneXQf1@KT*?}byzGjQF!ojVp8fIh}2=EqR2$JfF zs5%12md4fv79=*v*`*=xa!Y0=JLIYbX;}->BHwMQ9u0uv2+;h(bi`^nT00XW?*Nau z&CT!-WgW&s3s;i`b6) z2n_lz!2stoMc4E@M?RHrL`!YfXElkQU}D+K!j@zpt-bI(nw=L_jV7v~hPX}H!xfS% zXH$jFsRr7!NP(?&$QP(7ySl78s6W|J{W8ZWuPXY^mTE9xpwPO!oU{Z7#kMrmOQ*3| z_WbsTW9yWEyxC=DT1IxZXqS^6Yx;7s;|;T%>?bWR`zdX++i-}$#re2-weqL&PvBCO zQ*IVf9h+RLa@iROu|YR(4aIb^?7`{DO*CJ$#WN-coq<>mbOxeLcA={9GyK5bo-q96 zl<7b}E#{)d2;xahKY^W#?NPHVoY@o4>K|wJ^{v_6 z{JK?oll*ksxHaJ|<6ME<&wBTBlBBYf3tOYH(urT>KAb^f@Y~jX-I!RyUSJ{H1SIBn zLHk*z0ibVmwA}#gP!>5vbu>9dvD1b6qIhAZq?EG_z)ol9$!!1{1cf`WO*3gVwKC22 zn`T=0Hb4Z2D6NOWewlV-&o}vy6sljvAZF_g$F+Y8zI18HIlz0{7sQ071w}PU(l%Ue znQMO=B&ZbY+`Un)Z7s<4cIB`Ew#Ea~^FGVNLLJ`7>wG=KLCuY|Zh_n8m*|S@)mX z)5YOmHH&3Eo*GG{)t*@a*+o){mV@jV1P2bCjXHEFGEzq|Wi3aZ^fA&33jNH&J&p1A zkUmZ5XAb>oA@7|(pjLT&Xn`O1@=|0m!y|J_SF0Aaj<*F)tOb1RmR`8JNMCk-BHA7v z?BxFzdcj4GuJ&k2VSu$#klHN2n8U;NU|Cm*H^>TON~cs}))(=}V8m>Wo!^PhKe}BE zKHKFn&Q}jpgp32ylx3bMXyGB#h=us7e0M2ZD`@-anp*o6vR&-(r zfzKOC{3#~CsLjmvHd-zuT5e5uUB#S+R``o+IMoavVkUv)j_Nmj+%Mgupq&E_8gMr3 zH$-uGbPaa1fTEQgqEu2RNtEu;U0q4(SrLAc{4w$jnR9sz7V9_|rtCCEOza2r0GXdk zmc{{g?x}$T)%vnDBD<|1ji3H34HGJ!m$Ia;%+lz(A|~;(+NbFTT0jl>*M44s5+JYS z6#xO~YF;TD;E8q9v;Yd5y;{9Ge+jS$yE0joRZz`pUg4hxl3xELB-VO#+FrqR*$<+a!+tD;4k)OLd1fd^Uin;1c-@pvV#7K^Xqgylih*cG)K_bF z&WXv;o1QEUw1_N(?<`HYAx-$s(u5$=_z7JT7pScyji1nQKV|`0ez*c;KT-jxAEW@! z(?9^_5xpuS6c+Gctkt=Vuz=z z4$YA;xW=KGP4W!Q1447;(d;r|uAmrb2JacFz^|CrLNv>u(TZjZp&u|}yF&dYm0QuQ z6>$#DHez845z$P86|hchLXA_P_Em0(bSa^b*TXAKJ0djK(KAuod;&b$KXqql9>~zV zIzuz0>hlQ|wbdX8RILU&ZxExQ8PQ{CcG$&?NRe8XE_&%mG52JsT_e;M9BQ%TkqexH zY+r*oKWz>umaPv=hVJ+AO7}y5`+24Np}#A61$CjnT+;1<4kQ8X-ASOqBeE&X1v@^U zCq&58Cm?0~)2a+Z)eJ)`G7R-*7%BwPlg~&ZRLQ6guJmJGy(V*wk(Mg&=;ao@_>w-y zo6T8Y`l+;5BhnliC1)KMaFl5{JQK-BUdK1YAyBCipZMwv@!}Ik#b*w7kj?WN6NkD1 zqJjK?ZDW6=YXrCf#)zmS{L942Pe8Qs)E?3pi$EI2SbIrhK*Ibq?&>@MGM>wY2Lcs_ zK^zGv0kW7800L0)Ax1R7lP*Kk0wX{J7nw7Qd|RPG|J0X_cqO9(?o;w#xxLyyi4X_r zvEk}e(1jJ9pEPocjRG>0LguE4Z+OD;sm6qs8=iVdqjRD8hNoWA=waxC;fc!`)y=FU z>ZA@U^Aq@;XVsyho=XRo=^1q31D-dBc_AFrv^Bny9#3m@tB;Lo15X3ld{~`fY*mIa zuHf_~#0#Yx=J3=Bp4!nV2Eobe=un(@;eGwg!tE)zN}4Fo8f61n+WMNXhDbXt@I z)h{Ql; zAUlZ~P#GYL*m4B8l2^(Gcv46il|YJ~epa@@Q#Hd$e}?`Q8FskRJm5+6vx<2pLee~o zl2wj=jCTc@EC!a*50+yxC#x*>!^``$SqZeJiP({iYIio~J=uU&veEC&hEwwhv}j1g zJG?v%gW#uCK$^rWXbDKuECVgsNCft?a9XX%(9)Nor7@Yf)5TYB@>B!^`7pPd<*CT0 zk`kAQMOx+EU8cqNdo8{r)8b3juVc^**^!z1E0=X5os+JZHzeTlF0R2|gQa*D}plZqXr-pe|hH(}> z9{0;qEv0v(S}K0kN$pfiuy1H*<^aBC%O%qrO@}uJZQU%;DILBGSk1~M@n(&*jlufn zc|Tst&^e1WC+p*ZN!i)9jAoD6*f7KTGQK`l}j=kazzGWuT0<| zZM87iX{TIz3_(P`Anr2$X<5ppNgH`wHk3;t z2TZtKRX@XvmCtl{$SkXfP-V|HipPS){C`Q56h_ihcGgO12i77mTw2jtDiz9|9q6f1 zdWO@z*`+mVy@C;QG$32Kklp&3pRr8y0x;#)SL_@wqa9l$?K6? z7FV(lz4jrCn^%?~v=0~yptCH@p1En+hZXiAi^@l9y9V(UC9_4(u>e>Ck0Plyn5AN+ zB8}-8CWi*%o?&h%R`#6q>!%F=Fxqxnf*T74Q}+fWU4sKf8y>87g=BzMf?iYOYR0@v zx(dhH6OPDm#OlmNN3ySgtsU`lg$UOufvK1=WGzxk=h*%~!VwA~iAgw^g{|P`dP~7u z$s@0n5@MS?m@u=HSxdnPnxzmekUaCb6bK;+GiE^4Gmu`r&$+$HM##9@jrGnQ-Az0> z5^*h<1Q2HBz^-D@oAC{eQDeCVf|H;F_Lvogz;=*acZ&H8s_X)3_(PP1JIK&{JjAvY ze8^%?n*`KnXp{s`X(DS|&9KBS_=8{n>;L2t-IG{P&;USnp4*yLV z#bL_gVmk#y}&Etu1rK6lgSVD)A{mse9fq8C`rjx&Am zAa5y`Ra{3k(~dDC$rO0J@<)dBy)RuS>cnnoEX{+B-7f}oE{93tm#)K&>7A-jnp0Q0 zRu?JOx?OZLwXMfFyO83qT0(8*1ujT=k9e(gq0)@Yh`I3YIgHxKT^zcLM#Jy#<)e6@ zMJq012;lUE7+ji9FeENgjA6C9=t(~ehPjF9gP_4~tT90Z88qn)0h$^kogsU-#<**a z5`Q99__vUpk-Mc(%7wqGh}vjJw?@b8@yK2->=>25QGZ1{1aB^78y|^XN640kj>*{0 z2i4F_)FIr8WT^lLI};A8sz;=XSAv~UW_e_m@^Zo?;KCQ**zOk0!Wo({i=D@i>KGG8 zx_vo&G89U60*lPF@(JFfG0UY83D!KT#TT_8M^@DBT)2Y;<~3I_9uw-2;m;r+zMzh{ zrrYTyB9xQcDV+wN3@oaI@3!l>2PIm96=q{7TH-w$LvrOjy$@gjfhw}wHt(sCTGUm4TR&D4g--aJ06l=%QSy z49jGt)z0V6t;r&z_Cz!{ zt_~fm}a}=#O>1^Dw*351&Q{qatn8#&3{=l^6@(P91L5k&0C($QJivH zr06q-gC*hTwrr(eSbJKwc$px|sGn~BTY;GHtn{ERxy)&5CF zoegpJuPx#%_)dr{(1Tg!E-7v@UkjffnYOI_$h0N%w|WF3(^^m1HnZQB_Ot3<5`Js@ zk!j1yk4#%Ke{1^{Omaza+|qtz+LG{F+mB3JGJn(pADPyAz<-U0!xv zT$j^!ZW&ol_W8q1^;X0a-f~&+G0rV3KjAHx%pbLo8Rozxr&eoz!dtfFcT?rt3p9zA zik4DGTam_nw{oAuIA9lA8V>EZQzovAV?_$^_gl#dpIE@>!pVg~_2<(! zUmsO<&7-rj7x7%ap~lL&pKL^RbD^?g7n9&PauqjKeTGFouU-0cvh?TmOMgCT>CdNR zpS64qt(GaHiV3#zV6@aZsjzaRkJ+ltpUTb7NtG~)$@0{6PU`U#uRNj?@bM)I;VNfZ3W9-JaiKrEOha;3SG>fctR7femI(5R+qhp=52i1`6O65pLQSQvnZc-cRsf!pY~3CdksiCpLT6P=Y85aoXp^~ML*_^h2thW z3APR4t~0lqG>ge{vdeI`5V~;`wa7WvAB|)E)kR`cWphpA17h6>a_SuW7f^By!9z6z zYiH4AQ#Y_GXf|amlWhuG4;CqF6xzNJ{b*CjdCyykVyfxo#vXxBh}=u#iFc}U!3 z3!6YKt`9mdqEHCfY(YfQxegqJW7#=K>dvE4wo5`Iz=90(LbK}%2;D8L?y42pwK8z* z6d39|(jGf6Q8=N1rCeEb>zVPw^pahi=NM!&mT&?IB~9o69|#H-P^M3m*iF11?S!$J zoDEn>m&0mZtV`c%iHeLcN{p2BlIrCY&_GI1GJqn;Fj_KUXTzn=&@e@wpiK?JP*EFW zsP;-l7>qZjW2!= zdbFpPR?O7zMvmL!lWq;3cAH#W4egmgZlZD9X~0&`hLVN9Q5s}}wO(g$49E7B7;6+_ z4~>kzXq5J7`0RSS#JY)2z&=SJ55zFrGGe-dU_mh4UfFl!sNC2NiHtZiRM2|EqG(~T z$f%dJ%`Tb87dO&wSB-P^AFh%%Dd~xu0gCSdMgm7so81r?@%i~(`K-91 zqqrR1)%Xm10v%v7?MZmu%{eWRXCS505*NOyF^%1 zvjn~j!4{Y$n?*t^42B^yjwcXCneFBeY%Ir#{7lLvdQQ()*ea&o?VGd-X8#J8-C6l$ zwKKX{QJ59ctn1>_3-<5f4OUxpJDRK34MYIqUwN0fC80JRR~{zi8*1I6 za`w#T4;2*z*+`Z9KwP;V`%u;{d^b^gxCv4j%P$ru(4jV-^^JK3XLawyTNeJJIrGXk zcpm1yvlxnaP?QJsYoR%0p}kt|#@f??-GjXbYWDZo(u-1^P5aBPq<5rN*+s&xIV_ekD7#P)1TX&|hg3jjju&L3Kg9jh6Wk zAjn+3D$X)Lydf#PRkU6G-B@F}*nf$J4S#{i8aq2%n)D+B_8Y{|M|EJmh}RLqC`u}7 zYEsx=qhr*PWlZ9?ijC1UNhT{(NpPGNOwa;Sq9neKEP?|LLcu!+`#|HXW@lepV!vMz zec;jodiVkwHJ_Dl{(9S{)qSFO9xA@HFAjkA`3FNYtpEc(9E)_BlD^a5GE=znMgRN@ zmmFw3k^1ZZ^2pyFGxlfEfyR^TgpnT1lWJAh2GMA!YvV5-sKvM24CqN;Y77|KK|)$i z^bA8}aS}$?lMc*?xxZ?U&ct-4uYLE5Gr?eI`sg=Lq`$Dc4*J}_4}w-MaHjdMrLi|Ne=`xmtDZ_DxxP z58!`{v#09fNI_`!{9Lk{R?OAnd|rJ$*!_`jZJ=>r8JnS z-+rX>u5(W_BpmQ9Jjk@pntR`!2TniF{;Avh51jtkrO&Jb;Lg_0QtRLfG1Fp(fPPg{ zRa>G1NkoId#au0-8SwlY+$npB?M}QVMkQIc;Z)$Y+NJvpZ@I^Jo?xsr7?;x7=1_Y z&~GIW3qZt5-G4^<^hpDK-`nn(9R7uEryV%`J0qX|P@7i`JkEahH(M9-bX1>w>CbZ??z5|0aAwASD(G{haPH>NA zdPqy6LuHU0HRrU*ZeaT?NGE`}py)u{HgT4L_@jP-xO9)8?KvwC!g6X|zy+T0-AMB- zNXq>p<>f>rAL{jVgkj4ihSTCG!mVYw<-(Vkl@u2S@Bqb?naW9 z(h*6HV!8&lja5tKK(>+XE>HC2mR1X;Dm~eyY%E)`^sz=GKd7L{AeZ;x>om<*2?O*} zlSl~@rs>cw>JnVEjea4nfZ+X#iXOkS=JXMTdk8WR6%q`Ena5| zB2AmF5r9njF2V1KkYwr8P~Ue=qFh>Om_93W>(XQ`&iG700u%M~?W?RcsK zf;+K#%~C3qOeF9?ox)u^u)bjI3Lc#=h>bQYSZyf?AgzzAUsSj*Uk(nEl_O|EQ-#3E zmpdw7PGMw2Ly4BzR1P@#a!<*Zi*w~z5;T!Tn%oy9c|)j%N4RCQJ{ExDzHScTU|~%8bXvBTmkb)>rsoY6+s(5qnYG zLdD1}oPk-0j&{QMcTp#f*MN|@NwN0Dr{Rj?l#`w(yXNecIIsz1f&;OMp1)7Vq8`XQ z=>ddfmfgT6Z(z=KbW6pMHZ2Vrt;Td{Wk;7ukC~pl`SLpl5e$XO$|$-dLHKOi@S0k5 zaT2|{vdJvTVq?exx@oo<>_I0K*yebN4m?YEAc6HGndXDPz}pddvU62#cD7wy-8F2b4$V7qxgOXZBAanjmax}e|8ZAHA!+=@9c(reex)1&P z4=>t*?0waxm+w&(!lCVmTJ94H(L$&WWWht`r}A=YhdIJekk#FH~PhqrXr%Grf=PTdJ(|dL{w8S zs={coX=;45{x#e%Ns-s2xCtcHM=sEI&=8#Rfg(!D=W=m`fnAIGbS}L5`j{tnE7Bjy zN|Y2wWI9jpp_^uQRDWePTp!<)*4W2|Qbd^a29@thI-qK-@i?aQ{NnVQd9Lp!NxdVX z)}xN7Tu-75I|fBa7ZapIAN$aAv_3Jc^vRr3P=}KuXrl;l5Pk`}7+6`9A3ep?Rx}S+ z5T62C!rp=UfGvqf{r}8$NuNiHdhB4z#E!az!Ub4g-f(U8u_RY@f`@HH@R;wi$Fo|Y zYRw-IX~zp*jOE%P)-I2L6qrf9iF)KJby$|=qH=9V)WyDt$iYq8lv#h}*-R+y9bI*{ zorKv?7>v=tq8IXo`q;ahRt;C3O`F0d0ez5?TZH`JS{pcqqyE5qM>ZCYqNx~uHx%HJ z9;_5XETwQx!J(*d%dqs0`a{bG3~M4QM65Te6w8w-qaC&^<`w!@uJSI3Li)NW66B!= z#_>kikG=wJFXr0LF3hxcRMmD2W1@H|jW%p(*w%~k4(|8H)tE_H~-o;s9} z07vwl>7+9Vg)-z!U*KLcfVtj?4g;wnHbf*?{xN^jL=ChNX-(0aYPN^N(EuHAu^~0V zvnz!+v&h_GgN6_xs|MHSab#v>Qb_M+Hb9TcB6_gP8bFIp2Zmnr8T6>Mo83Y_oWcig zvbJT-F1nU!p4MVXoMPw)wq!On*p2kmq!z|m3*Agm9X?OKh16?pG`2tssee8d(UaeV zh>f3dg;M2WZ)mrjNn!fF*F|7c*UP0>U+wsN@2DO*>01=}xeFR#jSq{IvGB#u{ zG8?A7nksHeGBFC8?VblU+FH5vxY@{XRvDfd8`?ZtPo~F{ZNp<*lacz~!p@=5(eW*> z+%`GBlRx$P*5sn0sbp(?YWTu2UdTE=Ho7<2Tu-);la!%t)Ah;ZmD}q>6P9($_|A#Z z`gEO425M-!zO_(DADS;zj+>Yq-#W8}>|4j{Q_0x)bh3SDcRd*zONO>g5A&oJaQoI> zg-U(P(3mo8866tlnM~F%8k*cXmCTGy5056(+o^r~(C}C?JmpHNl4SkRbTV2Wnwm~d ze%^7(_%_u~gGcIPQ^~~8t0tGkV17A z4Nq?;_k>_>9a7WY{I`WlZ+(1fc>F|zOwtV`{g2_PsTm>CD%&cWP)i zRZdahQxxcPFkB*OUm@)XhC|4=&J2%j8y%V+9v|c5_xM?Rb=IJ+9f4Lpw>h{O&@fYxB(B#Jyg{tH%Qg+v;_) zT&pa+CGK@UuSe;1=g=gbYtT)7&+wG$ct07Av8GJcr|Od;rZz44qQH29nyNz;WAzI` zF1a`FomREqBSUp;oPnPjr%Ux@a{MAS_(R}kcx-BB+ct=&J~o}~ni-!S;>#QP@@yOK z#Pye=Tk1gEnrP}Is)gZJPer8DAKvc7wGd}fO2WH~gKuJ~}F(rx_!JnygNy)V3b%)N!Q6E>gBEFE(* z)=ea)&hTWQ)A8L*#gk7;_ST0cMVKF@%u}bfkI#%kuGXBf@v#$rr#?CEJ4v3elIQp_ zhC(#GWnu=_Fggu~@Ysbfj87OT)Dy7`f&HV86e_hQEV`aB3e(AE;9NAkb$UA)-@8~w z)sxToc`~kV2XUIw(dahAeQfFMtR$B3vk1{?+>@I&hQvVzBJj)Np3=?yDa%gO78{-T+ zxiA^trtvc3hd7}-sAe0GAEcCq8VD5bh$i<)@ir(9kB=xQI){HmAo$++OkC~9tyt@ zE?l34>A?Y@80%LU21MCKd=YbV0zzK_@m)X+jKgAF_B`&c_(Y+yc6baV4~NfF6ZI{_ z+lEbt_)|Vt7nXV#$qm)QSHERuauS9O+ibLw%0ENibs27a-liPiBF7r3BjaOeCnBk& zzHM85i=@qEpDa{P4ZVjwPpfN7^?Y+3b;x9r@BAG=c-qWZeGlD|&N4JL1v8o2yL0pS zD2mC%jH-EnOnm_j;_IY6L>i*Vp=QhY7_1v5MB2dvuZx0=+?y$9!(&@eX{HQq-zURb z38Jat-$DD47R9$whHiKZ<^S-HqDn1CTx!tHp*>JO0|@p^tZJ^^LdIwC<&{G-)7!@< zho|?xa%+8JdV82IkXNRGJ%{{XApf9gi&Hbmgvn{uJUYB{*gEcLNc8$B`HtH=KGTp@ zn;Cx4KRrHi!f1VWeKau%yobEkUlUcHrwJ*+xi=Zp1PTPF$w|R5KK2djbHFJ3S<1fP zcOq+;wJm{WV1c{^zz8Yekk z|AwftvPmLR3F&`Ey4P2&vn0Knq#hx~5JbZJN$9k0@^Tk19YQ|OALcpk;o%-0V1pof zXr?hULNm9FjypnokZez}1_tsosGIkqWE=;WSN*Xl%`*=H^J@3@;S0Bmu?sKtNix2b zjB27|>?GVw!b;EP^95c}iydy%>Aw}jj)1PZ$xIOX!^M`MWD$g0;yaP6(^$7zYT4icY4o#0wzEaOl9I}4d ziR2o7B`dtTrqErKJknK91C0Sfd|@r+ByuY72ozO5n%UHVl~-V zTrj#w{rcoKr%E5>%c|^)lv)4byL>oR>(HUe;VBA*hWkm|TFF#El~!MfEGoVEI;O-$ zusG4mdwD6H^0EStxA8c5;>pi`&U2qPw0R3k!G+t0cZ`hg92=k5H90jsv-_ewdw+*~ zUr>sgWvL&M%|v+A7|a4q-1R=q(H_~!u@y1_%xrYEebv_N5PZzosgbKil)J|nL)&*77W%~|1_$clq)+mv)M+&&#T3z zz-K6SM9AAZ3m)R*n*7JyM0kvEPnlxaFvu_uGOJ5iJ-_jK82pJ~@LD~H<#R5p5+Bb4 z?oX8}B+tKxH@M$NHlPDEk_&~-`#$-L-}v`mJ`L-9KAGGbi?{tFx!D$|3~Xlg428jt Lq^(ZLz*PAEB!|}j diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt b/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt deleted file mode 100644 index 61c7b168..00000000 --- a/tests/test_contracts/old_versions/v1.8.3/eosio.system/README.txt +++ /dev/null @@ -1,3 +0,0 @@ -Compiled with -eosio.contracts: 7109f002fa9afff18edcafce5c32b224a21eef98 (v1.8.3) -eosio.cdt: 263e41cbb3e58dca71117401f43be104f1e58ae4 (v1.6.3) diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi b/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi deleted file mode 100644 index 65afebad..00000000 --- a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.abi +++ /dev/null @@ -1,2097 +0,0 @@ -{ - "____comment": "This file was generated with eosio-abigen. DO NOT EDIT ", - "version": "eosio::abi/1.1", - "types": [], - "structs": [ - { - "name": "abi_hash", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "hash", - "type": "checksum256" - } - ] - }, - { - "name": "activate", - "base": "", - "fields": [ - { - "name": "feature_digest", - "type": "checksum256" - } - ] - }, - { - "name": "authority", - "base": "", - "fields": [ - { - "name": "threshold", - "type": "uint32" - }, - { - "name": "keys", - "type": "key_weight[]" - }, - { - "name": "accounts", - "type": "permission_level_weight[]" - }, - { - "name": "waits", - "type": "wait_weight[]" - } - ] - }, - { - "name": "bid_refund", - "base": "", - "fields": [ - { - "name": "bidder", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "bidname", - "base": "", - "fields": [ - { - "name": "bidder", - "type": "name" - }, - { - "name": "newname", - "type": "name" - }, - { - "name": "bid", - "type": "asset" - } - ] - }, - { - "name": "bidrefund", - "base": "", - "fields": [ - { - "name": "bidder", - "type": "name" - }, - { - "name": "newname", - "type": "name" - } - ] - }, - { - "name": "block_header", - "base": "", - "fields": [ - { - "name": "timestamp", - "type": "uint32" - }, - { - "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": "blockchain_parameters", - "base": "", - "fields": [ - { - "name": "max_block_net_usage", - "type": "uint64" - }, - { - "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": "uint32" - }, - { - "name": "max_inline_action_depth", - "type": "uint16" - }, - { - "name": "max_authority_depth", - "type": "uint16" - } - ] - }, - { - "name": "buyram", - "base": "", - "fields": [ - { - "name": "payer", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "quant", - "type": "asset" - } - ] - }, - { - "name": "buyrambytes", - "base": "", - "fields": [ - { - "name": "payer", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "bytes", - "type": "uint32" - } - ] - }, - { - "name": "buyrex", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "canceldelay", - "base": "", - "fields": [ - { - "name": "canceling_auth", - "type": "permission_level" - }, - { - "name": "trx_id", - "type": "checksum256" - } - ] - }, - { - "name": "claimrewards", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "closerex", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "cnclrexorder", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "connector", - "base": "", - "fields": [ - { - "name": "balance", - "type": "asset" - }, - { - "name": "weight", - "type": "float64" - } - ] - }, - { - "name": "consolidate", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "defcpuloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "defnetloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "delegatebw", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "stake_net_quantity", - "type": "asset" - }, - { - "name": "stake_cpu_quantity", - "type": "asset" - }, - { - "name": "transfer", - "type": "bool" - } - ] - }, - { - "name": "delegated_bandwidth", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "to", - "type": "name" - }, - { - "name": "net_weight", - "type": "asset" - }, - { - "name": "cpu_weight", - "type": "asset" - } - ] - }, - { - "name": "deleteauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "permission", - "type": "name" - } - ] - }, - { - "name": "deposit", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - }, - { - "name": "eosio_global_state", - "base": "blockchain_parameters", - "fields": [ - { - "name": "max_ram_size", - "type": "uint64" - }, - { - "name": "total_ram_bytes_reserved", - "type": "uint64" - }, - { - "name": "total_ram_stake", - "type": "int64" - }, - { - "name": "last_producer_schedule_update", - "type": "block_timestamp_type" - }, - { - "name": "last_pervote_bucket_fill", - "type": "time_point" - }, - { - "name": "pervote_bucket", - "type": "int64" - }, - { - "name": "perblock_bucket", - "type": "int64" - }, - { - "name": "total_unpaid_blocks", - "type": "uint32" - }, - { - "name": "total_activated_stake", - "type": "int64" - }, - { - "name": "thresh_activated_stake_time", - "type": "time_point" - }, - { - "name": "last_producer_schedule_size", - "type": "uint16" - }, - { - "name": "total_producer_vote_weight", - "type": "float64" - }, - { - "name": "last_name_close", - "type": "block_timestamp_type" - } - ] - }, - { - "name": "eosio_global_state2", - "base": "", - "fields": [ - { - "name": "new_ram_per_block", - "type": "uint16" - }, - { - "name": "last_ram_increase", - "type": "block_timestamp_type" - }, - { - "name": "last_block_num", - "type": "block_timestamp_type" - }, - { - "name": "total_producer_votepay_share", - "type": "float64" - }, - { - "name": "revision", - "type": "uint8" - } - ] - }, - { - "name": "eosio_global_state3", - "base": "", - "fields": [ - { - "name": "last_vpay_state_update", - "type": "time_point" - }, - { - "name": "total_vpay_share_change_rate", - "type": "float64" - } - ] - }, - { - "name": "eosio_global_state4", - "base": "", - "fields": [ - { - "name": "continuous_rate", - "type": "float64" - }, - { - "name": "inflation_pay_factor", - "type": "int64" - }, - { - "name": "votepay_factor", - "type": "int64" - } - ] - }, - { - "name": "exchange_state", - "base": "", - "fields": [ - { - "name": "supply", - "type": "asset" - }, - { - "name": "base", - "type": "connector" - }, - { - "name": "quote", - "type": "connector" - } - ] - }, - { - "name": "fundcpuloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "payment", - "type": "asset" - } - ] - }, - { - "name": "fundnetloan", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "payment", - "type": "asset" - } - ] - }, - { - "name": "init", - "base": "", - "fields": [ - { - "name": "version", - "type": "varuint32" - }, - { - "name": "core", - "type": "symbol" - } - ] - }, - { - "name": "key_weight", - "base": "", - "fields": [ - { - "name": "key", - "type": "public_key" - }, - { - "name": "weight", - "type": "uint16" - } - ] - }, - { - "name": "linkauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "code", - "type": "name" - }, - { - "name": "type", - "type": "name" - }, - { - "name": "requirement", - "type": "name" - } - ] - }, - { - "name": "mvfrsavings", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "rex", - "type": "asset" - } - ] - }, - { - "name": "mvtosavings", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "rex", - "type": "asset" - } - ] - }, - { - "name": "name_bid", - "base": "", - "fields": [ - { - "name": "newname", - "type": "name" - }, - { - "name": "high_bidder", - "type": "name" - }, - { - "name": "high_bid", - "type": "int64" - }, - { - "name": "last_bid_time", - "type": "time_point" - } - ] - }, - { - "name": "newaccount", - "base": "", - "fields": [ - { - "name": "creator", - "type": "name" - }, - { - "name": "name", - "type": "name" - }, - { - "name": "owner", - "type": "authority" - }, - { - "name": "active", - "type": "authority" - } - ] - }, - { - "name": "onblock", - "base": "", - "fields": [ - { - "name": "header", - "type": "block_header" - } - ] - }, - { - "name": "onerror", - "base": "", - "fields": [ - { - "name": "sender_id", - "type": "uint128" - }, - { - "name": "sent_trx", - "type": "bytes" - } - ] - }, - { - "name": "pair_time_point_sec_int64", - "base": "", - "fields": [ - { - "name": "key", - "type": "time_point_sec" - }, - { - "name": "value", - "type": "int64" - } - ] - }, - { - "name": "permission_level", - "base": "", - "fields": [ - { - "name": "actor", - "type": "name" - }, - { - "name": "permission", - "type": "name" - } - ] - }, - { - "name": "permission_level_weight", - "base": "", - "fields": [ - { - "name": "permission", - "type": "permission_level" - }, - { - "name": "weight", - "type": "uint16" - } - ] - }, - { - "name": "producer_info", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "total_votes", - "type": "float64" - }, - { - "name": "producer_key", - "type": "public_key" - }, - { - "name": "is_active", - "type": "bool" - }, - { - "name": "url", - "type": "string" - }, - { - "name": "unpaid_blocks", - "type": "uint32" - }, - { - "name": "last_claim_time", - "type": "time_point" - }, - { - "name": "location", - "type": "uint16" - } - ] - }, - { - "name": "producer_info2", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "votepay_share", - "type": "float64" - }, - { - "name": "last_votepay_share_update", - "type": "time_point" - } - ] - }, - { - "name": "producer_key", - "base": "", - "fields": [ - { - "name": "producer_name", - "type": "name" - }, - { - "name": "block_signing_key", - "type": "public_key" - } - ] - }, - { - "name": "producer_schedule", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint32" - }, - { - "name": "producers", - "type": "producer_key[]" - } - ] - }, - { - "name": "refund", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "refund_request", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "request_time", - "type": "time_point_sec" - }, - { - "name": "net_amount", - "type": "asset" - }, - { - "name": "cpu_amount", - "type": "asset" - } - ] - }, - { - "name": "regproducer", - "base": "", - "fields": [ - { - "name": "producer", - "type": "name" - }, - { - "name": "producer_key", - "type": "public_key" - }, - { - "name": "url", - "type": "string" - }, - { - "name": "location", - "type": "uint16" - } - ] - }, - { - "name": "regproxy", - "base": "", - "fields": [ - { - "name": "proxy", - "type": "name" - }, - { - "name": "isproxy", - "type": "bool" - } - ] - }, - { - "name": "rentcpu", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "loan_payment", - "type": "asset" - }, - { - "name": "loan_fund", - "type": "asset" - } - ] - }, - { - "name": "rentnet", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "loan_payment", - "type": "asset" - }, - { - "name": "loan_fund", - "type": "asset" - } - ] - }, - { - "name": "rex_balance", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "owner", - "type": "name" - }, - { - "name": "vote_stake", - "type": "asset" - }, - { - "name": "rex_balance", - "type": "asset" - }, - { - "name": "matured_rex", - "type": "int64" - }, - { - "name": "rex_maturities", - "type": "pair_time_point_sec_int64[]" - } - ] - }, - { - "name": "rex_fund", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "owner", - "type": "name" - }, - { - "name": "balance", - "type": "asset" - } - ] - }, - { - "name": "rex_loan", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "payment", - "type": "asset" - }, - { - "name": "balance", - "type": "asset" - }, - { - "name": "total_staked", - "type": "asset" - }, - { - "name": "loan_num", - "type": "uint64" - }, - { - "name": "expiration", - "type": "time_point" - } - ] - }, - { - "name": "rex_order", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "owner", - "type": "name" - }, - { - "name": "rex_requested", - "type": "asset" - }, - { - "name": "proceeds", - "type": "asset" - }, - { - "name": "stake_change", - "type": "asset" - }, - { - "name": "order_time", - "type": "time_point" - }, - { - "name": "is_open", - "type": "bool" - } - ] - }, - { - "name": "rex_pool", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "total_lent", - "type": "asset" - }, - { - "name": "total_unlent", - "type": "asset" - }, - { - "name": "total_rent", - "type": "asset" - }, - { - "name": "total_lendable", - "type": "asset" - }, - { - "name": "total_rex", - "type": "asset" - }, - { - "name": "namebid_proceeds", - "type": "asset" - }, - { - "name": "loan_num", - "type": "uint64" - } - ] - }, - { - "name": "rex_return_buckets", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "return_buckets", - "type": "pair_time_point_sec_int64[]" - } - ] - }, - { - "name": "rex_return_pool", - "base": "", - "fields": [ - { - "name": "version", - "type": "uint8" - }, - { - "name": "last_dist_time", - "type": "time_point_sec" - }, - { - "name": "pending_bucket_time", - "type": "time_point_sec" - }, - { - "name": "oldest_bucket_time", - "type": "time_point_sec" - }, - { - "name": "pending_bucket_proceeds", - "type": "int64" - }, - { - "name": "current_rate_of_increase", - "type": "int64" - }, - { - "name": "proceeds", - "type": "int64" - } - ] - }, - { - "name": "rexexec", - "base": "", - "fields": [ - { - "name": "user", - "type": "name" - }, - { - "name": "max", - "type": "uint16" - } - ] - }, - { - "name": "rmvproducer", - "base": "", - "fields": [ - { - "name": "producer", - "type": "name" - } - ] - }, - { - "name": "sellram", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "bytes", - "type": "int64" - } - ] - }, - { - "name": "sellrex", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "rex", - "type": "asset" - } - ] - }, - { - "name": "setabi", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "abi", - "type": "bytes" - } - ] - }, - { - "name": "setacctcpu", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "cpu_weight", - "type": "int64?" - } - ] - }, - { - "name": "setacctnet", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "net_weight", - "type": "int64?" - } - ] - }, - { - "name": "setacctram", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "ram_bytes", - "type": "int64?" - } - ] - }, - { - "name": "setalimits", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "ram_bytes", - "type": "int64" - }, - { - "name": "net_weight", - "type": "int64" - }, - { - "name": "cpu_weight", - "type": "int64" - } - ] - }, - { - "name": "setcode", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "vmtype", - "type": "uint8" - }, - { - "name": "vmversion", - "type": "uint8" - }, - { - "name": "code", - "type": "bytes" - } - ] - }, - { - "name": "setinflation", - "base": "", - "fields": [ - { - "name": "annual_rate", - "type": "int64" - }, - { - "name": "inflation_pay_factor", - "type": "int64" - }, - { - "name": "votepay_factor", - "type": "int64" - } - ] - }, - { - "name": "setparams", - "base": "", - "fields": [ - { - "name": "params", - "type": "blockchain_parameters" - } - ] - }, - { - "name": "setpriv", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "is_priv", - "type": "uint8" - } - ] - }, - { - "name": "setram", - "base": "", - "fields": [ - { - "name": "max_ram_size", - "type": "uint64" - } - ] - }, - { - "name": "setramrate", - "base": "", - "fields": [ - { - "name": "bytes_per_block", - "type": "uint16" - } - ] - }, - { - "name": "setrex", - "base": "", - "fields": [ - { - "name": "balance", - "type": "asset" - } - ] - }, - { - "name": "undelegatebw", - "base": "", - "fields": [ - { - "name": "from", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "unstake_net_quantity", - "type": "asset" - }, - { - "name": "unstake_cpu_quantity", - "type": "asset" - } - ] - }, - { - "name": "unlinkauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "code", - "type": "name" - }, - { - "name": "type", - "type": "name" - } - ] - }, - { - "name": "unregprod", - "base": "", - "fields": [ - { - "name": "producer", - "type": "name" - } - ] - }, - { - "name": "unstaketorex", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "receiver", - "type": "name" - }, - { - "name": "from_net", - "type": "asset" - }, - { - "name": "from_cpu", - "type": "asset" - } - ] - }, - { - "name": "updateauth", - "base": "", - "fields": [ - { - "name": "account", - "type": "name" - }, - { - "name": "permission", - "type": "name" - }, - { - "name": "parent", - "type": "name" - }, - { - "name": "auth", - "type": "authority" - } - ] - }, - { - "name": "updaterex", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - } - ] - }, - { - "name": "updtrevision", - "base": "", - "fields": [ - { - "name": "revision", - "type": "uint8" - } - ] - }, - { - "name": "user_resources", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "net_weight", - "type": "asset" - }, - { - "name": "cpu_weight", - "type": "asset" - }, - { - "name": "ram_bytes", - "type": "int64" - } - ] - }, - { - "name": "voteproducer", - "base": "", - "fields": [ - { - "name": "voter", - "type": "name" - }, - { - "name": "proxy", - "type": "name" - }, - { - "name": "producers", - "type": "name[]" - } - ] - }, - { - "name": "voter_info", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "proxy", - "type": "name" - }, - { - "name": "producers", - "type": "name[]" - }, - { - "name": "staked", - "type": "int64" - }, - { - "name": "last_vote_weight", - "type": "float64" - }, - { - "name": "proxied_vote_weight", - "type": "float64" - }, - { - "name": "is_proxy", - "type": "bool" - }, - { - "name": "flags1", - "type": "uint32" - }, - { - "name": "reserved2", - "type": "uint32" - }, - { - "name": "reserved3", - "type": "asset" - } - ] - }, - { - "name": "wait_weight", - "base": "", - "fields": [ - { - "name": "wait_sec", - "type": "uint32" - }, - { - "name": "weight", - "type": "uint16" - } - ] - }, - { - "name": "withdraw", - "base": "", - "fields": [ - { - "name": "owner", - "type": "name" - }, - { - "name": "amount", - "type": "asset" - } - ] - } - ], - "actions": [ - { - "name": "activate", - "type": "activate", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Activate Protocol Feature\nsummary: 'Activate protocol feature {{nowrap feature_digest}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} activates the protocol feature with a digest of {{feature_digest}}." - }, - { - "name": "bidname", - "type": "bidname", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Bid On a Premium Account Name\nsummary: '{{nowrap bidder}} bids on the premium account name {{nowrap newname}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{bidder}} bids {{bid}} on an auction to own the premium account name {{newname}}.\n\n{{bidder}} transfers {{bid}} to the system to cover the cost of the bid, which will be returned to {{bidder}} only if {{bidder}} is later outbid in the auction for {{newname}} by another account.\n\nIf the auction for {{newname}} closes with {{bidder}} remaining as the highest bidder, {{bidder}} will be authorized to create the account with name {{newname}}.\n\n## Bid refund behavior\n\nIf {{bidder}}’s bid on {{newname}} is later outbid by another account, {{bidder}} will be able to claim back the transferred amount of {{bid}}. The system will attempt to automatically do this on behalf of {{bidder}}, but the automatic refund may occasionally fail which will then require {{bidder}} to manually claim the refund with the bidrefund action.\n\n## Auction close criteria\n\nThe system should automatically close the auction for {{newname}} if it satisfies the condition that over a period of two minutes the following two properties continuously hold:\n\n- no one has bid on {{newname}} within the last 24 hours;\n- and, the value of the latest bid on {{newname}} is greater than the value of the bids on each of the other open auctions.\n\nBe aware that the condition to close the auction described above are sufficient but not necessary. The auction for {{newname}} cannot close unless both of the properties are simultaneously satisfied, but it may be closed without requiring the properties to hold for a period of 2 minutes." - }, - { - "name": "bidrefund", - "type": "bidrefund", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Refund on Name Bid\nsummary: 'Claim refund on {{nowrap newname}} bid'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{bidder}} claims refund on {{newname}} bid after being outbid by someone else." - }, - { - "name": "buyram", - "type": "buyram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy RAM\nsummary: '{{nowrap payer}} buys RAM on behalf of {{nowrap receiver}} by paying {{nowrap quant}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{payer}} buys RAM on behalf of {{receiver}} by paying {{quant}}. This transaction will incur a 0.5% fee out of {{quant}} and the amount of RAM delivered will depend on market rates." - }, - { - "name": "buyrambytes", - "type": "buyrambytes", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy RAM\nsummary: '{{nowrap payer}} buys {{nowrap bytes}} bytes of RAM on behalf of {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{payer}} buys approximately {{bytes}} bytes of RAM on behalf of {{receiver}} by paying market rates for RAM. This transaction will incur a 0.5% fee and the cost will depend on market rates." - }, - { - "name": "buyrex", - "type": "buyrex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy REX Tokens\nsummary: '{{nowrap from}} buys REX tokens in exchange for {{nowrap amount}} and their vote stake increases by {{nowrap amount}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{amount}} is taken out of {{from}}’s REX fund and used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{from}} must have voted for a proxy or at least 21 block producers. {{amount}} is added to {{from}}’s vote stake.\n\nA sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately." - }, - { - "name": "canceldelay", - "type": "canceldelay", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cancel Delayed Transaction\nsummary: '{{nowrap canceling_auth.actor}} cancels a delayed transaction'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{canceling_auth.actor}} cancels the delayed transaction with id {{trx_id}}." - }, - { - "name": "claimrewards", - "type": "claimrewards", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Block Producer Rewards\nsummary: '{{nowrap owner}} claims block and vote rewards'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{owner}} claims block and vote rewards from the system." - }, - { - "name": "closerex", - "type": "closerex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cleanup Unused REX Data\nsummary: 'Delete REX related DB entries and free associated RAM'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nDelete REX related DB entries and free associated RAM for {{owner}}.\n\nTo fully delete all REX related DB entries, {{owner}} must ensure that their REX balance and REX fund amounts are both zero and they have no outstanding loans." - }, - { - "name": "cnclrexorder", - "type": "cnclrexorder", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Cancel Scheduled REX Sell Order\nsummary: '{{nowrap owner}} cancels a scheduled sell order if not yet filled'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} cancels their open sell order." - }, - { - "name": "consolidate", - "type": "consolidate", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Consolidate REX Maturity Buckets Into One\nsummary: 'Consolidate REX maturity buckets into one'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nConsolidate REX maturity buckets into one bucket that {{owner}} will not be able to sell until 4 to 5 days later." - }, - { - "name": "defcpuloan", - "type": "defcpuloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from the Fund of a Specific CPU Loan\nsummary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of CPU loan number {{nowrap loan_num}} back to REX fund'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{amount}} from the fund of CPU loan number {{loan_num}} back to REX fund." - }, - { - "name": "defnetloan", - "type": "defnetloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from the Fund of a Specific NET Loan\nsummary: '{{nowrap from}} transfers {{nowrap amount}} from the fund of NET loan number {{nowrap loan_num}} back to REX fund'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{amount}} from the fund of NET loan number {{loan_num}} back to REX fund." - }, - { - "name": "delegatebw", - "type": "delegatebw", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Stake Tokens for NET and/or CPU\nsummary: 'Stake tokens for NET and/or CPU and optionally transfer ownership'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{#if transfer}} {{from}} stakes on behalf of {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth.\n\nStaked tokens will also be transferred to {{receiver}}. The sum of these two quantities will be deducted from {{from}}’s liquid balance and add to the vote weight of {{receiver}}.\n{{else}}\n{{from}} stakes to self and delegates to {{receiver}} {{stake_net_quantity}} for NET bandwidth and {{stake_cpu_quantity}} for CPU bandwidth.\n\nThe sum of these two quantities add to the vote weight of {{from}}.\n{{/if}}" - }, - { - "name": "deleteauth", - "type": "deleteauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Delete Account Permission\nsummary: 'Delete the {{nowrap permission}} permission of {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDelete the {{permission}} permission of {{account}}." - }, - { - "name": "deposit", - "type": "deposit", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit Into REX Fund\nsummary: 'Add to {{nowrap owner}}’s REX fund by transferring {{nowrap amount}} from {{nowrap owner}}’s liquid balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nTransfer {{amount}} from {{owner}}’s liquid balance to {{owner}}’s REX fund. All proceeds and expenses related to REX are added to or taken out of this fund." - }, - { - "name": "fundcpuloan", - "type": "fundcpuloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit into the Fund of a Specific CPU Loan\nsummary: '{{nowrap from}} funds a CPU loan'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{payment}} from REX fund to the fund of CPU loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time." - }, - { - "name": "fundnetloan", - "type": "fundnetloan", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deposit into the Fund of a Specific NET Loan\nsummary: '{{nowrap from}} funds a NET loan'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} transfers {{payment}} from REX fund to the fund of NET loan number {{loan_num}} in order to be used in loan renewal at expiry. {{from}} can withdraw the total balance of the loan fund at any time." - }, - { - "name": "init", - "type": "init", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Initialize System Contract\nsummary: 'Initialize system contract'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\nInitialize system contract. The core token symbol will be set to {{core}}." - }, - { - "name": "linkauth", - "type": "linkauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Link Action to Permission\nsummary: '{{nowrap account}} sets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract to {{nowrap requirement}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{account}} sets the minimum required permission for the {{#if type}}{{type}} action of the{{/if}} {{code}} contract to {{requirement}}.\n\n{{#if type}}{{else}}Any links explicitly associated to specific actions of {{code}} will take precedence.{{/if}}" - }, - { - "name": "mvfrsavings", - "type": "mvfrsavings", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unlock REX Tokens\nsummary: '{{nowrap owner}} unlocks REX Tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} unlocks {{rex}} by moving it out of the REX savings bucket. The unlocked REX tokens cannot be sold until 4 to 5 days later." - }, - { - "name": "mvtosavings", - "type": "mvtosavings", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Lock REX Tokens\nsummary: '{{nowrap owner}} locks REX Tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{owner}} locks {{rex}} by moving it into the REX savings bucket. The locked REX tokens cannot be sold directly and will have to be unlocked explicitly before selling." - }, - { - "name": "newaccount", - "type": "newaccount", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Create New Account\nsummary: '{{nowrap creator}} creates a new account with the name {{nowrap name}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{creator}} creates a new account with the name {{name}} and the following permissions:\n\nowner permission with authority:\n{{to_json owner}}\n\nactive permission with authority:\n{{to_json active}}" - }, - { - "name": "onblock", - "type": "onblock", - "ricardian_contract": "" - }, - { - "name": "onerror", - "type": "onerror", - "ricardian_contract": "" - }, - { - "name": "refund", - "type": "refund", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Claim Unstaked Tokens\nsummary: 'Return previously unstaked tokens to {{nowrap owner}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nReturn previously unstaked tokens to {{owner}} after the unstaking period has elapsed." - }, - { - "name": "regproducer", - "type": "regproducer", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Register as a Block Producer Candidate\nsummary: 'Register {{nowrap producer}} account as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\nRegister {{producer}} account as a block producer candidate.\n\n{{$clauses.BlockProducerAgreement}}" - }, - { - "name": "regproxy", - "type": "regproxy", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Register/unregister as a Proxy\nsummary: 'Register/unregister {{nowrap proxy}} as a proxy account'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{#if isproxy}}\n{{proxy}} registers as a proxy that can vote on behalf of accounts that appoint it as their proxy.\n{{else}}\n{{proxy}} unregisters as a proxy that can vote on behalf of accounts that appoint it as their proxy.\n{{/if}}" - }, - { - "name": "rentcpu", - "type": "rentcpu", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Rent CPU Bandwidth for 30 Days\nsummary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent CPU bandwidth for {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} pays {{loan_payment}} to rent CPU bandwidth on behalf of {{receiver}} for a period of 30 days.\n\n{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s CPU resources. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan.\n\nAt expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s CPU bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s CPU bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund." - }, - { - "name": "rentnet", - "type": "rentnet", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Rent NET Bandwidth for 30 Days\nsummary: '{{nowrap from}} pays {{nowrap loan_payment}} to rent NET bandwidth for {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} pays {{loan_payment}} to rent NET bandwidth on behalf of {{receiver}} for a period of 30 days.\n\n{{loan_payment}} is taken out of {{from}}’s REX fund. The market price determines the number of tokens to be staked to {{receiver}}’s NET resources for 30 days. In addition, {{from}} provides {{loan_fund}}, which is also taken out of {{from}}’s REX fund, to be used for automatic renewal of the loan.\n\nAt expiration, if the loan has less funds than {{loan_payment}}, it is closed and lent tokens that have been staked are taken out of {{receiver}}’s NET bandwidth. Otherwise, it is renewed at the market price at the time of renewal, that is, the number of staked tokens is recalculated and {{receiver}}’s NET bandwidth is updated accordingly. {{from}} can fund or defund a loan at any time before expiration. When the loan is closed, {{from}} is refunded any tokens remaining in the loan fund." - }, - { - "name": "rexexec", - "type": "rexexec", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Perform REX Maintenance\nsummary: 'Process sell orders and expired loans'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nPerforms REX maintenance by processing a maximum of {{max}} REX sell orders and expired loans. Any account can execute this action." - }, - { - "name": "rmvproducer", - "type": "rmvproducer", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Forcibly Unregister a Block Producer Candidate\nsummary: '{{nowrap producer}} is unregistered as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} unregisters {{producer}} as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered." - }, - { - "name": "sellram", - "type": "sellram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Sell RAM From Account\nsummary: 'Sell unused RAM from {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\nSell {{bytes}} bytes of unused RAM from account {{account}} at market price. This transaction will incur a 0.5% fee on the proceeds which depend on market rates." - }, - { - "name": "sellrex", - "type": "sellrex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Sell REX Tokens in Exchange for EOS\nsummary: '{{nowrap from}} sells {{nowrap rex}} tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from}} initiates a sell order to sell {{rex}} tokens at the market exchange rate during the time at which the order is ultimately executed. If {{from}} already has an open sell order in the sell queue, {{rex}} will be added to the amount of the sell order without change the position of the sell order within the queue. Once the sell order is executed, proceeds are added to {{from}}’s REX fund, the value of sold REX tokens is deducted from {{from}}’s vote stake, and votes are updated accordingly.\n\nDepending on the market conditions, it may not be possible to fill the entire sell order immediately. In such a case, the sell order is added to the back of a sell queue. A sell order at the front of the sell queue will automatically be executed when the market conditions allow for the entire order to be filled. Regardless of the market conditions, the system is designed to execute this sell order within 30 days. {{from}} can cancel the order at any time before it is filled using the cnclrexorder action." - }, - { - "name": "setabi", - "type": "setabi", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deploy Contract ABI\nsummary: 'Deploy contract ABI on account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDeploy the ABI file associated with the contract on account {{account}}." - }, - { - "name": "setacctcpu", - "type": "setacctcpu", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the CPU Quota of Account\nsummary: 'Explicitly manage the CPU bandwidth quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value cpu_weight}}\nExplicitly manage the CPU bandwidth quota of account {{account}} by pinning it to a weight of {{cpu_weight}}.\n\n{{account}} can stake and unstake, however, it will not change their CPU bandwidth quota as long as it remains pinned.\n{{else}}\nUnpin the CPU bandwidth quota of account {{account}}. The CPU bandwidth quota of {{account}} will be driven by the current tokens staked for CPU bandwidth by {{account}}.\n{{/if_has_value}}" - }, - { - "name": "setacctnet", - "type": "setacctnet", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the NET Quota of Account\nsummary: 'Explicitly manage the NET bandwidth quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value net_weight}}\nExplicitly manage the network bandwidth quota of account {{account}} by pinning it to a weight of {{net_weight}}.\n\n{{account}} can stake and unstake, however, it will not change their NET bandwidth quota as long as it remains pinned.\n{{else}}\nUnpin the NET bandwidth quota of account {{account}}. The NET bandwidth quota of {{account}} will be driven by the current tokens staked for NET bandwidth by {{account}}.\n{{/if_has_value}}" - }, - { - "name": "setacctram", - "type": "setacctram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Explicitly Manage the RAM Quota of Account\nsummary: 'Explicitly manage the RAM quota of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if_has_value ram_bytes}}\nExplicitly manage the RAM quota of account {{account}} by pinning it to {{ram_bytes}} bytes.\n\n{{account}} can buy and sell RAM, however, it will not change their RAM quota as long as it remains pinned.\n{{else}}\nUnpin the RAM quota of account {{account}}. The RAM quota of {{account}} will be driven by the current RAM holdings of {{account}}.\n{{/if_has_value}}" - }, - { - "name": "setalimits", - "type": "setalimits", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Adjust Resource Limits of Account\nsummary: 'Adjust resource limits of account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} updates {{account}}’s resource limits to have a RAM quota of {{ram_bytes}} bytes, a NET bandwidth quota of {{net_weight}} and a CPU bandwidth quota of {{cpu_weight}}." - }, - { - "name": "setcode", - "type": "setcode", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Deploy Contract Code\nsummary: 'Deploy contract code on account {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nDeploy compiled contract code to the account {{account}}." - }, - { - "name": "setinflation", - "type": "setinflation", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set Inflation Parameters\nsummary: 'Set inflation parameters'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets the inflation parameters as follows:\n\n* Annual inflation rate (in units of a hundredth of a percent): {{annual_rate}}\n* Fraction of inflation used to reward block producers: 10000/{{inflation_pay_factor}}\n* Fraction of block producer rewards to be distributed proportional to blocks produced: 10000/{{votepay_factor}}" - }, - { - "name": "setparams", - "type": "setparams", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set System Parameters\nsummary: 'Set System Parameters'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets system parameters to:\n{{to_json params}}" - }, - { - "name": "setpriv", - "type": "setpriv", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Make an Account Privileged or Unprivileged\nsummary: '{{#if is_priv}}Make {{nowrap account}} privileged{{else}}Remove privileged status of {{nowrap account}}{{/if}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{#if is_priv}}\n{{$action.account}} makes {{account}} privileged.\n{{else}}\n{{$action.account}} removes privileged status of {{account}}.\n{{/if}}" - }, - { - "name": "setram", - "type": "setram", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Configure the Available RAM\nsummary: 'Configure the available RAM'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} configures the available RAM to {{max_ram_size}} bytes." - }, - { - "name": "setramrate", - "type": "setramrate", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Set the Rate of Increase of RAM\nsummary: 'Set the rate of increase of RAM per block'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} sets the rate of increase of RAM to {{bytes_per_block}} bytes/block." - }, - { - "name": "setrex", - "type": "setrex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Adjust REX Pool Virtual Balance\nsummary: 'Adjust REX Pool Virtual Balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} adjusts REX loan rate by setting REX pool virtual balance to {{balance}}. No token transfer or issue is executed in this action." - }, - { - "name": "undelegatebw", - "type": "undelegatebw", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unstake Tokens for NET and/or CPU\nsummary: 'Unstake tokens for NET and/or CPU from {{nowrap receiver}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/resource.png#3830f1ce8cb07f7757dbcf383b1ec1b11914ac34a1f9d8b065f07600fa9dac19\n---\n\n{{from}} unstakes from {{receiver}} {{unstake_net_quantity}} for NET bandwidth and {{unstake_cpu_quantity}} for CPU bandwidth.\n\nThe sum of these two quantities will be removed from the vote weight of {{receiver}} and will be made available to {{from}} after an uninterrupted 3 day period without further unstaking by {{from}}. After the uninterrupted 3 day period passes, the system will attempt to automatically return the funds to {{from}}’s regular token balance. However, this automatic refund may occasionally fail which will then require {{from}} to manually claim the funds with the refund action." - }, - { - "name": "unlinkauth", - "type": "unlinkauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unlink Action from Permission\nsummary: '{{nowrap account}} unsets the minimum required permission for the {{#if type}}{{nowrap type}} action of the{{/if}} {{nowrap code}} contract'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\n{{account}} removes the association between the {{#if type}}{{type}} action of the{{/if}} {{code}} contract and its minimum required permission.\n\n{{#if type}}{{else}}This will not remove any links explicitly associated to specific actions of {{code}}.{{/if}}" - }, - { - "name": "unregprod", - "type": "unregprod", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Unregister as a Block Producer Candidate\nsummary: '{{nowrap producer}} unregisters as a block producer candidate'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{producer}} unregisters as a block producer candidate. {{producer}} account will retain its votes and those votes can change based on voter stake changes or votes removed from {{producer}}. However new voters will not be able to vote for {{producer}} while it remains unregistered." - }, - { - "name": "unstaketorex", - "type": "unstaketorex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Buy REX Tokens Using Staked Tokens\nsummary: '{{nowrap owner}} buys REX tokens in exchange for tokens currently staked to NET and/or CPU'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\n{{from_net}} and {{from_cpu}} are withdrawn from {{receiver}}’s NET and CPU bandwidths respectively. These funds are used to purchase REX tokens at the current market exchange rate. In order for the action to succeed, {{owner}} must have voted for a proxy or at least 21 block producers.\n\nA sell order of the purchased amount can only be initiated after waiting for the maturity period of 4 to 5 days to pass. Even then, depending on the market conditions, the initiated sell order may not be executed immediately." - }, - { - "name": "updateauth", - "type": "updateauth", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Modify Account Permission\nsummary: 'Add or update the {{nowrap permission}} permission of {{nowrap account}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/account.png#3d55a2fc3a5c20b456f5657faf666bc25ffd06f4836c5e8256f741149b0b294f\n---\n\nModify, and create if necessary, the {{permission}} permission of {{account}} to have a parent permission of {{parent}} and the following authority:\n{{to_json auth}}" - }, - { - "name": "updaterex", - "type": "updaterex", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Update REX Owner Vote Weight\nsummary: 'Update vote weight to current value of held REX tokens'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nUpdate vote weight of {{owner}} account to current value of held REX tokens." - }, - { - "name": "updtrevision", - "type": "updtrevision", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Update System Contract Revision Number\nsummary: 'Update system contract revision number'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/admin.png#9bf1cec664863bd6aaac0f814b235f8799fb02c850e9aa5da34e8a004bd6518e\n---\n\n{{$action.account}} advances the system contract revision number to {{revision}}." - }, - { - "name": "voteproducer", - "type": "voteproducer", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Vote for Block Producers\nsummary: '{{nowrap voter}} votes for {{#if proxy}}the proxy {{nowrap proxy}}{{else}}up to 30 block producer candidates{{/if}}'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/voting.png#db28cd3db6e62d4509af3644ce7d377329482a14bb4bfaca2aa5f1400d8e8a84\n---\n\n{{#if proxy}}\n{{voter}} votes for the proxy {{proxy}}.\nAt the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the producers voted by {{proxy}}.\n{{else}}\n{{voter}} votes for the following block producer candidates:\n\n{{#each producers}}\n + {{this}}\n{{/each}}\n\nAt the time of voting the full weight of voter’s staked (CPU + NET) tokens will be cast towards each of the above producers.\n{{/if}}" - }, - { - "name": "withdraw", - "type": "withdraw", - "ricardian_contract": "---\nspec_version: \"0.2.0\"\ntitle: Withdraw from REX Fund\nsummary: 'Withdraw {{nowrap amount}} from {{nowrap owner}}’s REX fund by transferring to {{owner}}’s liquid balance'\nicon: http://127.0.0.1/ricardian_assets/eosio.contracts/icons/rex.png#d229837fa62a464b9c71e06060aa86179adf0b3f4e3b8c4f9702f4f4b0c340a8\n---\n\nWithdraws {{amount}} from {{owner}}’s REX fund and transfer them to {{owner}}’s liquid balance." - } - ], - "tables": [ - { - "name": "abihash", - "type": "abi_hash", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "bidrefunds", - "type": "bid_refund", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "cpuloan", - "type": "rex_loan", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "delband", - "type": "delegated_bandwidth", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global", - "type": "eosio_global_state", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global2", - "type": "eosio_global_state2", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global3", - "type": "eosio_global_state3", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "global4", - "type": "eosio_global_state4", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "namebids", - "type": "name_bid", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "netloan", - "type": "rex_loan", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "producers", - "type": "producer_info", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "producers2", - "type": "producer_info2", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rammarket", - "type": "exchange_state", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "refunds", - "type": "refund_request", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "retbuckets", - "type": "rex_return_buckets", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexbal", - "type": "rex_balance", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexfund", - "type": "rex_fund", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexpool", - "type": "rex_pool", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexqueue", - "type": "rex_order", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "rexretpool", - "type": "rex_return_pool", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "userres", - "type": "user_resources", - "index_type": "i64", - "key_names": [], - "key_types": [] - }, - { - "name": "voters", - "type": "voter_info", - "index_type": "i64", - "key_names": [], - "key_types": [] - } - ], - "ricardian_clauses": [ - { - "id": "UserAgreement", - "body": "User agreement for the chain can go here." - }, - { - "id": "BlockProducerAgreement", - "body": "I, {{producer}}, hereby nominate myself for consideration as an elected block producer.\n\nIf {{producer}} is selected to produce blocks by the system contract, I will sign blocks with {{producer_key}} and I hereby attest that I will keep this key secret and secure.\n\nIf {{producer}} is unable to perform obligations under this contract I will resign my position by resubmitting this contract with the null producer key.\n\nI acknowledge that a block is 'objectively valid' if it conforms to the deterministic blockchain rules in force at the time of its creation, and is 'objectively invalid' if it fails to conform to those rules.\n\n{{producer}} hereby agrees to only use {{producer_key}} to sign messages under the following scenarios:\n\n* proposing an objectively valid block at the time appointed by the block scheduling algorithm;\n* pre-confirming a block produced by another producer in the schedule when I find said block objectively valid;\n* and, confirming a block for which {{producer}} has received pre-confirmation messages from more than two-thirds of the active block producers.\n\nI hereby accept liability for any and all provable damages that result from my:\n\n* signing two different block proposals with the same timestamp with {{producer_key}};\n* signing two different block proposals with the same block number with {{producer_key}};\n* signing any block proposal which builds off of an objectively invalid block;\n* signing a pre-confirmation for an objectively invalid block;\n* or, signing a confirmation for a block for which I do not possess pre-confirmation messages from more than two-thirds of the active block producers.\n\nI hereby agree that double-signing for a timestamp or block number in concert with two or more other block producers shall automatically be deemed malicious and cause {{producer}} to be subject to:\n\n* a fine equal to the past year of compensation received,\n* immediate disqualification from being a producer,\n* and/or other damages.\n\nAn exception may be made if {{producer}} can demonstrate that the double-signing occurred due to a bug in the reference software; the burden of proof is on {{producer}}.\n\nI hereby agree not to interfere with the producer election process. I agree to process all producer election transactions that occur in blocks I create, to sign all objectively valid blocks I create that contain election transactions, and to sign all pre-confirmations and confirmations necessary to facilitate transfer of control to the next set of producers as determined by the system contract.\n\nI hereby acknowledge that more than two-thirds of the active block producers may vote to disqualify {{producer}} in the event {{producer}} is unable to produce blocks or is unable to be reached, according to criteria agreed to among block producers.\n\nIf {{producer}} qualifies for and chooses to collect compensation due to votes received, {{producer}} will provide a public endpoint allowing at least 100 peers to maintain synchronization with the blockchain and/or submit transactions to be included. {{producer}} shall maintain at least one validating node with full state and signature checking and shall report any objectively invalid blocks produced by the active block producers. Reporting shall be via a method to be agreed to among block producers, said method and reports to be made public.\n\nThe community agrees to allow {{producer}} to authenticate peers as necessary to prevent abuse and denial of service attacks; however, {{producer}} agrees not to discriminate against non-abusive peers.\n\nI agree to process transactions on a FIFO (first in, first out) best-effort basis and to honestly bill transactions for measured execution time.\n\nI {{producer}} agree not to manipulate the contents of blocks in order to derive profit from: the order in which transactions are included, or the hash of the block that is produced.\n\nI, {{producer}}, hereby agree to disclose and attest under penalty of perjury all ultimate beneficial owners of my business entity who own more than 10% and all direct shareholders.\n\nI, {{producer}}, hereby agree to cooperate with other block producers to carry out our respective and mutual obligations under this agreement, including but not limited to maintaining network stability and a valid blockchain.\n\nI, {{producer}}, agree to maintain a website hosted at {{url}} which contains up-to-date information on all disclosures required by this contract.\n\nI, {{producer}}, agree to set the location value of {{location}} such that {{producer}} is scheduled with minimal latency between my previous and next peer.\n\nI, {{producer}}, agree to maintain time synchronization within 10 ms of global atomic clock time, using a method agreed to among block producers.\n\nI, {{producer}}, agree not to produce blocks before my scheduled time unless I have received all blocks produced by the prior block producer.\n\nI, {{producer}}, agree not to publish blocks with timestamps more than 500ms in the future unless the prior block is more than 75% full by either NET or CPU bandwidth metrics.\n\nI, {{producer}}, agree not to set the RAM supply to more RAM than my nodes contain and to resign if I am unable to provide the RAM approved by more than two-thirds of active block producers, as shown in the system parameters." - } - ], - "variants": [] -} \ No newline at end of file diff --git a/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm b/tests/test_contracts/old_versions/v1.8.3/eosio.system/eosio.system.wasm deleted file mode 100755 index 7934a4a9790a1c53055b6df8af1fb95a7f213f98..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 263877 zcmeFa3!Gh5dH26B=QeX@l1;cclCi7RK)nP+K`2V`mZGgeQBl#NfLGLLQBhIj`--Af^8fyxwf5QjoH;YO z5Ku4)Wbd>0TF-jcv!2^}*0a_QPF;6q7z9E1q4=rGgJ5}OGk>^j;!n7Fd88jPkKDcg zchmA9+_XI06fBQ6<%Lzpsz#e%9xShJ769IF-l#&G!j1Ot%kAII22pKoQuV5uR0HlN zSYA_IdlFcKz@exxsp^IBiuoNZ5B0x(>iH&t2pt@UiIvuan75SN2o^P(a(8<~BhiHOC+Nq*iqkZ4?^9h}Y_| z%KBpY6N(u`;SNTw1_1b}8isgYWpnhM=Ck9KXPw(z@seeyuR3eRvQ>+Z2_iiiT6y-m zRc9|db=|s^Yu5*{9;NG6u3z?&)n}hJaoQQDt~zVknp4-FdgjXYE7z{$_OywWD_pVK znJdpcZOu!Aiq-jFyQ@=GvBLy<&DyiqoV{-43f-(Y=QQ93HNC8!`jWH3A<(^mQ`P|= zI_;dbYgeANe%bm}XRZwDdVh%8JN2~ntIl0n0%L6qtz9{J&Z@O5mz{df`ZI!tO3!i4 zt~z(s>XrWs{0H>#U_D&Ba^2bItUYbzvem23T(y2(FlcWCy!TC0Z;~97wJT3sN!x23 zHg&K)^Xzk1I&_DZEnB%^{mQdetUG=E=|=}cs@Pn%?DW-VpSphCs`aNk@->z%JM)~? z>ra1TFsuSpvI6Iv)m3E0s&hL#1;a|ESM)01k{#+F~JSC)UBRr~_j zx^rIA0XDR3+4{BToORmz(^pV?u7?F3a#%%ybv#N`ps{A{sFZVn2dT<{Jt}^SAJ2kV#*a37!;TY|tvln?qo1@mn5SCJ;@K12 zlTxWCJ>h8gEb*n*u3EG5%oR^qyvRMSl_Amosq4;Iy?)gbgM$UR!b=ZQ-vvsbJPMpS%|ro^gh$fR(X2j{E- zsB8R@Ds(u{R;}2uY{l8hm-9MWCD)eq+DmEf&iDbBVw7URYi27j#Lb5A?< ztkYJmUbbT8=_}C#D}o~oHzR82S!yLa)yus&g!WHgdFuLeq!XkvppOS~@ER!YALV5n zCSE*Y6cbMv=N!pm{`=rgORLZRo0V%{Lg!WlE#YtwZ;EF|HxowDl5v1;Vt6;O^W3w1 zY>F2ieEy^$Fq8^g&1* zx^UqUpmTH_hDXm^7(aI2!lRFVqOgb;#;(B8^XA1z9~vJ`-A4<~qmBum^d$A2>W3c9 z<8a>5M^pA_kf#Sn&pWyrFPz7pLt~!s$R6{1!91!Q5zkw=SpV?<5#c=Arv^V&mBI@T zJ$B(d{$IERdinpCETkUq1k)~1O)!mI_H4wzkN*r(cK(E-an+ER$Cbf~`L7xuT3r}F zIev<0f5g1_IB+o74u1USk3OU_uTl-yP#tOoVePPZbC^wS51N~U?AsTF`K3M(R!?2C zX7x*hzZhtQK^8WnRTG21e$U*y<4Ta6)V#bIB+pKRG<<$#>DbiNuWozy`4``D$>ucT zw;m_|9#(mN&6ocEP5=Dv7Z#8Iqx1OcFMK8_o`2MyPu+FhkGJ3YcO@{}^YYuS|Jlh! z@f-B`-gn*h#Vaqp^@b9dk2x??@A>sNe|UKb%*Xxnsb607)v*H1jsEd%H(pkL{K>rZ z)SW;1c?tTb{PV3he)9We=r`H(ZNIqupDrnb`LsR$;=jG`{EN$vKVy%-dP&dY&)Vbb zKXF}m>6`8G)GgP&@52`#U10t>d;FU(T=(&JchT|luK3jU_k5$==70Lf*S-4I+skCX z#XaBgxqtq^S5GUTf1!Z#&8HTRzsTcTuKuUbz3Hwy?=20+t-kd2_k8jTCF0)3S^RF75TQ7abH!k~ZxvyXI&;RRRKG*g9>-K!>m*3OPsdw1psi_NZzxo?xG{2$e zSAO-=cii-yH+-Um&NuaZ$K5~w;CZ+H>dmEYeXH~QTR$p4-{Iijb^F!det(%f-{$%D zw_o+ai{5nA4@yM-jw?Pj^@BUgL-Jn+{imP4_{|`S~?$h`5 z{EpXr@eRNJ(#_@P-?#ExFZ=0d-u=rGE(SRgQW}k)^ZeQ`{=+Xmc+dCBYUv&i<&8hM`O{A+aQuZm-g?PB@BBvj@h=U?dp`J` z4_sev^WLzU1}HuLY`^}Z+k+QWmS*<*tGB-I$FKZpkR09I$3OI?12tEGK-BjJ}StPiB^~f|K5(q(k)lC;%I69H;u-EzZ?$IIQ!N4KfEt~ zj@|Cs_0e7R=L}P0ZZlfSJ9@S2WzXbYa6({zc7F6F!*PDU%a;n*XS;Uo`gHx-21Ir0 zlTRD22#PNn1g#3-KJnYn-1oBQ4d=jkS{(|T1@PmywyPf3>^uMQC*$onJLKH#6&uD| zVF{372CA1-)L@WSFU=7;eye`wzdpM4Qre{8ROQ+8)9O1~m8ShZelmO84VUbS$FCVn zFMtl5)8H9mf-HHqP)nXWx0yUYJ8Us9jfYj3x0}ZqhHyN2Zd-ka zQZVOu8c(*Pr;FROjj$Scv@2PCvK>BcI8qThPql2rc)QBGRxORwFy+leyS|nN==R2O z07XJ1^iMX7r!|9-x-wO&#P%*op4Utx4HN%IK&9CY;{bLb11RW03KLqf-_0jNwCpe^ zxzM*FVFZih1ws?l)6n|biXpQ4PTl5`Fk-NQ&-?jph|&&*gLo;#3pD5#Ep11t8yyr- z-P5EAVvsrwl9QWr0@XG`fwX)2qUHop-S9<6sz8(tjSD0F|7@Dc+l!OGq-wNO4O(MB z;-wmMRZ>a}2SX7}M#czS;e(dmC*wzgL$kp@pms_xD*pLjH>*KX3!2Y!9JPZX38@!? z%2!0lhTSIIfgKNZr`JL9s_1b0ora@&2el@Wh$lM&8g9PWbO{*454~OHFt&P>Uv}CXDmJpC(v%IstY)wkwL90^sK<*=n$1#93@<;i=z>crsH9<{BVzj>LCMylExEB zRY=OV1ZhpZf)Ae@&_^qUY?;c>f+q)h#ie-VFw&^S$&17tsYc~Gracg@R&ZZw^o&R- z0`&l)&Kl!%B*-e`jtp0{>Ox+Wi=kY*k=56y^=wx#x%SDyTu~6L(#k{@Jj(|6+8d>^ zY9a*I0^!c)j%Q&KAD-6iDI?LYh?yET2yUnb7~_gWxg9bZy-1WAsrPSWAZwIbX!sTe zG?uZ(cGgbJDZ!ty6LV(nL^^;Rx9TM*X@4y1S*wI)E5}ky1p&lV8Zj@x3&U_zv@{DA z25(tv*5;`A%BAS1hE$OF;VryOVfrhVBJLBB92Qspt*-oNw3YH=upS_-0RHI*M-~Ub zZ#BSUchxuJvfuFTe_OF}?C0_3E86JEtq64UJ+X;lc1Ww1UHI{!RfocL{?@YSOxPn{ zPj}#=bl@mhH-1rjU_LC=;PvM5v@wwm%x~8uKNYx$>JwRfZky`au5c2AUwP(y-HDtK zl;85JxJfq_w|r$`)XCOd7mCIMp5;8{G8rE3!o}c?SwFPDT+Aq9&-t7&Bg0Jwz3!acj^$ zMh1EM3=>mGBdFP;91LCcHR;xP_BcHkWvoNgt3Fpa4GW^Ln+~QRGlle(F-oh?GE!id z8+1^O8&w;ol?G%bvxNda(7Z;jOB%F7*L7aRIG6Cw!oV4p40?vN7TSw24SCU$PDfPZ zRwzQ!Jq=$l0pJj;?aNoj+oo!xZ1Xx;ch_(K`)|f4v#D3S^85{ILhQ_7f|8&w48rM9 z9Y~Nd$XuFZW_u&dBM_)3H02-Yg64I2ffc+u-jcL<<@;BrZPG~T>o!?Wbk_!rA#2V&crXBmjs z&lQMQZVP45cM`)Kn! z?b;AaV$tTxrg)=ye%QUL%zFmr^ASG@A1+;5Zx2ks0dW>V5}tbN1`*>d7#HR05K|sS zI*>NUTSExOpU82mXCv#gk#o{89YV|34hn;GP~13}lQ&Kgy76|?0dYuU`U zF|PEYo}GmJhLhO6Tci;XA6fBd=;DP?R!u$u8PFo*nTw?ZC#PBWl5%!7z#|l}f;W zbVcI;EV>eDC>dJ~5Vh`N%E4&4riQcap#As= zrnTLXhaA`4U7>^Zv^_Wbf5)NztpSYJzfxMCb8>xmA&PKX0T|o=2^v9@_wGS3&}4$PbX3Gy3VEBTKY7LTA%TtpEVSvM(79>em* zL6@cnr3ZPn76hlY=gn^&1Y^~V|0d@%R*23JB8`&-%T?1k7+4fUZqOKD@eCRxkfdk| z>6k*MF-xD>Iv8lYoioIE4QFRhwuZC8)}ZcF30srt#?vKe&Fs!V3TY5P&Flx%?5^L_Iw?@5J16t~6$IJZ-LPHF;jb ze*paDEmqAXl2+tza8`Rb4OUOI2g~RW8v1he=$7#nC7*{~8V2Z~q3@J&3H`d7KG$P^ za2b0IXrJ*oY!Alc!5x4M<364E3!2%V_(7719;(O@mJYyVO}2*_g2-8a%$zxD2vICu zIv6j_(o)S7QI_>L!yQ0HhIxRIl1R6P@X4{|(~8$~YcQ;kBwohzxWwt;1g+qCj*BI& z6-^Y)g>W8vsTGE7qTr>&#q+JT7{s6>OTm0~h%SMZxEwdcNktdSXU9@yE>1pbsUM5; z^4YY*?DbqB*Pl%=$ytJ0YNUf@9(g3)7i*jU6U1O5=98Hho$!k$Kp170&Y@{}3*d)& z7(7?g8$S^ERU!|f1%c`lqHGILS-&xGyq(5!P26aKIAb$Ni-enohvqcXxuwBqy1~ON zc#%9*TyQY-p&(lPt(Ssvygs||lfk%j`^aVON2ZT_>!t0(bAR^u6@FUvNdIJKc3PU> z2f^u+M*52M?IW+&>>U)>`6>rpoI}Y@qZnFdY6IF1w=x`paSpmlKZa2%BXA3Jt880I zWhgOM95)v%D?>J2a_Un)qf@s%>QW;hJzCO`5^Jv^=RTO)B+F%SZkbIEDpZLE%ISQI z*1`tAPl!T$Cx^(Av6Nv50DV2NKx!c zHh7j4(`v$w7B%p0(Hv1}j$S{LUe+hiDD)wKne_Jc#vwmK>$P4qs7#{bw3`%k3z;|0pul1I?_2E zTs>RQU;_#}TrwC#)^(E%=U5N5hONuNxHHegxt*mme`u5I-*>kVCz!>a+o~*rFmQu% zrkadgHEpoOO0-`>3FTQ-^s-l#(Aevc*G`J9X3n71bYS+XyzZ%*C{mWI7vo3g`hb9V zfYvlG0x%b`TfziKbKYvUX`FwU8nWcc>a1Qdm2y{CG@_{MM(8^69a}SSy^!cD2x9oB zlWpSht}JRq9lp0u*_7~Ncd4&*O4(|!x$5YfE{gGnMtpAuB$fjZ+lgfjv4pEIC6ld& zSFw)pRH>;ogJq#i;jKj$0-xZ~!QI4k(8SbtQ({VAdP_S{5?lY0_@rQoSh~^J>*@z_ zAgwB>HoyuM52IGY3vmOP4iqW#;R-p7ZB0oOW+qNubXMX^;9G7uZ8yC5;z7ImWF^8oxP=it)1+AnS3KSPh)`+&7AL)<`J$@bJFD3fQ26&Ms62p7`zR6Dv&tGkFmQ!V|wwsfj7oUyukD@h1YV zo}G)=2&>nL7Ma-t$>GWn{Nh%tW#W^Hcu7)76!buc(}ZaD4EN|gD2y* za^~>@E1{$wtQTWg)s&@tmcp7BM7HRkouw8c2poZ8cSSK-BRjjL6|C>!LMZt|C|mPg zFNlpav!)dc*S80SHi2s{Ol6>A6YyY>jAv^mTlg#k$;n!&m+9s?>n9b~j>K9f6cNq~ zHm>HMv2Lj~^a=~>t~hVu2`Zr?DCmoY*`Nlmp`}59YTXoB%-qtujAhN%q(sMxqY?{F ztP<~x!g|31VYUXQ>JUO4AR3AhS}{Xz69^45Z`?3LORX+q69!vVx)7%tkWg#huHRY+ zrr%--=?a4lV}LBBVIxE%)6$P;0wb=%usFB~m?030EhO{MP3n@=mM{&Wxuw`>8s`zE zie`w6n;^hs9s=&1W=Q&bP*YM}%WV-^Xxj7fDAL3AYUaROQrbP@6D=4$U zlacbGdZyI@YE>r6)mT_@Lqv5Ak-auBV1_(}un)2&=^{01t)am%+V}_?a4||2lq1Ls zAF`^i&?QUU^}`KJM-Sxk#^RF68*Gqsnj?xr3&o=fg9xqU>H76<{sPl{1Ogy7^e^WoN9>k2cmUf6CO* z$k~zxI2ygGL6E>yjoWhNDtTkF2FHop8MbKLG?sWZALhspGgdnvK;v^$u%(C1Tivid zygK#%ep0OIXS*u0nmn4=cBB}QL#U-EYe>DhOvq(!F6COdzc>a+vKeR! zda`vkdd6;5KYG#-a%3oD3L+wm*s+w|FExe3^T3$SJv`TQxEwSAU(8h|2k($^=?E_5 z1`_y7qvy=G8gl=L3TkDo%nIlWlX&rrmu08&qz_9E$ykys12RfhBz)l`LM%0Ye9>%mqe`Px3rS?jq zCI$&Jc_nFetZ@NEuRS3M&Tm)7mTWnn?uO=Ir4`;88Kk+g)J-0&svJ4=`rB@>Y%HK0 z8_ObjIM7E;(+Q$qfiMvUpq<0fY;X0bC$Y zW6af2ygD}C4)!+CTq1R@q5-iqMU1cpgM!<`Ht!PpIl?)B z&FTJz$!;p@+)~u}N>OJ=SDm|5XJ=98-lEP_ z)M;mnw0sA*3z=7B7hzXCZd)nn>33yOXDS|diQ1m(*LGlJTXii z;^~#e?X|`2wxaCz;^|Gr?JX+slu#r2mE!4+q8cyn((L1Iduu~}Z&7f{`^glzu#zJy zoVS>d2a9sewxK0G4YpIt)8HnnU=VK+m=4{(qB=W@I(HRyb{2K+?W!|{1D9>V*Z1vQ zSnafP5x1Uqwlc3T+PPA7wiN}hEvj!X>fF>-=N8rZN>Ok}QT?u>&d#nn_o~hm^AV5R zmRbk53%T{UT|_!mf!kI&`&Slqt}W_p>lDmx)UAn6_K^-GWk27f>f6wgeqL#+K1@U7 zwC#7j<^6XCrQ0NElS_lLkCsyHA~YQH>f~jk5ela2wB$GLa#}Kbe`tA%f{%cWMvA>s zt(KkPp7*I#bLk-{&|~A1P{>+5nS$F-T$cQYCmb+hPxXT)M+2Gzyq3Bd}i@#nd z#Rq31{q}sT{azeh$u;@^lxbnzPy(K52X0E;E!}o{j?$*b?OKjLHYc+_;{{@VAW!zs zKQaI%M5q^|SOCRhPqBD3N_(grljuO3xE{K= zW?Wy;T6te?EJo4Y(iiNmvbw-1**G0+UsN=Bv!WtD>4d=lVMa(24gU}D|Dd^TqQRac zC!Y!Alq^53*9(IYdK*6`PMD!mV5o(8R2YMZljhIFh#wzDqW9xNS{MEAg8m}x4{^t; zPL18g?V!6wXQcy9Q|{!p;ckDDD`J#CX&*K zBPmujC+STEN!@KXNjHt+Eq9Mlko7^KhorrAs>EAs%@ZzRqs_$^zx(*)Ij#EGEf>VC zaBTaws1-Tl?iG5P=vR|XBJQ-t@R5lnLR^LLs;p*fDT1irpT!r+Hf}9!xEyD@>UWsnE2CPC=h{`GQS?{S z92tk45ha)A%cfPAb`6iB#+V5_5fi&7?WGXcDLDvS0ncG;B3_ zE`C1|C`EHulg?7xc*sn8~CtyR? zxXT9jZVLK(%VJk73w6x0*zc|O+bjz@V6iM>%*+L(e#_1bJpIMd`%QK=DT_;%MLso= z9Ky?v{f)NmI_ypWB>)6>icLpdbqMCE4poIX(>(2$VBnc|jMx^GTCQE>t((iPSy)U4 zesUinV~h4yv{49+IRf)II2sB?GD5{x@=^mgT=C!VrBDQ@tbDc!rl%j?{q!J8t2uvdfkg_xK$Vyv*heiviyn&~6P6(`1( zju=;RF?PF=y2ZGH7)QAn6ZAujvox31h8rDP(Xb>iD2bUYH=;0Z|Dn?YOjc!KV13)% z!iA*S8`+bt|LbsL2;i+C&8bS|q1P_?VLF9&PzP0vR;F#pxfmFZ^NSJlw)wRp&eu z>d4y+U9cHuoSCieJYEqnGbp3(vZ(vz5~s+P=Jw^kbNg~aM;Vzv*RJ>H^Tu??Af@PZ z_BQ>)kAF3{5_2Wz>lqUq{*{++&t9cx zxWN2-QU2_LP+Xc3vQYozgGds1Lb#&s_H){TdMv_u86a9~LP$}!`m6QB)JcG3%>lC= zGbwv*2sukdi)&J0iUIH0%$$0zh!S)?{3Wjo24~Ed_ArGoNadd z$SV%mEUn!%t+ku?y)_4Hme$;Sw=4(DMEA9C4%jTM5t#0wB+-n0ZOs9jr8O7ZD))`R z*S@yqfX&jHi#?WGBQUwItvO(`w6?{C@JjmYwfo+h12#)*JA&SEyEEA1zDa2=431+t zPZPdMcB2844EBh8St-_Mmf8AvyVoiiiiBMlEg=TQp0OZ+MGp=iVfd&s7~|(>gmJZz&tx{=#@EO;?cstrzinBAa4?9UzLYMxXpp{`c0z`RgdL2LV~(&) zWYIa`q1<&tnyS_fOQI)^6(ldhyO!z!VB6NHeH<;X8WB0ra=ej%#5MJp;~3a9n@zD` zpfwz3XC&-c&utD*X*!rIGS`R%S1p)oG8A%!m($XwUQ7}x$k9E~1pEH8jgyMZ30^oF zEpa(ccKV2^yP(<52Pma`Y6ut1?kc)dq2>n)1tG$*^6#J(s_gE&6%>hb%8OR>r&VR8&@ z0y`-MBwqv_l>ni0!o0?0{a<;8(t6GB#!PLQ4Q_YY3Wi`;4L!u_!DM;KMSeBKc1{Ebl0JI3EqQr^_!;8vX z3l$u8y;6U&IrH(SVau9^_I?v2ua)F)7bfl>;N%6tm-0bXR z7dPiY+k%@vkaKfj%M$&$dG}FfSTOY**y%Mm=Up=4%lk`k+Q!U?!OlVY1g9QMx0ZDH z^q9`wB3>^Nld88RCUsr$OzM9)K#oU`EVF1qiVlmGNMS5WJI0~;^F8O#yhb;NE}D%& z=}^I+Q%W-K<RBc zqG-`&9p#2yv3nY_Q?0V3o7J2<)5U6eFj=gIIQ=$qT9e4VDSA};G^N=uP7Y%kznFIL z;?c!eM#pN7DvZ=vi>7XHReoxTVH`r9Vf+tcn8Y#6A!UXsI@Dp9QiqITh>{z_>)ik~IqsXnUvek&yF&82oq-2nh@rU@P z;mPL2edY$|+4endAHM{jxwPcqa-(oNgdBm{im*fz^j~wR z<#{eOtvTetf?~~qjAt0p`!Agzynm%RzbFNkb&}WnUb}3%2rfmZelUz8cQhj8CRI5_ zZ-XpC1^L_@bat_p3ugxm(u0k1%H#q|=J4v{?%DX)R>hy@m7NUD*c ztDA(Bh95&bp1e^WzM@3(a`*G_KPh@JhySZOm@?XA`Tbdh+j45AIu7fQqK`zb)G&_9lJ>PuIi`exRu&vUkb;=K5f6klXQ&z6{;e^7i z_90?7f7W!07Q(efPa{^B`PN@X&BX!-xpOgvX0Aq>QX{r_HAJ1Xt_8~md3$W@%(cg0 zs?sUP^qyjycyobIhZLu*b3Bnt*i22w1=*~hv6!;_ zZ|52;j*fA@9c%xVJoq54hrVZT*F$$b?1qpe?tVk4d4<@$P%(Z8b&RMdQ8*U)!gzZ+GZL%uU*pE6}EU^91fAj?U7`fEhUOxU{8QW zUj*JoI$bQ0cMO%Bcswx<%7Nx~T6e;UiZFIV?Al1}f-)AnCQgr!xQD5`jJnGry%S?w z$>ZF^6W!$``6G+zu_6L=;SvSe$R9sR7qDvEW-;zZqZhYHG5-r2BJWRg&lCX5^1NYA zqj3Am>PkdU0Ed{J#6!zP*IB+Ut&{24NlJ5fuVIjZAGkj?}3@+{MP4<5o5;G3?QLL^F3nGHl_FGdkl)sjF+cG0yht$ z5wO@(&iCkWfEeA=@Xetd1zCh{??VI~9lLjMBP>5)UE+t``-8qsxU{Rx0L5CzND%WL znwc9xue`U2vyi;S3Z?Axdz!baci)-ae(e~ z`hgt2`WWY%*EtT5zS0+Ff0FqcA28r39FAi!>J4O1AeKS$rxt3I-8mo~pqPbE<{rTB zfi2*4CP|JwTr3~Z*d_Tp7wCBL82SVVtT-58mrxoYb8uJk*KWCXAbFmDz@gJpXf};% zXd2b<(_xd_?F znWR^f^-#;MzWu7(wJeccr5k@ho{(ctwu)7<+pfC(Pg#;fMzmj;r9^BKCk7x^j3hd5 zH3tRgWD|6kHWaxNGm;l;LdU?c2?$ju`628>;Wn{ZthyeArs<@8OtdMaAdnzxAC?vu zv@aMA)>5J5oGGU+X2Ns?4VJSN!uOF(sJK8YX09&74fuYI)N1?x?;0bfUQFw41g_r%|Ito7y?MsyU9v$H%R*}f) z2sk#<1!ZF&%2TYt2XBLny+4Xzbtmp9OlEl%X{;4@%iy)mi=~4(m`l~NJFK?lxfc=t z8nJRkZWTV?j+nBx6$rYgv z8?nQY?)(zwpd5YI+vZRIAXZQntJ4Z9JHNYDNuv`wtE4)Y;uN=7%F-xn2`q{Ky%tNe z&5NTIykO~TIUxpOg1>{6@qfrS!q0ee2)x8;*ZHopu(Yep0+5{*)3;S>teEn#K7EeU zK2^J&RnyW^M$V9Xkd$RcSwHuLGNG5km>PJaoZQ?iYA#ZJ8muCWn)B9So~ZK zKcCR5XEz|utomJ};WB8pDBaiYj0zlg$`j}}n~@#>faE@BAI zfgvR-rDtUIhso>QI?8g^QF!AL&OAsRHX+HkrIb?sSxqtjS||Uk4{;r7701!Ss?vv( zm2RaPZL>mW_&f`R5K1AL_R>GLJke1bS}Uz3PiiZ&O_~hY2~M(D>oePJjq9q|zAdkF zE}1B$?vP8T3ccH1f;9)xbW@N4Lp@|zcGIiWIkA#0X@Llj>q zD~p?Wem3>>fUlC*^+4H43goj+V5ep#EPdGUyXC%&WeQ5T`XOIM;Ve^)WfDRO{{u2u zAw}GI6y&=rS@YnLQLIWJcLrQOcE^K`S{Xza7xtx3Vtig4(@Qtbikh= zbtR8tiAtXx`%uCXrLSyMb2+vJH6Q<`w-P>M0T$=^DLcZkt2^WK^g&rt!G9CvcT-1n z?sn8Ww^R3q#r@P%OZVI7mVQhX5ZxkJ0oHyOuL%j7Cfx-evs zL(GAa^*>Cbx zoCcJ{K8{V%+rE`Qw03UVX*IJ~|15tzs)Jc1dPzGs=!RtomYiQ`_toTIY~D0#i`OC- z&mZfP`dEo_i<2%WQE@%WQses@N*Tsyn=$_ zj?|otD^eRn8NE#bYVDX`3M?9 zYS;4M=#_}3d?`zE;c+?hLk-(&4(!K+DnNBH5Vz zwNyvSjkYyB#dz8}D4DapUt_&q^IovD3Hl9AB~%GWHu-vSvCjQ?oeLhHnardBEdv8d%<}uh4G^04<-Mo^91pum2--8`C4T^ zS`c_s@zSaT1YFWG=>dT80?UHF1Qvmin`jc*Ie~B16L$;|b|bxhw|;b?2T3HXvVqp} zRkVN2@>TLp3u&J2^Q!;jRC(97-|zZ|t~Vy(2=@qEMy+GYYOv{ITD3#c{lS_j2&clx z(GHAoB%D=S12HRTN`_*oO<$4bgFjOBH9Utw0I618eye=ankIl}P=pWtP(f+iF&n&* z`S<)>rpLWLJs&DWBnHK5&g z1B^Q*tT;Is{O)WGC0mTqZ|j3fDoj=e`9q8>#Ys}ZPqr^c(WX%Y3L=_9-fOCJ1ApB#FZ|(*}AZ4^omQYS-Na*`Df5r?O z>~ZI>u2*Br>c?J~?pHQse_0^_2Tu=3} z9LQJXrI05!oqU5X`NX_N>b2?$Eez_wQZ5=dOMRj|ImUd;tt>wUty^J5f1p z%2omqttf+vt3IgewyOz3yzU-Jm$Uvj2n?2Jf(v_q{yAA6H2ULYgD`o6X2DujcS&+C^AsT}lH|k-i2JzL?ou;7>2JKlDpsklP5Se9<&1sf6^G$l54{@ zY_+K87-^fE@GzA%CHMbd%{?D!N6v@02vybc*x|dbJa#uP!CTi%BtY4;Yq}SSQrJGf z$GG`ic3RM^#2IiERD-r%u^s9{bZjEoAP(1zb|g<#)PWHE?(E}bB1PV@HDt*sZnkA* zM)9uBpfCDip-44Anxgx%kripMe6)fBJD86s8#lR*eUC!LEVB9bj)eGgbeOregUn`M zqF9nZJ>jqzQAUxe5E-l}ELACmr7+LSMN@;I-6uxo$NI5~<+)h`w4 z#(-=1m!lfYZBR04C&_+!O9@}b@K$vEsO9nqoPj?ImQ*@xk{8W&BR+<@u* z14c2w8*z7VN;T^~3>Y8H@gf&KTxTUVjN1oFvE%;4V12>{yRRf?d{m2j$SZ+`$AVUq zgm*=J*xwl8hTt)^*b^8p&CBs2S%YdH6dKY8h4@(R6ZAo$rhQOoNOKGYbDR305Me-h z7eMcPP>5JB!w)uZ{)KrJQ99&i6CMs?XDG-gY(>IID3sv11YRaOfGJRsc!7$VFTN>c z5=~{wBtPX<++AEWMvu{!Fpqag-C#)!fdiBl;YA-7A9Eh;I} zCu`aUJe1O#1zr+MQw>vFaIy<}P*gz=ih4;*`DNQ(ESnqcf=lRRj}JO99)1KQND@4k zBwq7J@}@Ru@JuR_$Y-xQ>2O@zXud6qwMWZ7AeHv){YGQDA(?gWH~pg#B7=0nogj!D zN~hMOQ|13NNF9oqm!ep+Czl;)!$zfsXonuM$691ylxxD-EQ$+SeeNg58QN2hd!xN% zwCc}+KsSmq(AY7$-kbulwBfvFs#Y_ z8K3*)V2<4--08#3#J#v1;;v%l*wXLI>8omRKW_>A`*Kjh)VFvrJ}!8Ke&WP=T=d;F zhs)u1CtMzBcfv(;ch|>*?M^t)vpbbL$nI2*egDE4y3_Pw{9x?3JJjxktj>7>S(f*X zuxBdw$DMM2)G3E(Xhw&MgL~THM0NxVCMbmKbPyIoVmlHn$ivu5E!i_HxZOfKHpOY` zxQ9$I4KraL(xg9yB|lt+6I9UJ>cGg@U3Jzb6l*jGc6)$iV$1ATzVB3CGVZj@t3Ln) zkkg1PV~T0u%c&j`zAypJ6F_=^^4lvov-Dfea1Cd8K+f<$$r;9o(uhog$kQHh{xA@7 zf7tlO9T-;w;4P+NWQWY#ZJ9gmp9 z#BqGfg^RU^*p12uK78@fZbl*Qr*)3TV)ez~ptGHQguZ4ewV=_4g%NWdqvv=?GVgwj zP2K#O%irh2UYY}d_!2H2vLolz_s!hUK(fu4PscBspKb03=D6%gzn4Xd+>s^#C+mwT zEl(AR7|Rn))tty}a|-O8?ukpVGVXmJ92w7ucfRZCI3&0Yo#~>w8zuk7R~1=;F)BJ2 z#Gk7V#zq`eyp`l1{~PkA!d}CX?{T0DZpU{qrBKA0(F$Op&O8{t&8HMLC1OfpONn3B z!Tr{dLV-qiD!cZy$fS4&n zk!@?>Dw}mPaey_zUQc)adk9rrYbL5!BauL5=aG&Qk2Se{&P@f||0d-_MnxG!7P5^8sKw??VKkN*~ zAo;LiaZJlDi)<3lv=Te27Fhe!nzUV(%Bn7oPNX81gnv<2A0cu=!;9L0!>eccFL^xh z-6Ly60CtVN?xTNnHCRp!$IngO` zoGQ0qC`*>FDryn&NOV+ZRZ(8I)U-`QSxfwt&X!`hSYK2jzlhktV?JJP+N8l*N94;vc7~MXsH!KD8_`y9GPxd@X5S9KFVb4o6@i z3_)ViOx{(fFSJ!52xMawi(@r#7jz)BS!SEcr_hKQ{gGu@lm=#dV1fjXP?@7F^Re_} z2Tzg%LRgaua!5H|#CAmIX3$&Go3DB&P8V}0K~_{WKSRMjOzhh3m}`YjNskLKlx7Tl zPeIFBR|O#OG|(Dwg`bnNzK{Okcts>vvn`n!4K`M7fl@h+(Y<0*HvS}XLIinvOYKf9 zbRtj4*5zLWIeBBGS2EhB7Oe7-Cb1MS*~7Goj@sA$A36-sc@H)OGNo>BdZist=o{#0 zD4~Ma!4Rgl&z`)Z$X3YeS~Wu_@+#6=*{;}au8*|2Uej>Dxt>^iot^dmJT1-w3{YmV zOIZvIx`I}Im-}X>7t9|jP1bLXIV@lw*e-m6?OJQYmZPvHI8KlGIPRMJWQv0qOWDfU zJ2(m>&>)@>#Fbks2DAQzsOgE8h(#5jQjB)j?AL}s%wS)A zv3wCgh;I6)g39i88}jKjG>~IZxFFDnb^w}p+y@YI|D)HJQE7cuM&|+;ln#KB^YJFN zLA>hCQS-;4lRYi!LJ&K$!;N&Z$el4%$)-3m14Ciio{{KnAB==zT}hw(PM)B&EQ#$X zz3u%ZnvqyR%u&saooD2f9lu<-i6d%zKaLi|gL(MW@<-8Y;x->EN6zFuxo3Q|N)ry+ zR|#uK)suJ2E4AgZ6WnRLbd{-_>!5M8>m>H9NNJs+cdW4;0HOo{lNmSS{Mh2%ZGxEl zi;tv3O|)#-#XbE-+3`X0ReUan8cco?*%)V2i0=MEMR=U-nC>K943|?JtDiWH)irBC zk75<~ zYST3nyW^N4Y9$E@i{6)MW*Tw|WGcIGVP_6@jpc_bW{th9TuPb}O zK8qkqajqC@9Q7MX$6LIe^HQ^2!6dTJHyzs1`fJVyZj_Xw_<__iPmJ6Y&B=XSxpzgRH}r#bLCwMJ3%NNSE^T_$p^Qj!{xo^incL9_yYImADtfzwY zK*B(LN?4=3X^DTBWFQM50;+f#vZU5i0`HFXOqqYootI>b15@>mw8L%{)9#%N(yE!T zfLI5g=C!>;xHiQnd^O{#nkM54d%?jRYh!#H8Q;PjC8o7cg21mFPb&Vz$;tT>29{qT zE{09v2+yLfclWZutzM3%^()MyAiRYefHRa6T0(_!WZ}UP74aNBHdZ|-!hb%zqyjKj z@f}J%7ZXr^#8D9_;(ep!-y#muCim9HllLQX$tz9GOw}d5Z})n8XRSj&XZ}0(5kA^W z2SAt_Kbl8m19ylUKgL;Zk~9#wT2ReK+;C0)wjCv3LvlQVJ8MGlYmswME-VK4ej}(+ z*dnL2TSP?uE%lB_NL|~h{PIeeUUYx774=6^KU8u-tY|GuN`hl1QhLycUleAcw@T~8 zF}n(*x@#Sf8an4v8UaPQ2;o@Fx&6DLq3;C*p0dNO#Xm>IJ8Q|C!VYaOw88)014P@Y z{Zx}&g2_b(=xl^|py~Y9 z19W~+=zM7}owrr0I#rf^a4vIU`=06Ms-@hJ(QC8Z&ismy51|G(d&Klg$S*;ec_InI_q!vd!T7$`;s z`Fc@i`7?vcpQ)uy%b%%P{>&in$e*z!-3vf*TK-JblRratxGXU#+YV0N8D)gG2GmXd zA1uLf`7;<2TSCoIQN|e{)O?XYW7!TWnubSbu44YSct_6Rs+%uR^BQ9+{CC>O5qu; zeAyg{wIOqdl&YLNie{EzT<0t3+jM0|vFt14O^)V;N4pAljAyxJX9znjM+~C1#0o)I zWpmK*Yt1EH7^E$^Glh}#)-mFARc9`DXD2l#aV9c5vN^AZwUTEfpDNe|&P6R;>>ZSn zcONZvfA3d#s-Q4Z-|GY#wG^ikh0ENdLEY0pRS$KIVqK9d<0eNjAE}22`gp_+kK`uY zzb?o9_6Nv!+r3}xHLugaP_pE+^^qu}W{(H#r$MvG(`X@tnzwinVKO9bgJp2*2}^PwLW9Oqo(17vlvCdB%Fko9K=$m+9J_ba#ls+X+4@hfKs z%&D{S=Hcv%Iqhhvy|Aj@F#4AJDf~i3x#_zWHpe?ZaWfyo~ zo$rT&w)od#^qsaiF#3N$qyK^4(f{w?*>qv{>B01=b1^rwDUzT4&Jb4bXRh~X-n}R0 zdLN?gnlmQb3gSD9a)9{VdiQ}O{zncFfBL#o+2}ox#NU2^_`f^if4rCY4;M%FlSRjz zBRlngg$4V#=FVq#@gl{#6bCh%ru~tXY}53FwO_P?S`LObXpL3P3E&YK^8cRt-R~LieRQC11vl)BeLFh?; zGp|Ug8VE+dUfx;Ht7ID|dlKQ|>^GL%R&idDvKo2}-61~6xtm>Fb@{a6G=Uet; z7Ksw6Z&U&d*X?#CD~O{8InPQ-&&sgaHa*Ei40xj*6BcLN;730{01A%3@}UJ%8O|4K z16!U2A7|Sw?Ss_uQeJTZ%d+8FGY1M;)nwZMg{-FDbacCdnpCRFn3a)++`Ws2GgjZO-&qw z*hx|;`V(jO!SQ5QIp|h8i}DuijC){qXp-+*aO?aKkwt&yscf(3AFgIUJ8qnErAt}P z(hM4duH=%(hxgTzH?mPe$rDW2NEMx8i{GTBl>6mEsN%B9Z!yt%Tg+}ZPQ%bv7Iq^> z8a_^A5eKldkKb(Hw(Rsg6~$e(7lX4_^ts}g{lIEKOrYA_sdm61ty?Na@!4aS7sq!B0?^|)$WUKhpnJe*#X2$4j)-4FCNi7kl+n$3Rh(%?W$6hWb%T$~ z=UOY;N8t{aRBy?v$C7Udp150h!wyTl~%1Mxw5oTOB~|3z!z4Yv>ngx zJznV(znbktFE`P!VAlfV?oISjB(Wv`2vc1!3U_f83^QYtM*&!sv>$s0_TpAz2HJB|9MI8vf4%4C0LXvjpp(VHqMdK*}6{<(-B zQZ#*XxL^^o3J_Kqvr($M4M3&s4u#DUY=N=tT9~4HlS;WdeB0p}(*_PPX^PS^POgx( zHu7WJdt%?Z03}%{xAWR*d48yKUf*9>*Vha5g9{lHTDz5|iM3ONpDv9{I9RS;a(PM3 zk48IdrHw;BCr!=i_^qbn**c_6YnA=DY0cwZ-n3S8o7QS>(^>@UlsBzO<7(R)`=uF| zHg-8?7rS<@MQ-OBDt;pQN$6jrGHu&hyV^Olk4|+qttqoLW}iE3fa1giaFP<6lk?ro zwC(of#nSXY&>{t__K%gY;V2+i0-rVwg6!7lemt#&C z?uB`F3xiSUmZ!W~f6yvg`6hEt2X2H2Z`hpfSm>qw&XwK^8ej`aPev)5ct~>i_JR zQ|G9@et<+JD#1ymV+G0{xOiS{hE!vsoN+gmz^sbr5@&y&0!}8ICXM~{0T`4n>ZlA# z<#n)t#@8nC9t7J?J%}OpM*yO4?HmyRNURJ%8Ib}CDfaglkwf+iBBT-AUqlw{7ev?r zaDNdwa=#$L?t=S^$Yb{lBJ5PSzla>OUl3Vx{}DNEzaX-mv!SMuq-!!>mS3|!UVfvF z{C*4=GE}($cU3P5u(lOD3nu3xH21`OXsp-6Chqjj-ni3ieveJ?FD;(vY_R-?!t%Pj zV_Dwa#1l2GSs47XG_Aot6ntAT6U3t4K2IfbJ z`KPAi?qESpy~6G(HnE&poFq3|yNc0@@ao-PKurNxpPFRP`Yt;?&W_Nag|ylKrHL>ih>e^1fWDN%zaidcN3bRFB^P6lFnEaEZKcX3ID+&JY(2jqEZHfPqkL%+Yc zHCn-5(T%`|>#otQV!;}Spq^^&0nR?~kspN}9~vL|x!xbJO15#-nLTs|*&jCcfz3g?TjQ~^S18bztPDOyMs{k^14KqVz0XQ7_Z zecXOehfHyeJ`K1SQK+-rdS+<7@mCu)A~l4(a&?yvyTz76eHXUqYj5?uuRyR+{`9`) zsO;#6N>{L_jEc+Ha2$vp_o&>pe^BA9y8BI)d-o42oMty2mA$0O7Ok(sFvg7gK0p`t zLuI;z&&n$o^`O#sHt%_*n9Y0LKv2Ms^Va=<%9X(A1Qwu57g0-Wi;5~m2GK}TdhXQ6 z12zvm2YDVEHt)+(pTP7?45(2r7;sutiY4o5fvqkEDhIau2d449AE3Z=mrRxsF+8wGOXO$Cmy}0^Nw=$oFVZgcQXa*Kkq2RDxJyb*9T<_q?NjlEo~L`e@`lL!zH)h|8dI7gE8B{=RH)l0~_8 z-X%|jVr@O0RKS*Yj%aEoa)OUVe2377;f1T7j zzb@DA>e628q^?ivl@T!|JI(d(nqN<3!HkH6Gf%PmPX+ox^0eJceZQAo>YWPoL&WR* zK8QGW`Tp!-{24)(ze7}bKW+)4=TnG9B)<&JOf<1~i)gcADI41ZXnOp<3?SzogV8s< zt{%EoG34U2U2B$I^SOOpYq9M&I)K+LUCy@JqJ2I6x)|k4o%U6!S(YfemTPSO()sMA zOn3JpkiOh)XCpo6h>?ZwmXc6Kicw8N3=7t7|atth%G3_v7MI*I>?u z+Vr6mY9U!2ZfQCQldNlWj}J=KL!hRbhDNncE?~dtby4|TF&Bb9jzRk z%%xZ#HDSnH0+VA#lKD*?gnTPV-|%6R<1>^O6!LxCVj%>U?~2%#q`KqimN^NY@=#@Q zr_rVhR*sxT%&e0qZvlgE8QpKGN^ng4X3^ftocx)6sC=2mo1zbs~kixm-j2-*#OWVeh&Jtm*B(?}PiYIBeK#IsLJs_WbJ#!RNR^uU%p^)+301TXk$^U{!~7q6Y@zv)5S)t z1`VYHJ-g9!ZXHkzV<2nwn$4Em;YNS0I(y-QJp0y6Qj5g1h;Mt*cDJE&2Hcscxg9el z<1irNnaN^HdmHxVLm@u3t=rT%UQr7JfOpnL4vh?e%w!2C<`d+ImOOl@zt7Nxbb^D)^V#MY(?OEqjd-eRYt?V+a zXCtfGh*xo6>(EID_LVjFHCCOnujmJ)3D=TAOn-yw)}yf!3ZwcXIvIWo--iQ8veGZI30~X+tQj4XUV* zX=`g~8P%>{SNf`teEw=~z>JopY~^xG;%&EEjCZRvrg%Z@xbft|sH8jO@|N++1=eg+ zS$Ft;N_3ru(t1rtcNn?!k-#!6BNs}DuUPjEhle5EAv)#NyFx=bDh7e%ew&m_cX(8K zbjQU}9NA9kUL&pz2AG0#We+CjUn3(fTaHQZvE>zK%PZoFN{1_^*>bE_7gq>*SuKUK z^ARX)d50?`N=`G_`4uQLP~xA-cHOoNquHg=iTLm_qxtqJY9R>lG@eLn&o%pT-A}dW zp^JIYZ#}k$uYxi}C5ujid2AcV16!_@qU&aXE|s6t9Tq57+C=xRiGk5ji@*B|8lOtt zkI;t9d>d|H>UW)nJ;p7kBbGrsqfKS#SsOP98bN*0@j!mWLuY~d-)9f3m9i4M;W^IAE>BVihSxIIqtX+X0lX7 zrzHq%yXun6Q8@+Npl4ijxad+LnU9GccZ04nysaQtUj;xZoPLPvyds$&Demde966ew z%8&ji2!cM#XQh?tvr-%zrlXwNP@0a`H63MJ-R#rR9_Gufm@!}B;Fv>FFHKANF14e4 z+jj5u*i*=n&waayVD{43oMSpff#UcMwXjFk{B*v%CeC=mu^(yJGok%S=s*13kC4C1 zxqWWmD-$^(oi*jOxW4w@5v^qJ-PkyLUr5nGVYmr~4aSatbvxXchOcUF8L7HcWFq$+ z%pH7kzQSZbv;!VAYjJB6Q@B*eS)v@6Dwz-n2>zy~q_0XF(k6+++T7Le< z(!;suo%A%f6|*|Vy({s9Pvs>LPmS%^&X{)r5WlQ5BMhRw>L5`~o=n?8vRT`|8nk57 zwd}{ARq^~WcxkKWPd>-PF*_^>%*KKj4o92@*7d;3o%f%VV}WN(r?O0a;KLUmtxwt` zOw>9yUX&%t$@+3KapR-nB|6K8`QuUXB6k+rZMbB7FxgJHV=kB76zVgd?vs;1y!kbk zzi<2X7u^n^n^-H*bnzCg8IZdponbRPrjvZOKJQ|7np;_3hLeJyPFYw`w`!e1+743DOe0CkVtx)IB=v<0C4d?o~2& z6c|Hj9AzX%#S;sIw5?{wu%0xpz$^7t7gRG@e`{HyF@=p>u?U2NNw9fv7RNcJG$v@0gF5-|6kbU@LQo zNmT_|-Gz22-)M9tbN2ipM-(}_gRgtKMnxlcejh!yW9@*T$4E7WN23jz^H;L%5XSXo zZ1b`4wG68Ud7D@s(%qyt-7ryPszS} zo9@J%iYWE}D?GM^?ExD5NN6EZ1z3!G>k6#My0jaBNUNxb6xPvaXBlfaNbxXNT0yxK z5R5Uk(IemaZ>JyJGfpT|Z%7f-xs)}XFNii^EGrqgS^$@9Y=6Tqul(Z0o55Tg*n<;? zLy=z~k-e+K_Fgps+lq_nNDA_aMCpZw*lo8<>*c*loDxMZ(!ZA@b%UE-v0r{EFV<>^ zNdVG7kxRXy$m!se>0!a)jXb4FMiyOZ9H;1=#&Jt${P-}ibc-pA=CSbxzV6$kKY36&>CbX^c*(`rnIuJ{8j^&Et1~O3#SlK*gE~~R67blW`t)6!*Z(5;}q~k<4C;I z8v23a@Q-zzfePp?B80BcEO5Qa8?3k#mJSF(MZ46u+!d zNL9o^n5_ShX*61c<7uM@KBy7K(#8!`QtCia-Xc$qsK89~0bNrbPZcxPpfo+m8AgM# zBpYR{iPjlDx?HA#AHg+c7x81r1jx=NX}WdO=nj)W)LD`qvZAA(oG-E9A!YI zc1@QxID*s!lI&Qj@Ih?rg^p28wp!(KQ>KjTXyW8lt#V{H2jfsdC}npPw|5q|V0aua zQO!$D!lM)1O6@ZUV%MtxgMw{6=DG zfPxo4oRjP}Nd*1pAL~)VU2-V`0-ZHU0hZwpdLSgCs|ncLwJpj$RkI^cMq?+=V!e!o zQD1d5dJ9MLQHdBEd}GJcAx|~aciZlB3f<{r30d+EZ(%PdcOA-aK}BO>%^`B!U?PAX zMsMLd)N*seIHTVgb%58Y0e@i!Q7q;`R5FIm`Xn>aaNjwXD%S|Z6K;q#YQCk8u<@_$*0s++4imTpJDEQ2|Kb!~||jc}3tMgHd`U9C0& zGR%h5q{SvD+Jox-U{*N?A4sebN=4KdA~{Nfh^JISg`)^fT51xZMW`n($CP1F8kp_D z306zP6Q%DkEq*FEz)DFQ@*N{;4q(huH%$?Hnc3ZT`>X!*d(V-G5^Q00Mg$pzPa3kz zQjNL{fw)F2t>T5XhRp)B<~XLC3)h>#@CBst6vHMOjDo)rE1hc((m86OmJXTSNQWg4 z;3<_55ZyOh%^d(-R~-#pn?})N9AOtx2t*ce!QnNO0(5U)(6n$`TZmT~%8}%s$@%R8 z%C^FE;2OFUWaJGGz>d7q!=|FsOmML3j-f)0$pGsy9}cY%(PO}>=`Mtf8chC&o~&+3 z+Ux>@t3M}lsb$-xYfsYc;^-896PV}UTd*OYlRH`ip@l(UuArk9u;FgK8jTjU4F`jI z42Zz>HP{Pwo2xr~+7}1SH%GBfn6*_Q4y+F0JR2e+-cFZ`tUz_kX6|Te810%Cu@!en zwEE8ho9e$!K-GT*-H}#?f6XMGzJ#xqQ=!eFg-mW1aLTpx4N-J}nOye)q@IY7u(JrM zKnrIV8FR_~gM1PH%c_Y)hqwz1#qQKd+r$$jAK~0ZRly?>0G*2ZcmTUc9=cSODF&sl zAdu%0ntxQ#4%J#3EDRd$I6Ii7ii4j$pS#1yvz_szkxSwTFrml-zg6Cmo*hy3HLwG3Y_-<_!Jxr&5 za5gJXp;^@}N~Xklun`;w$lYd}Egc1&?rz&{ie$ zs~Nv=P^2Z$;5wt#RE*+yn(k7te8`P2jicj=#e&Xh>KI{Li|L$m;|sw3Qe^N0V z6ABq5V>;Z1H7=cMMxZfh57;^IdNY)dBP6!jqLJJCTQG7;QOu``>Lg)0B?D{gWpd7( z_u=CKrhj5xrGJ_r^&tqAGGtN;O4vq%GxKI+Bk5Tij71qtF?mGo6*Ty;+ z)p!B69Z3U5mJ#{;T^bQ{+2jN`mu;s#ghUp7h2fdFF#2Ym5jc1u*=)3{j_vY)j^Eh1 z-6c;K&>y(h2D?7i*kX1EePb-wxFQ=_pQ+x<#&y*0mq{!L(}s#E5u!0Rbzgj*;!|ip zq9IXxPzoZ#Jk^+zXdcUBST`^D0uJT1+LWaTHY1`!yQwOQ1TNbl`f&rRf7Pb{v-GdPulTt=_#e55-tcQ+1J>+Tr~LNdFBv?V z{+hi;kc&gSe`>oPx^PT! z?2$y)7(K~&X|_Sq(>N23nkF2z&V)nmCyHYCYlkkt{aOtpT;(G17OC_Cr)PVIxv9613&msY$S4fK_x0m%`QYNncn91Y?)fQbY_IzE>p z9wSG2LCKNTRtN?;(j3I(h$F-Bk#drh2}oL)=J$1u zYG(q705`HxrG-_^`!FL^)$GHig;jB3M^_VAEQOX_K#BPQP6GB>6A3wEHi59E1XM7O z^>zVobAKN%3)XX!BR7qe!w{h>ay#HABg`-StYQISA^cIvK0XyXLH_mvPHJbm;1|_Q z@wz_93?hwwSrIn}lOS(LE_{eQ^;996#MGjwqFIo1f@tUT4)GwUh)*v6j(n+!mOSAQ zZGbJp>L9!_jZE0MLk?YcPC>e}Q;OgCii#|Pe3Y%hZ*+trYA-J`R+yYuAfuN|VU3Iy zN>T+Tlby;N)uek(X?;V$SC+FT@I0lA5-v3q%wlzsgUAIZ5~SL;IB4ig%X)L=)`VR$ zV5F2;=&Y)G@8*S4=$bAC5C!17-MNN&JWG*)q81u>|BTL;{p7CBcq4Hsrs^WzR}v-IUym@-c{wh7D6{d<*hxT;5&m z+4uiv?_IzxyQ+H6z1M!7v-hd06^L3=@v_dox&58AV3%zOCDtXi4<(k@a4oNh@izDS zitmD5ouHkHAz!+?LY+W>@DQRPgos+H011ykL{I{TlpumUG(p0{@F)QxfdEl?1VPfj z|9{N2_S*aGQ;(R01S$n*t-T&|%{k_n<2}agXhK^;Un?3Np|2w3(DiKNYVZMCV0$Nt zI|_CK5W-kwu^hHKA@kJgfKV=N}r{wHMsk1J^Ns=>!s}c*^AB z5!s1Hd?xAbsE<{7+wMFEFaD+LVV%BJg7O;?tML@#$ z6d6qjL4=(etIENOX~8|@9_e9*S)(Cd0dwe0Af3l8vc2SXJgAeuZw7U$2Zc1O)yhmc zpy$Xlm5kE@?_2^eHSGoA_R&EY0R&z<0pZ5rs@AFy88N8$yUL4gLB=RaTz5NQMq$-u zKu`*x4W-c@fuu2(Vbv+J2hqZ0LSfast|)t>6lYRk;&q7h~zc>LW<-(R-u6*1hs2^A8}9Ko^{x z(;mE}kF_QXYt6Mp@xa~S=*o3j!EI-GrzNlaImCd$C@(;N691I{YZvGC<)Vb`Hlc>~ z)f6f*P+ZxKu+g<-!9}pZp$pH~CWidR`iE)4zH%EyM|XYH#v8V{;_C>(y)a}%d=2cO z{_|3}`SQx4_r3YmDOlzbE|_gUvUM5OP}~QWvJkE>ZHmY9KINasrsH9uC>3wrbQ1TUwisOHy z*L+-&JB@neP9q|BXx+grf)#BzaHnBw4>#(8J1v|f3f$pA`4Nif*GZD$X&soi9wIRt zQ)Izl6pd1TKjsga!h%jMaK{r+^oC3sf=xgj3sj2SX-r1$&`nuH>GtZ#9qGokv7;qL zP#BX^_*Y5Y>|?N+9745MJYxgSH5!O|K zJ6bOpv%ZA4$$A5gTGDY(0>2ctBU{%NeS>1eS4$qGqY=A9>#uAM8zE9%t?ujn-%$7{v+KjtcgRl<l+#-{lCEr^Jj@KUd zY99A$N*CEKo&GeC=sxvozNBTZW((Vt1*B5VeeE-1O%bys_8WTXx6;Lun)41TV52;q zat5)W$aa(%jq1$3b|^!18=)4?%eBiBZ2^p~D z{U15>rT2d5x_z}a^G1GAQ;}DGACg>hv< z`)kZaf2J3qugAnX`ZX`YfZm$dV*P^4mRs0I#a(9#%vb`OBJXj&4P$@qljqL?eH_V5{(tG8*}*!3c zCh*;S*19bb6FWICb=xxyS%SWeRo8y~Q_p(>)&b0)9-2BOBxZmwZA$7-D;4OC$*+SG z6p~ z>4G{%hhSYof57|Mk*-qei8s}uh{F=yN{whJQjYUCvV6suR}`$Hi5I=nCm8RkG9d3Y zjM}5y5zNJ5nFd3dQzfBzBWtN=JeqTd0n(J!G;qvB$BS->%b1C)2SUwgkJxmBi&!N1 zONZK00P;7`ndukoeiIpC>WO(nnxM1VW;ykmzH0*tNQ)8C8#-XVV3tM4AQ0!;v0j3>il_fJ)H_+SdYurFjMhC@?+ElnIGPJD`vW~6+ zSdI*BgCq<{7yF8g>`zCA(#3jYD8wo(r)6X)Yj;*;DAeiRjtp(vOi{*%-rUTR{5Bng zwyjjE4i|(50+H3C2~pq~2!C-izd7n|CiKwCVcvKy2yqoa)f#O>ok2%11+Niugq4V% z`qPN(+`cUR3*xNsDc0Ad<8LZoBZ;POsSj(yCA#^jhNTXp1h9fwA#lT`SSoNG_}NZu z#rAG8TS7{k%I)Noce9zlIHJBzmAFi%%+W-B$w3LF*x&9@h=-UZN!6i6&4^o~OXk|5 zJbYa)h%QP>70Nd+iUNWjCX}xaD9Z>v>9>6e{X@s%%|{H84PabWJ2mBDPO3*J2#cXE z3>VOF2T~puv>@g=%m_ge9Z4ZbJrkA(LWei9#-Uv9u(_xrpM(qN_7y=Q7hjH|jz_?k_Q^F8XCn2_Qf#|6@d9>#$kG2etV90wmSmzR! zB%Mo+c1*jH&qU61C{(CkStEOF8q*GeEe$6Su$O0FAhVG15SmkvGUcTtF z7H;i6p&8-J5=8UxGW$HAGOEvuVauU4?5~#DyRy=ZlMw+suND2-GJ8LSha(vfBK5E# z*;EpH*;u2Lb+Fn>64=e51&cc^d#cY4N$5NWu=OqXrfiuWc^EB8Z}}ffdIwrd!)&=3 zDTZ(RoTPVMlYcj)cN|?zwZV$g3mdcmpRQ&XYU(sM*>Xx#y!9UqT;T`8p1S0Y?Bu4z0^to%0O=44vA7I!X?+O(m(4W7WqM2+KBTb< ziSH=ZVrVNG2Jy-W$7Qus~;5@dVM^HRlz8CD?)5f}N9zkVjN=dGZ8o7veSunB65Hg z-DVlem>L{uih&3f!k8$56xF0|w1?a}rB#Uj$?4(eI0kW~v$(0^=ad@Kml`sM4CQhb zC&!`S(03NMzn0fDk-1V6=}v1Rs}eajOJKW4H4&KoeWZyTw^?}RkJ~InVNy2h{l#W+ z95;{SCMt+s*Y`Kvd|p9BXY1+nvfkW?N7SkQ1rc-yn^=Z0yI8ykodn)A>|GqWlw3h% z<?b^8+FYgyK3};0}!y%dW1dOG)F`SC3CX; zM*C3!rOsc?F{}(k{1KJtrY>tHkYF6Ldi9~(UUAd=(5taA^h?iCSB7*79sDWTrZO`4 z_k@)J;YZeQausaNjpuoeK+Zptl+F8#gXMjTm}}AWq!!DSl*vbgCVgqM?j#x=lpmR4t(G3xeXetL;ctDpQ& zie3Crl1O<*LX%{je*RX>is{QC$<*QHf#Lp7ZRI~PTnM|8uI$IfKj3T1IvrqIno5>H z!gbyha+?LFA;XbFffiQE>FJJMPb2H#216AWV1_xB&k84k#4@aZZbS2)^NSW6#X3Z} zlsT=0XuTM>OWVJ~^gKF2fU_06H`g&=lTX`QHIVQ;Ya+cK{$7hkz8$8wD3aym&0i`n z0zigu8$E+`1y29a3&!qML3!Yr+yUUvaJUf8S%wG(;(l;1n2@(+`XZgZx;b1x5AbrV z0jggtgyztfb&3{MCj+Do&0!$T!J}Fz`gSLERpm-gMfixKN7f0fpjHeXs2_G+u?W4c z?2=_#s>Rhyiz|$f%~@*;10Gd*X0EN#LB4wkWz(o`EdQlVz?0Q9Yu!-Rh!t2yU0u=Q11r7w`YgVt?7Gd$uIpvS z8c$8c%H#D}D^II`yz=_7@~940TY2DIth|1G<>^JQy#C=<9-d;ayz$dsc?tO-c#D%0 z>6Q1Y+tVTg1lY^NW_kIS%`6sx)Zzvl0tC;=^@b_&gmB*{vJ$jEae&gO_#mDPr}Kd2 zV?}gOE}-E$AXz}Jp?55%2YKZ<65~OIo-UwJXBH>aoX%!=i|a7wu=0521U0bQs;D*b zAg%LeaYFGRSryBc8e@|#m$t%{x_d@s5YPkSd?|86VV*ss?0m27Y!BhhTDV$*0Nqp# z>K&wQT^f9`4!{aIa7uEE`x}bBR#ZG!KtS~iTja79*#^!vjD2m`36J!;JrR%N~CCP!$gg|7>TO|~|Bh$l46cUDC@|BWT!az&6!6hntFP2rY z&lW!__SsS!HQZPQqzXU!`3(tq=Pq8}_p36?TO_3ZRgA%8Pu%v=4^iTR#|7piFH(U{ z4+*U0fM7=+P&v%4JOK2-;91PXZ%eoekqR;v!jA0dNz@ZbCQTJiM*J`d;sz3 zFT4=zPgg{o%5}oPs&ZX-T)D10sw&r+Qvgy0SkQ5xkrCvr!{Y_#iOO{m>y;cN7G6Ub z76jxu7d+#cgI-HAUv-^36g}pLd(VvK@1)~;+kITQZG&UWH5Y1^>7`9Zsp51-o$6~^ zIJ#GoTEa3^t!!=M0YPoYhXf4Y>6 zn7I6zEl_?G6=jkb=!%3~w6Y~ER})p?V`KYU>2Op&mb|Smy7DnxH&s6F${D0ZCouv5 za;Eu>A5(r0BcEV_?1zuj>!1dVu1X`0Zv3WNc`K{=T?sID0nz0%qPCoCj)lxFZZA+_ zfiCZ<+HHRbjJOx-v~kY-X{49-+!-Yg3#txJYvj!jpPa;7;hrFn;DGE#nx=< zlg<+YxQQ?G&763pj%V6x^!Vr6YP5h$SKN>MF9qQn9ryJYE$`^%+H08i@A-0HGBD35 z_tlA1!p^8H_th!OeG#^T5Hwltt3$ajVzQ##m(1)xrA=5-r%#SUp+nJuYAyx2RAC2j z%?CcOU(^AMmFhzgzm^oNBSPJhxvG=ji2h1=jHtM)bSV!{;Su4jaM0sKl`dxkga;a> zNV+C*iu$sX;BkeDY*Q*Mf{#^RD(RX*9#fSroUGyYRh2I3mL`YoRHbVp)F#>ynn)va zd59JmCD0D`w;XPvfE)}u(;-qv7fZwt!%xU4RAWJ5FdLX1{CKgag*tvl2r5<{q=#FI$QmMu>VtN5ul`_RiPRq~CK{Xipn3igKgjIX z*I6ypi(r|L??>zN(*P+`N`b*)~8#@&zZWQ-yj zTs0`PFG*}O8z@0@G(9pZjeB&={Sm{+fDa4ocr_?7_WRY=b3p*1v@%JFz+|F|-eGPk z>#m}H_h{A~#7aEj7_;sWeSQ$L?oK7^?)qsKbvMFYVLFO-F&!BacO{Nt9ai=(j<*if{KZIbOS;eBDqeRrk2hC$ve-JUD{9vslK>fozl!c*={RQ5{ifNX zJMK%#{`ZOKF1yAtiSCzoI?8O2=w9xLIuT%1v9BZKH#m(?d=Np$CDOw5CgGYjB~uyJ zEDEC8F!E^ZNO}-$idR+(`LJgxb#`IyXvTHYZwu2fQxQAp-v;Kv=V7pbI9R6MHb6~AuCRdpFD$A+C+Usg?r)= z6>ty)&ii&msjQ#_?^1bWviy_sqj6<3#)Z#Ax{MoyZS$s9?>sV`rLJ1{6o^8>}Nbs%s~Q_ zhw54lrUOtlNCBf=keK+u8m&kY*5>hO`7u3O0zV^xGDbT|*CXkthaBjXT!M9t#T*8S zD!>VIQ-yKfPjVtnCI0kA4?D)hpW|hdA2^EgJAZJ?CeJDBRfU}wN`>)WS75IiJ$_IsTVTKh3iGOzi}aCZT!&^ zCB8=rAv2iL*i)4gI-ayH+-1s+C#|E++|L5Q|F&zd3|l;?)RZ!3WJ{L5(Y7!j1*dAN zR2f=?S2~3j%`QB}x<72aDT?Gwh8Ed-NTarihlR;WirSnK$xq=#mXhERcgAZ1BJiCS0TL-WNV?k&Y(v+g~ru_d0|8W(rOVJAJtL3n0( z*5>oSQcfvpd2$shqfuo~)eXk{L=^}fyY;rFEZsR^cF<{3^6TMDwALwcD*5#aE;`YV zx?jn!$EXWME33=g#uy-VR#VG0*6P^J_xm{YCLflL9ftNhwHBzZ2wDM_1iyIet2bNAKQ+G2EV-GTSfm` zE=iS_rhi+6@4yn~ql&bEpF`F)lsRn*4NqxuQ)~p=F8e~g3TIC^ItTC0*q+WA<&2T7e_yAaxOOU7?+lrxG3(noMsRG(!TQQsWwJ};ADUs+aq)g7Kh6Y9lnHw1b z1+W#%*JG!sC~Ix4BOCoBRdaA^|2+5PwRT96wk#QMW~JI7EUH>H3Eab#!v6eF*q^wJ zBtQ#9Xu9EWlmjVebp7|hEB0|p7anim0ki2XO^{pU#bRr(RCVIr84Bds+_ZM-1{V{E zaMZ(r3Z)@H)kb+tbyE%lD#}~6lY%x4sfpp$$jKQ*3JAZCS;zl_%2R?W@v7=!Mqj zRods+%)$mk5w5Tv+7xF8$oTy)nzY2liTC9Q!OmC4P>+B58`WzV9E=9QKp!c3dzTxs zNg&*5uyiLL<#(cQjsjruaqCt8q@F@6^rq;#X8A1{NWSXY;1ezOw=bs(PF$Ql?1&Tp z0M6N){#jr<<~gfgi#a3oR5QkWMZAY^iy~4xv!##`lSpRiW&a|2?@7YgqlzIS>{YZo za}A9Xe%OMen)On$)Pig~x~cET!ppSwL=9EN%?UFF@HG`# z3+v`Zeol&7jQX=*)2L~t^@wav_V%YQuN=JW1Mlwb&7TB<^Tfx#X}DxTw4!jsE;=?2 z4t`_{v4uXVh^mXBQ0F1>_p;6d5Fq<~q$&=IXVK!=Ws{iBToSUWv)vMMY%?oE9W$4$ z0(!#$i_A?4K=mpPidjOIE9iiNH8gMbPzp={Lfy-ehZv`7zFD-KaEoU8y3@9by?Tcy z^=u_8*j+IGxpv^10YERP;iwQn%_$wa^6QQKeSAaEi9(dP3eGFH(V;MO2%-v<;! z%c>^G0aDyq`S#3?q`0$jN08uYn9mQrm|+bC&r;zY)^V8_0$DZVwNiK0i@dw4Xl<%!x`X-6zhtZSltBfjy1%+i?^ zJ+Fz^|pfR+Az(qcQbWsD86YOO*P4!&TJAa z2LIP;QsUmM4jy%DF-ENpuNn!BmSI9}k*o;_v}h(e7jTL7SH`JUEeZUdL&=}{rOZHp zd+@wgtM&92iggk!scdulbB3M0Mdw-COc3aTuXmA)XF@)yrnA7goP0Lu{={=KFoQ~AP zPSFpW1y-Lzgrdm2S#r^2NARL$)lU`=J_%l7&!Cg#XNRp(5xb`F{bu#$zT2fMOr5*j z;5@3g(;aoQ=(wVLy<2gg1?{&Hk_l!GvluF1bMU2R9ntBVz^^}MGLw@XOI-9;Vzi1I>7*i*;{auq5?50RYo=F; zS&WxRauiLzDQOyXX5Iq%)@r7tR&FWdTeJEiBrI3?;QiX!550CaN3HL7PTx(>JlJyC z>Dp1omj8k!W$$rb1#?r{GkQ24Zeq&QvE}u*%Z|vnS2i%KBbm*?3Fd*6vovL_`$qUTeCZyF8^RQwZ}7H?daHK~y!>T^A*mc=Dk4bie!4&K$<69+ji_;;Xa>=)a) zO0o)1XBOuf{wRY}65!TC5O+M~10utq<0-moiU7k(mJ0`x-gb;-@%vt5Rym6c+TZDMS4-Q#`j z+JW54E7)S?&p3~}vf#5bHebiL%*pvh?_3w0WH_gL;0=D$_x9+b3)mXXyNih(HP548 z4?Ulo9Gf&H8!qAW%3XWt`F`MB1VmlgG0Zkul<|Js?1rPOPlq;c;@SUjK24rWIJ@7* z#Iwn79c-LC%(Uy6ip}!_5dbfW`WX;H1r$W-zWVWF(TF5IMvbUiz6tS10D@f8P2D@# zNH1pb;z{)v5v{8ip@0)F(vUxx-rH1vkF`*}Cta}qLE5Rm_mKK~qPJy7Q8p&tqn-MD zKU#lJYHazQWZq#N4=7USDke-D|ldJp+(;yv1_zxN}x_kdaTp5Qm}9_`fM`{CMq zwRxDDhUr=Oq1s!uNtl|0sVO+I_EK#IrY2wt{tvFbR0IDM^rwLTpxR3{*iV6e3i2n^ zUaA3p3hq;2&&My-pgs-sDVT27XQ;oLlW*?n+{^Ek0 zT6rFh_vT3H?SDdPrL%{F^Qny0+=GdYib?~_MUUOI2*=a6!(_v`U+9cp>=(M{E1=mg za0_#tUr=Y3z+>)=JoNW_GHn;GuGh%uv1>R z#;(52LZZZm!T8nY<>lLeHllQ5e*JL%cep#N8MHuAH1hvbQ@PeZ6>e7X6%_^YSI`L(&dbSD7^*a>Dt)LP@&*eO#b^t;7 z;thO(V1|{I7qx%U)hT!+D_bw`Xi0%mdhXyKIhLZ&^xtq7YD-o&v@e|)%Jc$g_DA1M z4;AaSzv5|)OSXRQkxxG`KI7`I{mY&2eCTh!s(E017K1S6IUa^)kadK<<+rvy=D;w! z-V2~V`h`UWDuAYF1b%W4Yuv~vp`<@L@o6k{2}hQpUi8Q7e;x>SNB?^JPcYt5bFqVw zZuS_2DKx;Ch1l7#j=`@>JlZCn9HAImH!Z}&(V=HG&-!t^oa>7@lLv+)`E8 zf$kkl_wy@;CzQQAogz;g_Fp-CkVh|+Ip>)-NO}cRhYwCq&28Jy3^w*t=jsIRhz`+( zm6hyVKK-Ec&f-U5igd&9!~<9G#D?O;BERB_16LdvZaARHKcFU&qRW5VzxrQ)_P;DW z{e7n&*#4AT{`$rL<=G!RegA>&&C!p&X4iQ)>GW~`%Zq;LSAOMYo!<4j|NE9d{f%36 z+WIN|_gPN&5A*%k+tcX&9vGg$NBKg=cp7E55AH7>OfU8iv--2TduaYWUpbx50hJpA zDjHyM!WCC+|F_noKH?a}WzuwUQXU$p;hvZ*4wqF8@LvEhov^`h7% zF5Pj%{-Hau>*s#xn|y|*w{QRS|G0DThQ~kJKsblMYh6CGw#s6v8R~*>> z-DmvxQ)u9Z>A~{V#q~C;Rsh(bkL2o0^FTqRE+&Dunsft_kHLRTFEFl4&9R7maU~ia z{PzEcO5g=Ob5((~ym6z{wSHGXl%!sEqe8pzAG?q{^w6;B>D ze+#0s)_0nI=qWq|8Pgi1^L$E}+|x3=Nc<0;VCCVU?Bqy=&$!?$IH5T4ScMU__szRD z?7`(HR`J8$7}ZCi_#GC=#<1_`2PR`=fVA*qt>6got?V zV~1Uvq}@2tGmZusfO`4|rt&#O>$@jvdgwwyGrnq@^WnZaE*|8sI&Sot?*tj>s$ZnPKwj zALa*M8qR*mXX@;UoY7fA*dOX^dhS2?OwavT_1sBCGhb$XIOMIbrSv)x*1@~FyT(99w6#DZ75E}Mfd^UuRV_|r%qF`M!;!?FMtK< zM#lb*cvX$kxMbqy2}qIZnJ?m;#} zdJ+@|8l*0XGoRAhRwit7@sMMpptX$=wE^jXH%ZU7!3DHMdJI!^xZDGjZBEA<ZoiMSg{GQ`L#wuQh~ zn0s1BLdqsPj!D*$Ij6a26CV7Y9-h0#(vGsJr(Vsr0ghfuLgwG83`G!*FtIIb*BC+P(E~<^<9VoV2@zR0G-b2(~H8t>sK`q$LvPquwaxyWSfp zP5!#3b}#fRbibrg+91xw1%>vw-U*mWIatgIu=r5G!d!Y1x7F6s;I(90f;A!-JHmgl za5}D-u7b)Ln$@nTL}6r73!iYBnm4s%QlhT!xDmOl-=tD(dJZF&PLp2RIx7VU+t zWk|#7SiY^ouP^_{o~pJewXXx!aDv~#iQsdQNB9*(6NtdH@}J0gFscrxiDyx$8~lf^ zdG{_yhj|0eHi;EQ4|N53zeFDN9wECi+2ya*R(LppQO-w zZEz0tV=Ox_BnV!tBT@!#khTDS#bUV+1nw00G5i zv`Q~Qg1a#N))PP8x(wSsMRTt^P_(Z*fVR7`^*1m7^W`gt^V?+?xa+P@KjtYO*h`c8 zk!|Cl_>YjN`Rd10HVx<360dFZE9S3_FaWao+KQ2S&hn*ygP@W>hCW9)z!uJ6&(;{# z`?h=EFZw*3Z|5esMQ4|WajEt`jF=mQ-SbHG{?+k5hShi<_W_h)IJj_;bVYg)KoO-V z>-S!U$Z5P5P`zK%3MQRZ%QX{f@+;E1vxy?UyTk;vRcP7x znK66Ab&qWA8%m9ZtDj|k9%0GSC&%|~WKbLKMZiQVOFGN3Fy=lTf4C0EKDb`!7w-|ULj z+C{Dum0Asw>pvbi>TOyK8oExl0e@NAqv!rjBmXqUOXI356+`r2Pt9gYA(@J2kFz!D zGB@{EH($B>=I-)EPl;y3X`W2NeKxi9a(zOmgh1sSGr5}M^)bimtBF1G9HR~d+#ev5 zJG$dp!ca}{)mVZK9pwZcetHLog({m^YUR{70IdLAZvQ#8avpF{y|aSqXE62LGf-VP zEL0Z)s^hIezYlSB<=G{!Uh<(v{ty3tTooFxL5R$V#YHYL>u8LwMyXB0>H^8s4Vc}v z<4XfwlGc6)QV<54DJe)~o||m@Dsc>_%;*JiIztk&_FYLr`B)O74z(m9g8nxa8){OJ z#AxkCLaRs=oIpdLQ7R8L(PslB_A{BH*8F}=^ucUQ#xN9*`u=AkYLyaHr125=u3gZ7 z73N{VeOPZE^N091p+EGEM!~RB@C=x{Bnf@?Udj$>6%KTNg9Pa$hqtzp999kl*gRF*umXh z%tN%qmvQm)6`2Ft#XvLUo|dyZYBGJ}IYX>nMozCpK@>I^x#!V%&De^$M`SymUUaV6 zH}xFv7IQz2b~rB;tdtS7r7;eM{6KqgUXUpN38HNo1Kd5oz@ycNtCRe)cIAj|G~^aL zcb$rGc;yMyedOH}t{k3Fmslrk`2%4g*`_VqAxfuiw1r1nT|RtkSqL8zK=v&TYCn|K z`pe!#qB!ANg;TJ-lm7q9n}!43)2_1883HIP_BF_nLTw4+HT& z=!xuRTmoT~D7E8kNk#LQFOEkd$ZDRrUxU9Oe*)VbU)Cl$gZbe1X&G3_kohIm;vZ${ zDuriV0ozF6uZddBWBsRuYJPv}H81ksJqgKULGEv&p|V=nlCr&A_j|ea_>LVH8eb`W z6QY%*Z)oL_L~oMT`^PSDOPsMrqG%zfUwjXQ?YUCew%0B;SFQ^FtroUNk{JNIWwCeQ z()s*R@;9b-ZDD(D4##VyoOVnY@n_$Aj7Z}7u?Ui5jQAePlIVM(el5}+CC4uBxeB2e{&p89k;`iv`0NUnrJGxSJ_}a zxm0+;mfBO3Br#9Rm{FYzt^_x%RbK2OGVWo)E65%eBk)uBjLlH6X*s*Doj)0i*f}s| zjl^Rah(qfE`V+OqTACuvS;-?JYlqwhqjQM5U_8#R>x@q3Y8un1c`nrh6c>s4n{JCY zs;VX4f799hw_WxP_lOU9OCi-_f)eAykmSZNIv7#_f!ovQfD!N}D_^_nau@6Dts>+) z<9S#r)^Pz|;NZnb{YShDUjjg&5#E+a&|xZ>TKP!x->?CIZM~j&JbfO)t2XHoLRLYLOyKVHX);7mho@7hZ;4 zFi2UW5SH29TL*1|4&vdHx+i`<$JSpvcY zzlk%i3cE<@sfP)>kYI%Z@`#~a`_P4DBq!QY*hM?SE{+Q*0ui$2dD3By3(wAx!SRRn zkA>&0a&_1ynNLd>+n&_0)3Tj9m8rdJ2dg)F%|9rnAdzpZ*h#>ION3&FU2t>MbaUg# ztWxYqbV-U`+lrlc*gdY;A#oqa&HJlj_kjq}%2FV;N?10;+%V5e*KLe;LsU+(wo54B z#v!&CXO2qSRkkU*t{C4&av_L$XpQ#CQd18lWDT~>oRsmewvn?!<&AnUs1=sdFxvAd zvKA@);!!?0yBh{2=D~YJGp7PNme3^FB>_=+{|JUGZDOz`81{IjF}mQasTUN3VL?tW zD7GvfO=C7BDyH9*-eF*93DMey8Q)5pp>!7F>IvUrW#l+ zR328ktv6Llw?L*G)0BWbE#21NF2(GC_^ghEboyd`1(5-Q?1AVe1eF3(CEOlJqI8M|d6()`Mx9uO^*eSPvkmEqf8CG%1mFd8}@zQM)9(UzeSh^;` zaVj6_jUDvsP+B^o;9BpaTRY+f_NU(-r?WSTz;dAgQaj$fdy1ovvD+zZg39|vxlzQs zz7t=zDUJ_(tdqhfR#rarnm2y(ZTm2E;EITdQEe6Re_)h-8Dt~U#}BEhFAE@FkmT%N8*z8Q843>JXJx~`WIp6U z)BWHUe6}_EQJBGIojHtH2gMb)kQZej#q%r9L~Ox!ol6AOrJS2Pf|&4k%UStX(e7pr zzpofph?2fUbOd`ooJ<=Xo;}ooIMR_aI-(<8tW)V?)z`ccnM)^o6ADzZG?~ocP%dt4 zu|&&wI^}#J7%`$g_*U9&0#~>CF5{^j$vT6IZd0JIq=juHHKu?C5QJ;c$OMD@4klyr zQKipn6A5N5W@+&8`?m@2_k^Q3ZcwYytk}8|W`LU^|0xx7wFuz@z|du&lN+;26JB6e zX~Gk_Z466ZVHnAfZPOii5)taK9o-W5Gct+NIyC(Sc5YM;C4(Q;9cAH$84`kDP3}n~ z+G=hIn&o}YG_}N`XlgO6RZ~mUZ}2%Gc1$f*DI$JDEY^HBdO+PzW>fVm(7Q1RXks@m z65Svikm%GDzqKwD*$_o%@R??&cy;Iy82~kFODzN7^LK{aFp=4E^|uW3rdA*^I`kh* zC$ft?B9;R}XKR=#@?Y`@5|HFEA7s|ZM*oi{fioF41l_Pp2ymPUy1Ee1wQWJB2`xcf zs0#eoQd80it8CKTF}1{!@!{QBz2;*QXax?zpQwNOl!}|C>aZX7#>!L0O6gD*Jg0vxHU2A^?G1awRLVW0!RL`58z#$nr*JJ2iJYschwX|xQrhqo79WR{NN z7L>86fO}{eIu4iB&gz(a#oZGN;+jn&D?P>JJ4{F=8EP^4H)#V42^y)lP3N8gYliw>ifIa<<)(si8t!*k0Ydfq=!sIatUfJwcX80kH6 zL<-A|a)gnRfhqngjFhTgVkDQRi%lR`$!C5x9EPxbR!RM>_DUdEwu|0 zD~i=hGLk~<9m?s*%#FHP!2dVOUaS7{do#ZUZS(=mxWchve2#wlb4331iN^c}LQ87V z{EVOC_qS&lD|o#lvO$yH1PrX@F7Z8oiHSxQTo}_G&1Nm1)9;v$MFtcPGfR{D)JMJq zu?T(2r{;X(fkH+YCAt+7y_Ad52XAlW-^AWr{tHEjwXlG>%QXU2ZbRR*FcMpwF$K3< zhN!Nmea_zbWj?Hxw6KU66G~Ad;5dCz2Dj1gTK1BlLp0KzTB&Bm$E_QZc#peNwC3+` z){VE;w(^iga-1@cIJ=Qlf@GEP)(NI`9Sp%DUal#Jcp$<@0maCO=C^DTx~RcQ&ps&A zLD5m^JTLYp3#F0&6zSOBi7B?jYfAPly{qk$d1A4P*2JTCLtP|0aUAk7Q(u&Cv6VtWA!DQFqZ&Ixvpj>fFH&_rLrF`_~e^+vz z?L|^K!(Mbtx>yov-ZQcx4PpWeE*fa00wDm%$Rsu;ZFLB5l~Re91iRScJbd4I_-to7 z+9}pOFO2Mx_|XRi^_EI3k*L53m0Yx&M@UwAEOcDKC>S8XvbWzwKhrI9ag_vxWvNW3 z_5vwrj}O5c8+_IKn8IPX>%t`Dq}VhObfg?ZMF zM3UVaPr2G0cSmu7=76uN7d9<1rmn05`p&$p1M{-`5PGL3WMw3r)`lgN#GUyg({lT8 zq^ZwGuDqr}yw6n$O3^~9By;DkkuT5qkTU30{?kf-G8223*mkrSgdusd>V!dXPcY9U z0Cgb%l%JkW9Q0^mDgyj%cr1_{#&r*(uC{usS+_qU*)TH%Ar)hl@C2i^6w;L`vuu&; zr73fw$$Qp*;?3^vfA*7`TNd7}NGiTmHXX@EGZe{pq#9`xisYS9!;6hyz-qq@|28+3FhQLp63u$y)!a5g9odh>8G--7c8l2Ts zX=Zw!17h-b1p$oCrAqerq3XAD%{k^a$yBZ~3Z} zANIC6`k1O?N9TlLACqbK5Mi1sV`3V7;C&xK8C`DVj}11_P#}4JR~FUwj9#;zrL3^_ z-Nf<1vkzg7`%`W<5}9qin>LWZlXrXHFrphQxXa< zhuR3~;+Y*vN~9b|=!5OO!&KelF)TXxA-IlDfW@Y7MwJi>f3%eDu%xvwS;QGzy4!WC zqbLHdveUAsCgPxMUhH99zLiYZ72PK}F!EKj$R#Vn(A^##L}XO=Z52q$WV{WTxv2iK zfF*0jR2ztpk~u|=Lgb`>yDfbg+`JSLSa|Gs5^IxWPSG(5p*o|ZL~xB(n)iSZEsRHq z)?sHH&WyvZIP3;Abm1I63)pZ1J%b)d0^Sv@!}74U14XJiBg93p z0kNk|pF!G_2$a(zaNQ-~ivojr@GG66xbL!F;@h3Dxim+2v_=0RwW%vD39|V!>CWWy zmXSL_m_3t&=d7O}Z%f=%6``vBSVydP)%L`#ZHF^>ITJRqHSs_8iZ14c)PR?G*su8C z^cK=EH(5@3R{Re)r}*DMuZaIqxm&LfX7E4tZ^5s!>aqV=$2*Kc?mq9|=uTYc>%2zC z2014F(y+i$I&$=qWS6sf4e$=60oY&HxBMT@^Fcw$?2_HBF9uRnQ4w|)>uT&yvi>?P zcw%8H3*5@VTVGLH;F9y461(}utzr3ojm`1NoJtAS=T78+XD6p3ZyySjpOrrg`oS?G zie+zN${-ICd&%t+g8B_K8#x!3ymr-}iFMm4)~QkUTRAP$CzL0L)(HBtX8W-W`l0yx zS6=wAF%Cr>mg2D42Yl;#1mfev4!X-HShMuC=;zO7Q5Jo<`Z$R0(Kmgc;Xi&jz+G6a zO{QYFeu=e-vNpQR^P;uMveeoH1>JG2&4OPv+0d+{wMmL!u}HgdJ1^HJGtD(jNbXIC z;HCUIbZGKnEljH?xhxLq!TKT}ZS~olrh1N_tm)wi+~X8gTn`P-LU8GxKl;vHcRh5E zuF!4v%~LWJ&R#E>^5(Fq+k@&h2-Iw`UbsYH6-HrhpFLVBKrx-S7iA}goq|#1PnL-1 zPAr~4QoRLCUT6GgkFuxH4{w5?PV=gV;n;Q|a{h#ZRm_Ptd9#WqC$4J1r&rku5EZbR z28=Tr36<)y(F&U`$a=a$$qKd0$TbZOo@RjSd6FfQKBBqM7wB#3!cbpjHcMFQdHTX! zj@U6_{n?{^zct#sN2FElQ6FNE@3$>JW7vD+xPaAqqT+o)@KyUQUZ}>ggwj{xDWkpv2rVabge{e_H z)m{GYeGD&6h4ctRVimMBJ{cYmDH{?gL5L|Ku5>rxu91)!7XR;jF*=*Spq0c@x5wK@ z*G#Gc%~tABW{9`H0S0(K@ZY9WlhPKmlD|+VnMI+DkLNE! zzEdep3ZgdiC!wzqbA@jPuSJ2X#GU+7>`nrO|3MGw47R{vZ_J zF2B-FDwuFQe8Yg6o|Nm5-na+(ive-e)(vp+O$i&mNv{N(x-`y1JFz;@!~7+}#|2i^ zx(kPN!3!#ZoM91-dlrv%^WSTUE-r|4(CR6zT`K5XaH&h(>9l3s=-Y~k65vmcvV_e2 zOBEgMujMZTAtk{L;XQY?_7v>*YFe-RE6t(W_AF+ji)Hi>y>1r^LD$<7g=Eo$rJ!`i zkOu0_Kte2WJ|^{W2^aK<>WB;KMXy-Uw73rMy}KM_un>vB?0DGaaM=TBIcOz_srAWyMu9|2|!FO#|ku1+WZe84G(V=8YF|`qPPc8&on7N z6T^*3TmDD94>zLB6|Lt3Bj*L#{h8-F*L^lB0xBqkTclkW!k zv?EBooE?b9w=LD1!xzL@rkA9JW}?>RsKwo29y`T6b_MGIBOGU??bIr!z*|(oBFf@l zn`MoOB3uA0PdgSX;T!d!Ug;)^uB*g^_BUIJN;kHHi<_ZW>T{{YgadRjv8cc7d{DLn z00n?9rFEjj1ZFYhDUgdN9m;zmDiJ7vJY)--K+aD=95|*k&Vjz=(fu!c%j-Y+sYm1E z`D#lxLl7~KOhML)KOKgcB3aag38V=AZM)f33fA|FKl?s2#epH1;ygEN`nqLBlesc% z4&m#z;nLU8ElXcFlr2K`J7H4XO1rFFhhBe0+7C0x)=SCXEwn87#l?1_K6VCMnvrX% z5N^UV<~$7*+!{y7T+k~rK(XPcUSC*kw#Jae4n#o- zlzULX>*>CVCOS4B9BW&-0 zhsmS@c4=WyHeGN7q6@=7F3=2Rn-SH(YI&)|J?~dizkfdmb^!WJhIOcsAe}L_qDUPm zl1cbN9OgI-5=E*rl9Cjez?;q|io}Jqd~{Yal8PefV#P=*iZo^; z6meLJ!)70{Epb5I;1MZG@+|Kxvhp)Fhn zmNIlUDZN>0bPvMw6Vh8J<;)f6%2sX)5q`9*Y@1HB#w9h7<(j-e5mLxcd4Z(ba*E)i zhcKH_v$S;d=vJe291tUbbT+`ti8H0+fD^EwKWT{(^L0;$uy>S4GV1nw?*ftq$R$wyEYYrN+PJ(=4EleM=suxkcdK5_7_k{#j!cx!E7kMf00N54tqm!xO_N)WI0-N{VoQ0)mi8o9IsBIa0NF8sW z<>Jk_9Lae3uvvufvZ^SlgXcMb~ zxneDE7e=QZez6Lp?F{EaiL`3SNb5ag2pXs%E$3}yL-_$0=VXS!s-*g_+PEk@j9k0O zTY0NAR!_DH5t0q6Axn{4j1K^Xs17L}9JIWFB7{Wxhm;8s91{RSw^%kJNoW~fK+1mB znI78iGtr_QJ`*iEg9eDalQ$#3ga`3IFXR2d98ZR+7ry!?HL)ujUH;!g4eaH=m@Yit zhI;U0dY3cW#1!VpoOCw0vfYw1%lu`$;}(;ub!`dTlZ#ge@FAzFa!bhE%6aiUEfOgx za+h03BxJ}x!Br8}T4_zja>lTC&Eg!$&_+m3WvAv;myASu#V}7GgZE4Tse}v^xd+9^ z^G$yUcqwOF@y_HrmE_GH0xp!d)sT@v(h%fMDtGC}=Df{<>IoU}j<$si?Ddl(jty`z zLG5NJF4wi;ipLT%kU1vga8$1kk``H?%%mhm!XCu?0tHle5rU*N?8qh#F;SRsvabmf z%w)`!usjId;%&wRX)X~ZoNS9sifxWsbwigYl_dE1geJkd#dCPCM3XLP5*LgnauS0k zbE*U|mns49!SH^jlfnL0vlDUA!V04T#e7B^e?vwvz&U!|&9A*#hKtc_brK;gdJJyo z$J(P0zxL+;75BXWL&-5n71gwVo*jCzX0q%?8=sm#9=}Y6Mbx2r+O!_O9EL7UzSOy< znFxynXX8_c&;^iAY_yq-YEp}3#1*(%j6CEWIDud6z-bP}eLgKz9x6|b2T3m`C>`#` zE4z~yNurK8mfH3K7;)PvA@Lh?VUI}n68+soA&P<#(7q-YIBJ&PltEjg@TgjHJkhpV z64#7jC>7daT;M;AsB^8dXU+UM+5m#seX+~1L5oU_H<27Xztd3|srb!|LWQzXAB_pe zQUipYzADbZ+*hat_{D?hLByIUoX6@57qQrkmz^HU%0f9kml7>WjD-egGnUR2V?nYOV*&7R5u<|+W-KfvnWBZ< zrXb=V;wmTU0v#zWHbF~tEoh0(#8ohdnRN4LjjPc1;kgPD=uvQ$L@rWwgTIMtGIJm! zW}E3M4o8QI!aAE|=)PoG3xO^XEhIFrmvuzKtpe2K`qhZ#MrSS0%N$ek0?pnyqG_Fe z3Y+;K0oe?WO*~;NT8?b+VHdQ{7YbZIgu>7fZ4U$*6J2CPl~@gy5*@?|6Rip>dRN^T ztvnqEi+-!aVkbR#nur>9A9|S37-BZEd?f02hUJTR27F!*J`Wg!?MlS+37^-`z-MpE z2?#<^Ivj6YP!`V^9-$YkEhuSxC2!<4P4?@FkBo-<~SGk1As@rf#0%K6El&*K9glz9yL-^JQ`0?<@$F_w4 z=u`32vgJeLmU;7I+dw+7{sY@aD_3^TIW7Az7orP?Xd$(KNbQ5Wdg_f2fjKSl93=a+ z>=Pp7EJd(mn2Pss^Ap?5nab;C=OvryvPMcaF`RekS`7_pr$$t@c!X8T`|h*mDy0Wa zT7fTRJ6`nWLQZOvYnV43Jrit3>zk-X9CYg|HnV;cD*%x}A%C<)9?SDZ7DF-SBziB0 zwBAM&NF(4Ata}<0J7zTFHKg8Fad+ORCa}A2sv+$^kuB2!5fueAh8|i`fyN{iKoLPt z8nFDkEPrPMX{uTNcx+d(Gv(C-D=+`-uzC_&5=^-whbEU}EsM(onOu?Wv6Xo*f zybVKD5(v=grsdyd`8$gc;kR7=bHUCSx|Y8~Iyn^Gdu{pCcD4M~ zu~o}|?rtpqYr1X8R#KDhE;}=hLjT3px{dO02&r6#_VF2?3b7(y!D#Jb(7NH zIxUxVGnPx8TgK?dD}wJK1eB^GDXaCBURu%0+tX%+!*I(a{UHtl$+TRuv|J8vR+!+H zGArC$-0}$0-_h9=Cb{KJon}vw2{L&#F@_P<>1gAtR0bbA)j7m!$OM9{qiPZA8Reb5{OKq0hW_qyjm|_TfX?#kL-Wt zAALNfaFOa2TN3s1Pqzq_EwJgy8e;`=3$I7IBAp9kTJLdurYW^jdV23{`uv;M;D+6- zi_&RZk9$-Dbd`~MiFK4z#qjYED#9fR<}!v@Qr88^;wSkQOIxD4E@CVU3z8TPV)>yK zooPP2;n;FLu*7{gNNe2c)T1=RWXoIsK&TiGKO);EFh3oW-}9gS-Z$^tn}E(x=QKuq zcST1Uc-e1tpI=MaR+)A9ntL|Y|LCKf%nT(4piUKQ_U1EKHtIdM?lA)tSSe%BpH=s% z%;LCLbrg%ILj&B7;3kzPJ^VRZPtPK-L_}pK3^FSM4Gt4{4XG3w;4x5)t~4*$Z%RN@ zm*Z2EXo!COqxu!*vcaq7O4t4h@!l=RMbtiKbJvuq70ZY}=RV55u4r$GR#GZt9-DgJ zrr8~3@NcGQ3P z9paire=z7|*}mYJ%UhR!hJGzPcGD$So%QgB8dEnVrO<8ZcfIA#v(=;oDC~4B&D!XZ z>NGekN9waH;kP_8iJYsRZH2E&PYmh5o{>3GBk#z3MJw3D7&&m)$YuVMSx}fNCqIL3 zFc=Lxji^!fS=0-b*AS!N0b(90x1gTz6T+uqwMG$4?#MALU6^Ex7DHCv_?}^VldNC7 zsdC%xP5F7uArh~&(CAO&l#J;vz!_EPR-=I*n;oI<#^1}_|JLmHHm`b5L7hf8R*5Sr z^K0{2`OB3k&b=yAoQ^0Ou%+#7g$K+J0d3hfb$54p@Ak=iy8H0PX2zvAAKoZ*=BjMG zv<2NeT_cNzX`(oD{)AC;(T@T~wpEL=7tD>y>ep{c&*9~~XsE$7$-pSu)MaZhw7F52 zq+2H(kMp=Ig<(7v#ztT{qVC06RDGI^$%De4b5zzhEypv9j9}3+4$A(=1+WM+q>!n7 zA4eUm83*Nww;y2~2bHc3o*xC`%bF=r%gA%p03hz-IxGa%wRjJzng}9)!mj=5cm37d z-pvcZl!{tETT)TwAty7gU&7?Jaflcf)s%-4?!xXP8?NL>k>ni_x0|6dqE521m~SO@ zSrjB#l}VQ+&)N>l zu2v~1@jK%}Unt?z(#jhYDn5D}U77@xVPs6@6Y{#52I1wWI6U;GS9t)_3r z^Ar5+uz}>6#@Pfk3M2;=97xV@OHf)93PQp-E)j`86cqX>QUKzN0=*>%%993cGcxev zbkrO?s|Ux<%CZUuJ;_xJQ%p3tY*xvoVD3$sso6~#(y1wTNT;0u%weQbHZV}mKk2QK zN+n(}8w4_>*-+*x7e$Fat{HGTH5~=oaF9$jrUk(;Y+t$J8q-@~@SunyAUT-y2N)bk zu_QX639nd;h7`%FNUM&U@CQf#32fNrp5&ZutQ$@*XNsiI1)&jy zh_eOGvpum_v#| zjwQ{5;EhoOZA%MyBRvXLO>2ju6xL7b#t*Pd)Q}eukR*Qiz1=uD$xA^3V11Q57UKB8 zi#5KcMX+{D__IFs6#9WcPRSMfyYF@l1J?{yyXIO#-2#rFExR<}QDYw~X|3qLKOEDUN04rBx8j5TSoC;PY@~+6bOQBqpn7C_Mca+3Ju~@#tYVB z$pP~T!pT!H&H8W&>{~@U&t#4vp5Al;2b@?0hWOwVKClymeid<8(g@s!hAlodm%p0v z$QHdzhXh0+7qB^1Hpep(Ks%#{r7{oLib(SX~u=2IOtGxW*adOaLPwt2r_$UinSW zfwqrubreD$q z^o-hjM%npxG-Z2Ga24I>MFF5S+f1Jh$Rg^oa4et;%H&a1CFIn&j?-k5pHuQjfz+>G z`GU|H&lCEwgpomY285S&wthBbQxO&9XX$!aE#-=y8HK4O)&(k;PKMEgJ`fL`=@20v(I>g2cLFy-+UU z%N?dTU(d#2!?^|ha^f)(3}x^f?UN(~-XYoV1Ij2z<&bR+3|P`e zCX_Zy>CC{6dvA(0II?&n}yEs4)!K8u)aQu9;l9S(&IQke-r zmi^E-tlUA~an@lQmvYx~b;x!ionj`*521lM%eXz!enX-G<9z`=e9V%v`dZH6atA922vhd!^vZWz&y0Ek3yAE!;W~MT zQLw8FaxSZ#TH$ZMEr%Bw@4{k0LAK=vV4(mRb0Dxv(PhcChhS%}JJ?u+uEmfTZDByX3s~<~fvP=UH)zTRIGT%1lAv&#$pstf*&9a&{x6>a2PZ-JyIDC%298itq;F zDUyWAN$tFWc4EQPZBPyzA&bLAi3(}5ArZylcm>%`*1D7uw0e z{GOJ#X;tBHEQwQPCd$QqpA zkvmirO@`*3h8z_o5TD~GQk2fRuLOg1_fU@>)~56q6KT`JpACN9X*x8z#| zXHmUlGiRH9jkT=IT>>2BsL=HC2Vda7+S0poSsL&=qg;pWq;(VTM07Xy8Wv%<^b2V8 z!Z1d!+%G%OxbN&reTB^jpJJm8U1pOBZ-s%GM;kN9)g>I`kL@5O(KLQ`&>FF6vpk{m z?r*+L#EWrY5WZRoRZO8`LNp(4ydN~Efa4-xcncB(u&Rm3Q|DqGXz zhbqLV(ys78%>;JJA`T}ru&OO4Q1oS7Dqs63Y6@DlaiF)qvgXuI!Ce`lVu<|2>Pybgw#pKji&a)_4XG_|A*Op3g`WR3vt?EYF`vIJlL43S>>8?Kq$ji^uH<b=S@q>>av0E2knuaIp^2Eo!oh}Ai@Ey7zy9NDgU3`ori?ligvGG53(&A{ zJj8PnWv_{)7F~zV#)P%eE2mo|d`*{g>U{0;7z0=uN33pX* z0dUaH`+08-buBw%LQ^}7)_tAzB7{W@sg61^S>H`_c(0*L_)p$-Z|nrM`51SCy6qJ= zy^q)obgfwdMpIM7Mqie3%E)Cv;Ws(p!j(+e=9*_eE-yC#>JNBN4I6R z4dur-n1s&4_9IF;6;5b|W4SA(S4y`+k$Z@M*224pT1EuSYiNwbCBvrVo7cYKI%^_{ zSpkvK{nneG^|zmYTu5~6{(@KwO(EoeEU%K1cz&2p_1ra0fJk)*jL_8-@F}CFC>+2B8+)^lZQj-1F<9E z)6P$bvXVz&v*ZXVh{T6&vL#C5Bh-F$P)Y;E#I-8Uh@0LVRXE-1sdNM`-xYU{@)-&&<~I?~)F`+o78+j4SZGS#f>N@msyHXHbw@dI zVomGF3+=^sd!c>1-HTEJ8KneLWf15`Dm+Eckh^P@L6{}flIWOBRWLm+pseTn7IFAO z$B)v4f>fotcIL8&DZ(d7012exvgVXzuYpD+Usfg*E=y{waoKsX@?gZoLuj*^;X1t{ zvCS43wgZ`ELXi&4gh-A+Pxo*Y+rT`0Uky=Fwh$N(F$11Z@;;h8MeoH?e9$kd6f2Os znH#~vZX*dZ!j3=yp@Q`dWamC4o_Zvr^6cseGr@4iqH)EMc~u;lPZdX$Y+)+@H*+oR zuV4rI{>Zg)W4TC1?7Zhy>;lq5=mTFH{RNw$UTrPLT1^V?g()e3?TIXF9>VM_G54mA zTV8HeJ7DbcGg?%1fz=Hi6VldAIwG0QZFsI!5{H24vw;tY z16LhLaae)_%B5z4|MqV|7v&Rw_(^?2_iT9bw%_9*j7GWF_dKvodwr|$h*zL%>LZOe zhJ69jdwpx0LbNj!9Y@k*J@wN}b0km~N+ssANf=?z4xV$26(3ktMV#eBy;JFBD7Zw= zV9M{ylt0-BMl=Ojk%J6Kn4kPLEooLUCMJ!$N|1m72rXel$~q!=@v>&7;Od6P?CDp> zQd}-*!IajyR6CF?`HB~pD-e=d6Y)6NB=tV_ClDP{UlLDv9B(6X4wkeZPd=! z@;xo4OPS+pgCX^TQSTJTegR!(qCFRp#DIi9I#}&51i?|StX3-ti^0;C_bfu10zo45 z4Ai*PxK=(8)8N_WElOvnF11E4AWZRfbZhzz$DhRpVCreEXwU+yP=$3~OE3GB@SYwg z45!&~YFS;FXJ!OY^_dyuFIL)a{`$1ys!Sp3n;E}HWYdHJNnKF;WYCoNzD5H!E=Bj2 zD3+bx!v0jdG1~8xoOj(Day;R#wV<~Gk~S8)XYA;jYBkN4<0%J^tl<`GOJ}0V!L^F^ zbuz=fV)Cu5yez6p+(+KXwaV^8%WjySS1%p8^fp&n- z4}=b*O~ZVn!(^>1JR6>5r-qF5L|6y2;UH$yw^Kv>CQ@dis@t56U?+1Go>b_7WK$M( z3(tnGg=a%&2g9?WQ&_%=2W_E2qydpr`!{6VoA5By#4MG4Ys>S2oV8Q4tcNXU$?`Q_ z*^Mp5Bngw;TuRaQ>eawB6Ec zxHw+>{Zun9^D2$nl=Yf%Ss9XwcOPX`x-i_`2cVCMW3pykHlt>o3VzJ28P^NSAOR1X zA%YZbt7S)^!f|v4BNfkM-YE}>@CC*?d|M^S7Rh~fm$++f+A1uclc8E{)nyN~|MK_8 zMjF?B_>aH-S2rym>qZ){yQlU&h+PgUmoKudGGZj4iH%|?gFXz8G4IIUtCM912`65p z7cA)lq_y;tDt9Biq!5tshgB8D_2jL(dXMaJ@T#^eVaYCF6>amBU2*5p*%gzegZ1Hn z7>LZIbunC%(zL?9ClY^p5!^uC#k(EK|NM` zCuH~4>OdJKuu2^enj$Bm2Gff(q++bq=-|W6EX9DZ06SyoDmNs!kX^wWOTQ3W_RlmQ z1|^aqU;Zs=ksPq(^37}+R$_@jKVb6h{7o%9k#qqro5O%gtYNRfzIp_}OJDqDQ>YP$HYv z+UGyR`_ag}E&iIsaH+t|Y!bwkut%7MzoS`7ZdjLhAq$Y^_UeUj!&YXQaKny&uI+{e zzK{?S8UIBKM*9Xz(3cd?43=s7>a?sq zUQAu%^^+!^km-lz+#9?nYdV?+(&f-6r7eSj80*9%Ch|b-I6N`LpPYk&JC#3wtBiEE zDM|Afmq75b+SOYv)S9MG+F52KO}JE22}R%g;OXwu5R4e^U`6%Gm;rEmJM z3}1?;B7T!Wig%b*5Ng#7$|kmn2rf*4F31XLb)evv)d6|nY@QPV3>}{r18s5lgY>$M4sqVK~M?ECK{j1doH+z zXhZ}QBmrd6u!s>*K}Er*=KcQPS9R{Wy-a4ZIl*M0&$)H#)T#RF+v}^ZGD}J&P*}Pp zjjR)TdZHhHC$0SpA9*(sRL6Jz-GeLwfxS#(IE4$qUk5!N6@ib6z;8Yg_#1GEM@1l9 z_)!tKtO)$i|1uGH@9~Sk_mvFIpicxtQ>ucicy&d^qVKv&fLN9(gocE&As3C}k}S$y z+EbJOo!^r6BMID<*fm*Nm-T~wlXQ{O7-#4Z_hJ389x1Dzc1zYzP1cWTu`*VA()=Tp zO0<`;==gfHYFr~SOGYXJd){Rg1Zh>vf8nK-&b#St{3n~O-E}LLAz~AeJe;0zux?f( zOcz@gJ^LSc3)d7?$H{}mbF^%p2NURzU)FnyrD%FyHN@}QE4@N9nTjl$G9?E(zpao? zGrIrac$VKTIf~g$gTd(5F8t_nGW_*SZuH~fQK=k2c$DUCu~C*URH=wa<@r0N1X>Rt&A@@$HYQ+v)!!LdmIln}_yI99B zg>$-ala!=*LuZ6&FjO%?E^%gZyzD78-9R2PnlN?8H3akDmou4>1Mi%Ti!WL-;QcuB;)kg2qzZiJhtL;UlzH zJPd^PhmQn8lT7`lAhbIkCA1S!qP?<5Xus2_)oyC~xtmG}Sz06Y6))B;S+~c;{5ttv z@lwO7^V>h8KxZwM?q<2uHehRw5*?h#FGKFcXwE@7QoO%YE_98lHP zI@tMfb%qtEeWXKLyI=(;rVYg49a?S$1Ddg_TEiIXTf-QF&01uB-6QiYmL(k@QcJ}e z27y%eA>Vna?Y-oh>rI9&#fneYckE)DGg!k{o!6mK6a=NCkk`z3E5WYHe5o zQ(GxKBY;J5Fxb^ zoV?n7L&N1%xs^8xS-!Zos3i?eDSiU*TIy2_kkk!!LYIYwr#l7SC=} zRbRzq!oq*HnY8yau43N)FTCm#b40hAkxd{lrmcaFzx2d*{l(PV-;NO|3=FWh=oKxk zE(3ekr(Ol z|H-*T5(PAAxTmA1ZBp(Gxiid|=GH`epXE%`gg!6wjvxK3^xIysF_gD_&hR#5=~p91 z=ch%?2|hW};XCqw`SWTdG6QGJpcFUDuaTpuEByizTWj_@A{N#bJZhFfoHb5kKSa5_ zPb6S^^G^peVo^l+v7R*{vLmC1q539JpRFq;)K@AG<;P~fC|_n#60WR^e5KWJ21U%R zfM=EWg(44SoLVg>zp(ZZ$>HR=b3!f+CDR8amOCEVahvgnj*+hdj<7cfA4&hHHlWxN z{okxFfo(aF%c{6Z+_Xauc+255M!9&Z~ZY zi-azWoFwTXW~y2^J8*BMxImug#5#SRDvx|Y+;+kU`ieu>yQ?K-+D8>Z``O-4YnyL z3&3_fucu?sxr4m}dXey!SHt2p6=SL64HaS1W`?Eq>0XLM5qk;D`57WF^^pc28P5GA z-jt^t(?gOcO${gU+R3|Qh0;%*#0%sJWXT2&(M6rs+a2`HP{ZU$3&q48DH^)}AAxhI znMrXxt8PBN#m^Oj>Id8AZfSsCb|h=gN9?#Y9m(o--Cwfev8z?p(y^=NZ5am7(Y#6`^@n-bLwt3xCw zS8x(19UtYqOr^?Zhj8q7*N%d2$DZ3MLNyQpv?P-WLu6nvte5*bM$)jtdWSVJ9E7Uv z^p^F-(1)@gwBw<5vZG~x5!V{kmi%4aL3CE+B&d$q^z0Yp zgB*nF1?6*)n_9nVhV>gnj^Z*Aup!{+i;W`syAYyM5oDW|H|Rzo8u#bA*(wS%-(~;) z+za9GyuWCFu1Q>$Wiw~(ieyFN636PNKp`mymX)|xO?+seBypQif1^wKHJz%)A-+W- zmI1X>lDPg6A_Fi)6~irT)hm*?O3T7MVc|<8u2i?1w3gfng6PEVZIrm$Uu5FLB<@zr zEFd|${^)X)CCUqn*k{j1)(CP`FoVTIHzr3{Ixm^${c==`fYL3s?HMiiW<;S%mx6zq;N_Fua49cP|l7csRMG=M@ zmw$!rSbrudEw!1xXvTq6HgF%(y7|QPH2lo*D!IpO@%jD=ZH(BSa0?>9 z!Wisq0h0qDyMzV|&bFhC4}lB-9qK^Xpm8TK)|A+RObM_!GeTkk-4o$Gva>tdmabZW7!zuJ-v}OxcROP-7#)WTO)g;owd;L0}PbVQj(@Sk`3?bb_&7O*^rIG zhmE<8;6hPxd-E(CE`4VgF_ zl{g#C^f-z$?(5?eNt|_LO(4#i95FGfcoq6XkD5W8H4$f{QbyQTAH~_Ii?dM|XIx|^ zj&f$SlQGLe3YulLzh@jiF#iE<7vfAETe3@K^nRS{{r-k!(+sg4W=KC2!mP(wQCXz+ ztz@8xPxKh8QD4pQys$<(3*po@UJ0FytN^(zZ9s+QMAKBSAWMhTry-Z6!Vt@u)x(z5xPLhl{L`vBbbXY4YeePB2kuLleza_2`~Kui2*wpi zChLUlb!H0QH$#`FsLar{pR?u+9Zy@q&?#P?q1T+D*Myl(Ic>$z&G9N#XsH=k^t9tW zWs_wzT7kfQiJynLw@eF*GWp$FVuq^+XKVDn+EQKIBUe=bH4AluzINLZK&_J%O@~H| zb2Omg+P1_B9)m4iMmCi?Md`dePQKs7#O^x(0{*Dh7``~#Sz4$=(;;Bg^ODAtdb@fLb*x`p55k?BLX{ z9(~zw`%__|t&m`g{$`xLYBdFWGq-HG0c5%HXKJjBufGe zACSAlR;&K}=l}Po+4(d;lp-Lxgmf!IIFbL3J(;1MB(|eN%m!yAHE#O>4qyPsjUox5trn-#_`b<&1fRT#S*rvw#n{&iB@!hBrk`+DU`kDGXH51=;w z!OApF&5?((TLLZ!Lc=zOu1#q^!Q0B;QM&Z|`5^)l>EZaYUjl~s+YxGVJN4PN94Ktb zvTPQA+;8vSEN<(cMIAPi&ko&H&TnUZvB7C#E4rPGWjq?l!;5br31s-%2Xz337= zE1`)|LR)+XMV=;|Ln3zTdg8#N^u$atae_hl!a`b_RssWii6YE2La~` z0O$Rtc(`9oyz!t=JSZ(S;J@@BtJl;k4aL7$EQ7Xioi40ofm-=Z3Q!~BUG?-_RJL~t zkC0}%Tcq;jxAYekIxz*aJ{wR16Vn@{((0KH=_kT4xtNo)zBLBm7z1wYfXX?v#82FA-&0A~@IX zv?+=70BAY7KwXeu$$C`YuTd^P8Y$Om_uVV){~@ zq0mKQhR7Mbe8|uO!}SCXK2PQx&g3Hw(-mWg2+XI<=Sg=yPrCDY(w)y!UGro|0DVGH z7iS4^w@Nj5+;PMSy}eEdnMfuqqjMwS2Uaq&ZhcptaLx~if2S=@*XXRO64YUSJ{^{$ zGBjy%L+nINDy?xUu>)&SYqg`aR$ttj@Yq^wJ*cg*;qyW4TW5vVnnxLFYw<|kh68SE z9@N&>o8tkLO_ZUC2pr96Wmn$UH-(L8PUVtgGOceGN@Ac_hCN~Tqsa^*_D4uE!=I@U z=u|muqEVrtE*Z1RQ`qZ_T-0Qf7{?D`fn@R3)#X2Ae|T>#j`a2L6gdpdLN)=|)bT$g zO-1WN)fsZ8KNK7QJZf1zjj@jC~wOm`gFIVA^)Ltzf1OYpwWjAq5 z^k(RJ-42LWV3y*al0g5HDJgPzI@CWM4kL3*vc76WJOn{OB!j zebZmymJrRzQz4&1L+M4=2n_I!!f6;nG3A&i;nd}7!F&_a?BLuUlIgY@K_tOwd-tPx zK~FSN0;3GuA&t(>r~xu*mdz9T0jU_ZWzHTv#<1g{TcGKivVkEf5+IzE4d)In}w0BsCwD(4#y-UAFiI*-+F^ptWzOk&ma}JEGJ~TsA_Mn1G zm4|f^=VMa7VT#o|6+9vB>2w7SV#G)O#0|~z9jSS(&TC;&ri`!QlW6t|!8U`ylyOVT zCE%fqOWZfgs<=+2kqe?v6$gn-yOO=$2-O%X=`~RwFdvR)cJ*@LIzU5& zqs_NXq#Kv=HR&fFDg`@rnFF1DFnGD|z9vC*UK<}0^`6Rw_3bK)k+m&q=HdI74UL>u zPpSirv^_jB+F7&qr1ht4*!Y-JPhK~+YISRH2!;nMsWJu}ckMZ zn}r3Oh?ftK=NlQ!xjYf)Kp+U|IUVp+{0u|wC!^4eSKAx7*ozkppO)7tKL=E^EH!G! z7E{#fWAc-E_QW*LU{r%(Ge}L8tnjND&I=TZucuG|7UvqYRc`D%A-O(*MSgaE3e7x0 z3o@32Tb~B@8z?+m%2`Vch~V2Fbu28!J&P*x0qUKlU{Z{I7R{)sK<5hSJsUhZQ(j0^ zQh29SQj2!pkT-eqtv04YEoHHNL*AnNj5HtQvI!WtdP-97Q}ZE;9$$>TI=rFHQbM1K zx-mbAI*(INq^aiX`E|P0ftsxd*#Nj*seKk-V?$#5vFe|Q8IU!eHM}-&Q^;yd%htC~ z$=C98oS%q|sy@j8-^azUr)~0@WNx{9CrH~ zUju4vK1%7SC1qCIU|g9crrMQR7!T9174XuTbFF`u53kQVytxrCZBSg-=VKIrKg#}S zfzDO5SbzHb;gj-JJUv-X-KfjPdLpj&Nt}PcWnF57w>Hfm!>=`7xY`R>rG|84so`ZO zwdo(_zyxZJqz1iVpTKr%0Oss&&D~I%uj4Z4g{{=4rnzl-5kdXJM;y{`Z&Xu{9=$)j35jYP2r(nVvj`6p08-65LIa;l>>Nm@!x`(MVE%X6 zaK-o+rFA=2l^UrZsG0_YiAOCf34tTRxnZg)=)RlUFQ}L0L$BoqlhL_CEO6QnONI$m z{gc_ytqS-#j0N+xZ~VsllSBG-mLB+t1QR!&0=dMVQ}aNmQd^UlPcUhGum-|4Yi%_hfC1(SfY(gEfPdv)z5W zwAjK>HX^n#(r>A@eUdagHRJVJTLC^R0iH(z@V;^4m;gT{swZy8hLf60n1C1G?=S?l zr?ONrLL;@Og{3+SWwR?sbZ(n-v}`_Pbe>v368p=`ma36BCrxNjW~plDcqH!OMZ_(u zlRbeped>)IuaUORC{0V`Ob3?|a-jV5>(#2xybI3sJ|TWw%9+3}H#4&;fz9kPppG4{ zj>yvS>e4$Eh$T@5`k}jNqY>pYgxE`k1PW{Et*-J&#|qSMOPEk(wZbczC!0onk_Yzq z^rv{FK%qu~3i6actoqYys-6yK$v)O&fxGdW2$kTb1~8K2QYVkkA^i}kleObgCtt2y zbITp|bc_~uz$5WtF}JuyL5_4`j-2O)RPOorwB<%WKo6~h7i{H4t1q_AzxOk4^Iv*q zG&pVMyCOlARUUT~pnpW~AO3K~b5zTJh&h6Ng9!=M0@N7A)+Kn!!+1*h*UNEiSZ5x| zh5;Or+VVCa#+{eFRl<76r^ImxFn(p7T9sM^EVbcVjIR^ zyAq-8I~FU&@ahVqH^zd{yyB5R$)EK2|A8L8*<6czoX<2U$O!KO!;J}0C=3Bc06z}_ zMv}X>z}nD?s%a>=O)*-vKHM~ct`m2#%;euN9SU<|TSf}e3KM5xVkSL>BT2qAuBc9U zSW|P3pM+>2;)>$?U_z0xvV@q#7%f3e9KuC_r4Bz)x&qV^a|A3?zl4}NzY)C|8c-Z& z-L}ODM92w6H-hm+e*5~e!Sz;6GOb<;uGb-AP2U8sy$vzAo?>*sSWyR%`A5+339eTX zbz(6GWCIg!fjMehm1WMSyCe{3;`Y{=(JJ0o)pGO+Fm zWCj&+hsa&_1(~E0$*h{9lByn+Ns;d_Khqx?tf*!?%MeRgj#b!j=WiiUy}T(Kx>0aF zKhw5vI>;%>WxS*0d?^(0lOzU>FN<>+QAfo&NOpOgvkjQe_y7G}KlOdEtv-xB|)LUXPL%^CCplf(Al`x66xN3|Mw>0)E^ienZrSxLlXs4Hg2%g-tMlKl$JytZ(w z3{Qv+w*|}3@C*5han-bB9JLDL2vZ6&fn^-Ho{iSHmrcA@^K;-J!E{k{ishtIAV^qb zLk8ILzS}H?Z$cp|@oZQ z=1K;wwI0;g+7GBT6fKPu=eIfc*%=1QaK%ljy?K@mEL#5W8>e(9j{sP9sGSqJb8AlI z&XpoD`Vjd3q1;C4W8w%&R|sf0ee}2vW?!q`OX51<9Htw;salX6&U-bOC zutv&*+U;z?Pf>iI9q{4%5s&#kwU+5ZPJFO|#JeGdMOsU1YhUDduN!C!-VME|l{(lS zWsABJ7VRHW0C^a8uV?>709xFQ;{wpj2MY|65uq7emLRbNP}+Ufv&4HOf9?mzzHH^z zdK`N(SCsNDTei#+S7@jzR3m`WLq^b5g@wF$JaS-#rZwV+yN@eMmlLRuD+-wtsE;ek zniHsxD~g;GsE;cOvT`3Kw8TyDU&}FjbU}vSDyBvo5F5%!1BZarVHNy>@>$hXv@ycU zf&=gfo>8?@!XpqZ@*Gw42n}1c!%G`^>2x*;>#<@i@=oWsE3l9d@GN$>5eZDIWr;3t zcaXfe!UFTKHEg}xAe?YXbp>nt5IsG3mZa~gSK{LOiN;xjW?j;S8w|`86Qo&BPj8mz zv&8kWP?qI^c4Az0F`urXx|SQV?I>n(yFMT$%^`^a&IQ-EIn#3ZiQBga#`F4SLBJO} zuIYRga0K=44?QB(P8|#$U8-OQZN;?*60`Iu-wLbJkcE=8FpJ11n!3~k?58bANl^jX z^jIST2MbiWif~5RTxlQCy~*|1nrs;FHs^1BncQ1Bn_1X9i8H5_AE{g~j}-**j?O>g z=rwB7AM()4O2y$rr}d}P#eP{S!ADm>!8O>B!_+#SCD#&V_s~`+e zaG_?o+uWsX{~^mkYXbnJn9q|Ouk{>(3wyb>tMgBk(?FbF->)=pJ zNU8nG>T?oocvePtb}PZ9OxrdHjnqt`PM3Y_MdyG?gcOsYKEjzmx1x_Q`jA;eUKPc- zF&txE^rgO#@hL)5LH$IHK@}npyY)khxg=F@KGPL!u&{ehW6%dG`MOM z-Gy`4;ynV-(o9r4|J+-#_;{x>qWH+n7GZoKy}v%kHks_yxL6%Uw(OU$$Oe}@tIHAJ z6-Z9g4Mp*c5oWDRH)!e=#!X-|&lJES=#o+~uP!iIZ2PD#fHu!z>MW^vf}zAr3B@R2 z(ujm60%k}k%2{AUqh%Tl3^oj6;@~BT!C(ZGefk z^+a(hwt-t58KmzpZ+SI8LP(R`RaH^1LZv!iV-&&? zOIbj`6wZ4iWQHkMzVOWm7ZL^6l>mVeIm_!-pgVryd2RDuE>MzCjF0aE#MK2NeBil! zo_ju$+gx{vY^b@65oGy(R_Tnwf@vmGMhwD&C?zgUY|2NB{i`&WhM>gts`UyjW|a+H z-{2G>smKX~B>6=&1iCGW=DCv9G}?5aIX(i!4*~dH zWWVAm#K^E{QXR5j7E!AkIAT9EM^dc3x__rNj}8V3sV-3(J_dpsz+`|V+>k|YrjuJbXa~fz1U-}1`G1l(+N${ke+&8R4BY|drDcu05!m%UH0&zVM!}sstdA9 zp(q-Iv3r_`78;e8%&KpIcpww12`DDiLg2vt(!3tigtB=*PUw(&j!@I(zh*)$E=3%G zDa2&(6OnkcK1f>RfJ8*o`)q*$lfxG%l7^E)^euX&VkmQW25GD~8ld+Wc2x^}Ut+ zNY%rVf;59AU%bJZ4qb=Mm~0`mhC7%!TYKTip*kU@j3dZIn1kil(X;ST*iRku>ef47 zHwHkzyF*4tQI5h24bl}LEvgZe)c`V}+LpZ`9ws&h3)B;F70rw`yx1cOgerPU45?Q# zUBZAgY!qU&1H^PH{-KJ@ARl0|A37AfnYR zUoX?2dWJF+P}gaZnbbh6ckVn?l&iB6K0-J8`RfTni4vEAwSLo5B8*(Btxs*Ik)%IU zucWrYsZQ_^_=wJ=%bG6p$7*t+Jz+ALaN-$(uvzuuZVSdPtrg2H>fE+CMOZTF3T*QP z@w~_q>0@z|yQ{e5*WYAJz0n)ek)vkS^5eF#wYJm&3Qs(NF zgmt6P@>HMNv=OyD#fmC%0$AUWvJpReB!e3maL}k--df|%*ra!(zY+3B>mqGHE~OwU z@0AVozP1w`*>Zsz<8#HF)j#8Z2~^lDQiO)YVlX7*(zGUc_cv(fkXRDU-Yc6ZC2Ce1 zbIMb1NJ8==v2PE#VPL$3;;9Qu^HPvd*w_Fd1qlx}|5$4(D@aYYHdrQ>rc2IhEYN$k}xR`evXB`<7_}B{r-ON?#&) zLNA~h+h-c)vqq88K((lEs*{qz)=E_>sho}~5l z_?!re&{tisKRh{IiI%D|EV1lBJN6%8>$`ysNl5=5aEkJ^UR8o4i_jJkjF@aN(hUD) zq=}KZtuNAXg0cKGHQ8@^77-StmUiOI-i!~?oQO$2p&F(_q$gi$r&}86fT*boPuR~! z2iYQM2Z5f1@xt>!PYg_&MAhg?DHTifB>re5AtHe<1^Oy=FVYh`LEuR!HRdQ}45s+> zNJ?KYj!3@>l6rKi9x+q(uEwK|@tsfs)cwut7(a2H_77|kFbMNv>16$~F&!|#VzoT- zWYpWLxE;Qt#W5Y)CxW4zRnJby5B4l25|YhFK-W(mBdwe$F;y!}d*4o(Afrs1YaC@A z$)Z5|m;6OB<+e;hXlcVh8y4VVFjbH?D=r|F8!9bsVKO}Qo#Na}G;zr^ncU{KW&_Tm z(LLOqT9GnVgjC2owNI5b*p2-?ZRFF z9@uG_*Kw<5-SevRx;wAB&kB^f>44oSb<-ic+r-@wjYp>qomYLC-|AE-l$x9UmmNm_ z!`$nvNB-WE?CgArWe$txvnb_|$C5rOL5X5PFF`F*HRgNxlkoHq+`(zuJzbcc-y4LwN!6dX~Z=wE` zUM5zCmo2)gSq{R|7Qdna&BSXfVo{H#7}8`P5cg;4z7r>J@bFOV7%FC!W=iAh2> zLFELaC<=zA;kU>0vM*c|U`|{;FKNlLK*11sb1achGj7|UDYjYo(_VhHW%HnXsmiAR zI;RPO9HJEKqujCqB^9pDtrYYMZYSO2Jzzv}For1FY;LdMezFIfsJ$68qgRm^6&Z-> zT--uYEex~Gj9TFS0gw^X;_5@{^EF{7bsO<)0j|7Y!` zeyXB&tW@c%MO5R8D$Yu3sGZVTN%l5%wJ}3-LkoqBx29DSRtzm5dzpDqaNi^BJ2{6y1iZ-VE=gKn<*XZJ&7_pSri(+tB{rzS-d0(tE!N;OBc=q z)kSACa6u2#Wg7|)WW)wC6K$5fi58_Wo~}i)n5R_=qjr;dPFBmhYJ289PpkAr&(n&! zXo*^>Xu9HsG>ee6oUJbjIa{yf(>Fa8{mj~5uZy%qawKKkqZiaA8j*dLzf~)WS_z^V z?ks<6MpZ2#Qgw0uRyoF{(&BqtnlZ{cLIlRYA9w!Nmo`t>5c0*=`ih%=$}wdnvrBW@ z3-(^z+M{9FvRGFDT~&H;fF5er(L(T7v^!U5x_?%RfYGpdN|bA{EOY>(u$@yYG;|z& zd|+YOi!tZH51@WXH@dw04(w5x_mAM6K#xi~7iy16x+v-HJ#I<&kP_MAZCsDU-DD3b zfW8^H&_fEKZw3td^<&&Mv&es3(%Ix4y&qc=kKe~F7s-j}#y>$9JZcy%S{69g1&^by zEy#>r(|Hxib;E+d?Y>oJ(T*!^%pe`z8inwn4i>v*u<+{dFlTv@LY+vW<~)v6w!_R` zkc`qTC`TII0lF@^B=0^`t3&3v<^5KF3~ zcrwctK_pcXj3hA1k;w}z0+$D`+b2H7a{m#t$n zBo|G|!$kXw?F?JiS!!ym$VX&s9L1Pi(KKDL!7_n7#GPBw(mfG6x8g3m6QOe}+O{V` z=T>(Ki`?VTkBy-pUu!a&%ALOKrbmX@?L$h16>nzz+T=c#AhE3|i-)R1^1@Ip*4g3}wPUXsDsduOFtrXabgd3jfL~Ud*~mVjjaLI3 z6ilq7t~qeQCCqs~80KrSUQK zO~7FEf|{awyNZxRo3NS+JMLDsg@k79p#?&Q*KB2%QdAPY4DzT4#43dSBi21F9jn;( zj|iJA_Biz1_RQ)jmZA3^S*yic9MRe>!n7y`&=-3^RH8QV&-HeTP{sH8>6na4*i}%B zwm^!1L1hXL4abOw5hg7UXXK8Mfyz#UYFvG!XcK zND*wR3A24%*?^yuWonR709egK24zt1hYg!_SAvb)l!k*W@H^(18rlaN+m!3DAz`1x zhVg)rq>NMd95!sL(taungatM%R38IubToLn1U9~NDZ-|pxjxuvd(u&1W3ln!@UVWc zD7^iB)nn7+%29G9B~Ea=9|qhCKHh$3@nT1;L)pv{@lvrhKWeMoTEu6BjCPUqgbXZI zh#_t+)Tl<+bC_;z$nA5FtG1A<$}3E!H3WXg3=^?6Ys=&RKCTFKE00_c=Ac%@M8qnX zCK0t!YAwIbQz;QR9uh7ZM^M!G2MASiLm+1viWaoVxMY}6BI74)#}_9rZ>*8NPeFXF zO)|ADd^%|PdK|TU?h$RYg_aL?L-9;A@`@lmb;34rh&r`caeIRi}B?hGC~` zitLC35B61*O19|Ld$r0`r6CTV&$9neBSGL*^CMMGb%X~UsYssIG;-qx)DDydg9#t$ zV=LALhbW{_1Tc0I3EgN&c(R0-1gy}08J;8GSxuYLt zSY{HnAXr2~(2p?*m9Yy>S_(|kU@Hu)GQ~#LJYfH}$Qo+w%N?<(wfk|7VVOxBb89P} zV|c$>Tk#yjqqJsxrwlib*@UmGc#h%yYOQ2m920Yu;?ZNS1@8%Yrt!7B-d&q=h z%(rgme(|1=fQnlaWUOTXGF6yUpiTCc@}r>6fGXwuD3QG@Aem5A+nG${9YTm)8$u|l zqrEIC1D+*iz_X+b@`acsMI7xNo}fV;LQG2#jJHu)hs9{b_Ovod);-jnMc5d7F&MkdiAR{ zJly6G1&(RCe0Z1xVn*7lc_LVH@V01}qpNXsQND`Q6dX^0gwbgg7jYU%ozhO44Qtwl zGj?ycRcSz{%Ot}?99=S^qf2y%4yjhPW1F<`(x36HX_66nrjvJcXHks=Ir6Hyg>BL1 zG@Ft3u&fEwA=T0II>@C1->`ojPf>qe2o zDKe5nTV){t6`kHRJk5S1D8xMSW2!vCk@BPZq4Gi)bHK}9hQ7U)5fIEXoH1Vz`(3Ho z2p%+T-!!n8tW}Scb_O}aESnD;!#5)M4u87r&@jfpB$_?hyxV`GJzKa-m-+Sbrw`s;VaIsKpQp1m(2q5*f_gYTB%GY;(!5~LuYAi z(RulwfU7=N%7x{7xr3ayx;<~1p0okj+(cLnIx`D2#=x>t%VZ#H!uJ8w-M~uw7?)48 zGcNb+2pD!?q06$sxM~J8Mq$`3+BIL0#x1{~ zNevS&4jH5I;6joB66mctgBBLMv2YOAc0IMaiA{u53P;`G#^a(HFn|hlxS<$=cPz9h zm!}?3?6ah?2zz}TyzM;_B+OWI*$V*dJSXZ|@9bsk57qnnLpq%T-a;Zi&jhH0f{}rB zK(O|y7nDRlqzV!!4KCIqlXbBUzp!U4FIu7d&%k^+wlve0SSaIKnupjhQ|m1oIvC*N z2ZSa*yv5@Za*l)1x-ftCSp%x!T@U?N9wqM@;PrWL%-R%y9q!!G_3ma--q_eR|~rzJLao2grsR?>5Fe6|6zQqyHV6bu+*76UYe~`@|jAn2s&z3?Wx> zq2Qv?Pd`0HRMY>DN_V@533r-ykqK-P&bFgxP`j24l0&qSHFfYu9qk?hK)#uu2$fva zI+TCP-qq1FQitCBSM-E+k_p8(dk3;14iQB$R&F@U8=fezns&AC?e~7-t?&5fTiH{> zp&($8G6CW^@4UUD^ha0Pfi|&K%!K}Cjl-Cp1z^O6h#dz)7vNu5Z+Eh(HqstmYRWr1 zJ3lGyhkbtvI56Pw^X7_;U10cOzhz)mghdYs)@y(Og7kn;Lq6MA^>Mg@K8^(SFRKq5 zi#}xB5%7IQbqmLks4+i=JireU^E?x;u0ptr#MB zim5?<++#C~y@~Z@@#=W-ZJg@CHVVafzzH2Usyh^|Z72tZqjZ8qa+pPWE<`~=B2NC| zVd>`qNrZuRE~fUU@x8A{ta!;1tiS|f1fPYqSR)K@Nh5~Pd>q^gLmt2-*!iDON`Jpx zbFle`S282|e0fIlO#-@4W`w=ri*^b!KJykju61_W*e|g;>&>3-0Br#L=Qz?sh_`fn za8{cLs;Z^V6Qn5?WRq!An@pR#T&Qa-=N8xk$PYxvr#hHNzJeP+jor#XJr=t%E{kxaen z4&Tz{ooqyJwX>1pxxY0Kk(8byRW1yyyq^D|5r;+?hAFl}`Ya}6+|h~=?OO(|a8|8% zLN#@Q`VRwILAMVCt$5wgDj=2l_E$hEsxC&VJ`PdFlKY8NU|r-K;VymUK&5h1j!h)Q z2hU9hmG2@sJ3-v@$A07kI}yi-f4h27BNW-yi<+Uxu3pp%MRxU~!BAvZFB%F(cJ-n( z6xr2_+M&pP4MUWLGa53q^MIqE(^Du3oe{6xr2_)`TLv zdePcYWLGa*7mDoaMJI(KyL!?3P-IsxIyn^C)r(FEMRxU~4WY=cUbHb3+0~0q4MleK zqQ`_HyL!=Sp~$XYl!YR@deL|&va1($Ly=v*=&_;5u3mI{D6;FbWRF+Vf2-Hg1rJsH z)W6N-jlxe`KRp32D^XPn$F|?`If;LhK-%B$tm23M+BLcSY+P5;$r|~oJI_dxryAOB zVr2~eY)SQn#stZ0aj*DI0ERpg;kPY=?i7z}z5%AHqzK&>_zyeO*6@Z^!;|U;qj4@6 z7(&xD)y`frJLsd;os)f)11wP*%i#psuA(A6#$(tg?V*OQ7aBjpwgkGEP%+GXB0vDe7` z+~5X>Z~BzAJ`q}n|N8f5Bal6>upmQ1r%WzPcqGRypJbz5IX21 zt+IwZpxGYmJjGmIN*yc{fMfB_V@T}lXJ|jBZKAcq71<#f`8LpUm2<-mtW^XGj1e~z z&<#^0MhSLSgliPz0K5OV)OoMN0?~;3ZTpL_WCJuTf&tmBP+wjLLv*FuThVX9e>W zOq49EQ^{T(*_9GNPo88sG6M6w(jC+@IbPB<#>ce4@K&4U`CA3YmL;@ zUSsPD*MRvqrR&Q*x_PHeO5JTL?$#?YvKP~5aYRMD%e(~KfHU4j-$bSGS5)v}WKBLO zS659k6lRh&Ic`x_s0g1mS`mJ6#v))?a+IQ&Uim0R zSez_vyJ#Oa&mrB6k-=ws+7CjUE4P>y(QT{RBnJ$fyhxptzrMzhHhE|Y zOLg+{cv_?U^@CWf_#i9|Qp}6=`avEasbp0#3H^6KTjyimBN=i!Vzu)#bq0cAJ?~lZ zRfa&2?9iRuYJRub*J`MF2)@hZz^?rKJ^7l;pd{$ORnYBZUYS$b*~$5sfxHZaP6hb@ z+WBg;p$t2)d;36xq0uBzEQZ*S5Vs;5jlV*ltjI?1MU2ggLL`qG zWM_ zYypS^eB^J?@BtMq^d21wk38F#=P!PBwI;W;osUd34$7}HXK6SdJCPvLMEznaT@_iB zV_ByVgChj}JEL&JRc5>C;!7+Nu7`-5LEQE`km)EASj{#hZmZ@yRodCI1Gyf>El1o` zqPP`av(-tj@~2M?ZgdifS5(L=?Nprj3T#3P?~_ti@Jphr_)?7+EBy4c)k>q#5PB(s z1#A!#N7+FBwjX=n>G;R;w{n%FXN=PEv>HvNX8xn^d+Vypm^_&va>EUY+6 zqUY!DCe7~vvl&8%%@1KIf~7d{{{f9E>0D_xNS*q4qYB)ti*Z0e5x45%9VJ|?i*b~2 z)i_xRR|AhM_=PR*m2eeuW*{UdzhsZT%&Hd(pWUJCf|ia4MUr^X38FLuL1z^B8lQ&d zZbB)lBF_XE718SHr>mBxCLR%2k<}Z)2*?eOW$V=Po0w~mfVunR-(nd?pmo6*dkh`% zRnSKmWZq#RUKuepG{fS~QxH`F=wcNhfEzpkw_SdBNa5$|88RheaQwg`B-Sdqt%6jg zGm4FrkhliqK#3j_+nV}AfW!r?#eg8)B>mE<4f4jDy4d!tinte`YSgDn{#uUm&>qE0 zED%CauNmxp1{VL#DjE8!STdNMCqgpna-+OQEdeDHUJnObEC+;lK{FrAR{Dc4Ix1e3Nkz(Awo?DQ{ z)^^mXx?~i8SvX)qyhO@qJ**0P35y?;py3vEq~+9QP821eK%vYvg*Q#ez$NVf*g~I$ z$#h5@Ok6~(Xo)L`n!9W)G=;llXSS;Nfd;a=_<<&-9Es``XEjMMXC3j&4$uW&Af0%@ z2-4k3*ELym2g*g&tqYlO4T!>UDME-@Qx_Sewh&mRZbk!D8$&Su za>@$T#4)Jwf8Ya)+X;`vBH|<14ab*gNlmlEln9GAUn+TnK)iSue*i`F2eYR!-mVb` z%vcCjg+Wy9Nzw!=LV(NK0DqRl)YQ80bBv!QOj^y)5)!TD zC-27gG)TG@n+iCvw!mThWue*C1%)h!4eJVQ5X1qiKm{^54r~Soh?Eeo!e&5(INabW z)ikgtTOu6}QU&%+Ozp`KH-X0|qXZvK%tf)6ojfvBt;vcRz0an4o`4;R za3#L~qTxEx!Y31KOgWsTO+fL{uVOu;Y_G?D%9wSEvOv zswNj;BM`~r&=}!7v=rvbu#S~aO>Gauz!60haOq(fh_Z?@E)gRP>o9hNGzD4+W!6!~ z<)rY9F~&ht>%-60{G^rG@>+hD(Do#L@@{Mo>8q~ArUKTTRNzo#=5aYTe;GA@g(%S*cBtxwMw44gH&j&-qO&WaPW=#<)`{;ZzlfYP7 z!gUOD7 zy#mby9SMjw&o}vSO^yYxOix@F%wts{YdeKJM$m?K)@D&)2|O-9Y}vej8e1lp4eT|5 z?N+U+k4y$lb;Y!uSGbsl{RglIBEJ-VBWgKcnw`NOEP$NhH)gHY#}oJwC9Y`n+FaaT zGct=x3U?AJDCR<)fDZW;24*t~Sqe(gAypIn+mvZyi+Y*_%D6 zm4Qg_V%1#`sy9u+{u5&DC0d z@@{NThp^JM*i<2CBg;np51?L-(e>1>o}e|BC;3Xq4a}_vZ*e+P%U#-npul%f$`DYl zcK&ZYa6rISvENuhEu#!=QpZ<_w@%mRio4k>x8UO{=1z~Z)`oE{tq}B>V=8YbW)rEz zA->Bwmo5_RJ*w zCl>+>!RFlUEyS5aKQV8My!bffyDg8?YV|D{*50BGyr|K(9&pRkl*?D1BMC0qVH%TE zR(a=icN%wzhGj9VzyDc_5x~>QLe0-n<4m0YsN>KT9j&E*QK_zoM zahNI0kKSx#HHQqo7CC?|(H|9%`*`qS^eiRr?7EbkhNzi^G0)wJKlTEfBX zahk|YYwEkqu?Hd_d4JORH};!N_v_pgf6sFs@x1T(iOFn@jmm{*))oG4HkV+5(%6PV=3mANw=CQge@O z?;F(7spx3+S`yJ?f>v0P&nx3*lOX(H-x4LLleQXwc0mt*loLWKcIqZ{B)_3;t)~WD z73Rl*(Ey#qE42mMH7g+7iMnBvIjCXLLFs++I7$t;(C*SWk*OxqLhqzRWP_T>7D@&3 zLwce%@3%9rt*N{s8|Ka41mNR2ulj5VZ}_|_@v8EzwHU;^1ToY*oSEM7btR{O!b zWfOhm-{199-$(FC0_?QNO-C`vI98>5`@oM%#E#fV9~#;$6F_ba=0A6r&AiV&rFr%eu&k~w@YnI zJMVzI@MU1ZzSjK9$@rMe;FOE)z8#Yp+~yZ}tPA}e9v=%{gb2+?uivZ?$i_x)s<(!d zO0C)+97>xbqn)u;>rPsK@~Mx>p7i8=>vvpo>33fCoabKty)XJ7S6;P!{=mT(A3A*F z4=n7z;p&OG@B982Uh(W5lT+7Rd)-sdf7%64|Mq8W`L+wE&)fFA=YQ7=zI)g1J$q-) zeah_h`@U!AGcUUMS*M+{VdLsGYsb5fJ^gW;&N}DpCp__tZ~d0XZ$5LNA?;^V^<3?L zKa8tqto@HLuntPN_IzNg!;U)LRWBNTS*86_p0s!}n5DA+toSfaoU!&-^h6|@4!^R} zeg(f)WrHsozA66?A^hL#sU#AlEy0*xG<+!kPd)iNp0vkX?L+!xOP@tvjkUj|VsGv+ zZlSUE7oiJna7aC%hvuZfAUPBoq(Y*1p!5rp4Ej^YwfdjZB17A(hME@*zodf4Y^?pa zv~6N#vwZ>yIYj9_Dg_L_&wj`RBGOOIkMRC@Q(bIzy;Bzr&*9G+Ykz^4QaFo;4W+W4 zVBZ9Y8H;?g;>Q#M0SCk1{sTtef6XgV4>&ARZ-1VWr2-Uob~qp5@#h%%DA&(YZ7IjR zDev&?GdwFe=Z)&A@x#OU7X{8h(F*ifpSnlz%}V{tI;m>B#TD(eIC2?GJnmeoDXT(+55( z)>`NJS{{Ft>gd#4qKr$fk*qwNujAQWdIqz-O%X-gvXtV#R+D#Hlg5wpllc7+>h;+2 zJ0n|e-{?(uNBbMUG5pteY%iC|Dd8jQ&FI!_f#+) zDEm{&Sg~?%e2`} zV!EwDI1P{9$D=0H^j@w`PR;xu^*{y4QjzEHSMq;W(H{Y&r4+?3mgOkQJrMmAMH~m? z{F>UjgXW1gLPxN#KvMsr;y+aJ@-(G6Wfk*xso^`&#S?zFlK+$5yPZ-aE6ec^$O>l# zgoS$I`YXC7*`H?e_0$(I*<~kfsi#zpuP&x_d`<6mt#Je_!p_CKeKK#~#@lY{$zz3r zDSIAL&MULy>$oG!5O*gPck9cI+2*tHlX>xOUew9ui2m^nUKu52BPHx;8b6gQ>xJWw z;mVrec*%NQ)1L9k(Xqs5C);eZ&i}6DpA;y5kIsqb_%oFG>xbV^Y5x?Z8$B%2PLq*R z1n+BQCo%cA=pn3v0JeSCca@Z+ttlPIGR7gUY0R(9ULe~4Z7S31&hZTDZ{>HW?A`h% z#sZBp7;Z2-6F5w> z%7lvEr`8!&SoJnyC@o|&#CjU|RnNPSfBfS~XU<<0Fv_p4kFSynhw>cOOO1?)J3Cpg zpiOD$eyeVOK;8Tex)~s?viGa(*S*XjywILsIwNnaT}p3nb8kA96u z8|_hh9}RSem;;QeAtWVw`YAjCYfsh%?mm@o;FVwDm8D#LD&NSnU*=iC)wj1N0#~2R zKdX=Z5>L|@hJ<4Lrb_-fmET%ozn@pZFRJ43R9i77Qh_({ryP`07)TTOW2pWvs$-%l zTnWB@rNR>?^3!Z>yp0xmkTJUz<8eBFEYIG`GeM>yBl4Q|6iXUs zCz)i-hcx21@Yt0X?fH0Bg+nkYeY5&c)IM&Cn-7eq`Jby$#Nud9I**<74Pz_(ci^R4 zFWmZcaK3%l{d6k4k)L4u`fTJ`!;|eDsjVhur}^v^n@x+^ zyE=ayFNrgZFngb^N>$+grxF`6eFzxb>x*wLusdyyCE7JTMAwHkk@0F|Qq-F92lX$U-QV#k`{YZYZx; z=TD)n|3zEP;a&N8-2WK&YqQZekFU*GVm`CB{+97IQtay8mea%9jJ=(da`jT9GRLK7 z=ig2fKSC3-PBpd98{VBigR=kGhe&Po4+>wSF&MuzL_$YC4n*3WzejESFm3ekXlH)A z3SUj(GHA3b|Dc}!kUm>r(MhcQ?OI$th=%ouhW$LFvP*`x)M;m>DBWer@KLq=N?JB# zSB|k({xOwFucvg0WI$TTQv@;25+OrHv`H$OVE7CDewj7aFBmj?$kqoW82;lg3c&!g zT3#?f_4g$hX7j&PFJ<0DxiFi5T17AMB8EpYgezgUl>H!O&gS!{^79Bk9epkuzC8a{ zN^Sy1CgZ@f=d_<~kG&upx_J2c`ID)G@;Sut;X~*03yodQx$A^eRf>vt^qp^id>@d-@8a?4ZiGhM${nrf>UY5V#`$M1C%q#Sw`9U0SLpQcMbF z=NI$?4NUPkxqK^giY6Fq&x+-bwXesK$z`9io{gby*{{6{KNxH8@hZC&p)dyZ*kz~E zq>Z(wQ$iEQ+SmDe*D7J%So@mPy*N{8KE}^UzwB@;ZF`#kt-d(nrB|m!obmIj)J&o8 z_sjRCX4_opm;d3H7o~0>eQ&s4;l(dR{iT8LNzIh`ZvXWHzkHWpo}cDsfjloYY}l6O zr|`z*etB-1pUSW2q^52>+kah_=ATiwzSDnRn&y9|pO>I?b9q+yd9nYzC^d=x%ryTt z9)5@a+Ul3wFI!SqfS%z$zdg-Qr|P$*Cde=JUr$f-3n;w6e?2WV+BrYXC5)cxm-EtG zqUtFaCS1<-%aham41PT+H8MCSH459D=1-#ViGF#47oP3E&hlSp`U~Ic1a?Mh$i6Af zg-DP0uYZeQ9_N?S{qk5TRn+OG`Jd_vg&Kp;Qs>8~rTHJI{4uF((5I%ZHE&E^2i}lk zL-72R)b+)aQ&%w8rywZhCk4%8UFvGW+BCmQPU;o` z2yUEdB+X5|BR%22>v=nM>oHC9uj=SvaAji~VTM-d!w$ z))v@c6_yxqa8zrooybVRKfJZP*9vvXqC%Vbf$Os>&vCTlpRVTTC^X*pzYef}(l+~Q zRj#}VYw@ZW3w`JnEbX&|^=e-gyK-wn1iJ0OvWC^BC!^2`88N;*KrPkiMW{a$|FwiTpq zO`Vj>$o3HUB9NBzd=Us$R#Vs0;uXb_)s&K^(B2dL-@s6xMAt)ffE4W8!J4lT_!@^u z7M|X1+Pe*DxH`g~utuQuBYN-^jO=L7_rwnlNVmroh$4G@jH~SNRlPO=0G-Bek=j=a z`!&0(Wz2vwAeYvHGwx6;PN&{#in5)ZU#$0h)Y+I@G@W44B-Z3oIA|#>STVj7X6iqy zWI^pW{8BKJ#jB!F7HWSju4+}Iy6^9>4l0>xxoQMf!ZmsdKKqiiDzjD!{u;$7amcz9 z{ActAzpmPIwJ|4avYM&*Clxgu5s>LMEvBEOo3dW?Lw9`P)!C2V78x^*&S)hP?JGQI| z3M|t`Zq8NB3JyAlx=bnjG7;*x$|X9;N|h@4IldVmB)q)h)ACCozTB*=`rq+DWq=m- zA#>+A|7``py|n?)xDg^-v?-<+9TMF-#}FYRzKN#{>lPQv8^EUWUVA0l1Kjz?Yx1QD z^3+vL0_C`vGgVt%8n+a9`8GLNIoC`cD_i5Y%oimIJSYilj*bLJk+6bhC8+v#N~6gXXXhARApInRyQCD(V-G(zj8XCl5oA8oq<^^TdtS_92`RG^8x(PFHdsM+{;49nG?&`YJ zUe@%VYKzk4JOrexfHX~Sw;#P;8eR{F=z=>iOH}FeO0o?im9q>@(cS0v`Txv*SydRFYya2p!(7k)_Gv^ zE9w?8E}1TLs!JEu4gA7a>g14k>ViydPnX$bMqL?`7-Z#CT_eE2y01QEiU8HfQ3q@> z1sH6qW;j}E{+KlsGdP7Al%c^0lKg4!?7WeP)BeixbwtoIF?5X6Xti6u1sQrWjHVJl zv{<_Kdg+5g?6w%KOkJ*&{I??ZJF2yY+(z-J8hL?;@2)8Hx-Ur@0W_4{C#ZN06B9MA z4%OG?VS^r5_OK~!8AQlz*B5)(EaN(^vZ%(9JWyn5IW6oWg2PE~Y8({k9ya+PEJ4B% zkJY6=LUyCnuGGDO4%x}B3@TpqzL7Gl=Y6Z=ee(iS@w7o5?^{b+ek*AChQ`JLgwJ&B z4Jlg+s)t7c&m@~#CLk(z-T+&2L%_Xw0alZ?v2=SqX*a2zq z1jbZsfU;<_Rg_^8#+^Fa8b(vS4OO;RD7Jj`E!8qt=vr(F&Y|9{R!D>O%a`y~w%mp) z^3#TTy)D%OVs}Wpd{_XZb$)3(vbIyPb&X4yYy&$sD-AgGtAhR-Stpiu3q;MDOu5n@ zpa}auDy&CUG8Yg_{hHANfDA)k3@)+r4S|Kax_E$-CImnaQzm#9?*idb%DBX>ga+s_ z$^dlSPZ;Jb0*e&QY9+QDW-2xsCMmWTa3D4n0L@m`&IGzGu zB`;YDW~G5CfDyo~R4|LdY}RW8O8~REI3jFt`>Cl28MXqbl?Ziw$C{^z?W_376u~eI zUx)Zf*W!-10OoZCnvlLJ)Eq4Kb*?G)b*?VJ4625D0!4QfvGM&Ep6qPLSb%82GF7HyCmOM%<$W0Er6# zEWl?lywuK;34FtzQH=;Ib%-+NA`aa4U$!Y@LLz^L z_VBZ*Yq2SEH>iiB1}oixgQ3?wW=vR7C?hp~xa$9FzCn!0&k9VAsExOxLq~CiD1w${vMpx6!fsVpb?9PvbnctKD!gf0S-XGjl-$I zWjQ2hM>@VfQu(Z68@k_hDT!sT*yce%E(?H?hxkT&d6OXa9r4D>=95I z&4X3YykyIgQ3w37p~tZr{@@SN_~RGLbk@Ta(T77K3J#+)0jq>RLNS_(Xa|u9l(A(Y zTL}Tj_{qDmJ^9s{m57P~PGbfB^x)JfU@}^Of24rUZ~vQ>^hrt?IZ ztWA0a{;)bD2DZww87bMwQbHUkW_7Tb^PytG(qi`8#dL~}0E?zXGalq=oPH-+mJ4T*YH7J}7O9rDnEBADmN=F*%>-`-h-37GyW>(VrFU~S zj@&Jqms2ePrhy&GDWI>(bsgS}%^G64Ast?M75bG+ba<07#$ZGD0-*bp%K+#;DTT>9FHU}(e;g~}r3G60&T@X&wE<8ZgOAktPrkUiy+TneF{ z5rZk0C{Bxsp$0JkWP>i+2(NTa6{?d97RNvUt?BLk$|aTUEun$fD|j2FO;9f5@Pl$0 z#~YN(INn9dWv!s_R>5!97F=dIHrAZrHAtmKfz(G+%%|^xs3a_Of z8RXonD*LwUhnsU|GW{jJOn+5$D7=7L*RK&7GhX!%lkZR4qr0ecx)@(F?nCMxm=VF@ z2u*Y^5sM1MTZ~CnoJkS8;I^{nw5b`D*oIBH$s54i6j!nbT2ig@t9XDQvhkSo1lInw*zGUw5dm2Fl@%t9)N;YEm*{CkctU@!3 z^8HmUqKx>MH8q);Xd)wE6xb#jFwbtSR#Su}r5vd%i!AC(0B~$dmh40%+6Df`T+(1>evd^~^Qq zrASCb@QH>rsDSLjoFp_f+yZF$d7FYAO95=WkG@-}^~S-GfO^b!4+;XNSyDg|*COjw zQz4}A2?g2KI2Vb-tO?K7QN~4R?e##hMFx_&t{^w*U6IF_>q=Y+Jc-H|$@kP$RK5f; z8jCICCsYHGXL@iz(H^PaL=Lej^YtfLr%3*WYb5m0yolCUmpz7?h2l0=BNWBkm_U0hwt3DW3%58Q}4z}w>Fv&42{3C7w7Q-yG#rF-vn6CB6I zLjIrpOkj;!9R@RyR~NbvlafxLn1Qn4HJGK`X|?%oouv|`-PLc)am=?sF`ZT+MnOt# zoC+BW43@o@kd-b~>2p?74cFDc5**rDgR#LZfV&NG;4*UZ+kmz3;BAbaLf7%Hh#~fY>imU}%W7d3{=i%6y#u(|3McGCK9rL^} zH9I@Q)4ka>(+8#|uiAcaerhh;F|&7Wes*EU{LE}JJFzF*GjTAR*}MB-wtb4KJ7%XQ z=B6f-gEI@+j)}eD$@C;Qd}H6)yQlU~?at=-?(~6#3VUbf)#CoC*?IME{<^7bZekCA z4({1Lvpdo6nZ4eRi5>IPv=Uz8Ydh#Jy_}q$rMtTi(({S!yQkF5HPd@1vt3gMlRXP_ z^V#IozL~jceP>orcTMe07G`&IHtwjzQ}dh7HrKfdCzTz}~M4qUW@k4(Pf*M9x(VH$W<{ju-;p(Ow1KTOiQ zDmTnd&rccb=cZo_(C4y+y?}l9^xXXP4g=ZLo_+HNv%LZ&PX*(NY(Etyvxyx$W)}9& z`!gW5-KHj)-s_KjD&~N5vTt@~a$yJ9F*(DmtBva>_D^NZsV0KECGefd49on5Cs_(7Ii@21&nAGdq=q|nX2Z&_iQT|*@?dt|^tIPbfjvNIa%vV*IhZ~FqARi+rsuEA=H@4M89{+db3I5g zi1)rXN&luYF+Z;<5Gu}1%|jvwppM-$H}Ju^soDL|$2m{Vc3d|x3n+oGCW;S(odWaH zi4u9nnTj;Cdt!PI&D}6DJE{4fp9Y};Dvd&~8ipnbN}tR&P0VMzq00H}oTof4o4H0z zz{y|^HZTj$Oz#s*;Jy7b^V55;JtK(}!)G<-YZmrS_C~2bUc>Z49{Df5FG+v4%J{CD zSeUtG2xfajd(t^sq?fsj2lh}!2Mz+I54>MUVN7yvVc)))Sw^?8 zclY!j=(r%sxd@#C1E&r^(G7jAxmUrCfbN4m$`LF&IL0Nfz{v0Ea(7h5jSlAo739B^e zwPRWg1m-}2Q>=?DBW8)BAZaIiz+W`3k~k{yivrLRPki%WF~T{z`JaE5q`y-!hEDr8 z05u!Je5Rfoh*ePFRwDLpVjwAfVs2skyf{zhaJEU9oR%h_AqB}Rn$Px4&7Qp-jbT@| zePPG0sd>j1P3aO&AEkx*AIOBcTi82&{epxB^8(sKtx5jw4=3pdE6<&pzhP#UhIw|w z^dxv7&U7@u8wX5c=Y`BYf-ib&;462wfM>ymjzX)T8#pz^Xb%RuPZ;d1Q@t_$SOZ>r z&^VOZXHc*FNW$4z5fx0N857t$HGkC&QxMvGBHZumek9|hz+s0qm>d9&riGwEcrOCC zCRqY$cIrUEHD;%-g)YZ)HL98+Rq?t;@h~$G(LKKUg>8Lh;npU#Bq! zNxftDj8x8E2Zs80H>yj_IpV5CuC^Q?jW8JEo=(qk+c< z=`QZV^cD2&EMpGcc>0=Y!{pC@G)WH>lh+%L35lo+8`^F^n4PovafvIk(l3Nwv48j7 z4WJ;HA3&!o3ExkBEJ=S#d=|_?|6Z!rWPBFwIhma@`sls8XX4tu)AI|HDAy33aoYe2 z>pFzHduk4NTu0ka`u_8tRHA}wrf0>L7Y+*dB3O4U%!+r=i5?b$TwnWmlD@H0K#Yg3 zZpGIQq8kN)$c)ih(_m&Miypgn8aP-at}>tPmlR9sgyC&MdY_e@dq&aOzAnD@6G^%c zGh|_6_f;kv0q5gQ?Ccdjqsuxe8nt2V7_%&KZp|eaQW6Oh`?0pn5OL}(&=tLA3MRW_ z9>^T|WRl(vx(Bg*6(n@kHLzq*&SpSU)i(>?i+#vPFn<}2Amvss3H!4t*lk2E5yGAs z*!w|YkmI>&np4;Ap1yV(gQ?&kO!s^SdpH{R*bYr&RrDCh?Vn20msZ3F?t2UYh)XHe zI~dVo5s_{`2L)m`w0;213Jq^A>XrdW2pE(cfO^NLlk^n`N5qI3D8e2iV$^Fhm#&$b zif{^Fbe=H>?PT*dXQBt%y$+_2Eo5S{e|kkpbJlD?dKYdxuA7=%kTvREq&M&X%Ori3 zD}DW@gozE)OoRPAi)3BQB^gEEpaq+`_>rXmjI+Hmt4s1b|0+pujQlggCBoc!Xa+?( zrUgS~spv`E`t0wVxbgO>DLD$vB$vDo2niN*w*&E@Df;l;N&3T46P6Fa+y}1WL;Yg# zt^&k)(s$s(PKvMygl%XzymU-681)ME6Ua)R-#)Qh-J(yQ{!Eg-ys`idn`+J+qG!u0 zv{{~pQ5r&F67ymA!Pxg>2RZ-2?TwJ&b|ZW!3- zlk|5>ti9CqB2>;c?L!eTGdtTejgM)5$8~2UCTfG50HE%eg405+Qq?u(5|45&fe`Md zxgin#2e=f%ya$AU6vso>B=PubY13ujGe0k1j6OD+Ahj)d z?`LAIWh$GU+Jhq^DAAGF&T_cgOV*u86URf#5bQlk`qPyq2z=i>5J>`zU0X5+EQMp5 z*_BTa+Z4J-O@j$e%+4jdXRgI{Wg6RAWr;Jh1I8aa-qX3tGM8!j#@{CCl`E)w!8PKD zvv+3i*)N`&MQFLptdE+5COQvIiwmL?L~Dsp-1WsIy?Ckq5#H&qT_PSy%@PV2%TMw* zehDwx9P_n%Y97wFNM~QJQ|P3n?ih+8F89vKp}g2!={LcX{3Tyb(wza_kH!y|`|fhU zu&*!Uv_c-Ctpckr^TFvQ7;{vXxAM39N8VS@v;)n}-(eZt51v#=I!#|t+XG@89m0qm zu@rru&wudmlXU6C%ZH8Z~Mm8iy33MAB$& z&cL0KlZz&5Ct8SU#E?R41S=I$un|+nPAe@ef+@s+B8U*h#ETmBH-C0#Hk;dXFLpP# zH*aQV-n{p{?@eBu3|wwJQ>k(Qjd{|`FjA{kweK)II0HYQm#8;S-v|^(9n!ahWkLz0 zT>B!?B`2l9!FNw}jO`byS|Zjf!*`nySQ{*dGn#DXA7i-{_}M5< z?5DEtwOUvu>OI4}h&enf-45DhtKtP9ytagZw-L}a|Cgl>+%OzzE}I2Y{Y|1$&;tjB zy?6Sj{rgzgMS~8tb;M73lECS|=9_gsK-*7Ce<#GO=b=R1SdgfHwKa7+P?(70KX)Q> zUj<~oZO6`CJ-bUMZT;lo)23eX$XQGr#g!?uoMM;4N!?uJ3R;oGUdXZ~G!=i7kDLy9 zJXyA25HHIBe*na2?VlI~BakcwM5lx6}xwxC$S)SQF+Zm*mB!3ZLD~q0Mza{CkNdi4Lu%Np6nCu1nKx%WGOcO>fiABl!C^T|DW!72H7FTw3OMk=>(Hd|Om-4ff$sd{>4U9=}}Ypk+ai~;His8La$>Ac@{ZUC5)jy_}v=x8SJfNGWl znf=StC;eJFdPdWeFs59(0D9CMHSi0mOGs62W(CyAi1q-0To&aw2U^k>pI5>W8oB0x zajAxz5R@M65K?;jR)eTpG!F-Z#LhVv@feX|mV{e9CS5M-9rCuvLehD(*jngBppoEd zvI**=c89$ZvmHdr20L9Ct9j~Rnr<7-dnC6y>b-by|FuZ_tCxMBmirHIStI%>S_7;>U20ljA6n^i{j@?|M-qeBV5;~L>i7=9@1QkLI?H@?2)U9HYIIT_9GQ>gZn1K3FN%WtJmaD-i=sdv zya3$_1s53|ayFY0YBMpe$#`7=(C>XLiPGPKk!J0YR)VR(XAds51VB1Y=}kIkkv&+SC!JT_dc{4LxnL;V#+YQByRevb2g9HBKDcFcz-5)nwrI)dguXa#b0rI?Tmw zXgzB~xFZ^%LBFvf=(>zUJ7NwW4-gk!B}je5z)PxJCtVZpY&Wf%Y<=&o4iJ__4XuWUX!x9R2;`>*DO&d7-(<4FT7>VdNbd zUMp=^lYJ?5E$I~_txncS9SNMqY&l_z4Xwk1=xW&(_NDjO$?Kp+4OVb3>}q1C2iOZR zU9P=b7=Z4}(D}B(lXAMBr3!X6OmIx0_R$18EeXhpVp~7CgRNA#B@ADw%B8A=Dmzt% z)1@l9%G{|^sagdXsj@P_KPWe?2xkR;N-J2mxNJH;u;JEq%WzUP;V Date: Fri, 5 Mar 2021 08:18:46 -0500 Subject: [PATCH 1048/1048] update README --- README.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index cb90a374..0190c485 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,20 @@ -# eosio.contracts - +# eosio.token ## Version : 1.9.2 -The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, system, msig, wrap (formerly known as sudo) and token contracts. - -This repository contains examples of these privileged contracts that are useful when deploying, managing, and/or using an EOSIO blockchain. They are provided for reference purposes: +The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the bios, boot, system, msig, wrap (formerly known as sudo) and token contracts. - * [eosio.bios](./contracts/eosio.bios) - * [eosio.system](./contracts/eosio.system) - * [eosio.msig](./contracts/eosio.msig) - * [eosio.wrap](./contracts/eosio.wrap) +This repository contains a reference token example contracts that are useful when deploying a token using an EOSIO blockchain. It is provided for reference purposes: -The following unprivileged contract(s) are also part of the system. +The following unprivileged contract(s) are in this repository. * [eosio.token](./contracts/eosio.token) Dependencies: -* [eosio.cdt v1.7.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.7.0) -* [eosio v2.0.x](https://github.com/EOSIO/eos/releases/tag/v2.0.8) (optional dependency only needed to build unit tests) +* [eosio.cdt v1.8.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.8.0-rc1) +* [eosio v2.1.x](https://github.com/EOSIO/eos/releases/tag/v2.1.0-rc2) (optional dependency only needed to build unit tests) ## Build -To build the contracts follow the instructions in [Build and deploy](https://developers.eos.io/manuals/eosio.contracts/latest/build-and-deploy) section. +To build the contracts follow the instructions in [Build and deploy](https://developers.eos.io/manuals/eosio.token/latest/build-and-deploy) section. ## Contributing